Skip to content

Commit

Permalink
export functionality - trial version finished
Browse files Browse the repository at this point in the history
  • Loading branch information
vicrucann committed Apr 13, 2017
1 parent 6095bd4 commit b0aa6f4
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/cherish/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ const float STROKE_LINE_WIDTH = 4.f;
const int STROKE_SEGMENTS_NUMBER = 11;
const float STROKE_FOG_MIN = 4.f;
const float STROKE_FOG_MAX = 30.f;
const float STROKE_MESH_RADIUS = 0.01f;

// polygon settings
const float POLYGON_LINE_WIDTH = 4.f;
Expand Down
25 changes: 25 additions & 0 deletions src/libSGEntities/Canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,31 @@ bool entity::Canvas::attachFrame()
return m_switch->addChild(m_toolFrame.get());
}

osg::Group *entity::Canvas::attachMeshGroup()
{
osg::ref_ptr<osg::Group> group = new osg::Group;
if (!m_groupData->addChild(group.get())){
qWarning("Could not add mesh group to the group data. No export will be perfomed.");
return nullptr;
}
return group.release();
}

bool entity::Canvas::disattachMeshGroup(osg::Group *group)
{
return m_groupData->removeChild(group);
}

bool entity::Canvas::addToMeshGroup(osg::Group *group, osg::Node *mesh)
{
if (!m_groupData->containsNode(group)){
qWarning("The mesh group is not part of the group data, cannot proceed.");
return false;
}
bool added = group->addChild(mesh);
return added;
}

void entity::Canvas::setModeEdit(bool on)
{
m_edit = on;
Expand Down
17 changes: 17 additions & 0 deletions src/libSGEntities/Canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,23 @@ class Canvas : public osg::ProtectedGroup {
* \sa detachFrame */
bool attachFrame();

/*! A method to be used only before calling on scene export function. It adds to the group data a new child -
* mesh group where all the stroke's meshes will be kept for export purposes.
* \return pointer on the added mesh group. */
osg::Group* attachMeshGroup();

/*! A methog to be used only after calling on scene export function. It removed the mesh group as a child of
* group data, thus deleting the whole structure.
* \return true if deletion was successfull. */
bool disattachMeshGroup(osg::Group* group);

/*! A method to add a stroke mesh to the selected mesh group as a child. Only to be used to prepare the
* user scene for exporting.
* \param group is the mesh group which is already a child of a group data,
* \param mesh is the stroke mesh which will be added as a child to the group.
* \return true if mesh was added sucessfully. */
bool addToMeshGroup(osg::Group* group, osg::Node* mesh);

/*! Method to switch the normal canvas mode to edit mode, used for editing canvas position and rotation.
* \param on is true when the canvas is in the process of editing, and false otherwise.
* \sa setFrameEditable(). */
Expand Down
27 changes: 26 additions & 1 deletion src/libSGEntities/RootScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,31 @@ bool RootScene::exportSceneToFile(const std::string &name)
state->stripDataFrom(this);
Q_ASSERT(!state->isEmpty());

std::vector< osg::ref_ptr<osg::Group> > meshes;
/* for each canvas, detach its tools */
for (int i=0; i<m_userScene->getNumCanvases(); ++i){
entity::Canvas* canvas = m_userScene->getCanvas(i);
if (!canvas) continue;
canvas->detachFrame();
// for all the strokes within canvas, replace them with mesh representation

/* attach mesh group */
meshes.push_back(canvas->attachMeshGroup());

// for all the strokes within canvas, add the correspondig mesh to the mesh group
for (unsigned int j=0; j<canvas->getNumStrokes(); ++j){
entity::Stroke* stroke = canvas->getStroke(j);
if (!stroke) continue;
osg::ref_ptr<osg::Node> mesh = stroke->getMeshRepresentation();
if (!mesh.get()){
qWarning("Could not obtain mesh represenation from the stroke.");
continue;
}
bool added = meshes.back()->addChild(mesh.get());
if (!added){
qWarning("Could not attach mesh to the mesh group.");
continue;
}
}

}

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

}

bool stateset = this->setSceneState(state);
Expand Down
29 changes: 28 additions & 1 deletion src/libSGEntities/Stroke.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "CameraCallbacks.h"
#include "CurveFitting/libPathFitter/OsgPathFitter.h"
#include "ParallelTransportFrame/libPTFTube/PTFTube.h"

const GLenum STROKE_PHANTOM_TYPE = GL_LINE_STRIP;

Expand Down Expand Up @@ -133,6 +134,32 @@ bool entity::Stroke::redefineToShape(osg::MatrixTransform *t)
return true;
}

osg::Node *entity::Stroke::getMeshRepresentation() const
{
if (!m_isCurved){
qCritical("The stroke was never sampled and cannot be converted to the mesh.");
return nullptr;
}
const osg::Vec3Array* vertices = static_cast<const osg::Vec3Array*>(this->getVertexArray());
if (!vertices){
qWarning("Could not extract the vertices.");
return nullptr;
}
std::vector<osg::Vec3f> path;
for (unsigned int i=0; i<vertices->size(); ++i){
if (i>0){
if (path.back() == vertices->at(i))
continue;
}
path.push_back(vertices->at(i));
}

PTFTube extrusion(path, cher::STROKE_MESH_RADIUS, 8);
extrusion.build();

return extrusion.generateTriMesh();
}

// read more on why: http://stackoverflow.com/questions/36655888/opengl-thick-and-smooth-non-broken-lines-in-3d
bool entity::Stroke::redefineToShader(osg::MatrixTransform *t)
{
Expand Down Expand Up @@ -202,7 +229,7 @@ osg::Vec3Array *entity::Stroke::getCurvePoints(const osg::Vec3Array *bezierPts)
osg::ref_ptr<osg::Vec3Array> points = new osg::Vec3Array;

float delta = 1.f / cher::STROKE_SEGMENTS_NUMBER;
for (unsigned int j=0; j<bezierPts->size(); j=j+4){
for (unsigned int j=0; j<bezierPts->size(); j=j+4) {
auto b0 = bezierPts->at(j)
, b1 = bezierPts->at(j+1)
, b2 = bezierPts->at(j+2)
Expand Down
5 changes: 5 additions & 0 deletions src/libSGEntities/Stroke.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ class Stroke : public entity::ShaderedEntity2D {
* \return true upon success. */
virtual bool redefineToShape(osg::MatrixTransform* t = 0);

/*! A method that generates mesh representation of the stroke using Parallel Transport Algorithm.
* \return pointer on the cretated mesh structure. The structure is not attached to the scene graph. */
osg::Node* getMeshRepresentation() const;

protected:
/*! A method to tune the look of the stroke with smoother connections and thicker linewidth.
* So that to avoid broken and thin look of the default OpenGL functionality when using GL_LINE_STRIP_ADJACENCY and such. */
Expand All @@ -107,6 +111,7 @@ class Stroke : public entity::ShaderedEntity2D {

protected:

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

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

0 comments on commit b0aa6f4

Please sign in to comment.