Skip to content

Commit b0aa6f4

Browse files
committed
export functionality - trial version finished
1 parent 6095bd4 commit b0aa6f4

File tree

6 files changed

+102
-2
lines changed

6 files changed

+102
-2
lines changed

src/cherish/Settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ const float STROKE_LINE_WIDTH = 4.f;
220220
const int STROKE_SEGMENTS_NUMBER = 11;
221221
const float STROKE_FOG_MIN = 4.f;
222222
const float STROKE_FOG_MAX = 30.f;
223+
const float STROKE_MESH_RADIUS = 0.01f;
223224

224225
// polygon settings
225226
const float POLYGON_LINE_WIDTH = 4.f;

src/libSGEntities/Canvas.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,31 @@ bool entity::Canvas::attachFrame()
721721
return m_switch->addChild(m_toolFrame.get());
722722
}
723723

724+
osg::Group *entity::Canvas::attachMeshGroup()
725+
{
726+
osg::ref_ptr<osg::Group> group = new osg::Group;
727+
if (!m_groupData->addChild(group.get())){
728+
qWarning("Could not add mesh group to the group data. No export will be perfomed.");
729+
return nullptr;
730+
}
731+
return group.release();
732+
}
733+
734+
bool entity::Canvas::disattachMeshGroup(osg::Group *group)
735+
{
736+
return m_groupData->removeChild(group);
737+
}
738+
739+
bool entity::Canvas::addToMeshGroup(osg::Group *group, osg::Node *mesh)
740+
{
741+
if (!m_groupData->containsNode(group)){
742+
qWarning("The mesh group is not part of the group data, cannot proceed.");
743+
return false;
744+
}
745+
bool added = group->addChild(mesh);
746+
return added;
747+
}
748+
724749
void entity::Canvas::setModeEdit(bool on)
725750
{
726751
m_edit = on;

src/libSGEntities/Canvas.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,23 @@ class Canvas : public osg::ProtectedGroup {
263263
* \sa detachFrame */
264264
bool attachFrame();
265265

266+
/*! A method to be used only before calling on scene export function. It adds to the group data a new child -
267+
* mesh group where all the stroke's meshes will be kept for export purposes.
268+
* \return pointer on the added mesh group. */
269+
osg::Group* attachMeshGroup();
270+
271+
/*! A methog to be used only after calling on scene export function. It removed the mesh group as a child of
272+
* group data, thus deleting the whole structure.
273+
* \return true if deletion was successfull. */
274+
bool disattachMeshGroup(osg::Group* group);
275+
276+
/*! A method to add a stroke mesh to the selected mesh group as a child. Only to be used to prepare the
277+
* user scene for exporting.
278+
* \param group is the mesh group which is already a child of a group data,
279+
* \param mesh is the stroke mesh which will be added as a child to the group.
280+
* \return true if mesh was added sucessfully. */
281+
bool addToMeshGroup(osg::Group* group, osg::Node* mesh);
282+
266283
/*! Method to switch the normal canvas mode to edit mode, used for editing canvas position and rotation.
267284
* \param on is true when the canvas is in the process of editing, and false otherwise.
268285
* \sa setFrameEditable(). */

src/libSGEntities/RootScene.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,31 @@ bool RootScene::exportSceneToFile(const std::string &name)
165165
state->stripDataFrom(this);
166166
Q_ASSERT(!state->isEmpty());
167167

168+
std::vector< osg::ref_ptr<osg::Group> > meshes;
168169
/* for each canvas, detach its tools */
169170
for (int i=0; i<m_userScene->getNumCanvases(); ++i){
170171
entity::Canvas* canvas = m_userScene->getCanvas(i);
171172
if (!canvas) continue;
172173
canvas->detachFrame();
173-
// for all the strokes within canvas, replace them with mesh representation
174+
175+
/* attach mesh group */
176+
meshes.push_back(canvas->attachMeshGroup());
177+
178+
// for all the strokes within canvas, add the correspondig mesh to the mesh group
179+
for (unsigned int j=0; j<canvas->getNumStrokes(); ++j){
180+
entity::Stroke* stroke = canvas->getStroke(j);
181+
if (!stroke) continue;
182+
osg::ref_ptr<osg::Node> mesh = stroke->getMeshRepresentation();
183+
if (!mesh.get()){
184+
qWarning("Could not obtain mesh represenation from the stroke.");
185+
continue;
186+
}
187+
bool added = meshes.back()->addChild(mesh.get());
188+
if (!added){
189+
qWarning("Could not attach mesh to the mesh group.");
190+
continue;
191+
}
192+
}
174193

175194
}
176195

@@ -185,6 +204,12 @@ bool RootScene::exportSceneToFile(const std::string &name)
185204
qCritical("RootScene::writeSceneToFile: could not attach the tools back");
186205
result = false;
187206
}
207+
/* delete the mesh group */
208+
if ( !canvas->disattachMeshGroup(meshes.at(i).get()) ){
209+
qCritical("Failed to remove helper meshes. The scene graph is messed up.");
210+
return false;
211+
}
212+
188213
}
189214

190215
bool stateset = this->setSceneState(state);

src/libSGEntities/Stroke.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "CameraCallbacks.h"
1212
#include "CurveFitting/libPathFitter/OsgPathFitter.h"
13+
#include "ParallelTransportFrame/libPTFTube/PTFTube.h"
1314

1415
const GLenum STROKE_PHANTOM_TYPE = GL_LINE_STRIP;
1516

@@ -133,6 +134,32 @@ bool entity::Stroke::redefineToShape(osg::MatrixTransform *t)
133134
return true;
134135
}
135136

137+
osg::Node *entity::Stroke::getMeshRepresentation() const
138+
{
139+
if (!m_isCurved){
140+
qCritical("The stroke was never sampled and cannot be converted to the mesh.");
141+
return nullptr;
142+
}
143+
const osg::Vec3Array* vertices = static_cast<const osg::Vec3Array*>(this->getVertexArray());
144+
if (!vertices){
145+
qWarning("Could not extract the vertices.");
146+
return nullptr;
147+
}
148+
std::vector<osg::Vec3f> path;
149+
for (unsigned int i=0; i<vertices->size(); ++i){
150+
if (i>0){
151+
if (path.back() == vertices->at(i))
152+
continue;
153+
}
154+
path.push_back(vertices->at(i));
155+
}
156+
157+
PTFTube extrusion(path, cher::STROKE_MESH_RADIUS, 8);
158+
extrusion.build();
159+
160+
return extrusion.generateTriMesh();
161+
}
162+
136163
// read more on why: http://stackoverflow.com/questions/36655888/opengl-thick-and-smooth-non-broken-lines-in-3d
137164
bool entity::Stroke::redefineToShader(osg::MatrixTransform *t)
138165
{
@@ -202,7 +229,7 @@ osg::Vec3Array *entity::Stroke::getCurvePoints(const osg::Vec3Array *bezierPts)
202229
osg::ref_ptr<osg::Vec3Array> points = new osg::Vec3Array;
203230

204231
float delta = 1.f / cher::STROKE_SEGMENTS_NUMBER;
205-
for (unsigned int j=0; j<bezierPts->size(); j=j+4){
232+
for (unsigned int j=0; j<bezierPts->size(); j=j+4) {
206233
auto b0 = bezierPts->at(j)
207234
, b1 = bezierPts->at(j+1)
208235
, b2 = bezierPts->at(j+2)

src/libSGEntities/Stroke.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ class Stroke : public entity::ShaderedEntity2D {
8383
* \return true upon success. */
8484
virtual bool redefineToShape(osg::MatrixTransform* t = 0);
8585

86+
/*! A method that generates mesh representation of the stroke using Parallel Transport Algorithm.
87+
* \return pointer on the cretated mesh structure. The structure is not attached to the scene graph. */
88+
osg::Node* getMeshRepresentation() const;
89+
8690
protected:
8791
/*! A method to tune the look of the stroke with smoother connections and thicker linewidth.
8892
* So that to avoid broken and thin look of the default OpenGL functionality when using GL_LINE_STRIP_ADJACENCY and such. */
@@ -107,6 +111,7 @@ class Stroke : public entity::ShaderedEntity2D {
107111

108112
protected:
109113

114+
/*! \return Sampled points from provided set of bezier control points. */
110115
osg::Vec3Array* getCurvePoints(const osg::Vec3Array* bezierPts) const;
111116

112117
/*! A method to make sure the curve is not too small, neither too large for a fitter tolerance level.

0 commit comments

Comments
 (0)