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 #endif
00027
00028 #include <Base/Console.h>
00029
00030 #include <Gui/Application.h>
00031 #include <Gui/Document.h>
00032 #include <Gui/Command.h>
00033 #include <Gui/MainWindow.h>
00034 #include <Gui/DlgEditFileIncludeProptertyExternal.h>
00035 #include <Gui/Selection.h>
00036 #include <Gui/SelectionFilter.h>
00037 #include <Mod/Sketcher/App/SketchObject.h>
00038
00039 #include "ViewProviderSketch.h"
00040 #include "DrawSketchHandler.h"
00041
00042 using namespace std;
00043 using namespace SketcherGui;
00044
00045
00046
00047 void ActivateHandler(Gui::Document *doc,DrawSketchHandler *handler)
00048 {
00049 if (doc) {
00050 if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom
00051 (SketcherGui::ViewProviderSketch::getClassTypeId()))
00052 dynamic_cast<SketcherGui::ViewProviderSketch*>
00053 (doc->getInEdit())->activateHandler(handler);
00054 }
00055 }
00056
00057 bool isCreateGeoActive(Gui::Document *doc)
00058 {
00059 if (doc) {
00060
00061 if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom
00062 (SketcherGui::ViewProviderSketch::getClassTypeId())) {
00063 if (dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit())->
00064 getSketchMode() == ViewProviderSketch::STATUS_NONE)
00065 return true;
00066 }
00067 }
00068 return false;
00069 }
00070
00071 SketcherGui::ViewProviderSketch* getSketchViewprovider(Gui::Document *doc)
00072 {
00073 if (doc) {
00074 if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom
00075 (SketcherGui::ViewProviderSketch::getClassTypeId()) )
00076 return dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
00077 }
00078 return 0;
00079 }
00080
00081
00082
00083
00084 static const char *cursor_createline[]={
00085 "32 32 3 1",
00086 "+ c white",
00087 "# c red",
00088 ". c None",
00089 "......+.........................",
00090 "......+.........................",
00091 "......+.........................",
00092 "......+.........................",
00093 "......+.........................",
00094 "................................",
00095 "+++++...+++++...................",
00096 "................................",
00097 "......+...............###.......",
00098 "......+...............#.#.......",
00099 "......+...............###.......",
00100 "......+..............#..........",
00101 "......+.............#...........",
00102 "....................#...........",
00103 "...................#............",
00104 "..................#.............",
00105 "..................#.............",
00106 ".................#..............",
00107 "................#...............",
00108 "................#...............",
00109 "...............#................",
00110 "..............#.................",
00111 "..............#.................",
00112 ".............#..................",
00113 "..........###...................",
00114 "..........#.#...................",
00115 "..........###...................",
00116 "................................",
00117 "................................",
00118 "................................",
00119 "................................",
00120 "................................"};
00121
00122 class DrawSketchHandlerLine: public DrawSketchHandler
00123 {
00124 public:
00125 DrawSketchHandlerLine():Mode(STATUS_SEEK_First),EditCurve(2){}
00126 virtual ~DrawSketchHandlerLine(){}
00128 enum SelectMode {
00129 STATUS_SEEK_First,
00130 STATUS_SEEK_Second,
00131 STATUS_End
00132 };
00133
00134 virtual void activated(ViewProviderSketch *sketchgui)
00135 {
00136 setCursor(QPixmap(cursor_createline),7,7);
00137 }
00138
00139 virtual void mouseMove(Base::Vector2D onSketchPos)
00140 {
00141 setPositionText(onSketchPos);
00142
00143 if (Mode==STATUS_SEEK_First) {
00144 if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f))) {
00145 renderSuggestConstraintsCursor(sugConstr1);
00146 return;
00147 }
00148 }
00149 else if (Mode==STATUS_SEEK_Second){
00150 EditCurve[1] = onSketchPos;
00151 sketchgui->drawEdit(EditCurve);
00152 if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - EditCurve[0])) {
00153 renderSuggestConstraintsCursor(sugConstr2);
00154 return;
00155 }
00156 }
00157 applyCursor();
00158 }
00159
00160 virtual bool pressButton(Base::Vector2D onSketchPos)
00161 {
00162 if (Mode==STATUS_SEEK_First){
00163 EditCurve[0] = onSketchPos;
00164 Mode = STATUS_SEEK_Second;
00165 }
00166 else {
00167 EditCurve[1] = onSketchPos;
00168 sketchgui->drawEdit(EditCurve);
00169 Mode = STATUS_End;
00170 }
00171 return true;
00172 }
00173
00174 virtual bool releaseButton(Base::Vector2D onSketchPos)
00175 {
00176 if (Mode==STATUS_End){
00177 unsetCursor();
00178 resetPositionText();
00179
00180 Gui::Command::openCommand("Add sketch line");
00181 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
00182 sketchgui->getObject()->getNameInDocument(),
00183 EditCurve[0].fX,EditCurve[0].fY,EditCurve[1].fX,EditCurve[1].fY);
00184 Gui::Command::commitCommand();
00185 Gui::Command::updateActive();
00186
00187
00188 if (sugConstr1.size() > 0) {
00189 createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::start);
00190 sugConstr1.clear();
00191 }
00192
00193
00194 if (sugConstr2.size() > 0) {
00195 createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::end);
00196 sugConstr2.clear();
00197 }
00198
00199 EditCurve.clear();
00200 sketchgui->drawEdit(EditCurve);
00201 sketchgui->purgeHandler();
00202 }
00203 return true;
00204 }
00205 protected:
00206 SelectMode Mode;
00207 std::vector<Base::Vector2D> EditCurve;
00208 std::vector<AutoConstraint> sugConstr1, sugConstr2;
00209 };
00210
00211
00212
00213 DEF_STD_CMD_A(CmdSketcherCreateLine);
00214
00215 CmdSketcherCreateLine::CmdSketcherCreateLine()
00216 : Command("Sketcher_CreateLine")
00217 {
00218 sAppModule = "Sketcher";
00219 sGroup = QT_TR_NOOP("Sketcher");
00220 sMenuText = QT_TR_NOOP("Create line");
00221 sToolTipText = QT_TR_NOOP("Create a line in the sketch");
00222 sWhatsThis = sToolTipText;
00223 sStatusTip = sToolTipText;
00224 sPixmap = "Sketcher_CreateLine";
00225 sAccel = "L";
00226 eType = ForEdit;
00227 }
00228
00229 void CmdSketcherCreateLine::activated(int iMsg)
00230 {
00231 ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerLine() );
00232 }
00233
00234 bool CmdSketcherCreateLine::isActive(void)
00235 {
00236 return isCreateGeoActive(getActiveGuiDocument());
00237 }
00238
00239
00240
00241
00242
00243 static const char *cursor_createbox[]={
00244 "32 32 3 1",
00245 "+ c white",
00246 "# c red",
00247 ". c None",
00248 "......+.........................",
00249 "......+.........................",
00250 "......+.........................",
00251 "......+.........................",
00252 "......+.........................",
00253 "................................",
00254 "+++++...+++++...................",
00255 "................................",
00256 "......+.........................",
00257 "......+.........................",
00258 "......+.........................",
00259 "......+.........................",
00260 "......+.........................",
00261 "................................",
00262 "................................",
00263 "..........................###...",
00264 "...........################.#...",
00265 "...........#..............###...",
00266 "...........#...............#....",
00267 "...........#...............#....",
00268 "...........#...............#....",
00269 "...........#...............#....",
00270 "...........#...............#....",
00271 "...........#...............#....",
00272 "..........###..............#....",
00273 "..........#.################....",
00274 "..........###...................",
00275 "................................",
00276 "................................",
00277 "................................",
00278 "................................",
00279 "................................"};
00280
00281 class DrawSketchHandlerBox: public DrawSketchHandler
00282 {
00283 public:
00284 DrawSketchHandlerBox():Mode(STATUS_SEEK_First),EditCurve(5){}
00285 virtual ~DrawSketchHandlerBox(){}
00287 enum BoxMode {
00288 STATUS_SEEK_First,
00289 STATUS_SEEK_Second,
00290 STATUS_End
00291 };
00292
00293 virtual void activated(ViewProviderSketch *sketchgui)
00294 {
00295 setCursor(QPixmap(cursor_createbox),7,7);
00296 }
00297
00298 virtual void mouseMove(Base::Vector2D onSketchPos)
00299 {
00300 setPositionText(onSketchPos);
00301
00302 if (Mode==STATUS_SEEK_First) {
00303 if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f))) {
00304 renderSuggestConstraintsCursor(sugConstr1);
00305 return;
00306 }
00307 }
00308 else if (Mode==STATUS_SEEK_Second) {
00309 EditCurve[2] = onSketchPos;
00310 EditCurve[1] = Base::Vector2D(onSketchPos.fX ,EditCurve[0].fY);
00311 EditCurve[3] = Base::Vector2D(EditCurve[0].fX,onSketchPos.fY);
00312 sketchgui->drawEdit(EditCurve);
00313 if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f))) {
00314 renderSuggestConstraintsCursor(sugConstr2);
00315 return;
00316 }
00317 }
00318 applyCursor();
00319 }
00320
00321 virtual bool pressButton(Base::Vector2D onSketchPos)
00322 {
00323 if (Mode==STATUS_SEEK_First){
00324 EditCurve[0] = onSketchPos;
00325 EditCurve[4] = onSketchPos;
00326 Mode = STATUS_SEEK_Second;
00327 }
00328 else {
00329 EditCurve[2] = onSketchPos;
00330 EditCurve[1] = Base::Vector2D(onSketchPos.fX ,EditCurve[0].fY);
00331 EditCurve[3] = Base::Vector2D(EditCurve[0].fX,onSketchPos.fY);
00332 sketchgui->drawEdit(EditCurve);
00333 Mode = STATUS_End;
00334 }
00335 return true;
00336 }
00337
00338 virtual bool releaseButton(Base::Vector2D onSketchPos)
00339 {
00340 if (Mode==STATUS_End){
00341 unsetCursor();
00342 resetPositionText();
00343 Gui::Command::openCommand("Add sketch box");
00344 int firstCurve = getHighestCurveIndex() + 1;
00345
00346 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
00347 sketchgui->getObject()->getNameInDocument(),
00348 EditCurve[0].fX,EditCurve[0].fY,EditCurve[1].fX,EditCurve[1].fY);
00349 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
00350 sketchgui->getObject()->getNameInDocument(),
00351 EditCurve[1].fX,EditCurve[1].fY,EditCurve[2].fX,EditCurve[2].fY);
00352 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
00353 sketchgui->getObject()->getNameInDocument(),
00354 EditCurve[2].fX,EditCurve[2].fY,EditCurve[3].fX,EditCurve[3].fY);
00355 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
00356 sketchgui->getObject()->getNameInDocument(),
00357 EditCurve[3].fX,EditCurve[3].fY,EditCurve[0].fX,EditCurve[0].fY);
00358
00359 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,2,%i,1)) "
00360 ,sketchgui->getObject()->getNameInDocument()
00361 ,firstCurve,firstCurve+1);
00362 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,2,%i,1)) "
00363 ,sketchgui->getObject()->getNameInDocument()
00364 ,firstCurve+1,firstCurve+2);
00365 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,2,%i,1)) "
00366 ,sketchgui->getObject()->getNameInDocument()
00367 ,firstCurve+2,firstCurve+3);
00368 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,2,%i,1)) "
00369 ,sketchgui->getObject()->getNameInDocument()
00370 ,firstCurve+3,firstCurve);
00371
00372 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Horizontal',%i)) "
00373 ,sketchgui->getObject()->getNameInDocument()
00374 ,firstCurve);
00375 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Horizontal',%i)) "
00376 ,sketchgui->getObject()->getNameInDocument()
00377 ,firstCurve+2);
00378
00379 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Vertical',%i)) "
00380 ,sketchgui->getObject()->getNameInDocument()
00381 ,firstCurve+1);
00382 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Vertical',%i)) "
00383 ,sketchgui->getObject()->getNameInDocument()
00384 ,firstCurve+3);
00385
00386 Gui::Command::commitCommand();
00387 Gui::Command::updateActive();
00388
00389
00390 if (sugConstr1.size() > 0) {
00391 createAutoConstraints(sugConstr1, getHighestCurveIndex() - 3 , Sketcher::start);
00392 sugConstr1.clear();
00393 }
00394
00395
00396 if (sugConstr2.size() > 0) {
00397 createAutoConstraints(sugConstr2, getHighestCurveIndex() - 2, Sketcher::end);
00398 sugConstr2.clear();
00399 }
00400
00401 EditCurve.clear();
00402 sketchgui->drawEdit(EditCurve);
00403 sketchgui->purgeHandler();
00404 }
00405 return true;
00406 }
00407 protected:
00408 BoxMode Mode;
00409 std::vector<Base::Vector2D> EditCurve;
00410 std::vector<AutoConstraint> sugConstr1, sugConstr2;
00411 };
00412
00413
00414
00415 DEF_STD_CMD_A(CmdSketcherCreateRectangle);
00416
00417 CmdSketcherCreateRectangle::CmdSketcherCreateRectangle()
00418 : Command("Sketcher_CreateRectangle")
00419 {
00420 sAppModule = "Sketcher";
00421 sGroup = QT_TR_NOOP("Sketcher");
00422 sMenuText = QT_TR_NOOP("Create rectangle");
00423 sToolTipText = QT_TR_NOOP("Create a rectangle in the sketch");
00424 sWhatsThis = sToolTipText;
00425 sStatusTip = sToolTipText;
00426 sPixmap = "Sketcher_CreateRectangle";
00427 sAccel = "R";
00428 eType = ForEdit;
00429 }
00430
00431 void CmdSketcherCreateRectangle::activated(int iMsg)
00432 {
00433 ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerBox() );
00434 }
00435
00436 bool CmdSketcherCreateRectangle::isActive(void)
00437 {
00438 return isCreateGeoActive(getActiveGuiDocument());
00439 }
00440
00441
00442
00443
00444
00445 static const char *cursor_createlineset[]={
00446 "32 32 3 1",
00447 "+ c white",
00448 "# c red",
00449 ". c None",
00450 "......+.........................",
00451 "......+.........................",
00452 "......+.........................",
00453 "......+.........................",
00454 "......+.........................",
00455 "................................",
00456 "+++++...+++++...................",
00457 "................................",
00458 "......+...............###.......",
00459 "......+...............#.#.......",
00460 "......+...............###.......",
00461 "......+..............#..#.......",
00462 "......+.............#....#......",
00463 "....................#....#......",
00464 "...................#......#.....",
00465 "..................#.......#.....",
00466 "..................#........#....",
00467 ".................#.........#....",
00468 "................#..........###..",
00469 "................#..........#.#..",
00470 "......#........#...........###..",
00471 ".......#......#.................",
00472 "........#.....#.................",
00473 ".........#...#..................",
00474 "..........###...................",
00475 "..........#.#...................",
00476 "..........###...................",
00477 "................................",
00478 "................................",
00479 "................................",
00480 "................................",
00481 "................................"};
00482
00483 class DrawSketchHandlerLineSet: public DrawSketchHandler
00484 {
00485 public:
00486 DrawSketchHandlerLineSet()
00487 : Mode(STATUS_SEEK_First),EditCurve(2),firstPoint(-1),previousCurve(-1){}
00488 virtual ~DrawSketchHandlerLineSet(){}
00490 enum SelectMode {
00491 STATUS_SEEK_First,
00492 STATUS_SEEK_Second,
00493 STATUS_Do,
00494 STATUS_Close
00495 };
00496
00497 virtual void activated(ViewProviderSketch *sketchgui)
00498 {
00499 setCursor(QPixmap(cursor_createlineset),7,7);
00500 }
00501
00502 virtual void mouseMove(Base::Vector2D onSketchPos)
00503 {
00504 setPositionText(onSketchPos);
00505 if (Mode==STATUS_SEEK_First) {
00506 if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f))) {
00507 renderSuggestConstraintsCursor(sugConstr1);
00508 return;
00509 }
00510 }
00511 else if (Mode==STATUS_SEEK_Second){
00512 EditCurve[1] = onSketchPos;
00513 sketchgui->drawEdit(EditCurve);
00514 if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - EditCurve[0])) {
00515 renderSuggestConstraintsCursor(sugConstr2);
00516 return;
00517 }
00518 }
00519 applyCursor();
00520 }
00521
00522 virtual bool pressButton(Base::Vector2D onSketchPos)
00523 {
00524 if (Mode==STATUS_SEEK_First) {
00525
00526 firstPoint = getHighestVertexIndex() + 1;
00527 firstCurve = getHighestCurveIndex() + 1;
00528 EditCurve[0] = onSketchPos;
00529 Mode = STATUS_SEEK_Second;
00530 }
00531 else if (Mode==STATUS_SEEK_Second) {
00532 EditCurve[1] = onSketchPos;
00533 sketchgui->drawEdit(EditCurve);
00534 applyCursor();
00535
00536 if (EditCurve[1] == EditCurve[0]) {
00537 unsetCursor();
00538 EditCurve.clear();
00539 resetPositionText();
00540 sketchgui->drawEdit(EditCurve);
00541 sketchgui->purgeHandler();
00542 }
00543 if (sketchgui->getPreselectPoint() == firstPoint)
00544 Mode = STATUS_Close;
00545 else
00546 Mode = STATUS_Do;
00547 }
00548 return true;
00549 }
00550
00551 virtual bool releaseButton(Base::Vector2D onSketchPos)
00552 {
00553 if (Mode==STATUS_Do || Mode==STATUS_Close) {
00554
00555 Gui::Command::openCommand("add sketch wire");
00556
00557 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
00558 sketchgui->getObject()->getNameInDocument(),
00559 EditCurve[0].fX,EditCurve[0].fY,EditCurve[1].fX,EditCurve[1].fY);
00560
00561
00562 if (previousCurve != -1) {
00563 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,2,%i,1)) "
00564 ,sketchgui->getObject()->getNameInDocument()
00565 ,previousCurve-1,previousCurve
00566 );
00567 }
00568
00569 if (Mode==STATUS_Close) {
00570
00571 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,2,%i,1)) "
00572 ,sketchgui->getObject()->getNameInDocument()
00573 ,previousCurve,firstCurve
00574 );
00575
00576 Gui::Command::commitCommand();
00577 Gui::Command::updateActive();
00578
00579 if (sugConstr2.size() > 0) {
00580
00581 std::vector<AutoConstraint> sugConstr;
00582 for (int i=0; i < sugConstr2.size(); i++) {
00583 if (sugConstr2[i].Type != Sketcher::Coincident)
00584 sugConstr.push_back(sugConstr2[i]);
00585 }
00586 createAutoConstraints(sugConstr, getHighestCurveIndex(), Sketcher::end);
00587 sugConstr2.clear();
00588 }
00589
00590 unsetCursor();
00591 EditCurve.clear();
00592 resetPositionText();
00593 sketchgui->drawEdit(EditCurve);
00594 sketchgui->purgeHandler();
00595 }
00596 else {
00597 Gui::Command::commitCommand();
00598 Gui::Command::updateActive();
00599
00600
00601 if (sugConstr1.size() > 0) {
00602 createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::start);
00603 sugConstr1.clear();
00604 }
00605
00606 if (sugConstr2.size() > 0) {
00607 createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::end);
00608 sugConstr2.clear();
00609 }
00610
00611
00612 previousCurve = getHighestCurveIndex() + 1;
00613
00614
00615
00616 Part::Geometry *geom = getObject()->Geometry.getValues()[getHighestCurveIndex()];
00617 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
00618 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geom);
00619 EditCurve[0] = Base::Vector2D(lineSeg->getEndPoint().x, lineSeg->getEndPoint().y);
00620 }
00621 else
00622 EditCurve[0] = onSketchPos;
00623
00624 sketchgui->drawEdit(EditCurve);
00625 applyCursor();
00626
00627 Mode = STATUS_SEEK_Second;
00628 }
00629 }
00630 return true;
00631 }
00632 protected:
00633 SelectMode Mode;
00634 std::vector<Base::Vector2D> EditCurve;
00635 Base::Vector2D lastPos;
00636 int firstPoint;
00637 int firstCurve;
00638 int previousCurve;
00639 std::vector<AutoConstraint> sugConstr1, sugConstr2;
00640 };
00641
00642
00643 DEF_STD_CMD_A(CmdSketcherCreatePolyline);
00644
00645 CmdSketcherCreatePolyline::CmdSketcherCreatePolyline()
00646 : Command("Sketcher_CreatePolyline")
00647 {
00648 sAppModule = "Sketcher";
00649 sGroup = QT_TR_NOOP("Sketcher");
00650 sMenuText = QT_TR_NOOP("Create polyline");
00651 sToolTipText = QT_TR_NOOP("Create a polyline in the sketch");
00652 sWhatsThis = sToolTipText;
00653 sStatusTip = sToolTipText;
00654 sPixmap = "Sketcher_CreatePolyline";
00655 eType = ForEdit;
00656 }
00657
00658 void CmdSketcherCreatePolyline::activated(int iMsg)
00659 {
00660 ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerLineSet() );
00661 }
00662
00663 bool CmdSketcherCreatePolyline::isActive(void)
00664 {
00665 return isCreateGeoActive(getActiveGuiDocument());
00666 }
00667
00668
00669
00670
00671 static const char *cursor_createarc[]={
00672 "32 32 3 1",
00673 "+ c white",
00674 "# c red",
00675 ". c None",
00676 "......+...........###...........",
00677 "......+...........#.#...........",
00678 "......+...........###...........",
00679 "......+..............##.........",
00680 "......+...............##........",
00681 ".......................#........",
00682 "+++++...+++++...........#.......",
00683 "........................##......",
00684 "......+..................#......",
00685 "......+..................#......",
00686 "......+...................#.....",
00687 "......+...................#.....",
00688 "......+...................#.....",
00689 "..........................#.....",
00690 "..........................#.....",
00691 "..........................#.....",
00692 "..........................#.....",
00693 ".........................#......",
00694 ".........................#......",
00695 "........................#.......",
00696 "........................#.......",
00697 "...###.................#........",
00698 "...#.#................#.........",
00699 "...###...............#..........",
00700 "......##...........##...........",
00701 ".......###.......##.............",
00702 "..........#######...............",
00703 "................................",
00704 "................................",
00705 "................................",
00706 "................................",
00707 "................................"};
00708
00709 class DrawSketchHandlerArc : public DrawSketchHandler
00710 {
00711 public:
00712 DrawSketchHandlerArc()
00713 : Mode(STATUS_SEEK_First),EditCurve(2){}
00714 virtual ~DrawSketchHandlerArc(){}
00716 enum SelectMode {
00717 STATUS_SEEK_First,
00718 STATUS_SEEK_Second,
00719 STATUS_SEEK_Third,
00720 STATUS_End
00721 };
00722
00723 virtual void activated(ViewProviderSketch *sketchgui)
00724 {
00725 setCursor(QPixmap(cursor_createarc),7,7);
00726 }
00727
00728 virtual void mouseMove(Base::Vector2D onSketchPos)
00729 {
00730 setPositionText(onSketchPos);
00731
00732 if (Mode==STATUS_SEEK_First) {
00733 if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f))) {
00734 renderSuggestConstraintsCursor(sugConstr1);
00735 return;
00736 }
00737 }
00738 else if (Mode==STATUS_SEEK_Second) {
00739 float dx_ = onSketchPos.fX - EditCurve[0].fX;
00740 float dy_ = onSketchPos.fY - EditCurve[0].fY;
00741 for (int i=0; i < 16; i++) {
00742 float angle = i*M_PI/16.0;
00743 float dx = dx_ * cos(angle) + dy_ * sin(angle);
00744 float dy = -dx_ * sin(angle) + dy_ * cos(angle);
00745 EditCurve[1+i] = Base::Vector2D(EditCurve[0].fX + dx, EditCurve[0].fY + dy);
00746 EditCurve[17+i] = Base::Vector2D(EditCurve[0].fX - dx, EditCurve[0].fY - dy);
00747 }
00748 EditCurve[33] = EditCurve[1];
00749 sketchgui->drawEdit(EditCurve);
00750 if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f))) {
00751 renderSuggestConstraintsCursor(sugConstr2);
00752 return;
00753 }
00754 }
00755 else if (Mode==STATUS_SEEK_Third) {
00756 float angle1 = atan2(onSketchPos.fY - CenterPoint.fY,
00757 onSketchPos.fX - CenterPoint.fX) - startAngle;
00758 float angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI ;
00759 arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;
00760 for (int i=1; i <= 29; i++) {
00761 float angle = i*arcAngle/29.0;
00762 float dx = rx * cos(angle) - ry * sin(angle);
00763 float dy = rx * sin(angle) + ry * cos(angle);
00764 EditCurve[i] = Base::Vector2D(CenterPoint.fX + dx, CenterPoint.fY + dy);
00765 }
00766 sketchgui->drawEdit(EditCurve);
00767 if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2D(0.f,0.f))) {
00768 renderSuggestConstraintsCursor(sugConstr3);
00769 return;
00770 }
00771 }
00772 applyCursor();
00773
00774 }
00775
00776 virtual bool pressButton(Base::Vector2D onSketchPos)
00777 {
00778 if (Mode==STATUS_SEEK_First){
00779 CenterPoint = onSketchPos;
00780 EditCurve.resize(34);
00781 EditCurve[0] = onSketchPos;
00782 Mode = STATUS_SEEK_Second;
00783 }
00784 else if (Mode==STATUS_SEEK_Second){
00785 EditCurve.resize(31);
00786 EditCurve[0] = onSketchPos;
00787 EditCurve[30] = CenterPoint;
00788 rx = EditCurve[0].fX - CenterPoint.fX;
00789 ry = EditCurve[0].fY - CenterPoint.fY;
00790 startAngle = atan2(ry, rx);
00791 arcAngle = 0.;
00792 Mode = STATUS_SEEK_Third;
00793 }
00794 else {
00795 EditCurve.resize(30);
00796 float angle1 = atan2(onSketchPos.fY - CenterPoint.fY,
00797 onSketchPos.fX - CenterPoint.fX) - startAngle;
00798 float angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI ;
00799 arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;
00800 if (arcAngle > 0)
00801 endAngle = startAngle + arcAngle;
00802 else {
00803 endAngle = startAngle;
00804 startAngle += arcAngle;
00805 }
00806
00807 sketchgui->drawEdit(EditCurve);
00808 applyCursor();
00809 Mode = STATUS_End;
00810 }
00811
00812 return true;
00813 }
00814
00815 virtual bool releaseButton(Base::Vector2D onSketchPos)
00816 {
00817 if (Mode==STATUS_End) {
00818 unsetCursor();
00819 resetPositionText();
00820 Gui::Command::openCommand("Add sketch arc");
00821 Gui::Command::doCommand(Gui::Command::Doc,
00822 "App.ActiveDocument.%s.addGeometry(Part.ArcOfCircle"
00823 "(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),"
00824 "%f,%f))",
00825 sketchgui->getObject()->getNameInDocument(),
00826 CenterPoint.fX, CenterPoint.fY, sqrt(rx*rx + ry*ry),
00827 startAngle, endAngle);
00828
00829 Gui::Command::commitCommand();
00830 Gui::Command::updateActive();
00831
00832
00833 if (sugConstr1.size() > 0) {
00834 createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::mid);
00835 sugConstr1.clear();
00836 }
00837
00838
00839 if (sugConstr2.size() > 0) {
00840 createAutoConstraints(sugConstr2, getHighestCurveIndex(), (arcAngle > 0) ? Sketcher::start : Sketcher::end );
00841 sugConstr2.clear();
00842 }
00843
00844
00845 if (sugConstr3.size() > 0) {
00846 createAutoConstraints(sugConstr3, getHighestCurveIndex(), (arcAngle > 0) ? Sketcher::end : Sketcher::start);
00847 sugConstr3.clear();
00848 }
00849
00850 EditCurve.clear();
00851 sketchgui->drawEdit(EditCurve);
00852 sketchgui->purgeHandler();
00853 }
00854 return true;
00855 }
00856 protected:
00857 SelectMode Mode;
00858 std::vector<Base::Vector2D> EditCurve;
00859 Base::Vector2D CenterPoint;
00860 float rx, ry, startAngle, endAngle, arcAngle;
00861 std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3;
00862 };
00863
00864 DEF_STD_CMD_A(CmdSketcherCreateArc);
00865
00866 CmdSketcherCreateArc::CmdSketcherCreateArc()
00867 : Command("Sketcher_CreateArc")
00868 {
00869 sAppModule = "Sketcher";
00870 sGroup = QT_TR_NOOP("Sketcher");
00871 sMenuText = QT_TR_NOOP("Create arc");
00872 sToolTipText = QT_TR_NOOP("Create an arc in the sketch");
00873 sWhatsThis = sToolTipText;
00874 sStatusTip = sToolTipText;
00875 sPixmap = "Sketcher_CreateArc";
00876 eType = ForEdit;
00877 }
00878
00879 void CmdSketcherCreateArc::activated(int iMsg)
00880 {
00881 ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerArc() );
00882 }
00883
00884 bool CmdSketcherCreateArc::isActive(void)
00885 {
00886 return isCreateGeoActive(getActiveGuiDocument());
00887 }
00888
00889
00890
00891
00892 static const char *cursor_createcircle[]={
00893 "32 32 3 1",
00894 "+ c white",
00895 "# c red",
00896 ". c None",
00897 "......+.........................",
00898 "......+.........................",
00899 "......+.........................",
00900 "......+.........................",
00901 "......+.........................",
00902 "................................",
00903 "+++++...+++++...................",
00904 "................................",
00905 "......+........#######..........",
00906 "......+......##.......##........",
00907 "......+.....#...........#.......",
00908 "......+....#.............#......",
00909 "......+...#...............#.....",
00910 ".........#.................#....",
00911 "........#...................#...",
00912 "........#...................#...",
00913 ".......#.....................#..",
00914 ".......#.....................#..",
00915 ".......#.........###.........#..",
00916 ".......#.........#.#.........#..",
00917 ".......#.........###.........#..",
00918 ".......#.....................#..",
00919 ".......#.....................#..",
00920 "........#...................#...",
00921 "........#...................#...",
00922 ".........#.................#....",
00923 "..........#...............#.....",
00924 "...........#.............#......",
00925 "............#...........#.......",
00926 ".............##.......##........",
00927 "...............#######..........",
00928 "................................"};
00929
00930 class DrawSketchHandlerCircle : public DrawSketchHandler
00931 {
00932 public:
00933 DrawSketchHandlerCircle() : Mode(STATUS_SEEK_First),EditCurve(34){}
00934 virtual ~DrawSketchHandlerCircle(){}
00936 enum SelectMode {
00937 STATUS_SEEK_First,
00938 STATUS_SEEK_Second,
00939 STATUS_Close
00940 };
00941
00942 virtual void activated(ViewProviderSketch *sketchgui)
00943 {
00944 setCursor(QPixmap(cursor_createcircle),7,7);
00945 }
00946
00947 virtual void mouseMove(Base::Vector2D onSketchPos)
00948 {
00949 setPositionText(onSketchPos);
00950 if (Mode==STATUS_SEEK_First) {
00951 if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f))) {
00952 renderSuggestConstraintsCursor(sugConstr1);
00953 return;
00954 }
00955 }
00956 else if (Mode==STATUS_SEEK_Second) {
00957 float rx0 = onSketchPos.fX - EditCurve[0].fX;
00958 float ry0 = onSketchPos.fY - EditCurve[0].fY;
00959 for (int i=0; i < 16; i++) {
00960 float angle = i*M_PI/16.0;
00961 float rx = rx0 * cos(angle) + ry0 * sin(angle);
00962 float ry = -rx0 * sin(angle) + ry0 * cos(angle);
00963 EditCurve[1+i] = Base::Vector2D(EditCurve[0].fX + rx, EditCurve[0].fY + ry);
00964 EditCurve[17+i] = Base::Vector2D(EditCurve[0].fX - rx, EditCurve[0].fY - ry);
00965 }
00966 EditCurve[33] = EditCurve[1];
00967 sketchgui->drawEdit(EditCurve);
00968 if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f), CURVE)) {
00969 renderSuggestConstraintsCursor(sugConstr2);
00970 return;
00971 }
00972 }
00973 applyCursor();
00974 }
00975
00976 virtual bool pressButton(Base::Vector2D onSketchPos)
00977 {
00978 if (Mode==STATUS_SEEK_First){
00979 EditCurve[0] = onSketchPos;
00980 Mode = STATUS_SEEK_Second;
00981 } else {
00982 EditCurve[1] = onSketchPos;
00983 Mode = STATUS_Close;
00984 }
00985 return true;
00986 }
00987
00988 virtual bool releaseButton(Base::Vector2D onSketchPos)
00989 {
00990 if (Mode==STATUS_Close) {
00991 float rx = EditCurve[1].fX - EditCurve[0].fX;
00992 float ry = EditCurve[1].fY - EditCurve[0].fY;
00993 unsetCursor();
00994 resetPositionText();
00995 Gui::Command::openCommand("Add sketch circle");
00996 Gui::Command::doCommand(Gui::Command::Doc,
00997 "App.ActiveDocument.%s.addGeometry(Part.Circle"
00998 "(App.Vector(%f,%f,0),App.Vector(0,0,1),%f))",
00999 sketchgui->getObject()->getNameInDocument(),
01000 EditCurve[0].fX, EditCurve[0].fY,
01001 sqrt(rx*rx + ry*ry));
01002
01003 Gui::Command::commitCommand();
01004 Gui::Command::updateActive();
01005
01006
01007 if (sugConstr1.size() > 0) {
01008 createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::mid);
01009 sugConstr1.clear();
01010 }
01011
01012
01013 if (sugConstr2.size() > 0) {
01014 createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::none);
01015 sugConstr2.clear();
01016 }
01017
01018 EditCurve.clear();
01019 sketchgui->drawEdit(EditCurve);
01020 sketchgui->purgeHandler();
01021 }
01022 return true;
01023 }
01024 protected:
01025 SelectMode Mode;
01026 std::vector<Base::Vector2D> EditCurve;
01027 std::vector<AutoConstraint> sugConstr1, sugConstr2;
01028
01029 };
01030
01031 DEF_STD_CMD_A(CmdSketcherCreateCircle);
01032
01033 CmdSketcherCreateCircle::CmdSketcherCreateCircle()
01034 : Command("Sketcher_CreateCircle")
01035 {
01036 sAppModule = "Sketcher";
01037 sGroup = QT_TR_NOOP("Sketcher");
01038 sMenuText = QT_TR_NOOP("Create circle");
01039 sToolTipText = QT_TR_NOOP("Create a circle in the sketch");
01040 sWhatsThis = sToolTipText;
01041 sStatusTip = sToolTipText;
01042 sPixmap = "Sketcher_CreateCircle";
01043 eType = ForEdit;
01044 }
01045
01046 void CmdSketcherCreateCircle::activated(int iMsg)
01047 {
01048 ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerCircle() );
01049 }
01050
01051 bool CmdSketcherCreateCircle::isActive(void)
01052 {
01053 return isCreateGeoActive(getActiveGuiDocument());
01054 }
01055
01056
01057
01058 DEF_STD_CMD_A(CmdSketcherCreatePoint);
01059
01060 CmdSketcherCreatePoint::CmdSketcherCreatePoint()
01061 : Command("Sketcher_CreatePoint")
01062 {
01063 sAppModule = "Sketcher";
01064 sGroup = QT_TR_NOOP("Sketcher");
01065 sMenuText = QT_TR_NOOP("Create point");
01066 sToolTipText = QT_TR_NOOP("Create a point in the sketch");
01067 sWhatsThis = sToolTipText;
01068 sStatusTip = sToolTipText;
01069 sPixmap = "Sketcher_CreatePoint";
01070 eType = ForEdit;
01071 }
01072
01073 void CmdSketcherCreatePoint::activated(int iMsg)
01074 {
01075 }
01076
01077 bool CmdSketcherCreatePoint::isActive(void)
01078 {
01079 return false;
01080 }
01081
01082
01083
01084 DEF_STD_CMD_A(CmdSketcherCreateText);
01085
01086 CmdSketcherCreateText::CmdSketcherCreateText()
01087 : Command("Sketcher_CreateText")
01088 {
01089 sAppModule = "Sketcher";
01090 sGroup = QT_TR_NOOP("Sketcher");
01091 sMenuText = QT_TR_NOOP("Create text");
01092 sToolTipText = QT_TR_NOOP("Create text in the sketch");
01093 sWhatsThis = sToolTipText;
01094 sStatusTip = sToolTipText;
01095 sPixmap = "Sketcher_CreateText";
01096 eType = ForEdit;
01097 }
01098
01099 void CmdSketcherCreateText::activated(int iMsg)
01100 {
01101 }
01102
01103 bool CmdSketcherCreateText::isActive(void)
01104 {
01105 return false;
01106 }
01107
01108
01109
01110 DEF_STD_CMD_A(CmdSketcherCreateDraftLine);
01111
01112 CmdSketcherCreateDraftLine::CmdSketcherCreateDraftLine()
01113 : Command("Sketcher_CreateDraftLine")
01114 {
01115 sAppModule = "Sketcher";
01116 sGroup = QT_TR_NOOP("Sketcher");
01117 sMenuText = QT_TR_NOOP("Create draft line");
01118 sToolTipText = QT_TR_NOOP("Create a draft line in the sketch");
01119 sWhatsThis = sToolTipText;
01120 sStatusTip = sToolTipText;
01121 sPixmap = "Sketcher_DraftLine";
01122 eType = ForEdit;
01123 }
01124
01125 void CmdSketcherCreateDraftLine::activated(int iMsg)
01126 {
01127 }
01128
01129 bool CmdSketcherCreateDraftLine::isActive(void)
01130 {
01131 return false;
01132 }
01133
01134
01135
01136 namespace SketcherGui {
01137 class FilletSelection : public Gui::SelectionFilterGate
01138 {
01139 App::DocumentObject* object;
01140 public:
01141 FilletSelection(App::DocumentObject* obj)
01142 : Gui::SelectionFilterGate((Gui::SelectionFilter*)0), object(obj)
01143 {}
01144
01145 bool allow(App::Document *pDoc, App::DocumentObject *pObj, const char *sSubName)
01146 {
01147 if (pObj != this->object)
01148 return false;
01149 if (!sSubName || sSubName[0] == '\0')
01150 return false;
01151 std::string element(sSubName);
01152 if (element.substr(0,4) == "Edge") {
01153 int index=std::atoi(element.substr(4,4000).c_str());
01154 Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
01155 const std::vector<Part::Geometry *> &geo = Sketch->Geometry.getValues();
01156 const Part::Geometry *geom = geo[index];
01157 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId())
01158 return true;
01159 }
01160 if (element.substr(0,6) == "Vertex") {
01161 int index=std::atoi(element.substr(6,4000).c_str());
01162 Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
01163 std::vector<int> GeoIdList;
01164 std::vector<Sketcher::PointPos> PosIdList;
01165 Sketch->getCoincidentPoints(index, GeoIdList, PosIdList);
01166 if (GeoIdList.size() == 2) {
01167 const std::vector<Part::Geometry *> &geo = Sketch->Geometry.getValues();
01168 const Part::Geometry *geom1 = geo[GeoIdList[0]];
01169 const Part::Geometry *geom2 = geo[GeoIdList[1]];
01170 if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
01171 geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId())
01172 return true;
01173 }
01174 }
01175 return false;
01176 }
01177 };
01178 };
01179
01180
01181 static const char *cursor_createfillet[]={
01182 "32 32 3 1",
01183 "+ c white",
01184 "* c red",
01185 ". c None",
01186 "......+.........................",
01187 "......+.........................",
01188 "......+.........................",
01189 "......+.........................",
01190 "......+.........................",
01191 "................................",
01192 "+++++...+++++...................",
01193 "................................",
01194 "......+.........................",
01195 "......+.........................",
01196 "......+.........................",
01197 "......+.........................",
01198 "......+..*......................",
01199 ".........*......................",
01200 ".........*......................",
01201 ".........*......................",
01202 ".........*......................",
01203 ".........*......................",
01204 ".........*.........***..........",
01205 ".........*.........*.*..........",
01206 ".........*.........***..........",
01207 ".........*......................",
01208 ".........*......................",
01209 "..........*.....................",
01210 "..........*.....................",
01211 "...........*....................",
01212 "............*...................",
01213 ".............*..................",
01214 "..............*.................",
01215 "...............**...............",
01216 ".................**************.",
01217 "................................"};
01218
01219 class DrawSketchHandlerFillet: public DrawSketchHandler
01220 {
01221 public:
01222 DrawSketchHandlerFillet() : Mode(STATUS_SEEK_First) {}
01223 virtual ~DrawSketchHandlerFillet()
01224 {
01225 Gui::Selection().rmvSelectionGate();
01226 }
01227 enum SelectMode{
01228 STATUS_SEEK_First,
01229 STATUS_SEEK_Second
01230 };
01231
01232 virtual void activated(ViewProviderSketch *sketchgui)
01233 {
01234 Gui::Selection().rmvSelectionGate();
01235 Gui::Selection().addSelectionGate(new FilletSelection(sketchgui->getObject()));
01236 setCursor(QPixmap(cursor_createfillet),7,7);
01237 }
01238
01239 virtual void mouseMove(Base::Vector2D onSketchPos)
01240 {
01241 }
01242
01243 virtual bool pressButton(Base::Vector2D onSketchPos)
01244 {
01245 return true;
01246 }
01247
01248 virtual bool releaseButton(Base::Vector2D onSketchPos)
01249 {
01250 int VtId = sketchgui->getPreselectPoint();
01251 if (Mode == STATUS_SEEK_First && VtId != -1) {
01252 int GeoId;
01253 Sketcher::PointPos PosId=Sketcher::none;
01254 sketchgui->getSketchObject()->getGeoVertexIndex(VtId,GeoId,PosId);
01255 const std::vector<Part::Geometry *> &geo = sketchgui->getSketchObject()->Geometry.getValues();
01256 const Part::Geometry *geom = geo[GeoId];
01257 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
01258 (PosId == Sketcher::start || PosId == Sketcher::end)) {
01259
01260
01261 double radius=-1;
01262 std::vector<int> GeoIdList;
01263 std::vector<Sketcher::PointPos> PosIdList;
01264 sketchgui->getSketchObject()->getCoincidentPoints(GeoId, PosId, GeoIdList, PosIdList);
01265 if (GeoIdList.size() == 2) {
01266 const Part::Geometry *geom1 = geo[GeoIdList[0]];
01267 const Part::Geometry *geom2 = geo[GeoIdList[1]];
01268 if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
01269 geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01270 const Part::GeomLineSegment *lineSeg1 = dynamic_cast<const Part::GeomLineSegment *>(geom1);
01271 const Part::GeomLineSegment *lineSeg2 = dynamic_cast<const Part::GeomLineSegment *>(geom2);
01272 Base::Vector3d dir1 = lineSeg1->getEndPoint() - lineSeg1->getStartPoint();
01273 Base::Vector3d dir2 = lineSeg2->getEndPoint() - lineSeg2->getStartPoint();
01274 if (PosIdList[0] == Sketcher::end)
01275 dir1 *= -1;
01276 if (PosIdList[1] == Sketcher::end)
01277 dir2 *= -1;
01278 double l1 = dir1.Length();
01279 double l2 = dir2.Length();
01280 double angle = dir1.GetAngle(dir2);
01281 radius = (l1 < l2 ? l1 : l2) * 0.2 * sin(angle/2);
01282 }
01283 }
01284 if (radius < 0)
01285 return false;
01286
01287
01288 Gui::Command::openCommand("Create fillet");
01289 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.fillet(%d,%d,%f)",
01290 sketchgui->getObject()->getNameInDocument(),
01291 GeoId, PosId, radius);
01292 Gui::Command::commitCommand();
01293 Gui::Command::updateActive();
01294 }
01295 return true;
01296 }
01297
01298 int GeoId = sketchgui->getPreselectCurve();
01299 if (GeoId > -1) {
01300 const std::vector<Part::Geometry *> &geo = sketchgui->getSketchObject()->Geometry.getValues();
01301 const Part::Geometry *geom = geo[GeoId];
01302 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01303 if (Mode==STATUS_SEEK_First) {
01304 firstCurve = GeoId;
01305 firstPos = onSketchPos;
01306 Mode = STATUS_SEEK_Second;
01307
01308 std::stringstream ss;
01309 ss << "Edge" << firstCurve;
01310 Gui::Selection().addSelection(sketchgui->getSketchObject()->getDocument()->getName()
01311 ,sketchgui->getSketchObject()->getNameInDocument()
01312 ,ss.str().c_str()
01313 ,onSketchPos.fX
01314 ,onSketchPos.fY
01315 ,0.f);
01316 }
01317 else if (Mode==STATUS_SEEK_Second) {
01318 int secondCurve = GeoId;
01319 Base::Vector2D secondPos = onSketchPos;
01320
01321
01322 const Part::GeomLineSegment *lineSeg1 = dynamic_cast<const Part::GeomLineSegment *>(geo[firstCurve]);
01323 const Part::GeomLineSegment *lineSeg2 = dynamic_cast<const Part::GeomLineSegment *>(geo[secondCurve]);
01324 Base::Vector3d refPnt1(firstPos.fX, firstPos.fY, 0.f);
01325 Base::Vector3d refPnt2(secondPos.fX, secondPos.fY, 0.f);
01326 double radius = Part::suggestFilletRadius(lineSeg1, lineSeg2, refPnt1, refPnt2);
01327 if (radius < 0)
01328 return false;
01329
01330
01331 Gui::Command::openCommand("Create fillet");
01332 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.fillet(%d,%d,App.Vector(%f,%f,0),App.Vector(%f,%f,0),%f)",
01333 sketchgui->getObject()->getNameInDocument(),
01334 firstCurve, secondCurve,
01335 firstPos.fX, firstPos.fY,
01336 secondPos.fX, secondPos.fY, radius);
01337 Gui::Command::commitCommand();
01338 Gui::Command::updateActive();
01339
01340 Gui::Selection().clearSelection();
01341 Mode = STATUS_SEEK_First;
01342 }
01343 }
01344 }
01345
01346 if (VtId < 0 && GeoId < 0)
01347 sketchgui->purgeHandler();
01348
01349 return true;
01350 }
01351
01352 protected:
01353 SelectMode Mode;
01354 int firstCurve;
01355 Base::Vector2D firstPos;
01356 };
01357
01358 DEF_STD_CMD_A(CmdSketcherCreateFillet);
01359
01360 CmdSketcherCreateFillet::CmdSketcherCreateFillet()
01361 : Command("Sketcher_CreateFillet")
01362 {
01363 sAppModule = "Sketcher";
01364 sGroup = QT_TR_NOOP("Sketcher");
01365 sMenuText = QT_TR_NOOP("Create fillet");
01366 sToolTipText = QT_TR_NOOP("Create a fillet between to lines or at a coincident point");
01367 sWhatsThis = sToolTipText;
01368 sStatusTip = sToolTipText;
01369 sPixmap = "Sketcher_CreateFillet";
01370 sAccel = "F";
01371 eType = ForEdit;
01372 }
01373
01374 void CmdSketcherCreateFillet::activated(int iMsg)
01375 {
01376 ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerFillet());
01377 }
01378
01379 bool CmdSketcherCreateFillet::isActive(void)
01380 {
01381 return isCreateGeoActive(getActiveGuiDocument());
01382 }
01383
01384
01385 namespace SketcherGui {
01386 class TrimmingSelection : public Gui::SelectionFilterGate
01387 {
01388 App::DocumentObject* object;
01389 public:
01390 TrimmingSelection(App::DocumentObject* obj)
01391 : Gui::SelectionFilterGate((Gui::SelectionFilter*)0), object(obj)
01392 {}
01393
01394 bool allow(App::Document *pDoc, App::DocumentObject *pObj, const char *sSubName)
01395 {
01396 if (pObj != this->object)
01397 return false;
01398 if (!sSubName || sSubName[0] == '\0')
01399 return false;
01400 std::string element(sSubName);
01401 if (element.substr(0,4) == "Edge") {
01402 int index=std::atoi(element.substr(4,4000).c_str());
01403 Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
01404 const std::vector<Part::Geometry *> &geo = Sketch->Geometry.getValues();
01405 const Part::Geometry *geom = geo[index];
01406 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
01407 geom->getTypeId() == Part::GeomCircle::getClassTypeId()||
01408 geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
01409 return true;
01410 }
01411 return false;
01412 }
01413 };
01414 };
01415
01416
01417 static const char *cursor_trimming[]={
01418 "32 32 3 1",
01419 "+ c white",
01420 "* c red",
01421 ". c None",
01422 "......+.........................",
01423 "......+.........................",
01424 "......+.........................",
01425 "......+.........................",
01426 "......+.........................",
01427 "................................",
01428 "+++++...+++++...................",
01429 "................................",
01430 "......+.........................",
01431 "......+.........................",
01432 "......+......................*..",
01433 "......+....................**...",
01434 "......+...................**....",
01435 ".*..............................",
01436 "..*.....................*.......",
01437 "...*..................**........",
01438 ".....*...............**.........",
01439 "......*.........................",
01440 ".......*..........*.............",
01441 ".........*......**..............",
01442 "..........*....**...............",
01443 "...........****.................",
01444 "............*.*.................",
01445 "............***.................",
01446 "..........*....*................",
01447 ".........*.......*..............",
01448 ".......*..........*.............",
01449 "......*............*............",
01450 "....*................*..........",
01451 "...*..................*.........",
01452 ".*.....................*........",
01453 ".........................*......"};
01454
01455 class DrawSketchHandlerTrimming: public DrawSketchHandler
01456 {
01457 public:
01458 DrawSketchHandlerTrimming() {}
01459 virtual ~DrawSketchHandlerTrimming()
01460 {
01461 Gui::Selection().rmvSelectionGate();
01462 }
01463
01464 virtual void activated(ViewProviderSketch *sketchgui)
01465 {
01466 Gui::Selection().clearSelection();
01467 Gui::Selection().rmvSelectionGate();
01468 Gui::Selection().addSelectionGate(new TrimmingSelection(sketchgui->getObject()));
01469 setCursor(QPixmap(cursor_trimming),7,7);
01470 }
01471
01472 virtual void mouseMove(Base::Vector2D onSketchPos)
01473 {
01474 }
01475
01476 virtual bool pressButton(Base::Vector2D onSketchPos)
01477 {
01478 return true;
01479 }
01480
01481 virtual bool releaseButton(Base::Vector2D onSketchPos)
01482 {
01483 int GeoId = sketchgui->getPreselectCurve();
01484 if (GeoId > -1) {
01485 const std::vector<Part::Geometry *> &geo = sketchgui->getSketchObject()->Geometry.getValues();
01486 const Part::Geometry *geom = geo[GeoId];
01487 if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
01488 geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
01489 geom->getTypeId() == Part::GeomCircle::getClassTypeId()
01490 ) {
01491 try {
01492 Gui::Command::openCommand("Trim edge");
01493 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.trim(%d,App.Vector(%f,%f,0))",
01494 sketchgui->getObject()->getNameInDocument(),
01495 GeoId, onSketchPos.fX, onSketchPos.fY);
01496 Gui::Command::commitCommand();
01497 Gui::Command::updateActive();
01498 }
01499 catch (const Base::Exception& e) {
01500 Base::Console().Error("%s\n", e.what());
01501 }
01502 }
01503 }
01504 else
01505 sketchgui->purgeHandler();
01506
01507 return true;
01508 }
01509 };
01510
01511 DEF_STD_CMD_A(CmdSketcherTrimming);
01512
01513 CmdSketcherTrimming::CmdSketcherTrimming()
01514 : Command("Sketcher_Trimming")
01515 {
01516 sAppModule = "Sketcher";
01517 sGroup = QT_TR_NOOP("Sketcher");
01518 sMenuText = QT_TR_NOOP("Trim edge");
01519 sToolTipText = QT_TR_NOOP("Trims an edge with respect to the picked position");
01520 sWhatsThis = sToolTipText;
01521 sStatusTip = sToolTipText;
01522 sPixmap = "Sketcher_Trimming";
01523 sAccel = "T";
01524 eType = ForEdit;
01525 }
01526
01527 void CmdSketcherTrimming::activated(int iMsg)
01528 {
01529 ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerTrimming());
01530 }
01531
01532 bool CmdSketcherTrimming::isActive(void)
01533 {
01534 return isCreateGeoActive(getActiveGuiDocument());
01535 }
01536
01537
01538 void CreateSketcherCommandsCreateGeo(void)
01539 {
01540 Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
01541
01542
01543 rcCmdMgr.addCommand(new CmdSketcherCreateArc());
01544 rcCmdMgr.addCommand(new CmdSketcherCreateCircle());
01545 rcCmdMgr.addCommand(new CmdSketcherCreateLine());
01546 rcCmdMgr.addCommand(new CmdSketcherCreatePolyline());
01547 rcCmdMgr.addCommand(new CmdSketcherCreateRectangle());
01548 rcCmdMgr.addCommand(new CmdSketcherCreateFillet());
01549
01550
01551 rcCmdMgr.addCommand(new CmdSketcherTrimming());
01552 }