From 054a23d7cecd7048818a9a6350ab3c25d0d18b03 Mon Sep 17 00:00:00 2001 From: Mihail Dumitrescu Date: Wed, 29 May 2024 16:48:30 +0300 Subject: [PATCH] Add ParallelPlane attachment mode. It results in an attachment similar to ObjectXY but with the XY plane translated to pass through a selected vertex. It is most useful to place sketches: pick a plane (XY, XZ, YZ) or another sketch then select a vertex to automatically translate the sketch in the Z-direction. In contrast to the Translate mode it does not change the origin. --- src/Mod/Part/App/Attacher.cpp | 31 +++++++++++++++++++++++++++++- src/Mod/Part/App/Attacher.h | 2 ++ src/Mod/Part/Gui/AttacherTexts.cpp | 6 ++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Mod/Part/App/Attacher.cpp b/src/Mod/Part/App/Attacher.cpp index 1ce962416438..bf9b8e822cfd 100644 --- a/src/Mod/Part/App/Attacher.cpp +++ b/src/Mod/Part/App/Attacher.cpp @@ -31,6 +31,7 @@ # include # include # include +# include # include # include # include @@ -134,6 +135,8 @@ const char* AttachEngine::eMapModeStrings[]= { "OYZ", "OYX", + "ParallelPlane", + nullptr}; //this list must be in sync with eRefType enum. @@ -1002,6 +1005,11 @@ AttachEngine3D::AttachEngine3D() modeRefTypes[mmObjectXZ] = ss; modeRefTypes[mmObjectYZ] = ss; + modeRefTypes[mmParallelPlane].push_back( + cat(eRefType(rtFlatFace | rtFlagHasPlacement), rtVertex)); + modeRefTypes[mmParallelPlane].push_back( + cat(eRefType(rtAnything | rtFlagHasPlacement), rtVertex)); + modeRefTypes[mmInertialCS].push_back(cat(rtAnything)); modeRefTypes[mmInertialCS].push_back(cat(rtAnything,rtAnything)); modeRefTypes[mmInertialCS].push_back(cat(rtAnything,rtAnything,rtAnything)); @@ -1146,7 +1154,8 @@ Base::Placement AttachEngine3D::_calculateAttachedPlacement( } break; case mmObjectXY: case mmObjectXZ: - case mmObjectYZ:{ + case mmObjectYZ: + case mmParallelPlane: { //DeepSOIC: could have been done much more efficiently, but I'm lazy... gp_Dir dirX, dirY, dirZ; if (types[0] & rtFlagHasPlacement) { @@ -1199,6 +1208,26 @@ Base::Placement AttachEngine3D::_calculateAttachedPlacement( SketchNormal = dirX; SketchXAxis = gp_Vec(dirY); break; + case mmParallelPlane: { + if (shapes.size() < 2) { + throw Base::ValueError("AttachEngine3D::calculateAttachedPlacement: not " + "enough subshapes (need one plane and one vertex)."); + } + + TopoDS_Vertex vertex; + try { vertex = TopoDS::Vertex(*(shapes[1])); } catch(...) {} + if (vertex.IsNull()) + throw Base::ValueError("Null vertex in AttachEngine3D::calculateAttachedPlacement()!"); + + SketchNormal = dirZ; + SketchXAxis = gp_Vec(dirX); + + // The new origin will be the vertex projected onto the normal. + Handle(Geom_Line) hCurve(new Geom_Line(SketchBasePoint, dirZ)); + gp_Pnt p = BRep_Tool::Pnt(vertex); + GeomAPI_ProjectPointOnCurve projector(p, hCurve); + SketchBasePoint = projector.NearestPoint(); + } break; default: break; } diff --git a/src/Mod/Part/App/Attacher.h b/src/Mod/Part/App/Attacher.h index 6ef477dd3749..73c0c1b962ee 100644 --- a/src/Mod/Part/App/Attacher.h +++ b/src/Mod/Part/App/Attacher.h @@ -110,6 +110,8 @@ enum eMapMode { mmOYZ, mmOYX, + mmParallelPlane, + mmDummy_NumberOfModes//a value useful to check the validity of mode value };//see also eMapModeStrings[] definition in .cpp diff --git a/src/Mod/Part/Gui/AttacherTexts.cpp b/src/Mod/Part/Gui/AttacherTexts.cpp index cd8333fad1a2..42b396b5cb19 100644 --- a/src/Mod/Part/Gui/AttacherTexts.cpp +++ b/src/Mod/Part/Gui/AttacherTexts.cpp @@ -63,6 +63,9 @@ TextSet getUIStrings(Base::Type attacherType, eMapMode mmode) case mmObjectYZ: return TwoStrings(qApp->translate("Attacher3D", "Object's Y Z X","Attachment3D mode caption"), qApp->translate("Attacher3D", "X', Y', Z' axes are matched with object's local Y, Z, X, respectively.","Attachment3D mode tooltip")); + case mmParallelPlane: + return TwoStrings(qApp->translate("Attacher3D", "XY parallel to plane","Attachment3D mode caption"), + qApp->translate("Attacher3D", "X' Y' plane is parallel to the plane (object's XY) and passes through the vertex.","Attachment3D mode tooltip")); case mmFlatFace: return TwoStrings(qApp->translate("Attacher3D", "XY on plane","Attachment3D mode caption"), qApp->translate("Attacher3D", "X' Y' plane is aligned to coincide planar face.","Attachment3D mode tooltip")); @@ -138,6 +141,9 @@ TextSet getUIStrings(Base::Type attacherType, eMapMode mmode) case mmObjectYZ: return TwoStrings(qApp->translate("Attacher2D", "Object's YZ","AttachmentPlane mode caption"), qApp->translate("Attacher2D", "Plane is aligned to YZ local plane of linked object.","AttachmentPlane mode tooltip")); + case mmParallelPlane: + return TwoStrings(qApp->translate("Attacher2D", "XY parallel to plane","AttachmentPlane mode caption"), + qApp->translate("Attacher2D", "X' Y' plane is parallel to the plane (object's XY) and passes through the vertex","AttachmentPlane mode tooltip")); case mmFlatFace: return TwoStrings(qApp->translate("Attacher2D", "Plane face","AttachmentPlane mode caption"), qApp->translate("Attacher2D", "Plane is aligned to coincide planar face.","AttachmentPlane mode tooltip"));