Skip to content

Commit

Permalink
[TD]fix handling of perforated section faces
Browse files Browse the repository at this point in the history
  • Loading branch information
WandererFan committed Feb 2, 2023
1 parent d9afb06 commit bd25c86
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 30 deletions.
135 changes: 110 additions & 25 deletions src/Mod/TechDraw/App/DrawViewSection.cpp
Expand Up @@ -56,7 +56,8 @@
#include <BRepTools.hxx>
#include <BRep_Builder.hxx>
#include <Bnd_Box.hxx>
#include <QtConcurrentRun>
#include <ShapeAnalysis.hxx>
#include <ShapeFix_Shape.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
Expand All @@ -73,6 +74,8 @@
#include <sstream>
#endif

#include <QtConcurrent>

#include <App/Application.h>
#include <App/Document.h>
#include <Base/BoundBox.h>
Expand Down Expand Up @@ -400,18 +403,26 @@ void DrawViewSection::makeSectionCut(TopoDS_Shape& baseShape)
}

// perform cut
BRep_Builder builder;
TopoDS_Compound cutPieces;
builder.MakeCompound(cutPieces);
TopExp_Explorer expl(myShape, TopAbs_SOLID);
for (; expl.More(); expl.Next()) {
const TopoDS_Solid& s = TopoDS::Solid(expl.Current());
BRepAlgoAPI_Cut mkCut(s, m_cuttingTool);
if (!mkCut.IsDone()) {
Base::Console().Warning("DVS: Section cut has failed in %s\n", getNameInDocument());
continue;
}
builder.Add(cutPieces, mkCut.Shape());
// BRep_Builder builder;
// TopoDS_Compound cutPieces;
// builder.MakeCompound(cutPieces);
// TopExp_Explorer expl(myShape, TopAbs_SOLID);
// for (; expl.More(); expl.Next()) {
// const TopoDS_Solid& s = TopoDS::Solid(expl.Current());
// BRepAlgoAPI_Cut mkCut(s, m_cuttingTool);
// if (!mkCut.IsDone()) {
// Base::Console().Warning("DVS: Section cut has failed in %s\n", getNameInDocument());
// continue;
// }
// builder.Add(cutPieces, mkCut.Shape());
// }

TopoDS_Shape cutPieces = TopoDS_Shape();
BRepAlgoAPI_Cut mkCut(myShape, m_cuttingTool);
if (!mkCut.IsDone()) {
Base::Console().Warning("DVS: Section cut has failed in %s\n", getNameInDocument());
} else {
cutPieces = mkCut.Shape();
}

// cutPieces contains result of cutting each subshape in baseShape with tool
Expand Down Expand Up @@ -543,6 +554,9 @@ void DrawViewSection::postHlrTasks(void)
requestPaint();
return;
}
if (debugSection()) {
BRepTools::Write(faceIntersections, "DVSFaceIntersections.brep");//debug
}

TopoDS_Shape centeredFaces = TechDraw::moveShape(faceIntersections, m_saveCentroid * -1.0);

Expand Down Expand Up @@ -601,10 +615,10 @@ gp_Pln DrawViewSection::getSectionPlane() const
//! case is a compound of individual cuts) with the "effective" (flattened) section plane.
TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape)
{
// Base::Console().Message("DVS::findSectionPlaneIntersections() - %s\n", getNameInDocument());
// Base::Console().Message("DVS::findSectionPlaneIntersections() - %s\n", getNameInDocument());
if (shape.IsNull()) {
// this shouldn't happen
// Base::Console().Warning("DrawViewSection::findSectionPlaneInter - %s - input shape is Null\n", getNameInDocument());
Base::Console().Warning("DrawViewSection::findSectionPlaneInter - %s - input shape is Null\n", getNameInDocument());
return TopoDS_Compound();
}

Expand Down Expand Up @@ -637,7 +651,9 @@ TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shap
//move section faces to line up with cut shape
TopoDS_Compound DrawViewSection::alignSectionFaces(TopoDS_Shape faceIntersections)
{
// Base::Console().Message("DVS::alignSectionFaces()\n");
// Base::Console().Message("DVS::alignSectionFaces() - %s - faceIntersection.isnull: %d\n",
// getNameInDocument(),
// faceIntersections.IsNull());
TopoDS_Compound sectionFaces;
TopoDS_Shape centeredShape =
TechDraw::moveShape(faceIntersections, getOriginalCentroid() * -1.0);
Expand All @@ -657,7 +673,11 @@ TopoDS_Compound DrawViewSection::mapToPage(TopoDS_Shape& shapeToAlign)
// needs to be aligned to paper plane (origin, stdZ);
//project the faces in the shapeToAlign, build new faces from the resulting wires and
//combine everything into a compound of faces
// Base::Console().Message("DVS::mapToPage() - shapeToAlign.null: %d\n", shapeToAlign.IsNull());
// Base::Console().Message("DVS::mapToPage() - shapeToAlign.null: %d\n", shapeToAlign.IsNull());
if (debugSection()) {
BRepTools::Write(shapeToAlign, "DVSShapeToAlign.brep"); //debug
}

BRep_Builder builder;
TopoDS_Compound result;
builder.MakeCompound(result);
Expand All @@ -682,24 +702,89 @@ TopoDS_Compound DrawViewSection::mapToPage(TopoDS_Shape& shapeToAlign)
faceWires.push_back(cleanWire);
}

//first wire should be the outer boundary of the face
BRepBuilderAPI_MakeFace mkFace(faceWires.front());
int wireCount = faceWires.size();
for (int iWire = 1; iWire < wireCount; iWire++) {
//make holes in the face with the rest of the wires
mkFace.Add(faceWires.at(iWire));
//validate section face wires
std::vector<TopoDS_Wire> goodWires;
constexpr double minWireArea = 0.000001; //arbitrary very small face size
for (auto &wire : faceWires) {
if (wire.IsNull()) {
continue;
}
if (!BRep_Tool::IsClosed(wire)) {
continue; //can not make a face from open wire
}
double area = ShapeAnalysis::ContourArea(wire);
if (area <= minWireArea) {
continue; //can not make a face from wire with no area
}
goodWires.push_back(wire);
}
builder.Add(result, mkFace.Face());

if (goodWires.empty()) {
Base::Console().Warning("DVS::mapToPage - %s - section face has no valid wires.\n",
getNameInDocument());
continue;
}

TopoDS_Shape holeyShape = makeFaceFromWires(goodWires);
if (holeyShape.IsNull()) {
continue;
}

builder.Add(result, TopoDS::Face(holeyShape));
if (debugSection()) {
std::stringstream ss;
ss << "DVSFaceFromWires" << iFace << ".brep";
BRepTools::Write(mkFace.Face(), ss.str().c_str());//debug
BRepTools::Write(holeyShape, ss.str().c_str()); //debug
}
}

return result;
}

//makes a [perforated] face from an outer wire and wires describing the holes. Open wires
//and wires with zero area are assumed to already have been removed.
TopoDS_Shape DrawViewSection::makeFaceFromWires(std::vector<TopoDS_Wire> &inWires)
{
//make sure the largest wire is the first
EdgeWalker eWalker;
std::vector<TopoDS_Wire> goodWires = eWalker.sortWiresBySize(inWires);

// make a face from the good wires
//first good wire should be the outer boundary of the face
TopoDS_Face faceToFix;
TopoDS_Shape orientedShape = goodWires.at(0).Oriented(TopAbs_FORWARD);
TopoDS_Wire orientedWire = TopoDS::Wire(orientedShape);
orientedWire.Orientation(TopAbs_FORWARD);
TopoDS_Face blankFace = BRepBuilderAPI_MakeFace(orientedWire);
int wireCount = goodWires.size();
if (wireCount < 2) {
faceToFix = blankFace;
} else {
//add the holes
BRepBuilderAPI_MakeFace mkFace(blankFace);
for (int iWire = 1; iWire < wireCount; iWire++) {
//make holes in the face with the rest of the wires
orientedShape = goodWires.at(iWire).Oriented(TopAbs_REVERSED);
orientedWire = TopoDS::Wire(orientedShape);
mkFace.Add(orientedWire);
}

if (!mkFace.IsDone()) {
Base::Console().Warning("DVS::makeFaceFromWires - %s - failed to make section face.\n",
getNameInDocument());
return TopoDS_Shape();
}
faceToFix = mkFace.Face();
}

//setting the wire orientation above should generate a valid face, but sometimes
//does not, so we fix the shape to resolve any issues
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
sfs->Init(faceToFix);
sfs->Perform();
return sfs->Shape();
}

//turn OCC section faces into TD geometry
std::vector<TechDraw::FacePtr> DrawViewSection::makeTDSectionFaces(TopoDS_Compound topoDSFaces)
{
Expand Down
7 changes: 2 additions & 5 deletions src/Mod/TechDraw/App/DrawViewSection.h
Expand Up @@ -37,7 +37,6 @@

#include "DrawViewPart.h"


class Bnd_Box;
class gp_Pln;
class gp_Pnt;
Expand All @@ -48,10 +47,6 @@ class gp_Ax2;
namespace TechDraw
{
class Face;
}

namespace TechDraw
{
class DrawProjGroupItem;
class DrawGeomHatch;
class PATLineSpec;
Expand Down Expand Up @@ -171,6 +166,8 @@ class TechDrawExport DrawViewSection: public DrawViewPart

bool showSectionEdges(void);

TopoDS_Shape makeFaceFromWires(std::vector<TopoDS_Wire> &inWires);

public Q_SLOTS:
virtual void onSectionCutFinished(void);

Expand Down

0 comments on commit bd25c86

Please sign in to comment.