Skip to content

Commit

Permalink
fixed #49
Browse files Browse the repository at this point in the history
  • Loading branch information
vicrucann committed May 10, 2016
1 parent 5e1ee8b commit 332774c
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 11 deletions.
78 changes: 78 additions & 0 deletions src/libSGControls/AddEntityCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,81 @@ void AddStrokeCommand::redo()
m_canvas->updateFrame(m_scene->getCanvasPrevious());
m_scene->updateWidgets();
}

AddCanvasSeparationCommand::AddCanvasSeparationCommand(entity::UserScene *scene, entity::Canvas *source, entity::Canvas *copy, QUndoCommand *parent)
: QUndoCommand(parent)
, m_scene(scene)
, m_source(source)
, m_target(new entity::Canvas)
, m_entities(0)
{
m_target->initializeSG();
m_target->setName(copy->getName());
m_target->setMatrixRotation(copy->getMatrixRotation());
m_target->setMatrixTranslation(copy->getMatrixTranslation());

this->setText(QObject::tr("Separate to canvas %1") .arg(QString(m_target->getName().c_str())));
for (size_t i=0; i<copy->getGeodeData()->getNumChildren(); ++i){
entity::Entity2D* ent = dynamic_cast<entity::Entity2D*>(copy->getGeodeData()->getDrawable(i));
if (!ent) continue;
m_entities.push_back(ent);
}
if (m_entities.size() != m_target->getGeodeData()->getNumChildren())
outErrMsg("AddCanvasSeparationCommand: failed to initialize entities");
}

void AddCanvasSeparationCommand::undo()
{
// make sure current/previous rules hold
if (m_target == m_scene->getCanvasCurrent())
m_scene->setCanvasCurrent(m_scene->getCanvasPrevious());
if (m_target == m_scene->getCanvasPrevious() ||
m_scene->getCanvasCurrent() == m_scene->getCanvasPrevious()){
for (unsigned int i = 0; i < m_scene->getNumChildren(); ++i){
entity::Canvas* cnvi = dynamic_cast<entity::Canvas*>( m_scene->getChild(i));
if (cnvi != NULL && cnvi != m_scene->getCanvasCurrent() && cnvi != m_target){
m_scene->setCanvasPrevious(cnvi);
break;
}
}
}

// move entities to source, remove from target
this->moveEntities(m_target.get(), m_source.get());

// delete target
emit m_scene->canvasRemoved(m_scene->getCanvasIndex(m_target.get()));
m_target->unselectAll();
m_scene->removeChild(m_target);
if (m_scene->getCanvasCurrent()) m_scene->getCanvasCurrent()->updateFrame(0);
m_scene->updateWidgets();
}

void AddCanvasSeparationCommand::redo()
{
emit m_scene->canvasAdded(m_target->getName());

// add entities to target, remove from source
this->moveEntities(m_source.get(), m_target.get());

// add target to scene graph
m_scene->addChild(m_target);
m_scene->setCanvasCurrent(m_target);
m_scene->updateWidgets();
}

void AddCanvasSeparationCommand::moveEntities(entity::Canvas *from, entity::Canvas *to)
{
if (!from || !to) return;

for (size_t i=0; i<m_entities.size(); ++i){
entity::Entity2D* entity = m_entities.at(i);
if (!entity) continue;
if (!to->getGeodeData()->addDrawable(entity))
outErrMsg("AddCanvasSeparationCommand: could not add entity to the target");
if (!from->getGeodeData()->removeDrawable(entity))
outErrMsg("AddCanvasSeparationCommand: could not remove entity from the source");
}
to->updateFrame(0);
from->updateFrame(0);
}
18 changes: 18 additions & 0 deletions src/libSGControls/AddEntityCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ class AddCanvasCommand : public QUndoCommand
osg::ref_ptr<entity::Canvas> m_canvas;
};

class AddCanvasSeparationCommand : public QUndoCommand
{
public:
AddCanvasSeparationCommand(entity::UserScene* scene, entity::Canvas* source, entity::Canvas* copy,
QUndoCommand* parent = 0);

void undo() Q_DECL_OVERRIDE;
void redo() Q_DECL_OVERRIDE;

private:
void moveEntities(entity::Canvas* from, entity::Canvas* to);

osg::observer_ptr<entity::UserScene> m_scene;
osg::observer_ptr<entity::Canvas> m_source;
osg::ref_ptr<entity::Canvas> m_target;
std::vector<entity::Entity2D*> m_entities;
};

class AddPhotoCommand : public QUndoCommand
{
public:
Expand Down
6 changes: 4 additions & 2 deletions src/libSGControls/EventHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,6 @@ void EventHandler::doCanvasSeparate(const osgGA::GUIEventAdapter &ea, osgGA::GUI
|| (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton()==osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
))
return;
if (m_scene->getCanvasCurrent()->getStrokesSelectedSize() == 0)
return;

osg::Vec3f XC = osg::Vec3f(0.f,0.f,0.f);
switch (ea.getEventType()){
Expand All @@ -421,6 +419,7 @@ void EventHandler::doCanvasSeparate(const osgGA::GUIEventAdapter &ea, osgGA::GUI
if (!this->getRaytraceNormalProjection(ea,aa,XC))
this->finishAll();
m_scene->editCanvasSeparate(XC, dureu::EVENT_RELEASED);
m_glWidget->setMouseMode(dureu::SELECT_ENTITY);
break;
case osgGA::GUIEventAdapter::DRAG:
if (!this->getRaytraceNormalProjection(ea,aa,XC))
Expand Down Expand Up @@ -822,6 +821,9 @@ void EventHandler::finishAll()
case dureu::CREATE_CANVASCLONE:
m_scene->editCanvasClone(osg::Vec3f(0,0,0), dureu::EVENT_OFF);
break;
case dureu::CREATE_CANVASSEPARATE:
m_scene->editCanvasClone(osg::Vec3f(0,0,0), dureu::EVENT_OFF);
break;
case dureu::ENTITY_MOVE:
m_scene->editStrokesMove(0,0, dureu::EVENT_OFF);
break;
Expand Down
35 changes: 34 additions & 1 deletion src/libSGEntities/Canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ entity::Canvas *entity::Canvas::clone() const
switch(entcopy->getEntityType()){
case dureu::ENTITY_STROKE:
{
entity::Stroke* stroke = dynamic_cast<entity::Stroke*>(m_geodeData->getChild(i));
entity::Stroke* stroke = dynamic_cast<entity::Stroke*>(entcopy);
if (stroke){
entity::Stroke* si = new entity::Stroke(*stroke, osg::CopyOp::DEEP_COPY_ALL);
if (si){
Expand All @@ -590,6 +590,39 @@ entity::Canvas *entity::Canvas::clone() const
return clone.release();
}

entity::Canvas *entity::Canvas::separate()
{
osg::ref_ptr<entity::Canvas> clone = new Canvas;
if (!clone.get()) return NULL;
clone->initializeSG();
clone->setMatrixRotation(this->getMatrixRotation());
clone->setMatrixTranslation(this->getMatrixTranslation());
clone->setName(this->getName());

for (size_t i=0; i<(size_t)m_selectedGroup.getSize(); ++i){
entity::Entity2D* entcopy = m_selectedGroup.getEntity(i);;
if (!entcopy) continue;
switch(entcopy->getEntityType()){
case dureu::ENTITY_STROKE:{
// copy the stroke
entity::Stroke* stroke = dynamic_cast<entity::Stroke*>(entcopy);
if (stroke){
if (!clone->getGeodeData()->addDrawable(stroke))
outErrMsg("canvas separate: could not copy stroke");
}
break;
}
case dureu::ENTITY_PHOTO:
break;
default:
break;
}
}
clone->updateFrame();

return clone.release();
}

entity::Canvas::~Canvas()
{
}
Expand Down
1 change: 1 addition & 0 deletions src/libSGEntities/Canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class Canvas : public osg::Group {
osg::Plane getPlane() const;
osg::MatrixTransform* getMatrixTransform() const;
entity::Canvas* clone() const;
entity::Canvas* separate();

osg::Node* getTool(const std::string& name);
entity::FrameTool* getToolFrame() const;
Expand Down
56 changes: 50 additions & 6 deletions src/libSGEntities/UserScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,12 +615,12 @@ void entity::UserScene::editCanvasSeparate(QUndoStack *stack, const osg::Vec3f &
this->canvasSeparateAppend(translate);
break;
case dureu::EVENT_DRAGGED:
if (!this->canvasSeparateValid())
if (!this->canvasCloneValid())
this->canvasSeparateStart();
this->canvasSeparateAppend(translate);
break;
case dureu::EVENT_RELEASED:
if (!this->canvasSeparateValid())
if (!this->canvasCloneValid())
break;
this->canvasSeparateAppend(translate);
this->canvasSeparateFinish(stack);
Expand Down Expand Up @@ -1467,22 +1467,66 @@ bool entity::UserScene::canvasCloneValid() const

void entity::UserScene::canvasSeparateStart()
{
/* if the canvas is hidden, show it all so that user could see where they sketch */
if (!m_canvasCurrent->getVisibilityData())
m_canvasCurrent->setVisibilityAll(true);

entity::Canvas* cnv = m_canvasCurrent->separate();
cnv->setName(this->getCanvasName());
if (!cnv){
outErrMsg("canvasCloneStart: could not clone the canvas, ptr is NULL");
return;
}
m_canvasClone = cnv;

// now clone contains all the strokes needed
m_canvasCurrent->unselectAll();

if (!this->addChild(m_canvasClone.get())){
outErrMsg("canvasCloneStart: could not add clone as a child");
return;
}

/* have to set the clone as current so that to calculate offset correctly */
if (!this->setCanvasCurrent(m_canvasClone.get())){
outErrMsg("canvasCloneStart: could not set clone as current");
this->removeChild(m_canvasClone.get());
m_canvasClone = 0;
return;
}
}

void entity::UserScene::canvasSeparateAppend(const osg::Vec3f &t)
{
if (!this->canvasCloneValid()){
outErrMsg("canvasCloneAppend: clone is not valid");
return;
}

/* clone is also current */
m_canvasCurrent->translate(osg::Matrix::translate(t.x(), t.y(), t.z()));
this->updateWidgets();
}

void entity::UserScene::canvasSeparateFinish(QUndoStack *stack)
{
if (!this->canvasCloneValid()){
outErrMsg("canvasCloneFinish: clone is not valid");
return;
}

}
this->setCanvasCurrent(m_canvasPrevious.get());

bool entity::UserScene::canvasSeparateValid() const
{
return m_canvasClone.get();
AddCanvasSeparationCommand* cmd = new AddCanvasSeparationCommand(this, m_canvasCurrent.get(),
m_canvasClone.get());

this->removeChild(m_canvasClone.get());
m_canvasClone = 0;
if (!cmd){
outErrMsg("canvasCloneFinish: could not allocated AddCanvasCommand");
return;
}
stack->push(cmd);
}

void entity::UserScene::canvasRotateStart()
Expand Down
3 changes: 1 addition & 2 deletions src/libSGEntities/UserScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ public slots:
void canvasSeparateStart();
void canvasSeparateAppend(const osg::Vec3f& t);
void canvasSeparateFinish(QUndoStack* stack);
bool canvasSeparateValid() const;

void canvasRotateStart();
void canvasRotateAppend(const osg::Quat& r, const osg::Vec3f& center3d);
Expand All @@ -180,7 +179,7 @@ public slots:
osg::observer_ptr<entity::Canvas> m_canvasPrevious;
osg::observer_ptr<entity::Canvas> m_canvasSelected;
osg::observer_ptr<entity::Canvas> m_canvasTarget; /* for push operations */
osg::observer_ptr<entity::Canvas> m_canvasClone; /* for clone current canvas */
osg::ref_ptr<entity::Canvas> m_canvasClone; /* for clone current canvas */

osg::Vec3f m_deltaT; /* for edit operations: translate */
osg::Quat m_deltaR; /* for edit operation: rotate */
Expand Down

0 comments on commit 332774c

Please sign in to comment.