Skip to content

Commit

Permalink
Part: Inside TopoShape::makeElementPrismUntil use more points to chec…
Browse files Browse the repository at this point in the history
…k for concavity
  • Loading branch information
wwmayer committed Jan 5, 2025
1 parent 38682ac commit 3fb6a81
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 20 deletions.
41 changes: 25 additions & 16 deletions src/Mod/Part/App/Tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ TopLoc_Location Part::Tools::fromPlacement(const Base::Placement& plm)
}

bool Part::Tools::isConcave(const TopoDS_Face &face,
const gp_Pnt &pointOfVue,
const std::vector<gp_Pnt> &pointOfVue,
const gp_Dir &direction)
{
bool result = false;
Expand All @@ -761,26 +761,35 @@ bool Part::Tools::isConcave(const TopoDS_Face &face,

// create a line through the point of vue
gp_Lin line;
line.SetLocation(pointOfVue);
line.SetDirection(direction);

// Find intersection of line with the face
BRepIntCurveSurface_Inter mkSection;
mkSection.Init(face, line, Precision::Confusion());

if (mkSection.More()) {
result = mkSection.Transition() == IntCurveSurface_In;

// compute normals at the intersection
gp_Pnt iPnt;
gp_Vec dU, dV;
surf->D1(mkSection.U(), mkSection.V(), iPnt, dU, dV);
mkSection.Load(face, Precision::Confusion());
for (const auto pnt : pointOfVue) {
line.SetLocation(pnt);
Handle(Geom_Line) geomline = new Geom_Line(line);
GeomAdaptor_Curve aCurve(geomline);
mkSection.Init(aCurve);

if (mkSection.More()) {
result = mkSection.Transition() == IntCurveSurface_In;

// compute normals at the intersection
gp_Pnt iPnt;
gp_Vec dU, dV;
surf->D1(mkSection.U(), mkSection.V(), iPnt, dU, dV);

// check normals orientation
gp_Dir dirdU(dU);
result = (dirdU.Angle(line.Direction()) - M_PI_2) <= Precision::Confusion();
gp_Dir dirdV(dV);
result = result || ((dirdV.Angle(line.Direction()) - M_PI_2) <= Precision::Confusion());
}

// check normals orientation
gp_Dir dirdU(dU);
result = (dirdU.Angle(line.Direction()) - M_PI_2) <= Precision::Confusion();
gp_Dir dirdV(dV);
result = result || ((dirdV.Angle(line.Direction()) - M_PI_2) <= Precision::Confusion());
if (result) {
break;
}
}

return result;
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/Part/App/Tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class PartExport Tools
* \return true if the face is concave when shown from pointOfVue and looking into direction
* and false otherwise, plane case included.
*/
static bool isConcave(const TopoDS_Face &face, const gp_Pnt &pointOfVue, const gp_Dir &direction);
static bool isConcave(const TopoDS_Face &face, const std::vector<gp_Pnt> &pointOfVue, const gp_Dir &direction);
};

} //namespace Part
Expand Down
13 changes: 10 additions & 3 deletions src/Mod/Part/App/TopoShapeExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4244,11 +4244,18 @@ TopoShape& TopoShape::makeElementPrismUntil(const TopoShape& _base,
BRepFeat_MakePrism PrismMaker;

// don't remove limits of concave face
if (checkLimits && __uptoface.shapeType(true) == TopAbs_FACE){
if (checkLimits && __uptoface.shapeType(true) == TopAbs_FACE) {
// get all vertexes of the sketch as the COG alone may fail to intersect the face
std::vector<gp_Pnt> pnts;
for (TopExp_Explorer xp(profile.getShape(), TopAbs_VERTEX); xp.More(); xp.Next()) {
pnts.push_back(BRep_Tool::Pnt(TopoDS::Vertex(xp.Current())));
}

Base::Vector3d vCog;
profile.getCenterOfGravity(vCog);
gp_Pnt pCog(vCog.x, vCog.y, vCog.z);
checkLimits = ! Part::Tools::isConcave(TopoDS::Face(__uptoface.getShape()), pCog , direction);
gp_Pnt cog(vCog.x, vCog.y, vCog.z);
pnts.push_back(cog);
checkLimits = !Part::Tools::isConcave(TopoDS::Face(__uptoface.getShape()), pnts , direction);
}

TopoShape _uptoface(__uptoface);
Expand Down

0 comments on commit 3fb6a81

Please sign in to comment.