From ebfbe29d2ff4f44d8f44be627679dc3c84d81f27 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Mon, 26 Dec 2016 22:54:47 +0100 Subject: [PATCH] Sketcher: Restore internal geometry tool refactoring and extended support ========================================================================= - Long felt need of refactoring the code so as not to repeat code already existing in SketchObject. - Refactored code supports preexisting Ellipse and Arc of Ellipse and adds support for Arcs of Hyperbola and Parabola. --- src/Mod/Sketcher/Gui/CommandSketcherTools.cpp | 265 ++++-------------- 1 file changed, 48 insertions(+), 217 deletions(-) diff --git a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp index 0b5ff9adc..e129176bd 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp @@ -762,226 +762,57 @@ void CmdSketcherRestoreInternalAlignmentGeometry::activated(int iMsg) const Part::Geometry *geo = Obj->getGeometry(GeoId); // Only for supported types - if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { - // First we search what has to be restored - bool major=false; - bool minor=false; - bool focus1=false; - bool focus2=false; - - int majorelementindex=-1; - int minorelementindex=-1; - int focus1elementindex=-1; - int focus2elementindex=-1; - - const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); - - for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); - it != vals.end(); ++it) { - if((*it)->Type == Sketcher::InternalAlignment && (*it)->Second == GeoId) - { - switch((*it)->AlignmentType){ - case Sketcher::EllipseMajorDiameter: - major=true; - majorelementindex=(*it)->First; - break; - case Sketcher::EllipseMinorDiameter: - minor=true; - minorelementindex=(*it)->First; - break; - case Sketcher::EllipseFocus1: - focus1=true; - focus1elementindex=(*it)->First; - break; - case Sketcher::EllipseFocus2: - focus2=true; - focus2elementindex=(*it)->First; - break; - default: - break; - } - } - } - - if(major && minor && focus1 && focus2) - { - // Hide unused geometry here - int majorconstraints=0; // number of constraints associated to the geoid of the major axis - int minorconstraints=0; - int focus1constraints=0; - int focus2constraints=0; - - for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); - it != vals.end(); ++it) { - - if((*it)->Second == majorelementindex || (*it)->First == majorelementindex || (*it)->Third == majorelementindex) - majorconstraints++; - else if((*it)->Second == minorelementindex || (*it)->First == minorelementindex || (*it)->Third == minorelementindex) - minorconstraints++; - else if((*it)->Second == focus1elementindex || (*it)->First == focus1elementindex || (*it)->Third == focus1elementindex) - focus1constraints++; - else if((*it)->Second == focus2elementindex || (*it)->First == focus2elementindex || (*it)->Third == focus2elementindex) - focus2constraints++; - } - // those with less than 2 constraints must be removed - if(majorconstraints>=2 && minorconstraints>=2 && focus1constraints>=2 && focus2constraints>=2) - return; // nothing to delete - - App::Document* doc = App::GetApplication().getActiveDocument(); - - if (!doc) return; - - doc->openTransaction("Delete"); - - if(majorconstraints<2) { - ss.str(std::string()); - ss << "Edge" << majorelementindex + 1; - Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str()); - } - - if(minorconstraints<2) { - ss.str(std::string()); - ss << "Edge" << minorelementindex + 1; - Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str()); - } - - if(focus1constraints<2) { - ss.str(std::string()); - int vertex = Obj->getVertexIndexGeoPos(focus1elementindex,Sketcher::start); - if(vertex>-1){ - ss << "Vertex" << vertex + 1; - Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str()); - } - } - - if(focus2constraints<2) { - ss.str(std::string()); - int vertex = Obj->getVertexIndexGeoPos(focus2elementindex,Sketcher::start); - if(vertex>-1){ - ss << "Vertex" << vertex + 1; - Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str()); - } - } - - SketcherGui::ViewProviderSketch* vp = dynamic_cast(getActiveGuiDocument()->getInEdit()); + if( geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || + geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || + geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() || + geo->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() ) { - if (vp) { - std::vector sel = Gui::Selection().getSelectionEx(doc->getName()); - vp->onDelete(sel[0].getSubNames()); - } - - - doc->commitTransaction(); - return; - } - - Gui::Command::openCommand("Expose ellipse internal geometry"); - - int currentgeoid= Obj->getHighestCurveIndex(); - int incrgeo= 0; - - Base::Vector3d center; - double majord; - double minord; - Base::Vector3d majdir; - - if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId()){ - const Part::GeomEllipse *ellipse = static_cast(geo); - - center=ellipse->getCenter(); - majord=ellipse->getMajorRadius(); - minord=ellipse->getMinorRadius(); - majdir=ellipse->getMajorAxisDir(); - } - else { - const Part::GeomArcOfEllipse *aoe = static_cast(geo); - - center=aoe->getCenter(); - majord=aoe->getMajorRadius(); - minord=aoe->getMinorRadius(); - majdir=aoe->getMajorAxisDir(); - } + int currentgeoid = Obj->getHighestCurveIndex(); - Base::Vector3d mindir = Base::Vector3d(-majdir.y, majdir.x, 0.0); - - Base::Vector3d majorpositiveend = center + majord * majdir; - Base::Vector3d majornegativeend = center - majord * majdir; - Base::Vector3d minorpositiveend = center + minord * mindir; - Base::Vector3d minornegativeend = center - minord * mindir; - - double df= sqrt(majord*majord-minord*minord); - - Base::Vector3d focus1P = center + df * majdir; - Base::Vector3d focus2P = center - df * majdir; - - try{ - if(!major) - { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)),True)", - Obj->getNameInDocument(), - majorpositiveend.x,majorpositiveend.y,majornegativeend.x,majornegativeend.y); // create line for major axis - - Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMajorDiameter',%d,%d)) ", - selection[0].getFeatName(),currentgeoid+incrgeo+1,GeoId); // constrain major axis - incrgeo++; - } - if(!minor) - { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)),True)", - Obj->getNameInDocument(), - minorpositiveend.x,minorpositiveend.y,minornegativeend.x,minornegativeend.y); // create line for minor axis - - Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMinorDiameter',%d,%d)) ", - selection[0].getFeatName(),currentgeoid+incrgeo+1,GeoId); // constrain minor axis - incrgeo++; - } - if(!focus1) - { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Point(App.Vector(%f,%f,0)))", - Obj->getNameInDocument(), - focus1P.x,focus1P.y); - - Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus1',%d,%d,%d)) ", - selection[0].getFeatName(),currentgeoid+incrgeo+1,Sketcher::start,GeoId); // constrain major axis - incrgeo++; - } - if(!focus2) - { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Point(App.Vector(%f,%f,0)))", - Obj->getNameInDocument(), - focus2P.x,focus2P.y); - - Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus2',%d,%d,%d)) ", - Obj->getNameInDocument(),currentgeoid+incrgeo+1,Sketcher::start,GeoId); // constrain major axis - } - - Gui::Command::commitCommand(); - - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); - bool autoRecompute = hGrp->GetBool("AutoRecompute",false); - - if(autoRecompute) - Gui::Command::updateActive(); - - } - catch (const Base::Exception& e) { - Base::Console().Error("%s\n", e.what()); - Gui::Command::abortCommand(); - - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); - bool autoRecompute = hGrp->GetBool("AutoRecompute",false); - - if(autoRecompute) - Gui::Command::updateActive(); - } - - } // if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) - else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Currently internal geometry is only supported for ellipse and arc of ellipse. The last selected element must be an ellipse or an arc of ellipse.")); - } + try { + Gui::Command::openCommand("Exposing Internal Geometry"); - } + Gui::Command::doCommand(Gui::Command::Doc, + "App.ActiveDocument.%s.ExposeInternalGeometry(%d)", + Obj->getNameInDocument(), + GeoId); + + int aftergeoid = Obj->getHighestCurveIndex(); + + if(aftergeoid == currentgeoid) { // if we did not expose anything, deleteunused + Gui::Command::doCommand(Gui::Command::Doc, + "App.ActiveDocument.%s.DeleteUnusedInternalGeometry(%d)", + Obj->getNameInDocument(), + GeoId); + } + + } + catch (const Base::Exception& e) { + Base::Console().Error("%s\n", e.what()); + Gui::Command::abortCommand(); + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); + bool autoRecompute = hGrp->GetBool("AutoRecompute",false); + + if(autoRecompute) + Gui::Command::updateActive(); + else + static_cast(Obj)->solve(); + + return; + } + + Gui::Command::commitCommand(); + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); + bool autoRecompute = hGrp->GetBool("AutoRecompute",false); + + if(autoRecompute) + Gui::Command::updateActive(); + else + static_cast(Obj)->solve(); + } + } } }