Skip to content

Commit

Permalink
[TD]fix exception on empty compound
Browse files Browse the repository at this point in the history
- if the intersection of the segment tool and
  source shape is empty, processing should
  continue with next segment
  • Loading branch information
WandererFan committed Nov 7, 2022
1 parent 4ea2cb4 commit 38f1906
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 14 deletions.
40 changes: 27 additions & 13 deletions src/Mod/TechDraw/App/DrawComplexSection.cpp
Expand Up @@ -299,7 +299,7 @@ TopoDS_Shape DrawComplexSection::getShapeToPrepare() const
//get the shape ready for projection and cut surface finding
TopoDS_Shape DrawComplexSection::prepareShape(const TopoDS_Shape &cutShape, double shapeSize)
{
// Base::Console().Message("DCS::prepareShape() - strat: %d\n", ProjectionStrategy.getValue());
// Base::Console().Message("DCS::prepareShape() - strat: %d\n", ProjectionStrategy.getValue());
if (ProjectionStrategy.getValue() == 0) {
//Offset. Use regular section behaviour
return DrawViewSection::prepareShape(cutShape, shapeSize);
Expand All @@ -321,7 +321,7 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
const TopoDS_Shape &toolFaceShape,
double extrudeDistance)
{
// Base::Console().Message("DCS::makeAlignedPieces()\n");
// Base::Console().Message("DCS::makeAlignedPieces()\n");
std::vector<TopoDS_Shape> pieces;
std::vector<double> pieceXSize;//size in sectionCS.XDirection (width)
std::vector<double> pieceYSize;//size in sectionCS.Direction (depth)
Expand Down Expand Up @@ -369,7 +369,6 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,

gp_Vec rotateAxis = getSectionCS().Direction().Crossed(gProfileVec);


//make a tool for each segment of the toolFaceShape and intersect it with the
//raw shape
TopExp_Explorer expFaces(toolFaceShape, TopAbs_FACE);
Expand All @@ -390,8 +389,9 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
BRepPrimAPI_MakePrism mkPrism(face, extrudeDir);
TopoDS_Shape segmentTool = mkPrism.Shape();
TopoDS_Shape intersect = shapeShapeIntersect(segmentTool, rawShape);

gp_Pnt pieceCentroid = findCentroid(intersect);
if (intersect.IsNull()) {
continue;
}
double faceAngle =
gp_Vec(getSectionCS().Direction().Reversed()).AngleWithRef(segmentNormal, rotateAxis);

Expand All @@ -402,7 +402,6 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
TopoDS_Shape pieceCentered = mkTransXLate.Shape();

//rotate the intersection so interesting face is aligned with paper plane
pieceCentroid = findCentroid(pieceCentered);
gp_Ax1 faceAxis(gp_Pnt(0.0, 0.0, 0.0), rotateAxis);
gp_Ax3 pieceCS;//XYZ tipped so face is aligned with sectionCS
pieceCS.Rotate(faceAxis, faceAngle);
Expand Down Expand Up @@ -516,7 +515,7 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
TopoDS_Compound
DrawComplexSection::findSectionPlaneIntersections(const TopoDS_Shape &shapeToIntersect)
{
// Base::Console().Message("DCS::findSectionPlaneIntersections() - %s\n", getNameInDocument());
// Base::Console().Message("DCS::findSectionPlaneIntersections() - %s\n", getNameInDocument());
if (shapeToIntersect.IsNull()) {
// this shouldn't happen
Base::Console().Warning("DCS::findSectionPlaneInter - %s - cut shape is Null\n",
Expand All @@ -527,7 +526,7 @@ DrawComplexSection::findSectionPlaneIntersections(const TopoDS_Shape &shapeToInt
return singleToolIntersections(shapeToIntersect);
}

return piecewiseToolIntersections(shapeToIntersect);
return alignedToolIntersections(shapeToIntersect);
}

//Intersect cutShape with each segment of the cutting tool
Expand Down Expand Up @@ -566,21 +565,21 @@ TopoDS_Compound DrawComplexSection::singleToolIntersections(const TopoDS_Shape &
}

//Intersect cutShape with the effective (flattened) cutting plane to generate cut surface faces
TopoDS_Compound DrawComplexSection::piecewiseToolIntersections(const TopoDS_Shape &cutShape)
TopoDS_Compound DrawComplexSection::alignedToolIntersections(const TopoDS_Shape &cutShape)
{
// Base::Console().Message("DCS::piecewiseToolIntersections()\n");
// Base::Console().Message("DCS::alignedToolIntersections()\n");
BRep_Builder builder;
TopoDS_Compound result;
builder.MakeCompound(result);

App::DocumentObject *toolObj = CuttingToolWireObject.getValue();
if (!isLinearProfile(toolObj)) {
//TODO: special handling here
// Base::Console().Message("DCS::pieceWiseToolIntersection - profile has curves\n");
// Base::Console().Message("DCS::alignedToolIntersection - profile has curves\n");
}

gp_Pln effectivePlane = getSectionPlane();
//piecewise result can be much wider than the shape itself, so we use an
//aligned result can be much wider than the shape itself, so we use an
//infinite face.
BRepBuilderAPI_MakeFace mkFace(effectivePlane, -Precision::Infinite(), Precision::Infinite(),
-Precision::Infinite(), Precision::Infinite());
Expand Down Expand Up @@ -1037,7 +1036,11 @@ TopoDS_Shape DrawComplexSection::shapeShapeIntersect(const TopoDS_Shape &shape0,
anOp.SetArguments(anArg1);
anOp.SetTools(anArg2);
anOp.Build();
return anOp.Shape();//always a compound
TopoDS_Shape result = anOp.Shape();//always a compound
if (isTrulyEmpty(result)) {
return TopoDS_Shape();
}
return result;
}

//find all the intersecting regions of face and shape
Expand Down Expand Up @@ -1162,6 +1165,17 @@ bool DrawComplexSection::isLinearProfile(App::DocumentObject *obj)
return false;
}

//a compound with no content is not considered IsNull by OCC. A more thorough check
//is required.
//https://dev.opencascade.org/content/compound-empty
bool DrawComplexSection::isTrulyEmpty(TopoDS_Shape inShape)
{
if (!inShape.IsNull() && TopoDS_Iterator(inShape).More()) {
return false;
}
return true;
}

// Python Drawing feature ---------------------------------------------------------

namespace App
Expand Down
3 changes: 2 additions & 1 deletion src/Mod/TechDraw/App/DrawComplexSection.h
Expand Up @@ -88,7 +88,7 @@ class TechDrawExport DrawComplexSection: public DrawViewSection
double extrudeDistance);
TopoDS_Shape distributeAlignedPieces(std::vector<TopoDS_Shape> pieces);
TopoDS_Compound singleToolIntersections(const TopoDS_Shape &cutShape);
TopoDS_Compound piecewiseToolIntersections(const TopoDS_Shape &cutShape);
TopoDS_Compound alignedToolIntersections(const TopoDS_Shape &cutShape);

BaseGeomPtrVector makeSectionLineGeometry();
std::pair<Base::Vector3d, Base::Vector3d> sectionArrowDirs();
Expand All @@ -106,6 +106,7 @@ class TechDrawExport DrawComplexSection: public DrawViewSection
static bool isProfileObject(App::DocumentObject *obj);
static bool isMultiSegmentProfile(App::DocumentObject *obj);
static bool isLinearProfile(App::DocumentObject *obj);
static bool isTrulyEmpty(TopoDS_Shape inShape);

private:
gp_Dir getFaceNormal(TopoDS_Face &face);
Expand Down

0 comments on commit 38f1906

Please sign in to comment.