diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index 0d09dac8b..784ecef82 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -76,8 +76,6 @@ using namespace std; // DrawViewPart //=========================================================================== -Base::Vector3d _getValidXDir(const DrawViewPart *me); - App::PropertyFloatConstraint::Constraints DrawViewPart::floatRange = {0.01f,5.0f,0.05f}; PROPERTY_SOURCE(TechDraw::DrawViewPart, TechDraw::DrawView) @@ -124,8 +122,18 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) return new App::DocumentObjectExecReturn("FVP - Linked shape object is empty"); } + geometryObject->setTolerance(Tolerance.getValue()); + geometryObject->setScale(Scale.getValue()); try { - buildGeometryObject(shape); + gp_Pnt inputCenter = TechDrawGeometry::findCentroid(shape, + Direction.getValue(), + getValidXDir()); + TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(shape, + inputCenter, + //Direction.getValue(), + //getValidXDir(), + Scale.getValue()); + buildGeometryObject(mirroredShape,inputCenter); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); @@ -184,13 +192,12 @@ void DrawViewPart::onChanged(const App::Property* prop) //TODO: when scale changes, any Dimensions for this View sb recalculated. (might happen anyway if document is recomputed?) } -void DrawViewPart::buildGeometryObject(TopoDS_Shape shape) +void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter) { - geometryObject->setTolerance(Tolerance.getValue()); - geometryObject->setScale(Scale.getValue()); - geometryObject->initHLR(shape, + geometryObject->projectShape(shape, + inputCenter, Direction.getValue(), - _getValidXDir(this)); + getValidXDir()); geometryObject->extractGeometry(TechDrawGeometry::ecHARD, true); geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE, @@ -281,7 +288,7 @@ TechDrawGeometry::BaseGeom *DrawViewPart::getCompleteEdge(int idx) const TechDrawGeometry::BaseGeom* prjShape = 0; try { - prjShape = geometryObject->projectEdge(shape, support, Direction.getValue(), _getValidXDir(this)); + prjShape = geometryObject->projectEdge(shape, support, Direction.getValue(), getValidXDir()); } catch(Standard_Failure) { Base::Console().Error("getCompleteEdge - OCC Error - could not project Edge: %d\n",idx); @@ -315,7 +322,7 @@ TechDrawGeometry::Vertex * DrawViewPart::getVertex(int idx) const const TopoDS_Shape &support = static_cast(link)->Shape.getValue(); //TODO: Make sure prjShape gets deleted - TechDrawGeometry::Vertex *prjShape = geometryObject->projectVertex(shape, support, Direction.getValue(), _getValidXDir(this)); + TechDrawGeometry::Vertex *prjShape = geometryObject->projectVertex(shape, support, Direction.getValue(), getValidXDir()); //Base::Console().Log("vert %f, %f \n", prjShape->pnt.fX, prjShape->pnt.fY); return prjShape; } @@ -432,9 +439,9 @@ bool DrawViewPart::hasGeometry(void) const return result; } -Base::Vector3d _getValidXDir(const DrawViewPart *me) +Base::Vector3d DrawViewPart::getValidXDir() const { - Base::Vector3d xDir = me->XAxisDirection.getValue(); + Base::Vector3d xDir = XAxisDirection.getValue(); if (xDir.Length() == 0) { Base::Console().Warning("XAxisDirection has zero length - using (1,0,0)\n"); xDir = Base::Vector3d(1.0,0.0,0.0); @@ -453,6 +460,18 @@ void DrawViewPart::dumpVertexRefs(char* text) const } } +void DrawViewPart::dumpVertexes(const char* text, const TopoDS_Shape& s) +{ + Base::Console().Message("DUMP - %s\n",text); + TopExp_Explorer expl(s, TopAbs_VERTEX); + int i; + for (i = 1 ; expl.More(); expl.Next(),i++) { + const TopoDS_Vertex& v = TopoDS::Vertex(expl.Current()); + gp_Pnt pnt = BRep_Tool::Pnt(v); + Base::Console().Message("v%d: (%.3f,%.3f,%.3f)\n",i,pnt.X(),pnt.Y(),pnt.Z()); + } +} + PyObject *DrawViewPart::getPyObject(void) { if (PythonObject.is(Py::_None())) { diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 75edccee9..024a01c22 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -106,10 +106,12 @@ public: virtual PyObject *getPyObject(void); void dumpVertexRefs(char* text) const; + void dumpVertexes(const char* text, const TopoDS_Shape& s); protected: void onChanged(const App::Property* prop); - void buildGeometryObject(TopoDS_Shape shape); + Base::Vector3d getValidXDir() const; + void buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center); TechDrawGeometry::GeometryObject *geometryObject; Base::BoundBox3d bbox; diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index 09c843aa4..0e9c19dbb 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -31,6 +31,14 @@ #include #include #include + +#include +#include +#include +#include +#include +#include + //#include #include #include @@ -145,7 +153,7 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) return new App::DocumentObjectExecReturn("Section Plane doesn't intersect part"); } - bb.Enlarge(1.0); // Enlarge the bounding box to prevent any clipping + //bb.Enlarge(1.0); // Enlarge the bounding box to prevent any clipping // Gather the points std::vector pnts; @@ -200,41 +208,48 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) TopoDS_Shape myShape = BuilderCopy.Shape(); BRepAlgoAPI_Cut mkCut(myShape, prism); - // Let's check if the fusion has been successful if (!mkCut.IsDone()) return new App::DocumentObjectExecReturn("Section cut has failed"); - // Cache the sectionShape - sectionShape = mkCut.Shape(); + TopoDS_Shape rawShape = mkCut.Shape(); + geometryObject->setTolerance(Tolerance.getValue()); + geometryObject->setScale(Scale.getValue()); try { - buildGeometryObject(sectionShape); + gp_Pnt inputCenter = TechDrawGeometry::findCentroid(rawShape, + Direction.getValue(), + getValidXDir()); + TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape, + inputCenter, + Scale.getValue()); + buildGeometryObject(mirroredShape,inputCenter); + + TopoDS_Compound sectionCompound = findSectionPlaneIntersections(rawShape); + TopoDS_Shape mirroredSection = TechDrawGeometry::mirrorShape(sectionCompound, + inputCenter, + Scale.getValue()); + TopoDS_Compound newFaces; + BRep_Builder builder; + builder.MakeCompound(newFaces); + TopExp_Explorer expl(mirroredSection, TopAbs_FACE); + for (int i = 1 ; expl.More(); expl.Next(),i++) { + const TopoDS_Face& face = TopoDS::Face(expl.Current()); + TopoDS_Face pFace = projectFace(face, + inputCenter, + Direction.getValue(), + getValidXDir()); + builder.Add(newFaces,pFace); + } + sectionFaces = newFaces; } catch (Standard_Failure) { Handle_Standard_Failure e1 = Standard_Failure::Caught(); - Base::Console().Log("DrawViewSection::execute - extractGeometry failed: %s\n",e1->GetMessageString()); + Base::Console().Log("DrawViewSection::execute - building Section shape failed: %s\n",e1->GetMessageString()); return new App::DocumentObjectExecReturn(e1->GetMessageString()); } - TopoDS_Compound sectionFaces; - try { - sectionFaces = getSectionFaces(); - } - catch (Standard_Failure) { - Handle_Standard_Failure e2 = Standard_Failure::Caught(); - Base::Console().Log("DrawViewSection::execute - getSectionFaces failed: %s\n",e2->GetMessageString()); - return new App::DocumentObjectExecReturn(e2->GetMessageString()); - } - - if (!sectionFaces.IsNull()) { - //TODO: do something with sectionFaces - //?add to GeometryObject faceGeom? but need to tag these faces as "special" - //how does QGIVSection know to shade these faces?? - } - - // TODO: touch references? see DrawViewPart.execute() touch(); - return DrawView::execute(); //note: not DrawViewPart + return DrawView::execute(); } gp_Pln DrawViewSection::getSectionPlane() const @@ -245,29 +260,29 @@ gp_Pln DrawViewSection::getSectionPlane() const return gp_Pln(gp_Pnt(plnPnt.x, plnPnt.y, plnPnt.z), gp_Dir(plnNorm.x, plnNorm.y, plnNorm.z)); } -//! tries to find the intersection of the section plane with the sectionShape (a collection of planar faces) -TopoDS_Compound DrawViewSection::getSectionFaces(void) +//! tries to find the intersection of the section plane with the shape giving a collection of planar faces +TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape) { TopoDS_Compound result; - if(sectionShape.IsNull()){ - //throw Base::Exception("Sectional View sectionShape is Empty"); - Base::Console().Log("DrawViewSection::getSectionSurface - Sectional View sectionShape is Empty\n"); + if(shape.IsNull()){ + Base::Console().Log("DrawViewSection::getSectionSurface - Sectional View shape is Empty\n"); return result; } - gp_Pln pln = getSectionPlane(); + gp_Pln plnSection = getSectionPlane(); BRep_Builder builder; builder.MakeCompound(result); - // Iterate through all faces - TopExp_Explorer expFaces(sectionShape, TopAbs_FACE); - for ( ; expFaces.More(); expFaces.Next()) { + TopExp_Explorer expFaces(shape, TopAbs_FACE); + int i; + for (i = 1 ; expFaces.More(); expFaces.Next(), i++) { const TopoDS_Face& face = TopoDS::Face(expFaces.Current()); - BRepAdaptor_Surface adapt(face); if (adapt.GetType() == GeomAbs_Plane){ - gp_Pln plane = adapt.Plane(); - if(plane.Contains(pln.Location(), Precision::Confusion()) && plane.Axis().IsParallel(pln.Axis(), Precision::Angular())) { + gp_Pln plnFace = adapt.Plane(); + + if(plnSection.Contains(plnFace.Location(), Precision::Confusion()) && + plnFace.Axis().IsParallel(plnSection.Axis(), Precision::Angular())) { builder.Add(result, face); } } @@ -275,6 +290,152 @@ TopoDS_Compound DrawViewSection::getSectionFaces(void) return result; } +//! get display geometry for Section faces +std::vector DrawViewSection::getFaceGeometry() +{ + std::vector result; + //TopoDS_Compound c = getSectionFaces(); //get projected section faces? + TopoDS_Compound c = sectionFaces; + //for face in c + TopExp_Explorer faces(c, TopAbs_FACE); + for (; faces.More(); faces.Next()) { + TechDrawGeometry::Face* f = new TechDrawGeometry::Face(); + const TopoDS_Face& face = TopoDS::Face(faces.Current()); + TopExp_Explorer wires(face, TopAbs_WIRE); + for (; wires.More(); wires.Next()) { + TechDrawGeometry::Wire* w = new TechDrawGeometry::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()); + TechDrawGeometry::BaseGeom* base = TechDrawGeometry::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 +TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, + gp_Pnt faceCenter, + const Base::Vector3d &direction, + const Base::Vector3d &xaxis) +{ + if(face.IsNull()) { + throw Base::Exception("DrawViewSection::projectFace - input Face is NULL"); + return TopoDS_Face(); + } + + gp_Ax2 transform; + transform = gp_Ax2(faceCenter, + 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(face); + + HLRAlgo_Projector projector( transform ); + brep_hlr->Projector(projector); + brep_hlr->Update(); + brep_hlr->Hide(); + + HLRBRep_HLRToShape hlrToShape(brep_hlr); + TopoDS_Shape hardEdges = hlrToShape.VCompound(); + TopoDS_Shape outEdges = hlrToShape.OutLineVCompound(); + std::vector 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 - GO::addGeomFromCompound - hard edge: %d is NULL\n",i); + continue; + } + faceEdges.push_back(edge); + } + expl.Init(outEdges, TopAbs_EDGE); + 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); + continue; + } + faceEdges.push_back(edge); + } + + //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); + if (!faceWires.empty()) { + std::vector sortedWires = sortWiresBySize(faceWires); + if (sortedWires.empty()) { + return projectedFace; + } + BRepBuilderAPI_MakeFace mkFace(sortedWires.front(),true); //true => only want planes? + std::vector::iterator itWire = (sortedWires.begin()) + 1; //starting with second face + for (; itWire != sortedWires.end(); itWire++) { + mkFace.Add(*itWire); + } + projectedFace = mkFace.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 12d7e763c..6410972d0 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.h +++ b/src/Mod/TechDraw/App/DrawViewSection.h @@ -27,10 +27,14 @@ #include #include +#include + #include "DrawViewPart.h" +#include "Geometry.h" class gp_Pln; class TopoDS_Compound; +class TopoDS_Face; namespace TechDraw { @@ -66,11 +70,20 @@ public: } public: - TopoDS_Compound getSectionFaces(void); + std::vector getFaceGeometry(); protected: - TopoDS_Shape sectionShape; + TopoDS_Shape sectionShape; //obs?? 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 344796590..e8490b354 100644 --- a/src/Mod/TechDraw/App/Geometry.cpp +++ b/src/Mod/TechDraw/App/Geometry.cpp @@ -142,6 +142,76 @@ Base::Vector2D BaseGeom::getEndPoint() return verts[1]; } +//!convert 1 OCC edge into 1 BaseGeom (static factory method) +BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) +{ + BaseGeom* result = NULL; + BRepAdaptor_Curve adapt(edge); + + switch(adapt.GetType()) { + case GeomAbs_Circle: { + double f = adapt.FirstParameter(); + double l = adapt.LastParameter(); + gp_Pnt s = adapt.Value(f); + gp_Pnt e = adapt.Value(l); + + if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) { + Circle *circle = new Circle(edge); + //circle->extractType = extractionType; + result = circle; + } else { + AOC *aoc = new AOC(edge); + //aoc->extractType = extractionType; + result = aoc; + } + } break; + case GeomAbs_Ellipse: { + double f = adapt.FirstParameter(); + double l = adapt.LastParameter(); + gp_Pnt s = adapt.Value(f); + gp_Pnt e = adapt.Value(l); + if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) { + Ellipse *ellipse = new Ellipse(edge); + //ellipse->extractType = extractionType; + result = ellipse; + } else { + AOE *aoe = new AOE(edge); + //aoe->extractType = extractionType; + result = aoe; + } + } break; + case GeomAbs_BSplineCurve: { + BSpline *bspline = 0; + Generic* gen = NULL; + try { + bspline = new BSpline(edge); + //bspline->extractType = extractionType; + if (bspline->isLine()) { + gen = new Generic(edge); + //gen->extractType = extractionType; + result = gen; + delete bspline; + } else { + result = bspline; + } + break; + } + catch (Standard_Failure) { + delete bspline; + delete gen; + bspline = 0; + // Move onto generating a primitive + } + } + default: { + Generic *primitive = new Generic(edge); + //primitive->extractType = extractionType; + result = primitive; + } break; + } + return result; +} + Ellipse::Ellipse(const TopoDS_Edge &e) { geomType = ELLIPSE; @@ -309,27 +379,6 @@ bool BSpline::isLine() result = true; } return result; -#if 0 - bool result = true; - std::vector::iterator iSeg = segments.begin(); - double slope; - if ((*iSeg).poles == 2) { - slope = ((*iSeg).pnts[1].fY - (*iSeg).pnts[0].fY) / - ((*iSeg).pnts[1].fX - (*iSeg).pnts[0].fX); //always at least 2 points? - } - for (; iSeg != segments.end(); iSeg++) { - if ((*iSeg).poles != 2) { - result = false; - break; - } - double newSlope = ((*iSeg).pnts[1].fY - (*iSeg).pnts[0].fY) / ((*iSeg).pnts[1].fX - (*iSeg).pnts[0].fX); - if (fabs(newSlope - slope) > Precision::Confusion()) { - result = false; - break; - } - } - return result; -#endif } //**** Vertex diff --git a/src/Mod/TechDraw/App/Geometry.h b/src/Mod/TechDraw/App/Geometry.h index c4bf2fc53..626d8dcd8 100644 --- a/src/Mod/TechDraw/App/Geometry.h +++ b/src/Mod/TechDraw/App/Geometry.h @@ -73,6 +73,8 @@ public: std::vector findEndPoints(); Base::Vector2D getStartPoint(); Base::Vector2D getEndPoint(); +public: //class wide methods + static BaseGeom* baseFactory(TopoDS_Edge edge); }; class TechDrawExport Circle: public BaseGeom @@ -171,17 +173,21 @@ public: std::vector points; }; + + /// Simple Collection of geometric features based on BaseGeom inherited classes in order -struct TechDrawExport Wire +class TechDrawExport Wire { +public: Wire(); ~Wire(); std::vector geoms; }; /// Simple Collection of geometric features based on BaseGeom inherited classes in order -struct TechDrawExport Face +class TechDrawExport Face { +public: Face(); ~Face(); std::vector wires; diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index 8d4b57960..ab2376503 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -73,6 +73,7 @@ # include # include # include +#include # include # include @@ -84,7 +85,8 @@ # include # include -# include +#include +#include # include # include # include @@ -103,7 +105,7 @@ # include -# include "GeometryObject.h" +#include "GeometryObject.h" //#include @@ -120,7 +122,7 @@ const char* _printBool(bool b); void _dumpEdge(char* label, int i, TopoDS_Edge e); -GeometryObject::GeometryObject() : brep_hlr(NULL), Tolerance(0.05f), Scale(1.f) +GeometryObject::GeometryObject() : Tolerance(0.05f), Scale(1.f) { } @@ -167,50 +169,25 @@ void GeometryObject::clear() edgeReferences.clear(); } -//!set up a hidden line remover and load a shape into it -void GeometryObject::initHLR(const TopoDS_Shape &input, - const Base::Vector3d &direction, - const Base::Vector3d &xAxis) +//!set up a hidden line remover and project a shape with it +void GeometryObject::projectShape(const TopoDS_Shape& input, + const gp_Pnt& inputCenter, + const Base::Vector3d& direction, + const Base::Vector3d& xAxis) { // Clear previous Geometry and References that may have been stored //TODO: hate losing references on recompute! if Shape has changed, aren't reference potentially invalid anyway? clear(); - if (brep_hlr) { - if (brep_hlr->NbShapes()) { //TODO: hack. in ProjGroupItems sometimes brep_hlr has no shapes when we get here. why?? - brep_hlr->Remove(1); //remove the old shape from brep (would we ever have > 1 shape?) - } - } - ///TODO: Consider whether it would be possible/beneficial to cache some of this effort (eg don't do scale in OpenCASCADE land) IR - TopoDS_Shape transShape; - gp_Pnt inputCentre; + Handle_HLRBRep_Algo brep_hlr = NULL; try { - inputCentre = findCentroid(input, direction, xAxis); - } - catch (...) { - Base::Console().Log("GeometryObject::initHLR - findCentroid failed.\n"); - return; - } - try { - // Make tempTransform scale the object around it's centre point and - // mirror about the Y axis - gp_Trsf tempTransform; - tempTransform.SetScale(inputCentre, Scale); - gp_Trsf mirrorTransform; - mirrorTransform.SetMirror( gp_Ax2(inputCentre, gp_Dir(0, 1, 0)) ); - tempTransform.Multiply(mirrorTransform); - - // Apply that transform to the shape. This should preserve the centre. - BRepBuilderAPI_Transform mkTrf(input, tempTransform); - transShape = mkTrf.Shape(); - - brep_hlr = new HLRBRep_Algo(); //leak? when does this get freed? handle/smart pointer - brep_hlr->Add(transShape); + brep_hlr = new HLRBRep_Algo(); //leak? when does this get freed? handle/smart pointer? + brep_hlr->Add(input); // Project the shape into view space with the object's centroid // at the origin. gp_Ax2 viewAxis; - viewAxis = gp_Ax2(inputCentre, + viewAxis = gp_Ax2(inputCenter, gp_Dir(direction.x, direction.y, direction.z), gp_Dir(xAxis.x, xAxis.y, xAxis.z)); HLRAlgo_Projector projector( viewAxis ); @@ -219,28 +196,56 @@ void GeometryObject::initHLR(const TopoDS_Shape &input, brep_hlr->Hide(); } catch (...) { - Standard_Failure::Raise("GeometryObject::initHLR - error occurred while projecting shape"); + Standard_Failure::Raise("GeometryObject::projectShape - error occurred while projecting shape"); } + try { + HLRBRep_HLRToShape hlrToShape(brep_hlr); + + visHard = hlrToShape.VCompound(); + visSmooth = hlrToShape.Rg1LineVCompound(); + visSeam = hlrToShape.RgNLineVCompound(); + visOutline = hlrToShape.OutLineVCompound(); + visIso = hlrToShape.IsoLineVCompound(); + hidHard = hlrToShape.HCompound(); + hidSmooth = hlrToShape.Rg1LineHCompound(); + hidSeam = hlrToShape.RgNLineHCompound(); + hidOutline = hlrToShape.OutLineHCompound(); + hidIso = hlrToShape.IsoLineHCompound(); + + BRepLib::BuildCurves3d(visHard); + BRepLib::BuildCurves3d(visSmooth); + BRepLib::BuildCurves3d(visSeam); + BRepLib::BuildCurves3d(visOutline); + BRepLib::BuildCurves3d(visIso); + BRepLib::BuildCurves3d(hidHard); + BRepLib::BuildCurves3d(hidSmooth); + BRepLib::BuildCurves3d(hidSeam); + BRepLib::BuildCurves3d(hidOutline); + BRepLib::BuildCurves3d(hidIso); + } + catch (...) { + Standard_Failure::Raise("GeometryObject::projectShape - error occurred while extracting edges"); + } + } //!add edges meeting filter criteria for category, visibility void GeometryObject::extractGeometry(edgeClass category, bool visible) { - HLRBRep_HLRToShape hlrToShape(brep_hlr); TopoDS_Shape filtEdges; if (visible) { switch (category) { case ecHARD: - filtEdges = hlrToShape.VCompound(); + filtEdges = visHard; break; case ecOUTLINE: - filtEdges = hlrToShape.OutLineVCompound(); + filtEdges = visOutline; break; case ecSMOOTH: - filtEdges = hlrToShape.Rg1LineVCompound(); + filtEdges = visSmooth; break; case ecSEAM: - filtEdges = hlrToShape.RgNLineHCompound(); + filtEdges = visSeam; break; default: Base::Console().Warning("GeometryObject::ExtractGeometry - unsupported visible edgeClass: %d\n",category); @@ -249,7 +254,7 @@ void GeometryObject::extractGeometry(edgeClass category, bool visible) } else { switch (category) { case ecHARD: - filtEdges = hlrToShape.HCompound(); + filtEdges = hidHard; break; //more cases here? default: @@ -281,7 +286,7 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i); continue; } - base = edgeToBase(edge); + base = BaseGeom::baseFactory(edge); base->classOfEdge = category; base->visible = visible; edgeGeom.push_back(base); @@ -290,7 +295,7 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca //add vertices of new edge if not already in list if (visible) { BaseGeom* lastAdded = edgeGeom.back(); - //if (edgeGeom.empty()) {horrible_death();} //back() undefined behavior (can't happen? edgeToBase always returns a Base?) + //if (edgeGeom.empty()) {horrible_death();} //back() undefined behavior (can't happen? baseFactory always returns a Base?) bool v1Add = true, v2Add = true; TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint()); TechDrawGeometry::Vertex* v2 = new TechDrawGeometry::Vertex(lastAdded->getEndPoint()); @@ -322,110 +327,11 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca } } -//!convert 1 OCC edge into 1 BaseGeom -BaseGeom* GeometryObject::edgeToBase(TopoDS_Edge edge) -{ - BaseGeom* result = NULL; - BRepAdaptor_Curve adapt(edge); - - switch(adapt.GetType()) { - case GeomAbs_Circle: { - double f = adapt.FirstParameter(); - double l = adapt.LastParameter(); - gp_Pnt s = adapt.Value(f); - gp_Pnt e = adapt.Value(l); - - if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) { - Circle *circle = new Circle(edge); - //circle->extractType = extractionType; - result = circle; - } else { - AOC *aoc = new AOC(edge); - //aoc->extractType = extractionType; - result = aoc; - } - } break; - case GeomAbs_Ellipse: { - double f = adapt.FirstParameter(); - double l = adapt.LastParameter(); - gp_Pnt s = adapt.Value(f); - gp_Pnt e = adapt.Value(l); - if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) { - Ellipse *ellipse = new Ellipse(edge); - //ellipse->extractType = extractionType; - result = ellipse; - } else { - AOE *aoe = new AOE(edge); - //aoe->extractType = extractionType; - result = aoe; - } - } break; - case GeomAbs_BSplineCurve: { - BSpline *bspline = 0; - Generic* gen = NULL; - try { - bspline = new BSpline(edge); - //bspline->extractType = extractionType; - if (bspline->isLine()) { - gen = new Generic(edge); - //gen->extractType = extractionType; - result = gen; - delete bspline; - } else { - result = bspline; - } - break; - } - catch (Standard_Failure) { - delete bspline; - delete gen; - bspline = 0; - // Move onto generating a primitive - } - } - default: { - Generic *primitive = new Generic(edge); - //primitive->extractType = extractionType; - result = primitive; - } break; - } - return result; -} - //!find the 3D edges & vertices that correspond to 2D edges & vertices void GeometryObject::update3DRefs() { } -gp_Pnt GeometryObject::findCentroid(const TopoDS_Shape &shape, - const Base::Vector3d &direction, - const Base::Vector3d &xAxis) const -{ - gp_Ax2 viewAxis; - viewAxis = gp_Ax2(gp_Pnt(0, 0, 0), - gp_Dir(direction.x, -direction.y, direction.z), - gp_Dir(xAxis.x, -xAxis.y, xAxis.z)); // Y invert warning! - - gp_Trsf tempTransform; - tempTransform.SetTransformation(viewAxis); - BRepBuilderAPI_Transform builder(shape, tempTransform); - - Bnd_Box tBounds; - BRepBndLib::Add(builder.Shape(), tBounds); - - tBounds.SetGap(0.0); - Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; - tBounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); - - Standard_Real x = (xMin + xMax) / 2.0, - y = (yMin + yMax) / 2.0, - z = (zMin + zMax) / 2.0; - - // Get centroid back into object space - tempTransform.Inverted().Transforms(x, y, z); - - return gp_Pnt(x, y, z); -} /////////////// bbox routines @@ -966,6 +872,66 @@ bool GeometryObject::findVertex(Base::Vector2D v) return found; } +/// utility non-class member functions +//! Returns the centroid of shape, as viewed according to direction and xAxis +gp_Pnt TechDrawGeometry::findCentroid(const TopoDS_Shape &shape, + const Base::Vector3d &direction, + const Base::Vector3d &xAxis) +{ + gp_Ax2 viewAxis; + viewAxis = gp_Ax2(gp_Pnt(0, 0, 0), + gp_Dir(direction.x, -direction.y, direction.z), + gp_Dir(xAxis.x, -xAxis.y, xAxis.z)); // Y invert warning! + + gp_Trsf tempTransform; + tempTransform.SetTransformation(viewAxis); + BRepBuilderAPI_Transform builder(shape, tempTransform); + + Bnd_Box tBounds; + BRepBndLib::Add(builder.Shape(), tBounds); + + tBounds.SetGap(0.0); + Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; + tBounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); + + Standard_Real x = (xMin + xMax) / 2.0, + y = (yMin + yMax) / 2.0, + z = (zMin + zMax) / 2.0; + + // Get centroid back into object space + tempTransform.Inverted().Transforms(x, y, z); + + return gp_Pnt(x, y, z); +} + +//!scales & mirrors a shape about a center +TopoDS_Shape TechDrawGeometry::mirrorShape(const TopoDS_Shape &input, + const gp_Pnt& inputCenter, + double scale) +{ + TopoDS_Shape transShape; + try { + // Make tempTransform scale the object around it's centre point and + // mirror about the Y axis + // TODO: is this really always Y axis? sb whatever is vertical direction in projection? + gp_Trsf tempTransform; + tempTransform.SetScale(inputCenter, scale); + gp_Trsf mirrorTransform; + mirrorTransform.SetMirror( gp_Ax2(inputCenter, gp_Dir(0, 1, 0)) ); + tempTransform.Multiply(mirrorTransform); + + // Apply that transform to the shape. This should preserve the centre. + BRepBuilderAPI_Transform mkTrf(input, tempTransform); + transShape = mkTrf.Shape(); + } + catch (...) { + Base::Console().Log("GeometryObject::mirrorShape - mirror/scale failed.\n"); + return transShape; + } + return transShape; +} + +/// debug functions void _dumpEdgeData(char* label, int i, HLRBRep_EdgeData& ed) { Base::Console().Message("Dump of EdgeData for %s Edge: %d\n",label,i); diff --git a/src/Mod/TechDraw/App/GeometryObject.h b/src/Mod/TechDraw/App/GeometryObject.h index e9910a74e..dfe83f7fa 100644 --- a/src/Mod/TechDraw/App/GeometryObject.h +++ b/src/Mod/TechDraw/App/GeometryObject.h @@ -23,8 +23,8 @@ #ifndef _TECHDRAW_GEOMETRYOBJECT_H #define _TECHDRAW_GEOMETRYOBJECT_H -#include #include +#include #include #include @@ -44,6 +44,16 @@ namespace TechDrawGeometry class BaseGeom; +//! scales & mirrors a shape about a center +TopoDS_Shape TechDrawExport mirrorShape(const TopoDS_Shape &input, + const gp_Pnt& inputCenter, + double scale); + +//! Returns the centroid of shape, as viewed according to direction and xAxis +gp_Pnt TechDrawExport findCentroid(const TopoDS_Shape &shape, + const Base::Vector3d &direction, + const Base::Vector3d &xAxis); + class TechDrawExport GeometryObject { public: @@ -67,6 +77,7 @@ public: const std::vector & getEdgeRefs() const { return edgeReferences; }; const std::vector & getFaceRefs() const { return faceReferences; }; +//begin obs? void projectSurfaces(const TopoDS_Shape &face, const TopoDS_Shape &support, const Base::Vector3d &direction, @@ -80,15 +91,28 @@ public: const TopoDS_Shape &support, const Base::Vector3d &direction, const Base::Vector3d &projXAxis) const; +//end obs? - void initHLR(const TopoDS_Shape &input, + void projectShape(const TopoDS_Shape &input, + const gp_Pnt& inputCenter, const Base::Vector3d &direction, const Base::Vector3d &xAxis); void extractGeometry(edgeClass category, bool visible); - BaseGeom* edgeToBase(TopoDS_Edge edge); void update3DRefs(); protected: + //HLR output + TopoDS_Shape visHard; + TopoDS_Shape visOutline; + TopoDS_Shape visSmooth; + TopoDS_Shape visSeam; + TopoDS_Shape visIso; + TopoDS_Shape hidHard; + TopoDS_Shape hidOutline; + TopoDS_Shape hidSmooth; + TopoDS_Shape hidSeam; + TopoDS_Shape hidIso; + void addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible); /// Helper for calcBoundingBox() @@ -124,14 +148,8 @@ protected: std::vector edgeReferences; std::vector faceReferences; - Handle_HLRBRep_Algo brep_hlr; double Tolerance; double Scale; - - /// Returns the centroid of shape, as viewed according to direction and xAxis - gp_Pnt findCentroid(const TopoDS_Shape &shape, - const Base::Vector3d &direction, - const Base::Vector3d &xAxis) const; }; } //namespace TechDrawGeometry diff --git a/src/Mod/TechDraw/Gui/CMakeLists.txt b/src/Mod/TechDraw/Gui/CMakeLists.txt index 3d8ade416..2e331e2d6 100644 --- a/src/Mod/TechDraw/Gui/CMakeLists.txt +++ b/src/Mod/TechDraw/Gui/CMakeLists.txt @@ -125,6 +125,7 @@ SET(TechDrawGuiView_SRCS QGIHatch.h TemplateTextField.cpp TemplateTextField.h + ZVALUE.h ) SET(TechDrawGuiViewProvider_SRCS ViewProviderPage.cpp diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 1459fc1c3..34069b08c 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -345,7 +345,7 @@ void CmdTechDrawNewViewSection::activated(int iMsg) openCommand("Create view"); for (std::vector::iterator it = shapes.begin(); it != shapes.end(); ++it) { - std::string FeatName = getUniqueObjectName("View"); + std::string FeatName = getUniqueObjectName("Section"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewSection','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Source = App.activeDocument().%s",FeatName.c_str(),(*it)->getNameInDocument()); doCommand(Doc,"App.activeDocument().%s.Direction = (0.0,0.0,1.0)",FeatName.c_str()); diff --git a/src/Mod/TechDraw/Gui/QGIEdge.cpp b/src/Mod/TechDraw/Gui/QGIEdge.cpp index 9f53042c6..1928ff01a 100644 --- a/src/Mod/TechDraw/Gui/QGIEdge.cpp +++ b/src/Mod/TechDraw/Gui/QGIEdge.cpp @@ -160,12 +160,11 @@ void QGIEdge::setStrokeWidth(float width) { update(); } +//TODO: obs? we never change an existing edge's visibility. void QGIEdge::setHiddenEdge(bool b) { isHiddenEdge = b; if (b) m_colCurrent = m_colHid; update(); - //TODO: need some fiddling here so hidden edges don't get selected?? is it ok to select a hidden edge? - //wf: probably bad drafing practice to dimension a hidden line } void QGIEdge::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { diff --git a/src/Mod/TechDraw/Gui/QGIEdge.h b/src/Mod/TechDraw/Gui/QGIEdge.h index 3f1c28bfc..0c0508eff 100644 --- a/src/Mod/TechDraw/Gui/QGIEdge.h +++ b/src/Mod/TechDraw/Gui/QGIEdge.h @@ -40,7 +40,6 @@ namespace TechDrawGui class TechDrawGuiExport QGIEdge : public QGraphicsPathItem { public: -// explicit QGIEdge(int ref = -1); explicit QGIEdge(int index); ~QGIEdge() {} @@ -51,6 +50,7 @@ public: QPainterPath shape() const; virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + //TODO: edge doesn't need ref to 3D, just index in projection. links to 3D handled in Features. int getReference() const { return reference; } void setReference(int ref) {reference = ref; } int getProjIndex() const { return projIndex; } diff --git a/src/Mod/TechDraw/Gui/QGISVGTemplate.cpp b/src/Mod/TechDraw/Gui/QGISVGTemplate.cpp index ae2479952..9f522e425 100644 --- a/src/Mod/TechDraw/Gui/QGISVGTemplate.cpp +++ b/src/Mod/TechDraw/Gui/QGISVGTemplate.cpp @@ -41,6 +41,7 @@ #include #include +#include "ZVALUE.h" #include "QGISVGTemplate.h" using namespace TechDrawGui; @@ -184,7 +185,7 @@ void QGISVGTemplate::load(const QString &fileName) item->setPen(myPen); item->setBrush(myBrush); - item->setZValue(100); + item->setZValue(ZVALUE::SVGTEMPLATE); addToGroup(item); textFields.push_back(item); } diff --git a/src/Mod/TechDraw/Gui/QGITemplate.cpp b/src/Mod/TechDraw/Gui/QGITemplate.cpp index 7150622df..2d0c167b5 100644 --- a/src/Mod/TechDraw/Gui/QGITemplate.cpp +++ b/src/Mod/TechDraw/Gui/QGITemplate.cpp @@ -30,6 +30,7 @@ #include +#include "ZVALUE.h" #include "QGITemplate.h" using namespace TechDrawGui; @@ -39,7 +40,7 @@ QGITemplate::QGITemplate(QGraphicsScene *scene) : QGraphicsItemGroup(), { setHandlesChildEvents(false); setCacheMode(QGraphicsItem::NoCache); - setZValue(-1000); //Template is situated in background + setZValue(ZVALUE::TEMPLATE); //Template is situated in background scene->addItem(this); } diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 6f65623e4..1069cc057 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -48,7 +48,8 @@ #include "../App/DrawUtil.h" #include "../App/DrawViewPart.h" #include "../App/DrawHatch.h" -#include "../App/Geometry.h" + +#include "ZVALUE.h" #include "QGIViewPart.h" using namespace TechDrawGui; @@ -286,53 +287,22 @@ void QGIViewPart::drawViewPart() prepareGeometryChange(); -#if MOD_TECHDRAW_HANDLE_FACES // Draw Faces - const std::vector &faceGeoms = part->getFaceGeometry(); - const std::vector &faceRefs = part->getFaceReferences(); + const std::vector &faceGeoms = viewPart->getFaceGeometry(); std::vector::const_iterator fit = faceGeoms.begin(); - QGIFace* face; QPen facePen; + facePen.setCosmetic(true); + QBrush faceBrush; for(int i = 0 ; fit != faceGeoms.end(); fit++, i++) { - std::vector faceWires = (*fit)->wires; - QPainterPath facePath; - for(std::vector::iterator wire = faceWires.begin(); wire != faceWires.end(); wire++) { - QPainterPath wirePath; - QPointF shapePos; - for(std::vector::iterator baseGeom = (*wire)->geoms.begin(); - baseGeom != (*wire)->geoms.end(); - baseGeom++) { - QPainterPath edgePath = drawPainterPath(*baseGeom); - //If the current end point matches the shape end point the new edge path needs reversing - QPointF shapePos = (wirePath.currentPosition()- edgePath.currentPosition()); - if(sqrt(shapePos.x() * shapePos.x() + shapePos.y()*shapePos.y()) < 0.05) { - edgePath = edgePath.toReversed(); - } - wirePath.connectPath(edgePath); - wirePath.setFillRule(Qt::WindingFill); - } - facePath.addPath(wirePath); - } - - //debug a path - //std::stringstream faceId; - //faceId << "facePath" << i; - //_dumpPath(faceId.str().c_str(),facePath); - - QGIFace *fitem = new QGIFace(-1); - // TODO: TechDrawGeometry::Face has no easy method of determining hidden/visible??? - // Hide any edges that are hidden if option is set. -// if((*fit)->extractType == TechDrawGeometry::WithHidden && !part->ShowHiddenLines.getValue()) -// graphicsItem->hide(); - addToGroup(fitem); - fitem->setPos(0.0,0.0); - //QPainterPath simplePath = facePath.simplified(); - //simplePath.setFillRule(Qt::WindingFill); - //fitem->setPath(simplePath); - fitem->setPath(facePath); - fitem->setFlag(QGraphicsItem::ItemIsSelectable, true); + QGIFace* newFace = drawFace(*fit); + newFace->setPen(facePen); + newFace->setZValue(ZVALUE::FACE); + //newFace->setBrush(faceBrush); } -#endif //#if MOD_TECHDRAW_HANDLE_FACES + //debug a path + //std::stringstream faceId; + //faceId << "facePath" << i; + //_dumpPath(faceId.str().c_str(),facePath); // Draw Hatches std::vector hatchObjs = viewPart->getHatches(); @@ -380,6 +350,7 @@ void QGIViewPart::drawViewPart() hatch->setColor(feat->HatchColor.getValue()); //_dumpPath("hatchPath",hatchPath); hatch->setFlag(QGraphicsItem::ItemIsSelectable, true); + hatch->setZValue(ZVALUE::HATCH); } } @@ -416,13 +387,12 @@ void QGIViewPart::drawViewPart() item->setPath(drawPainterPath(*itEdge)); item->setFlag(QGraphicsItem::ItemIsSelectable, true); item->setAcceptHoverEvents(true); - + item->setZValue(ZVALUE::EDGE); //debug a path - //QPainterPath edgePath=drawPainterPath(*itEdge); - //item->setPath(edgePath); - //std::stringstream edgeId; - //edgeId << "edge" << i; - //_dumpPath(edgeId.str().c_str(),edgePath); + QPainterPath edgePath=drawPainterPath(*itEdge); + std::stringstream edgeId; + edgeId << "QGIVP.edgePath" << i; + _dumpPath(edgeId.str().c_str(),edgePath); } } @@ -436,9 +406,39 @@ void QGIViewPart::drawViewPart() addToGroup(item); item->setPos((*vert)->pnt.fX, (*vert)->pnt.fY); //this is in ViewPart coords item->setRadius(lineWidth * vertexScaleFactor); + item->setZValue(ZVALUE::VERTEX); } } +QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f) +{ + std::vector fWires = f->wires; + QPainterPath facePath; + for(std::vector::iterator wire = fWires.begin(); wire != fWires.end(); ++wire) { + QPainterPath wirePath; + for(std::vector::iterator edge = (*wire)->geoms.begin(); edge != (*wire)->geoms.end(); ++edge) { + //Save the start Position + QPainterPath edgePath = drawPainterPath(*edge); + // If the current end point matches the shape end point the new edge path needs reversing + QPointF shapePos = (wirePath.currentPosition()- edgePath.currentPosition()); + if(sqrt(shapePos.x() * shapePos.x() + shapePos.y()*shapePos.y()) < 0.05) { //magic tolerance + edgePath = edgePath.toReversed(); + } + wirePath.connectPath(edgePath); + wirePath.setFillRule(Qt::WindingFill); + } + facePath.addPath(wirePath); + } + QGIFace* gFace = new QGIFace(-1); + addToGroup(gFace); + gFace->setPos(0.0,0.0); + gFace->setPath(facePath); + _dumpPath("QGIVP.facePath",facePath); + + //gFace->setFlag(QGraphicsItem::ItemIsSelectable, true); ??? + return gFace; +} + std::vector QGIViewPart::getHatchesForView(TechDraw::DrawViewPart* viewPart) { std::vector docObjs = viewPart->getDocument()->getObjectsOfType(TechDraw::DrawHatch::getClassTypeId()); diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.h b/src/Mod/TechDraw/Gui/QGIViewPart.h index 0a245412a..32b6b60ae 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.h +++ b/src/Mod/TechDraw/Gui/QGIViewPart.h @@ -31,16 +31,14 @@ #include "QGIEdge.h" #include "QGIVertex.h" #include "QGIHatch.h" +#include "../App/Geometry.h" + namespace TechDraw { class DrawViewPart; class DrawHatch; } -namespace TechDrawGeometry { -class BaseGeom; -} - namespace TechDrawGui { @@ -94,6 +92,7 @@ protected: QPainterPath drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom) const; std::vector getHatchesForView(TechDraw::DrawViewPart* viewPart); void drawViewPart(); + QGIFace* drawFace(TechDrawGeometry::Face* f); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); diff --git a/src/Mod/TechDraw/Gui/QGIViewSection.cpp b/src/Mod/TechDraw/Gui/QGIViewSection.cpp index 5edd3b983..192568601 100644 --- a/src/Mod/TechDraw/Gui/QGIViewSection.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewSection.cpp @@ -41,6 +41,8 @@ #include #include "../App/DrawViewSection.h" + +#include "ZVALUE.h" #include "QGIViewSection.h" using namespace TechDrawGui; @@ -65,73 +67,29 @@ void QGIViewSection::drawSectionFace() if(getViewObject() == 0 || !getViewObject()->isDerivedFrom(TechDraw::DrawViewSection::getClassTypeId())) return; - TechDraw::DrawViewSection *part = dynamic_cast(getViewObject()); - if (!part->hasGeometry()) { + TechDraw::DrawViewSection *section = dynamic_cast(getViewObject()); + if (!section->hasGeometry()) { return; } //Base::Console().Log("drawing section face\n"); - // Get the section faces from the feature - std::vector sectionFaces; - //part->getSectionFaces(faceGeoms); + std::vector sectionFaces; + sectionFaces = section->getFaceGeometry(); if (sectionFaces.empty()) { Base::Console().Log("INFO - QGIViewSection::drawSectionFace - No sectionFaces available. Check Section plane.\n"); return; } - -#if MOD_TECHDRAW_HANDLE_FACES - // Draw Faces - std::vector::const_iterator fit = faceGeoms.begin(); - - QGraphicsItem*graphicsItem = 0; + std::vector::iterator fit = sectionFaces.begin(); QPen facePen; - -//TODO: check if this is the same logic as QGIVPart - for(int i = 0 ; fit != faceGeoms.end(); ++fit, i++) { - std::vector faceWires = (*fit)->wires; - QPainterPath facePath; - for(std::vector::iterator wire = faceWires.begin(); wire != faceWires.end(); ++wire) { - QPainterPath wirePath; - QPointF shapePos; - for(std::vector::iterator baseGeom = (*wire)->geoms.begin(); baseGeom != (*wire)->geoms.end(); ++baseGeom) { - //Save the start Position - QPainterPath edgePath = drawPainterPath(*baseGeom); - - // If the current end point matches the shape end point the new edge path needs reversing - QPointF shapePos = (wirePath.currentPosition()- edgePath.currentPosition()); - if(sqrt(shapePos.x() * shapePos.x() + shapePos.y()*shapePos.y()) < 0.05) { - edgePath = edgePath.toReversed(); - } - wirePath.connectPath(edgePath); - wirePath.setFillRule(Qt::WindingFill); - } - facePath.addPath(wirePath); - } - - QGIFace *item = new QGIFace(-1); - - item->setPath(facePath); - // item->setStrokeWidth(lineWidth); - - QBrush faceBrush(QBrush(QColor(0,0,255,40))); - - item->setBrush(faceBrush); - facePen.setColor(Qt::black); - item->setPen(facePen); - item->moveBy(x(), y()); - graphicsItem = dynamic_cast(item); - - if(graphicsItem) { - // Hide any edges that are hidden if option is set. - // if(!(*fit)->visible && !part->ShowHiddenLines.getValue()) - // graphicsItem->hide(); - - addToGroup(graphicsItem); - graphicsItem->setFlag(QGraphicsItem::ItemIsSelectable, true); - } + 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->setEyeCandy() } -#endif } void QGIViewSection::updateView(bool update) diff --git a/src/Mod/TechDraw/Gui/QGVPage.cpp b/src/Mod/TechDraw/Gui/QGVPage.cpp index bf4244465..7019fd07b 100644 --- a/src/Mod/TechDraw/Gui/QGVPage.cpp +++ b/src/Mod/TechDraw/Gui/QGVPage.cpp @@ -72,6 +72,7 @@ #include "QGIViewSymbol.h" #include "QGIViewClip.h" +#include "ZVALUE.h" #include "QGVPage.h" using namespace TechDrawGui; @@ -101,7 +102,7 @@ QGVPage::QGVPage(ViewProviderPage *vp, QWidget *parent) m_backgroundItem = new QGraphicsRectItem(); m_backgroundItem->setCacheMode(QGraphicsItem::NoCache); - m_backgroundItem->setZValue(-999999); + m_backgroundItem->setZValue(ZVALUE::BACKGROUND); // scene()->addItem(m_backgroundItem); // TODO IF SEGFAULTS WITH DRAW ENABLE THIS (REDRAWS ARE SLOWER :s) // Prepare background check-board pattern @@ -287,7 +288,7 @@ void QGVPage::addDimToParent(QGIViewDimension* dim, QGIView* parent) QPointF mapPos = dim->mapToItem(parent, posRef); dim->moveBy(-mapPos.x(), -mapPos.y()); parent->addToGroup(dim); - dim->setZValue(50.0); + dim->setZValue(ZVALUE::DIMENSION); } QGIView * QGVPage::findView(App::DocumentObject *obj) const diff --git a/src/Mod/TechDraw/Gui/ZVALUE.h b/src/Mod/TechDraw/Gui/ZVALUE.h new file mode 100644 index 000000000..3bfba33ad --- /dev/null +++ b/src/Mod/TechDraw/Gui/ZVALUE.h @@ -0,0 +1,14 @@ +#ifndef _TECHDRAW_ZVALUE_ +#define _TECHDRAW_ZVALUE_ +namespace ZVALUE { + const int BACKGROUND = -999999; + const int TEMPLATE = -1000; + const int SVGTEMPLATE = -500; + const int SECTIONFACE = 10; + const int FACE = 20; + const int HATCH = 25; + const int EDGE = 30; + const int VERTEX = 40; + const int DIMENSION = 50; +} +#endif