diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index d0109d4e72..f6abf55423 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -384,6 +384,9 @@ void TopoShape::mapSubElementTypeForShape(const TopoShape& other, } std::ostringstream ss; char elementType {shapeName(type)[0]}; + if ( ! elementMap() ) { + FC_THROWM(NullShapeException, "No element map"); + } elementMap()->encodeElementName(elementType, name, ss, &sids, Tag, op, other.Tag); elementMap()->setElementName(element, name, Tag, &sids); } diff --git a/src/Mod/Part/App/TopoShapeMapper.cpp b/src/Mod/Part/App/TopoShapeMapper.cpp index 69f9653d18..4268a433d2 100644 --- a/src/Mod/Part/App/TopoShapeMapper.cpp +++ b/src/Mod/Part/App/TopoShapeMapper.cpp @@ -1,3 +1,5 @@ +#include "PreCompiled.h" + #include "TopoShapeMapper.h" namespace Part diff --git a/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplineApproximate.svg b/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplineApproximate.svg index 66e92f507b..e0c8e5ac32 100644 --- a/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplineApproximate.svg +++ b/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplineApproximate.svg @@ -15,6 +15,17 @@ xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + @@ -464,7 +484,8 @@ transform="matrix(0.1460346,0,0,0.1460346,-220.10298,-55.131225)"> + id="g4428-3-2" + style="display:inline"> diff --git a/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplineInsertKnot.svg b/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplineInsertKnot.svg index fa676a240d..569e11ffd3 100644 --- a/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplineInsertKnot.svg +++ b/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplineInsertKnot.svg @@ -380,7 +380,7 @@ id="path3826" /> + diff --git a/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_JoinCurves.svg b/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_JoinCurves.svg index 0ac32bc5e1..3cf03594f5 100644 --- a/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_JoinCurves.svg +++ b/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_JoinCurves.svg @@ -261,11 +261,11 @@ @@ -316,6 +316,15 @@ y1="35.978416" x2="25.988253" y2="29.916241" /> + @@ -368,7 +377,7 @@ + transform="matrix(-1,0,0,1,47.987644,0)"> + + + + diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index dd3b963bc0..05f7db40c7 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -3886,6 +3886,11 @@ void ViewProviderSketch::generateContextMenu() int selectedConics = 0; int selectedPoints = 0; int selectedConstraints = 0; + int selectedBsplines = 0; + int selectedBsplineKnots = 0; + int selectedOrigin = 0; + int selectedEndPoints = 0; + bool onlyOrigin = false; Gui::MenuItem menu; menu.setCommand("Sketcher context"); @@ -3896,31 +3901,70 @@ void ViewProviderSketch::generateContextMenu() // if something is selected, count different elements in the current selection if (selection.size() > 0) { const std::vector SubNames = selection[0].getSubNames(); - - for (auto& name : SubNames) { - if (name.substr(0, 4) == "Edge") { - ++selectedEdges; - + const Sketcher::SketchObject* obj; + if (selection[0].getObject()->isDerivedFrom()) { + obj = static_cast(selection[0].getObject()); + for (auto& name : SubNames) { int geoId = std::atoi(name.substr(4, 4000).c_str()) - 1; - if (geoId >= 0) { - const Part::Geometry* geo = getSketchObject()->getGeometry(geoId); - if (isLineSegment(*geo)) { - ++selectedLines; - } - else { - ++selectedConics; + const Part::Geometry* geo = getSketchObject()->getGeometry(geoId); + if (name.substr(0, 4) == "Edge") { + ++selectedEdges; + + if (geoId >= 0) { + if (isLineSegment(*geo)) { + ++selectedLines; + } + else if (geo->is()) { + ++selectedBsplines; + } + else { + ++selectedConics; + } } } - } - else if (name.substr(0, 4) == "Vert") { - ++selectedPoints; - } - else if (name.substr(0, 4) == "Cons") { - ++selectedConstraints; + else if (name.substr(0, 4) == "Vert") { + ++selectedPoints; + Sketcher::PointPos posId; + getIdsFromName(name, obj, geoId, posId); + if (isBsplineKnotOrEndPoint(obj, geoId, posId)) { + ++selectedBsplineKnots; + } + if (Sketcher::PointPos::start != posId || Sketcher::PointPos::end != posId) { + ++selectedEndPoints; + } + } + else if (name.substr(0, 4) == "Cons") { + ++selectedConstraints; + } + else if (name.substr(2, 5) == "Axis") { + ++selectedEdges; + ++selectedLines; + ++selectedOrigin; + } + else if (name.substr(0, 4) == "Root") { + ++selectedPoints; + ++selectedOrigin; + } } } + if (selectedPoints + selectedEdges == selectedOrigin) { + onlyOrigin = true; + } // build context menu items depending on the selection - if (selectedEdges >= 1 && selectedPoints == 0) { + if (selectedBsplines > 0 && selectedBsplines == selectedEdges && selectedPoints == 0 + && !onlyOrigin) { + menu << "Sketcher_BSplineInsertKnot" + << "Sketcher_BSplineIncreaseDegree" + << "Sketcher_BSplineDecreaseDegree"; + } + else if (selectedBsplineKnots > 0 && selectedBsplineKnots == selectedPoints + && selectedEdges == 0 && !onlyOrigin) { + if (selectedBsplineKnots == 1) { + menu << "Sketcher_BSplineIncreaseKnotMultiplicity" + << "Sketcher_BSplineDecreaseKnotMultiplicity"; + } + } + if (selectedEdges >= 1 && selectedPoints == 0 && selectedBsplines == 0 && !onlyOrigin) { menu << "Sketcher_Dimension"; if (selectedConics == 0) { menu << "Sketcher_ConstrainHorVer" @@ -3948,9 +3992,9 @@ void ViewProviderSketch::generateContextMenu() menu << "Sketcher_ConstrainTangent"; } } - else if (selectedEdges == 1 && selectedPoints >= 1) { + else if (selectedEdges == 1 && selectedPoints >= 1 && !onlyOrigin) { menu << "Sketcher_Dimension"; - if (selectedConics == 0) { + if (selectedConics == 0 && selectedBsplines == 0) { menu << "Sketcher_ConstrainCoincidentUnified" << "Sketcher_ConstrainHorVer" << "Sketcher_ConstrainVertical" @@ -3958,6 +4002,10 @@ void ViewProviderSketch::generateContextMenu() if (selectedPoints == 2) { menu << "Sketcher_ConstrainSymmetric"; } + if (selectedPoints == 1) { + menu << "Sketcher_ConstrainPerpendicular" + << "Sketcher_ConstrainTangent"; + } } else { menu << "Sketcher_ConstrainCoincidentUnified" @@ -3965,7 +4013,7 @@ void ViewProviderSketch::generateContextMenu() << "Sketcher_ConstrainTangent"; } } - else if (selectedEdges == 0 && selectedPoints >= 1) { + else if (selectedEdges == 0 && selectedPoints >= 1 && !onlyOrigin) { menu << "Sketcher_Dimension"; if (selectedPoints > 1) { @@ -3974,8 +4022,15 @@ void ViewProviderSketch::generateContextMenu() << "Sketcher_ConstrainVertical" << "Sketcher_ConstrainHorizontal"; } + if (selectedPoints == 2) { + menu << "Sketcher_ConstrainPerpendicular" + << "Sketcher_ConstrainTangent"; + if (selectedEndPoints == 2) { + menu << "Sketcher_JoinCurves"; + } + } } - else if (selectedLines >= 1 && selectedPoints >= 1) { + else if (selectedLines >= 1 && selectedPoints >= 1 && !onlyOrigin) { menu << "Sketcher_Dimension" << "Sketcher_ConstrainHorVer" << "Sketcher_ConstrainVertical" diff --git a/src/Mod/TechDraw/App/Cosmetic.cpp b/src/Mod/TechDraw/App/Cosmetic.cpp index aa47615f21..5b65996ff1 100644 --- a/src/Mod/TechDraw/App/Cosmetic.cpp +++ b/src/Mod/TechDraw/App/Cosmetic.cpp @@ -257,6 +257,8 @@ unsigned int CosmeticEdge::getMemSize () const void CosmeticEdge::Save(Base::Writer &writer) const { + // TODO: this should be using m_format->Save(writer) instead of saving the individual + // fields. writer.Stream() << writer.ind() << "