Skip to content

Commit

Permalink
Part Attacher: Implement 1D intersection for attachments (FreeCAD#12328)
Browse files Browse the repository at this point in the history
* PD: Implement 1D intersection for attachments

Extract a line from the intersection of two faces.

Closes FreeCAD#6870

* fixup! Use Handle macro

For some reason I don't fully understand yet the CI was failing, let's
see if this fixes the compilation errors.

* fixup! Add missing(?) header

Well, it compiles just fine on my system...

* fixup! Be more specific in error messages
  • Loading branch information
LemonBoy authored Feb 13, 2024
1 parent c0e318c commit 7f5d89f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
31 changes: 30 additions & 1 deletion src/Mod/Part/App/Attacher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
# include <GeomAPI.hxx>
# include <GeomAPI_ProjectPointOnCurve.hxx>
# include <GeomAPI_ProjectPointOnSurf.hxx>
# include <GeomAPI_IntSS.hxx>
# include <GeomLib_IsPlanarSurface.hxx>
# include <gp_Ax1.hxx>
# include <gp_Dir.hxx>
Expand Down Expand Up @@ -1687,7 +1688,7 @@ AttachEngineLine::AttachEngineLine()

modeRefTypes[mm1FaceNormal] = attacher3D.modeRefTypes[mmTangentPlane];


modeRefTypes[mm1Intersection].push_back(cat(rtFace,rtFace));

this->EnableAllSupportedModes();
}
Expand Down Expand Up @@ -1886,6 +1887,34 @@ Base::Placement AttachEngineLine::calculateAttachedPlacement(const Base::Placeme
LineBasePoint = dx2.Location();
}
}break;
case mm1Intersection:{
if (shapes.size() < 2)
throw Base::ValueError("AttachEngineLine::calculateAttachedPlacement: Intersection mode requires two shapes; only one is supplied");
if (shapes[0]->IsNull() || shapes[1]->IsNull())
throw Base::ValueError("Null shape in AttachEngineLine::calculateAttachedPlacement()!");

const TopoDS_Face &face1 = TopoDS::Face(*(shapes[0]));
const TopoDS_Face &face2 = TopoDS::Face(*(shapes[1]));

Handle(Geom_Surface) hSurf1 = BRep_Tool::Surface(face1);
Handle(Geom_Surface) hSurf2 = BRep_Tool::Surface(face2);
GeomAPI_IntSS intersector(hSurf1, hSurf2, Precision::Confusion());
if (!intersector.IsDone())
throw Base::ValueError("AttachEngineLine::calculateAttachedPlacement: Intersection failed");

const Standard_Integer intLines = intersector.NbLines();
if (intLines == 0)
throw Base::ValueError("AttachEngineLine::calculateAttachedPlacement: The two shapes don't intersect");
if (intLines != 1)
throw Base::ValueError("AttachEngineLine::calculateAttachedPlacement: Intersection is not a single curve");

GeomAdaptor_Curve adapt(intersector.Line(1));
if (adapt.GetType() != GeomAbs_Line)
throw Base::ValueError("AttachEngineLine::calculateAttachedPlacement: Intersection is not a straight line");

LineBasePoint = adapt.Line().Location();
LineDir = adapt.Line().Direction();
}break;
case mm1Proximity:{
if (shapes.size() < 2)
throw Base::ValueError("AttachEngineLine::calculateAttachedPlacement: Proximity mode requires two shapes; only one is supplied");
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/Part/Gui/AttacherTexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ TextSet getUIStrings(Base::Type attacherType, eMapMode mmode)
qApp->translate("Attacher1D", "Line that passes through two vertices.","AttachmentLine mode tooltip"));
case mm1Intersection:
return TwoStrings(qApp->translate("Attacher1D", "Intersection","AttachmentLine mode caption"),
qApp->translate("Attacher1D", "Not implemented.","AttachmentLine mode tooltip"));
qApp->translate("Attacher1D", "Intersection of two faces.","AttachmentLine mode tooltip"));
case mm1Proximity:
return TwoStrings(qApp->translate("Attacher1D", "Proximity line","AttachmentLine mode caption"),
qApp->translate("Attacher1D", "Line that spans the shortest distance between shapes.","AttachmentLine mode tooltip"));
Expand Down

0 comments on commit 7f5d89f

Please sign in to comment.