[TD]Improve section face display

This commit is contained in:
WandererFan
2020-05-30 22:08:50 -04:00
committed by wandererfan
parent 7fffe88433
commit 2db99798f6
9 changed files with 209 additions and 219 deletions

View File

@@ -31,10 +31,12 @@
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
//#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRep_Builder.hxx>
#include <BRepTools.hxx>
@@ -353,11 +355,13 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void)
void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
{
// cut base shape with tool
//is SectionOrigin valid?
Bnd_Box centerBox;
BRepBndLib::Add(baseShape, centerBox);
centerBox.SetGap(0.0);
// make tool
gp_Pln pln = getSectionPlane();
gp_Dir gpNormal = pln.Axis().Direction();
Base::Vector3d orgPnt = SectionOrigin.getValue();
@@ -381,6 +385,7 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
BRepBuilderAPI_Copy BuilderCopy(baseShape);
TopoDS_Shape myShape = BuilderCopy.Shape();
// perform cut
BRep_Builder builder;
TopoDS_Compound pieces;
builder.MakeCompound(pieces);
@@ -399,15 +404,16 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
builder.Add(pieces, cut);
outdb++;
}
// pieces contains result of cutting each subshape in baseShape with tool
TopoDS_Shape rawShape = pieces;
if (debugSection()) {
BRepTools::Write(myShape, "DVSCopy.brep"); //debug
BRepTools::Write(aProjFace, "DVSFace.brep"); //debug
BRepTools::Write(prism, "DVSTool.brep"); //debug
BRepTools::Write(rawShape, "DVSResult.brep"); //debug
BRepTools::Write(pieces, "DVSPieces.brep"); //debug
}
// check for error in cut
Bnd_Box testBox;
BRepBndLib::Add(rawShape, testBox);
testBox.SetGap(0.0);
@@ -416,6 +422,7 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
return;
}
// build display geometry as in DVP, with minor mods
gp_Ax2 viewAxis;
TopoDS_Shape centeredShape;
try {
@@ -452,16 +459,18 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
getNameInDocument(),e1.GetMessageString());
return;
}
//display geometry for cut shape is in geometryObject as in DVP
try {
// build section face geometry
// try {
//sectionFaces = build sectionFaces(rawShape);
TopoDS_Compound sectionCompound = findSectionPlaneIntersections(rawShape);
TopoDS_Compound faceIntersections = findSectionPlaneIntersections(rawShape);
Base::Vector3d sectionOrigin = SectionOrigin.getValue();
TopoDS_Shape centeredShape = TechDraw::moveShape(sectionCompound,
TopoDS_Shape centeredShapeF = TechDraw::moveShape(faceIntersections,
sectionOrigin * -1.0);
TopoDS_Shape scaledSection = TechDraw::scaleShape(centeredShape,
TopoDS_Shape scaledSection = TechDraw::scaleShape(centeredShapeF,
getScale());
if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) {
scaledSection = TechDraw::rotateShape(scaledSection,
@@ -471,54 +480,61 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
if (debugSection()) {
BRepTools::Write(scaledSection, "DVSScaledFaces.brep"); //debug
}
sectionFaceWires.clear();
TopoDS_Compound newFaces;
BRep_Builder builder;
builder.MakeCompound(newFaces);
TopExp_Explorer expl(scaledSection, TopAbs_FACE);
int idb = 0;
for (; expl.More(); expl.Next()) {
const TopoDS_Face& face = TopoDS::Face(expl.Current());
TopoDS_Face pFace = projectFace(face,
viewAxis);
if (!pFace.IsNull()) {
if (debugSection()) {
std::stringstream ss;
ss << "DVSScaledFace" << idb << ".brep" ;
std::string faceName = ss.str();
BRepTools::Write(pFace, faceName.c_str()); //debug
std::stringstream ss2;
ss2 << "DVSOuter" << idb << ".brep" ;
TopoDS_Wire owdb = ShapeAnalysis::OuterWire(pFace);
std::string wireName = ss2.str();
BRepTools::Write(owdb, wireName.c_str()); //debug
}
TopoDS_Wire ow = ShapeAnalysis::OuterWire(pFace);
//this check helps prevent "ghost" faces
BRepCheck_Wire chkWire(ow);
TopoDS_Edge e1, e2;
BRepCheck_Status status = chkWire.SelfIntersect(pFace, e1, e2);
if (status == BRepCheck_NoError) {
builder.Add(newFaces,pFace);
sectionFaceWires.push_back(ShapeAnalysis::OuterWire(pFace));
}
}
idb++;
// scaledSection is compound of TopoDS_Face intersections, but aligned to pln(origin, sectionNormal)
// needs to be aligned to pln (origin, stdZ);
gp_Ax3 R3;
gp_Ax2 projCS = getSectionCS();
gp_Ax3 proj3 = gp_Ax3(gp_Pnt(0.0, 0.0, 0.0),
projCS.Direction(),
projCS.XDirection());
gp_Trsf fromR3;
fromR3.SetTransformation(R3, proj3);
BRepBuilderAPI_Transform xformer(fromR3);
xformer.Perform(scaledSection, true);
if (xformer.IsDone()) {
sectionFaces = TopoDS::Compound(xformer.Shape());
// BRepTools::Write(sectionFaces, "DVSXFaces.brep"); //debug
} else {
Base::Console().Message("DVS::sectionExec - face xform failed\n");
}
//return newFaces;
sectionFaces = newFaces;
}
catch (Standard_Failure& e2) {
Base::Console().Warning("DVS::execute - failed to build section faces for %s - %s **\n",
getNameInDocument(),e2.GetMessageString());
return;
}
sectionFaces = TopoDS::Compound(GeometryObject::invertGeometry(sectionFaces)); //handle Qt -y
//turn section faces into something we can draw
tdSectionFaces.clear();
TopExp_Explorer sectionExpl(sectionFaces, TopAbs_FACE);
int iface = 0;
for (; sectionExpl.More(); sectionExpl.Next()) {
iface++;
const TopoDS_Face& face = TopoDS::Face(sectionExpl.Current());
TechDraw::Face* sectionFace = new TechDraw::Face();
TopExp_Explorer expFace(face, TopAbs_WIRE);
int iwire = 0;
for ( ; expFace.More(); expFace.Next()) {
iwire++;
TechDraw::Wire* w = new TechDraw::Wire();
const TopoDS_Wire& wire = TopoDS::Wire(expFace.Current());
int iedge = 0;
TopExp_Explorer expWire(wire, TopAbs_EDGE);
for ( ; expWire.More(); expWire.Next()) {
iedge++;
const TopoDS_Edge& edge = TopoDS::Edge(expWire.Current());
TechDraw::BaseGeom* e = BaseGeom::baseFactory(edge);
if (e != nullptr) {
w->geoms.push_back(e);
}
}
sectionFace->wires.push_back(w);
}
tdSectionFaces.push_back(sectionFace);
}
// add cosmetic entities to view
addCosmeticVertexesToGeom();
addCosmeticEdgesToGeom();
addCenterLinesToGeom();
// add landmark dim reference points to view
addReferencesToGeom();
}
@@ -561,123 +577,10 @@ TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shap
}
}
}
// BRepTools::Write(result, "DVSIntersect.brep"); //debug
return result;
}
//! get display geometry for Section faces
std::vector<TechDraw::Face*> DrawViewSection::getFaceGeometry()
{
std::vector<TechDraw::Face*> result;
TopoDS_Compound c = sectionFaces;
TopExp_Explorer faces(c, TopAbs_FACE);
for (; faces.More(); faces.Next()) {
TechDraw::Face* f = new TechDraw::Face();
const TopoDS_Face& face = TopoDS::Face(faces.Current());
TopExp_Explorer wires(face, TopAbs_WIRE);
for (; wires.More(); wires.Next()) {
TechDraw::Wire* w = new TechDraw::Wire();
const TopoDS_Wire& wire = TopoDS::Wire(wires.Current());
TopExp_Explorer edges(wire, TopAbs_EDGE);
for (; edges.More(); edges.Next()) {
const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
//dumpEdge("edge",edgeCount,edge);
TechDraw::BaseGeom* base = TechDraw::BaseGeom::baseFactory(edge);
w->geoms.push_back(base);
}
f->wires.push_back(w);
}
result.push_back(f);
}
return result;
}
//! project a single face using HLR - used for section faces
TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face,
const gp_Ax2 CS)
{
// Base::Console().Message("DVS::projectFace()\n");
if(face.IsNull()) {
throw Base::ValueError("DrawViewSection::projectFace - input Face is NULL");
}
TopoDS_Shape hardEdges = geometryObject->projectFace(face, CS);
std::vector<TopoDS_Edge> faceEdges;
TopExp_Explorer expl(hardEdges, TopAbs_EDGE);
int i;
for (i = 1 ; expl.More(); expl.Next(),i++) {
const TopoDS_Edge& edge = TopoDS::Edge(expl.Current());
if (edge.IsNull()) {
Base::Console().Log("INFO - DVS::projectFace - hard edge: %d is NULL\n",i);
continue;
}
faceEdges.push_back(edge);
}
//TODO: verify that outline edges aren't required
//if edge is both hard & outline, it will be duplicated? are hard edges enough?
// TopExp_Explorer expl2(outEdges, TopAbs_EDGE);
// for (i = 1 ; expl2.More(); expl2.Next(),i++) {
// const TopoDS_Edge& edge = TopoDS::Edge(expl2.Current());
// if (edge.IsNull()) {
// Base::Console().Log("INFO - GO::projectFace - outline edge: %d is NULL\n",i);
// continue;
// }
// bool addEdge = true;
// //is edge already in faceEdges? maybe need to use explorer for this for IsSame to work?
// for (auto& e:faceEdges) {
// if (e.IsPartner(edge)) {
// addEdge = false;
// Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 1\n");
// }
// }
// expl.ReInit();
// for (; expl.More(); expl.Next()){
// const TopoDS_Edge& eHard = TopoDS::Edge(expl.Current());
// if (eHard.IsPartner(edge)) {
// addEdge = false;
// Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 2\n");
// }
// }
// if (addEdge) {
// faceEdges.push_back(edge);
// }
// }
TopoDS_Face projectedFace;
if (faceEdges.empty()) {
Base::Console().Log("LOG - DVS::projectFace - no faceEdges\n");
return projectedFace;
}
//recreate the wires for this single face
EdgeWalker ew;
ew.loadEdges(faceEdges);
bool success = ew.perform();
if (success) {
std::vector<TopoDS_Wire> fw = ew.getResultNoDups();
if (!fw.empty()) {
std::vector<TopoDS_Wire> sortedWires = ew.sortStrip(fw, true);
if (sortedWires.empty()) {
return projectedFace;
}
BRepBuilderAPI_MakeFace mkFace(sortedWires.front(),true); //true => only want planes?
std::vector<TopoDS_Wire>::iterator itWire = ++sortedWires.begin(); //starting with second face
for (; itWire != sortedWires.end(); itWire++) {
mkFace.Add(*itWire);
}
projectedFace = mkFace.Face();
}
} else {
Base::Console().Warning("DVS::projectFace - input is not planar graph. No face detection\n");
}
return projectedFace;
}
//calculate the ends of the section line in BaseView's coords
std::pair<Base::Vector3d, Base::Vector3d> DrawViewSection::sectionLineEnds(void)
{
@@ -873,14 +776,22 @@ std::vector<LineSet> DrawViewSection::getDrawableLines(int i)
{
// Base::Console().Message("DVS::getDrawableLines(%d) - lineSets: %d\n", i, m_lineSets.size());
std::vector<LineSet> result;
result = DrawGeomHatch::getTrimmedLines(this,m_lineSets,i,HatchScale.getValue());
result = DrawGeomHatch::getTrimmedLinesSection(this,m_lineSets,
getSectionTFace(i),
HatchScale.getValue());
return result;
}
std::vector<TopoDS_Wire> DrawViewSection::getWireForFace(int idx) const
TopoDS_Face DrawViewSection::getSectionTFace(int i)
{
std::vector<TopoDS_Wire> result;
result.push_back(sectionFaceWires.at(idx));
TopoDS_Face result;
TopExp_Explorer expl(sectionFaces, TopAbs_FACE);
int count = 1;
for (; expl.More(); expl.Next(), count++) {
if (count == i+1) {
result = TopoDS::Face(expl.Current());
}
}
return result;
}