From 6d35d55905db7664c1b3a38673e0e1f524a1cc19 Mon Sep 17 00:00:00 2001 From: logari81 Date: Sat, 24 Dec 2011 22:17:39 +0000 Subject: [PATCH 01/21] + fix minor bug in freeGCS + make handling of negative curve indices in ViewProviderSketch more consistent git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5347 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/App/freegcs/GCS.cpp | 3 + src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 69 ++++++++++----------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/Mod/Sketcher/App/freegcs/GCS.cpp b/src/Mod/Sketcher/App/freegcs/GCS.cpp index 5b3795b57..069e18162 100644 --- a/src/Mod/Sketcher/App/freegcs/GCS.cpp +++ b/src/Mod/Sketcher/App/freegcs/GCS.cpp @@ -755,6 +755,9 @@ int System::solve_DL(SubSystem* subsys) int xsize = subsys->pSize(); int csize = subsys->cSize(); + if (xsize == 0) + return Success; + Eigen::VectorXd x(xsize), x_new(xsize); Eigen::VectorXd fx(csize), fx_new(csize); Eigen::MatrixXd Jx(csize, xsize), Jx_new(csize, xsize); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 468a49a27..0d208a1cb 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -364,19 +364,19 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe float dci = (float) QApplication::doubleClickInterval()/1000.0f; float length = (point - prvClickPoint).length(); - if (edit->PreselectPoint >= 0) { + if (edit->PreselectPoint != -1) { //Base::Console().Log("start dragging, point:%d\n",this->DragPoint); Mode = STATUS_SELECT_Point; done = true; - } else if (edit->PreselectCurve >= 0) { + } else if (edit->PreselectCurve != -1) { //Base::Console().Log("start dragging, point:%d\n",this->DragPoint); Mode = STATUS_SELECT_Edge; done = true; - } else if (edit->PreselectCross >= 0) { + } else if (edit->PreselectCross != -1) { //Base::Console().Log("start dragging, point:%d\n",this->DragPoint); Mode = STATUS_SELECT_Cross; done = true; - } else if (edit->PreselectConstraint >= 0) { + } else if (edit->PreselectConstraint != -1) { //Base::Console().Log("start dragging, point:%d\n",this->DragPoint); Mode = STATUS_SELECT_Constraint; done = true; @@ -435,14 +435,11 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe case STATUS_SELECT_Edge: if (pp) { //Base::Console().Log("Select Point:%d\n",this->DragPoint); - int maxGeoId = getSketchObject()->getHighestCurveIndex(); std::stringstream ss; - if (edit->PreselectCurve <= maxGeoId) + if (edit->PreselectCurve >= 0) ss << "Edge" << edit->PreselectCurve; - else { // external geometry - int extGeoCount = getSketchObject()->getExternalGeometryCount(); - ss << "ExternalEdge" << extGeoCount - 2 - (edit->PreselectCurve - maxGeoId); - } + else // external geometry + ss << "ExternalEdge" << -edit->PreselectCurve - 3; // If edge already selected move from selection if (Gui::Selection().isSelected(getSketchObject()->getDocument()->getName() @@ -590,11 +587,11 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe case STATUS_NONE: { // A right click shouldn't change the Edit Mode - if (edit->PreselectPoint >= 0) { + if (edit->PreselectPoint != -1) { return true; - } else if (edit->PreselectCurve >= 0) { + } else if (edit->PreselectCurve != -1) { return true; - } else if (edit->PreselectConstraint >= 0) { + } else if (edit->PreselectConstraint != -1) { return true; } else { //Get Viewer @@ -665,7 +662,7 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe if (edit->PreselectCurve == index) rightClickOnSelectedLine = true; } else { - // The selection is not exclusivly edges + // The selection is not exclusively edges rightClickOnSelectedLine = false; } } // End of Iteration @@ -700,16 +697,16 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe void ViewProviderSketch::editDoubleClicked(void) { - if (edit->PreselectPoint >= 0) { + if (edit->PreselectPoint != -1) { Base::Console().Log("double click point:%d\n",edit->PreselectPoint); } - else if (edit->PreselectCurve >= 0) { + else if (edit->PreselectCurve != -1) { Base::Console().Log("double click edge:%d\n",edit->PreselectCurve); } - else if (edit->PreselectCross >= 0) { + else if (edit->PreselectCross != -1) { Base::Console().Log("double click cross:%d\n",edit->PreselectCross); } - else if (edit->PreselectConstraint >= 0) { + else if (edit->PreselectConstraint != -1) { // Find the constraint Base::Console().Log("double click constraint:%d\n",edit->PreselectConstraint); @@ -1170,7 +1167,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI assert(edit); PtIndex = -1; - CurvIndex = -1; + CurvIndex = -1; // valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry CrossIndex = -1; ConstrIndex = -1; @@ -1195,6 +1192,11 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI if (curve_detail && curve_detail->getTypeId() == SoLineDetail::getClassTypeId()) { // get the index CurvIndex = static_cast(curve_detail)->getLineIndex(); + int maxGeoId = getSketchObject()->getHighestCurveIndex(); + if (CurvIndex > maxGeoId) { // hit on external geometry + int extGeoCount = getSketchObject()->getExternalGeometryCount(); + CurvIndex = -extGeoCount + (CurvIndex - maxGeoId - 1); + } } // checking for a hit in the cross } else if (tail == edit->RootCrossSet) { @@ -1215,7 +1217,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI } } - if (PtIndex >= 0 && PtIndex != edit->PreselectPoint) { // if a new point is hit + if (PtIndex != -1 && PtIndex != edit->PreselectPoint) { // if a new point is hit std::stringstream ss; ss << "Vertex" << PtIndex; bool accepted = @@ -1235,15 +1237,12 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI edit->sketchHandler->applyCursor(); return true; } - } else if (CurvIndex >= 0 && CurvIndex != edit->PreselectCurve) { // if a new curve is hit - int maxGeoId = getSketchObject()->getHighestCurveIndex(); + } else if (CurvIndex != -1 && CurvIndex != edit->PreselectCurve) { // if a new curve is hit std::stringstream ss; - if (CurvIndex <= maxGeoId) + if (CurvIndex >= 0) ss << "Edge" << CurvIndex; - else { // external geometry - int extGeoCount = getSketchObject()->getExternalGeometryCount(); - ss << "ExternalEdge" << extGeoCount - 2 - (CurvIndex - maxGeoId); - } + else // external geometry + ss << "ExternalEdge" << -CurvIndex - 3; // convert index start from -3 to 0 bool accepted = Gui::Selection().setPreselect(getSketchObject()->getDocument()->getName() ,getSketchObject()->getNameInDocument() @@ -1261,7 +1260,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI edit->sketchHandler->applyCursor(); return true; } - } else if (CrossIndex >= 0 && CrossIndex != edit->PreselectCross) { // if a cross line is hit + } else if (CrossIndex != -1 && CrossIndex != edit->PreselectCross) { // if a cross line is hit std::stringstream ss; switch(CrossIndex){ case 0: ss << "RootPoint" ; break; @@ -1285,7 +1284,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI edit->sketchHandler->applyCursor(); return true; } - } else if (ConstrIndex >= 0 && ConstrIndex != edit->PreselectConstraint) { // if a constraint is hit + } else if (ConstrIndex != -1 && ConstrIndex != edit->PreselectConstraint) { // if a constraint is hit std::stringstream ss; ss << "Constraint" << ConstrIndex; bool accepted = @@ -1305,9 +1304,9 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI edit->sketchHandler->applyCursor(); return true; } - } else if ((PtIndex < 0 && CurvIndex < 0 && CrossIndex < 0 && ConstrIndex < 0) && - (edit->PreselectPoint >= 0 || edit->PreselectCurve >= 0 || edit->PreselectCross >= 0 - || edit->PreselectConstraint >= 0 || edit->blockedPreselection)) { + } else if ((PtIndex == -1 && CurvIndex == -1 && CrossIndex == -1 && ConstrIndex == -1) && + (edit->PreselectPoint != -1 || edit->PreselectCurve != -1 || edit->PreselectCross != -1 + || edit->PreselectConstraint != -1 || edit->blockedPreselection)) { // we have just left a preselection resetPreselectPoint(); edit->PreselectCurve = -1; @@ -1321,8 +1320,8 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI Gui::Selection().setPreselectCoord(Point->getPoint()[0] ,Point->getPoint()[1] ,Point->getPoint()[2]); - } else if (edit->PreselectCurve >= 0 || edit->PreselectPoint >= 0 || - edit->PreselectConstraint >= 0 || edit->PreselectCross >= 0 || edit->blockedPreselection) { + } else if (edit->PreselectCurve != -1 || edit->PreselectPoint != -1 || + edit->PreselectConstraint != -1 || edit->PreselectCross != -1 || edit->blockedPreselection) { resetPreselectPoint(); edit->PreselectCurve = -1; edit->PreselectCross = -1; @@ -1366,7 +1365,7 @@ void ViewProviderSketch::updateColor(void) int GeoId = (i < intGeoCount) ? i : -(extGeoCount - (i - intGeoCount)); if (edit->SelCurvSet.find(GeoId) != edit->SelCurvSet.end()) color[i] = SelectColor; - else if (edit->PreselectCurve == i) + else if (edit->PreselectCurve == GeoId) color[i] = PreselectColor; else if (GeoId < -2) // external Geometry color[i] = CurveExternalColor; From d83e488394f4034e218ad15d0ae9cd594aae233f Mon Sep 17 00:00:00 2001 From: logari81 Date: Sat, 24 Dec 2011 23:50:31 +0000 Subject: [PATCH 02/21] + improve support for external geometries in sketcher constraints git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5348 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/Gui/CommandConstraints.cpp | 125 ++++++++++++++++---- 1 file changed, 103 insertions(+), 22 deletions(-) diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index b00676d5e..f6f77b7e6 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -66,6 +66,17 @@ void updateDatumDistance(Gui::Document *doc, Constraint *constr) } } +bool checkBothExternal(int GeoId1, int GeoId2) +{ + if (GeoId1 < 0 && GeoId2 < 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Cannot add a constraint between two external geometries!")); + return true; + } + else + return false; +} + namespace SketcherGui { struct SketchSelection{ @@ -188,7 +199,7 @@ void CmdSketcherConstrainHorizontal::activated(int iMsg) std::vector ids; // go through the selected subelements - for(std::vector::const_iterator it=SubNames.begin();it!=SubNames.end();++it){ + for (std::vector::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) { // only handle edges if (it->size() > 4 && it->substr(0,4) == "Edge") { int index=std::atoi(it->substr(4,4000).c_str()); @@ -217,6 +228,13 @@ void CmdSketcherConstrainHorizontal::activated(int iMsg) ids.push_back(index); } } + + if (ids.empty()) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), + QObject::tr("The selected item(s) can't accept a horizontal constraint!")); + return; + } + // undo command open openCommand("add horizontal constraint"); for (std::vector::iterator it=ids.begin(); it != ids.end(); it++) { @@ -272,7 +290,6 @@ void CmdSketcherConstrainVertical::activated(int iMsg) const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues(); std::vector ids; - // go through the selected subelements for (std::vector::const_iterator it=SubNames.begin();it!=SubNames.end();++it) { // only handle edges @@ -304,6 +321,12 @@ void CmdSketcherConstrainVertical::activated(int iMsg) } } + if (ids.empty()) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Impossible constraint"), + QObject::tr("The selected item(s) can't accept a vertical constraint!")); + return; + } + // undo command open openCommand("add vertical constraint"); for (std::vector::iterator it=ids.begin(); it != ids.end(); it++) { @@ -500,13 +523,6 @@ CmdSketcherConstrainDistance::CmdSketcherConstrainDistance() void CmdSketcherConstrainDistance::activated(int iMsg) { -#if 0 - - SketchSelection selection; - - int num = selection.setUp(); - -#else // get the selection std::vector selection = getSelection().getSelectionEx(); @@ -568,8 +584,9 @@ void CmdSketcherConstrainDistance::activated(int iMsg) getSelection().clearSelection(); return; } - else if ((VtId1 >= 0 && GeoId2 >= 0) || (VtId2 >= 0 && GeoId1 >= 0)) { // point to line distance - if (VtId2 >= 0 && GeoId1 >= 0) { + else if ((VtId1 >= 0 && GeoId2 != Constraint::GeoUndef) || + (VtId2 >= 0 && GeoId1 != Constraint::GeoUndef)) { // point to line distance + if (VtId2 >= 0 && GeoId1 != Constraint::GeoUndef) { std::swap(VtId1,VtId2); std::swap(GeoId1,GeoId2); } @@ -602,7 +619,13 @@ void CmdSketcherConstrainDistance::activated(int iMsg) return; } } - else if (GeoId1 >= 0) { // line length + else if (GeoId1 != Constraint::GeoUndef) { // line length + if (GeoId1 < 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Cannot add a length constraint on an external geometry!")); + return; + } + const Part::Geometry *geom = Obj->getGeometry(GeoId1); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment *lineSeg; @@ -630,7 +653,6 @@ void CmdSketcherConstrainDistance::activated(int iMsg) QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select exactly one line or one point and one line or two points from the sketch.")); return; -#endif } bool CmdSketcherConstrainDistance::isActive(void) @@ -696,8 +718,9 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg) VtId2 = std::atoi(SubNames[1].substr(6,4000).c_str()); } - if ((VtId1 >= 0 && GeoId2 != Constraint::GeoUndef) || (VtId2 >= 0 && GeoId1 != Constraint::GeoUndef)) { - if (VtId2 >= 0 && GeoId1 >= 0) { + if ((VtId1 >= 0 && GeoId2 != Constraint::GeoUndef) || + (VtId2 >= 0 && GeoId1 != Constraint::GeoUndef)) { + if (VtId2 >= 0 && GeoId1 != Constraint::GeoUndef) { std::swap(VtId1,VtId2); std::swap(GeoId1,GeoId2); } @@ -705,6 +728,9 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg) Sketcher::PointPos PosId1; Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1); + if (checkBothExternal(GeoId1, GeoId2)) + return; + const Part::Geometry *geom = Obj->getGeometry(GeoId2); // Currently only accepts line segments and circles @@ -820,7 +846,15 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) getSelection().clearSelection(); return; } - else if (GeoId1 >= 0 && GeoId2 == Constraint::GeoUndef && VtId2 < 0) { // horizontal length of a line + else if (GeoId1 != Constraint::GeoUndef && + GeoId2 == Constraint::GeoUndef && VtId2 < 0) { // horizontal length of a line + + if (GeoId1 < 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Cannot add a horizontal length constraint on an external geometry!")); + return; + } + const Part::Geometry *geom = Obj->getGeometry(GeoId1); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment *lineSeg; @@ -965,7 +999,15 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) getSelection().clearSelection(); return; } - else if (GeoId1 >= 0 && GeoId2 == Constraint::GeoUndef && VtId2 < 0) { // horizontal length of a line + else if (GeoId1 != Constraint::GeoUndef && + GeoId2 == Constraint::GeoUndef && VtId2 < 0) { // vertical length of a line + + if (GeoId1 < 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Cannot add a vertical length constraint on an external geometry!")); + return; + } + const Part::Geometry *geom = Obj->getGeometry(GeoId1); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment *lineSeg; @@ -1149,6 +1191,8 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) int GeoId1,GeoId2; if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge") GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str()); + else if (SubNames[0].size() > 12 && SubNames[0].substr(0,12) == "ExternalEdge") + GeoId1 = -3 - std::atoi(SubNames[0].substr(12,4000).c_str()); else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select exactly two lines from the sketch.")); @@ -1157,12 +1201,17 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge") GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str()); + else if (SubNames[1].size() > 12 && SubNames[1].substr(0,12) == "ExternalEdge") + GeoId2 = -3 - std::atoi(SubNames[1].substr(12,4000).c_str()); else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select exactly two lines from the sketch.")); return; } + if (checkBothExternal(GeoId1, GeoId2)) + return; + const Part::Geometry *geo1 = Obj->getGeometry(GeoId1); const Part::Geometry *geo2 = Obj->getGeometry(GeoId2); @@ -1235,11 +1284,15 @@ void CmdSketcherConstrainTangent::activated(int iMsg) int GeoId1=Constraint::GeoUndef, VtId1=-1, GeoId2=Constraint::GeoUndef, VtId2=-1; if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge") GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str()); + else if (SubNames[0].size() > 12 && SubNames[0].substr(0,12) == "ExternalEdge") + GeoId1 = -3 - std::atoi(SubNames[0].substr(12,4000).c_str()); else if (SubNames[0].size() > 6 && SubNames[0].substr(0,6) == "Vertex") VtId1 = std::atoi(SubNames[0].substr(6,4000).c_str()); if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge") GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str()); + else if (SubNames[1].size() > 12 && SubNames[1].substr(0,12) == "ExternalEdge") + GeoId2 = -3 - std::atoi(SubNames[1].substr(12,4000).c_str()); else if (SubNames[1].size() > 6 && SubNames[1].substr(0,6) == "Vertex") VtId2 = std::atoi(SubNames[1].substr(6,4000).c_str()); @@ -1247,6 +1300,10 @@ void CmdSketcherConstrainTangent::activated(int iMsg) if (VtId1 >= 0 && VtId2 >= 0) { // tangency at common point Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1); Obj->getGeoVertexIndex(VtId2,GeoId2,PosId2); + + if (checkBothExternal(GeoId1, GeoId2)) + return; + openCommand("add tangent constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d,%d)) ", @@ -1256,14 +1313,19 @@ void CmdSketcherConstrainTangent::activated(int iMsg) getSelection().clearSelection(); return; } - else if ((VtId1 >= 0 && GeoId2 >= 0) || (VtId2 >= 0 && GeoId1 >= 0)) { // VtId1 is a tangency point - if (VtId2 >= 0 && GeoId1 >= 0) { + else if ((VtId1 >= 0 && GeoId2 != Constraint::GeoUndef) || + (VtId2 >= 0 && GeoId1 != Constraint::GeoUndef)) { // VtId1 is a tangency point + if (VtId2 >= 0 && GeoId1 != Constraint::GeoUndef) { VtId1 = VtId2; VtId2 = -1; GeoId2 = GeoId1; GeoId1 = -1; } Obj->getGeoVertexIndex(VtId1,GeoId1,PosId1); + + if (checkBothExternal(GeoId1, GeoId2)) + return; + openCommand("add tangent constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d)) ", @@ -1273,7 +1335,11 @@ void CmdSketcherConstrainTangent::activated(int iMsg) getSelection().clearSelection(); return; } - else if (GeoId1 >= 0 && GeoId2 >= 0) { // simple tangency between GeoId1 and GeoId2 + else if (GeoId1 != Constraint::GeoUndef && GeoId2 != Constraint::GeoUndef) { // simple tangency between GeoId1 and GeoId2 + + if (checkBothExternal(GeoId1, GeoId2)) + return; + openCommand("add tangent constraint"); Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ", @@ -1416,12 +1482,21 @@ void CmdSketcherConstrainAngle::activated(int iMsg) int GeoId1=Constraint::GeoUndef, GeoId2=Constraint::GeoUndef; if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge") GeoId1 = std::atoi(SubNames[0].substr(4,4000).c_str()); + else if (SubNames[0].size() > 12 && SubNames[0].substr(0,12) == "ExternalEdge") + GeoId1 = -3 - std::atoi(SubNames[0].substr(12,4000).c_str()); + if (SubNames.size() == 2) { if (SubNames[1].size() > 4 && SubNames[1].substr(0,4) == "Edge") GeoId2 = std::atoi(SubNames[1].substr(4,4000).c_str()); + else if (SubNames[1].size() > 12 && SubNames[1].substr(0,12) == "ExternalEdge") + GeoId2 = -3 - std::atoi(SubNames[1].substr(12,4000).c_str()); } - if (GeoId2 >= 0) { // line to line angle + if (GeoId2 != Constraint::GeoUndef) { // line to line angle + + if (checkBothExternal(GeoId1, GeoId2)) + return; + const Part::Geometry *geom1 = Obj->getGeometry(GeoId1); const Part::Geometry *geom2 = Obj->getGeometry(GeoId2); if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId() && @@ -1475,7 +1550,13 @@ void CmdSketcherConstrainAngle::activated(int iMsg) getSelection().clearSelection(); return; } - } else if (GeoId1 >= 0) { // line angle + } else if (GeoId1 != Constraint::GeoUndef) { // line angle + if (GeoId1 < 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Cannot add an angle constraint on an external geometry!")); + return; + } + const Part::Geometry *geom = Obj->getGeometry(GeoId1); if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment *lineSeg; From a402ab5320c6d8680ca482094888348ee8db351d Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 27 Dec 2011 14:39:29 +0000 Subject: [PATCH 03/21] + raise exception in TopoShape::getSubShape() if shape is empty or wrong sub-type is given git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5349 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/TopoShape.cpp | 67 ++++++++++++---------- src/Mod/Sketcher/App/SketchObject.cpp | 33 ++++++----- src/Mod/Sketcher/App/SketchObjectPy.xml | 2 +- src/Mod/Sketcher/App/SketchObjectPyImp.cpp | 2 +- 4 files changed, 58 insertions(+), 46 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 0206d8569..dfe43aee7 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -355,7 +355,11 @@ void TopoShape::getFacesFromSubelement(const Data::Segment* element, TopoDS_Shape TopoShape::getSubShape(const char* Type) const { - if (!Type) return TopoDS_Shape(); + if (!Type) + Standard_Failure::Raise("No sub-shape type given"); + if (this->_Shape.IsNull()) + Standard_Failure::Raise("Cannot get sub-shape from empty shape"); + std::string shapetype(Type); if (shapetype.size() > 4 && shapetype.substr(0,4) == "Face") { int index=std::atoi(&shapetype[4]); @@ -376,7 +380,8 @@ TopoDS_Shape TopoShape::getSubShape(const char* Type) const return anIndices.FindKey(index); } - return TopoDS_Shape(); + Standard_Failure::Raise("Not supported sub-shape type"); + return TopoDS_Shape(); // avoid compiler warning } unsigned long TopoShape::countSubShapes(const char* Type) const @@ -1738,27 +1743,27 @@ TopoDS_Shape TopoShape::removeSplitter() const Standard_Failure::Raise("Cannot remove splitter from empty shape"); if (_Shape.ShapeType() == TopAbs_SOLID) { - const TopoDS_Solid& solid = TopoDS::Solid(_Shape); - ModelRefine::FaceUniter uniter(solid); - if (uniter.process()) { - TopoDS_Solid solidMod; - if (!uniter.getSolid(solidMod)) - Standard_Failure::Raise("Getting solid failed"); - return solidMod; - } - else { + const TopoDS_Solid& solid = TopoDS::Solid(_Shape); + ModelRefine::FaceUniter uniter(solid); + if (uniter.process()) { + TopoDS_Solid solidMod; + if (!uniter.getSolid(solidMod)) + Standard_Failure::Raise("Getting solid failed"); + return solidMod; + } + else { Standard_Failure::Raise("Removing splitter failed"); - } + } } else if (_Shape.ShapeType() == TopAbs_SHELL) { - const TopoDS_Shell& shell = TopoDS::Shell(_Shape); - ModelRefine::FaceUniter uniter(shell); - if (uniter.process()) { - return uniter.getShell(); - } - else { + const TopoDS_Shell& shell = TopoDS::Shell(_Shape); + ModelRefine::FaceUniter uniter(shell); + if (uniter.process()) { + return uniter.getShell(); + } + else { Standard_Failure::Raise("Removing splitter failed"); - } + } } else if (_Shape.ShapeType() == TopAbs_COMPOUND) { BRep_Builder builder; @@ -1768,21 +1773,21 @@ TopoDS_Shape TopoShape::removeSplitter() const TopExp_Explorer xp; // solids for (xp.Init(_Shape, TopAbs_SOLID); xp.More(); xp.Next()) { - const TopoDS_Solid& solid = TopoDS::Solid(xp.Current()); - ModelRefine::FaceUniter uniter(solid); - if (uniter.process()) { - TopoDS_Solid solidMod; - if (uniter.getSolid(solidMod)) - builder.Add(comp, solidMod); - } + const TopoDS_Solid& solid = TopoDS::Solid(xp.Current()); + ModelRefine::FaceUniter uniter(solid); + if (uniter.process()) { + TopoDS_Solid solidMod; + if (uniter.getSolid(solidMod)) + builder.Add(comp, solidMod); + } } // free shells for (xp.Init(_Shape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next()) { - const TopoDS_Shell& shell = TopoDS::Shell(xp.Current()); - ModelRefine::FaceUniter uniter(shell); - if (uniter.process()) { - builder.Add(comp, uniter.getShell()); - } + const TopoDS_Shell& shell = TopoDS::Shell(xp.Current()); + ModelRefine::FaceUniter uniter(shell); + if (uniter.process()) { + builder.Add(comp, uniter.getShell()); + } } // the rest for (xp.Init(_Shape, TopAbs_FACE, TopAbs_SHELL); xp.More(); xp.Next()) { diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 904b8b063..4d7dce5af 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -92,7 +92,7 @@ App::DocumentObjectExecReturn *SketchObject::execute(void) // setup and diagnose the sketch rebuildExternalGeometry(); Sketch sketch; - int dofs = sketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), + int dofs = sketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), true, getExternalGeometryCount()); if (dofs < 0) { // over-constrained sketch std::string msg="Over-constrained sketch\n"; @@ -123,7 +123,7 @@ int SketchObject::hasConflicts(void) const { // set up a sketch (including dofs counting and diagnosing of conflicts) Sketch sketch; - int dofs = sketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), + int dofs = sketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), true, getExternalGeometryCount()); if (dofs < 0) // over-constrained sketch return -2; @@ -161,7 +161,7 @@ int SketchObject::setDatum(int ConstrId, double Datum) // set up a sketch (including dofs counting and diagnosing of conflicts) Sketch sketch; - int dofs = sketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), + int dofs = sketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), true, getExternalGeometryCount()); int err=0; if (dofs < 0) // over-constrained sketch @@ -187,7 +187,7 @@ int SketchObject::setDatum(int ConstrId, double Datum) int SketchObject::movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative) { Sketch sketch; - int dofs = sketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), + int dofs = sketch.setUpSketch(getCompleteGeometry(), Constraints.getValues(), true, getExternalGeometryCount()); if (dofs < 0) // over-constrained sketch return -1; @@ -668,7 +668,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none; ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject; - for (std::vector::const_iterator it=constraints.begin(); + for (std::vector::const_iterator it=constraints.begin(); it != constraints.end(); ++it) { Constraint *constr = *(it); if (secondPos1 == Sketcher::none && (constr->First == GeoId1 && constr->Second == GeoId)) { @@ -691,7 +691,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) newConstr->SecondPos = secondPos1; delConstraintOnPoint(GeoId1, secondPos1, false); } - + addConstraint(newConstr); // Reset the second pos @@ -737,7 +737,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) ConstraintType constrType = Sketcher::PointOnObject; PointPos secondPos = Sketcher::none; - for (std::vector::const_iterator it=constraints.begin(); + for (std::vector::const_iterator it=constraints.begin(); it != constraints.end(); ++it) { Constraint *constr = *(it); if ((constr->First == GeoId1 && constr->Second == GeoId)) { @@ -818,7 +818,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none; ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject; - for (std::vector::const_iterator it=constraints.begin(); + for (std::vector::const_iterator it=constraints.begin(); it != constraints.end(); ++it) { Constraint *constr = *(it); if (secondPos1 == Sketcher::none && (constr->First == GeoId1 && constr->Second == GeoId)) { @@ -904,7 +904,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none; ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject; - for (std::vector::const_iterator it=constraints.begin(); + for (std::vector::const_iterator it=constraints.begin(); it != constraints.end(); ++it) { Constraint *constr = *(it); if (secondPos1 == Sketcher::none && @@ -970,7 +970,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) ConstraintType constrType = Sketcher::PointOnObject; PointPos secondPos = Sketcher::none; - for (std::vector::const_iterator it=constraints.begin(); + for (std::vector::const_iterator it=constraints.begin(); it != constraints.end(); ++it) { Constraint *constr = *(it); if ((constr->First == GeoId1 && constr->Second == GeoId)) { @@ -1013,7 +1013,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) if (constrType == Sketcher::Coincident) newConstr->SecondPos = secondPos; - + addConstraint(newConstr); delete newConstr; return 0; @@ -1065,7 +1065,7 @@ int SketchObject::delExternal(int ExtGeoId) return 0; } - + const Part::Geometry* SketchObject::getGeometry(int GeoId) const { if (GeoId >= 0) { @@ -1122,7 +1122,14 @@ void SketchObject::rebuildExternalGeometry(void) const Part::Feature *refObj=static_cast(Obj); const Part::TopoShape& refShape=refObj->Shape.getShape(); - TopoDS_Shape refSubShape=refShape.getSubShape(SubElement.c_str()); + TopoDS_Shape refSubShape; + try { + refSubShape = refShape.getSubShape(SubElement.c_str()); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Base::Exception(e->GetMessageString()); + } switch (refSubShape.ShapeType()) { diff --git a/src/Mod/Sketcher/App/SketchObjectPy.xml b/src/Mod/Sketcher/App/SketchObjectPy.xml index e4eae9a3d..e5b93b44e 100644 --- a/src/Mod/Sketcher/App/SketchObjectPy.xml +++ b/src/Mod/Sketcher/App/SketchObjectPy.xml @@ -45,7 +45,7 @@ - add a link to a external geometry to use them in a constraint + add a link to an external geometry to use it in a constraint diff --git a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp index c57e6865c..d7ecedd90 100644 --- a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp +++ b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp @@ -143,7 +143,7 @@ PyObject* SketchObjectPy::addExternal(PyObject *args) PyErr_SetString(PyExc_ValueError, str.str().c_str()); return 0; } - // check if its belong to the sketch support + // check if it belongs to the sketch support if (this->getSketchObjectPtr()->Support.getValue() != Obj) { std::stringstream str; str << ObjectName << "is not supported by this sketch"; From 7a7be8e2d41cd7220755f83bdd8b15f8676d8bdf Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 28 Dec 2011 10:17:16 +0000 Subject: [PATCH 04/21] + updated refinement algorithm (tanderson69) git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5350 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/modelRefine.cpp | 102 +++++++++++++------------------ src/Mod/Part/App/modelRefine.h | 13 ++-- 2 files changed, 48 insertions(+), 67 deletions(-) diff --git a/src/Mod/Part/App/modelRefine.cpp b/src/Mod/Part/App/modelRefine.cpp index 0fa258ef7..9f65ffc88 100644 --- a/src/Mod/Part/App/modelRefine.cpp +++ b/src/Mod/Part/App/modelRefine.cpp @@ -201,18 +201,38 @@ const FaceVectorType& FaceTypeSplitter::getTypedFaceVector(const GeomAbs_Surface ///////////////////////////////////////////////////////////////////////////////////////////////////////// +FaceAdjacencySplitter::FaceAdjacencySplitter(const TopoDS_Shell &shell) +{ + TopExp_Explorer shellIt; + for (shellIt.Init(shell, TopAbs_FACE); shellIt.More(); shellIt.Next()) + { + TopTools_ListOfShape shapeList; + TopExp_Explorer it; + for (it.Init(shellIt.Current(), TopAbs_EDGE); it.More(); it.Next()) + shapeList.Append(it.Current()); + faceToEdgeMap.Add(shellIt.Current(), shapeList); + } + TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, TopAbs_FACE, edgeToFaceMap); +} + + void FaceAdjacencySplitter::split(const FaceVectorType &facesIn) { + facesInMap.Clear(); + processedMap.Clear(); + adjacencyArray.clear(); + + FaceVectorType::const_iterator it; + for (it = facesIn.begin(); it != facesIn.end(); ++it) + facesInMap.Add(*it); //the reserve call guarantees the vector will never get "pushed back" in the //recursiveFind calls, thus invalidating the iterators. We can be sure of this as any one //matched set can't be bigger than the set passed in. if we have seg faults, we will //want to turn this tempFaces vector back into a std::list ensuring valid iterators //at the expense of std::find speed. - buildMap(facesIn); FaceVectorType tempFaces; tempFaces.reserve(facesIn.size() + 1); - FaceVectorType::const_iterator it; for (it = facesIn.begin(); it != facesIn.end(); ++it) { //skip already processed shapes. @@ -220,9 +240,8 @@ void FaceAdjacencySplitter::split(const FaceVectorType &facesIn) continue; tempFaces.clear(); - tempFaces.push_back(*it); processedMap.Add(*it); - recursiveFind(tempFaces, facesIn); + recursiveFind(*it, tempFaces); if (tempFaces.size() > 1) { adjacencyArray.push_back(tempFaces); @@ -230,70 +249,28 @@ void FaceAdjacencySplitter::split(const FaceVectorType &facesIn) } } -void FaceAdjacencySplitter::recursiveFind(FaceVectorType &tempFaces, const FaceVectorType &facesIn) +void FaceAdjacencySplitter::recursiveFind(const TopoDS_Face &face, FaceVectorType &outVector) { - FaceVectorType::iterator tempIt; - FaceVectorType::const_iterator faceIt; + outVector.push_back(face); - for (tempIt = tempFaces.begin(); tempIt != tempFaces.end(); ++tempIt) + const TopTools_ListOfShape &edges = faceToEdgeMap.FindFromKey(face); + TopTools_ListIteratorOfListOfShape edgeIt; + for (edgeIt.Initialize(edges); edgeIt.More(); edgeIt.Next()) { - for(faceIt = facesIn.begin(); faceIt != facesIn.end(); ++faceIt) + const TopTools_ListOfShape &faces = edgeToFaceMap.FindFromKey(edgeIt.Value()); + TopTools_ListIteratorOfListOfShape faceIt; + for (faceIt.Initialize(faces); faceIt.More(); faceIt.Next()) { - if ((*tempIt).IsSame(*faceIt)) + if (!facesInMap.Contains(faceIt.Value())) continue; - if (processedMap.Contains(*faceIt)) + if (processedMap.Contains(faceIt.Value())) continue; - if (adjacentTest(*tempIt, *faceIt)) - { - tempFaces.push_back(*faceIt); - processedMap.Add(*faceIt); - recursiveFind(tempFaces, facesIn); - } + processedMap.Add(faceIt.Value()); + recursiveFind(TopoDS::Face(faceIt.Value()), outVector); } } } -bool FaceAdjacencySplitter::hasBeenMapped(const TopoDS_Face &shape) -{ - for (std::vector::iterator it(adjacencyArray.begin()); it != adjacencyArray.end(); ++it) - { - if (std::find((*it).begin(), (*it).end(), shape) != (*it).end()) - return true; - } - return false; -} - -void FaceAdjacencySplitter::buildMap(const FaceVectorType &facesIn) -{ - FaceVectorType::const_iterator vit; - for (vit = facesIn.begin(); vit != facesIn.end(); ++vit) - { - TopTools_ListOfShape shapeList; - TopExp_Explorer it; - for (it.Init(*vit, TopAbs_EDGE); it.More(); it.Next()) - shapeList.Append(it.Current()); - faceEdgeMap.Bind((*vit), shapeList); - } -} - -bool FaceAdjacencySplitter::adjacentTest(const TopoDS_Face &faceOne, const TopoDS_Face &faceTwo) -{ - const TopTools_ListOfShape &faceOneEdges = faceEdgeMap.Find(faceOne); - const TopTools_ListOfShape &faceTwoEdges = faceEdgeMap.Find(faceTwo); - TopTools_ListIteratorOfListOfShape itOne, itTwo; - - for (itOne.Initialize(faceOneEdges); itOne.More(); itOne.Next()) - { - for (itTwo.Initialize(faceTwoEdges); itTwo.More(); itTwo.Next()) - { - if ((itOne.Value()).IsSame(itTwo.Value())) - return true; - } - } - - return false; -} - ////////////////////////////////////////////////////////////////////////////////////////////////////// void FaceEqualitySplitter::split(const FaceVectorType &faces, FaceTypedBase *object) @@ -406,8 +383,7 @@ TopoDS_Face FaceTypedPlane::buildFace(const FaceVectorType &faces) const current = faceFix.Face(); } - BRepLib_FuseEdges edgeFuse(current, Standard_True); - return TopoDS::Face(edgeFuse.Shape()); + return current; } FaceTypedPlane& ModelRefine::getPlaneObject() @@ -489,6 +465,8 @@ bool FaceUniter::process() ModelRefine::FaceVectorType facesToRemove; ModelRefine::FaceVectorType facesToSew; + ModelRefine::FaceAdjacencySplitter adjacencySplitter(workShell); + for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt) { ModelRefine::FaceVectorType typedFaces = splitter.getTypedFaceVector((*typeIt)->getType()); @@ -496,7 +474,6 @@ bool FaceUniter::process() equalitySplitter.split(typedFaces, *typeIt); for (std::size_t indexEquality(0); indexEquality < equalitySplitter.getGroupCount(); ++indexEquality) { - ModelRefine::FaceAdjacencySplitter adjacencySplitter; adjacencySplitter.split(equalitySplitter.getGroup(indexEquality)); // std::cout << " adjacency group count: " << adjacencySplitter.getGroupCount() << std::endl; for (std::size_t adjacentIndex(0); adjacentIndex < adjacencySplitter.getGroupCount(); ++adjacentIndex) @@ -544,6 +521,9 @@ bool FaceUniter::process() for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt) builder.Add(workShell, *sewIt); } + + BRepLib_FuseEdges edgeFuse(workShell, Standard_True); + workShell = TopoDS::Shell(edgeFuse.Shape()); } return true; } diff --git a/src/Mod/Part/App/modelRefine.h b/src/Mod/Part/App/modelRefine.h index 08a146294..1f51b8ded 100644 --- a/src/Mod/Part/App/modelRefine.h +++ b/src/Mod/Part/App/modelRefine.h @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -105,20 +106,20 @@ namespace ModelRefine class FaceAdjacencySplitter { public: - FaceAdjacencySplitter(){} + FaceAdjacencySplitter(const TopoDS_Shell &shell); void split(const FaceVectorType &facesIn); int getGroupCount() const {return adjacencyArray.size();} const FaceVectorType& getGroup(const std::size_t &index) const {return adjacencyArray[index];} private: - bool hasBeenMapped(const TopoDS_Face &shape); - void recursiveFind(FaceVectorType &tempSet, const FaceVectorType &facesIn); - void buildMap(const FaceVectorType &facesIn); - bool adjacentTest(const TopoDS_Face &faceOne, const TopoDS_Face &faceTwo); + FaceAdjacencySplitter(){} + void recursiveFind(const TopoDS_Face &face, FaceVectorType &outVector); std::vector adjacencyArray; - TopTools_DataMapOfShapeListOfShape faceEdgeMap; TopTools_MapOfShape processedMap; + TopTools_MapOfShape facesInMap; + TopTools_IndexedDataMapOfShapeListOfShape faceToEdgeMap; + TopTools_IndexedDataMapOfShapeListOfShape edgeToFaceMap; }; class FaceEqualitySplitter From 5aebda6e2c63ec9af29b2b7cb7e69fee3045b6b9 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 28 Dec 2011 10:45:17 +0000 Subject: [PATCH 05/21] + allow negative values in revolve task panel git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5351 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui index e7a062aa7..a80c300fe 100644 --- a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.ui @@ -53,6 +53,9 @@ 1 + + -360.000000000000000 + 360.000000000000000 From 93665fa95a29195a6893cb40c39d01398e0b9fda Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 28 Dec 2011 13:19:26 +0000 Subject: [PATCH 06/21] + restore external constraints after project load git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5352 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/App/Document.cpp | 4 +++- src/App/DocumentObject.h | 2 ++ src/Mod/Sketcher/App/SketchObject.cpp | 11 ++++++++++- src/Mod/Sketcher/App/SketchObject.h | 1 + src/Mod/Sketcher/App/SketchObjectSF.cpp | 2 +- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 9c9399ccb..d70734bfa 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -987,8 +987,10 @@ void Document::restore (void) reader.readFiles(zipstream); // reset all touched - for (std::map::iterator It= d->objectMap.begin();It!=d->objectMap.end();++It) + for (std::map::iterator It= d->objectMap.begin();It!=d->objectMap.end();++It) { + It->second->onDocumentRestored(); It->second->purgeTouched(); + } GetApplication().signalRestoreDocument(*this); } diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index 9658d6527..48c3f6751 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -179,6 +179,8 @@ protected: virtual void onBeforeChange(const Property* prop); /// get called by the container when a property was changed virtual void onChanged(const Property* prop); + /// get called after a document has been fully restored + virtual void onDocumentRestored() {} /// python object of this class and all descendend protected: // attributes diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 4d7dce5af..0fc4f76bd 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -1300,7 +1300,6 @@ void SketchObject::Restore(XMLReader &reader) { // read the father classes Part::Part2DObject::Restore(reader); - rebuildExternalGeometry(); Constraints.acceptGeometry(getCompleteGeometry()); rebuildVertexIndex(); } @@ -1312,6 +1311,16 @@ void SketchObject::onChanged(const App::Property* prop) Part::Part2DObject::onChanged(prop); } +void SketchObject::onDocumentRestored() +{ + try { + rebuildExternalGeometry(); + Constraints.acceptGeometry(getCompleteGeometry()); + } + catch (...) { + } +} + void SketchObject::getGeoVertexIndex(int VertexId, int &GeoId, PointPos &PosId) { if (VertexId < 0 || VertexId >= (int)VertexId2GeoId.size()) { diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index e3ae6b800..84f2dd0c7 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -148,6 +148,7 @@ public: protected: /// get called by the container when a property has changed virtual void onChanged(const App::Property* /*prop*/); + virtual void onDocumentRestored(); private: std::vector ExternalGeo; diff --git a/src/Mod/Sketcher/App/SketchObjectSF.cpp b/src/Mod/Sketcher/App/SketchObjectSF.cpp index 2f82b4cc3..a0adf0bc1 100644 --- a/src/Mod/Sketcher/App/SketchObjectSF.cpp +++ b/src/Mod/Sketcher/App/SketchObjectSF.cpp @@ -52,7 +52,7 @@ short SketchObjectSF::mustExecute() const App::DocumentObjectExecReturn *SketchObjectSF::execute(void) { - Base::Console().Warning("%s: This feature is deprecated and will not longer supported in future version of FreeCAD \n",this->getNameInDocument()); + Base::Console().Warning("%s: This feature is deprecated and won't be longer supported in future FreeCAD versions\n",this->getNameInDocument()); // do nothing return App::DocumentObject::StdReturn; } From 0ab5a839032aaefeff766830198f6f03a7b41ec8 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 28 Dec 2011 16:13:43 +0000 Subject: [PATCH 07/21] + support of circle and arcs as external geometries git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5353 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/App/SketchObject.cpp | 74 ++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 0fc4f76bd..9485b8cd3 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -26,12 +26,16 @@ # include # include # include +# include # include # include +# include # include # include # include # include +# include +# include #endif #include @@ -1096,6 +1100,12 @@ void SketchObject::rebuildExternalGeometry(void) Rot.multVec(dX,dX); Base::Placement invPlm = Plm.inverse(); + Base::Matrix4D invMat = invPlm.toMatrix(); + gp_Trsf mov; + mov.SetValues(invMat[0][0],invMat[0][1],invMat[0][2],invMat[0][3], + invMat[1][0],invMat[1][1],invMat[1][2],invMat[1][3], + invMat[2][0],invMat[2][1],invMat[2][2],invMat[2][3], + 0.00001,0.00001); gp_Ax3 sketchAx3(gp_Pnt(Pos.x,Pos.y,Pos.z), gp_Dir(dN.x,dN.y,dN.z), @@ -1103,6 +1113,8 @@ void SketchObject::rebuildExternalGeometry(void) gp_Pln sketchPlane(sketchAx3); Handle(Geom_Plane) gPlane = new Geom_Plane(sketchPlane); + BRepBuilderAPI_MakeFace mkFace(sketchPlane); + TopoDS_Shape aProjFace = mkFace.Shape(); for (std::vector::iterator it=ExternalGeo.begin(); it != ExternalGeo.end(); ++it) if (*it) delete *it; @@ -1172,7 +1184,67 @@ void SketchObject::rebuildExternalGeometry(void) ExternalGeo.push_back(line); } else { - throw Base::Exception("Not yet supported geometry for external geometry"); + try { + BRepOffsetAPI_NormalProjection mkProj(aProjFace); + mkProj.Add(edge); + mkProj.Build(); + const TopoDS_Shape& projShape = mkProj.Projection(); + if (!projShape.IsNull()) { + TopExp_Explorer xp; + for (xp.Init(projShape, TopAbs_EDGE); xp.More(); xp.Next()) { + TopoDS_Edge edge = TopoDS::Edge(xp.Current()); + TopLoc_Location loc(mov); + edge.Location(loc); + BRepAdaptor_Curve curve(edge); + if (curve.GetType() == GeomAbs_Line) { + gp_Pnt P1 = curve.Value(curve.FirstParameter()); + gp_Pnt P2 = curve.Value(curve.LastParameter()); + Base::Vector3d p1(P1.X(),P1.Y(),P1.Z()); + Base::Vector3d p2(P2.X(),P2.Y(),P2.Z()); + + if (Base::Distance(p1,p2) < Precision::Confusion()) { + std::string msg = SubElement + " perpendicular to the sketch plane cannot be used as external geometry"; + throw Base::Exception(msg.c_str()); + } + + Part::GeomLineSegment* line = new Part::GeomLineSegment(); + line->setPoints(p1,p2); + + line->Construction = true; + ExternalGeo.push_back(line); + } + else if (curve.GetType() == GeomAbs_Circle) { + gp_Circ c = curve.Circle(); + gp_Pnt p = c.Location(); + gp_Pnt P1 = curve.Value(curve.FirstParameter()); + gp_Pnt P2 = curve.Value(curve.LastParameter()); + + if (P1.SquareDistance(P2) < Precision::Confusion()) { + Part::GeomCircle* circle = new Part::GeomCircle(); + circle->setRadius(c.Radius()); + circle->setCenter(Base::Vector3d(p.X(),p.Y(),p.Z())); + + circle->Construction = true; + ExternalGeo.push_back(circle); + } + else { + Part::GeomArcOfCircle* arc = new Part::GeomArcOfCircle(); + arc->setRadius(c.Radius()); + arc->setCenter(Base::Vector3d(p.X(),p.Y(),p.Z())); + arc->setRange(curve.FirstParameter(), curve.LastParameter()); + + arc->Construction = true; + ExternalGeo.push_back(arc); + } + } + else { + throw Base::Exception("Not yet supported geometry for external geometry"); + } + } + } + } + catch (...) { + } } } break; From 3e939999c4fed33ecd5275e6b7304f31d5b4c888 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 29 Dec 2011 10:06:28 +0000 Subject: [PATCH 08/21] + convert OCC exception to FreeCAD exception git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5354 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/App/SketchObject.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 9485b8cd3..c48ebb78e 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -1243,7 +1243,9 @@ void SketchObject::rebuildExternalGeometry(void) } } } - catch (...) { + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Base::Exception(e->GetMessageString()); } } } @@ -1256,7 +1258,6 @@ void SketchObject::rebuildExternalGeometry(void) break; } } - } std::vector SketchObject::getCompleteGeometry(void) const From b755192047427d12d98eb89373b5e8f082315fee Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 29 Dec 2011 10:31:21 +0000 Subject: [PATCH 09/21] + disallow duplicates of external constraints git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5355 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/App/SketchObject.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index c48ebb78e..1bde4c70f 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -1042,6 +1042,13 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName) std::vector originalObjects = Objects; std::vector originalSubElements = SubElements; + std::vector ::iterator it; + it = std::find(originalSubElements.begin(), originalSubElements.end(), SubName); + + // avoid duplicates + if (it != originalSubElements.end()) + return -1; + // add the new ones Objects.push_back(Obj); SubElements.push_back(std::string(SubName)); From 0b0f55e8f8875359be2d1ec169969bcf7d3121b9 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 29 Dec 2011 11:20:49 +0000 Subject: [PATCH 10/21] + fix problems with call tips window if text after dot is not a word + fix problems with history in python console git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5356 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Gui/CallTips.cpp | 7 +++++++ src/Gui/PythonConsole.cpp | 14 +++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Gui/CallTips.cpp b/src/Gui/CallTips.cpp index 25a3ccc11..72aa941c1 100644 --- a/src/Gui/CallTips.cpp +++ b/src/Gui/CallTips.cpp @@ -156,6 +156,13 @@ void CallTipsList::validateCursor() cursor.setPosition(this->cursorPos); cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); QString word = cursor.selectedText(); + if (!word.isEmpty()) { + // the following text might be an operator, brackets, ... + const QChar underscore = QLatin1Char('_'); + const QChar ch = word.at(0); + if (!ch.isLetterOrNumber() && ch != underscore) + word.clear(); + } if (currentPos > this->cursorPos+word.length()) { hide(); } diff --git a/src/Gui/PythonConsole.cpp b/src/Gui/PythonConsole.cpp index a9ce79959..cc4f66ffb 100644 --- a/src/Gui/PythonConsole.cpp +++ b/src/Gui/PythonConsole.cpp @@ -548,8 +548,20 @@ void PythonConsole::keyPressEvent(QKeyEvent * e) restartHistory = false; } break; - case Qt::Key_Backspace: case Qt::Key_Left: + { + if (cursor > inputLineBegin) + { TextEdit::keyPressEvent(e); } + restartHistory = false; + } break; + + case Qt::Key_Right: + { + TextEdit::keyPressEvent(e); + restartHistory = false; + } break; + + case Qt::Key_Backspace: { if (cursor > inputLineBegin) { TextEdit::keyPressEvent(e); } From 5eaf2226abe6b15a5fb954709243cceb3a86f62e Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 29 Dec 2011 12:31:49 +0000 Subject: [PATCH 11/21] 0000521: Part Design: Pad from sketch on a face - reversed option greyed out in Taskview git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5357 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/PartDesign/Gui/TaskPadParameters.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp index 15372ad85..8a902b2b9 100644 --- a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp @@ -75,19 +75,10 @@ TaskPadParameters::TaskPadParameters(ViewProviderPad *PadView,QWidget *parent) ui->doubleSpinBox->setValue(l); ui->doubleSpinBox->selectAll(); ui->checkBoxMirrored->setChecked(mirrored); - - // check if the sketch has support - Sketcher::SketchObject *pcSketch; - if (pcPad->Sketch.getValue()) { - pcSketch = static_cast(pcPad->Sketch.getValue()); - if (pcSketch->Support.getValue()) - // in case of sketch with support, reverse makes no sense (goes into the part) - ui->checkBoxReversed->setEnabled(0); - else - ui->checkBoxReversed->setChecked(reversed); - } - + // According to bug #0000521 the reversed option + // shouldn't be de-activated if the pad has a support face ui->checkBoxReversed->setChecked(reversed); + // Make sure that the spin box has the focus to get key events // Calling setFocus() directly doesn't work because the spin box is not // yet visible. From fe0767a4b46e67d2d01e37b4396c020700c2d7b3 Mon Sep 17 00:00:00 2001 From: logari81 Date: Thu, 29 Dec 2011 16:25:40 +0000 Subject: [PATCH 12/21] 0000554 : Sketcher: adding angle constraint on a single line crashes FreeCAD git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5358 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 0d208a1cb..d530b08f8 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -2207,7 +2207,8 @@ Restart: case Angle: { assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount); - assert(Constr->Second >= -extGeoCount && Constr->Second < intGeoCount); + assert((Constr->Second >= -extGeoCount && Constr->Second < intGeoCount) || + Constr->Second == Constraint::GeoUndef); SbVec3f p0; double startangle,range,endangle; From 60ba9cf5db1ba10a4270a70dd2ea65a35cbb91c8 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 29 Dec 2011 18:20:59 +0000 Subject: [PATCH 13/21] 0000542: request for 'Draft Angle' option for extrusion git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5359 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/CMakeLists.txt | 1 + src/Mod/Part/App/FeatureExtrusion.cpp | 85 +++++++++++++++++++++++++-- src/Mod/Part/App/FeatureExtrusion.h | 3 + src/Mod/Part/Gui/DlgExtrusion.cpp | 8 ++- src/Mod/Part/Gui/DlgExtrusion.h | 2 +- src/Mod/Part/Gui/DlgExtrusion.ui | 31 ++++++++++ 6 files changed, 122 insertions(+), 8 deletions(-) diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index d24476215..39d4b18ab 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -119,6 +119,7 @@ SOURCE_GROUP("Features" FILES ${Features_SRCS}) IF(MSVC) SET_SOURCE_FILES_PROPERTIES(FeatureFillet.cpp PROPERTIES COMPILE_FLAGS "/EHa") SET_SOURCE_FILES_PROPERTIES(FeaturePartBoolean.cpp PROPERTIES COMPILE_FLAGS "/EHa") +SET_SOURCE_FILES_PROPERTIES(FeatureExtrusion.cpp PROPERTIES COMPILE_FLAGS "/EHa") ENDIF(MSVC) SET(Properties_SRCS diff --git a/src/Mod/Part/App/FeatureExtrusion.cpp b/src/Mod/Part/App/FeatureExtrusion.cpp index 6633d2e39..e110eb9c6 100644 --- a/src/Mod/Part/App/FeatureExtrusion.cpp +++ b/src/Mod/Part/App/FeatureExtrusion.cpp @@ -23,10 +23,23 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include #endif #include "FeatureExtrusion.h" +#include +#include using namespace Part; @@ -38,12 +51,16 @@ Extrusion::Extrusion() { ADD_PROPERTY(Base,(0)); ADD_PROPERTY(Dir,(Base::Vector3f(0.0f,0.0f,1.0f))); + ADD_PROPERTY(Solid,(false)); + ADD_PROPERTY(TaperAngle,(0.0f)); } short Extrusion::mustExecute() const { if (Base.isTouched() || - Dir.isTouched() ) + Dir.isTouched() || + Solid.isTouched() || + TaperAngle.isTouched()) return 1; return 0; } @@ -59,13 +76,69 @@ App::DocumentObjectExecReturn *Extrusion::execute(void) Base::Vector3f v = Dir.getValue(); gp_Vec vec(v.x,v.y,v.z); + float taperAngle = TaperAngle.getValue(); + bool makeSolid = Solid.getValue(); try { - // Now, let's get the TopoDS_Shape - TopoDS_Shape swept = base->Shape.getShape().makePrism(vec); - if (swept.IsNull()) - return new App::DocumentObjectExecReturn("Resulting shape is null"); - this->Shape.setValue(swept); + if (std::fabs(taperAngle) >= Precision::Confusion()) { +#if defined(__GNUC__) && defined (FC_OS_LINUX) + Base::SignalException se; +#endif + double distance = std::tan(Base::toRadians(taperAngle)) * vec.Magnitude(); + const TopoDS_Shape& shape = base->Shape.getValue(); + bool isWire = (shape.ShapeType() == TopAbs_WIRE); + if (!isWire) + return new App::DocumentObjectExecReturn("Only wires supported"); + + std::list wire_list; + BRepOffsetAPI_MakeOffset mkOffset; +#if 1 //OCC_HEX_VERSION < 0x060502 + // The input wire may have erorrs in its topology + // and thus may cause a crash in the Perfrom() method + // See also: + // http://www.opencascade.org/org/forum/thread_17640/ + // http://www.opencascade.org/org/forum/thread_12012/ + ShapeFix_Wire aFix; + aFix.Load(TopoDS::Wire(shape)); + aFix.FixReorder(); + aFix.FixConnected(); + aFix.FixClosed(); + mkOffset.AddWire(aFix.Wire()); + wire_list.push_back(aFix.Wire()); +#else + mkOffset.AddWire(TopoDS::Wire(shape)); +#endif + mkOffset.Perform(distance); + + gp_Trsf mat; + mat.SetTranslation(vec); + BRepBuilderAPI_Transform mkTransform(mkOffset.Shape(),mat); + wire_list.push_back(TopoDS::Wire(mkTransform.Shape())); + + BRepOffsetAPI_ThruSections mkGenerator(makeSolid ? Standard_True : Standard_False, Standard_False); + for (std::list::const_iterator it = wire_list.begin(); it != wire_list.end(); ++it) { + const TopoDS_Wire &wire = *it; + mkGenerator.AddWire(wire); + } + + mkGenerator.Build(); + this->Shape.setValue(mkGenerator.Shape()); + } + else { + // Now, let's get the TopoDS_Shape + TopoDS_Shape myShape = base->Shape.getValue(); + if (myShape.IsNull()) + Standard_Failure::Raise("Cannot extrude empty shape"); + if (makeSolid && myShape.ShapeType() == TopAbs_WIRE) { + BRepBuilderAPI_MakeFace mkFace(TopoDS::Wire(myShape)); + myShape = mkFace.Face(); + } + BRepPrimAPI_MakePrism mkPrism(myShape, vec); + TopoDS_Shape swept = mkPrism.Shape(); + if (swept.IsNull()) + return new App::DocumentObjectExecReturn("Resulting shape is null"); + this->Shape.setValue(swept); + } return App::DocumentObject::StdReturn; } catch (Standard_Failure) { diff --git a/src/Mod/Part/App/FeatureExtrusion.h b/src/Mod/Part/App/FeatureExtrusion.h index c5db68103..6576d0b17 100644 --- a/src/Mod/Part/App/FeatureExtrusion.h +++ b/src/Mod/Part/App/FeatureExtrusion.h @@ -25,6 +25,7 @@ #define PART_FEATUREEXTRUSION_H #include +#include #include "PartFeature.h" namespace Part @@ -39,6 +40,8 @@ public: App::PropertyLink Base; App::PropertyVector Dir; + App::PropertyBool Solid; + App::PropertyAngle TaperAngle; /** @name methods override feature */ //@{ diff --git a/src/Mod/Part/Gui/DlgExtrusion.cpp b/src/Mod/Part/Gui/DlgExtrusion.cpp index 5450f83a9..38e167657 100644 --- a/src/Mod/Part/Gui/DlgExtrusion.cpp +++ b/src/Mod/Part/Gui/DlgExtrusion.cpp @@ -162,6 +162,8 @@ void DlgExtrusion::apply() double dirX = ui->dirX->value(); double dirY = ui->dirY->value(); double dirZ = ui->dirZ->value(); + double angle = ui->taperAngle->value(); + bool makeSolid = ui->makeSolid->isChecked(); // inspect geometry App::DocumentObject* obj = activeDoc->getObject((const char*)shape.toAscii()); @@ -192,12 +194,16 @@ void DlgExtrusion::apply() "FreeCAD.getDocument(\"%1\").addObject(\"%2\",\"%3\")\n" "FreeCAD.getDocument(\"%1\").%3.Base = FreeCAD.getDocument(\"%1\").%4\n" "FreeCAD.getDocument(\"%1\").%3.Dir = (%5,%6,%7)\n" + "FreeCAD.getDocument(\"%1\").%3.Solid = (%8)\n" + "FreeCAD.getDocument(\"%1\").%3.TaperAngle = (%9)\n" "FreeCADGui.getDocument(\"%1\").%4.Visibility = False\n") .arg(QString::fromAscii(this->document.c_str())) .arg(type).arg(name).arg(shape) .arg(dirX*len) .arg(dirY*len) - .arg(dirZ*len); + .arg(dirZ*len) + .arg(makeSolid ? QLatin1String("True") : QLatin1String("False")) + .arg(angle); Gui::Application::Instance->runPythonCode((const char*)code.toAscii()); QByteArray to = name.toAscii(); QByteArray from = shape.toAscii(); diff --git a/src/Mod/Part/Gui/DlgExtrusion.h b/src/Mod/Part/Gui/DlgExtrusion.h index 60d5254bc..deeabe375 100644 --- a/src/Mod/Part/Gui/DlgExtrusion.h +++ b/src/Mod/Part/Gui/DlgExtrusion.h @@ -68,7 +68,7 @@ public: void clicked(int); virtual QDialogButtonBox::StandardButtons getStandardButtons() const - { return QDialogButtonBox::Apply | QDialogButtonBox::Cancel; } + { return QDialogButtonBox::Apply | QDialogButtonBox::Close; } private: DlgExtrusion* widget; diff --git a/src/Mod/Part/Gui/DlgExtrusion.ui b/src/Mod/Part/Gui/DlgExtrusion.ui index 0244152f2..3fad61682 100644 --- a/src/Mod/Part/Gui/DlgExtrusion.ui +++ b/src/Mod/Part/Gui/DlgExtrusion.ui @@ -181,6 +181,37 @@ + + + Create solid + + + + + + + + + Taper outward angle + + + + + + + -180.000000000000000 + + + 180.000000000000000 + + + 5.000000000000000 + + + + + + From bdf43fcaa4ba1a55575369b3813910a12c693aed Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 29 Dec 2011 19:13:16 +0000 Subject: [PATCH 14/21] + support of face for draft angle extrusion git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5360 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/FeatureExtrusion.cpp | 40 +++++++++++++++++---------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/Mod/Part/App/FeatureExtrusion.cpp b/src/Mod/Part/App/FeatureExtrusion.cpp index e110eb9c6..9b9aa70e2 100644 --- a/src/Mod/Part/App/FeatureExtrusion.cpp +++ b/src/Mod/Part/App/FeatureExtrusion.cpp @@ -31,6 +31,7 @@ # include # include # include +# include # include # include # include @@ -87,27 +88,36 @@ App::DocumentObjectExecReturn *Extrusion::execute(void) double distance = std::tan(Base::toRadians(taperAngle)) * vec.Magnitude(); const TopoDS_Shape& shape = base->Shape.getValue(); bool isWire = (shape.ShapeType() == TopAbs_WIRE); - if (!isWire) - return new App::DocumentObjectExecReturn("Only wires supported"); + bool isFace = (shape.ShapeType() == TopAbs_FACE); + if (!isWire && !isFace) + return new App::DocumentObjectExecReturn("Only a wire or a face is supported"); std::list wire_list; BRepOffsetAPI_MakeOffset mkOffset; + if (isWire) { #if 1 //OCC_HEX_VERSION < 0x060502 - // The input wire may have erorrs in its topology - // and thus may cause a crash in the Perfrom() method - // See also: - // http://www.opencascade.org/org/forum/thread_17640/ - // http://www.opencascade.org/org/forum/thread_12012/ - ShapeFix_Wire aFix; - aFix.Load(TopoDS::Wire(shape)); - aFix.FixReorder(); - aFix.FixConnected(); - aFix.FixClosed(); - mkOffset.AddWire(aFix.Wire()); - wire_list.push_back(aFix.Wire()); + // The input wire may have erorrs in its topology + // and thus may cause a crash in the Perfrom() method + // See also: + // http://www.opencascade.org/org/forum/thread_17640/ + // http://www.opencascade.org/org/forum/thread_12012/ + ShapeFix_Wire aFix; + aFix.Load(TopoDS::Wire(shape)); + aFix.FixReorder(); + aFix.FixConnected(); + aFix.FixClosed(); + mkOffset.AddWire(aFix.Wire()); + wire_list.push_back(aFix.Wire()); #else - mkOffset.AddWire(TopoDS::Wire(shape)); + mkOffset.AddWire(TopoDS::Wire(shape)); #endif + } + else if (isFace) { + TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape)); + wire_list.push_back(outerWire); + mkOffset.AddWire(outerWire); + } + mkOffset.Perform(distance); gp_Trsf mat; From c6de527391c116d16511dba7e4a7c30828c3016e Mon Sep 17 00:00:00 2001 From: logari81 Date: Thu, 29 Dec 2011 20:12:57 +0000 Subject: [PATCH 15/21] + fix issue with conflicting constraints in fixed arcs git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5361 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/App/Sketch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index 4f99c7844..35f6bdb64 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -321,7 +321,8 @@ int Sketch::addArc(const Part::GeomArcOfCircle &circleSegment, bool fixed) Geoms.push_back(def); // arcs require an ArcRules constraint for the end points - GCSsys.addConstraintArcRules(a); + if (!fixed) + GCSsys.addConstraintArcRules(a); // return the position of the newly added geometry return Geoms.size()-1; From 00030a71c0c7b42ab6fc70d7095f0500002468d4 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 30 Dec 2011 10:59:54 +0000 Subject: [PATCH 16/21] + updated refinement algorithm (tanderson69) git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5362 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/modelRefine.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Mod/Part/App/modelRefine.cpp b/src/Mod/Part/App/modelRefine.cpp index 9f65ffc88..72b6c6486 100644 --- a/src/Mod/Part/App/modelRefine.cpp +++ b/src/Mod/Part/App/modelRefine.cpp @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #include #include @@ -523,6 +525,14 @@ bool FaceUniter::process() } BRepLib_FuseEdges edgeFuse(workShell, Standard_True); + TopTools_DataMapOfShapeShape affectedFaces; + edgeFuse.Faces(affectedFaces); + TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt; + for (mapIt.Initialize(affectedFaces); mapIt.More(); mapIt.Next()) + { + ShapeFix_Face faceFixer(TopoDS::Face(mapIt.Value())); + faceFixer.Perform(); + } workShell = TopoDS::Shell(edgeFuse.Shape()); } return true; From dfbea1de96d1b6de47eda4606200f0fc7494685f Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 30 Dec 2011 11:45:28 +0000 Subject: [PATCH 17/21] + move vec_traits into its own module git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5363 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Drawing/App/FeatureProjection.cpp | 1 + src/Mod/Drawing/Gui/TaskOrthoViews.cpp | 1 + src/Mod/Part/App/CMakeLists.txt | 1 + src/Mod/Part/App/Makefile.am | 1 + src/Mod/Part/App/Tools.h | 89 ++++++++++++++++++++ src/Mod/Part/App/TopoShape.cpp | 1 + src/Mod/Part/App/TopoShape.h | 43 +--------- src/Mod/Part/App/TopoShapeCompSolidPyImp.cpp | 3 +- src/Mod/Part/App/TopoShapeCompoundPyImp.cpp | 3 +- src/Mod/Part/App/TopoShapeSolidPyImp.cpp | 3 +- src/Mod/Part/Gui/DlgPrimitives.cpp | 16 +--- 11 files changed, 103 insertions(+), 59 deletions(-) create mode 100644 src/Mod/Part/App/Tools.h diff --git a/src/Mod/Drawing/App/FeatureProjection.cpp b/src/Mod/Drawing/App/FeatureProjection.cpp index a0905952c..50a8e088b 100644 --- a/src/Mod/Drawing/App/FeatureProjection.cpp +++ b/src/Mod/Drawing/App/FeatureProjection.cpp @@ -26,6 +26,7 @@ #ifndef _PreComp_ # include # include +# include # include #endif diff --git a/src/Mod/Drawing/Gui/TaskOrthoViews.cpp b/src/Mod/Drawing/Gui/TaskOrthoViews.cpp index 4cb50e288..055244a6a 100644 --- a/src/Mod/Drawing/Gui/TaskOrthoViews.cpp +++ b/src/Mod/Drawing/Gui/TaskOrthoViews.cpp @@ -39,6 +39,7 @@ #include #include #include +#include using namespace Gui; using namespace DrawingGui; diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index 39d4b18ab..40c81da59 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -230,6 +230,7 @@ SET(Part_SRCS edgecluster.h modelRefine.cpp modelRefine.h + Tools.h ) SET(Part_Scripts diff --git a/src/Mod/Part/App/Makefile.am b/src/Mod/Part/App/Makefile.am index 5a9a45605..91c711564 100644 --- a/src/Mod/Part/App/Makefile.am +++ b/src/Mod/Part/App/Makefile.am @@ -189,6 +189,7 @@ include_HEADERS=\ ProgressIndicator.h \ PropertyGeometryList.h \ PropertyTopoShape.h \ + Tools.h \ TopoShape.h diff --git a/src/Mod/Part/App/Tools.h b/src/Mod/Part/App/Tools.h new file mode 100644 index 000000000..b48ab6ab6 --- /dev/null +++ b/src/Mod/Part/App/Tools.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (c) 2011 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef PART_TOOLS_H +#define PART_TOOLS_H + +#include +#include +#include +#include + +namespace Base { +// Specialization for gp_Pnt +template <> +struct vec_traits { + typedef gp_Pnt vec_type; + typedef double float_type; + vec_traits(const vec_type& v) : v(v){} + inline float_type x() { return v.X(); } + inline float_type y() { return v.Y(); } + inline float_type z() { return v.Z(); } +private: + const vec_type& v; +}; +// Specialization for gp_Vec +template <> +struct vec_traits { + typedef gp_Vec vec_type; + typedef double float_type; + vec_traits(const vec_type& v) : v(v){} + inline float_type x() { return v.X(); } + inline float_type y() { return v.Y(); } + inline float_type z() { return v.Z(); } +private: + const vec_type& v; +}; +// Specialization for gp_Dir +template <> +struct vec_traits { + typedef gp_Dir vec_type; + typedef double float_type; + vec_traits(const vec_type& v) : v(v){} + inline float_type x() { return v.X(); } + inline float_type y() { return v.Y(); } + inline float_type z() { return v.Z(); } +private: + const vec_type& v; +}; +// Specialization for gp_XYZ +template <> +struct vec_traits { + typedef gp_XYZ vec_type; + typedef double float_type; + vec_traits(const vec_type& v) : v(v){} + inline float_type x() { return v.X(); } + inline float_type y() { return v.Y(); } + inline float_type z() { return v.Z(); } +private: + const vec_type& v; +}; +} + +namespace Part +{ + +} //namespace Part + + +#endif // PART_TOOLS_H diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index dfe43aee7..f81a04122 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -156,6 +156,7 @@ #include "TopoShapeVertexPy.h" #include "ProgressIndicator.h" #include "modelRefine.h" +#include "Tools.h" using namespace Part; diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index e2855e510..389511d05 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -25,53 +25,14 @@ #define PART_TOPOSHAPE_H #include -#include -#include #include #include #include #include +class gp_Ax1; class gp_Ax2; - -namespace Base { -// Specialization for gp_Pnt -template <> -struct vec_traits { - typedef gp_Pnt vec_type; - typedef double float_type; - vec_traits(const vec_type& v) : v(v){} - inline float_type x() { return v.X(); } - inline float_type y() { return v.Y(); } - inline float_type z() { return v.Z(); } -private: - const vec_type& v; -}; -// Specialization for gp_Vec -template <> -struct vec_traits { - typedef gp_Vec vec_type; - typedef double float_type; - vec_traits(const vec_type& v) : v(v){} - inline float_type x() { return v.X(); } - inline float_type y() { return v.Y(); } - inline float_type z() { return v.Z(); } -private: - const vec_type& v; -}; -// Specialization for gp_Dir -template <> -struct vec_traits { - typedef gp_Dir vec_type; - typedef double float_type; - vec_traits(const vec_type& v) : v(v){} - inline float_type x() { return v.X(); } - inline float_type y() { return v.Y(); } - inline float_type z() { return v.Z(); } -private: - const vec_type& v; -}; -} +class gp_Vec; namespace Part { diff --git a/src/Mod/Part/App/TopoShapeCompSolidPyImp.cpp b/src/Mod/Part/App/TopoShapeCompSolidPyImp.cpp index 438e31da2..c329042c8 100644 --- a/src/Mod/Part/App/TopoShapeCompSolidPyImp.cpp +++ b/src/Mod/Part/App/TopoShapeCompSolidPyImp.cpp @@ -23,9 +23,10 @@ #include "PreCompiled.h" #include +#include #include -#include "Mod/Part/App/TopoShape.h" +#include "TopoShape.h" // inclusion of the generated files (generated out of TopoShapeCompSolidPy.xml) #include "TopoShapeSolidPy.h" diff --git a/src/Mod/Part/App/TopoShapeCompoundPyImp.cpp b/src/Mod/Part/App/TopoShapeCompoundPyImp.cpp index b8e3a0d5e..489abda5e 100644 --- a/src/Mod/Part/App/TopoShapeCompoundPyImp.cpp +++ b/src/Mod/Part/App/TopoShapeCompoundPyImp.cpp @@ -23,8 +23,9 @@ #include "PreCompiled.h" -#include "Mod/Part/App/TopoShape.h" +#include "TopoShape.h" #include +#include #include // inclusion of the generated files (generated out of TopoShapeCompoundPy.xml) diff --git a/src/Mod/Part/App/TopoShapeSolidPyImp.cpp b/src/Mod/Part/App/TopoShapeSolidPyImp.cpp index ca1a952c3..8af8b1300 100644 --- a/src/Mod/Part/App/TopoShapeSolidPyImp.cpp +++ b/src/Mod/Part/App/TopoShapeSolidPyImp.cpp @@ -40,7 +40,8 @@ #include #include -#include "Mod/Part/App/TopoShape.h" +#include "TopoShape.h" +#include "Tools.h" // inclusion of the generated files (generated out of TopoShapeSolidPy.xml) #include "TopoShapeShellPy.h" diff --git a/src/Mod/Part/Gui/DlgPrimitives.cpp b/src/Mod/Part/Gui/DlgPrimitives.cpp index 0092cf756..4ea927906 100644 --- a/src/Mod/Part/Gui/DlgPrimitives.cpp +++ b/src/Mod/Part/Gui/DlgPrimitives.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "DlgPrimitives.h" @@ -143,21 +144,6 @@ DlgPrimitives::~DlgPrimitives() viewer->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback,this); } } - -namespace Base { -// Specialization for gp_XYZ -template <> -struct vec_traits { - typedef gp_XYZ vec_type; - typedef double float_type; - vec_traits(const vec_type& v) : v(v){} - inline float_type x() { return v.X(); } - inline float_type y() { return v.Y(); } - inline float_type z() { return v.Z(); } -private: - const vec_type& v; -}; -} QString DlgPrimitives::toPlacement() const { From db0ad3a49c2ecaf07ce19d80ff2b6d17d145763c Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 30 Dec 2011 14:30:52 +0000 Subject: [PATCH 18/21] + add new custom widget git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5364 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Gui/InputVector.cpp | 171 +++++++++++++++++++++ src/Gui/InputVector.h | 38 +++++ src/Tools/plugins/widget/customwidgets.cpp | 63 ++++++++ src/Tools/plugins/widget/customwidgets.h | 29 ++++ src/Tools/plugins/widget/plugin.cpp | 42 +++++ 5 files changed, 343 insertions(+) diff --git a/src/Gui/InputVector.cpp b/src/Gui/InputVector.cpp index 4d1d2a6e8..25757fdaa 100644 --- a/src/Gui/InputVector.cpp +++ b/src/Gui/InputVector.cpp @@ -28,6 +28,177 @@ using namespace Gui; +LocationWidget::LocationWidget (QWidget * parent) + : QWidget(parent) +{ + box = new QGridLayout(); + + xValue = new QDoubleSpinBox(this); + xValue->setMinimum(-2.14748e+09); + xValue->setMaximum(2.14748e+09); + xLabel = new QLabel(this); + box->addWidget(xLabel, 0, 0, 1, 1); + box->addWidget(xValue, 0, 1, 1, 1); + + yValue = new QDoubleSpinBox(this); + yValue->setMinimum(-2.14748e+09); + yValue->setMaximum(2.14748e+09); + yLabel = new QLabel(this); + box->addWidget(yLabel, 1, 0, 1, 1); + box->addWidget(yValue, 1, 1, 1, 1); + + zValue = new QDoubleSpinBox(this); + zValue->setMinimum(-2.14748e+09); + zValue->setMaximum(2.14748e+09); + zLabel = new QLabel(this); + box->addWidget(zLabel, 2, 0, 1, 1); + box->addWidget(zValue, 2, 1, 1, 1); + + dLabel = new QLabel(this); + dValue = new QComboBox(this); + dValue->setCurrentIndex(-1); + box->addWidget(dLabel, 3, 0, 1, 1); + box->addWidget(dValue, 3, 1, 1, 1); + + QGridLayout* gridLayout = new QGridLayout(this); + gridLayout->addLayout(box, 0, 0, 1, 2); + + retranslateUi(); +} + +LocationWidget::~LocationWidget() +{ +} + +QSize LocationWidget::sizeHint() const +{ + return QSize(150,190); +} + +void LocationWidget::changeEvent(QEvent* e) +{ + if (e->type() == QEvent::LanguageChange) { + this->retranslateUi(); + } + QWidget::changeEvent(e); +} + +void LocationWidget::retranslateUi() +{ + xLabel->setText(QApplication::translate("Gui::LocationWidget", "X:")); + yLabel->setText(QApplication::translate("Gui::LocationWidget", "Y:")); + zLabel->setText(QApplication::translate("Gui::LocationWidget", "Z:")); + dLabel->setText(QApplication::translate("Gui::LocationWidget", "Direction:")); + + if (dValue->count() == 0) { + dValue->insertItems(0, QStringList() + << QApplication::translate("Gui::LocationDialog", "X") + << QApplication::translate("Gui::LocationDialog", "Y") + << QApplication::translate("Gui::LocationDialog", "Z") + << QApplication::translate("Gui::LocationDialog", "User defined...") + ); + + dValue->setCurrentIndex(2); + + // Vector3f declared to use with QVariant see Gui/propertyeditor/PropertyItem.h + dValue->setItemData(0, QVariant::fromValue(Base::Vector3f(1,0,0))); + dValue->setItemData(1, QVariant::fromValue(Base::Vector3f(0,1,0))); + dValue->setItemData(2, QVariant::fromValue(Base::Vector3f(0,0,1))); + } + else { + dValue->setItemText(0, QApplication::translate("Gui::LocationDialog", "X")); + dValue->setItemText(1, QApplication::translate("Gui::LocationDialog", "Y")); + dValue->setItemText(2, QApplication::translate("Gui::LocationDialog", "Z")); + dValue->setItemText(dValue->count()-1, + QApplication::translate("Gui::LocationDialog", "User defined...")); + } +} + +Base::Vector3f LocationWidget::getPosition() const +{ + return Base::Vector3f((float)this->xValue->value(), + (float)this->yValue->value(), + (float)this->zValue->value()); +} + +void LocationWidget::setDirection(const Base::Vector3f& dir) +{ + if (dir.Length() < FLT_EPSILON) { + return; + } + + // check if the user-defined direction is already there + for (int i=0; icount()-1; i++) { + QVariant data = dValue->itemData (i); + if (data.canConvert()) { + const Base::Vector3f val = data.value(); + if (val == dir) { + dValue->setCurrentIndex(i); + return; + } + } + } + + // add a new item before the very last item + QString display = QString::fromAscii("(%1,%2,%3)") + .arg(dir.x) + .arg(dir.y) + .arg(dir.z); + dValue->insertItem(dValue->count()-1, display, + QVariant::fromValue(dir)); + dValue->setCurrentIndex(dValue->count()-2); +} + +Base::Vector3f LocationWidget::getDirection() const +{ + QVariant data = dValue->itemData (this->dValue->currentIndex()); + if (data.canConvert()) { + return data.value(); + } + else { + return Base::Vector3f(0,0,1); + } +} + +Base::Vector3f LocationWidget::getUserDirection(bool* ok) const +{ + Gui::Dialog::Ui_InputVector iv; + QDialog dlg(const_cast(this)); + iv.setupUi(&dlg); + Base::Vector3f dir; + if (dlg.exec()) { + dir.x = (float)iv.vectorX->value(); + dir.y = (float)iv.vectorY->value(); + dir.z = (float)iv.vectorZ->value(); + if (ok) *ok = true; + } + else { + if (ok) *ok = false; + } + + return dir; +} + +void LocationWidget::on_direction_activated(int index) +{ + // last item is selected to define direction by user + if (index+1 == dValue->count()) { + bool ok; + Base::Vector3f dir = this->getUserDirection(&ok); + if (ok) { + if (dir.Length() < FLT_EPSILON) { + QMessageBox::critical(this, LocationDialog::tr("Wrong direction"), + LocationDialog::tr("Direction must not be the null vector")); + return; + } + + setDirection(dir); + } + } +} + +// ---------------------------------------------------------------------------- + LocationDialog::LocationDialog(QWidget* parent, Qt::WFlags fl) : QDialog(parent, fl) { diff --git a/src/Gui/InputVector.h b/src/Gui/InputVector.h index 4508e1986..852ad2394 100644 --- a/src/Gui/InputVector.h +++ b/src/Gui/InputVector.h @@ -30,8 +30,46 @@ #include +class QGridLayout; +class QLabel; +class QDoubleSpinBox; +class QComboBox; + namespace Gui { +class LocationWidget : public QWidget +{ + Q_OBJECT + +public: + LocationWidget (QWidget * parent = 0); + virtual ~LocationWidget(); + QSize sizeHint() const; + + Base::Vector3f getPosition() const; + void setDirection(const Base::Vector3f& dir); + Base::Vector3f getDirection() const; + Base::Vector3f getUserDirection(bool* ok=0) const; + +private Q_SLOTS: + void on_direction_activated(int); + +private: + void changeEvent(QEvent*); + void retranslateUi(); + +private: + QGridLayout *box; + QLabel *xLabel; + QLabel *yLabel; + QLabel *zLabel; + QLabel *dLabel; + QDoubleSpinBox *xValue; + QDoubleSpinBox *yValue; + QDoubleSpinBox *zValue; + QComboBox *dValue; +}; + /** This is the base dialog class that defines the interface for * specifying a direction vector by the user. * @author Werner Mayer diff --git a/src/Tools/plugins/widget/customwidgets.cpp b/src/Tools/plugins/widget/customwidgets.cpp index 321fec30e..d46bd0541 100644 --- a/src/Tools/plugins/widget/customwidgets.cpp +++ b/src/Tools/plugins/widget/customwidgets.cpp @@ -71,6 +71,69 @@ void UrlLabel::setUrl(const QString& u) setToolTip(this->_url); } +LocationWidget::LocationWidget (QWidget * parent) + : QWidget(parent) +{ + box = new QGridLayout(); + + xValue = new QDoubleSpinBox(this); + xValue->setMinimum(-2.14748e+09); + xValue->setMaximum(2.14748e+09); + xLabel = new QLabel(this); + box->addWidget(xLabel, 0, 0, 1, 1); + box->addWidget(xValue, 0, 1, 1, 1); + + yValue = new QDoubleSpinBox(this); + yValue->setMinimum(-2.14748e+09); + yValue->setMaximum(2.14748e+09); + yLabel = new QLabel(this); + box->addWidget(yLabel, 1, 0, 1, 1); + box->addWidget(yValue, 1, 1, 1, 1); + + zValue = new QDoubleSpinBox(this); + zValue->setMinimum(-2.14748e+09); + zValue->setMaximum(2.14748e+09); + zLabel = new QLabel(this); + box->addWidget(zLabel, 2, 0, 1, 1); + box->addWidget(zValue, 2, 1, 1, 1); + + dLabel = new QLabel(this); + dValue = new QComboBox(this); + dValue->setCurrentIndex(-1); + box->addWidget(dLabel, 3, 0, 1, 1); + box->addWidget(dValue, 3, 1, 1, 1); + + QGridLayout* gridLayout = new QGridLayout(this); + gridLayout->addLayout(box, 0, 0, 1, 2); + + retranslateUi(); +} + +LocationWidget::~LocationWidget() +{ +} + +QSize LocationWidget::sizeHint() const +{ + return QSize(150,190); +} + +void LocationWidget::changeEvent(QEvent* e) +{ + if (e->type() == QEvent::LanguageChange) { + this->retranslateUi(); + } + QWidget::changeEvent(e); +} + +void LocationWidget::retranslateUi() +{ + xLabel->setText(QApplication::translate("Gui::LocationWidget", "X:")); + yLabel->setText(QApplication::translate("Gui::LocationWidget", "Y:")); + zLabel->setText(QApplication::translate("Gui::LocationWidget", "Z:")); + dLabel->setText(QApplication::translate("Gui::LocationWidget", "Direction:")); +} + FileChooser::FileChooser( QWidget *parent ) : QWidget( parent ), md( File ), _filter( QString::null ) { diff --git a/src/Tools/plugins/widget/customwidgets.h b/src/Tools/plugins/widget/customwidgets.h index cd22ccadd..2543a119e 100644 --- a/src/Tools/plugins/widget/customwidgets.h +++ b/src/Tools/plugins/widget/customwidgets.h @@ -35,6 +35,8 @@ #include #include #include +#include +#include namespace Gui { @@ -62,6 +64,33 @@ private: QString _url; }; +class LocationWidget : public QWidget +{ + Q_OBJECT + +public: + LocationWidget (QWidget * parent = 0); + virtual ~LocationWidget(); + QSize sizeHint() const; + +public Q_SLOTS: + +private: + void changeEvent(QEvent*); + void retranslateUi(); + +private: + QGridLayout *box; + QLabel *xLabel; + QLabel *yLabel; + QLabel *zLabel; + QLabel *dLabel; + QDoubleSpinBox *xValue; + QDoubleSpinBox *yValue; + QDoubleSpinBox *zValue; + QComboBox *dValue; +}; + /** * There is a bug in QtDesigner of Qt version 4.0, 4.1 and 4.2. If a class declaration * is inside a namespace and it uses the Q_ENUMS macro then QtDesigner doesn't handle diff --git a/src/Tools/plugins/widget/plugin.cpp b/src/Tools/plugins/widget/plugin.cpp index f23c057e6..d0a2aca92 100644 --- a/src/Tools/plugins/widget/plugin.cpp +++ b/src/Tools/plugins/widget/plugin.cpp @@ -108,6 +108,47 @@ public: } }; +class LocationWidgetPlugin : public QDesignerCustomWidgetInterface +{ + Q_INTERFACES(QDesignerCustomWidgetInterface) +public: + LocationWidgetPlugin() + { + } + QWidget *createWidget(QWidget *parent) + { + return new Gui::LocationWidget(parent); + } + QString group() const + { + return QLatin1String("Display Widgets"); + } + QIcon icon() const + { + return QIcon( QPixmap( urllabel_pixmap ) ); + } + QString includeFile() const + { + return QLatin1String("Gui/InputVector.h"); + } + QString toolTip() const + { + return QLatin1String("Location"); + } + QString whatsThis() const + { + return QLatin1String("A widget to define a location."); + } + bool isContainer() const + { + return false; + } + QString name() const + { + return QLatin1String("Gui::LocationWidget"); + } +}; + static const char *filechooser_pixmap[] = { "22 22 8 1", " c Gray100", @@ -1017,6 +1058,7 @@ QList CustomWidgetPlugin::customWidgets () con { QList cw; cw.append(new UrlLabelPlugin); + cw.append(new LocationWidgetPlugin); cw.append(new FileChooserPlugin); cw.append(new AccelLineEditPlugin); cw.append(new CommandIconViewPlugin); From 891421d805f0b09b6fc9805696d63cab72b4ae92 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 30 Dec 2011 17:27:21 +0000 Subject: [PATCH 19/21] + implement primitive dialog as task panel git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5365 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Gui/InputVector.cpp | 11 +- src/Gui/InputVector.h | 3 +- src/Mod/Part/Gui/CMakeLists.txt | 2 + src/Mod/Part/Gui/Command.cpp | 9 +- src/Mod/Part/Gui/DlgPrimitives.cpp | 628 +++++++++++---------- src/Mod/Part/Gui/DlgPrimitives.h | 42 +- src/Mod/Part/Gui/DlgPrimitives.ui | 382 +++---------- src/Mod/Part/Gui/Location.ui | 81 +++ src/Mod/Part/Gui/Makefile.am | 2 + src/Tools/plugins/widget/customwidgets.cpp | 2 +- 10 files changed, 562 insertions(+), 600 deletions(-) create mode 100644 src/Mod/Part/Gui/Location.ui diff --git a/src/Gui/InputVector.cpp b/src/Gui/InputVector.cpp index 25757fdaa..0afec49a8 100644 --- a/src/Gui/InputVector.cpp +++ b/src/Gui/InputVector.cpp @@ -63,6 +63,8 @@ LocationWidget::LocationWidget (QWidget * parent) QGridLayout* gridLayout = new QGridLayout(this); gridLayout->addLayout(box, 0, 0, 1, 2); + connect(dValue, SIGNAL(activated(int)), + this, SLOT(on_direction_activated(int))); retranslateUi(); } @@ -72,7 +74,7 @@ LocationWidget::~LocationWidget() QSize LocationWidget::sizeHint() const { - return QSize(150,190); + return QSize(150,100); } void LocationWidget::changeEvent(QEvent* e) @@ -121,6 +123,13 @@ Base::Vector3f LocationWidget::getPosition() const (float)this->zValue->value()); } +void LocationWidget::setPosition(const Base::Vector3f& v) +{ + this->xValue->setValue(v.x); + this->yValue->setValue(v.y); + this->zValue->setValue(v.z); +} + void LocationWidget::setDirection(const Base::Vector3f& dir) { if (dir.Length() < FLT_EPSILON) { diff --git a/src/Gui/InputVector.h b/src/Gui/InputVector.h index 852ad2394..b5c101251 100644 --- a/src/Gui/InputVector.h +++ b/src/Gui/InputVector.h @@ -37,7 +37,7 @@ class QComboBox; namespace Gui { -class LocationWidget : public QWidget +class GuiExport LocationWidget : public QWidget { Q_OBJECT @@ -47,6 +47,7 @@ public: QSize sizeHint() const; Base::Vector3f getPosition() const; + void setPosition(const Base::Vector3f&); void setDirection(const Base::Vector3f& dir); Base::Vector3f getDirection() const; Base::Vector3f getUserDirection(bool* ok=0) const; diff --git a/src/Mod/Part/Gui/CMakeLists.txt b/src/Mod/Part/Gui/CMakeLists.txt index 0626ca749..38a984c5e 100644 --- a/src/Mod/Part/Gui/CMakeLists.txt +++ b/src/Mod/Part/Gui/CMakeLists.txt @@ -58,6 +58,7 @@ set(PartGui_UIC_SRCS DlgPartImportIges.ui DlgPartImportStep.ui DlgPrimitives.ui + Location.ui DlgRevolution.ui DlgSettings3DViewPart.ui DlgSettingsGeneral.ui @@ -104,6 +105,7 @@ SET(PartGui_SRCS DlgPrimitives.cpp DlgPrimitives.h DlgPrimitives.ui + Location.ui DlgRevolution.cpp DlgRevolution.h DlgRevolution.ui diff --git a/src/Mod/Part/Gui/Command.cpp b/src/Mod/Part/Gui/Command.cpp index e5ccaaac5..f4288f997 100644 --- a/src/Mod/Part/Gui/Command.cpp +++ b/src/Mod/Part/Gui/Command.cpp @@ -208,16 +208,13 @@ CmdPartPrimitives::CmdPartPrimitives() void CmdPartPrimitives::activated(int iMsg) { - static QPointer dlg = 0; - if (!dlg) - dlg = new PartGui::DlgPrimitives(Gui::getMainWindow()); - dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->show(); + PartGui::TaskPrimitives* dlg = new PartGui::TaskPrimitives(); + Gui::Control().showDialog(dlg); } bool CmdPartPrimitives::isActive(void) { - return hasActiveDocument(); + return (hasActiveDocument() && !Gui::Control().activeDialog()); } //=========================================================================== diff --git a/src/Mod/Part/Gui/DlgPrimitives.cpp b/src/Mod/Part/Gui/DlgPrimitives.cpp index 4ea927906..8b5339832 100644 --- a/src/Mod/Part/Gui/DlgPrimitives.cpp +++ b/src/Mod/Part/Gui/DlgPrimitives.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "DlgPrimitives.h" @@ -48,15 +49,13 @@ using namespace PartGui; /* TRANSLATOR PartGui::DlgPrimitives */ -DlgPrimitives::DlgPrimitives(QWidget* parent, Qt::WFlags fl) - : Gui::LocationDialogComp(parent, fl) +DlgPrimitives::DlgPrimitives(QWidget* parent) + : QWidget(parent) { + ui.setupUi(this); Gui::Command::doCommand(Gui::Command::Doc, "from FreeCAD import Base"); Gui::Command::doCommand(Gui::Command::Doc, "import Part,PartGui"); - connect(ui.viewPositionButton, SIGNAL(clicked()), - this, SLOT(on_viewPositionButton_clicked())); - // set limits // // plane @@ -135,6 +134,247 @@ DlgPrimitives::DlgPrimitives(QWidget* parent, Qt::WFlags fl) */ DlgPrimitives::~DlgPrimitives() { +} + +void DlgPrimitives::createPrimitive(const QString& placement) +{ + try { + QString cmd; QString name; + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + QMessageBox::warning(this, tr("Create %1") + .arg(ui.comboBox1->currentText()), tr("No active document")); + return; + } + if (ui.comboBox1->currentIndex() == 0) { // plane + name = QString::fromAscii(doc->getUniqueObjectName("Plane").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Plane\",\"%1\")\n" + "App.ActiveDocument.%1.Length=%2\n" + "App.ActiveDocument.%1.Width=%3\n" + "App.ActiveDocument.%1.Placement=%4\n") + .arg(name) + .arg(ui.planeLength->value(),0,'f',2) + .arg(ui.planeWidth->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 1) { // box + name = QString::fromAscii(doc->getUniqueObjectName("Box").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Box\",\"%1\")\n" + "App.ActiveDocument.%1.Length=%2\n" + "App.ActiveDocument.%1.Width=%3\n" + "App.ActiveDocument.%1.Height=%4\n" + "App.ActiveDocument.%1.Placement=%5\n") + .arg(name) + .arg(ui.boxLength->value(),0,'f',2) + .arg(ui.boxWidth->value(),0,'f',2) + .arg(ui.boxHeight->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 2) { // cylinder + name = QString::fromAscii(doc->getUniqueObjectName("Cylinder").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Cylinder\",\"%1\")\n" + "App.ActiveDocument.%1.Radius=%2\n" + "App.ActiveDocument.%1.Height=%3\n" + "App.ActiveDocument.%1.Angle=%4\n" + "App.ActiveDocument.%1.Placement=%5\n") + .arg(name) + .arg(ui.cylinderRadius->value(),0,'f',2) + .arg(ui.cylinderHeight->value(),0,'f',2) + .arg(ui.cylinderAngle->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 3) { // cone + name = QString::fromAscii(doc->getUniqueObjectName("Cone").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Cone\",\"%1\")\n" + "App.ActiveDocument.%1.Radius1=%2\n" + "App.ActiveDocument.%1.Radius2=%3\n" + "App.ActiveDocument.%1.Height=%4\n" + "App.ActiveDocument.%1.Angle=%5\n" + "App.ActiveDocument.%1.Placement=%6\n") + .arg(name) + .arg(ui.coneRadius1->value(),0,'f',2) + .arg(ui.coneRadius2->value(),0,'f',2) + .arg(ui.coneHeight->value(),0,'f',2) + .arg(ui.coneAngle->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 4) { // sphere + name = QString::fromAscii(doc->getUniqueObjectName("Sphere").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Sphere\",\"%1\")\n" + "App.ActiveDocument.%1.Radius=%2\n" + "App.ActiveDocument.%1.Angle1=%3\n" + "App.ActiveDocument.%1.Angle2=%4\n" + "App.ActiveDocument.%1.Angle3=%5\n" + "App.ActiveDocument.%1.Placement=%6\n") + .arg(name) + .arg(ui.sphereRadius->value(),0,'f',2) + .arg(ui.sphereAngle1->value(),0,'f',2) + .arg(ui.sphereAngle2->value(),0,'f',2) + .arg(ui.sphereAngle3->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 5) { // ellipsoid + name = QString::fromAscii(doc->getUniqueObjectName("Ellipsoid").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Ellipsoid\",\"%1\")\n" + "App.ActiveDocument.%1.Radius1=%2\n" + "App.ActiveDocument.%1.Radius2=%3\n" + "App.ActiveDocument.%1.Angle1=%4\n" + "App.ActiveDocument.%1.Angle2=%5\n" + "App.ActiveDocument.%1.Angle3=%6\n" + "App.ActiveDocument.%1.Placement=%7\n") + .arg(name) + .arg(ui.ellipsoidRadius1->value(),0,'f',2) + .arg(ui.ellipsoidRadius2->value(),0,'f',2) + .arg(ui.ellipsoidAngle1->value(),0,'f',2) + .arg(ui.ellipsoidAngle2->value(),0,'f',2) + .arg(ui.ellipsoidAngle3->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 6) { // torus + name = QString::fromAscii(doc->getUniqueObjectName("Torus").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Torus\",\"%1\")\n" + "App.ActiveDocument.%1.Radius1=%2\n" + "App.ActiveDocument.%1.Radius2=%3\n" + "App.ActiveDocument.%1.Angle1=%4\n" + "App.ActiveDocument.%1.Angle2=%5\n" + "App.ActiveDocument.%1.Angle3=%6\n" + "App.ActiveDocument.%1.Placement=%7\n") + .arg(name) + .arg(ui.torusRadius1->value(),0,'f',2) + .arg(ui.torusRadius2->value(),0,'f',2) + .arg(ui.torusAngle1->value(),0,'f',2) + .arg(ui.torusAngle2->value(),0,'f',2) + .arg(ui.torusAngle3->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 7) { // wedge + name = QString::fromAscii(doc->getUniqueObjectName("Wedge").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Wedge\",\"%1\")\n" + "App.ActiveDocument.%1.Xmin=%2\n" + "App.ActiveDocument.%1.Ymin=%3\n" + "App.ActiveDocument.%1.Zmin=%4\n" + "App.ActiveDocument.%1.X2min=%5\n" + "App.ActiveDocument.%1.Z2min=%6\n" + "App.ActiveDocument.%1.Xmax=%7\n" + "App.ActiveDocument.%1.Ymax=%8\n" + "App.ActiveDocument.%1.Zmax=%9\n" + "App.ActiveDocument.%1.X2max=%10\n" + "App.ActiveDocument.%1.Z2max=%11\n" + "App.ActiveDocument.%1.Placement=%12\n") + .arg(name) + .arg(ui.wedgeXmin->value(),0,'f',2) + .arg(ui.wedgeYmin->value(),0,'f',2) + .arg(ui.wedgeZmin->value(),0,'f',2) + .arg(ui.wedgeX2min->value(),0,'f',2) + .arg(ui.wedgeZ2min->value(),0,'f',2) + .arg(ui.wedgeXmax->value(),0,'f',2) + .arg(ui.wedgeYmax->value(),0,'f',2) + .arg(ui.wedgeZmax->value(),0,'f',2) + .arg(ui.wedgeX2max->value(),0,'f',2) + .arg(ui.wedgeZ2max->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 8) { // helix + name = QString::fromAscii(doc->getUniqueObjectName("Helix").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Helix\",\"%1\")\n" + "App.ActiveDocument.%1.Pitch=%2\n" + "App.ActiveDocument.%1.Height=%3\n" + "App.ActiveDocument.%1.Radius=%4\n" + "App.ActiveDocument.%1.Angle=%5\n" + "App.ActiveDocument.%1.Placement=%6\n") + .arg(name) + .arg(ui.helixPitch->value(),0,'f',2) + .arg(ui.helixHeight->value(),0,'f',2) + .arg(ui.helixRadius->value(),0,'f',2) + .arg(ui.helixAngle->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 9) { // circle + name = QString::fromAscii(doc->getUniqueObjectName("Circle").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Circle\",\"%1\")\n" + "App.ActiveDocument.%1.Radius=%2\n" + "App.ActiveDocument.%1.Angle0=%3\n" + "App.ActiveDocument.%1.Angle1=%4\n" + "App.ActiveDocument.%1.Placement=%5\n") + .arg(name) + .arg(ui.circleRadius->value(),0,'f',2) + .arg(ui.circleAngle0->value(),0,'f',2) + .arg(ui.circleAngle1->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 10) { // vertex + name = QString::fromAscii(doc->getUniqueObjectName("Vertex").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Vertex\",\"%1\")\n" + "App.ActiveDocument.%1.X=%2\n" + "App.ActiveDocument.%1.Y=%3\n" + "App.ActiveDocument.%1.Z=%4\n" + "App.ActiveDocument.%1.Placement=%5\n") + .arg(name) + .arg(ui.vertexX->value(),0,'f',2) + .arg(ui.vertexY->value(),0,'f',2) + .arg(ui.vertexZ->value(),0,'f',2) + .arg(placement); + } + else if (ui.comboBox1->currentIndex() == 11) { // edge + name = QString::fromAscii(doc->getUniqueObjectName("Edge").c_str()); + cmd = QString::fromAscii( + "App.ActiveDocument.addObject(\"Part::Edge\",\"%1\")\n" + "App.ActiveDocument.%1.X1=%2\n" + "App.ActiveDocument.%1.Y1=%3\n" + "App.ActiveDocument.%1.Z1=%4\n" + "App.ActiveDocument.%1.X2=%5\n" + "App.ActiveDocument.%1.Y2=%6\n" + "App.ActiveDocument.%1.Z2=%7\n" + "App.ActiveDocument.%1.Placement=%8\n") + .arg(name) + .arg(ui.edgeX1->value(),0,'f',2) + .arg(ui.edgeY1->value(),0,'f',2) + .arg(ui.edgeZ1->value(),0,'f',2) + .arg(ui.edgeX2->value(),0,'f',2) + .arg(ui.edgeY2->value(),0,'f',2) + .arg(ui.edgeZ2->value(),0,'f',2) + .arg(placement); + } + + // Execute the Python block + QString prim = tr("Create %1").arg(ui.comboBox1->currentText()); + Gui::Application::Instance->activeDocument()->openCommand(prim.toUtf8()); + Gui::Command::doCommand(Gui::Command::Doc, (const char*)cmd.toAscii()); + Gui::Application::Instance->activeDocument()->commitCommand(); + Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()"); + Gui::Command::doCommand(Gui::Command::Gui, "Gui.SendMsgToActiveView(\"ViewFit\")"); + } + catch (const Base::PyException& e) { + QMessageBox::warning(this, tr("Create %1") + .arg(ui.comboBox1->currentText()), QString::fromLatin1(e.what())); + } +} + +// ---------------------------------------------- + +/* TRANSLATOR PartGui::Location */ + +Location::Location(QWidget* parent) +{ + ui.setupUi(this); + + connect(ui.viewPositionButton, SIGNAL(clicked()), + this, SLOT(on_viewPositionButton_clicked())); +} + +Location::~Location() +{ // no need to delete child widgets, Qt does it all for us if (!this->activeView.isNull()) { Gui::View3DInventorViewer* viewer = static_cast @@ -143,11 +383,60 @@ DlgPrimitives::~DlgPrimitives() viewer->setRedirectToSceneGraph(false); viewer->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback,this); } +} + +void Location::on_viewPositionButton_clicked() +{ + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + if (!doc) { + return; + } + + Gui::View3DInventor* view = static_cast(doc->getActiveView()); + if (view && !this->activeView) { + Gui::View3DInventorViewer* viewer = view->getViewer(); + if (!viewer->isEditing()) { + this->activeView = view; + viewer->setEditing(true); + viewer->setRedirectToSceneGraph(true); + viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, this); + } + } } -QString DlgPrimitives::toPlacement() const +void Location::pickCallback(void * ud, SoEventCallback * n) { - Base::Vector3f d = ui.getDirection(); + const SoMouseButtonEvent * mbe = static_cast(n->getEvent()); + Gui::View3DInventorViewer* view = reinterpret_cast(n->getUserData()); + + // Mark all incoming mouse button events as handled, especially, to deactivate the selection node + n->getAction()->setHandled(); + if (mbe->getButton() == SoMouseButtonEvent::BUTTON1) { + if (mbe->getState() == SoButtonEvent::UP) { + n->setHandled(); + view->setEditing(false); + view->setRedirectToSceneGraph(false); + Location* dlg = reinterpret_cast(ud); + dlg->activeView = 0; + view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback,ud); + } + else if (mbe->getState() == SoButtonEvent::DOWN) { + const SoPickedPoint * point = n->getPickedPoint(); + if (point) { + SbVec3f pnt = point->getPoint(); + SbVec3f nor = point->getNormal(); + Location* dlg = reinterpret_cast(ud); + dlg->ui.loc->setPosition(Base::Vector3f(pnt[0],pnt[1],pnt[2])); + dlg->ui.loc->setDirection(Base::Vector3f(nor[0],nor[1],nor[2])); + n->setHandled(); + } + } + } +} + +QString Location::toPlacement() const +{ + Base::Vector3f d = ui.loc->getDirection(); gp_Dir dir = gp_Dir(d.x,d.y,d.z); gp_Pnt pnt = gp_Pnt(0.0,0.0,0.0); gp_Ax3 ax3; @@ -190,293 +479,62 @@ QString DlgPrimitives::toPlacement() const Trf.GetRotation(theAxis,theAngle); Base::Rotation rot(Base::convertTo(theAxis), theAngle); + Base::Vector3f loc = ui.loc->getPosition(); return QString::fromAscii("Base.Placement(Base.Vector(%1,%2,%3),Base.Rotation(%4,%5,%6,%7))") - .arg(ui.xPos->value(),0,'f',2) - .arg(ui.yPos->value(),0,'f',2) - .arg(ui.zPos->value(),0,'f',2) + .arg(loc.x,0,'f',2) + .arg(loc.y,0,'f',2) + .arg(loc.z,0,'f',2) .arg(rot[0],0,'f',2) .arg(rot[1],0,'f',2) .arg(rot[2],0,'f',2) .arg(rot[3],0,'f',2); } + +// ---------------------------------------------- + +/* TRANSLATOR PartGui::TaskPrimitives */ + +TaskPrimitives::TaskPrimitives() +{ + Gui::TaskView::TaskBox* taskbox; + widget = new DlgPrimitives(); + taskbox = new Gui::TaskView::TaskBox(QPixmap(), widget->windowTitle(),true, 0); + taskbox->groupLayout()->addWidget(widget); + Content.push_back(taskbox); + + location = new Location(); + taskbox = new Gui::TaskView::TaskBox(QPixmap(), location->windowTitle(),true, 0); + taskbox->groupLayout()->addWidget(location); + Content.push_back(taskbox); +} + +TaskPrimitives::~TaskPrimitives() +{ + // automatically deleted in the sub-class +} + +QDialogButtonBox::StandardButtons TaskPrimitives::getStandardButtons() const +{ + return QDialogButtonBox::Close| + QDialogButtonBox::Ok; +} -void DlgPrimitives::pickCallback(void * ud, SoEventCallback * n) +void TaskPrimitives::modifyStandardButtons(QDialogButtonBox* box) { - const SoMouseButtonEvent * mbe = static_cast(n->getEvent()); - Gui::View3DInventorViewer* view = reinterpret_cast(n->getUserData()); - - // Mark all incoming mouse button events as handled, especially, to deactivate the selection node - n->getAction()->setHandled(); - if (mbe->getButton() == SoMouseButtonEvent::BUTTON1) { - if (mbe->getState() == SoButtonEvent::UP) { - n->setHandled(); - view->setEditing(false); - view->setRedirectToSceneGraph(false); - DlgPrimitives* dlg = reinterpret_cast(ud); - dlg->activeView = 0; - view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback,ud); - } - else if (mbe->getState() == SoButtonEvent::DOWN) { - const SoPickedPoint * point = n->getPickedPoint(); - if (point) { - SbVec3f pnt = point->getPoint(); - SbVec3f nor = point->getNormal(); - DlgPrimitives* dlg = reinterpret_cast(ud); - dlg->ui.xPos->setValue(pnt[0]); - dlg->ui.yPos->setValue(pnt[1]); - dlg->ui.zPos->setValue(pnt[2]); - dlg->ui.setDirection(Base::Vector3f(nor[0],nor[1],nor[2])); - n->setHandled(); - } - } - } -} - -void DlgPrimitives::on_viewPositionButton_clicked() -{ - Gui::Document* doc = Gui::Application::Instance->activeDocument(); - if (!doc) { - QMessageBox::warning(this, tr("Create %1") - .arg(ui.comboBox1->currentText()), tr("No active document")); - return; - } - - Gui::View3DInventor* view = static_cast(doc->getActiveView()); - if (view && !this->activeView) { - Gui::View3DInventorViewer* viewer = view->getViewer(); - if (!viewer->isEditing()) { - this->activeView = view; - viewer->setEditing(true); - viewer->setRedirectToSceneGraph(true); - viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), pickCallback, this); - } - } -} - -void DlgPrimitives::accept() -{ - try { - QString cmd; QString name; - App::Document* doc = App::GetApplication().getActiveDocument(); - if (!doc) { - QMessageBox::warning(this, tr("Create %1") - .arg(ui.comboBox1->currentText()), tr("No active document")); - return; - } - if (ui.comboBox1->currentIndex() == 0) { // plane - name = QString::fromAscii(doc->getUniqueObjectName("Plane").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Plane\",\"%1\")\n" - "App.ActiveDocument.%1.Length=%2\n" - "App.ActiveDocument.%1.Width=%3\n" - "App.ActiveDocument.%1.Placement=%4\n") - .arg(name) - .arg(ui.planeLength->value(),0,'f',2) - .arg(ui.planeWidth->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 1) { // box - name = QString::fromAscii(doc->getUniqueObjectName("Box").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Box\",\"%1\")\n" - "App.ActiveDocument.%1.Length=%2\n" - "App.ActiveDocument.%1.Width=%3\n" - "App.ActiveDocument.%1.Height=%4\n" - "App.ActiveDocument.%1.Placement=%5\n") - .arg(name) - .arg(ui.boxLength->value(),0,'f',2) - .arg(ui.boxWidth->value(),0,'f',2) - .arg(ui.boxHeight->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 2) { // cylinder - name = QString::fromAscii(doc->getUniqueObjectName("Cylinder").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Cylinder\",\"%1\")\n" - "App.ActiveDocument.%1.Radius=%2\n" - "App.ActiveDocument.%1.Height=%3\n" - "App.ActiveDocument.%1.Angle=%4\n" - "App.ActiveDocument.%1.Placement=%5\n") - .arg(name) - .arg(ui.cylinderRadius->value(),0,'f',2) - .arg(ui.cylinderHeight->value(),0,'f',2) - .arg(ui.cylinderAngle->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 3) { // cone - name = QString::fromAscii(doc->getUniqueObjectName("Cone").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Cone\",\"%1\")\n" - "App.ActiveDocument.%1.Radius1=%2\n" - "App.ActiveDocument.%1.Radius2=%3\n" - "App.ActiveDocument.%1.Height=%4\n" - "App.ActiveDocument.%1.Angle=%5\n" - "App.ActiveDocument.%1.Placement=%6\n") - .arg(name) - .arg(ui.coneRadius1->value(),0,'f',2) - .arg(ui.coneRadius2->value(),0,'f',2) - .arg(ui.coneHeight->value(),0,'f',2) - .arg(ui.coneAngle->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 4) { // sphere - name = QString::fromAscii(doc->getUniqueObjectName("Sphere").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Sphere\",\"%1\")\n" - "App.ActiveDocument.%1.Radius=%2\n" - "App.ActiveDocument.%1.Angle1=%3\n" - "App.ActiveDocument.%1.Angle2=%4\n" - "App.ActiveDocument.%1.Angle3=%5\n" - "App.ActiveDocument.%1.Placement=%6\n") - .arg(name) - .arg(ui.sphereRadius->value(),0,'f',2) - .arg(ui.sphereAngle1->value(),0,'f',2) - .arg(ui.sphereAngle2->value(),0,'f',2) - .arg(ui.sphereAngle3->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 5) { // ellipsoid - name = QString::fromAscii(doc->getUniqueObjectName("Ellipsoid").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Ellipsoid\",\"%1\")\n" - "App.ActiveDocument.%1.Radius1=%2\n" - "App.ActiveDocument.%1.Radius2=%3\n" - "App.ActiveDocument.%1.Angle1=%4\n" - "App.ActiveDocument.%1.Angle2=%5\n" - "App.ActiveDocument.%1.Angle3=%6\n" - "App.ActiveDocument.%1.Placement=%7\n") - .arg(name) - .arg(ui.ellipsoidRadius1->value(),0,'f',2) - .arg(ui.ellipsoidRadius2->value(),0,'f',2) - .arg(ui.ellipsoidAngle1->value(),0,'f',2) - .arg(ui.ellipsoidAngle2->value(),0,'f',2) - .arg(ui.ellipsoidAngle3->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 6) { // torus - name = QString::fromAscii(doc->getUniqueObjectName("Torus").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Torus\",\"%1\")\n" - "App.ActiveDocument.%1.Radius1=%2\n" - "App.ActiveDocument.%1.Radius2=%3\n" - "App.ActiveDocument.%1.Angle1=%4\n" - "App.ActiveDocument.%1.Angle2=%5\n" - "App.ActiveDocument.%1.Angle3=%6\n" - "App.ActiveDocument.%1.Placement=%7\n") - .arg(name) - .arg(ui.torusRadius1->value(),0,'f',2) - .arg(ui.torusRadius2->value(),0,'f',2) - .arg(ui.torusAngle1->value(),0,'f',2) - .arg(ui.torusAngle2->value(),0,'f',2) - .arg(ui.torusAngle3->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 7) { // wedge - name = QString::fromAscii(doc->getUniqueObjectName("Wedge").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Wedge\",\"%1\")\n" - "App.ActiveDocument.%1.Xmin=%2\n" - "App.ActiveDocument.%1.Ymin=%3\n" - "App.ActiveDocument.%1.Zmin=%4\n" - "App.ActiveDocument.%1.X2min=%5\n" - "App.ActiveDocument.%1.Z2min=%6\n" - "App.ActiveDocument.%1.Xmax=%7\n" - "App.ActiveDocument.%1.Ymax=%8\n" - "App.ActiveDocument.%1.Zmax=%9\n" - "App.ActiveDocument.%1.X2max=%10\n" - "App.ActiveDocument.%1.Z2max=%11\n" - "App.ActiveDocument.%1.Placement=%12\n") - .arg(name) - .arg(ui.wedgeXmin->value(),0,'f',2) - .arg(ui.wedgeYmin->value(),0,'f',2) - .arg(ui.wedgeZmin->value(),0,'f',2) - .arg(ui.wedgeX2min->value(),0,'f',2) - .arg(ui.wedgeZ2min->value(),0,'f',2) - .arg(ui.wedgeXmax->value(),0,'f',2) - .arg(ui.wedgeYmax->value(),0,'f',2) - .arg(ui.wedgeZmax->value(),0,'f',2) - .arg(ui.wedgeX2max->value(),0,'f',2) - .arg(ui.wedgeZ2max->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 8) { // helix - name = QString::fromAscii(doc->getUniqueObjectName("Helix").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Helix\",\"%1\")\n" - "App.ActiveDocument.%1.Pitch=%2\n" - "App.ActiveDocument.%1.Height=%3\n" - "App.ActiveDocument.%1.Radius=%4\n" - "App.ActiveDocument.%1.Angle=%5\n" - "App.ActiveDocument.%1.Placement=%6\n") - .arg(name) - .arg(ui.helixPitch->value(),0,'f',2) - .arg(ui.helixHeight->value(),0,'f',2) - .arg(ui.helixRadius->value(),0,'f',2) - .arg(ui.helixAngle->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 9) { // circle - name = QString::fromAscii(doc->getUniqueObjectName("Circle").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Circle\",\"%1\")\n" - "App.ActiveDocument.%1.Radius=%2\n" - "App.ActiveDocument.%1.Angle0=%3\n" - "App.ActiveDocument.%1.Angle1=%4\n" - "App.ActiveDocument.%1.Placement=%5\n") - .arg(name) - .arg(ui.circleRadius->value(),0,'f',2) - .arg(ui.circleAngle0->value(),0,'f',2) - .arg(ui.circleAngle1->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 10) { // vertex - name = QString::fromAscii(doc->getUniqueObjectName("Vertex").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Vertex\",\"%1\")\n" - "App.ActiveDocument.%1.X=%2\n" - "App.ActiveDocument.%1.Y=%3\n" - "App.ActiveDocument.%1.Z=%4\n" - "App.ActiveDocument.%1.Placement=%5\n") - .arg(name) - .arg(ui.vertexX->value(),0,'f',2) - .arg(ui.vertexY->value(),0,'f',2) - .arg(ui.vertexZ->value(),0,'f',2) - .arg(this->toPlacement()); - } - else if (ui.comboBox1->currentIndex() == 11) { // edge - name = QString::fromAscii(doc->getUniqueObjectName("Edge").c_str()); - cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Edge\",\"%1\")\n" - "App.ActiveDocument.%1.X1=%2\n" - "App.ActiveDocument.%1.Y1=%3\n" - "App.ActiveDocument.%1.Z1=%4\n" - "App.ActiveDocument.%1.X2=%5\n" - "App.ActiveDocument.%1.Y2=%6\n" - "App.ActiveDocument.%1.Z2=%7\n" - "App.ActiveDocument.%1.Placement=%8\n") - .arg(name) - .arg(ui.edgeX1->value(),0,'f',2) - .arg(ui.edgeY1->value(),0,'f',2) - .arg(ui.edgeZ1->value(),0,'f',2) - .arg(ui.edgeX2->value(),0,'f',2) - .arg(ui.edgeY2->value(),0,'f',2) - .arg(ui.edgeZ2->value(),0,'f',2) - .arg(this->toPlacement()); - } - - // Execute the Python block - QString prim = tr("Create %1").arg(ui.comboBox1->currentText()); - Gui::Application::Instance->activeDocument()->openCommand(prim.toUtf8()); - Gui::Command::doCommand(Gui::Command::Doc, (const char*)cmd.toAscii()); - Gui::Application::Instance->activeDocument()->commitCommand(); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()"); - Gui::Command::doCommand(Gui::Command::Gui, "Gui.SendMsgToActiveView(\"ViewFit\")"); - } - catch (const Base::PyException& e) { - QMessageBox::warning(this, tr("Create %1") - .arg(ui.comboBox1->currentText()), QString::fromLatin1(e.what())); - } + QPushButton* btn = box->button(QDialogButtonBox::Ok); + btn->setText(QApplication::translate("PartGui::DlgPrimitives", "&Create")); } + +bool TaskPrimitives::accept() +{ + widget->createPrimitive(location->toPlacement()); + return false; +} + +bool TaskPrimitives::reject() +{ + return true; +} #include "moc_DlgPrimitives.cpp" diff --git a/src/Mod/Part/Gui/DlgPrimitives.h b/src/Mod/Part/Gui/DlgPrimitives.h index 0e50ab4f6..d485047df 100644 --- a/src/Mod/Part/Gui/DlgPrimitives.h +++ b/src/Mod/Part/Gui/DlgPrimitives.h @@ -24,21 +24,34 @@ #define PARTGUI_DLGPRIMITIVES_H #include -#include +#include #include "ui_DlgPrimitives.h" +#include "ui_Location.h" class SoEventCallback; namespace PartGui { -class DlgPrimitives : public Gui::LocationDialogComp +class DlgPrimitives : public QWidget { Q_OBJECT public: - DlgPrimitives(QWidget* parent = 0, Qt::WFlags fl = 0); + DlgPrimitives(QWidget* parent = 0); ~DlgPrimitives(); - void accept(); + void createPrimitive(const QString&); + +private: + Ui_DlgPrimitives ui; +}; + +class Location : public QWidget +{ + Q_OBJECT + +public: + Location(QWidget* parent = 0); + ~Location(); QString toPlacement() const; private Q_SLOTS: @@ -47,6 +60,27 @@ private Q_SLOTS: private: static void pickCallback(void * ud, SoEventCallback * n); QPointer activeView; + Ui_Location ui; +}; + +class TaskPrimitives : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + TaskPrimitives(); + ~TaskPrimitives(); + +public: + bool accept(); + bool reject(); + + QDialogButtonBox::StandardButtons getStandardButtons() const; + void modifyStandardButtons(QDialogButtonBox*); + +private: + DlgPrimitives* widget; + Location* location; }; } // namespace PartGui diff --git a/src/Mod/Part/Gui/DlgPrimitives.ui b/src/Mod/Part/Gui/DlgPrimitives.ui index afbcc9441..648ea6406 100644 --- a/src/Mod/Part/Gui/DlgPrimitives.ui +++ b/src/Mod/Part/Gui/DlgPrimitives.ui @@ -1,96 +1,102 @@ PartGui::DlgPrimitives - + 0 0 - 480 - 341 + 258 + 331 Geometric Primitives - + true - - - 9 - - - 6 - - - - - 6 - - - 0 - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 20 - 20 - - - - - - - - &Create - - - Alt+C - - - true - - - true - - - - - - - Cl&ose - - - Alt+O - - - true - - - - - + Primitive - - - 9 - - - 6 - - + + + + + + 0 + 0 + + + + 14 + + + + Plane + + + + + Box + + + + + Cylinder + + + + + Cone + + + + + Sphere + + + + + Ellipsoid + + + + + Torus + + + + + Wedge + + + + + Helix + + + + + Circle + + + + + Vertex + + + + + Edge + + + + + Parameter @@ -1464,196 +1470,6 @@ - - - - Qt::Horizontal - - - - 221 - 20 - - - - - - - - - 0 - 0 - - - - 14 - - - - Plane - - - - - Box - - - - - Cylinder - - - - - Cone - - - - - Sphere - - - - - Ellipsoid - - - - - Torus - - - - - Wedge - - - - - Helix - - - - - Circle - - - - - Vertex - - - - - Edge - - - - - - - - Position - - - - - - 0 - - - 6 - - - - - -2147480000.000000000000000 - - - 2147480000.000000000000000 - - - - - - - Z: - - - - - - - X: - - - - - - - Direction: - - - - - - - -2147480000.000000000000000 - - - 2147480000.000000000000000 - - - - - - - Y: - - - - - - - -1 - - - - - - - -2147480000.000000000000000 - - - 2147480000.000000000000000 - - - - - - - - - 3D View - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - @@ -1662,10 +1478,6 @@ comboBox1 - xPos - yPos - zPos - direction planeLength planeWidth boxLength @@ -1692,8 +1504,6 @@ torusAngle1 torusAngle2 torusAngle3 - createSolidButton - buttonClose @@ -1713,37 +1523,5 @@ - - buttonClose - clicked() - PartGui::DlgPrimitives - reject() - - - 254 - 282 - - - 44 - 268 - - - - - createSolidButton - clicked() - PartGui::DlgPrimitives - accept() - - - 160 - 276 - - - 8 - 277 - - - diff --git a/src/Mod/Part/Gui/Location.ui b/src/Mod/Part/Gui/Location.ui new file mode 100644 index 000000000..69f22d4dd --- /dev/null +++ b/src/Mod/Part/Gui/Location.ui @@ -0,0 +1,81 @@ + + + PartGui::Location + + + + 0 + 0 + 209 + 205 + + + + Location + + + true + + + + + + Position + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 3D View + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Gui::LocationWidget + QWidget +
Gui/InputVector.h
+
+
+ + +
diff --git a/src/Mod/Part/Gui/Makefile.am b/src/Mod/Part/Gui/Makefile.am index 4f9c63311..fe7d7a8dd 100644 --- a/src/Mod/Part/Gui/Makefile.am +++ b/src/Mod/Part/Gui/Makefile.am @@ -12,6 +12,7 @@ BUILT_SOURCES=\ ui_DlgPartImportIges.h \ ui_DlgPartImportStep.h \ ui_DlgPrimitives.h \ + ui_Location.h \ ui_DlgSettings3DViewPart.h \ ui_DlgSettingsGeneral.h \ ui_Mirroring.h \ @@ -220,6 +221,7 @@ EXTRA_DIST = \ DlgPartImportIges.ui \ DlgPartImportStep.ui \ DlgPrimitives.ui \ + Location.ui \ DlgSettings3DViewPart.ui \ DlgSettingsGeneral.ui \ Mirroring.ui \ diff --git a/src/Tools/plugins/widget/customwidgets.cpp b/src/Tools/plugins/widget/customwidgets.cpp index d46bd0541..6a2280377 100644 --- a/src/Tools/plugins/widget/customwidgets.cpp +++ b/src/Tools/plugins/widget/customwidgets.cpp @@ -115,7 +115,7 @@ LocationWidget::~LocationWidget() QSize LocationWidget::sizeHint() const { - return QSize(150,190); + return QSize(150,100); } void LocationWidget::changeEvent(QEvent* e) From db3aa26cf125c0ae4d059573bf1edfd45be5f266 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 30 Dec 2011 18:59:57 +0000 Subject: [PATCH 20/21] + fix build error git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5366 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Gui/InputVector.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Gui/InputVector.cpp b/src/Gui/InputVector.cpp index 0afec49a8..de8683dfc 100644 --- a/src/Gui/InputVector.cpp +++ b/src/Gui/InputVector.cpp @@ -22,6 +22,9 @@ #include "PreCompiled.h" +#ifndef _PreComp_ +# include +#endif #include "InputVector.h" #include "ui_InputVector.h" From 0c70ddf59500ba0d8e3eafc58451c6ea6f412b41 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 30 Dec 2011 20:49:59 +0000 Subject: [PATCH 21/21] + implement primitive dialog as task panel git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5367 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/AppPart.cpp | 2 +- src/Mod/Part/App/PrimitiveFeature.cpp | 12 +- src/Mod/Part/App/PrimitiveFeature.h | 8 +- src/Mod/Part/Gui/DlgPrimitives.cpp | 9 +- src/Mod/Part/Gui/DlgPrimitives.ui | 455 +++++++++++++++----------- 5 files changed, 276 insertions(+), 210 deletions(-) diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index f4a1d4093..3905c2644 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -157,7 +157,7 @@ void PartExport initPart() Part::Polygon ::init(); Part::Circle ::init(); Part::Vertex ::init(); - Part::Edge ::init(); + Part::Line ::init(); Part::Ellipsoid ::init(); Part::Plane ::init(); Part::Sphere ::init(); diff --git a/src/Mod/Part/App/PrimitiveFeature.cpp b/src/Mod/Part/App/PrimitiveFeature.cpp index 9a4deb390..004166532 100644 --- a/src/Mod/Part/App/PrimitiveFeature.cpp +++ b/src/Mod/Part/App/PrimitiveFeature.cpp @@ -163,9 +163,9 @@ void Vertex::onChanged(const App::Property* prop) Part::Feature::onChanged(prop); } -PROPERTY_SOURCE(Part::Edge, Part::Primitive) +PROPERTY_SOURCE(Part::Line, Part::Primitive) -Edge::Edge() +Line::Line() { ADD_PROPERTY_TYPE(X1,(0.0f),"Vertex 1 - Start",App::Prop_None,"X value of the start vertex"); ADD_PROPERTY_TYPE(Y1,(0.0f),"Vertex 1 - Start",App::Prop_None,"Y value of the Start vertex"); @@ -175,11 +175,11 @@ Edge::Edge() ADD_PROPERTY_TYPE(Z2,(1.0f),"Vertex 2 - Finish",App::Prop_None,"Z value of the finish vertex"); } -Edge::~Edge() +Line::~Line() { } -short Edge::mustExecute() const +short Line::mustExecute() const { if (X1.isTouched() || Y1.isTouched() || @@ -191,7 +191,7 @@ short Edge::mustExecute() const return Part::Feature::mustExecute(); } -App::DocumentObjectExecReturn *Edge::execute(void) +App::DocumentObjectExecReturn *Line::execute(void) { gp_Pnt point1; point1.SetX(this->X1.getValue()); @@ -212,7 +212,7 @@ App::DocumentObjectExecReturn *Edge::execute(void) return App::DocumentObject::StdReturn; } -void Edge::onChanged(const App::Property* prop) +void Line::onChanged(const App::Property* prop) { if (!isRestoring()) { if (prop == &X1 || prop == &Y1 || prop == &Z1 || prop == &X2 || prop == &Y2 || prop == &Z2){ diff --git a/src/Mod/Part/App/PrimitiveFeature.h b/src/Mod/Part/App/PrimitiveFeature.h index 7100b2ecd..250bf1564 100644 --- a/src/Mod/Part/App/PrimitiveFeature.h +++ b/src/Mod/Part/App/PrimitiveFeature.h @@ -70,13 +70,13 @@ public: //@} }; -class PartExport Edge : public Part::Primitive +class PartExport Line : public Part::Primitive { - PROPERTY_HEADER(Part::Edge); + PROPERTY_HEADER(Part::Line); public: - Edge(); - virtual ~Edge(); + Line(); + virtual ~Line(); App::PropertyFloat X1; App::PropertyFloat Y1; diff --git a/src/Mod/Part/Gui/DlgPrimitives.cpp b/src/Mod/Part/Gui/DlgPrimitives.cpp index 8b5339832..30cdb79d1 100644 --- a/src/Mod/Part/Gui/DlgPrimitives.cpp +++ b/src/Mod/Part/Gui/DlgPrimitives.cpp @@ -114,7 +114,7 @@ DlgPrimitives::DlgPrimitives(QWidget* parent) ui.vertexX->setMinimum(INT_MIN); ui.vertexY->setMinimum(INT_MIN); ui.vertexZ->setMinimum(INT_MIN); - // edge + // line ui.edgeX1->setMaximum(INT_MAX); ui.edgeX1->setMinimum(INT_MIN); ui.edgeY1->setMaximum(INT_MAX); @@ -326,10 +326,10 @@ void DlgPrimitives::createPrimitive(const QString& placement) .arg(ui.vertexZ->value(),0,'f',2) .arg(placement); } - else if (ui.comboBox1->currentIndex() == 11) { // edge - name = QString::fromAscii(doc->getUniqueObjectName("Edge").c_str()); + else if (ui.comboBox1->currentIndex() == 11) { // line + name = QString::fromAscii(doc->getUniqueObjectName("Line").c_str()); cmd = QString::fromAscii( - "App.ActiveDocument.addObject(\"Part::Edge\",\"%1\")\n" + "App.ActiveDocument.addObject(\"Part::Line\",\"%1\")\n" "App.ActiveDocument.%1.X1=%2\n" "App.ActiveDocument.%1.Y1=%3\n" "App.ActiveDocument.%1.Z1=%4\n" @@ -506,6 +506,7 @@ TaskPrimitives::TaskPrimitives() location = new Location(); taskbox = new Gui::TaskView::TaskBox(QPixmap(), location->windowTitle(),true, 0); taskbox->groupLayout()->addWidget(location); + taskbox->hideGroupBox(); Content.push_back(taskbox); } diff --git a/src/Mod/Part/Gui/DlgPrimitives.ui b/src/Mod/Part/Gui/DlgPrimitives.ui index 648ea6406..5423a5de0 100644 --- a/src/Mod/Part/Gui/DlgPrimitives.ui +++ b/src/Mod/Part/Gui/DlgPrimitives.ui @@ -6,8 +6,8 @@ 0 0 - 258 - 331 + 285 + 370 @@ -86,12 +86,12 @@ - Vertex + Point - Edge + Line @@ -953,134 +953,179 @@ - + - - - X min - - - - - - - - - - x max - - - - - - - 10.000000000000000 - - + + + + + X min/max: + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + 10.000000000000000 + + + + + + + Y min/max: + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + 10.000000000000000 + + + + + + + Z min/max: + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + 10.000000000000000 + + + + + + + X2 min/max: + + + + + + + + 0 + 0 + + + + 2.000000000000000 + + + + + + + + 0 + 0 + + + + 8.000000000000000 + + + + + + + Z2 min/max: + + + + + + + + 0 + 0 + + + + 2.000000000000000 + + + + + + + + 0 + 0 + + + + 8.000000000000000 + + + + - - - Y min + + + Qt::Vertical - - - - - - - - - Y max + + + 20 + 81 + - - - - - - 10.000000000000000 - - - - - - - Z min - - - - - - - - - - Z max - - - - - - - 10.000000000000000 - - - - - - - X2 min - - - - - - - 2.000000000000000 - - - - - - - X2 max - - - - - - - 8.000000000000000 - - - - - - - Z2 min - - - - - - - 2.000000000000000 - - - - - - - Z2 max - - - - - - - 8.000000000000000 - - + @@ -1167,7 +1212,7 @@ - Angle - 0 for cyl + Angle: @@ -1221,7 +1266,7 @@ - Angle0 + Angle 1: @@ -1238,7 +1283,7 @@ - Angle1 + Angle 2: @@ -1276,57 +1321,64 @@ - - - - 10 - 10 - 201 - 76 - - - - - - - - - - - - - - - - X Value: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Y Value: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Z Value: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - + + + + + + + + + + + + + + + + X: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Y: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Z: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + Qt::Vertical + + + + 20 + 139 + + + + + @@ -1335,30 +1387,30 @@ - X + X: - Qt::AlignCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - Y + Y: - Qt::AlignCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - Z + Z: - Qt::AlignCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -1372,7 +1424,7 @@ - Finish Vertex + End point Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -1382,37 +1434,37 @@ - Start Vertex + Start point - X + X: - Qt::AlignCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - Y + Y: - Qt::AlignCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - Z + Z: - Qt::AlignCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -1463,6 +1515,19 @@ + + + + Qt::Vertical + + + + 20 + 0 + + + +