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
00026 #ifndef _PreComp_
00027 # include <Standard_math.hxx>
00028 # include <Poly_Polygon3D.hxx>
00029 # include <Geom_BSplineCurve.hxx>
00030 # include <Geom_Circle.hxx>
00031 # include <Geom_TrimmedCurve.hxx>
00032 # include <Inventor/actions/SoGetBoundingBoxAction.h>
00033 # include <Inventor/SoPath.h>
00034 # include <Inventor/SbBox3f.h>
00035 # include <Inventor/SoPickedPoint.h>
00036 # include <Inventor/details/SoLineDetail.h>
00037 # include <Inventor/details/SoPointDetail.h>
00038 # include <Inventor/nodes/SoBaseColor.h>
00039 # include <Inventor/nodes/SoCoordinate3.h>
00040 # include <Inventor/nodes/SoDrawStyle.h>
00041 # include <Inventor/nodes/SoImage.h>
00042 # include <Inventor/nodes/SoLineSet.h>
00043 # include <Inventor/nodes/SoPointSet.h>
00044 # include <Inventor/nodes/SoMarkerSet.h>
00045 # include <Inventor/nodes/SoMaterial.h>
00046 # include <Inventor/nodes/SoAsciiText.h>
00047 # include <Inventor/nodes/SoTransform.h>
00048 # include <Inventor/nodes/SoSeparator.h>
00049 # include <Inventor/nodes/SoVertexProperty.h>
00050 # include <Inventor/nodes/SoTranslation.h>
00051 # include <Inventor/nodes/SoText2.h>
00052 # include <Inventor/nodes/SoFont.h>
00053 # include <Inventor/sensors/SoIdleSensor.h>
00054 # include <Inventor/nodes/SoCamera.h>
00055
00057 # include <QAction>
00058 # include <QApplication>
00059 # include <QColor>
00060 # include <QDialog>
00061 # include <QFont>
00062 # include <QImage>
00063 # include <QMenu>
00064 # include <QMessageBox>
00065 # include <QPainter>
00066 #endif
00067
00068 #include <Inventor/SbTime.h>
00069
00071 #include <Base/Tools.h>
00072 #include <Base/Parameter.h>
00073 #include <Base/Console.h>
00074 #include <Base/Vector3D.h>
00075 #include <Gui/Application.h>
00076 #include <Gui/BitmapFactory.h>
00077 #include <Gui/Document.h>
00078 #include <Gui/Command.h>
00079 #include <Gui/Control.h>
00080 #include <Gui/Selection.h>
00081 #include <Gui/MainWindow.h>
00082 #include <Gui/MenuManager.h>
00083 #include <Gui/View3DInventor.h>
00084 #include <Gui/View3DInventorViewer.h>
00085 #include <Gui/DlgEditFileIncludeProptertyExternal.h>
00086 #include <Gui/SoFCUnifiedSelection.h>
00087
00088 #include <Mod/Part/App/Geometry.h>
00089 #include <Mod/Sketcher/App/SketchObject.h>
00090 #include <Mod/Sketcher/App/Sketch.h>
00091
00092 #include "SoZoomTranslation.h"
00093 #include "SoDatumLabel.h"
00094 #include "EditDatumDialog.h"
00095 #include "ViewProviderSketch.h"
00096 #include "DrawSketchHandler.h"
00097 #include "TaskDlgEditSketch.h"
00098
00099 using namespace SketcherGui;
00100 using namespace Sketcher;
00101
00102 SbColor ViewProviderSketch::VertexColor (1.0f,0.149f,0.0f);
00103 SbColor ViewProviderSketch::CurveColor (1.0f,1.0f,1.0f);
00104 SbColor ViewProviderSketch::CurveDraftColor (0.0f,0.0f,0.86f);
00105 SbColor ViewProviderSketch::CrossColorV (0.8f,0.4f,0.4f);
00106 SbColor ViewProviderSketch::CrossColorH (0.4f,0.8f,0.4f);
00107 SbColor ViewProviderSketch::FullyConstrainedColor (0.0f,1.0f,0.0f);
00108 SbColor ViewProviderSketch::ConstrDimColor (1.0f,0.149f,0.0f);
00109 SbColor ViewProviderSketch::ConstrIcoColor (1.0f,0.149f,0.0f);
00110 SbColor ViewProviderSketch::PreselectColor (0.88f,0.88f,0.0f);
00111 SbColor ViewProviderSketch::SelectColor (0.11f,0.68f,0.11f);
00112
00113
00114 SbTime ViewProviderSketch::prvClickTime;
00115 SbVec3f ViewProviderSketch::prvClickPoint;
00116
00117
00118
00119
00121 struct EditData {
00122 EditData():
00123 sketchHandler(0),
00124 DragPoint(-1),
00125 DragCurve(-1),
00126 DragConstraint(-1),
00127 PreselectPoint(-1),
00128 PreselectCurve(-1),
00129 PreselectCross(-1),
00130 PreselectConstraint(-1),
00131 blockedPreselection(false),
00132 FullyConstrained(false),
00133
00134 EditRoot(0),
00135 PointsMaterials(0),
00136 CurvesMaterials(0),
00137 PointsCoordinate(0),
00138 CurvesCoordinate(0),
00139 CurveSet(0),
00140 PointSet(0)
00141 {}
00142
00143
00144 DrawSketchHandler *sketchHandler;
00145
00146
00147 int DragPoint;
00148
00149 int DragCurve;
00150
00151 int DragConstraint;
00152
00153 SbColor PreselectOldColor;
00154 int PreselectPoint;
00155 int PreselectCurve;
00156 int PreselectCross;
00157 int PreselectConstraint;
00158 bool blockedPreselection;
00159 bool FullyConstrained;
00160
00161
00162 Sketcher::Sketch ActSketch;
00163
00164 std::set<int> SelPointSet;
00165 std::set<int> SelCurvSet;
00166 std::set<int> SelConstraintSet;
00167 std::set<int> SelCrossSet;
00168
00169
00170 std::vector<ConstraintType> vConstrType;
00171
00172
00173 SoSeparator *EditRoot;
00174 SoMaterial *PointsMaterials;
00175 SoMaterial *CurvesMaterials;
00176 SoMaterial *RootCrossMaterialsV;
00177 SoMaterial *RootCrossMaterialsH;
00178 SoMaterial *EditCurvesMaterials;
00179 SoCoordinate3 *PointsCoordinate;
00180 SoCoordinate3 *CurvesCoordinate;
00181 SoCoordinate3 *RootCrossCoordinateV;
00182 SoCoordinate3 *RootCrossCoordinateH;
00183 SoCoordinate3 *EditCurvesCoordinate;
00184 SoLineSet *CurveSet;
00185 SoLineSet *EditCurveSet;
00186 SoLineSet *RootCrossSetV;
00187 SoLineSet *RootCrossSetH;
00188 SoMarkerSet *PointSet;
00189
00190 SoText2 *textX;
00191 SoTranslation *textPos;
00192
00193 SoGroup *constrGroup;
00194 };
00195
00196
00197
00198
00199
00200 PROPERTY_SOURCE(SketcherGui::ViewProviderSketch, PartGui::ViewProvider2DObject)
00201
00202
00203 ViewProviderSketch::ViewProviderSketch()
00204 : edit(0),
00205 Mode(STATUS_NONE)
00206 {
00207
00208 ADD_PROPERTY_TYPE(Autoconstraints,(true),"Auto Constraints",(App::PropertyType)(App::Prop_None),"Create auto constraints");
00209
00210 sPixmap = "Sketcher_Sketch";
00211 LineColor.setValue(1,1,1);
00212 PointColor.setValue(1,1,1);
00213 PointSize.setValue(4);
00214
00215 zCross=0.001f;
00216 zConstr=0.002f;
00217 zLines=0.003f;
00218 zPoints=0.004f;
00219 zHighlight=0.005f;
00220 zText=0.006f;
00221 zEdit=0.001f;
00222
00223 xInit=0;
00224 yInit=0;
00225 relative=false;
00226 }
00227
00228 ViewProviderSketch::~ViewProviderSketch()
00229 {
00230 }
00231
00232
00233 void ViewProviderSketch::activateHandler(DrawSketchHandler *newHandler)
00234 {
00235 assert(edit);
00236 assert(edit->sketchHandler == 0);
00237 edit->sketchHandler = newHandler;
00238 Mode = STATUS_SKETCH_UseHandler;
00239 edit->sketchHandler->sketchgui = this;
00240 edit->sketchHandler->activated(this);
00241 }
00242
00244 void ViewProviderSketch::purgeHandler(void)
00245 {
00246 assert(edit);
00247 assert(edit->sketchHandler != 0);
00248 delete(edit->sketchHandler);
00249 edit->sketchHandler = 0;
00250 Mode = STATUS_NONE;
00251 }
00252
00253
00254
00255 bool ViewProviderSketch::keyPressed(bool pressed, int key)
00256 {
00257 switch (key)
00258 {
00259 case SoKeyboardEvent::ESCAPE:
00260 {
00261
00262 if (edit && edit->sketchHandler) {
00263 if (!pressed)
00264 edit->sketchHandler->quit();
00265 return true;
00266 }
00267 return false;
00268 }
00269 }
00270
00271 return true;
00272 }
00273
00274 void ViewProviderSketch::snapToGrid(double &x, double &y)
00275 {
00276 if (GridSnap.getValue() != false) {
00277
00278 const double snapTol = GridSize.getValue() / 5;
00279
00280 double tmpX = x, tmpY = y;
00281
00282
00283 tmpX = tmpX / GridSize.getValue();
00284 tmpX = tmpX < 0.0 ? ceil(tmpX - 0.5) : floor(tmpX + 0.5);
00285 tmpX *= GridSize.getValue();
00286
00287 tmpY = tmpY / GridSize.getValue();
00288 tmpY = tmpY < 0.0 ? ceil(tmpY - 0.5) : floor(tmpY + 0.5);
00289 tmpY *= GridSize.getValue();
00290
00291
00292 if (x < tmpX + snapTol && x > tmpX - snapTol)
00293 x = tmpX;
00294
00295
00296 if (y < tmpY + snapTol && y > tmpY - snapTol)
00297 y = tmpY;
00298 }
00299 }
00300
00301 void ViewProviderSketch::getCoordsOnSketchPlane(double &u, double &v,const SbVec3f &point, const SbVec3f &normal)
00302 {
00303
00304 Base::Vector3d R0(0,0,0),RN(0,0,1),RX(1,0,0),RY(0,1,0);
00305
00306
00307 Base::Placement Plz = getSketchObject()->Placement.getValue();
00308 R0 = Plz.getPosition() ;
00309 Base::Rotation tmp(Plz.getRotation());
00310 tmp.multVec(RN,RN);
00311 tmp.multVec(RX,RX);
00312 tmp.multVec(RY,RY);
00313 Plz.setRotation(tmp);
00314
00315
00316 Base::Vector3d R1(point[0],point[1],point[2]),RA(normal[0],normal[1],normal[2]);
00317 if (fabs(RN*RA) < FLT_EPSILON)
00318 throw Base::Exception("View direction is parallel to sketch plane");
00319
00320 Base::Vector3d S = R1 + ((RN * (R0-R1))/(RN*RA))*RA;
00321
00322
00323 S.TransformToCoordinateSystem(R0,RX,RY);
00324
00325 u = S.x;
00326 v = S.y;
00327 }
00328
00329 bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVec3f &point,
00330 const SbVec3f &normal, const SoPickedPoint *pp)
00331 {
00332 assert(edit);
00333
00334
00335 const int dblClickRadius = 5;
00336
00337 double x,y;
00338 SbVec3f pos = point;
00339 if (pp) {
00340 const SoDetail *detail = pp->getDetail();
00341 if (detail && detail->getTypeId() == SoPointDetail::getClassTypeId()) {
00342 pos = pp->getPoint();
00343 }
00344 }
00345
00346 getCoordsOnSketchPlane(x,y,pos,normal);
00347 snapToGrid(x, y);
00348
00349
00350 if (Button == 1) {
00351 if (pressed) {
00352
00353 switch (Mode) {
00354 case STATUS_NONE:{
00355 bool done=false;
00356
00357 SbTime tmp = (SbTime::getTimeOfDay() - prvClickTime);
00358 float dci = (float) QApplication::doubleClickInterval()/1000.0f;
00359 float length = (point - prvClickPoint).length();
00360
00361 if (edit->PreselectPoint >=0) {
00362
00363 Mode = STATUS_SELECT_Point;
00364 done = true;
00365 } else if (edit->PreselectCurve >=0) {
00366
00367 Mode = STATUS_SELECT_Edge;
00368 done = true;
00369 } else if (edit->PreselectCross >=0) {
00370
00371 Mode = STATUS_SELECT_Cross;
00372 done = true;
00373 } else if (edit->PreselectConstraint >=0) {
00374
00375 Mode = STATUS_SELECT_Constraint;
00376 done = true;
00377
00378 }
00379
00380 if (done && length < dblClickRadius && tmp.getValue() < dci) {
00381
00382 editDoubleClicked();
00383
00384 prvClickTime = SbTime();
00385 prvClickPoint = SbVec3f(0.0f, 0.0f, 0.0f);
00386 Mode = STATUS_NONE;
00387
00388 } else {
00389 prvClickTime = SbTime::getTimeOfDay();
00390 prvClickPoint = point;
00391 }
00392
00393 return done;
00394 }
00395 case STATUS_SKETCH_UseHandler:
00396 return edit->sketchHandler->pressButton(Base::Vector2D(x,y));
00397 default:
00398 return false;
00399 }
00400 }
00401 else {
00402
00403 switch (Mode) {
00404 case STATUS_SELECT_Point:
00405 if (pp) {
00406
00407
00408 std::stringstream ss;
00409 ss << "Vertex" << edit->PreselectPoint;
00410
00411 if (Gui::Selection().isSelected(getSketchObject()->getDocument()->getName()
00412 ,getSketchObject()->getNameInDocument(),ss.str().c_str()) ) {
00413 Gui::Selection().rmvSelection(getSketchObject()->getDocument()->getName()
00414 ,getSketchObject()->getNameInDocument(), ss.str().c_str());
00415 } else {
00416 Gui::Selection().addSelection(getSketchObject()->getDocument()->getName()
00417 ,getSketchObject()->getNameInDocument()
00418 ,ss.str().c_str()
00419 ,pp->getPoint()[0]
00420 ,pp->getPoint()[1]
00421 ,pp->getPoint()[2]);
00422 this->edit->DragPoint = -1;
00423 this->edit->DragCurve = -1;
00424 this->edit->DragConstraint = -1;
00425 }
00426 }
00427 Mode = STATUS_NONE;
00428 return true;
00429 case STATUS_SELECT_Edge:
00430 if (pp) {
00431
00432 std::stringstream ss;
00433 ss << "Edge" << edit->PreselectCurve;
00434
00435
00436 if (Gui::Selection().isSelected(getSketchObject()->getDocument()->getName()
00437 ,getSketchObject()->getNameInDocument(),ss.str().c_str()) ) {
00438 Gui::Selection().rmvSelection(getSketchObject()->getDocument()->getName()
00439 ,getSketchObject()->getNameInDocument(), ss.str().c_str());
00440 } else {
00441
00442 Gui::Selection().addSelection(getSketchObject()->getDocument()->getName()
00443 ,getSketchObject()->getNameInDocument()
00444 ,ss.str().c_str()
00445 ,pp->getPoint()[0]
00446 ,pp->getPoint()[1]
00447 ,pp->getPoint()[2]);
00448 this->edit->DragPoint = -1;
00449 this->edit->DragCurve = -1;
00450 this->edit->DragConstraint = -1;
00451 }
00452 }
00453 Mode = STATUS_NONE;
00454 return true;
00455 case STATUS_SELECT_Cross:
00456 if (pp) {
00457
00458 std::stringstream ss;
00459 switch(edit->PreselectCross){
00460 case 0: ss << "RootPoint" ; break;
00461 case 1: ss << "H_Axis" ; break;
00462 case 2: ss << "V_Axis" ; break;
00463 }
00464
00465
00466
00467 if (Gui::Selection().isSelected(getSketchObject()->getDocument()->getName()
00468 ,getSketchObject()->getNameInDocument(),ss.str().c_str()) ) {
00469 Gui::Selection().rmvSelection(getSketchObject()->getDocument()->getName()
00470 ,getSketchObject()->getNameInDocument(), ss.str().c_str());
00471 } else {
00472
00473 Gui::Selection().addSelection(getSketchObject()->getDocument()->getName()
00474 ,getSketchObject()->getNameInDocument()
00475 ,ss.str().c_str()
00476 ,pp->getPoint()[0]
00477 ,pp->getPoint()[1]
00478 ,pp->getPoint()[2]);
00479 this->edit->DragPoint = -1;
00480 this->edit->DragCurve = -1;
00481 this->edit->DragConstraint = -1;
00482 }
00483 }
00484 Mode = STATUS_NONE;
00485 return true;
00486 case STATUS_SELECT_Constraint:
00487 if (pp) {
00488
00489 std::stringstream ss;
00490 ss << "Constraint" << edit->PreselectConstraint;
00491
00492
00493 if (Gui::Selection().isSelected(getSketchObject()->getDocument()->getName()
00494 ,getSketchObject()->getNameInDocument(),ss.str().c_str()) ) {
00495 Gui::Selection().rmvSelection(getSketchObject()->getDocument()->getName()
00496 ,getSketchObject()->getNameInDocument(), ss.str().c_str());
00497 } else {
00498
00499 Gui::Selection().addSelection(getSketchObject()->getDocument()->getName()
00500 ,getSketchObject()->getNameInDocument()
00501 ,ss.str().c_str()
00502 ,pp->getPoint()[0]
00503 ,pp->getPoint()[1]
00504 ,pp->getPoint()[2]);
00505 this->edit->DragPoint = -1;
00506 this->edit->DragCurve = -1;
00507 this->edit->DragConstraint = -1;
00508 }
00509 }
00510 Mode = STATUS_NONE;
00511 return true;
00512 case STATUS_SKETCH_DragPoint:
00513 if (edit->DragPoint != -1 && pp) {
00514 int GeoId;
00515 Sketcher::PointPos PosId;
00516 getSketchObject()->getGeoVertexIndex(edit->DragPoint, GeoId, PosId);
00517 Gui::Command::openCommand("Drag Point");
00518 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.movePoint(%i,%i,App.Vector(%f,%f,0),%i)"
00519 ,getObject()->getNameInDocument()
00520 ,GeoId, PosId, x-xInit, y-yInit, relative ? 1 : 0
00521 );
00522 Gui::Command::commitCommand();
00523 Gui::Command::updateActive();
00524
00525 setPreselectPoint(edit->DragPoint);
00526 edit->DragPoint = -1;
00527
00528 }
00529 resetPositionText();
00530 Mode = STATUS_NONE;
00531 return true;
00532 case STATUS_SKETCH_DragCurve:
00533 if (edit->DragCurve != -1 && pp) {
00534 const std::vector<Part::Geometry *> *geomlist;
00535 geomlist = &getSketchObject()->Geometry.getValues();
00536 Part::Geometry *geo = (*geomlist)[edit->DragCurve];
00537 if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
00538 geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
00539 geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
00540 Gui::Command::openCommand("Drag Curve");
00541 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.movePoint(%i,%i,App.Vector(%f,%f,0),%i)"
00542 ,getObject()->getNameInDocument()
00543 ,edit->DragCurve, Sketcher::none, x-xInit, y-yInit, relative ? 1 : 0
00544 );
00545 Gui::Command::commitCommand();
00546 Gui::Command::updateActive();
00547 }
00548 edit->PreselectCurve = edit->DragCurve;
00549 edit->DragCurve = -1;
00550
00551 }
00552 resetPositionText();
00553 Mode = STATUS_NONE;
00554 return true;
00555 case STATUS_SKETCH_DragConstraint:
00556 if (edit->DragConstraint != -1 && pp) {
00557 Gui::Command::openCommand("Drag Constraint");
00558 moveConstraint(edit->DragConstraint, Base::Vector2D(x, y));
00559 edit->PreselectConstraint = edit->DragConstraint;
00560 edit->DragConstraint = -1;
00561
00562 }
00563 Mode = STATUS_NONE;
00564 return true;
00565 case STATUS_SKETCH_UseHandler:
00566 return edit->sketchHandler->releaseButton(Base::Vector2D(x,y));
00567 case STATUS_NONE:
00568 default:
00569 return false;
00570 }
00571 }
00572 }
00573
00574 else if (Button == 2) {
00575 if (!pressed) {
00576 switch (Mode) {
00577 case STATUS_SKETCH_UseHandler:
00578
00579 edit->sketchHandler->quit();
00580 return true;
00581 case STATUS_NONE:
00582 {
00583
00584 if (edit->PreselectPoint >=0) {
00585 return true;
00586 } else if (edit->PreselectCurve >=0) {
00587 return true;
00588 } else if (edit->PreselectConstraint >=0) {
00589 return true;
00590 } else {
00591
00592 Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
00593 Gui::View3DInventorViewer *viewer ;
00594 viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
00595
00596 Gui::MenuItem *geom = new Gui::MenuItem();
00597 geom->setCommand("Sketcher geoms");
00598 *geom
00599 << "Sketcher_CreateArc"
00600 << "Sketcher_CreateCircle"
00601 << "Sketcher_CreateLine"
00602 << "Sketcher_CreatePolyline"
00603 << "Sketcher_CreateRectangle"
00604 << "Sketcher_CreateFillet"
00605 << "Sketcher_Trimming"
00606 << "Sketcher_ToggleConstruction"
00607
00608 ;
00609
00610 Gui::Application::Instance->setupContextMenu("View", geom);
00611
00612 QMenu contextMenu(viewer->getGLWidget());
00613 Gui::MenuManager::getInstance()->setupContextMenu(geom, contextMenu);
00614 QAction *used = contextMenu.exec(QCursor::pos());
00615
00616 return true;
00617 }
00618 }
00619 case STATUS_SELECT_Point:
00620 break;
00621 case STATUS_SELECT_Edge:
00622 {
00623
00624 Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
00625 Gui::View3DInventorViewer *viewer ;
00626 viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
00627
00628 Gui::MenuItem *geom = new Gui::MenuItem();
00629 geom->setCommand("Sketcher constraints");
00630 *geom << "Sketcher_ConstrainVertical"
00631 << "Sketcher_ConstrainHorizontal";
00632
00633
00634 std::vector<Gui::SelectionObject> selection = Gui::Selection().getSelectionEx();
00635
00636 bool rightClickOnSelectedLine = false;
00637
00638
00639
00640
00641
00642 if (selection.size() == 1) {
00643
00644 const std::vector<std::string> &SubNames = selection[0].getSubNames();
00645
00646
00647 if (SubNames.size() == 2) {
00648
00649 for (std::vector<std::string>::const_iterator it=SubNames.begin();
00650 it!=SubNames.end();++it) {
00651
00652
00653 if (it->size() > 4 && it->substr(0,4) == "Edge") {
00654
00655 int index=std::atoi(it->substr(4,4000).c_str());
00656 if (edit->PreselectCurve == index)
00657 rightClickOnSelectedLine = true;
00658 } else {
00659
00660 rightClickOnSelectedLine = false;
00661 }
00662 }
00663 }
00664 }
00665
00666 if (rightClickOnSelectedLine) {
00667 *geom << "Sketcher_ConstrainParallel"
00668 << "Sketcher_ConstrainPerpendicular";
00669 }
00670
00671 Gui::Application::Instance->setupContextMenu("View", geom);
00672
00673 QMenu contextMenu(viewer->getGLWidget());
00674 Gui::MenuManager::getInstance()->setupContextMenu(geom, contextMenu);
00675 QAction *used = contextMenu.exec(QCursor::pos());
00676
00677 return true;
00678 }
00679 case STATUS_SELECT_Cross:
00680 case STATUS_SELECT_Constraint:
00681 case STATUS_SKETCH_DragPoint:
00682 case STATUS_SKETCH_DragCurve:
00683 case STATUS_SKETCH_DragConstraint:
00684 break;
00685 }
00686 }
00687 }
00688
00689 return false;
00690 }
00691
00692 void ViewProviderSketch::editDoubleClicked(void)
00693 {
00694 if (edit->PreselectPoint >=0) {
00695 Base::Console().Log("double click point:%d\n",edit->PreselectPoint);
00696 } else if (edit->PreselectCurve >=0) {
00697 Base::Console().Log("double click edge:%d\n",edit->PreselectCurve);
00698 } else if (edit->PreselectCross >=0) {
00699 Base::Console().Log("double click cross:%d\n",edit->PreselectCross);
00700 } else if (edit->PreselectConstraint >=0) {
00701
00702 Base::Console().Log("double click constraint:%d\n",edit->PreselectConstraint);
00703
00704 const std::vector<Sketcher::Constraint *> &ConStr = getSketchObject()->Constraints.getValues();
00705 Constraint *Constr = ConStr[edit->PreselectConstraint];
00706
00707
00708 if (Constr->Type == Sketcher::Distance ||
00709 Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY ||
00710 Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Angle) {
00711
00712 EditDatumDialog * editDatumDialog = new EditDatumDialog(this, edit->PreselectConstraint);
00713 SoIdleSensor* sensor = new SoIdleSensor(EditDatumDialog::run, editDatumDialog);
00714 sensor->schedule();
00715 }
00716 }
00717 }
00718
00719 bool ViewProviderSketch::mouseMove(const SbVec3f &point, const SbVec3f &normal, const SoPickedPoint *pp)
00720 {
00721 if (!edit)
00722 return false;
00723 assert(edit);
00724
00725 double x,y;
00726 getCoordsOnSketchPlane(x,y,point,normal);
00727 snapToGrid(x, y);
00728
00729 bool preselectChanged;
00730 if (Mode!=STATUS_SKETCH_DragPoint && Mode!=STATUS_SKETCH_DragCurve &&
00731 Mode!=STATUS_SKETCH_DragConstraint) {
00732 int PtIndex,CurvIndex,ConstrIndex,CrossIndex;
00733 preselectChanged = detectPreselection(pp,PtIndex,CurvIndex,ConstrIndex,CrossIndex);
00734 }
00735
00736 switch (Mode) {
00737 case STATUS_NONE:
00738 if (preselectChanged) {
00739 this->drawConstraintIcons();
00740 this->updateColor();
00741 return true;
00742 }
00743 return false;
00744 case STATUS_SELECT_Point:
00745 if (!edit->ActSketch.hasConflicts() &&
00746 edit->PreselectPoint != -1 && edit->DragPoint != edit->PreselectPoint) {
00747 Mode = STATUS_SKETCH_DragPoint;
00748 edit->DragPoint = edit->PreselectPoint;
00749 int GeoId;
00750 Sketcher::PointPos PosId;
00751 getSketchObject()->getGeoVertexIndex(edit->DragPoint, GeoId, PosId);
00752 edit->ActSketch.initMove(GeoId, PosId);
00753 relative = false;
00754 xInit = 0;
00755 yInit = 0;
00756 } else {
00757 Mode = STATUS_NONE;
00758 }
00759 resetPreselectPoint();
00760 edit->PreselectCurve = -1;
00761 edit->PreselectCross = -1;
00762 edit->PreselectConstraint = -1;
00763 return true;
00764 case STATUS_SELECT_Edge:
00765 if (!edit->ActSketch.hasConflicts() &&
00766 edit->PreselectCurve != -1 && edit->DragCurve != edit->PreselectCurve) {
00767 Mode = STATUS_SKETCH_DragCurve;
00768 edit->DragCurve = edit->PreselectCurve;
00769 edit->ActSketch.initMove(edit->DragCurve, Sketcher::none);
00770 Part::Geometry *geo = getSketchObject()->Geometry.getValues()[edit->DragCurve];
00771 if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
00772 relative = true;
00773 xInit = x;
00774 yInit = y;
00775 } else {
00776 relative = false;
00777 xInit = 0;
00778 yInit = 0;
00779 }
00780 } else {
00781 Mode = STATUS_NONE;
00782 }
00783 resetPreselectPoint();
00784 edit->PreselectCurve = -1;
00785 edit->PreselectCross = -1;
00786 edit->PreselectConstraint = -1;
00787 return true;
00788 case STATUS_SELECT_Constraint:
00789 Mode = STATUS_SKETCH_DragConstraint;
00790 edit->DragConstraint = edit->PreselectConstraint;
00791 resetPreselectPoint();
00792 edit->PreselectCurve = -1;
00793 edit->PreselectCross = -1;
00794 edit->PreselectConstraint = -1;
00795 return true;
00796 case STATUS_SKETCH_DragPoint:
00797 if (edit->DragPoint != -1) {
00798
00799 int GeoId;
00800 Sketcher::PointPos PosId;
00801 getSketchObject()->getGeoVertexIndex(edit->DragPoint, GeoId, PosId);
00802 Base::Vector3d vec(x-xInit,y-yInit,0);
00803 if (edit->ActSketch.movePoint(GeoId, PosId, vec, relative) == 0) {
00804 setPositionText(Base::Vector2D(x,y));
00805 draw(true);
00806 signalSolved(0, edit->ActSketch.SolveTime);
00807 } else {
00808 signalSolved(1, edit->ActSketch.SolveTime);
00809
00810 }
00811 }
00812 return true;
00813 case STATUS_SKETCH_DragCurve:
00814 if (edit->DragCurve != -1) {
00815 Base::Vector3d vec(x-xInit,y-yInit,0);
00816 if (edit->ActSketch.movePoint(edit->DragCurve, Sketcher::none, vec, relative) == 0) {
00817 setPositionText(Base::Vector2D(x,y));
00818 draw(true);
00819 signalSolved(0, edit->ActSketch.SolveTime);
00820 } else {
00821 signalSolved(1, edit->ActSketch.SolveTime);
00822 }
00823 }
00824 return true;
00825 case STATUS_SKETCH_DragConstraint:
00826 if (edit->DragConstraint != -1) {
00827 moveConstraint(edit->DragConstraint, Base::Vector2D(x,y));
00828 }
00829 return true;
00830 case STATUS_SKETCH_UseHandler:
00831 edit->sketchHandler->mouseMove(Base::Vector2D(x,y));
00832 if (preselectChanged) {
00833 this->drawConstraintIcons();
00834 this->updateColor();
00835 }
00836 return true;
00837 default:
00838 return false;
00839 }
00840
00841 return false;
00842 }
00843
00844 void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPos)
00845 {
00846
00847 if (!edit)
00848 return;
00849
00850 const std::vector<Sketcher::Constraint *> &ConStr = getSketchObject()->Constraints.getValues();
00851 Constraint *Constr = ConStr[constNum];
00852
00853 if (Constr->Type == Distance || Constr->Type == DistanceX || Constr->Type == DistanceY ||
00854 Constr->Type == Radius) {
00855
00856 const std::vector<Part::Geometry *> geomlist = edit->ActSketch.getGeometry();
00857 assert(Constr->First < int(geomlist.size()));
00858
00859 Base::Vector3d p1(0.,0.,0.), p2(0.,0.,0.);
00860 if (Constr->SecondPos != Sketcher::none) {
00861 p1 = edit->ActSketch.getPoint(Constr->First, Constr->FirstPos);
00862 p2 = edit->ActSketch.getPoint(Constr->Second, Constr->SecondPos);
00863 } else if (Constr->Second != Constraint::GeoUndef) {
00864 p1 = edit->ActSketch.getPoint(Constr->First, Constr->FirstPos);
00865 const Part::Geometry *geo = geomlist[Constr->Second];
00866 if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
00867 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
00868 Base::Vector3d l2p1 = lineSeg->getStartPoint();
00869 Base::Vector3d l2p2 = lineSeg->getEndPoint();
00870
00871 p2.ProjToLine(p1-l2p1, l2p2-l2p1);
00872 p2 += p1;
00873 } else
00874 return;
00875 } else if (Constr->FirstPos != Sketcher::none) {
00876 p2 = edit->ActSketch.getPoint(Constr->First, Constr->FirstPos);
00877 } else if (Constr->First != Constraint::GeoUndef) {
00878 const Part::Geometry *geo = geomlist[Constr->First];
00879 if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
00880 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
00881 p1 = lineSeg->getStartPoint();
00882 p2 = lineSeg->getEndPoint();
00883 } else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
00884 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo);
00885 double radius = arc->getRadius();
00886 double startangle, endangle;
00887 arc->getRange(startangle, endangle);
00888 double angle = (startangle + endangle)/2;
00889 p1 = arc->getCenter();
00890 p2 = p1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
00891 }
00892 else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
00893 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo);
00894 double radius = circle->getRadius();
00895 double angle = M_PI/4;
00896 p1 = circle->getCenter();
00897 p2 = p1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
00898 } else
00899 return;
00900 } else
00901 return;
00902
00903 Base::Vector3d vec = Base::Vector3d(toPos.fX, toPos.fY, 0) - p2;
00904
00905 Base::Vector3d dir;
00906 if (Constr->Type == Distance || Constr->Type == Radius)
00907 dir = (p2-p1).Normalize();
00908 else if (Constr->Type == DistanceX)
00909 dir = Base::Vector3d( (p2.x - p1.x >= FLT_EPSILON) ? 1 : -1, 0, 0);
00910 else if (Constr->Type == DistanceY)
00911 dir = Base::Vector3d(0, (p2.y - p1.y >= FLT_EPSILON) ? 1 : -1, 0);
00912
00913 if (Constr->Type == Radius)
00914 Constr->LabelDistance = vec.x * dir.x + vec.y * dir.y;
00915 else {
00916 Base::Vector3d norm(-dir.y,dir.x,0);
00917 Constr->LabelDistance = vec.x * norm.x + vec.y * norm.y;
00918 }
00919 }
00920 else if (Constr->Type == Angle) {
00921 const std::vector<Part::Geometry *> geomlist = edit->ActSketch.getGeometry();
00922 assert(Constr->First < int(geomlist.size()));
00923
00924 Base::Vector3d p0(0.,0.,0.);
00925 if (Constr->Second != Constraint::GeoUndef) {
00926 const Part::Geometry *geo1 = geomlist[Constr->First];
00927 const Part::Geometry *geo2 = geomlist[Constr->Second];
00928 if (geo1->getTypeId() != Part::GeomLineSegment::getClassTypeId() ||
00929 geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId())
00930 return;
00931 const Part::GeomLineSegment *lineSeg1 = dynamic_cast<const Part::GeomLineSegment *>(geo1);
00932 const Part::GeomLineSegment *lineSeg2 = dynamic_cast<const Part::GeomLineSegment *>(geo2);
00933
00934 bool flip1 = (Constr->FirstPos == end);
00935 bool flip2 = (Constr->SecondPos == end);
00936 Base::Vector3d dir1 = (flip1 ? -1. : 1.) * (lineSeg1->getEndPoint()-lineSeg1->getStartPoint());
00937 Base::Vector3d dir2 = (flip2 ? -1. : 1.) * (lineSeg2->getEndPoint()-lineSeg2->getStartPoint());
00938 Base::Vector3d pnt1 = flip1 ? lineSeg1->getEndPoint() : lineSeg1->getStartPoint();
00939 Base::Vector3d pnt2 = flip2 ? lineSeg2->getEndPoint() : lineSeg2->getStartPoint();
00940
00941
00942 {
00943 double det = dir1.x*dir2.y - dir1.y*dir2.x;
00944 if ((det > 0 ? det : -det) < 1e-10)
00945 return;
00946 double c1 = dir1.y*pnt1.x - dir1.x*pnt1.y;
00947 double c2 = dir2.y*pnt2.x - dir2.x*pnt2.y;
00948 double x = (dir1.x*c2 - dir2.x*c1)/det;
00949 double y = (dir1.y*c2 - dir2.y*c1)/det;
00950 p0 = Base::Vector3d(x,y,0);
00951 }
00952 } else if (Constr->First != Constraint::GeoUndef) {
00953 const Part::Geometry *geo = geomlist[Constr->First];
00954 if (geo->getTypeId() != Part::GeomLineSegment::getClassTypeId())
00955 return;
00956 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
00957 p0 = (lineSeg->getEndPoint()+lineSeg->getStartPoint())/2;
00958 } else
00959 return;
00960
00961 Base::Vector3d vec = Base::Vector3d(toPos.fX, toPos.fY, 0) - p0;
00962 Constr->LabelDistance = vec.Length()/2;
00963 }
00964 draw(true);
00965 }
00966
00967 bool ViewProviderSketch::isConstraintAtPosition(const Base::Vector3d &constrPos, const SoNode *constraint)
00968 {
00969 assert(edit);
00970 Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
00971 Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
00972
00973 SoRayPickAction rp(viewer->getViewportRegion());
00974 rp.setRadius(0.1f);
00975
00976 rp.setRay(SbVec3f(constrPos.x, constrPos.y,constrPos.z), SbVec3f(0, 0, 1) );
00977
00978 rp.apply(edit->constrGroup);
00979
00980
00981 SoPickedPoint *pp = rp.getPickedPoint();
00982
00983 if (pp) {
00984 SoPath *path = pp->getPath();
00985 int length = path->getLength();
00986 SoNode *tailFather = path->getNode(length-2);
00987 SoNode *tailFather2 = path->getNode(length-3);
00988
00989
00990 if (tailFather2 == constraint || tailFather == constraint) {
00991 return false;
00992 } else {
00993 return true;
00994 }
00995 } else {
00996 return false;
00997 }
00998 }
00999
01000 Base::Vector3d ViewProviderSketch::seekConstraintPosition(const Base::Vector3d &suggestedPos,
01001 const Base::Vector3d &dir, float step,
01002 const SoNode *constraint)
01003 {
01004 int multiplier = 0;
01005 Base::Vector3d freePos;
01006 do {
01007
01008 freePos = suggestedPos + (dir * (multiplier * step));
01009 multiplier++;
01010 }
01011 while (isConstraintAtPosition(freePos, constraint));
01012 return freePos;
01013 }
01014
01015 bool ViewProviderSketch::isSelectable(void) const
01016 {
01017 if (isEditing())
01018 return false;
01019 else
01020 return PartGui::ViewProvider2DObject::isSelectable();
01021 }
01022
01023 void ViewProviderSketch::onSelectionChanged(const Gui::SelectionChanges& msg)
01024 {
01025
01026 if (edit) {
01027 std::string temp;
01028 if (msg.Type == Gui::SelectionChanges::ClrSelection) {
01029
01030 if (edit->SelPointSet.size() > 0 || edit->SelCurvSet.size() > 0 || edit->SelCrossSet.size() > 0 || edit->SelConstraintSet.size() > 0) {
01031
01032 clearSelectPoints();
01033 edit->SelCurvSet.clear();
01034 edit->SelCrossSet.clear();
01035 edit->SelConstraintSet.clear();
01036 this->drawConstraintIcons();
01037 this->updateColor();
01038 }
01039 }
01040 else if (msg.Type == Gui::SelectionChanges::AddSelection) {
01041
01042 if (strcmp(msg.pDocName,getSketchObject()->getDocument()->getName())==0
01043 && strcmp(msg.pObjectName,getSketchObject()->getNameInDocument())== 0) {
01044 if (msg.pSubName) {
01045 std::string shapetype(msg.pSubName);
01046 if (shapetype.size() > 4 && shapetype.substr(0,4) == "Edge") {
01047 int index=std::atoi(&shapetype[4]);
01048 edit->SelCurvSet.insert(index);
01049 this->updateColor();
01050 }
01051 else if (shapetype.size() > 6 && shapetype.substr(0,6) == "Vertex") {
01052 int index=std::atoi(&shapetype[6]);
01053 addSelectPoint(index);
01054 this->updateColor();
01055 }
01056 else if (shapetype == "RootPoint") {
01057 edit->SelCrossSet.insert(0);
01058 this->updateColor();
01059 }
01060 else if (shapetype == "V_Axis") {
01061 edit->SelCrossSet.insert(2);
01062 this->updateColor();
01063 }
01064 else if (shapetype == "H_Axis") {
01065 edit->SelCrossSet.insert(1);
01066 this->updateColor();
01067 }
01068 else if (shapetype.size() > 10 && shapetype.substr(0,10) == "Constraint") {
01069 int index=std::atoi(&shapetype[10]);
01070 edit->SelConstraintSet.insert(index);
01071 this->drawConstraintIcons();
01072 this->updateColor();
01073 }
01074 }
01075 }
01076 }
01077 else if (msg.Type == Gui::SelectionChanges::RmvSelection) {
01078
01079 if (edit->SelPointSet.size() > 0 || edit->SelCurvSet.size() > 0 || edit->SelConstraintSet.size() > 0) {
01080
01081 if (strcmp(msg.pDocName,getSketchObject()->getDocument()->getName())==0
01082 && strcmp(msg.pObjectName,getSketchObject()->getNameInDocument())== 0) {
01083 if (msg.pSubName) {
01084 std::string shapetype(msg.pSubName);
01085 if (shapetype.size() > 4 && shapetype.substr(0,4) == "Edge") {
01086 int index=std::atoi(&shapetype[4]);
01087 edit->SelCurvSet.erase(index);
01088 this->updateColor();
01089 }
01090 else if (shapetype.size() > 6 && shapetype.substr(0,6) == "Vertex") {
01091 int index=std::atoi(&shapetype[6]);
01092 removeSelectPoint(index);
01093 this->updateColor();
01094 }
01095 else if (shapetype.size() > 10 && shapetype.substr(0,10) == "Constraint") {
01096 int index=std::atoi(&shapetype[10]);
01097 edit->SelConstraintSet.erase(index);
01098 this->drawConstraintIcons();
01099 this->updateColor();
01100 }
01101 }
01102 }
01103 }
01104 }
01105 else if (msg.Type == Gui::SelectionChanges::SetSelection) {
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120 }
01121
01122 }
01123 }
01124
01125 bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtIndex, int &CurvIndex, int &ConstrIndex, int &CrossIndex)
01126 {
01127 assert(edit);
01128
01129 PtIndex = -1;
01130 CurvIndex = -1;
01131 ConstrIndex = -1;
01132 CrossIndex = -1;
01133
01134 if (Point) {
01135
01136 SoPath *path = Point->getPath();
01137 SoNode *tail = path->getTail();
01138 SoNode *tailFather = path->getNode(path->getLength()-2);
01139 SoNode *tailFather2 = path->getNode(path->getLength()-3);
01140
01141
01142 if (tail == edit->PointSet) {
01143 const SoDetail *point_detail = Point->getDetail(edit->PointSet);
01144 if (point_detail && point_detail->getTypeId() == SoPointDetail::getClassTypeId()) {
01145
01146 PtIndex = static_cast<const SoPointDetail *>(point_detail)->getCoordinateIndex();
01147 }
01148 } else {
01149
01150 if (tail == edit->CurveSet) {
01151 const SoDetail *curve_detail = Point->getDetail(edit->CurveSet);
01152 if (curve_detail && curve_detail->getTypeId() == SoLineDetail::getClassTypeId()) {
01153
01154 CurvIndex = static_cast<const SoLineDetail *>(curve_detail)->getLineIndex();
01155 }
01156
01157 } else if (tail == edit->RootCrossSetV) {
01158
01159
01160
01161 CrossIndex = 1;
01162
01163 } else if (tail == edit->RootCrossSetH) {
01164
01165
01166
01167 CrossIndex = 2;
01168
01169 } else {
01170
01171 if (tailFather2 == edit->constrGroup)
01172 for (int i=0; i < edit->constrGroup->getNumChildren(); i++)
01173 if (edit->constrGroup->getChild(i) == tailFather) {
01174 ConstrIndex = i;
01175
01176 break;
01177 }
01178 }
01179 }
01180
01181 if (PtIndex >= 0 && PtIndex != edit->PreselectPoint) {
01182 std::stringstream ss;
01183 ss << "Vertex" << PtIndex;
01184 bool accepted =
01185 Gui::Selection().setPreselect(getSketchObject()->getDocument()->getName()
01186 ,getSketchObject()->getNameInDocument()
01187 ,ss.str().c_str()
01188 ,Point->getPoint()[0]
01189 ,Point->getPoint()[1]
01190 ,Point->getPoint()[2]);
01191 edit->blockedPreselection = !accepted;
01192 if (accepted) {
01193 setPreselectPoint(PtIndex);
01194 edit->PreselectCurve = -1;
01195 edit->PreselectCross = -1;
01196 edit->PreselectConstraint = -1;
01197 if (edit->sketchHandler)
01198 edit->sketchHandler->applyCursor();
01199 return true;
01200 }
01201 } else if (CurvIndex >= 0 && CurvIndex != edit->PreselectCurve) {
01202 std::stringstream ss;
01203 ss << "Edge" << CurvIndex;
01204 bool accepted =
01205 Gui::Selection().setPreselect(getSketchObject()->getDocument()->getName()
01206 ,getSketchObject()->getNameInDocument()
01207 ,ss.str().c_str()
01208 ,Point->getPoint()[0]
01209 ,Point->getPoint()[1]
01210 ,Point->getPoint()[2]);
01211 edit->blockedPreselection = !accepted;
01212 if (accepted) {
01213 resetPreselectPoint();
01214 edit->PreselectCurve = CurvIndex;
01215 edit->PreselectCross = -1;
01216 edit->PreselectConstraint = -1;
01217 if (edit->sketchHandler)
01218 edit->sketchHandler->applyCursor();
01219 return true;
01220 }
01221 } else if (CrossIndex >= 0 && CrossIndex != edit->PreselectCross) {
01222 std::stringstream ss;
01223 switch(CrossIndex){
01224 case 0: ss << "RootPoint" ; break;
01225 case 1: ss << "H_Axis" ; break;
01226 case 2: ss << "V_Axis" ; break;
01227 }
01228 bool accepted =
01229 Gui::Selection().setPreselect(getSketchObject()->getDocument()->getName()
01230 ,getSketchObject()->getNameInDocument()
01231 ,ss.str().c_str()
01232 ,Point->getPoint()[0]
01233 ,Point->getPoint()[1]
01234 ,Point->getPoint()[2]);
01235 edit->blockedPreselection = !accepted;
01236 if (accepted) {
01237 resetPreselectPoint();
01238 edit->PreselectCurve = -1;
01239 edit->PreselectCross = CrossIndex;
01240 edit->PreselectConstraint = -1;
01241 if (edit->sketchHandler)
01242 edit->sketchHandler->applyCursor();
01243 return true;
01244 }
01245 } else if (ConstrIndex >= 0 && ConstrIndex != edit->PreselectConstraint) {
01246 std::stringstream ss;
01247 ss << "Constraint" << ConstrIndex;
01248 bool accepted =
01249 Gui::Selection().setPreselect(getSketchObject()->getDocument()->getName()
01250 ,getSketchObject()->getNameInDocument()
01251 ,ss.str().c_str()
01252 ,Point->getPoint()[0]
01253 ,Point->getPoint()[1]
01254 ,Point->getPoint()[2]);
01255 edit->blockedPreselection = !accepted;
01256 if (accepted) {
01257 resetPreselectPoint();
01258 edit->PreselectCurve = -1;
01259 edit->PreselectCross = -1;
01260 edit->PreselectConstraint = ConstrIndex;
01261 if (edit->sketchHandler)
01262 edit->sketchHandler->applyCursor();
01263 return true;
01264 }
01265 } else if ((PtIndex < 0 && CurvIndex < 0 && CrossIndex < 0 && ConstrIndex < 0) &&
01266 (edit->PreselectPoint >= 0 || edit->PreselectCurve >= 0 || edit->PreselectCross >= 0
01267 || edit->PreselectConstraint >= 0 || edit->blockedPreselection)) {
01268
01269 resetPreselectPoint();
01270 edit->PreselectCurve = -1;
01271 edit->PreselectCross = -1;
01272 edit->PreselectConstraint = -1;
01273 edit->blockedPreselection = false;
01274 if (edit->sketchHandler)
01275 edit->sketchHandler->applyCursor();
01276 return true;
01277 }
01278 Gui::Selection().setPreselectCoord(Point->getPoint()[0]
01279 ,Point->getPoint()[1]
01280 ,Point->getPoint()[2]);
01281 } else if (edit->PreselectCurve >= 0 || edit->PreselectPoint >= 0 ||
01282 edit->PreselectConstraint >= 0 || edit->PreselectCross >= 0 || edit->blockedPreselection) {
01283 resetPreselectPoint();
01284 edit->PreselectCurve = -1;
01285 edit->PreselectCross = -1;
01286 edit->PreselectConstraint = -1;
01287 edit->blockedPreselection = false;
01288 if (edit->sketchHandler)
01289 edit->sketchHandler->applyCursor();
01290 return true;
01291 }
01292
01293 return false;
01294 }
01295
01296 void ViewProviderSketch::updateColor(void)
01297 {
01298 assert(edit);
01299
01300
01301 int PtNum = edit->PointsMaterials->diffuseColor.getNum();
01302 SbColor *pcolor = edit->PointsMaterials->diffuseColor.startEditing();
01303 int CurvNum = edit->CurvesMaterials->diffuseColor.getNum();
01304 SbColor *color = edit->CurvesMaterials->diffuseColor.startEditing();
01305 SbColor *ccolorV = edit->RootCrossMaterialsV->diffuseColor.startEditing();
01306 SbColor *ccolorH = edit->RootCrossMaterialsH->diffuseColor.startEditing();
01307
01308
01309 for (int i=0; i < PtNum; i++) {
01310 if (edit->SelPointSet.find(i) != edit->SelPointSet.end())
01311 pcolor[i] = SelectColor;
01312 else if (edit->PreselectPoint == i)
01313 pcolor[i] = PreselectColor;
01314 else if (edit->FullyConstrained)
01315 pcolor[i] = FullyConstrainedColor;
01316 else
01317 pcolor[i] = VertexColor;
01318 }
01319
01320
01321 for (int i=0; i < CurvNum; i++) {
01322 if (edit->SelCurvSet.find(i) != edit->SelCurvSet.end())
01323 color[i] = SelectColor;
01324 else if (edit->PreselectCurve == i)
01325 color[i] = PreselectColor;
01326 else if (this->getSketchObject()->Geometry.getValues()[i]->Construction)
01327 color[i] = CurveDraftColor;
01328 else if (edit->FullyConstrained)
01329 color[i] = FullyConstrainedColor;
01330 else
01331 color[i] = CurveColor;
01332 }
01333
01334
01335 if (edit->SelCrossSet.find(1) != edit->SelCrossSet.end())
01336 ccolorV[0] = SelectColor;
01337 else if (edit->PreselectCross == 1)
01338 ccolorV[0] = PreselectColor;
01339 else
01340 ccolorV[0] = CrossColorV;
01341
01342 if (edit->SelCrossSet.find(2) != edit->SelCrossSet.end())
01343 ccolorH[0] = SelectColor;
01344 else if (edit->PreselectCross == 2)
01345 ccolorH[0] = PreselectColor;
01346 else
01347 ccolorH[0] = CrossColorH;
01348
01349
01350
01351 for (int i=0; i < edit->constrGroup->getNumChildren(); i++) {
01352 SoSeparator *s = dynamic_cast<SoSeparator *>(edit->constrGroup->getChild(i));
01353 SoMaterial *m = dynamic_cast<SoMaterial *>(s->getChild(0));
01354
01355
01356 ConstraintType type = this->getSketchObject()->Constraints.getValues()[i]->Type;
01357 bool hasDatumLabel = (type == Sketcher::Angle ||
01358 type == Sketcher::Radius ||
01359 type == Sketcher::Distance || type == Sketcher::DistanceX || type == Sketcher::DistanceY);
01360
01361 if (edit->SelConstraintSet.find(i) != edit->SelConstraintSet.end()) {
01362 m->diffuseColor = SelectColor;
01363 if (hasDatumLabel) {
01364 SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(4));
01365 l->textColor = SelectColor;
01366 }
01367 } else if (edit->PreselectConstraint == i) {
01368 m->diffuseColor = PreselectColor;
01369 if (hasDatumLabel) {
01370 SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(4));
01371 l->textColor = PreselectColor;
01372 }
01373 }
01374 else {
01375 m->diffuseColor = ConstrDimColor;
01376 if (hasDatumLabel) {
01377 SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(4));
01378 l->textColor = ConstrDimColor;
01379 }
01380 }
01381 }
01382
01383
01384 edit->CurvesMaterials->diffuseColor.finishEditing();
01385 edit->PointsMaterials->diffuseColor.finishEditing();
01386 edit->RootCrossMaterialsV->diffuseColor.finishEditing();
01387 edit->RootCrossMaterialsH->diffuseColor.finishEditing();
01388 }
01389
01390 bool ViewProviderSketch::isPointOnSketch(const SoPickedPoint *pp) const
01391 {
01392
01393 SoPath *path = pp->getPath();
01394 return path->containsNode(edit->EditRoot);
01395 }
01396
01397 bool ViewProviderSketch::doubleClicked(void)
01398 {
01399 Gui::Application::Instance->activeDocument()->setEdit(this);
01400 return true;
01401 }
01402
01403 void ViewProviderSketch::drawConstraintIcons()
01404 {
01405 const std::vector<Sketcher::Constraint *> &constraints = getSketchObject()->Constraints.getValues();
01406 int constrId = 0;
01407 for (std::vector<Sketcher::Constraint *>::const_iterator it=constraints.begin();
01408 it != constraints.end(); ++it, constrId++) {
01409
01410 int index1 = 2, index2 = -1;
01411 QString icoType;
01412 switch((*it)->Type) {
01413 case Horizontal:
01414 icoType = QString::fromAscii("small/Constraint_Horizontal_sm");
01415 break;
01416 case Vertical:
01417 icoType = QString::fromAscii("small/Constraint_Vertical_sm");
01418 break;
01419 case PointOnObject:
01420 icoType = QString::fromAscii("small/Constraint_PointOnObject_sm");
01421 break;
01422 case Tangent:
01423 icoType = QString::fromAscii("small/Constraint_Tangent_sm");
01424 {
01425 Part::Geometry *geo1 = getSketchObject()->Geometry.getValues()[(*it)->First];
01426 Part::Geometry *geo2 = getSketchObject()->Geometry.getValues()[(*it)->Second];
01427 if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
01428 geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01429 index2 = 4;
01430 }
01431 }
01432 break;
01433 case Parallel:
01434 icoType = QString::fromAscii("small/Constraint_Parallel_sm");
01435 index2 = 4;
01436 break;
01437 case Perpendicular:
01438 icoType = QString::fromAscii("small/Constraint_Perpendicular_sm");
01439 index2 = 4;
01440 break;
01441 case Equal:
01442 icoType = QString::fromAscii("small/Constraint_EqualLength_sm");
01443 index2 = 4;
01444 break;
01445 case Symmetric:
01446 icoType = QString::fromAscii("small/Constraint_Symmetric_sm");
01447 index1 = 3;
01448 break;
01449 default:
01450 continue;
01451 }
01452
01453
01454 const int constrImgSize = 16;
01455
01456 QColor constrIcoColor((int)(ConstrIcoColor [0] * 255.0f), (int)(ConstrIcoColor[1] * 255.0f),(int)(ConstrIcoColor[2] * 255.0f));
01457 QColor constrIconSelColor ((int)(SelectColor[0] * 255.0f), (int)(SelectColor[1] * 255.0f),(int)(SelectColor[2] * 255.0f));
01458 QColor constrIconPreselColor ((int)(PreselectColor[0] * 255.0f), (int)(PreselectColor[1] * 255.0f),(int)(PreselectColor[2] * 255.0f));
01459
01460
01461 QColor iconColor;
01462 if (edit->PreselectConstraint == constrId)
01463 iconColor = constrIconPreselColor;
01464 else if (edit->SelConstraintSet.find(constrId) != edit->SelConstraintSet.end())
01465 iconColor = constrIconSelColor;
01466 else
01467 iconColor = constrIcoColor;
01468
01469
01470
01471
01472 QPainter qp;
01473 QImage icon;
01474
01475 icon = Gui::BitmapFactory().pixmap(icoType.toAscii()).toImage();
01476
01477
01478 int imgwidth = icon.width() + ((index2 == -1) ? 0 : 9 * (1 + (constrId + 1)/10));
01479 QImage image = icon.copy(0, 0, imgwidth, icon.height());
01480
01481
01482 qp.begin(&image);
01483 qp.setCompositionMode(QPainter::CompositionMode_SourceIn);
01484 qp.fillRect(0,0, constrImgSize, constrImgSize, iconColor);
01485
01486
01487 if (index2 != -1) {
01488 qp.setCompositionMode(QPainter::CompositionMode_SourceOver);
01489 qp.setPen(iconColor);
01490 QFont font = QApplication::font();
01491 font.setPixelSize(11);
01492 font.setBold(true);
01493 qp.setFont(font);
01494 qp.drawText(constrImgSize, image.height(), QString::number(constrId + 1));
01495 }
01496 qp.end();
01497
01498 SoSFImage icondata = SoSFImage();
01499
01500 Gui::BitmapFactory().convert(image, icondata);
01501
01502 int nc = 4;
01503 SbVec2s iconSize(image.width(), image.height());
01504
01505
01506 SoSeparator *sep = dynamic_cast<SoSeparator *>(edit->constrGroup->getChild(constrId));
01507 SoImage *constraintIcon1 = dynamic_cast<SoImage *>(sep->getChild(index1));
01508
01509 constraintIcon1->image.setValue(iconSize, 4, icondata.getValue(iconSize, nc));
01510
01511
01512 constraintIcon1->vertAlignment = SoImage::HALF;
01513 constraintIcon1->horAlignment = SoImage::CENTER;
01514
01515
01516 if (index2 != -1) {
01517 SoImage *constraintIcon2 = dynamic_cast<SoImage *>(sep->getChild(index2));
01518 constraintIcon2->image.setValue(iconSize, 4, icondata.getValue(iconSize, nc));
01519
01520 constraintIcon2->vertAlignment = SoImage::HALF;
01521 constraintIcon2->horAlignment = SoImage::CENTER;
01522 }
01523 }
01524 }
01525
01526 float ViewProviderSketch::getScaleFactor()
01527 {
01528 Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
01529 if (mdi && mdi->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
01530 Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
01531 return viewer->getCamera()->getViewVolume(viewer->getCamera()->aspectRatio.getValue()).getWorldToScreenScale(SbVec3f(0.f, 0.f, 0.f), 0.1f) / 3;
01532 } else {
01533 return 1.f;
01534 }
01535 }
01536
01537 void ViewProviderSketch::draw(bool temp)
01538 {
01539 assert(edit);
01540
01541
01542 Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
01543
01544
01545 std::vector<Base::Vector3d> Coords;
01546 std::vector<Base::Vector3d> Points;
01547 std::vector<unsigned int> Index;
01548
01549 const std::vector<Part::Geometry *> *geomlist;
01550 std::vector<Part::Geometry *> tempGeo;
01551 if (temp) {
01552 tempGeo = edit->ActSketch.getGeometry();
01553 geomlist = &tempGeo;
01554 } else
01555 geomlist = &getSketchObject()->Geometry.getValues();
01556
01557 for (std::vector<Part::Geometry *>::const_iterator it = geomlist->begin(); it != geomlist->end(); ++it) {
01558 if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01559 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(*it);
01560
01561 Coords.push_back(lineSeg->getStartPoint());
01562 Coords.push_back(lineSeg->getEndPoint());
01563 Points.push_back(lineSeg->getStartPoint());
01564 Points.push_back(lineSeg->getEndPoint());
01565 Index.push_back(2);
01566 }
01567 else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) {
01568 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(*it);
01569 Handle_Geom_Circle curve = Handle_Geom_Circle::DownCast(circle->handle());
01570
01571 int countSegments = 50;
01572 Base::Vector3d center = circle->getCenter();
01573 double segment = (2 * M_PI) / countSegments;
01574 for (int i=0; i < countSegments; i++) {
01575 gp_Pnt pnt = curve->Value(i*segment);
01576 Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
01577 }
01578
01579 gp_Pnt pnt = curve->Value(0);
01580 Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
01581
01582 Index.push_back(countSegments+1);
01583 Points.push_back(center);
01584 }
01585 else if ((*it)->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
01586 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(*it);
01587 Handle_Geom_TrimmedCurve curve = Handle_Geom_TrimmedCurve::DownCast(arc->handle());
01588
01589 double startangle, endangle;
01590 arc->getRange(startangle, endangle);
01591 if (startangle > endangle)
01592 std::swap(startangle, endangle);
01593
01594 double range = endangle-startangle;
01595 int countSegments = std::max(6, int(50.0 * range / (2 * M_PI)));
01596 double segment = range / countSegments;
01597
01598 Base::Vector3d center = arc->getCenter();
01599 Base::Vector3d start = arc->getStartPoint();
01600 Base::Vector3d end = arc->getEndPoint();
01601
01602 for (int i=0; i < countSegments; i++) {
01603 gp_Pnt pnt = curve->Value(startangle);
01604 Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
01605 startangle += segment;
01606 }
01607
01608
01609 gp_Pnt pnt = curve->Value(endangle);
01610 Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
01611
01612 Index.push_back(countSegments+1);
01613 Points.push_back(center);
01614 Points.push_back(start);
01615 Points.push_back(end);
01616 }
01617 else if ((*it)->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
01618 const Part::GeomBSplineCurve *spline = dynamic_cast<const Part::GeomBSplineCurve *>(*it);
01619 Handle_Geom_BSplineCurve curve = Handle_Geom_BSplineCurve::DownCast(spline->handle());
01620
01621 double first = curve->FirstParameter();
01622 double last = curve->LastParameter();
01623 if (first > last)
01624 std::swap(first, last);
01625
01626 double range = last-first;
01627 int countSegments = 50;
01628 double segment = range / countSegments;
01629
01630 for (int i=0; i < countSegments; i++) {
01631 gp_Pnt pnt = curve->Value(first);
01632 Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
01633 first += segment;
01634 }
01635
01636
01637 gp_Pnt end = curve->Value(last);
01638 Coords.push_back(Base::Vector3d(end.X(), end.Y(), end.Z()));
01639
01640 std::vector<Base::Vector3d> poles = spline->getPoles();
01641 for (std::vector<Base::Vector3d>::iterator it = poles.begin(); it != poles.end(); ++it) {
01642 Points.push_back(*it);
01643 }
01644
01645 Index.push_back(countSegments+1);
01646 }
01647 else {
01648 ;
01649 }
01650 }
01651
01652 edit->CurvesCoordinate->point.setNum(Coords.size());
01653 edit->CurveSet->numVertices.setNum(Index.size());
01654 edit->CurvesMaterials->diffuseColor.setNum(Index.size());
01655 edit->PointsCoordinate->point.setNum(Points.size());
01656 edit->PointsMaterials->diffuseColor.setNum(Points.size());
01657
01658 SbVec3f *verts = edit->CurvesCoordinate->point.startEditing();
01659 int32_t *index = edit->CurveSet->numVertices.startEditing();
01660 SbVec3f *pverts = edit->PointsCoordinate->point.startEditing();
01661
01662
01663 edit->RootCrossSetV->numVertices.set1Value(0,2);
01664 edit->RootCrossSetH->numVertices.set1Value(0,2);
01665
01666 float MiX = -exp(ceil(log(std::abs(MinX))));
01667 MiX = std::min(MiX,(float)-exp(ceil(log(std::abs(0.1f*MaxX)))));
01668 float MaX = exp(ceil(log(std::abs(MaxX))));
01669 MaX = std::max(MaX,(float)exp(ceil(log(std::abs(0.1f*MinX)))));
01670 float MiY = -exp(ceil(log(std::abs(MinY))));
01671 MiY = std::min(MiY,(float)-exp(ceil(log(std::abs(0.1f*MaxY)))));
01672 float MaY = exp(ceil(log(std::abs(MaxY))));
01673 MaY = std::max(MaY,(float)exp(ceil(log(std::abs(0.1f*MinY)))));
01674
01675 edit->RootCrossCoordinateV->point.set1Value(0,SbVec3f(MiX, 0.0f, zCross));
01676 edit->RootCrossCoordinateV->point.set1Value(1,SbVec3f(MaX, 0.0f, zCross));
01677 edit->RootCrossCoordinateH->point.set1Value(0,SbVec3f(0.0f, MiY, zCross));
01678 edit->RootCrossCoordinateH->point.set1Value(1,SbVec3f(0.0f, MaY, zCross));
01679
01680 int i=0;
01681 for (std::vector<Base::Vector3d>::const_iterator it = Coords.begin(); it != Coords.end(); ++it,i++)
01682 verts[i].setValue(it->x,it->y,zLines);
01683
01684 i=0;
01685 for (std::vector<unsigned int>::const_iterator it = Index.begin(); it != Index.end(); ++it,i++)
01686 index[i] = *it;
01687
01688
01689 i=0;
01690 for (std::vector<Base::Vector3d>::const_iterator it = Points.begin(); it != Points.end(); ++it,i++)
01691 pverts[i].setValue(it->x,it->y,zPoints);
01692
01693
01694 edit->CurvesCoordinate->point.finishEditing();
01695 edit->CurveSet->numVertices.finishEditing();
01696 edit->PointsCoordinate->point.finishEditing();
01697
01698
01699 const std::vector<Sketcher::Constraint *> &ConStr = getSketchObject()->Constraints.getValues();
01700
01701
01702 if (geomlist->empty() && !ConStr.empty()) {
01703 rebuildConstraintsVisual();
01704 return;
01705 }
01706
01707 Restart:
01708
01709 if (ConStr.size() != edit->vConstrType.size())
01710 rebuildConstraintsVisual();
01711 assert(int(ConStr.size()) == edit->constrGroup->getNumChildren());
01712 assert(int(edit->vConstrType.size()) == edit->constrGroup->getNumChildren());
01713
01714 i = 0;
01715 for (std::vector<Sketcher::Constraint *>::const_iterator it = ConStr.begin(); it != ConStr.end(); ++it,i++) {
01716
01717 if ((*it)->Type != edit->vConstrType[i]) {
01718
01719 edit->vConstrType.clear();
01720 goto Restart;
01721 }
01722
01723 SoSeparator *sep = dynamic_cast<SoSeparator *>(edit->constrGroup->getChild(i));
01724 const Constraint *Constr = *it;
01725
01726
01727 switch (Constr->Type) {
01728 case Horizontal:
01729 case Vertical:
01730 {
01731 assert(Constr->First < int(geomlist->size()));
01732
01733 const Part::Geometry *geo = (*geomlist)[Constr->First];
01734
01735 assert(geo->getTypeId() == Part::GeomLineSegment::getClassTypeId());
01736 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
01737
01738
01739 Base::Vector3d midpos = ((lineSeg->getEndPoint()+lineSeg->getStartPoint())/2);
01740
01741
01742 Base::Vector3d dir = (lineSeg->getEndPoint()-lineSeg->getStartPoint()).Normalize();
01743 Base::Vector3d norm(-dir.y,dir.x,0);
01744
01745 float scale = dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->getScaleFactor();
01746 Base::Vector3d constrPos = midpos + (norm * 2.5 * scale);
01747
01748 constrPos = seekConstraintPosition(constrPos, dir, 2.5 * scale, edit->constrGroup->getChild(i));
01749
01750
01751 Base::Vector3d relPos = constrPos - midpos;
01752 relPos = relPos / scale;
01753
01754 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->abPos = SbVec3f(midpos.x, midpos.y, zConstr);
01755
01756
01757 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->translation = SbVec3f(relPos.x, relPos.y, 0);
01758
01759 }
01760 break;
01761 case Parallel:
01762 case Perpendicular:
01763 case Equal:
01764 {
01765 assert(Constr->First < int(geomlist->size()));
01766 assert(Constr->Second < int(geomlist->size()));
01767
01768 const Part::Geometry *geo1 = (*geomlist)[Constr->First];
01769 const Part::Geometry *geo2 = (*geomlist)[Constr->Second];
01770
01771 Base::Vector3d midpos1, dir1, norm1;
01772 Base::Vector3d midpos2, dir2, norm2;
01773 if (geo1->getTypeId() != Part::GeomLineSegment::getClassTypeId() ||
01774 geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId()) {
01775 if (Constr->Type == Equal) {
01776 double r1,r2,angle1,angle2;
01777 if (geo1->getTypeId() == Part::GeomCircle::getClassTypeId()) {
01778 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo1);
01779 r1 = circle->getRadius();
01780 angle1 = M_PI/4;
01781 midpos1 = circle->getCenter();
01782 } else if (geo1->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
01783 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo1);
01784 r1 = arc->getRadius();
01785 double startangle, endangle;
01786 arc->getRange(startangle, endangle);
01787 angle1 = (startangle + endangle)/2;
01788 midpos1 = arc->getCenter();
01789 } else
01790 break;
01791
01792 if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) {
01793 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo2);
01794 r2 = circle->getRadius();
01795 angle2 = M_PI/4;
01796 midpos2 = circle->getCenter();
01797 } else if (geo2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
01798 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo2);
01799 r2 = arc->getRadius();
01800 double startangle, endangle;
01801 arc->getRange(startangle, endangle);
01802 angle2 = (startangle + endangle)/2;
01803 midpos2 = arc->getCenter();
01804 } else
01805 break;
01806
01807 norm1 = Base::Vector3d(cos(angle1),sin(angle1),0);
01808 dir1 = Base::Vector3d(-norm1.y,norm1.x,0);
01809 midpos1 += r1*norm1;
01810
01811 norm2 = Base::Vector3d(cos(angle2),sin(angle2),0);
01812 dir2 = Base::Vector3d(-norm2.y,norm2.x,0);
01813 midpos2 += r2*norm2;
01814 } else
01815 break;
01816 } else {
01817 const Part::GeomLineSegment *lineSeg1 = dynamic_cast<const Part::GeomLineSegment *>(geo1);
01818 const Part::GeomLineSegment *lineSeg2 = dynamic_cast<const Part::GeomLineSegment *>(geo2);
01819
01820
01821 midpos1 = ((lineSeg1->getEndPoint()+lineSeg1->getStartPoint())/2);
01822 midpos2 = ((lineSeg2->getEndPoint()+lineSeg2->getStartPoint())/2);
01823
01824 dir1 = (lineSeg1->getEndPoint()-lineSeg1->getStartPoint()).Normalize();
01825 dir2 = (lineSeg2->getEndPoint()-lineSeg2->getStartPoint()).Normalize();
01826 norm1 = Base::Vector3d(-dir1.y,dir1.x,0.);
01827 norm2 = Base::Vector3d(-dir2.y,dir2.x,0.);
01828 }
01829
01830
01831 float scale = dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->getScaleFactor();
01832
01833 Base::Vector3d constrPos1 = midpos1 + (norm1 * scale * 2.5 );
01834 constrPos1 = seekConstraintPosition(constrPos1, dir1, scale * 2.5, edit->constrGroup->getChild(i));
01835
01836 Base::Vector3d constrPos2 = midpos2 + (norm2 * scale * 2.5);
01837 constrPos2 = seekConstraintPosition(constrPos2, dir2, scale * 2.5, edit->constrGroup->getChild(i));
01838
01839
01840 Base::Vector3d relPos1 = constrPos1 - midpos1 ;
01841 Base::Vector3d relPos2 = constrPos2 - midpos2 ;
01842
01843 relPos1 = relPos1 / scale;
01844 relPos2 = relPos2 / scale;
01845
01846 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->abPos = SbVec3f(midpos1.x, midpos1.y, zConstr);
01847
01848
01849 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->translation = SbVec3f(relPos1.x, relPos1.y, 0);
01850
01851 Base::Vector3d secondPos = midpos2 - midpos1;
01852 dynamic_cast<SoZoomTranslation *>(sep->getChild(3))->abPos = SbVec3f(secondPos.x, secondPos.y, zConstr);
01853
01854
01855 dynamic_cast<SoZoomTranslation *>(sep->getChild(3))->translation = SbVec3f(relPos2.x -relPos1.x, relPos2.y -relPos1.y, 0);
01856
01857 }
01858 break;
01859 case Distance:
01860 case DistanceX:
01861 case DistanceY:
01862 {
01863 assert(Constr->First < int(geomlist->size()));
01864
01865 Base::Vector3d pnt1(0.,0.,0.), pnt2(0.,0.,0.);
01866 if (Constr->SecondPos != Sketcher::none) {
01867 if (temp) {
01868 pnt1 = edit->ActSketch.getPoint(Constr->First, Constr->FirstPos);
01869 pnt2 = edit->ActSketch.getPoint(Constr->Second, Constr->SecondPos);
01870 } else {
01871 pnt1 = getSketchObject()->getPoint(Constr->First, Constr->FirstPos);
01872 pnt2 = getSketchObject()->getPoint(Constr->Second, Constr->SecondPos);
01873 }
01874 } else if (Constr->Second != Constraint::GeoUndef) {
01875 if (temp) {
01876 pnt1 = edit->ActSketch.getPoint(Constr->First, Constr->FirstPos);
01877 } else {
01878 pnt1 = getSketchObject()->getPoint(Constr->First, Constr->FirstPos);
01879 }
01880 const Part::Geometry *geo = (*geomlist)[Constr->Second];
01881 if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01882 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
01883 Base::Vector3d l2p1 = lineSeg->getStartPoint();
01884 Base::Vector3d l2p2 = lineSeg->getEndPoint();
01885
01886 pnt2.ProjToLine(pnt1-l2p1, l2p2-l2p1);
01887 pnt2 += pnt1;
01888 } else
01889 break;
01890 } else if (Constr->FirstPos != Sketcher::none) {
01891 if (temp) {
01892 pnt2 = edit->ActSketch.getPoint(Constr->First, Constr->FirstPos);
01893 } else {
01894 pnt2 = getSketchObject()->getPoint(Constr->First, Constr->FirstPos);
01895 }
01896 } else if (Constr->First != Constraint::GeoUndef) {
01897 const Part::Geometry *geo = (*geomlist)[Constr->First];
01898 if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
01899 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
01900 pnt1 = lineSeg->getStartPoint();
01901 pnt2 = lineSeg->getEndPoint();
01902 } else
01903 break;
01904 } else
01905 break;
01906
01907 SbVec3f p1(pnt1.x,pnt1.y,zConstr);
01908 SbVec3f p2(pnt2.x,pnt2.y,zConstr);
01909
01910 SbVec3f dir, norm;
01911 if (Constr->Type == Distance)
01912 dir = (p2-p1);
01913 else if (Constr->Type == DistanceX)
01914 dir = SbVec3f( (pnt2.x - pnt1.x >= FLT_EPSILON) ? 1 : -1, 0, 0);
01915 else if (Constr->Type == DistanceY)
01916 dir = SbVec3f(0, (pnt2.y - pnt1.y >= FLT_EPSILON) ? 1 : -1, 0);
01917 dir.normalize();
01918 norm = SbVec3f (-dir[1],dir[0],0);
01919
01920
01921
01922
01923 float normproj12 = (p2-p1).dot(norm);
01924
01925 SbVec3f p1_ = p1 + normproj12 * norm;
01926 SbVec3f midpos = (p1_ + p2)/2;
01927
01928 SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(4));
01929 if ((Constr->Type == DistanceX || Constr->Type == DistanceY) &&
01930 Constr->FirstPos != Sketcher::none && Constr->Second == Constraint::GeoUndef)
01931
01932 asciiText->string = SbString().sprintf("%.2f",Constr->Value);
01933 else
01934 asciiText->string = SbString().sprintf("%.2f",std::abs(Constr->Value));
01935
01936
01937 Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
01938
01939
01940 SoGetBoundingBoxAction bbAction(viewer->getViewportRegion());
01941 bbAction.apply(sep->getChild(4));
01942
01943 float bx,by,bz;
01944 bbAction.getBoundingBox().getSize(bx,by,bz);
01945 SbVec3f textBB(bx,by,bz);
01946
01947
01948
01949 SbVec3f textBBCenter = bbAction.getBoundingBox().getCenter();
01950
01951 float length = Constr->LabelDistance;
01952
01953
01954 double angle = atan2f(dir[1],dir[0]);
01955 bool flip=false;
01956 if (angle > M_PI_2+M_PI/12) {
01957 angle -= M_PI;
01958 flip = true;
01959 } else if (angle <= -M_PI_2+M_PI/12) {
01960 angle += M_PI;
01961 flip = true;
01962 }
01963
01964 SbVec3f textpos = midpos + norm * (length + ( (flip ? 1:-1) * textBBCenter[1] / 4));
01965
01966
01967 SoTransform *transform = dynamic_cast<SoTransform *>(sep->getChild(2));
01968 transform->rotation.setValue(SbVec3f(0, 0, 1), (float)angle);
01969 transform->translation.setValue(textpos);
01970
01971
01972 SoSeparator *sepDatum = dynamic_cast<SoSeparator *>(sep->getChild(1));
01973 SoCoordinate3 *datumCord = dynamic_cast<SoCoordinate3 *>(sepDatum->getChild(0));
01974
01975
01976 float offset1 = (length + normproj12 < 0) ? -0.5 : 0.5;
01977 float offset2 = (length < 0) ? -0.5 : 0.5;
01978 offset1 *= getScaleFactor();
01979 offset2 *= getScaleFactor();
01980
01981 datumCord->point.set1Value(0,p1);
01982 datumCord->point.set1Value(1,p1_ + norm * (length + offset1));
01983 datumCord->point.set1Value(2,p2);
01984 datumCord->point.set1Value(3,p2 + norm * (length + offset2));
01985
01986
01987 datumCord->point.set1Value(4,p1_ + norm * length);
01988 datumCord->point.set1Value(5,midpos + norm * length - dir * (textBB[0]/1.7f) );
01989 datumCord->point.set1Value(6,midpos + norm * length + dir * (textBB[0]/1.7f) );
01990 datumCord->point.set1Value(7,p2 + norm * length);
01991
01992
01993 SoLineSet *datumLineSet = dynamic_cast<SoLineSet *>(sepDatum->getChild(1));
01994 datumLineSet->numVertices.set1Value(0,2);
01995 datumLineSet->numVertices.set1Value(1,2);
01996 datumLineSet->numVertices.set1Value(2,2);
01997 datumLineSet->numVertices.set1Value(3,2);
01998 }
01999 break;
02000 case PointOnObject:
02001 case Tangent:
02002 {
02003 assert(Constr->First < int(geomlist->size()));
02004 assert(Constr->Second < int(geomlist->size()));
02005
02006 Base::Vector3d pos, relPos;
02007 if (Constr->Type == PointOnObject) {
02008 pos = edit->ActSketch.getPoint(Constr->First, Constr->FirstPos);
02009 relPos = Base::Vector3d(0.f, 1.f, 0.f);
02010 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->abPos = SbVec3f(pos.x, pos.y, zConstr);
02011 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->translation = SbVec3f(relPos.x, relPos.y, 0);
02012 }
02013 else if (Constr->Type == Tangent) {
02014
02015 const Part::Geometry *geo1 = (*geomlist)[Constr->First];
02016 const Part::Geometry *geo2 = (*geomlist)[Constr->Second];
02017
02018 if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
02019 geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
02020 const Part::GeomLineSegment *lineSeg1 = dynamic_cast<const Part::GeomLineSegment *>(geo1);
02021 const Part::GeomLineSegment *lineSeg2 = dynamic_cast<const Part::GeomLineSegment *>(geo2);
02022
02023 Base::Vector3d midpos1 = ((lineSeg1->getEndPoint()+lineSeg1->getStartPoint())/2);
02024 Base::Vector3d midpos2 = ((lineSeg2->getEndPoint()+lineSeg2->getStartPoint())/2);
02025 Base::Vector3d dir1 = (lineSeg1->getEndPoint()-lineSeg1->getStartPoint()).Normalize();
02026 Base::Vector3d dir2 = (lineSeg2->getEndPoint()-lineSeg2->getStartPoint()).Normalize();
02027 Base::Vector3d norm1 = Base::Vector3d(-dir1.y,dir1.x,0.f);
02028 Base::Vector3d norm2 = Base::Vector3d(-dir2.y,dir2.x,0.f);
02029
02030
02031 float scale = dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->getScaleFactor();
02032
02033 Base::Vector3d constrPos1 = midpos1 + (norm1 * scale * 2.5);
02034 constrPos1 = seekConstraintPosition(constrPos1, dir1, scale * 2.5, edit->constrGroup->getChild(i));
02035
02036 Base::Vector3d constrPos2 = midpos2 + (norm2 * scale * 2.5);
02037 constrPos2 = seekConstraintPosition(constrPos2, dir2, scale * 2.5, edit->constrGroup->getChild(i));
02038
02039
02040 Base::Vector3d relPos1 = constrPos1 - midpos1 ;
02041 Base::Vector3d relPos2 = constrPos2 - midpos2 ;
02042
02043 relPos1 = relPos1 / scale;
02044 relPos2 = relPos2 / scale;
02045
02046 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->abPos = SbVec3f(midpos1.x, midpos1.y, zConstr);
02047
02048
02049 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->translation = SbVec3f(relPos1.x, relPos1.y, 0);
02050
02051 Base::Vector3d secondPos = midpos2 - midpos1;
02052 dynamic_cast<SoZoomTranslation *>(sep->getChild(3))->abPos = SbVec3f(secondPos.x, secondPos.y, zConstr);
02053
02054
02055 dynamic_cast<SoZoomTranslation *>(sep->getChild(3))->translation = SbVec3f(relPos2.x -relPos1.x, relPos2.y -relPos1.y, 0);
02056
02057 break;
02058 }
02059 else if (geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
02060 std::swap(geo1,geo2);
02061 }
02062
02063 if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
02064 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo1);
02065 Base::Vector3d dir = (lineSeg->getEndPoint() - lineSeg->getStartPoint()).Normalize();
02066 Base::Vector3d norm(-dir.y, dir.x, 0);
02067 if (geo2->getTypeId()== Part::GeomCircle::getClassTypeId()) {
02068 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo2);
02069
02070 float length = (circle->getCenter() - lineSeg->getStartPoint())*dir;
02071
02072 pos = lineSeg->getStartPoint() + dir * length;
02073 relPos = norm * 1;
02074 }
02075 else if (geo2->getTypeId()== Part::GeomArcOfCircle::getClassTypeId()) {
02076 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo2);
02077
02078 float length = (arc->getCenter() - lineSeg->getStartPoint())*dir;
02079
02080 pos = lineSeg->getStartPoint() + dir * length;
02081 relPos = norm * 1;
02082 }
02083 }
02084
02085 if (geo1->getTypeId()== Part::GeomCircle::getClassTypeId() &&
02086 geo2->getTypeId()== Part::GeomCircle::getClassTypeId()) {
02087 const Part::GeomCircle *circle1 = dynamic_cast<const Part::GeomCircle *>(geo1);
02088 const Part::GeomCircle *circle2 = dynamic_cast<const Part::GeomCircle *>(geo2);
02089
02090 }
02091 else if (geo2->getTypeId()== Part::GeomCircle::getClassTypeId()) {
02092 std::swap(geo1,geo2);
02093 }
02094
02095 if (geo1->getTypeId()== Part::GeomCircle::getClassTypeId()) {
02096 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo1);
02097 if (geo2->getTypeId()== Part::GeomArcOfCircle::getClassTypeId()) {
02098 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo2);
02099
02100 }
02101 }
02102
02103 if (geo1->getTypeId()== Part::GeomArcOfCircle::getClassTypeId() &&
02104 geo1->getTypeId()== Part::GeomArcOfCircle::getClassTypeId()) {
02105 const Part::GeomArcOfCircle *arc1 = dynamic_cast<const Part::GeomArcOfCircle *>(geo1);
02106 const Part::GeomArcOfCircle *arc2 = dynamic_cast<const Part::GeomArcOfCircle *>(geo2);
02107
02108 }
02109 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->abPos = SbVec3f(pos.x, pos.y, zConstr);
02110 dynamic_cast<SoZoomTranslation *>(sep->getChild(1))->translation = SbVec3f(relPos.x, relPos.y, 0);
02111 }
02112 }
02113 break;
02114 case Symmetric:
02115 {
02116 assert(Constr->First < int(geomlist->size()));
02117 assert(Constr->Second < int(geomlist->size()));
02118
02119 Base::Vector3d pnt1 = edit->ActSketch.getPoint(Constr->First, Constr->FirstPos);
02120 Base::Vector3d pnt2 = edit->ActSketch.getPoint(Constr->Second, Constr->SecondPos);
02121
02122 SbVec3f p1(pnt1.x,pnt1.y,zConstr);
02123 SbVec3f p2(pnt2.x,pnt2.y,zConstr);
02124 SbVec3f dir = (p2-p1);
02125 dir.normalize();
02126 SbVec3f norm (-dir[1],dir[0],0);
02127
02128
02129 SoSeparator *sepArrows = dynamic_cast<SoSeparator *>(sep->getChild(1));
02130 SoCoordinate3 *arrowsCord = dynamic_cast<SoCoordinate3 *>(sepArrows->getChild(0));
02131
02132 arrowsCord->point.setNum(10);
02133
02134
02135 arrowsCord->point.set1Value(0,p1);
02136 arrowsCord->point.set1Value(1,p1 + dir * 5);
02137 arrowsCord->point.set1Value(2,p1 + dir * 3 + norm * 2);
02138 arrowsCord->point.set1Value(3,p1 + dir * 5);
02139 arrowsCord->point.set1Value(4,p1 + dir * 3 - norm * 2);
02140
02141
02142 arrowsCord->point.set1Value(5,p2);
02143 arrowsCord->point.set1Value(6,p2 - dir * 5);
02144 arrowsCord->point.set1Value(7,p2 - dir * 3 + norm * 2);
02145 arrowsCord->point.set1Value(8,p2 - dir * 5);
02146 arrowsCord->point.set1Value(9,p2 - dir * 3 - norm * 2);
02147
02148
02149 SoLineSet *arrowsLineSet = dynamic_cast<SoLineSet *>(sepArrows->getChild(1));
02150 arrowsLineSet->numVertices.set1Value(0,3);
02151 arrowsLineSet->numVertices.set1Value(1,2);
02152 arrowsLineSet->numVertices.set1Value(2,3);
02153 arrowsLineSet->numVertices.set1Value(3,2);
02154
02155 dynamic_cast<SoTranslation *>(sep->getChild(2))->translation = (p1 + p2)/2;
02156 }
02157 break;
02158 case Angle:
02159 {
02160 assert(Constr->First < int(geomlist->size()));
02161 assert(Constr->Second < int(geomlist->size()));
02162
02163 SbVec3f p0;
02164 double startangle,range,endangle;
02165 if (Constr->Second != Constraint::GeoUndef) {
02166 const Part::Geometry *geo1 = (*geomlist)[Constr->First];
02167 const Part::Geometry *geo2 = (*geomlist)[Constr->Second];
02168 if (geo1->getTypeId() != Part::GeomLineSegment::getClassTypeId() ||
02169 geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId())
02170 break;
02171 const Part::GeomLineSegment *lineSeg1 = dynamic_cast<const Part::GeomLineSegment *>(geo1);
02172 const Part::GeomLineSegment *lineSeg2 = dynamic_cast<const Part::GeomLineSegment *>(geo2);
02173
02174 bool flip1 = (Constr->FirstPos == end);
02175 bool flip2 = (Constr->SecondPos == end);
02176 Base::Vector3d dir1 = (flip1 ? -1. : 1.) * (lineSeg1->getEndPoint()-lineSeg1->getStartPoint());
02177 Base::Vector3d dir2 = (flip2 ? -1. : 1.) * (lineSeg2->getEndPoint()-lineSeg2->getStartPoint());
02178 Base::Vector3d pnt1 = flip1 ? lineSeg1->getEndPoint() : lineSeg1->getStartPoint();
02179 Base::Vector3d pnt2 = flip2 ? lineSeg2->getEndPoint() : lineSeg2->getStartPoint();
02180
02181
02182 {
02183 double det = dir1.x*dir2.y - dir1.y*dir2.x;
02184 if ((det > 0 ? det : -det) < 1e-10)
02185 break;
02186 double c1 = dir1.y*pnt1.x - dir1.x*pnt1.y;
02187 double c2 = dir2.y*pnt2.x - dir2.x*pnt2.y;
02188 double x = (dir1.x*c2 - dir2.x*c1)/det;
02189 double y = (dir1.y*c2 - dir2.y*c1)/det;
02190 p0 = SbVec3f(x,y,0);
02191 }
02192
02193 startangle = atan2(dir1.y,dir1.x);
02194 range = atan2(-dir1.y*dir2.x+dir1.x*dir2.y,
02195 dir1.x*dir2.x+dir1.y*dir2.y);
02196 endangle = startangle + range;
02197
02198 } else if (Constr->First != Constraint::GeoUndef) {
02199 const Part::Geometry *geo = (*geomlist)[Constr->First];
02200 if (geo->getTypeId() != Part::GeomLineSegment::getClassTypeId())
02201 break;
02202 const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
02203
02204 p0 = Base::convertTo<SbVec3f>((lineSeg->getEndPoint()+lineSeg->getStartPoint())/2);
02205
02206 Base::Vector3d dir = lineSeg->getEndPoint()-lineSeg->getStartPoint();
02207 startangle = 0.;
02208 range = atan2(dir.y,dir.x);
02209 endangle = startangle + range;
02210 } else
02211 break;
02212
02213 SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(4));
02214 asciiText->string = SbString().sprintf("%.2f",Base::toDegrees<double>(std::abs(Constr->Value)));
02215
02216
02217 Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
02218
02219
02220 SoGetBoundingBoxAction bbAction(viewer->getViewportRegion());
02221 bbAction.apply(sep->getChild(4));
02222
02223 float bx,by,bz;
02224 bbAction.getBoundingBox().getSize(bx,by,bz);
02225 SbVec3f textBB(bx,by,bz);
02226
02227 SbVec3f textBBCenter = bbAction.getBoundingBox().getCenter();
02228
02229 float length = Constr->LabelDistance;
02230 float r = 2*length;
02231
02232 SbVec3f v0(cos(startangle+range/2),sin(startangle+range/2),0);
02233 SbVec3f textpos = p0 + v0 * r - SbVec3f(0,1,0) * textBBCenter[1]/4;
02234
02235
02236 if (range >= 0)
02237 range = std::max(0.2*range, range - textBB[0]/(2*r));
02238 else
02239 range = std::min(0.2*range, range + textBB[0]/(2*r));
02240
02241 int countSegments = std::max(6, abs(int(50.0 * range / (2 * M_PI))));
02242 double segment = range / (2*countSegments-2);
02243
02244
02245 SoTransform *transform = dynamic_cast<SoTransform *>(sep->getChild(2));
02246 transform->translation.setValue(textpos);
02247
02248
02249 SoSeparator *sepDatum = dynamic_cast<SoSeparator *>(sep->getChild(1));
02250 SoCoordinate3 *datumCord = dynamic_cast<SoCoordinate3 *>(sepDatum->getChild(0));
02251
02252 datumCord->point.setNum(2*countSegments+4);
02253 int i=0;
02254 int j=2*countSegments-1;
02255 for (; i < countSegments; i++, j--) {
02256 double angle = startangle + segment*i;
02257 datumCord->point.set1Value(i,p0+SbVec3f(r*cos(angle),r*sin(angle),0));
02258 angle = endangle - segment*i;
02259 datumCord->point.set1Value(j,p0+SbVec3f(r*cos(angle),r*sin(angle),0));
02260 }
02261 SbVec3f v1(cos(startangle),sin(startangle),0);
02262 SbVec3f v2(cos(endangle),sin(endangle),0);
02263 float sf = getScaleFactor();
02264 datumCord->point.set1Value(2*countSegments ,p0+(r-0.5f * sf)*v1);
02265 datumCord->point.set1Value(2*countSegments+1,p0+(r+0.5f * sf)*v1);
02266 datumCord->point.set1Value(2*countSegments+2,p0+(r-0.5f * sf)*v2);
02267 datumCord->point.set1Value(2*countSegments+3,p0+(r+0.5f * sf)*v2);
02268
02269
02270 SoLineSet *datumLineSet = dynamic_cast<SoLineSet *>(sepDatum->getChild(1));
02271 datumLineSet->numVertices.set1Value(0,countSegments);
02272 datumLineSet->numVertices.set1Value(1,countSegments);
02273 datumLineSet->numVertices.set1Value(2,2);
02274 datumLineSet->numVertices.set1Value(3,2);
02275 }
02276 break;
02277 case Radius:
02278 {
02279 assert(Constr->First < int(geomlist->size()));
02280
02281 Base::Vector3d pnt1(0.,0.,0.), pnt2(0.,0.,0.);
02282 if (Constr->First != Constraint::GeoUndef) {
02283 const Part::Geometry *geo = (*geomlist)[Constr->First];
02284
02285 if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
02286 const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo);
02287 double radius = arc->getRadius();
02288 double startangle, endangle;
02289 arc->getRange(startangle, endangle);
02290 double angle = (startangle + endangle)/2;
02291 pnt1 = arc->getCenter();
02292 pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
02293 }
02294 else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
02295 const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo);
02296 double radius = circle->getRadius();
02297 double angle = M_PI/4;
02298 pnt1 = circle->getCenter();
02299 pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
02300 } else
02301 break;
02302 } else
02303 break;
02304
02305 SbVec3f p1(pnt1.x,pnt1.y,zConstr);
02306 SbVec3f p2(pnt2.x,pnt2.y,zConstr);
02307
02308 SbVec3f dir = (p2-p1);
02309 dir.normalize();
02310 SbVec3f norm (-dir[1],dir[0],0);
02311
02312 float length = Constr->LabelDistance;
02313 SbVec3f pos = p2 + length*dir;
02314
02315 SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(4));
02316 asciiText->string = SbString().sprintf("%.2f",Constr->Value);
02317
02318
02319 Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
02320 Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
02321
02322
02323 SoGetBoundingBoxAction bbAction(viewer->getViewportRegion());
02324 bbAction.apply(sep->getChild(3));
02325
02326 float bx=0,by=0,bz=0;
02327 SbBox3f bbox = bbAction.getBoundingBox();
02328 if (!bbox.isEmpty())
02329 bbox.getSize(bx,by,bz);
02330 SbVec3f textBB(bx,by,bz);
02331
02332 SbVec3f textBBCenter = bbAction.getBoundingBox().getCenter();
02333
02334
02335 double angle = atan2f(dir[1],dir[0]);
02336 bool flip=false;
02337 if (angle > M_PI_2+M_PI/12) {
02338 angle -= M_PI;
02339 flip = true;
02340 } else if (angle <= -M_PI_2+M_PI/12) {
02341 angle += M_PI;
02342 flip = true;
02343 }
02344
02345 SbVec3f textpos = pos + norm * ( (flip ? 1:-1) * textBBCenter[1] / 1.7f);
02346
02347
02348 SoTransform *transform = dynamic_cast<SoTransform *>(sep->getChild(2));
02349 transform->rotation.setValue(SbVec3f(0, 0, 1), (float)angle);
02350 transform->translation.setValue(textpos);
02351
02352
02353 SoSeparator *sepDatum = dynamic_cast<SoSeparator *>(sep->getChild(1));
02354 SoCoordinate3 *datumCord = dynamic_cast<SoCoordinate3 *>(sepDatum->getChild(0));
02355
02356 SbVec3f p3 = pos + dir * (6+textBB[0]/1.7f);
02357 if ((p3-p1).length() > (p2-p1).length())
02358 p2 = p3;
02359
02360
02361 datumCord->point.set1Value(0,p1);
02362 datumCord->point.set1Value(1,pos - dir * (1+textBB[0]/1.7f) );
02363 datumCord->point.set1Value(2,pos + dir * (1+textBB[0]/1.7f) );
02364 datumCord->point.set1Value(3,p2);
02365
02366
02367 SoLineSet *datumLineSet = dynamic_cast<SoLineSet *>(sepDatum->getChild(1));
02368 datumLineSet->numVertices.set1Value(0,2);
02369 datumLineSet->numVertices.set1Value(1,2);
02370 }
02371 break;
02372 case Coincident:
02373 case None:
02374 break;
02375 }
02376 }
02377
02378 this->drawConstraintIcons();
02379 this->updateColor();
02380
02381
02382 for (std::vector<Part::Geometry *>::iterator it = tempGeo.begin(); it != tempGeo.end(); ++it)
02383 if (*it) delete *it;
02384
02385 if (mdi && mdi->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
02386 static_cast<Gui::View3DInventor *>(mdi)->getViewer()->render();
02387 }
02388 }
02389
02390 void ViewProviderSketch::rebuildConstraintsVisual(void)
02391 {
02392 const std::vector<Sketcher::Constraint *> &ConStr = getSketchObject()->Constraints.getValues();
02393
02394 edit->constrGroup->removeAllChildren();
02395 edit->vConstrType.clear();
02396
02397 for (std::vector<Sketcher::Constraint *>::const_iterator it = ConStr.begin(); it != ConStr.end(); ++it) {
02398
02399 SoSeparator *sep = new SoSeparator();
02400
02401 sep->renderCaching = SoSeparator::OFF;
02402
02403 SoMaterial *Material = new SoMaterial;
02404 Material->diffuseColor = ConstrDimColor;
02405 sep->addChild(Material);
02406
02407
02408 switch ((*it)->Type) {
02409 case Distance:
02410 case DistanceX:
02411 case DistanceY:
02412 case Radius:
02413 case Angle:
02414 {
02415 SoSeparator *sepDatum = new SoSeparator();
02416 sepDatum->addChild(new SoCoordinate3());
02417 SoLineSet *lineSet = new SoLineSet;
02418 sepDatum->addChild(lineSet);
02419
02420 sep->addChild(sepDatum);
02421
02422
02423 sep->addChild(new SoTransform());
02424
02425
02426 SoFont *font = new SoFont();
02427 font->size = 8.f;
02428 font->name = "FreeSans:bold, Helvetica, Arial, FreeSans:bold";
02429
02430 sep->addChild(font);
02431
02432 SoDatumLabel *text = new SoDatumLabel();
02433
02434 text->string = "";
02435 text->textColor = ConstrDimColor;
02436 sep->addChild(text);
02437
02438 edit->vConstrType.push_back((*it)->Type);
02439 }
02440 break;
02441 case Horizontal:
02442 case Vertical:
02443 {
02444 sep->addChild(new SoZoomTranslation());
02445 sep->addChild(new SoImage());
02446
02447
02448 edit->vConstrType.push_back((*it)->Type);
02449 }
02450 break;
02451 case Coincident:
02452 edit->vConstrType.push_back(Coincident);
02453 break;
02454 case Parallel:
02455 case Perpendicular:
02456 case Equal:
02457 {
02458
02459 sep->addChild(new SoZoomTranslation());
02460 sep->addChild(new SoImage());
02461 sep->addChild(new SoZoomTranslation());
02462 sep->addChild(new SoImage());
02463
02464
02465 edit->vConstrType.push_back((*it)->Type);
02466 }
02467 break;
02468 case PointOnObject:
02469 case Tangent:
02470 {
02471
02472 sep->addChild(new SoZoomTranslation());
02473 sep->addChild(new SoImage());
02474
02475 if ((*it)->Type == Tangent) {
02476 Part::Geometry *geo1 = getSketchObject()->Geometry.getValues()[(*it)->First];
02477 Part::Geometry *geo2 = getSketchObject()->Geometry.getValues()[(*it)->Second];
02478 if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
02479 geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
02480 sep->addChild(new SoZoomTranslation());
02481 sep->addChild(new SoImage());
02482 }
02483 }
02484
02485 edit->vConstrType.push_back((*it)->Type);
02486 }
02487 break;
02488 case Symmetric:
02489 {
02490 SoSeparator *sepArrows = new SoSeparator();
02491 sepArrows->addChild(new SoCoordinate3());
02492 SoLineSet *lineSet = new SoLineSet;
02493 sepArrows->addChild(lineSet);
02494 sep->addChild(sepArrows);
02495
02496
02497 sep->addChild(new SoTranslation());
02498 sep->addChild(new SoImage());
02499
02500 edit->vConstrType.push_back((*it)->Type);
02501 }
02502 break;
02503 default:
02504 edit->vConstrType.push_back(None);
02505 }
02506
02507 edit->constrGroup->addChild(sep);
02508 }
02509 }
02510
02511 void ViewProviderSketch::drawEdit(const std::vector<Base::Vector2D> &EditCurve)
02512 {
02513 assert(edit);
02514
02515 edit->EditCurveSet->numVertices.setNum(1);
02516 edit->EditCurvesCoordinate->point.setNum(EditCurve.size());
02517 SbVec3f *verts = edit->EditCurvesCoordinate->point.startEditing();
02518 int32_t *index = edit->EditCurveSet->numVertices.startEditing();
02519
02520 int i=0;
02521 for (std::vector<Base::Vector2D>::const_iterator it = EditCurve.begin(); it != EditCurve.end(); ++it,i++)
02522 verts[i].setValue(it->fX,it->fY,zEdit);
02523
02524 index[0] = EditCurve.size();
02525 edit->EditCurvesCoordinate->point.finishEditing();
02526 edit->EditCurveSet->numVertices.finishEditing();
02527 }
02528
02529 void ViewProviderSketch::updateData(const App::Property *prop)
02530 {
02531 ViewProvider2DObject::updateData(prop);
02532
02533 if (edit && (prop == &(getSketchObject()->Geometry) || &(getSketchObject()->Constraints))) {
02534 edit->FullyConstrained = false;
02535 int dofs = edit->ActSketch.setUpSketch(getSketchObject()->Geometry.getValues(),
02536 getSketchObject()->Constraints.getValues());
02537 std::string msg;
02538 if (getSketchObject()->Geometry.getSize() == 0) {
02539 signalSetUp(-1, 0, msg);
02540 signalSolved(-1, 0);
02541 }
02542 else if (dofs < 0) {
02543 SketchObject::appendConflictMsg(edit->ActSketch.getConflicting(), msg);
02544
02545 signalSetUp(3, 0, msg);
02546 signalSolved(-1,0);
02547 }
02548 else if (edit->ActSketch.hasConflicts()) {
02549 SketchObject::appendConflictMsg(edit->ActSketch.getConflicting(), msg);
02550
02551 signalSetUp(2, dofs, msg);
02552 signalSolved(-1,0);
02553 }
02554 else if (edit->ActSketch.solve() == 0) {
02555 if (dofs == 0) {
02556
02557 edit->FullyConstrained = true;
02558
02559 signalSetUp(0, 0, msg);
02560 }
02561 else {
02562
02563 signalSetUp(1, dofs, msg);
02564 }
02565 signalSolved(0,edit->ActSketch.SolveTime);
02566 }
02567 else {
02568 signalSolved(1,edit->ActSketch.SolveTime);
02569 }
02570 draw(true);
02571 }
02572 if (edit && &(getSketchObject()->Constraints)) {
02573
02574 signalConstraintsChanged();
02575 }
02576 }
02577
02578 void ViewProviderSketch::onChanged(const App::Property *prop)
02579 {
02580
02581 PartGui::ViewProvider2DObject::onChanged(prop);
02582 }
02583
02584 void ViewProviderSketch::attach(App::DocumentObject *pcFeat)
02585 {
02586 ViewProviderPart::attach(pcFeat);
02587 }
02588
02589 void ViewProviderSketch::setupContextMenu(QMenu *menu, QObject *receiver, const char *member)
02590 {
02591 menu->addAction(QObject::tr("Edit sketch"), receiver, member);
02592 }
02593
02594 bool ViewProviderSketch::setEdit(int ModNum)
02595 {
02596
02597
02598
02599 Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
02600 TaskDlgEditSketch *sketchDlg = qobject_cast<TaskDlgEditSketch *>(dlg);
02601 if (sketchDlg && sketchDlg->getSketchView() != this)
02602 sketchDlg = 0;
02603 if (dlg && !sketchDlg) {
02604 QMessageBox msgBox;
02605 msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
02606 msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
02607 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
02608 msgBox.setDefaultButton(QMessageBox::Yes);
02609 int ret = msgBox.exec();
02610 if (ret == QMessageBox::Yes)
02611 Gui::Control().closeDialog();
02612 else
02613 return false;
02614 }
02615
02616
02617 Gui::Selection().clearSelection();
02618
02619
02620 assert(!edit);
02621 edit = new EditData();
02622
02623 createEditInventorNodes();
02624 this->hide();
02625
02626 ShowGrid.setValue(true);
02627 TightGrid.setValue(false);
02628
02629 ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
02630 float transparency;
02631
02632
02633 unsigned long color = (unsigned long)(VertexColor.getPackedValue());
02634 color = hGrp->GetUnsigned("EditedVertexColor", color);
02635 VertexColor.setPackedValue((uint32_t)color, transparency);
02636
02637 color = (unsigned long)(CurveColor.getPackedValue());
02638 color = hGrp->GetUnsigned("EditedEdgeColor", color);
02639 CurveColor.setPackedValue((uint32_t)color, transparency);
02640
02641 color = (unsigned long)(CurveDraftColor.getPackedValue());
02642 color = hGrp->GetUnsigned("ConstructionColor", color);
02643 CurveDraftColor.setPackedValue((uint32_t)color, transparency);
02644
02645
02646
02647
02648 color = (unsigned long)(FullyConstrainedColor.getPackedValue());
02649 color = hGrp->GetUnsigned("FullyConstrainedColor", color);
02650 FullyConstrainedColor.setPackedValue((uint32_t)color, transparency);
02651
02652
02653
02654
02655
02656 unsigned long highlight = (unsigned long)(PreselectColor.getPackedValue());
02657 highlight = hGrp->GetUnsigned("HighlightColor", highlight);
02658 PreselectColor.setPackedValue((uint32_t)highlight, transparency);
02659
02660 highlight = (unsigned long)(SelectColor.getPackedValue());
02661 highlight = hGrp->GetUnsigned("SelectionColor", highlight);
02662 SelectColor.setPackedValue((uint32_t)highlight, transparency);
02663
02664
02665 if (sketchDlg)
02666 Gui::Control().showDialog(sketchDlg);
02667 else
02668 Gui::Control().showDialog(new TaskDlgEditSketch(this));
02669
02670
02671 int dofs = edit->ActSketch.setUpSketch(getSketchObject()->Geometry.getValues(),
02672 getSketchObject()->Constraints.getValues());
02673 std::string msg;
02674 if (getSketchObject()->Geometry.getSize() == 0) {
02675 signalSetUp(-1, 0, msg);
02676 signalSolved(-1, 0);
02677 }
02678 else if (dofs < 0) {
02679 SketchObject::appendConflictMsg(edit->ActSketch.getConflicting(), msg);
02680
02681 signalSetUp(3, 0, msg);
02682 signalSolved(-1, 0);
02683 }
02684 else if (edit->ActSketch.hasConflicts()) {
02685 SketchObject::appendConflictMsg(edit->ActSketch.getConflicting(), msg);
02686
02687 signalSetUp(2, dofs, msg);
02688 signalSolved(-1, 0);
02689 }
02690 else if (edit->ActSketch.solve() == 0) {
02691 if (dofs == 0) {
02692
02693 edit->FullyConstrained = true;
02694
02695 signalSetUp(0, 0, msg);
02696 }
02697 else {
02698
02699 signalSetUp(1, dofs, msg);
02700 }
02701 signalSolved(0, edit->ActSketch.SolveTime);
02702 }
02703 else {
02704 signalSolved(1, edit->ActSketch.SolveTime);
02705 }
02706
02707 draw();
02708
02709 return true;
02710 }
02711
02712 void ViewProviderSketch::createEditInventorNodes(void)
02713 {
02714 assert(edit);
02715
02716 edit->EditRoot = new SoSeparator;
02717 pcRoot->addChild(edit->EditRoot);
02718 edit->EditRoot->renderCaching = SoSeparator::OFF ;
02719
02720
02721 edit->PointsMaterials = new SoMaterial;
02722 edit->EditRoot->addChild(edit->PointsMaterials);
02723
02724 SoMaterialBinding *MtlBind = new SoMaterialBinding;
02725 MtlBind->value = SoMaterialBinding::PER_VERTEX;
02726 edit->EditRoot->addChild(MtlBind);
02727
02728 edit->PointsCoordinate = new SoCoordinate3;
02729 edit->EditRoot->addChild(edit->PointsCoordinate);
02730
02731 SoDrawStyle *DrawStyle = new SoDrawStyle;
02732 DrawStyle->pointSize = 8;
02733 edit->EditRoot->addChild(DrawStyle);
02734 edit->PointSet = new SoMarkerSet;
02735 edit->PointSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_7_7;
02736 edit->EditRoot->addChild(edit->PointSet);
02737
02738
02739 edit->CurvesMaterials = new SoMaterial;
02740 edit->EditRoot->addChild(edit->CurvesMaterials);
02741
02742 MtlBind = new SoMaterialBinding;
02743 MtlBind->value = SoMaterialBinding::PER_FACE;
02744 edit->EditRoot->addChild(MtlBind);
02745
02746 edit->CurvesCoordinate = new SoCoordinate3;
02747 edit->EditRoot->addChild(edit->CurvesCoordinate);
02748
02749 DrawStyle = new SoDrawStyle;
02750 DrawStyle->lineWidth = 3;
02751 edit->EditRoot->addChild(DrawStyle);
02752
02753 edit->CurveSet = new SoLineSet;
02754
02755 edit->EditRoot->addChild(edit->CurveSet);
02756
02757
02758 MtlBind = new SoMaterialBinding;
02759 MtlBind->value = SoMaterialBinding::PER_FACE;
02760 edit->EditRoot->addChild(MtlBind);
02761
02762 DrawStyle = new SoDrawStyle;
02763 DrawStyle->lineWidth = 2;
02764 edit->EditRoot->addChild(DrawStyle);
02765
02766 edit->RootCrossMaterialsV = new SoMaterial;
02767 edit->RootCrossMaterialsV->diffuseColor.set1Value(0,CrossColorV);
02768 edit->EditRoot->addChild(edit->RootCrossMaterialsV);
02769
02770 edit->RootCrossCoordinateV = new SoCoordinate3;
02771 edit->EditRoot->addChild(edit->RootCrossCoordinateV);
02772
02773 edit->RootCrossSetV = new SoLineSet;
02774 edit->RootCrossSetV->numVertices.set1Value(0,2);
02775 edit->EditRoot->addChild(edit->RootCrossSetV);
02776
02777 edit->RootCrossMaterialsH = new SoMaterial;
02778 edit->RootCrossMaterialsH->diffuseColor.set1Value(0,CrossColorH);
02779 edit->EditRoot->addChild(edit->RootCrossMaterialsH);
02780
02781 edit->RootCrossCoordinateH = new SoCoordinate3;
02782 edit->EditRoot->addChild(edit->RootCrossCoordinateH);
02783
02784 edit->RootCrossSetH = new SoLineSet;
02785 edit->RootCrossSetH->numVertices.set1Value(0,2);
02786 edit->EditRoot->addChild(edit->RootCrossSetH);
02787
02788
02789
02790 edit->EditCurvesMaterials = new SoMaterial;
02791 edit->EditRoot->addChild(edit->EditCurvesMaterials);
02792
02793 edit->EditCurvesCoordinate = new SoCoordinate3;
02794 edit->EditRoot->addChild(edit->EditCurvesCoordinate);
02795
02796 DrawStyle = new SoDrawStyle;
02797 DrawStyle->lineWidth = 3;
02798 edit->EditRoot->addChild(DrawStyle);
02799
02800 edit->EditCurveSet = new SoLineSet;
02801 edit->EditRoot->addChild(edit->EditCurveSet);
02802
02803
02804 SoMaterial *EditMaterials = new SoMaterial;
02805 EditMaterials->diffuseColor = SbColor(0,0,1);
02806 edit->EditRoot->addChild(EditMaterials);
02807
02808 SoSeparator *Coordsep = new SoSeparator();
02809
02810 Coordsep->renderCaching = SoSeparator::OFF;
02811
02812 SoFont *font = new SoFont();
02813 font->size = 15.0;
02814 Coordsep->addChild(font);
02815
02816 edit->textPos = new SoTranslation();
02817 Coordsep->addChild(edit->textPos);
02818
02819 edit->textX = new SoText2();
02820 edit->textX->justification = SoText2::LEFT;
02821 edit->textX->string = "";
02822 Coordsep->addChild(edit->textX);
02823 edit->EditRoot->addChild(Coordsep);
02824
02825
02826 MtlBind = new SoMaterialBinding;
02827 MtlBind->value = SoMaterialBinding::OVERALL ;
02828 edit->EditRoot->addChild(MtlBind);
02829
02830
02831 font = new SoFont();
02832 font->size = 8.0;
02833 edit->EditRoot->addChild(font);
02834
02835
02836 DrawStyle = new SoDrawStyle;
02837 DrawStyle->lineWidth = 1;
02838 edit->EditRoot->addChild(DrawStyle);
02839
02840
02841 edit->constrGroup = new SoGroup();
02842 edit->EditRoot->addChild(edit->constrGroup);
02843 }
02844
02845 void ViewProviderSketch::unsetEdit(int ModNum)
02846 {
02847 ShowGrid.setValue(false);
02848 TightGrid.setValue(true);
02849
02850 edit->EditRoot->removeAllChildren();
02851 pcRoot->removeChild(edit->EditRoot);
02852
02853 if (edit->sketchHandler) {
02854 edit->sketchHandler->unsetCursor();
02855 purgeHandler();
02856 }
02857 delete edit;
02858 edit = 0;
02859
02860 this->show();
02861
02862
02863 getSketchObject()->getDocument()->recompute();
02864
02865
02866 Gui::Selection().clearSelection();
02867 std::string ObjName = getSketchObject()->getNameInDocument();
02868 std::string DocName = getSketchObject()->getDocument()->getName();
02869 Gui::Selection().addSelection(DocName.c_str(),ObjName.c_str());
02870
02871
02872 Gui::Control().closeDialog();
02873 }
02874
02875 void ViewProviderSketch::setEditViewer(Gui::View3DInventorViewer* viewer, int ModNum)
02876 {
02877 Base::Placement plm = getSketchObject()->Placement.getValue();
02878 Base::Rotation tmp(plm.getRotation());
02879
02880 SbRotation rot((float)tmp[0],(float)tmp[1],(float)tmp[2],(float)tmp[3]);
02881 viewer->setCameraOrientation(rot);
02882
02883 viewer->setEditing(TRUE);
02884 SoNode* root = viewer->getSceneGraph();
02885 static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionRole.setValue(FALSE);
02886 }
02887
02888 void ViewProviderSketch::unsetEditViewer(Gui::View3DInventorViewer* viewer)
02889 {
02890 viewer->setEditing(FALSE);
02891 SoNode* root = viewer->getSceneGraph();
02892 static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionRole.setValue(TRUE);
02893 }
02894
02895 void ViewProviderSketch::setPositionText(const Base::Vector2D &Pos)
02896 {
02897 char buf[40];
02898 sprintf( buf, " (%.1f,%.1f)", Pos.fX,Pos.fY );
02899 edit->textX->string = buf;
02900 edit->textPos->translation = SbVec3f(Pos.fX,Pos.fY,zText);
02901 }
02902
02903 void ViewProviderSketch::resetPositionText(void)
02904 {
02905 edit->textX->string = "";
02906 }
02907
02908 void ViewProviderSketch::setPreselectPoint(int PreselectPoint)
02909 {
02910 if (edit) {
02911 SbVec3f *pverts = edit->PointsCoordinate->point.startEditing();
02912 float x,y,z;
02913 if (edit->PreselectPoint != -1 &&
02914 edit->SelPointSet.find(edit->PreselectPoint) == edit->SelPointSet.end()) {
02915
02916 pverts[edit->PreselectPoint].getValue(x,y,z);
02917 pverts[edit->PreselectPoint].setValue(x,y,zPoints);
02918 }
02919
02920 pverts[PreselectPoint].getValue(x,y,z);
02921 pverts[PreselectPoint].setValue(x,y,zHighlight);
02922 edit->PreselectPoint = PreselectPoint;
02923 edit->PointsCoordinate->point.finishEditing();
02924 }
02925 }
02926
02927 void ViewProviderSketch::resetPreselectPoint(void)
02928 {
02929 if (edit) {
02930 if (edit->PreselectPoint != -1 &&
02931 edit->SelPointSet.find(edit->PreselectPoint) == edit->SelPointSet.end()) {
02932
02933 SbVec3f *pverts = edit->PointsCoordinate->point.startEditing();
02934 float x,y,z;
02935 pverts[edit->PreselectPoint].getValue(x,y,z);
02936 pverts[edit->PreselectPoint].setValue(x,y,zPoints);
02937 edit->PointsCoordinate->point.finishEditing();
02938 }
02939 edit->PreselectPoint = -1;
02940 }
02941 }
02942
02943 void ViewProviderSketch::addSelectPoint(int SelectPoint)
02944 {
02945 if (edit) {
02946 SbVec3f *pverts = edit->PointsCoordinate->point.startEditing();
02947
02948 float x,y,z;
02949 pverts[SelectPoint].getValue(x,y,z);
02950 pverts[SelectPoint].setValue(x,y,zHighlight);
02951 edit->SelPointSet.insert(SelectPoint);
02952 edit->PointsCoordinate->point.finishEditing();
02953 }
02954 }
02955
02956 void ViewProviderSketch::removeSelectPoint(int SelectPoint)
02957 {
02958 if (edit) {
02959 SbVec3f *pverts = edit->PointsCoordinate->point.startEditing();
02960
02961 float x,y,z;
02962 pverts[SelectPoint].getValue(x,y,z);
02963 pverts[SelectPoint].setValue(x,y,zPoints);
02964 edit->SelPointSet.erase(SelectPoint);
02965 edit->PointsCoordinate->point.finishEditing();
02966 }
02967 }
02968
02969 void ViewProviderSketch::clearSelectPoints(void)
02970 {
02971 if (edit) {
02972 SbVec3f *pverts = edit->PointsCoordinate->point.startEditing();
02973
02974 float x,y,z;
02975 for (std::set<int>::const_iterator it=edit->SelPointSet.begin();
02976 it != edit->SelPointSet.end(); ++it) {
02977 pverts[*it].getValue(x,y,z);
02978 pverts[*it].setValue(x,y,zPoints);
02979 }
02980 edit->PointsCoordinate->point.finishEditing();
02981 edit->SelPointSet.clear();
02982 }
02983 }
02984
02985 int ViewProviderSketch::getPreselectPoint(void) const
02986 {
02987 if (edit)
02988 return edit->PreselectPoint;
02989 return -1;
02990 }
02991
02992 int ViewProviderSketch::getPreselectCurve(void) const
02993 {
02994 if (edit)
02995 return edit->PreselectCurve;
02996 return -1;
02997 }
02998
02999 int ViewProviderSketch::getPreselectConstraint(void) const
03000 {
03001 if (edit)
03002 return edit->PreselectConstraint;
03003 return -1;
03004 }
03005
03006 Sketcher::SketchObject *ViewProviderSketch::getSketchObject(void) const
03007 {
03008 return dynamic_cast<Sketcher::SketchObject *>(pcObject);
03009 }
03010
03011 bool ViewProviderSketch::onDelete(const std::vector<std::string> &subList)
03012 {
03013
03014 if (edit) {
03015
03016
03017 this->blockConnection(true);
03018 std::set<int>::const_reverse_iterator rit;
03019 for (rit = edit->SelConstraintSet.rbegin(); rit != edit->SelConstraintSet.rend(); rit++) {
03020 try {
03021 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.delConstraint(%i)"
03022 ,getObject()->getNameInDocument(), *rit);
03023 }
03024 catch (const Base::Exception& e) {
03025 Base::Console().Error("%s\n", e.what());
03026 }
03027 }
03028 for (rit = edit->SelCurvSet.rbegin(); rit != edit->SelCurvSet.rend(); rit++) {
03029 try {
03030 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.delGeometry(%i)"
03031 ,getObject()->getNameInDocument(), *rit);
03032 }
03033 catch (const Base::Exception& e) {
03034 Base::Console().Error("%s\n", e.what());
03035 }
03036 }
03037 for (rit = edit->SelPointSet.rbegin(); rit != edit->SelPointSet.rend(); rit++) {
03038 try {
03039 Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.delConstraintOnPoint(%i)"
03040 ,getObject()->getNameInDocument(), *rit);
03041 }
03042 catch (const Base::Exception& e) {
03043 Base::Console().Error("%s\n", e.what());
03044 }
03045 }
03046
03047 this->blockConnection(false);
03048 Gui::Selection().clearSelection();
03049 resetPreselectPoint();
03050 edit->PreselectCurve = -1;
03051 edit->PreselectCross = -1;
03052 edit->PreselectConstraint = -1;
03053 this->drawConstraintIcons();
03054 this->updateColor();
03055
03056 return false;
03057 }
03058
03059 return true;
03060 }