void CmdSketcherConnect::activated(int iMsg) { // get the selection std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx(); // only one sketch with its subelements are allowed to be selected if (selection.size() != 1) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select at least two edges from the sketch.")); return; } // get the needed lists and objects const std::vector<std::string> &SubNames = selection[0].getSubNames(); if (SubNames.size() < 2) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select at least two edges from the sketch.")); return; } Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject()); // undo command open openCommand("add coincident constraint"); // go through the selected subelements for (unsigned int i=0; i<(SubNames.size()-1); i++ ) { // only handle edges if (SubNames[i].size() > 4 && SubNames[i].substr(0,4) == "Edge" && SubNames[i+1].size() > 4 && SubNames[i+1].substr(0,4) == "Edge" ) { int GeoId1 = std::atoi(SubNames[i].substr(4,4000).c_str()) - 1; int GeoId2 = std::atoi(SubNames[i+1].substr(4,4000).c_str()) - 1; const Part::Geometry *geo1 = Obj->getGeometry(GeoId1); const Part::Geometry *geo2 = Obj->getGeometry(GeoId2); if ((geo1->getTypeId() != Part::GeomLineSegment::getClassTypeId() && geo1->getTypeId() != Part::GeomArcOfCircle::getClassTypeId()) || (geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId() && geo2->getTypeId() != Part::GeomArcOfCircle::getClassTypeId())) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), QObject::tr("One selected edge is not connectable")); abortCommand(); return; } Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%d,%d,%d,%d)) ", selection[0].getFeatName(),GeoId1,Sketcher::end,GeoId2,Sketcher::start); } } // finish the transaction and update commitCommand(); updateActive(); // clear the selection (convenience) getSelection().clearSelection(); }
void CmdSketcherIncreaseDegree::activated(int iMsg) { Q_UNUSED(iMsg); // get the selection std::vector<Gui::SelectionObject> selection; selection = getSelection().getSelectionEx(0, Sketcher::SketchObject::getClassTypeId()); // only one sketch with its subelements are allowed to be selected if (selection.size() != 1) { return; } // get the needed lists and objects const std::vector<std::string> &SubNames = selection[0].getSubNames(); Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject()); openCommand("Increase degree"); bool ignored=false; for (unsigned int i=0; i<SubNames.size(); i++ ) { // only handle edges if (SubNames[i].size() > 4 && SubNames[i].substr(0,4) == "Edge") { int GeoId = std::atoi(SubNames[i].substr(4,4000).c_str()) - 1; const Part::Geometry * geo = Obj->getGeometry(GeoId); if (geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) { Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.increaseBSplineDegree(%d) ", selection[0].getFeatName(),GeoId); // add new control points Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.exposeInternalGeometry(%d)", selection[0].getFeatName(), GeoId); } else { ignored=true; } } } if(ignored) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("At least one of the selected objects was not a B-Spline and was ignored.")); } commitCommand(); tryAutoRecomputeIfNotSolve(Obj); getSelection().clearSelection(); }
void DrawSketchHandler::createAutoConstraints(const std::vector<AutoConstraint> &autoConstrs, int geoId1, Sketcher::PointPos posId1) { if (!sketchgui->Autoconstraints.getValue()) return; // If Autoconstraints property is not set quit if (autoConstrs.size() > 0) { // Open the Command Gui::Command::openCommand("Add auto constraints"); // Iterate through constraints std::vector<AutoConstraint>::const_iterator it = autoConstrs.begin(); for (; it != autoConstrs.end(); ++it) { switch (it->Type) { case Sketcher::Coincident: { if (posId1 == Sketcher::none) continue; // If the auto constraint has a point create a coincident otherwise it is an edge on a point Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,%i,%i,%i)) " ,sketchgui->getObject()->getNameInDocument() ,geoId1, posId1, it->GeoId, it->PosId ); } break; case Sketcher::PointOnObject: { int geoId2 = it->GeoId; Sketcher::PointPos posId2 = it->PosId; if (posId1 == Sketcher::none) { // Auto constraining an edge so swap parameters std::swap(geoId1,geoId2); std::swap(posId1,posId2); } Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%i,%i,%i)) " ,sketchgui->getObject()->getNameInDocument() ,geoId1, posId1, geoId2 ); } break; case Sketcher::Horizontal: { bool start_external; bool mid_external; bool end_external; static_cast<Sketcher::SketchObject*>((sketchgui->getObject()))->isCoincidentWithExternalGeometry(geoId1, start_external, mid_external, end_external); if( !(start_external && end_external) ) { Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Horizontal',%i)) " ,sketchgui->getObject()->getNameInDocument() ,geoId1 ); } } break; case Sketcher::Vertical: { bool start_external; bool mid_external; bool end_external; static_cast<Sketcher::SketchObject*>((sketchgui->getObject()))->isCoincidentWithExternalGeometry(geoId1, start_external, mid_external, end_external); if( !(start_external && end_external) ) { Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Vertical',%i)) " ,sketchgui->getObject()->getNameInDocument() ,geoId1 ); } } break; case Sketcher::Tangent: { Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(sketchgui->getObject()); const Part::Geometry *geom1 = Obj->getGeometry(geoId1); const Part::Geometry *geom2 = Obj->getGeometry(it->GeoId); int geoId2 = it->GeoId; // ellipse tangency support using construction elements (lines) if( geom1 && geom2 && ( geom1->getTypeId() == Part::GeomEllipse::getClassTypeId() || geom2->getTypeId() == Part::GeomEllipse::getClassTypeId() )){ if(geom1->getTypeId() != Part::GeomEllipse::getClassTypeId()) std::swap(geoId1,geoId2); // geoId1 is the ellipse geom1 = Obj->getGeometry(geoId1); geom2 = Obj->getGeometry(geoId2); if( geom2->getTypeId() == Part::GeomEllipse::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || geom2->getTypeId() == Part::GeomCircle::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ) { // in all these cases an intermediate element is needed makeTangentToEllipseviaNewPoint(Obj,geom1,geom2,geoId1,geoId2); return; } } // arc of ellipse tangency support using external elements if( geom1 && geom2 && ( geom1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() )){ if(geom1->getTypeId() != Part::GeomArcOfEllipse::getClassTypeId()) std::swap(geoId1,geoId2); // geoId1 is the arc of ellipse geom1 = Obj->getGeometry(geoId1); geom2 = Obj->getGeometry(geoId2); if( geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || geom2->getTypeId() == Part::GeomCircle::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ) { // in all these cases an intermediate element is needed makeTangentToArcOfEllipseviaNewPoint(Obj,geom1,geom2,geoId1,geoId2); return; } } Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%i, %i)) " ,sketchgui->getObject()->getNameInDocument() ,geoId1, it->GeoId ); } break; default: break; } Gui::Command::commitCommand(); //Gui::Command::updateActive(); // There is already an recompute in each command creation, this is redundant. } } }
void CmdSketcherDecreaseKnotMultiplicity::activated(int iMsg) { Q_UNUSED(iMsg); #if OCC_VERSION_HEX < 0x060900 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong OCE/OCC version"), QObject::tr("This version of OCE/OCC does not support knot operation. You need 6.9.0 or higher")); return; #endif // get the selection std::vector<Gui::SelectionObject> selection; selection = getSelection().getSelectionEx(0, Sketcher::SketchObject::getClassTypeId()); // only one sketch with its subelements are allowed to be selected if (selection.size() != 1) { return; } // get the needed lists and objects const std::vector<std::string> &SubNames = selection[0].getSubNames(); if(SubNames.size()>1) { // Check that only one object is selected, as we need only one object to get the new GeoId after multiplicity change QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("The selection comprises more than one item. Please select just one knot.")); return; } Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject()); openCommand("Decrease knot multiplicity"); bool applied = false; bool notaknot = true; boost::uuids::uuid bsplinetag; int GeoId; Sketcher::PointPos PosId; getIdsFromName(SubNames[0], Obj, GeoId, PosId); if(isSimpleVertex(Obj, GeoId, PosId)) { 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)->First == GeoId && (*it)->AlignmentType == Sketcher::BSplineKnotPoint) { bsplinetag = Obj->getGeometry((*it)->Second)->getTag(); notaknot = false; try { Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.modifyBSplineKnotMultiplicity(%d,%d,%d) ", selection[0].getFeatName(),(*it)->Second, (*it)->InternalAlignmentIndex + 1, -1); applied = true; // Warning: GeoId list might have changed as the consequence of deleting pole circles and // particularly B-spline GeoID might have changed. } catch (const Base::Exception& e) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Error"), QObject::tr(getStrippedPythonExceptionString(e).c_str())); getSelection().clearSelection(); } break; // we have already found our knot. } } } if(notaknot){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("None of the selected elements is a knot of a B-spline")); } if(applied) { // find new geoid for B-spline as GeoId might have changed const std::vector< Part::Geometry * > &gvals = Obj->getInternalGeometry(); int ngeoid = 0; bool ngfound = false; for (std::vector<Part::Geometry *>::const_iterator geo = gvals.begin(); geo != gvals.end(); geo++, ngeoid++) { if ((*geo) && (*geo)->getTag() == bsplinetag) { ngfound = true; break; } } if(ngfound) { try { // add internalalignment for new pole Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.exposeInternalGeometry(%d)", selection[0].getFeatName(), ngeoid); } catch (const Base::Exception& e) { Base::Console().Error("%s\n", e.what()); getSelection().clearSelection(); } } } if(!applied) { abortCommand(); } else { commitCommand(); } tryAutoRecomputeIfNotSolve(Obj); getSelection().clearSelection(); }