From c9fbe9cc6a1769fb228dad4e426ebb1df57161a3 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Tue, 18 Apr 2017 01:14:55 +0200 Subject: [PATCH] Sketcher: Constraint Node restructuring to enable independent hidding of driving/driven constraints --- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 166 ++++++++++++++++---- src/Mod/Sketcher/Gui/ViewProviderSketch.h | 4 + 2 files changed, 143 insertions(+), 27 deletions(-) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 37c013e228..d8a49760d5 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -217,6 +217,7 @@ struct EditData { // helper data structures for the constraint rendering std::vector vConstrType; + std::vector vConstrIsDriving; // For each of the combined constraint icons drawn, also create a vector // of bounding boxes and associated constraint IDs, to go from the icon's @@ -1625,9 +1626,22 @@ std::set ViewProviderSketch::detectPreselectionConstr(const SoPickedPoint * SoPath *path = Point->getPath(); SoNode *tail = path->getTail(); SoNode *tailFather = path->getNode(path->getLength()-2); + + SoSwitch *drivingsw = static_cast(edit->constrGroup->getChild(0)); + SoSwitch *drivensw = static_cast(edit->constrGroup->getChild(1)); + + int numconstrchildren = drivingsw->getNumChildren() + drivensw->getNumChildren(); - for (int i=0; i < edit->constrGroup->getNumChildren(); ++i) - if (edit->constrGroup->getChild(i) == tailFather) { + for (int i=0; i < numconstrchildren; ++i) { + + SoSeparator *s; + + if(constrId2ToIsDriving[i]) + s = static_cast(drivingsw->getChild(constrId2ToIndex[i])); + else + s = static_cast(drivensw->getChild(constrId2ToIndex[i])); + + if (s == tailFather) { SoSeparator *sep = static_cast(tailFather); if(sep->getNumChildren() > CONSTRAINT_SEPARATOR_INDEX_FIRST_CONSTRAINTID) { SoInfo *constrIds = NULL; @@ -1678,6 +1692,7 @@ std::set ViewProviderSketch::detectPreselectionConstr(const SoPickedPoint * break; } + } return constrIndices; } @@ -1696,7 +1711,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, //Base::Console().Log("Point pick\n"); SoPath *path = Point->getPath(); SoNode *tail = path->getTail(); - SoNode *tailFather2 = path->getNode(path->getLength()-3); + SoNode *tailFather2 = path->getNode(path->getLength()-4); // checking for a hit in the points if (tail == edit->PointSet) { @@ -1725,10 +1740,10 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, CrossIndex = 1 + static_cast(cross_detail)->getLineIndex(); } } else { - // checking if a constraint is hit + // checking if a constraint is hit if (tailFather2 == edit->constrGroup) constrIndices = detectPreselectionConstr(Point, viewer, cursorPos); - } + } } if (PtIndex != -1 && PtIndex != edit->PreselectPoint) { // if a new point is hit @@ -1885,10 +1900,21 @@ void ViewProviderSketch::centerSelection() SoGroup* group = new SoGroup(); group->ref(); + + SoSwitch *drivingsw = static_cast(edit->constrGroup->getChild(0)); + SoSwitch *drivensw = static_cast(edit->constrGroup->getChild(1)); + + int numconstrchildren = drivingsw->getNumChildren() + drivensw->getNumChildren(); - for (int i=0; i < edit->constrGroup->getNumChildren(); i++) { + for (int i=0; i < numconstrchildren; i++) { if (edit->SelConstraintSet.find(i) != edit->SelConstraintSet.end()) { - SoSeparator *sep = dynamic_cast(edit->constrGroup->getChild(i)); + SoSeparator *sep; + + if(constrId2ToIsDriving[i]) + sep = static_cast(drivingsw->getChild(constrId2ToIndex[i])); + else + sep = static_cast(drivensw->getChild(constrId2ToIndex[i])); + if (sep) group->addChild(sep); } @@ -2552,9 +2578,18 @@ void ViewProviderSketch::updateColor(void) else crosscolor[1] = CrossColorV; + SoSwitch *drivingsw = static_cast(edit->constrGroup->getChild(0)); + SoSwitch *drivensw = static_cast(edit->constrGroup->getChild(1)); + + int numconstrchildren = drivingsw->getNumChildren() + drivensw->getNumChildren(); // colors of the constraints - for (int i=0; i < edit->constrGroup->getNumChildren(); i++) { - SoSeparator *s = static_cast(edit->constrGroup->getChild(i)); + for (int i=0; i < numconstrchildren; i++) { + SoSeparator *s; + + if(constrId2ToIsDriving[i]) + s = static_cast(drivingsw->getChild(constrId2ToIndex[i])); + else + s = static_cast(drivensw->getChild(constrId2ToIndex[i])); // Check Constraint Type Sketcher::Constraint* constraint = getSketchObject()->Constraints.getValues()[i]; @@ -2747,6 +2782,9 @@ void ViewProviderSketch::drawConstraintIcons() int constrId = 0; std::vector iconQueue; + + SoSwitch *drivingsw = static_cast(edit->constrGroup->getChild(0)); + SoSwitch *drivensw = static_cast(edit->constrGroup->getChild(1)); for (std::vector::const_iterator it=constraints.begin(); it != constraints.end(); ++it, ++constrId) { @@ -2785,8 +2823,12 @@ void ViewProviderSketch::drawConstraintIcons() break; } - // Find the Constraint Icon SoImage Node - SoSeparator *sep = static_cast(edit->constrGroup->getChild(constrId)); + SoSeparator *sep; + + if(constrId2ToIsDriving[constrId]) + sep = static_cast(drivingsw->getChild(constrId2ToIndex[constrId])); + else + sep = static_cast(drivensw->getChild(constrId2ToIndex[constrId])); SbVec3f absPos; // Somewhat hacky - we use SoZoomTranslations for most types of icon, @@ -3939,14 +3981,20 @@ Restart: // check if a new constraint arrived if (constrlist.size() != edit->vConstrType.size()) rebuildConstraintsVisual(); - assert(int(constrlist.size()) == edit->constrGroup->getNumChildren()); - assert(int(edit->vConstrType.size()) == edit->constrGroup->getNumChildren()); + + SoSwitch *drivingsw = static_cast(edit->constrGroup->getChild(0)); + SoSwitch *drivensw = static_cast(edit->constrGroup->getChild(1)); + + int numconstrchildren = drivingsw->getNumChildren() + drivensw->getNumChildren(); + + assert(int(constrlist.size()) == numconstrchildren); + assert(int(edit->vConstrType.size()) == numconstrchildren); // go through the constraints and update the position i = 0; for (std::vector::const_iterator it=constrlist.begin(); it != constrlist.end(); ++it, i++) { - // check if the type has changed - if ((*it)->Type != edit->vConstrType[i]) { + // check if the type or driving status has changed + if (((*it)->Type != edit->vConstrType[i]) || ((*it)->isDriving != edit->vConstrIsDriving[i])) { // clearing the type vector will force a rebuild of the visual nodes edit->vConstrType.clear(); //TODO: The 'goto' here is unsafe as it can happen that we cause an endless loop (see bug #0001956). @@ -3954,7 +4002,13 @@ Restart: } try{//because calculateNormalAtPoint, used in there, can throw // root separator for this constraint - SoSeparator *sep = static_cast(edit->constrGroup->getChild(i)); + SoSeparator *sep; + + if((*it)->isDriving) + sep = static_cast(drivingsw->getChild(constrId2ToIndex[i])); + else + sep = static_cast(drivensw->getChild(constrId2ToIndex[i])); + const Constraint *Constr = *it; // distinquish different constraint types to build up @@ -3976,7 +4030,7 @@ Restart: Base::Vector3d dir = (lineSeg->getEndPoint()-lineSeg->getStartPoint()).Normalize(); Base::Vector3d norm(-dir.y,dir.x,0); - Base::Vector3d relpos = seekConstraintPosition(midpos, norm, dir, 2.5, edit->constrGroup->getChild(i)); + Base::Vector3d relpos = seekConstraintPosition(midpos, norm, dir, 2.5, sep); static_cast(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_FIRST_TRANSLATION))->abPos = SbVec3f(midpos.x, midpos.y, zConstr); //Absolute Reference @@ -4071,12 +4125,12 @@ Restart: } - Base::Vector3d relpos1 = seekConstraintPosition(midpos1, norm1, dir1, 2.5, edit->constrGroup->getChild(i)); + Base::Vector3d relpos1 = seekConstraintPosition(midpos1, norm1, dir1, 2.5, sep); static_cast(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_FIRST_TRANSLATION))->abPos = SbVec3f(midpos1.x, midpos1.y, zConstr); static_cast(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_FIRST_TRANSLATION))->translation = SbVec3f(relpos1.x, relpos1.y, 0); if (twoIcons) { - Base::Vector3d relpos2 = seekConstraintPosition(midpos2, norm2, dir2, 2.5, edit->constrGroup->getChild(i)); + Base::Vector3d relpos2 = seekConstraintPosition(midpos2, norm2, dir2, 2.5, sep); Base::Vector3d secondPos = midpos2 - midpos1; static_cast(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_SECOND_TRANSLATION))->abPos = SbVec3f(secondPos.x, secondPos.y, zConstr); @@ -4260,8 +4314,8 @@ Restart: norm2 = Base::Vector3d(-dir2.y,dir2.x,0.); } - Base::Vector3d relpos1 = seekConstraintPosition(midpos1, norm1, dir1, 2.5, edit->constrGroup->getChild(i)); - Base::Vector3d relpos2 = seekConstraintPosition(midpos2, norm2, dir2, 2.5, edit->constrGroup->getChild(i)); + Base::Vector3d relpos1 = seekConstraintPosition(midpos1, norm1, dir1, 2.5, sep); + Base::Vector3d relpos2 = seekConstraintPosition(midpos2, norm2, dir2, 2.5, sep); static_cast(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_FIRST_TRANSLATION))->abPos = SbVec3f(midpos1.x, midpos1.y, zConstr); //Absolute Reference @@ -4384,7 +4438,7 @@ Restart: norm.Normalize(); Base::Vector3d dir = norm; dir.RotateZ(-M_PI/2.0); - relPos = seekConstraintPosition(pos, norm, dir, 2.5, edit->constrGroup->getChild(i)); + relPos = seekConstraintPosition(pos, norm, dir, 2.5, sep); static_cast(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_FIRST_TRANSLATION))->abPos = SbVec3f(pos.x, pos.y, zConstr); //Absolute Reference static_cast(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_FIRST_TRANSLATION))->translation = SbVec3f(relPos.x, relPos.y, 0); } @@ -4405,8 +4459,8 @@ Restart: Base::Vector3d norm1 = Base::Vector3d(-dir1.y,dir1.x,0.f); Base::Vector3d norm2 = Base::Vector3d(-dir2.y,dir2.x,0.f); - Base::Vector3d relpos1 = seekConstraintPosition(midpos1, norm1, dir1, 2.5, edit->constrGroup->getChild(i)); - Base::Vector3d relpos2 = seekConstraintPosition(midpos2, norm2, dir2, 2.5, edit->constrGroup->getChild(i)); + Base::Vector3d relpos1 = seekConstraintPosition(midpos1, norm1, dir1, 2.5, sep); + Base::Vector3d relpos2 = seekConstraintPosition(midpos2, norm2, dir2, 2.5, sep); static_cast(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_FIRST_TRANSLATION))->abPos = SbVec3f(midpos1.x, midpos1.y, zConstr); //Absolute Reference @@ -4731,11 +4785,29 @@ void ViewProviderSketch::rebuildConstraintsVisual(void) // clean up edit->constrGroup->removeAllChildren(); edit->vConstrType.clear(); + edit->vConstrIsDriving.clear(); + constrId2ToIsDriving.clear(); + constrId2ToIndex.clear(); ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); int fontSize = hGrp->GetInt("EditSketcherFontSize", 17); + + ParameterGrp::handle hGrpp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); + + SoSwitch *drivingsw = new SoSwitch(); + SoSwitch *drivensw = new SoSwitch(); + + drivingsw->whichChild = hGrpp->GetBool("DrivingConstraintsVisible", true)?SO_SWITCH_ALL:SO_SWITCH_NONE; + drivensw->whichChild = hGrpp->GetBool("DrivenConstraintsVisible", true)?SO_SWITCH_ALL:SO_SWITCH_NONE; + + drivingsw->ref(); + drivensw->ref(); + + int constrid = 0; + int drivingindex = 0; + int drivenindex = 0; - for (std::vector::const_iterator it=constrlist.begin(); it != constrlist.end(); ++it) { + for (std::vector::const_iterator it=constrlist.begin(); it != constrlist.end(); ++it,constrid++) { // root separator for one constraint SoSeparator *sep = new SoSeparator(); sep->ref(); @@ -4776,8 +4848,22 @@ void ViewProviderSketch::rebuildConstraintsVisual(void) anno->addChild(text); // #define CONSTRAINT_SEPARATOR_INDEX_MATERIAL_OR_DATUMLABEL 0 sep->addChild(text); - edit->constrGroup->addChild(anno); + + if((*it)->isDriving) { + drivingsw->addChild(anno); + constrId2ToIsDriving.insert(std::make_pair(constrid, true)); + constrId2ToIndex.insert(std::make_pair(constrid, drivingindex)); + drivingindex++; + } + else { + drivensw->addChild(anno); + constrId2ToIsDriving.insert(std::make_pair(constrid, false)); + constrId2ToIndex.insert(std::make_pair(constrid, drivenindex)); + drivenindex++; + } + edit->vConstrType.push_back((*it)->Type); + edit->vConstrIsDriving.push_back((*it)->isDriving); // nodes not needed sep->unref(); mat->unref(); @@ -4798,10 +4884,12 @@ void ViewProviderSketch::rebuildConstraintsVisual(void) // remember the type of this constraint node edit->vConstrType.push_back((*it)->Type); + edit->vConstrIsDriving.push_back((*it)->isDriving); } break; case Coincident: // no visual for coincident so far edit->vConstrType.push_back(Coincident); + edit->vConstrIsDriving.push_back((*it)->isDriving); break; case Parallel: case Perpendicular: @@ -4824,6 +4912,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void) // remember the type of this constraint node edit->vConstrType.push_back((*it)->Type); + edit->vConstrIsDriving.push_back((*it)->isDriving); } break; case PointOnObject: @@ -4854,6 +4943,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void) } edit->vConstrType.push_back((*it)->Type); + edit->vConstrIsDriving.push_back((*it)->isDriving); } break; case Symmetric: @@ -4873,22 +4963,44 @@ void ViewProviderSketch::rebuildConstraintsVisual(void) sep->addChild(new SoInfo()); edit->vConstrType.push_back((*it)->Type); + edit->vConstrIsDriving.push_back((*it)->isDriving); } break; case InternalAlignment: { edit->vConstrType.push_back((*it)->Type); + edit->vConstrIsDriving.push_back((*it)->isDriving); } break; default: edit->vConstrType.push_back((*it)->Type); + edit->vConstrIsDriving.push_back((*it)->isDriving); } - edit->constrGroup->addChild(sep); + if((*it)->isDriving) { + drivingsw->addChild(sep); + constrId2ToIsDriving.insert(std::make_pair(constrid, true)); + constrId2ToIndex.insert(std::make_pair(constrid, drivingindex)); + drivingindex++; + } + else { + drivensw->addChild(sep); + constrId2ToIsDriving.insert(std::make_pair(constrid, false)); + constrId2ToIndex.insert(std::make_pair(constrid, drivenindex)); + drivenindex++; + } + + // decrement ref counter again sep->unref(); mat->unref(); } + edit->constrGroup->addChild(drivingsw); + edit->constrGroup->addChild(drivensw); + + drivingsw->unref(); + drivensw->unref(); + } void ViewProviderSketch::drawEdit(const std::vector &EditCurve) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index 4a0985a222..995bdc6186 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -306,6 +306,10 @@ protected: /// Angle to rotate an icon double iconRotation; }; + + // Mapping of constrId to driving, driven and the index therein + std::map constrId2ToIsDriving; + std::map constrId2ToIndex; /// Internal type used for drawing constraint icons typedef std::vector IconQueue;