00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <QMessageBox>
00027 #endif
00028
00029 #include <Gui/Application.h>
00030 #include <Gui/Document.h>
00031 #include <Gui/Selection.h>
00032 #include <Gui/Command.h>
00033 #include <Gui/MainWindow.h>
00034 #include <Gui/DlgEditFileIncludeProptertyExternal.h>
00035
00036 #include <Mod/Part/App/Geometry.h>
00037 #include <Mod/Sketcher/App/SketchObject.h>
00038
00039 #include "ViewProviderSketch.h"
00040
00041 using namespace std;
00042 using namespace SketcherGui;
00043 using namespace Sketcher;
00044
00045 bool isCreateConstraintActive(Gui::Document *doc)
00046 {
00047 if (doc)
00048
00049 if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId()))
00050 if (dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit())
00051 ->getSketchMode() == ViewProviderSketch::STATUS_NONE)
00052 if (Gui::Selection().countObjectsOfType(Sketcher::SketchObject::getClassTypeId()) > 0)
00053 return true;
00054 return false;
00055 }
00056
00057 void updateDatumDistance(Gui::Document *doc, Constraint *constr)
00058 {
00059 float sf = 1.f;
00060 if (doc && doc->getInEdit() && doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) {
00061 SketcherGui::ViewProviderSketch *vp = dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
00062 sf = vp->getScaleFactor();
00063
00064 constr->LabelDistance = 2. * sf;
00065 vp->draw();
00066 }
00067 }
00068
00069 namespace SketcherGui {
00070
00071 struct SketchSelection{
00072 enum GeoType {
00073 Point,
00074 Line,
00075 Circle,
00076 Arc
00077 };
00078 int setUp(void);
00079 struct SketchSelectionItem {
00080 GeoType type;
00081 int GeoId;
00082 bool Extern;
00083 };
00084 std::list<SketchSelectionItem> Items;
00085 QString ErrorMsg;
00086 };
00087
00088 int SketchSelection::setUp(void)
00089 {
00090 std::vector<Gui::SelectionObject> selection = Gui::Selection().getSelectionEx();
00091
00092 Sketcher::SketchObject *SketchObj=0;
00093 Part::Feature *SupportObj=0;
00094 std::vector<std::string> SketchSubNames;
00095 std::vector<std::string> SupportSubNames;
00096
00097
00098 if (selection.size() == 1) {
00099
00100 if(!selection[0].getObject()->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId()))
00101 {
00102 ErrorMsg = QObject::tr("Only sketch and its support is allowed to select");
00103 return -1;
00104 }
00105
00106 SketchObj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00107 SketchSubNames = selection[0].getSubNames();
00108 } else if(selection.size() == 2) {
00109 if(selection[0].getObject()->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())){
00110 SketchObj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00111
00112 if(selection[1].getObject() != SketchObj->Support.getValue()){
00113 ErrorMsg = QObject::tr("Only sketch and its support is allowed to select");
00114 return-1;
00115 }
00116
00117 assert(selection[1].getObject()->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()));
00118 SupportObj = dynamic_cast<Part::Feature*>(selection[1].getObject());
00119 SketchSubNames = selection[0].getSubNames();
00120 SupportSubNames = selection[1].getSubNames();
00121
00122 } else if (selection[1].getObject()->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
00123 SketchObj = dynamic_cast<Sketcher::SketchObject*>(selection[1].getObject());
00124
00125 if(selection[0].getObject() != SketchObj->Support.getValue()){
00126 ErrorMsg = QObject::tr("Only sketch and its support is allowed to select");
00127 return -1;
00128 }
00129
00130 assert(selection[0].getObject()->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()));
00131 SupportObj = dynamic_cast<Part::Feature*>(selection[0].getObject());
00132 SketchSubNames = selection[1].getSubNames();
00133 SupportSubNames = selection[0].getSubNames();
00134
00135 } else {
00136 ErrorMsg = QObject::tr("One of the selected has to be on the sketch");
00137 return -1;
00138 }
00139 }
00140
00141
00142 for ( std::vector<std::string>::const_iterator it= SketchSubNames.begin();it!=SketchSubNames.end();++it){
00143
00144
00145 }
00146
00147
00148 return Items.size();
00149 }
00150
00151 }
00152
00153
00154
00155
00156 DEF_STD_CMD_A(CmdSketcherConstrainHorizontal);
00157
00158 CmdSketcherConstrainHorizontal::CmdSketcherConstrainHorizontal()
00159 :Command("Sketcher_ConstrainHorizontal")
00160 {
00161 sAppModule = "Sketcher";
00162 sGroup = QT_TR_NOOP("Sketcher");
00163 sMenuText = QT_TR_NOOP("Constrain horizontally");
00164 sToolTipText = QT_TR_NOOP("Create a horizontal constraint on the selected item");
00165 sWhatsThis = sToolTipText;
00166 sStatusTip = sToolTipText;
00167 sPixmap = "Constraint_Horizontal";
00168 sAccel = "H";
00169 eType = ForEdit;
00170 }
00171
00172 void CmdSketcherConstrainHorizontal::activated(int iMsg)
00173 {
00174
00175 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
00176
00177
00178 if (selection.size() != 1) {
00179 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00180 QObject::tr("Select an edge from the sketch."));
00181 return;
00182 }
00183
00184
00185 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00186 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00187 const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
00188 const std::vector<Part::Geometry *> &geomlist = Obj->Geometry.getValues();
00189
00190 std::vector<int> ids;
00191
00192 for(std::vector<std::string>::const_iterator it=SubNames.begin();it!=SubNames.end();++it){
00193
00194 if (it->size() > 4 && it->substr(0,4) == "Edge") {
00195 int index=std::atoi(it->substr(4,4000).c_str());
00196
00197 Part::Geometry *geo = geomlist[index];
00198 if (geo->getTypeId() != Part::GeomLineSegment::getClassTypeId()) {
00199 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"),
00200 QObject::tr("The selected edge is not a line segment"));
00201 return;
00202 }
00203
00204
00205 for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin();
00206 it != vals.end(); ++it) {
00207 if ((*it)->Type == Sketcher::Horizontal && (*it)->First == index){
00208 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Double constraint"),
00209 QObject::tr("The selected edge has already a horizontal constraint!"));
00210 return;
00211 }
00212 if ((*it)->Type == Sketcher::Vertical && (*it)->First == index) {
00213 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"),
00214 QObject::tr("The selected edge has already a vertical constraint!"));
00215 return;
00216 }
00217 }
00218 ids.push_back(index);
00219 }
00220 }
00221
00222 openCommand("add horizontal constraint");
00223
00224 for (std::vector<int>::iterator it=ids.begin(); it != ids.end(); it++) {
00225
00226 doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Horizontal',%d)) "
00227 ,selection[0].getFeatName(),*it);
00228 }
00229
00230 commitCommand();
00231 updateActive();
00232
00233
00234 getSelection().clearSelection();
00235 }
00236
00237 bool CmdSketcherConstrainHorizontal::isActive(void)
00238 {
00239 return isCreateConstraintActive( getActiveGuiDocument() );
00240 }
00241
00242
00243 DEF_STD_CMD_A(CmdSketcherConstrainVertical);
00244
00245 CmdSketcherConstrainVertical::CmdSketcherConstrainVertical()
00246 :Command("Sketcher_ConstrainVertical")
00247 {
00248 sAppModule = "Sketcher";
00249 sGroup = QT_TR_NOOP("Sketcher");
00250 sMenuText = QT_TR_NOOP("Constrain vertically");
00251 sToolTipText = QT_TR_NOOP("Create a vertical constraint on the selected item");
00252 sWhatsThis = sToolTipText;
00253 sStatusTip = sToolTipText;
00254 sPixmap = "Constraint_Vertical";
00255 sAccel = "V";
00256 eType = ForEdit;
00257 }
00258
00259 void CmdSketcherConstrainVertical::activated(int iMsg)
00260 {
00261
00262 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
00263
00264
00265 if (selection.size() != 1) {
00266 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00267 QObject::tr("Select an edge from the sketch."));
00268 return;
00269 }
00270
00271
00272 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00273 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00274 const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
00275 const std::vector<Part::Geometry *> &geomlist = Obj->Geometry.getValues();
00276
00277 std::vector<int> ids;
00278
00279
00280 for(std::vector<std::string>::const_iterator it=SubNames.begin();it!=SubNames.end();++it){
00281
00282 if (it->size() > 4 && it->substr(0,4) == "Edge") {
00283 int index=std::atoi(it->substr(4,4000).c_str());
00284
00285 Part::Geometry *geo = geomlist[index];
00286 if (geo->getTypeId() != Part::GeomLineSegment::getClassTypeId()) {
00287 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"),
00288 QObject::tr("The selected edge is not a line segment"));
00289 return;
00290 }
00291
00292
00293 for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin();
00294 it != vals.end(); ++it) {
00295 if ((*it)->Type == Sketcher::Horizontal && (*it)->First == index) {
00296 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"),
00297 QObject::tr("The selected edge has already a horizontal constraint!"));
00298 return;
00299 }
00300 if ((*it)->Type == Sketcher::Vertical && (*it)->First == index) {
00301 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Double constraint"),
00302 QObject::tr("The selected edge has already a vertical constraint!"));
00303 return;
00304 }
00305 }
00306 ids.push_back(index);
00307 }
00308 }
00309
00310
00311 openCommand("add vertical constraint");
00312 for (std::vector<int>::iterator it=ids.begin(); it != ids.end(); it++) {
00313
00314 doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Vertical',%d))"
00315 ,selection[0].getFeatName(),*it);
00316 }
00317
00318 commitCommand();
00319 updateActive();
00320
00321
00322 getSelection().clearSelection();
00323 }
00324
00325 bool CmdSketcherConstrainVertical::isActive(void)
00326 {
00327 return isCreateConstraintActive( getActiveGuiDocument() );
00328 }
00329
00330
00331 DEF_STD_CMD_A(CmdSketcherConstrainLock);
00332
00333 CmdSketcherConstrainLock::CmdSketcherConstrainLock()
00334 :Command("Sketcher_ConstrainLock")
00335 {
00336 sAppModule = "Sketcher";
00337 sGroup = QT_TR_NOOP("Sketcher");
00338 sMenuText = QT_TR_NOOP("Constrain lock");
00339 sToolTipText = QT_TR_NOOP("Create a lock constraint on the selected item");
00340 sWhatsThis = sToolTipText;
00341 sStatusTip = sToolTipText;
00342 sPixmap = "Sketcher_ConstrainLock";
00343 eType = ForEdit;
00344 }
00345
00346 void CmdSketcherConstrainLock::activated(int iMsg)
00347 {
00348
00349 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
00350
00351
00352 if (selection.size() != 1) {
00353 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00354 QObject::tr("Select entities from the sketch."));
00355 return;
00356 }
00357
00358
00359 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00360 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00361
00362 if (SubNames.size() != 1) {
00363 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00364 QObject::tr("Select exactly one entity from the sketch."));
00365 return;
00366 }
00367
00368 int GeoId;
00369 Sketcher::PointPos PosId=Sketcher::none;
00370 if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex") {
00371 int VtId = std::atoi(SubNames[0].substr(6,4000).c_str());
00372 Obj->getGeoVertexIndex(VtId,GeoId,PosId);
00373 }
00374 else if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
00375 GeoId = std::atoi(SubNames[0].substr(4,4000).c_str());
00376 else {
00377 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00378 QObject::tr("Select exactly one entity from the sketch."));
00379 return;
00380 }
00381
00382 Base::Vector3d pnt = Obj->getPoint(GeoId,PosId);
00383
00384
00385 openCommand("add fixed constraint");
00386 Gui::Command::doCommand(
00387 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%f)) ",
00388 selection[0].getFeatName(),GeoId,PosId,pnt.x);
00389 Gui::Command::doCommand(
00390 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%f)) ",
00391 selection[0].getFeatName(),GeoId,PosId,pnt.y);
00392
00393
00394 commitCommand();
00395 updateActive();
00396
00397
00398 getSelection().clearSelection();
00399 }
00400
00401 bool CmdSketcherConstrainLock::isActive(void)
00402 {
00403 return isCreateConstraintActive( getActiveGuiDocument() );
00404 }
00405
00406
00407 DEF_STD_CMD_A(CmdSketcherConstrainCoincident);
00408
00409 CmdSketcherConstrainCoincident::CmdSketcherConstrainCoincident()
00410 :Command("Sketcher_ConstrainCoincident")
00411 {
00412 sAppModule = "Sketcher";
00413 sGroup = QT_TR_NOOP("Sketcher");
00414 sMenuText = QT_TR_NOOP("Constrain coincident");
00415 sToolTipText = QT_TR_NOOP("Create a coincident constraint on the selected item");
00416 sWhatsThis = sToolTipText;
00417 sStatusTip = sToolTipText;
00418 sPixmap = "Constraint_PointOnPoint";
00419 sAccel = "C";
00420 eType = ForEdit;
00421 }
00422
00423 void CmdSketcherConstrainCoincident::activated(int iMsg)
00424 {
00425
00426 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
00427
00428
00429 if (selection.size() != 1) {
00430 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00431 QObject::tr("Select vertexes from the sketch."));
00432 return;
00433 }
00434
00435
00436 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00437 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00438
00439 if (SubNames.size() != 2) {
00440 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00441 QObject::tr("Select exactly two vertexes from the sketch."));
00442 return;
00443 }
00444
00445 int index1,index2;
00446
00447 if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex")
00448 index1 = std::atoi(SubNames[0].substr(6,4000).c_str());
00449 else {
00450 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00451 QObject::tr("Select exactly two vertexes from the sketch."));
00452 return;
00453 }
00454
00455
00456 if (SubNames[1].size() > 6 && SubNames[1].substr(0,6) == "Vertex")
00457 index2 = std::atoi(SubNames[1].substr(6,4000).c_str());
00458 else {
00459 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00460 QObject::tr("Select exactly two vertexes from the sketch."));
00461 return;
00462 }
00463 int GeoId1,GeoId2;
00464 Sketcher::PointPos Pt1,Pt2;
00465 Obj->getGeoVertexIndex(index1,GeoId1,Pt1);
00466 Obj->getGeoVertexIndex(index2,GeoId2,Pt2);
00467
00468
00469 openCommand("add coincident constraint");
00470 Gui::Command::doCommand(
00471 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%d,%d,%d,%d)) ",
00472 selection[0].getFeatName(),GeoId1,Pt1,GeoId2,Pt2);
00473
00474
00475 commitCommand();
00476 updateActive();
00477
00478
00479 getSelection().clearSelection();
00480 }
00481
00482 bool CmdSketcherConstrainCoincident::isActive(void)
00483 {
00484 return isCreateConstraintActive( getActiveGuiDocument() );
00485 }
00486
00487
00488 DEF_STD_CMD_A(CmdSketcherConstrainDistance);
00489
00490 CmdSketcherConstrainDistance::CmdSketcherConstrainDistance()
00491 :Command("Sketcher_ConstrainDistance")
00492 {
00493 sAppModule = "Sketcher";
00494 sGroup = QT_TR_NOOP("Sketcher");
00495 sMenuText = QT_TR_NOOP("Constrain distance");
00496 sToolTipText = QT_TR_NOOP("Fix a length of a line or the distance between a line and a vertex");
00497 sWhatsThis = sToolTipText;
00498 sStatusTip = sToolTipText;
00499 sPixmap = "Constraint_Length";
00500 sAccel = "D";
00501 eType = ForEdit;
00502 }
00503
00504 void CmdSketcherConstrainDistance::activated(int iMsg)
00505 {
00506 #if 0
00507
00508 SketchSelection selection;
00509
00510 int num = selection.setUp();
00511
00512 #else
00513
00514 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
00515
00516
00517 if (selection.size() != 1) {
00518 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00519 QObject::tr("Select vertexes from the sketch."));
00520 return;
00521 }
00522
00523
00524 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00525 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00526 const std::vector<Part::Geometry *> &geo = Obj->Geometry.getValues();
00527
00528 if (SubNames.size() < 1 || SubNames.size() > 2) {
00529 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00530 QObject::tr("Select exactly one line or one point and one line or two points from the sketch."));
00531 return;
00532 }
00533
00534 int GeoId1=Constraint::GeoUndef, VtId1=-1, GeoId2=Constraint::GeoUndef, VtId2=-1;
00535 if (SubNames.size() >= 1) {
00536 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
00537 GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str());
00538 else if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex")
00539 VtId1 = std::atoi(SubNames[0].substr(6,4000).c_str());
00540 }
00541 if (SubNames.size() == 2) {
00542 if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge")
00543 GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str());
00544 else if (SubNames[1].size() > 6 && SubNames[1].substr(0,6) == "Vertex")
00545 VtId2 = std::atoi(SubNames[1].substr(6,4000).c_str());
00546 }
00547
00548 if (VtId1 >= 0 && VtId2 >= 0) {
00549 Sketcher::PointPos PosId1,PosId2;
00550 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
00551 Obj->getGeoVertexIndex(VtId2,GeoId2,PosId2);
00552 Base::Vector3d pnt1 = Obj->getPoint(GeoId1,PosId1);
00553 Base::Vector3d pnt2 = Obj->getPoint(GeoId2,PosId2);
00554
00555 openCommand("add point to point distance constraint");
00556 Gui::Command::doCommand(
00557 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%d,%f)) ",
00558 selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,(pnt2-pnt1).Length());
00559 commitCommand();
00560
00561
00562 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00563 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00564
00565 updateDatumDistance(getActiveGuiDocument(), constr);
00566
00567
00568 getSelection().clearSelection();
00569 return;
00570 }
00571 else if ((VtId1 >= 0 && GeoId2 >= 0) || (VtId2 >= 0 && GeoId1 >= 0)) {
00572 if (VtId2 >= 0 && GeoId1 >= 0) {
00573 std::swap(VtId1,VtId2);
00574 std::swap(GeoId1,GeoId2);
00575 }
00576 Sketcher::PointPos PosId1;
00577 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
00578 Base::Vector3d pnt = Obj->getPoint(GeoId1,PosId1);
00579 const Part::Geometry *geom = geo[GeoId2];
00580 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
00581 const Part::GeomLineSegment *lineSeg;
00582 lineSeg = dynamic_cast<const Part::GeomLineSegment*>(geom);
00583 Base::Vector3d pnt1 = lineSeg->getStartPoint();
00584 Base::Vector3d pnt2 = lineSeg->getEndPoint();
00585 Base::Vector3d d = pnt2-pnt1;
00586 double ActDist = std::abs(-pnt.x*d.y+pnt.y*d.x+pnt1.x*pnt2.y-pnt2.x*pnt1.y) / d.Length();
00587
00588 openCommand("add point to line Distance constraint");
00589 Gui::Command::doCommand(
00590 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%f)) ",
00591 selection[0].getFeatName(),GeoId1,PosId1,GeoId2,ActDist);
00592 commitCommand();
00593
00594
00595 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00596 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00597
00598 updateDatumDistance(getActiveGuiDocument(), constr);
00599
00600
00601 getSelection().clearSelection();
00602 return;
00603 }
00604 }
00605 else if (GeoId1 >= 0) {
00606 const Part::Geometry *geom = geo[GeoId1];
00607 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
00608 const Part::GeomLineSegment *lineSeg;
00609 lineSeg = dynamic_cast<const Part::GeomLineSegment*>(geom);
00610 double ActLength = (lineSeg->getEndPoint()-lineSeg->getStartPoint()).Length();
00611
00612 openCommand("add length constraint");
00613 Gui::Command::doCommand(
00614 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Distance',%d,%f)) ",
00615 selection[0].getFeatName(),GeoId1,ActLength);
00616 commitCommand();
00617
00618
00619 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00620 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00621
00622 updateDatumDistance(getActiveGuiDocument(), constr);
00623
00624
00625 getSelection().clearSelection();
00626 return;
00627 }
00628 }
00629
00630 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00631 QObject::tr("Select exactly one line or one point and one line or two points from the sketch."));
00632 return;
00633 #endif
00634 }
00635
00636 bool CmdSketcherConstrainDistance::isActive(void)
00637 {
00638 return isCreateConstraintActive( getActiveGuiDocument() );
00639 }
00640
00641
00642 DEF_STD_CMD_A(CmdSketcherConstrainPointOnObject);
00643
00644 CmdSketcherConstrainPointOnObject::CmdSketcherConstrainPointOnObject()
00645 :Command("Sketcher_ConstrainPointOnObject")
00646 {
00647 sAppModule = "Sketcher";
00648 sGroup = QT_TR_NOOP("Sketcher");
00649 sMenuText = QT_TR_NOOP("Constrain point onto object");
00650 sToolTipText = QT_TR_NOOP("Fix a point onto an object");
00651 sWhatsThis = sToolTipText;
00652 sStatusTip = sToolTipText;
00653 sPixmap = "Constraint_PointOnObject";
00654 sAccel = "O";
00655 eType = ForEdit;
00656 }
00657
00658 void CmdSketcherConstrainPointOnObject::activated(int iMsg)
00659 {
00660
00661 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
00662
00663
00664 if (selection.size() != 1) {
00665 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00666 QObject::tr("Select vertexes from the sketch."));
00667 return;
00668 }
00669
00670
00671 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00672 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00673 const std::vector<Part::Geometry *> &geo = Obj->Geometry.getValues();
00674
00675 if (SubNames.size() < 1 || SubNames.size() > 2) {
00676 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00677 QObject::tr("Select exactly one point and one object from the sketch."));
00678 return;
00679 }
00680
00681 int GeoId1=Constraint::GeoUndef, VtId1=-1, GeoId2=Constraint::GeoUndef, VtId2=-1;
00682
00683 if (SubNames.size() >= 1) {
00684 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
00685 GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str());
00686 else if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex")
00687 VtId1 = std::atoi(SubNames[0].substr(6,4000).c_str());
00688 }
00689 if (SubNames.size() == 2) {
00690 if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge")
00691 GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str());
00692 else if (SubNames[1].size() > 6 && SubNames[1].substr(0,6) == "Vertex")
00693 VtId2 = std::atoi(SubNames[1].substr(6,4000).c_str());
00694 }
00695
00696 if ((VtId1 >= 0 && GeoId2 >= 0) || (VtId2 >= 0 && GeoId1 >= 0)) {
00697 if (VtId2 >= 0 && GeoId1 >= 0) {
00698 std::swap(VtId1,VtId2);
00699 std::swap(GeoId1,GeoId2);
00700 }
00701
00702 Sketcher::PointPos PosId1;
00703 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
00704
00705 const Part::Geometry *geom = geo[GeoId2];
00706
00707
00708 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
00709 geom->getTypeId() == Part::GeomCircle::getClassTypeId() ||
00710 geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ) {
00711
00712 openCommand("add point on object constraint");
00713 Gui::Command::doCommand(
00714 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
00715 selection[0].getFeatName(),GeoId1,PosId1,GeoId2);
00716 commitCommand();
00717
00718 getSelection().clearSelection();
00719 return;
00720 }
00721 }
00722
00723 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00724 QObject::tr("Select exactly one point and one object from the sketch."));
00725 return;
00726 }
00727
00728 bool CmdSketcherConstrainPointOnObject::isActive(void)
00729 {
00730 return isCreateConstraintActive( getActiveGuiDocument() );
00731 }
00732
00733 DEF_STD_CMD_A(CmdSketcherConstrainDistanceX);
00734
00735 CmdSketcherConstrainDistanceX::CmdSketcherConstrainDistanceX()
00736 :Command("Sketcher_ConstrainDistanceX")
00737 {
00738 sAppModule = "Sketcher";
00739 sGroup = QT_TR_NOOP("Sketcher");
00740 sMenuText = QT_TR_NOOP("Constrain horizontal distance");
00741 sToolTipText = QT_TR_NOOP("Fix the horizontal distance between two points or line ends");
00742 sWhatsThis = sToolTipText;
00743 sStatusTip = sToolTipText;
00744 sPixmap = "Constraint_HorizontalDistance";
00745 sAccel = "D";
00746 eType = ForEdit;
00747 }
00748
00749 void CmdSketcherConstrainDistanceX::activated(int iMsg)
00750 {
00751
00752 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
00753
00754
00755 if (selection.size() != 1) {
00756 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00757 QObject::tr("Select vertexes from the sketch."));
00758 return;
00759 }
00760
00761
00762 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00763 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00764 const std::vector<Part::Geometry *> &geo = Obj->Geometry.getValues();
00765
00766 if (SubNames.size() < 1 || SubNames.size() > 2) {
00767 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00768 QObject::tr("Select exactly one line or up to two points from the sketch."));
00769 return;
00770 }
00771
00772 int GeoId1=Constraint::GeoUndef, VtId1=-1, GeoId2=Constraint::GeoUndef, VtId2=-1;
00773 if (SubNames.size() >= 1) {
00774 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
00775 GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str());
00776 else if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex")
00777 VtId1 = std::atoi(SubNames[0].substr(6,4000).c_str());
00778 }
00779 if (SubNames.size() == 2) {
00780 if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge")
00781 GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str());
00782 else if (SubNames[1].size() > 6 && SubNames[1].substr(0,6) == "Vertex")
00783 VtId2 = std::atoi(SubNames[1].substr(6,4000).c_str());
00784 }
00785
00786 if (VtId1 >= 0 && VtId2 >= 0) {
00787 Sketcher::PointPos PosId1,PosId2;
00788 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
00789 Obj->getGeoVertexIndex(VtId2,GeoId2,PosId2);
00790 Base::Vector3d pnt1 = Obj->getPoint(GeoId1,PosId1);
00791 Base::Vector3d pnt2 = Obj->getPoint(GeoId2,PosId2);
00792 double ActLength = pnt2.x-pnt1.x;
00793
00794 openCommand("add point to point horizontal distance constraint");
00795 Gui::Command::doCommand(
00796 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%d,%d,%f)) ",
00797 selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,ActLength);
00798 commitCommand();
00799
00800
00801 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00802 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00803
00804 updateDatumDistance(getActiveGuiDocument(), constr);
00805
00806
00807 getSelection().clearSelection();
00808 return;
00809 }
00810 else if (GeoId1 >= 0 && GeoId2 < 0 && VtId2 < 0) {
00811 const Part::Geometry *geom = geo[GeoId1];
00812 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
00813 const Part::GeomLineSegment *lineSeg;
00814 lineSeg = dynamic_cast<const Part::GeomLineSegment*>(geom);
00815 double ActLength = lineSeg->getEndPoint().x-lineSeg->getStartPoint().x;
00816
00817 openCommand("add horizontal length constraint");
00818 Gui::Command::doCommand(
00819 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%f)) ",
00820 selection[0].getFeatName(),GeoId1,ActLength);
00821 commitCommand();
00822
00823
00824 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00825 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00826
00827 updateDatumDistance(getActiveGuiDocument(), constr);
00828
00829
00830 getSelection().clearSelection();
00831 return;
00832 }
00833 }
00834 else if (VtId1 >= 0) {
00835 Sketcher::PointPos PosId1;
00836 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
00837 Base::Vector3d pnt = Obj->getPoint(GeoId1,PosId1);
00838 double ActX = pnt.x;
00839
00840 openCommand("add fixed x-coordinate constraint");
00841 Gui::Command::doCommand(
00842 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%f)) ",
00843 selection[0].getFeatName(),GeoId1,PosId1,ActX);
00844 commitCommand();
00845
00846
00847 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00848 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00849
00850 updateDatumDistance(getActiveGuiDocument(), constr);
00851
00852
00853 getSelection().clearSelection();
00854 return;
00855 }
00856
00857 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00858 QObject::tr("Select exactly one line or up to two points from the sketch."));
00859 return;
00860 }
00861
00862 bool CmdSketcherConstrainDistanceX::isActive(void)
00863 {
00864 return isCreateConstraintActive( getActiveGuiDocument() );
00865 }
00866
00867
00868 DEF_STD_CMD_A(CmdSketcherConstrainDistanceY);
00869
00870 CmdSketcherConstrainDistanceY::CmdSketcherConstrainDistanceY()
00871 :Command("Sketcher_ConstrainDistanceY")
00872 {
00873 sAppModule = "Sketcher";
00874 sGroup = QT_TR_NOOP("Sketcher");
00875 sMenuText = QT_TR_NOOP("Constrain horizontal distance");
00876 sToolTipText = QT_TR_NOOP("Fix the vertical distance between two points or line ends");
00877 sWhatsThis = sToolTipText;
00878 sStatusTip = sToolTipText;
00879 sPixmap = "Constraint_VerticalDistance";
00880 sAccel = "D";
00881 eType = ForEdit;
00882 }
00883
00884 void CmdSketcherConstrainDistanceY::activated(int iMsg)
00885 {
00886
00887 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
00888
00889
00890 if (selection.size() != 1) {
00891 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00892 QObject::tr("Select vertexes from the sketch."));
00893 return;
00894 }
00895
00896
00897 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00898 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
00899 const std::vector<Part::Geometry *> &geo = Obj->Geometry.getValues();
00900
00901 if (SubNames.size() < 1 || SubNames.size() > 2) {
00902 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00903 QObject::tr("Select exactly one line or up to two points from the sketch."));
00904 return;
00905 }
00906
00907 int GeoId1=Constraint::GeoUndef, VtId1=-1, GeoId2=Constraint::GeoUndef, VtId2=-1;
00908 if (SubNames.size() >= 1) {
00909 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
00910 GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str());
00911 else if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex")
00912 VtId1 = std::atoi(SubNames[0].substr(6,4000).c_str());
00913 }
00914 if (SubNames.size() == 2) {
00915 if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge")
00916 GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str());
00917 else if (SubNames[1].size() > 6 && SubNames[1].substr(0,6) == "Vertex")
00918 VtId2 = std::atoi(SubNames[1].substr(6,4000).c_str());
00919 }
00920
00921 if (VtId1 >= 0 && VtId2 >= 0) {
00922 Sketcher::PointPos PosId1,PosId2;
00923 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
00924 Obj->getGeoVertexIndex(VtId2,GeoId2,PosId2);
00925 Base::Vector3d pnt1 = Obj->getPoint(GeoId1,PosId1);
00926 Base::Vector3d pnt2 = Obj->getPoint(GeoId2,PosId2);
00927 double ActLength = pnt2.y-pnt1.y;
00928
00929 openCommand("add point to point vertical distance constraint");
00930 Gui::Command::doCommand(
00931 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%d,%d,%f)) ",
00932 selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,ActLength);
00933 commitCommand();
00934
00935
00936 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00937 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00938
00939 updateDatumDistance(getActiveGuiDocument(), constr);
00940
00941
00942 getSelection().clearSelection();
00943 return;
00944 }
00945 else if (GeoId1 >= 0 && GeoId2 < 0 && VtId2 < 0) {
00946 const Part::Geometry *geom = geo[GeoId1];
00947 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
00948 const Part::GeomLineSegment *lineSeg;
00949 lineSeg = dynamic_cast<const Part::GeomLineSegment*>(geom);
00950 double ActLength = lineSeg->getEndPoint().y-lineSeg->getStartPoint().y;
00951
00952 openCommand("add vertical length constraint");
00953 Gui::Command::doCommand(
00954 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%f)) ",
00955 selection[0].getFeatName(),GeoId1,ActLength);
00956 commitCommand();
00957
00958
00959 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00960 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00961
00962 updateDatumDistance(getActiveGuiDocument(), constr);
00963
00964
00965 getSelection().clearSelection();
00966 return;
00967 }
00968 }
00969 else if (VtId1 >= 0) {
00970 Sketcher::PointPos PosId1;
00971 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
00972 Base::Vector3d pnt = Obj->getPoint(GeoId1,PosId1);
00973 double ActY = pnt.y;
00974
00975 openCommand("add fixed y-coordinate constraint");
00976 Gui::Command::doCommand(
00977 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceY',%d,%d,%f)) ",
00978 selection[0].getFeatName(),GeoId1,PosId1,ActY);
00979 commitCommand();
00980
00981
00982 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
00983 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
00984
00985 updateDatumDistance(getActiveGuiDocument(), constr);
00986
00987
00988 getSelection().clearSelection();
00989 return;
00990 }
00991
00992 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
00993 QObject::tr("Select exactly one line or up to two points from the sketch."));
00994 return;
00995 }
00996
00997 bool CmdSketcherConstrainDistanceY::isActive(void)
00998 {
00999 return isCreateConstraintActive( getActiveGuiDocument() );
01000 }
01001
01002
01003 DEF_STD_CMD_A(CmdSketcherConstrainParallel);
01004
01005 CmdSketcherConstrainParallel::CmdSketcherConstrainParallel()
01006 :Command("Sketcher_ConstrainParallel")
01007 {
01008 sAppModule = "Sketcher";
01009 sGroup = QT_TR_NOOP("Sketcher");
01010 sMenuText = QT_TR_NOOP("Constrain parallel");
01011 sToolTipText = QT_TR_NOOP("Create a parallel constraint between two lines");
01012 sWhatsThis = sToolTipText;
01013 sStatusTip = sToolTipText;
01014 sPixmap = "Constraint_Parallel";
01015 sAccel = "P";
01016 eType = ForEdit;
01017 }
01018
01019 void CmdSketcherConstrainParallel::activated(int iMsg)
01020 {
01021
01022 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
01023
01024
01025 if (selection.size() != 1) {
01026 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01027 QObject::tr("Select two or more lines from the sketch."));
01028 return;
01029 }
01030
01031
01032 const std::vector<std::string> &SubNames = selection[0].getSubNames();
01033 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
01034 const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
01035 const std::vector<Part::Geometry *> &geomlist = Obj->Geometry.getValues();
01036
01037
01038
01039
01040 if (SubNames.size() < 2) {
01041 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01042 QObject::tr("Select at least two lines from the sketch."));
01043 return;
01044 }
01045
01046 std::vector<int> ids;
01047 for (std::vector<std::string>::const_iterator it=SubNames.begin();it!=SubNames.end();++it) {
01048 int index;
01049 std::string subName = *it;
01050 if (subName.size() > 4 && subName.substr(0,4) == "Edge")
01051 index = std::atoi(subName.substr(4,4000).c_str());
01052 else {
01053 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01054 QObject::tr("Select a valid line"));
01055 return;
01056 }
01057
01058
01059 Part::Geometry *geo = geomlist[index];
01060 if (geo->getTypeId() != Part::GeomLineSegment::getClassTypeId()) {
01061 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01062 QObject::tr("The selected edge is not a valid line"));
01063 return;
01064 }
01065 ids.push_back(index);
01066 }
01067
01068
01069 openCommand("add parallel constraint");
01070 int i = 0;
01071 for (std::vector<int>::iterator it = ids.begin(); it!=ids.end();++it, i++) {
01072 if(i == ids.size() - 1)
01073 break;
01074
01075 Gui::Command::doCommand(
01076 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Parallel',%d,%d)) ",
01077 selection[0].getFeatName(),ids[i],ids[i+1]);
01078 }
01079
01080
01081 commitCommand();
01082 updateActive();
01083
01084
01085 getSelection().clearSelection();
01086 }
01087
01088 bool CmdSketcherConstrainParallel::isActive(void)
01089 {
01090 return isCreateConstraintActive( getActiveGuiDocument() );
01091 }
01092
01093
01094 DEF_STD_CMD_A(CmdSketcherConstrainPerpendicular);
01095
01096 CmdSketcherConstrainPerpendicular::CmdSketcherConstrainPerpendicular()
01097 :Command("Sketcher_ConstrainPerpendicular")
01098 {
01099 sAppModule = "Sketcher";
01100 sGroup = QT_TR_NOOP("Sketcher");
01101 sMenuText = QT_TR_NOOP("Constrain perpendicular");
01102 sToolTipText = QT_TR_NOOP("Create a Perpendicular constraint between two lines");
01103 sWhatsThis = sToolTipText;
01104 sStatusTip = sToolTipText;
01105 sPixmap = "Constraint_Perpendicular";
01106 sAccel = "N";
01107 eType = ForEdit;
01108 }
01109
01110 void CmdSketcherConstrainPerpendicular::activated(int iMsg)
01111 {
01112
01113 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
01114
01115
01116 if (selection.size() != 1) {
01117 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01118 QObject::tr("Select two lines from the sketch."));
01119 return;
01120 }
01121
01122
01123 const std::vector<std::string> &SubNames = selection[0].getSubNames();
01124 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
01125 const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
01126 const std::vector<Part::Geometry *> &geomlist = Obj->Geometry.getValues();
01127
01128 if (SubNames.size() != 2) {
01129 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01130 QObject::tr("Select exactly two lines from the sketch."));
01131 return;
01132 }
01133
01134 int GeoId1,GeoId2;
01135 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
01136 GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str());
01137 else {
01138 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01139 QObject::tr("Select exactly two lines from the sketch."));
01140 return;
01141 }
01142
01143 if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge")
01144 GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str());
01145 else {
01146 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01147 QObject::tr("Select exactly two lines from the sketch."));
01148 return;
01149 }
01150
01151 Part::Geometry *geo1 = geomlist[GeoId1];
01152 Part::Geometry *geo2 = geomlist[GeoId2];
01153
01154 if (geo1->getTypeId() != Part::GeomLineSegment::getClassTypeId() ||
01155 geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId()) {
01156
01157 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01158 QObject::tr("Select exactly two lines from the sketch."));
01159 return;
01160 }
01161
01162
01163 openCommand("add perpendicular constraint");
01164 Gui::Command::doCommand(
01165 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Perpendicular',%d,%d)) ",
01166 selection[0].getFeatName(),GeoId1,GeoId2);
01167
01168
01169 commitCommand();
01170 updateActive();
01171
01172
01173 getSelection().clearSelection();
01174 }
01175
01176 bool CmdSketcherConstrainPerpendicular::isActive(void)
01177 {
01178 return isCreateConstraintActive( getActiveGuiDocument() );
01179 }
01180
01181
01182 DEF_STD_CMD_A(CmdSketcherConstrainTangent);
01183
01184 CmdSketcherConstrainTangent::CmdSketcherConstrainTangent()
01185 :Command("Sketcher_ConstrainTangent")
01186 {
01187 sAppModule = "Sketcher";
01188 sGroup = QT_TR_NOOP("Sketcher");
01189 sMenuText = QT_TR_NOOP("Constrain tangent");
01190 sToolTipText = QT_TR_NOOP("Create a tangent constraint between two entities");
01191 sWhatsThis = sToolTipText;
01192 sStatusTip = sToolTipText;
01193 sPixmap = "Constraint_Tangent";
01194 sAccel = "T";
01195 eType = ForEdit;
01196 }
01197
01198 void CmdSketcherConstrainTangent::activated(int iMsg)
01199 {
01200
01201 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
01202
01203
01204 if (selection.size() != 1) {
01205 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01206 QObject::tr("Select two entities from the sketch."));
01207 return;
01208 }
01209
01210
01211 const std::vector<std::string> &SubNames = selection[0].getSubNames();
01212 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
01213
01214 if (SubNames.size() != 2) {
01215 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01216 QObject::tr("Select exactly two entities from the sketch."));
01217 return;
01218 }
01219
01220 int GeoId1=Constraint::GeoUndef, VtId1=-1, GeoId2=Constraint::GeoUndef, VtId2=-1;
01221 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
01222 GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str());
01223 else if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex")
01224 VtId1 = std::atoi(SubNames[0].substr(6,4000).c_str());
01225
01226 if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge")
01227 GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str());
01228 else if (SubNames[1].size() > 6 && SubNames[1].substr(0,6) == "Vertex")
01229 VtId2 = std::atoi(SubNames[1].substr(6,4000).c_str());
01230
01231 Sketcher::PointPos PosId1,PosId2;
01232 if (VtId1 >= 0 && VtId2 >= 0) {
01233 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
01234 Obj->getGeoVertexIndex(VtId2,GeoId2,PosId2);
01235 openCommand("add tangent constraint");
01236 Gui::Command::doCommand(
01237 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d,%d)) ",
01238 selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2);
01239 commitCommand();
01240 updateActive();
01241 getSelection().clearSelection();
01242 return;
01243 }
01244 else if ((VtId1 >= 0 && GeoId2 >= 0) || (VtId2 >= 0 && GeoId1 >= 0)) {
01245 if (VtId2 >= 0 && GeoId1 >= 0) {
01246 VtId1 = VtId2;
01247 VtId2 = -1;
01248 GeoId2 = GeoId1;
01249 GeoId1 = -1;
01250 }
01251 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
01252 openCommand("add tangent constraint");
01253 Gui::Command::doCommand(
01254 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d)) ",
01255 selection[0].getFeatName(),GeoId1,PosId1,GeoId2);
01256 commitCommand();
01257 updateActive();
01258 getSelection().clearSelection();
01259 return;
01260 }
01261 else if (GeoId1 >= 0 && GeoId2 >= 0) {
01262 openCommand("add tangent constraint");
01263 Gui::Command::doCommand(
01264 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ",
01265 selection[0].getFeatName(),GeoId1,GeoId2);
01266 commitCommand();
01267 updateActive();
01268 getSelection().clearSelection();
01269 return;
01270 }
01271 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01272 QObject::tr("Select exactly two entities from the sketch."));
01273 return;
01274 }
01275
01276 bool CmdSketcherConstrainTangent::isActive(void)
01277 {
01278 return isCreateConstraintActive( getActiveGuiDocument() );
01279 }
01280
01281
01282 DEF_STD_CMD_A(CmdSketcherConstrainRadius);
01283
01284 CmdSketcherConstrainRadius::CmdSketcherConstrainRadius()
01285 :Command("Sketcher_ConstrainRadius")
01286 {
01287 sAppModule = "Sketcher";
01288 sGroup = QT_TR_NOOP("Sketcher");
01289 sMenuText = QT_TR_NOOP("Constrain radius");
01290 sToolTipText = QT_TR_NOOP("Fix the radius of a circle or an arc");
01291 sWhatsThis = sToolTipText;
01292 sStatusTip = sToolTipText;
01293 sPixmap = "Constraint_Radius";
01294 sAccel = "R";
01295 eType = ForEdit;
01296 }
01297
01298 void CmdSketcherConstrainRadius::activated(int iMsg)
01299 {
01300
01301 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
01302
01303
01304 if (selection.size() != 1) {
01305 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01306 QObject::tr("Select exactly one arc or circle from the sketch."));
01307 return;
01308 }
01309
01310
01311 const std::vector<std::string> &SubNames = selection[0].getSubNames();
01312 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
01313 const std::vector<Part::Geometry *> &geo = Obj->Geometry.getValues();
01314
01315 if (SubNames.size() != 1) {
01316 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01317 QObject::tr("Select exactly one arc or circle from the sketch."));
01318 return;
01319 }
01320
01321 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge") {
01322 int GeoId = std::atoi(SubNames[0].substr(4,4000).c_str());
01323
01324 const Part::Geometry *geom = geo[GeoId];
01325 if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
01326 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geom);
01327 double ActRadius = arc->getRadius();
01328
01329 openCommand("add radius constraint");
01330 Gui::Command::doCommand(
01331 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
01332 selection[0].getFeatName(),GeoId,ActRadius);
01333 commitCommand();
01334
01335 getSelection().clearSelection();
01336 return;
01337 }
01338 else if (geom->getTypeId() == Part::GeomCircle::getClassTypeId()) {
01339 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geom);
01340 double ActRadius = circle->getRadius();
01341
01342 openCommand("add radius constraint");
01343 Gui::Command::doCommand(
01344 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
01345 selection[0].getFeatName(),GeoId,ActRadius);
01346 commitCommand();
01347
01348 getSelection().clearSelection();
01349 return;
01350 }
01351 }
01352
01353 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01354 QObject::tr("Select exactly one arc or circle from the sketch."));
01355 return;
01356 }
01357
01358 bool CmdSketcherConstrainRadius::isActive(void)
01359 {
01360 return isCreateConstraintActive( getActiveGuiDocument() );
01361 }
01362
01363
01364 DEF_STD_CMD_A(CmdSketcherConstrainAngle);
01365
01366 CmdSketcherConstrainAngle::CmdSketcherConstrainAngle()
01367 :Command("Sketcher_ConstrainAngle")
01368 {
01369 sAppModule = "Sketcher";
01370 sGroup = QT_TR_NOOP("Sketcher");
01371 sMenuText = QT_TR_NOOP("Constrain angle");
01372 sToolTipText = QT_TR_NOOP("Fix the angle of a line or the angle between two lines");
01373 sWhatsThis = sToolTipText;
01374 sStatusTip = sToolTipText;
01375 sPixmap = "Constraint_InternalAngle";
01376 sAccel = "A";
01377 eType = ForEdit;
01378 }
01379
01380 void CmdSketcherConstrainAngle::activated(int iMsg)
01381 {
01382
01383 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
01384
01385
01386 if (selection.size() != 1) {
01387 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01388 QObject::tr("Select vertexes from the sketch."));
01389 return;
01390 }
01391
01392
01393 const std::vector<std::string> &SubNames = selection[0].getSubNames();
01394 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
01395 const std::vector<Part::Geometry *> &geo = Obj->Geometry.getValues();
01396
01397 if (SubNames.size() < 1 || SubNames.size() > 2) {
01398 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01399 QObject::tr("Select exactly one or two lines from the sketch."));
01400 return;
01401 }
01402
01403 int GeoId1=Constraint::GeoUndef, GeoId2=Constraint::GeoUndef;
01404 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
01405 GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str());
01406 if (SubNames.size() == 2) {
01407 if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge")
01408 GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str());
01409 }
01410
01411 if (GeoId2 >= 0) {
01412 const Part::Geometry *geom1 = geo[GeoId1];
01413 const Part::Geometry *geom2 = geo[GeoId2];
01414 if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
01415 geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01416 const Part::GeomLineSegment *lineSeg1 = dynamic_cast<const Part::GeomLineSegment*>(geom1);
01417 const Part::GeomLineSegment *lineSeg2 = dynamic_cast<const Part::GeomLineSegment*>(geom2);
01418
01419
01420 Sketcher::PointPos PosId1,PosId2;
01421 Base::Vector3d p1a = lineSeg1->getStartPoint();
01422 Base::Vector3d p1b = lineSeg1->getEndPoint();
01423 Base::Vector3d p2a = lineSeg2->getStartPoint();
01424 Base::Vector3d p2b = lineSeg2->getEndPoint();
01425 double length = 1e10;
01426 for (int i=0; i <= 1; i++)
01427 for (int j=0; j <= 1; j++) {
01428 double tmp = ((j?p2a:p2b)-(i?p1a:p1b)).Length();
01429 if (tmp < length) {
01430 length = tmp;
01431 PosId1 = i ? Sketcher::start : Sketcher::end;
01432 PosId2 = j ? Sketcher::start : Sketcher::end;
01433 }
01434 }
01435
01436 Base::Vector3d dir1 = ((PosId1 == Sketcher::start) ? 1. : -1.) *
01437 (lineSeg1->getEndPoint()-lineSeg1->getStartPoint());
01438 Base::Vector3d dir2 = ((PosId2 == Sketcher::start) ? 1. : -1.) *
01439 (lineSeg2->getEndPoint()-lineSeg2->getStartPoint());
01440
01441 double ActAngle = atan2(-dir1.y*dir2.x+dir1.x*dir2.y,
01442 dir1.x*dir2.x+dir1.y*dir2.y);
01443 if (ActAngle < 0) {
01444 ActAngle *= -1;
01445 std::swap(GeoId1,GeoId2);
01446 std::swap(PosId1,PosId2);
01447 }
01448
01449 openCommand("add angle constraint");
01450 Gui::Command::doCommand(
01451 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Angle',%d,%d,%d,%d,%f)) ",
01452 selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,ActAngle);
01453 commitCommand();
01454
01455
01456 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
01457 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
01458
01459 updateDatumDistance(getActiveGuiDocument(), constr);
01460
01461
01462 getSelection().clearSelection();
01463 return;
01464 }
01465 } else if (GeoId1 >= 0) {
01466 const Part::Geometry *geom = geo[GeoId1];
01467 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01468 const Part::GeomLineSegment *lineSeg;
01469 lineSeg = dynamic_cast<const Part::GeomLineSegment*>(geom);
01470 Base::Vector3d dir = lineSeg->getEndPoint()-lineSeg->getStartPoint();
01471 double ActAngle = atan2(dir.y,dir.x);
01472
01473 openCommand("add angle constraint");
01474 Gui::Command::doCommand(
01475 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Angle',%d,%f)) ",
01476 selection[0].getFeatName(),GeoId1,ActAngle);
01477 commitCommand();
01478
01479
01480 const std::vector<Sketcher::Constraint *> &ConStr = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject())->Constraints.getValues();
01481 Sketcher::Constraint *constr = ConStr[ConStr.size() -1];
01482
01483 float sf = 1.f;
01484 Gui::Document *doc = getActiveGuiDocument();
01485 if (doc && doc->getInEdit() && doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) {
01486 SketcherGui::ViewProviderSketch *vp = dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
01487 sf = vp->getScaleFactor();
01488
01489 constr->LabelDistance = 2. * sf;
01490 vp->draw();
01491 }
01492
01493
01494 getSelection().clearSelection();
01495 return;
01496 }
01497 }
01498
01499 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01500 QObject::tr("Select exactly one or two lines from the sketch."));
01501 return;
01502 }
01503
01504 bool CmdSketcherConstrainAngle::isActive(void)
01505 {
01506 return isCreateConstraintActive( getActiveGuiDocument() );
01507 }
01508
01509
01510 DEF_STD_CMD_A(CmdSketcherConstrainEqual);
01511
01512 CmdSketcherConstrainEqual::CmdSketcherConstrainEqual()
01513 :Command("Sketcher_ConstrainEqual")
01514 {
01515 sAppModule = "Sketcher";
01516 sGroup = QT_TR_NOOP("Sketcher");
01517 sMenuText = QT_TR_NOOP("Constrain equal");
01518 sToolTipText = QT_TR_NOOP("Create an equality constraint between two lines or between circles and arcs");
01519 sWhatsThis = sToolTipText;
01520 sStatusTip = sToolTipText;
01521 sPixmap = "Constraint_EqualLength";
01522 sAccel = "E";
01523 eType = ForEdit;
01524 }
01525
01526 void CmdSketcherConstrainEqual::activated(int iMsg)
01527 {
01528
01529 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
01530
01531
01532 if (selection.size() != 1) {
01533 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01534 QObject::tr("Select two edges from the sketch."));
01535 return;
01536 }
01537
01538
01539 const std::vector<std::string> &SubNames = selection[0].getSubNames();
01540 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
01541 const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
01542 const std::vector<Part::Geometry *> &geomlist = Obj->Geometry.getValues();
01543
01544
01545
01546 if (SubNames.size() < 2) {
01547 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01548 QObject::tr("Select atleast two lines from the sketch."));
01549 return;
01550 }
01551
01552 std::vector<int> ids;
01553 bool lineSel = false, arcSel = false, circSel = false;
01554
01555 for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
01556 int index;
01557 std::string subName = *it;
01558 if (subName.size() > 4 && subName.substr(0,4) == "Edge")
01559 index = std::atoi(subName.substr(4,4000).c_str());
01560 else {
01561 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01562 QObject::tr("Select exactly two same geometries"));
01563 return;
01564 }
01565
01566 Part::Geometry *geo = geomlist[index];
01567 if (geo->getTypeId() != Part::GeomLineSegment::getClassTypeId()) {
01568 lineSel = true;
01569 } else if (geo->getTypeId() != Part::GeomArcOfCircle::getClassTypeId()) {
01570 arcSel = true;
01571 } else if (geo->getTypeId() != Part::GeomCircle::getClassTypeId()) {
01572 circSel = true;
01573 } else {
01574 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01575 QObject::tr("Select valid geometries"));
01576 return;
01577 }
01578
01579 ids.push_back(index);
01580 }
01581
01582 if (lineSel && (arcSel || circSel)) {
01583 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01584 QObject::tr("Select geometry of similar type"));
01585 return;
01586 }
01587
01588
01589 openCommand("add equality constraint");
01590 int i = 0;
01591 for (std::vector<int>::iterator it = ids.begin(); it!=ids.end();it++, i++) {
01592 if( i == ids.size() - 1)
01593 break;
01594 Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Equal',%d,%d)) ",
01595 selection[0].getFeatName(),ids[i],ids[i+1]);
01596 }
01597
01598 commitCommand();
01599 updateActive();
01600
01601
01602 getSelection().clearSelection();
01603 }
01604
01605 bool CmdSketcherConstrainEqual::isActive(void)
01606 {
01607 return isCreateConstraintActive( getActiveGuiDocument() );
01608 }
01609
01610
01611 DEF_STD_CMD_A(CmdSketcherConstrainSymmetric);
01612
01613 CmdSketcherConstrainSymmetric::CmdSketcherConstrainSymmetric()
01614 :Command("Sketcher_ConstrainSymmetric")
01615 {
01616 sAppModule = "Sketcher";
01617 sGroup = QT_TR_NOOP("Sketcher");
01618 sMenuText = QT_TR_NOOP("Constrain symmetrical");
01619 sToolTipText = QT_TR_NOOP("Create an symmetry constraint between two points with respect to a line");
01620 sWhatsThis = sToolTipText;
01621 sStatusTip = sToolTipText;
01622 sPixmap = "Constraint_Symmetric";
01623 sAccel = "S";
01624 eType = ForEdit;
01625 }
01626
01627 void CmdSketcherConstrainSymmetric::activated(int iMsg)
01628 {
01629
01630 std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
01631 Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
01632 const std::vector<Part::Geometry *> &geo = Obj->Geometry.getValues();
01633
01634
01635 if (selection.size() != 1) {
01636 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01637 QObject::tr("Select two points and one line from the sketch."));
01638 return;
01639 }
01640
01641
01642 const std::vector<std::string> &SubNames = selection[0].getSubNames();
01643
01644 if (SubNames.size() != 3) {
01645 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01646 QObject::tr("Select two points and one line from the sketch."));
01647 return;
01648 }
01649
01650 int GeoId1=Constraint::GeoUndef, VtId1=-1,
01651 GeoId2=Constraint::GeoUndef, VtId2=-1,
01652 GeoId3=Constraint::GeoUndef, VtId3=-1;
01653 if (SubNames.size() >= 1) {
01654 if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge")
01655 GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str());
01656 else if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex")
01657 VtId1 = std::atoi(SubNames[0].substr(6,4000).c_str());
01658 if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge")
01659 GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str());
01660 else if (SubNames[1].size() > 6 && SubNames[1].substr(0,6) == "Vertex")
01661 VtId2 = std::atoi(SubNames[1].substr(6,4000).c_str());
01662 if (SubNames[2].size() > 4 && SubNames[2].substr(0,4) == "Edge")
01663 GeoId3 = std::atoi(SubNames[2].substr(4,4000).c_str());
01664 else if (SubNames[2].size() > 6 && SubNames[2].substr(0,6) == "Vertex")
01665 VtId3 = std::atoi(SubNames[2].substr(6,4000).c_str());
01666 }
01667
01668 if (GeoId1 != Constraint::GeoUndef && GeoId3 == Constraint::GeoUndef) {
01669 std::swap(GeoId1,GeoId3);
01670 std::swap(VtId1,VtId3);
01671 }
01672 else if (GeoId2 != Constraint::GeoUndef && GeoId3 == Constraint::GeoUndef) {
01673 std::swap(GeoId2,GeoId3);
01674 std::swap(VtId2,VtId3);
01675 }
01676
01677 if (VtId1 >= 0 && VtId2 >= 0 && GeoId3 != Constraint::GeoUndef) {
01678 Sketcher::PointPos PosId1,PosId2;
01679 Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1);
01680 Obj->getGeoVertexIndex(VtId2,GeoId2,PosId2);
01681 const Part::Geometry *geom = geo[GeoId3];
01682 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01683
01684 openCommand("add symmetric constraint");
01685 Gui::Command::doCommand(
01686 Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Symmetric',%d,%d,%d,%d,%d)) ",
01687 selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,GeoId3);
01688
01689
01690 commitCommand();
01691 updateActive();
01692
01693
01694 getSelection().clearSelection();
01695 return;
01696 }
01697 }
01698 QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
01699 QObject::tr("Select two points and one line from the sketch."));
01700 }
01701
01702 bool CmdSketcherConstrainSymmetric::isActive(void)
01703 {
01704 return isCreateConstraintActive( getActiveGuiDocument() );
01705 }
01706
01707
01708
01709 void CreateSketcherCommandsConstraints(void)
01710 {
01711 Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
01712
01713 rcCmdMgr.addCommand(new CmdSketcherConstrainHorizontal());
01714 rcCmdMgr.addCommand(new CmdSketcherConstrainVertical());
01715 rcCmdMgr.addCommand(new CmdSketcherConstrainLock());
01716 rcCmdMgr.addCommand(new CmdSketcherConstrainCoincident());
01717 rcCmdMgr.addCommand(new CmdSketcherConstrainParallel());
01718 rcCmdMgr.addCommand(new CmdSketcherConstrainPerpendicular());
01719 rcCmdMgr.addCommand(new CmdSketcherConstrainTangent());
01720 rcCmdMgr.addCommand(new CmdSketcherConstrainDistance());
01721 rcCmdMgr.addCommand(new CmdSketcherConstrainDistanceX());
01722 rcCmdMgr.addCommand(new CmdSketcherConstrainDistanceY());
01723 rcCmdMgr.addCommand(new CmdSketcherConstrainRadius());
01724 rcCmdMgr.addCommand(new CmdSketcherConstrainAngle());
01725 rcCmdMgr.addCommand(new CmdSketcherConstrainEqual());
01726 rcCmdMgr.addCommand(new CmdSketcherConstrainPointOnObject());
01727 rcCmdMgr.addCommand(new CmdSketcherConstrainSymmetric());
01728 }