diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 784ecef82..84f776291 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -28,6 +28,7 @@ # include #endif +#include #include #include @@ -53,6 +54,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include @@ -130,10 +137,12 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) getValidXDir()); TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(shape, inputCenter, - //Direction.getValue(), - //getValidXDir(), Scale.getValue()); buildGeometryObject(mirroredShape,inputCenter); +#if MOD_TECHDRAW_HANDLE_FACES + extractFaces(); +#endif //#if MOD_TECHDRAW_HANDLE_FACES + } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); @@ -223,6 +232,32 @@ void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter) bbox = geometryObject->calcBoundingBox(); } +//! make faces from the existing edge geometry +void DrawViewPart::extractFaces() +{ + geometryObject->clearFaceGeom(); + const std::vector& goEdges = geometryObject->getEdgeGeometry(); + std::vector::const_iterator itEdge = goEdges.begin(); + std::vector occEdges; + for (;itEdge != goEdges.end(); itEdge++) { + occEdges.push_back((*itEdge)->occEdge); + } + + //almost works. :( + std::vector wires = connectEdges(occEdges); + std::vector sortedWires = sortWiresBySize(wires,true); //smallest first + + std::vector::iterator itWire = sortedWires.begin(); + for (; itWire != sortedWires.end(); itWire++) { + //version 1: 1 wire/face - no voids in face + TechDrawGeometry::Face* f = new TechDrawGeometry::Face(); + const TopoDS_Wire& wire = (*itWire); + TechDrawGeometry::Wire* w = new TechDrawGeometry::Wire(wire); + f->wires.push_back(w); + geometryObject->addFaceGeom(f); + } +} + std::vector DrawViewPart::getHatches() const { std::vector result; @@ -425,6 +460,65 @@ Base::BoundBox3d DrawViewPart::getBoundingBox() const return bbox; } +//! build 1 or more wires from list of edges +//note disjoint edges won't be connected. have to be able to traverse all the edges +std::vector DrawViewPart::connectEdges (std::vector& edges) +{ + std::vector result; + Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); + Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); + std::vector::const_iterator itEdge = edges.begin(); + for (; itEdge != edges.end(); itEdge++) + hEdges->Append(*itEdge); + + //tolerance sb tolerance of DrawViewPart instead of Precision::Confusion()? + ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_False, hWires); + + int len = hWires->Length(); + for(int i=1;i<=len;i++) { + TopoDS_Wire w = TopoDS::Wire(hWires->Value(i)); + //if (BRep_Tool::IsClosed(w)) { + result.push_back(w); + //} + } + //delete hEdges; //does Handle<> take care of this? + //delete hWires; + return result; +} + +//! return true if w1 bbox is bigger than w2 bbox +class DrawViewPart::wireCompare: public std::binary_function +{ +public: + bool operator() (const TopoDS_Wire& w1, const TopoDS_Wire& w2) + { + Bnd_Box box1, box2; + if (!w1.IsNull()) { + BRepBndLib::Add(w1, box1); + box1.SetGap(0.0); + } + + if (!w2.IsNull()) { + BRepBndLib::Add(w2, box2); + box2.SetGap(0.0); + } + + return box1.SquareExtent() > box2.SquareExtent(); + } +}; + +//sort wires in descending order of bbox diagonal. if reversed, then ascending bbox diagonal +std::vector DrawViewPart::sortWiresBySize(std::vector& w, bool reverse) +{ + std::vector wires = w; + std::sort(wires.begin(), wires.end(), wireCompare()); + if (reverse) { + std::reverse(wires.begin(),wires.end()); + } + return wires; +} + bool DrawViewPart::hasGeometry(void) const { bool result = false; diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 024a01c22..2bc0b95e7 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -109,11 +109,16 @@ public: void dumpVertexes(const char* text, const TopoDS_Shape& s); protected: + TechDrawGeometry::GeometryObject *geometryObject; + Base::BoundBox3d bbox; + void onChanged(const App::Property* prop); Base::Vector3d getValidXDir() const; void buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center); - TechDrawGeometry::GeometryObject *geometryObject; - Base::BoundBox3d bbox; + void extractFaces(); + std::vector connectEdges (std::vector& edges); + std::vector sortWiresBySize(std::vector& w, bool reverse = false); + class wireCompare; private: static App::PropertyFloatConstraint::Constraints floatRange; diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index 0e9c19dbb..2e101d615 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -351,7 +351,7 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, for (i = 1 ; expl.More(); expl.Next(),i++) { const TopoDS_Edge& edge = TopoDS::Edge(expl.Current()); if (edge.IsNull()) { - Base::Console().Log("INFO - GO::addGeomFromCompound - hard edge: %d is NULL\n",i); + Base::Console().Log("INFO - GO::projectFace - hard edge: %d is NULL\n",i); continue; } faceEdges.push_back(edge); @@ -360,7 +360,7 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, for (i = 1 ; expl.More(); expl.Next(),i++) { const TopoDS_Edge& edge = TopoDS::Edge(expl.Current()); if (edge.IsNull()) { - Base::Console().Log("INFO - GO::addGeomFromCompound - outline edge: %d is NULL\n",i); + Base::Console().Log("INFO - GO::projectFace - outline edge: %d is NULL\n",i); continue; } faceEdges.push_back(edge); @@ -368,9 +368,9 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, //no guarantee HLR gives edges in any particular order, so have to build back into a face. TopoDS_Face projectedFace; - std::vector faceWires = DrawViewSection::connectEdges(faceEdges); + std::vector faceWires = connectEdges(faceEdges); //from DrawViewPart if (!faceWires.empty()) { - std::vector sortedWires = sortWiresBySize(faceWires); + std::vector sortedWires = sortWiresBySize(faceWires); //from DrawViewPart if (sortedWires.empty()) { return projectedFace; } @@ -384,58 +384,6 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, return projectedFace; } -//! connect edges into 1 or more wires -std::vector DrawViewSection::connectEdges (std::vector& edges) -{ - std::vector result; - Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); - Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); - std::vector::const_iterator itEdge = edges.begin(); - for (; itEdge != edges.end(); itEdge++) - hEdges->Append(*itEdge); - - //tolerance sb tolerance of DrawViewSection instead of Precision::Confusion()? - ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_False, hWires); - - int len = hWires->Length(); - for(int i=1;i<=len;i++) { - result.push_back(TopoDS::Wire(hWires->Value(i))); - } - //delete hEdges; //does Handle<> take care of this? - //delete hWires; - return result; -} - -//! return true if w1 bbox is bigger than w2 bbox -class DrawViewSection::wireCompare: public std::binary_function -{ -public: - bool operator() (const TopoDS_Wire& w1, const TopoDS_Wire& w2) - { - Bnd_Box box1, box2; - if (!w1.IsNull()) { - BRepBndLib::Add(w1, box1); - box1.SetGap(0.0); - } - - if (!w2.IsNull()) { - BRepBndLib::Add(w2, box2); - box2.SetGap(0.0); - } - - return box1.SquareExtent() > box2.SquareExtent(); - } -}; - -//sort wires in descending order of size (bbox diagonal) -std::vector DrawViewSection::sortWiresBySize(std::vector& w) -{ - std::vector wires = w; - std::sort(wires.begin(), wires.end(), wireCompare()); - return wires; -} - // Python Drawing feature --------------------------------------------------------- diff --git a/src/Mod/TechDraw/App/DrawViewSection.h b/src/Mod/TechDraw/App/DrawViewSection.h index 6410972d0..4bd8967fa 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.h +++ b/src/Mod/TechDraw/App/DrawViewSection.h @@ -73,17 +73,14 @@ public: std::vector getFaceGeometry(); protected: - TopoDS_Shape sectionShape; //obs?? + TopoDS_Compound sectionFaces; + gp_Pln getSectionPlane() const; TopoDS_Compound findSectionPlaneIntersections(const TopoDS_Shape& shape); TopoDS_Face projectFace(const TopoDS_Shape &face, gp_Pnt faceCenter, const Base::Vector3d &direction, const Base::Vector3d &xaxis); - std::vector connectEdges (std::vector& edges); - std::vector sortWiresBySize(std::vector& w); - TopoDS_Compound sectionFaces; - class wireCompare; }; typedef App::FeaturePythonT DrawViewSectionPython; diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp index e8490b354..dde027eff 100644 --- a/src/Mod/TechDraw/App/Geometry.cpp +++ b/src/Mod/TechDraw/App/Geometry.cpp @@ -82,6 +82,16 @@ using namespace TechDrawGeometry; // Collection of Geometric Features Wire::Wire() { +} + +Wire::Wire(const TopoDS_Wire &w) +{ + TopExp_Explorer edges(w, TopAbs_EDGE); + for (; edges.More(); edges.Next()) { + const TopoDS_Edge& edge = TopoDS::Edge(edges.Current()); + TechDrawGeometry::BaseGeom* base = TechDrawGeometry::BaseGeom::baseFactory(edge); + geoms.push_back(base); + } } @@ -396,11 +406,11 @@ bool Vertex::isEqual(Vertex* v, double tol) extern "C" { //! return a vector of BaseGeom*'s in tail to nose order +//could/should this be replaced by DVP::connectEdges? std::vector TechDrawExport chainGeoms(std::vector geoms) { std::vector result; std::vector used(geoms.size(),false); - double tolerance = 0.0; if (geoms.empty()) { return result; @@ -413,7 +423,7 @@ std::vector TechDrawExport chainGeoms(std::vectorgetEndPoint(); used[0] = true; for (unsigned int i = 1; i < geoms.size(); i++) { //do size-1 more edges - getNextReturnVal next = nextGeom(atPoint,geoms,used,tolerance); + getNextReturnVal next = nextGeom(atPoint,geoms,used,Precision::Confusion()); if (next.index) { //found an unused edge with vertex == atPoint TechDrawGeometry::BaseGeom* nextEdge = geoms.at(next.index); used[next.index] = true; @@ -446,11 +456,11 @@ getNextReturnVal TechDrawExport nextGeom(Base::Vector2D atPoint, if (used[index]) { continue; } - if (atPoint == (*itGeom)->getStartPoint()) { + if ((atPoint - (*itGeom)->getStartPoint()).Length() < tolerance) { result.index = index; result.reversed = false; break; - } else if (atPoint == (*itGeom)->getEndPoint()) { + } else if ((atPoint - (*itGeom)->getEndPoint()).Length() < tolerance) { result.index = index; result.reversed = true; break; diff --git a/src/Mod/TechDraw/App/Geometry.h b/src/Mod/TechDraw/App/Geometry.h index 626d8dcd8..d95512ca6 100644 --- a/src/Mod/TechDraw/App/Geometry.h +++ b/src/Mod/TechDraw/App/Geometry.h @@ -27,6 +27,7 @@ #include #include #include +#include class BRepAdaptor_Curve; @@ -180,6 +181,7 @@ class TechDrawExport Wire { public: Wire(); + Wire(const TopoDS_Wire &w); ~Wire(); std::vector geoms; }; diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index ab2376503..7f814a380 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -332,7 +332,17 @@ void GeometryObject::update3DRefs() { } +//! empty Face geometry +void GeometryObject::clearFaceGeom() +{ + faceGeom.clear(); +} +//! add a Face to Face Geometry +void GeometryObject::addFaceGeom(Face* f) +{ + faceGeom.push_back(f); +} /////////////// bbox routines @@ -667,54 +677,6 @@ TechDrawGeometry::Vertex * GeometryObject::projectVertex(const TopoDS_Shape &ver #endif } -//!only used by DrawViewSection, but code is #if 0, so obs? -//don't need anything projected. DVS already has Compound of section faces. just need to turn those into -// BaseGeom::Face with tag for shading? like addGeomFromCompound without verts -void GeometryObject::projectSurfaces(const TopoDS_Shape &face, - const TopoDS_Shape &support, - const Base::Vector3d &direction, - const Base::Vector3d &xaxis, - std::vector &projFaces) const -{ - if(face.IsNull()) { - throw Base::Exception("Projected shape is null"); - return; - } -#if 0 - gp_Pnt supportCentre = findCentroid(support, direction, xaxis); - - // TODO: We used to invert Y twice here, make sure that wasn't intentional - gp_Trsf mat; - mat.SetMirror(gp_Ax2(supportCentre, gp_Dir(0, 1, 0))); - gp_Trsf matScale; - matScale.SetScale(supportCentre, Scale); - mat.Multiply(matScale); - - BRepBuilderAPI_Transform mkTrfScale(face, mat); - - gp_Ax2 transform; - transform = gp_Ax2(supportCentre, - gp_Dir(direction.x, direction.y, direction.z), - gp_Dir(xaxis.x, xaxis.y, xaxis.z)); - - HLRBRep_Algo *brep_hlr = new HLRBRep_Algo(); - brep_hlr->Add(mkTrfScale.Shape()); - - HLRAlgo_Projector projector( transform ); - brep_hlr->Projector(projector); - brep_hlr->Update(); - brep_hlr->Hide(); - - Base::Console().Log("GeometryObject::projectSurfaces - projecting face\n"); - - // Extract Faces - std::vector projFaceRefs; - - extractFaces(brep_hlr, mkTrfScale.Shape(), true, WithSmooth, projFaces, projFaceRefs); - delete brep_hlr; -#endif -} - //! only ever called from fvp::getCompleteEdge which is only ever called from CmdCreateDim for true dims. so obs? TechDrawGeometry::BaseGeom * GeometryObject::projectEdge(const TopoDS_Shape &edge, const TopoDS_Shape &support, diff --git a/src/Mod/TechDraw/App/GeometryObject.h b/src/Mod/TechDraw/App/GeometryObject.h index dfe83f7fa..25010049f 100644 --- a/src/Mod/TechDraw/App/GeometryObject.h +++ b/src/Mod/TechDraw/App/GeometryObject.h @@ -78,11 +78,6 @@ public: const std::vector & getFaceRefs() const { return faceReferences; }; //begin obs? - void projectSurfaces(const TopoDS_Shape &face, - const TopoDS_Shape &support, - const Base::Vector3d &direction, - const Base::Vector3d &xaxis, - std::vector &result) const; BaseGeom* projectEdge(const TopoDS_Shape &edge, const TopoDS_Shape &support, const Base::Vector3d &direction, @@ -99,6 +94,8 @@ public: const Base::Vector3d &xAxis); void extractGeometry(edgeClass category, bool visible); void update3DRefs(); + void addFaceGeom(Face * f); + void clearFaceGeom(); protected: //HLR output diff --git a/src/Mod/TechDraw/Gui/QGIFace.cpp b/src/Mod/TechDraw/Gui/QGIFace.cpp index 3ea966522..cdd7a9a33 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.cpp +++ b/src/Mod/TechDraw/Gui/QGIFace.cpp @@ -45,9 +45,9 @@ using namespace TechDrawGui; QGIFace::QGIFace(int ref) : reference(ref), - //m_fill(Qt::NoBrush) + m_fill(Qt::NoBrush) //m_fill(Qt::CrossPattern) - m_fill(Qt::Dense3Pattern) + //m_fill(Qt::Dense3Pattern) //m_fill(Qt::Dense6Pattern) { setCacheMode(QGraphicsItem::NoCache); @@ -63,7 +63,7 @@ QGIFace::QGIFace(int ref) : m_colPre = fcColor.asQColor(); //m_pen.setStyle(Qt::NoPen); - m_brush.setStyle(m_fill); + //m_brush.setStyle(m_fill); setPrettyNormal(); } @@ -95,23 +95,23 @@ void QGIFace::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) void QGIFace::setPrettyNormal() { m_pen.setColor(m_colNormal); - m_brush.setColor(m_colNormal); + //m_brush.setColor(m_colNormal); setPen(m_pen); - setBrush(m_brush); + //setBrush(m_brush); } void QGIFace::setPrettyPre() { m_pen.setColor(m_colPre); - m_brush.setColor(m_colPre); + //m_brush.setColor(m_colPre); setPen(m_pen); - setBrush(m_brush); + //setBrush(m_brush); } void QGIFace::setPrettySel() { m_pen.setColor(m_colSel); - m_brush.setColor(m_colSel); + //m_brush.setColor(m_colSel); setPen(m_pen); - setBrush(m_brush); + //setBrush(m_brush); } void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { @@ -119,8 +119,7 @@ void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * optio //myOption.state &= ~QStyle::State_Selected; //temp for debugging //m_pen.setColor(m_colCurrent); - setPen(m_pen); - setBrush(m_brush); + //setPen(m_pen); + //setBrush(m_brush); QGraphicsPathItem::paint (painter, &myOption, widget); } - diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 753c0fe09..0846ca5b2 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -287,12 +287,13 @@ void QGIViewPart::drawViewPart() prepareGeometryChange(); +#if MOD_TECHDRAW_HANDLE_FACES // Draw Faces const std::vector &faceGeoms = viewPart->getFaceGeometry(); std::vector::const_iterator fit = faceGeoms.begin(); QPen facePen; facePen.setCosmetic(true); - QBrush faceBrush; + //QBrush faceBrush; for(int i = 0 ; fit != faceGeoms.end(); fit++, i++) { QGIFace* newFace = drawFace(*fit); newFace->setPen(facePen); @@ -303,6 +304,7 @@ void QGIViewPart::drawViewPart() //std::stringstream faceId; //faceId << "facePath" << i; //_dumpPath(faceId.str().c_str(),facePath); +#endif //#if MOD_TECHDRAW_HANDLE_FACES // Draw Hatches std::vector hatchObjs = viewPart->getHatches(); @@ -433,7 +435,7 @@ QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f) addToGroup(gFace); gFace->setPos(0.0,0.0); gFace->setPath(facePath); - _dumpPath("QGIVP.facePath",facePath); + //_dumpPath("QGIVP.facePath",facePath); //gFace->setFlag(QGraphicsItem::ItemIsSelectable, true); ??? return gFace; diff --git a/src/Mod/TechDraw/Gui/QGIViewSection.cpp b/src/Mod/TechDraw/Gui/QGIViewSection.cpp index 192568601..f49d45b8c 100644 --- a/src/Mod/TechDraw/Gui/QGIViewSection.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewSection.cpp @@ -83,11 +83,12 @@ void QGIViewSection::drawSectionFace() std::vector::iterator fit = sectionFaces.begin(); QPen facePen; facePen.setCosmetic(true); - //QBrush faceBrush; QBrush faceBrush(QBrush(QColor(0,0,255,40))); //temp. sb preference or property. for(; fit != sectionFaces.end(); fit++) { QGIFace* newFace = drawFace(*fit); newFace->setZValue(ZVALUE::SECTIONFACE); + newFace->setBrush(faceBrush); + newFace->setPen(facePen); //newFace->setEyeCandy() } }