diff --git a/src/Mod/Path/App/Area.cpp b/src/Mod/Path/App/Area.cpp index 602789709..ad339672a 100644 --- a/src/Mod/Path/App/Area.cpp +++ b/src/Mod/Path/App/Area.cpp @@ -123,7 +123,6 @@ Area::Area(const Area &other, bool deep_copy) ,myShapes(other.myShapes) ,myTrsf(other.myTrsf) ,myParams(other.myParams) -,myShapePlane(other.myShapePlane) ,myWorkPlane(other.myWorkPlane) ,myHaveFace(other.myHaveFace) ,myHaveSolid(other.myHaveSolid) @@ -133,6 +132,7 @@ Area::Area(const Area &other, bool deep_copy) return; if(other.myArea) myArea.reset(new CArea(*other.myArea)); + myShapePlane = other.myShapePlane; myShape = other.myShape; myShapeDone = other.myShapeDone; mySections.reserve(other.mySections.size()); @@ -149,9 +149,8 @@ void Area::setPlane(const TopoDS_Shape &shape) { myWorkPlane.Nullify(); return; } - TopoDS_Shape plane; gp_Trsf trsf; - findPlane(shape,plane,trsf); + TopoDS_Shape plane = findPlane(shape,trsf); if (plane.IsNull()) throw Base::ValueError("shape is not planar"); myWorkPlane = plane; @@ -325,8 +324,8 @@ void Area::clean(bool deleteShapes) { myShape.Nullify(); myArea.reset(); myAreaOpen.reset(); + myShapePlane.Nullify(); if(deleteShapes){ - myShapePlane.Nullify(); myShapes.clear(); myHaveFace = false; myHaveSolid = false; @@ -453,20 +452,21 @@ static void show(const TopoDS_Shape &shape, const char *name) { } #endif -bool Area::findPlane(const TopoDS_Shape &shape, - TopoDS_Shape &plane, gp_Trsf &trsf) +TopoDS_Shape Area::findPlane(const TopoDS_Shape &shape, gp_Trsf &trsf) { - return findPlane(shape,TopAbs_FACE,plane,trsf) || - findPlane(shape,TopAbs_WIRE,plane,trsf) || - findPlane(shape,TopAbs_EDGE,plane,trsf); + TopoDS_Shape plane; + double top_z; + if(!findPlane(shape,TopAbs_FACE,plane,trsf,top_z) && + !findPlane(shape,TopAbs_WIRE,plane,trsf,top_z)) + findPlane(shape,TopAbs_EDGE,plane,trsf,top_z); + return plane; } bool Area::findPlane(const TopoDS_Shape &shape, int type, - TopoDS_Shape &dst, gp_Trsf &dst_trsf) + TopoDS_Shape &dst, gp_Trsf &dst_trsf, double &top_z) { bool haveShape = false; - double top_z; - bool top_found = false; + bool top_found = !dst.IsNull(); gp_Trsf trsf; for(TopExp_Explorer it(shape,(TopAbs_ShapeEnum)type); it.More(); it.Next()) { haveShape = true; @@ -478,17 +478,26 @@ bool Area::findPlane(const TopoDS_Shape &shape, int type, gp_Dir dir(pos.Direction()); trsf.SetTransformation(pos); - //pos.Location().Z() is always 0, why? As a walk around, use the first vertex Z gp_Pnt origin = pos.Location(); - for(TopExp_Explorer it(plane.Moved(trsf),TopAbs_VERTEX);it.More();) { - origin.SetZ(BRep_Tool::Pnt(TopoDS::Vertex(it.Current())).Z()); - break; - } - if(fabs(dir.X()) origin.Z()) continue; top_found = true; @@ -496,12 +505,8 @@ bool Area::findPlane(const TopoDS_Shape &shape, int type, }else if(!dst.IsNull()) continue; dst = plane; + dst_trsf = trsf; - //Some how the plane returned by BRepLib_FindSurface has Z always set to 0. - //We need to manually translate Z to its actual value - gp_Trsf trsf2; - trsf2.SetTranslationPart(gp_XYZ(0,0,-origin.Z())); - dst_trsf = trsf.Multiplied(trsf2); } return haveShape; } @@ -509,13 +514,13 @@ bool Area::findPlane(const TopoDS_Shape &shape, int type, std::vector > Area::makeSections( PARAM_ARGS(PARAM_FARG,AREA_PARAMS_SECTION_EXTRA), const std::vector &_heights, - const TopoDS_Shape &_plane) + const TopoDS_Shape §ion_plane) { TopoDS_Shape plane; gp_Trsf trsf; - if(!_plane.IsNull()) - findPlane(_plane,plane,trsf); + if(!section_plane.IsNull()) + plane = findPlane(section_plane,trsf); else plane = getPlane(&trsf); @@ -660,10 +665,15 @@ TopoDS_Shape Area::getPlane(gp_Trsf *trsf) { if(trsf) *trsf = myTrsf; return myWorkPlane; } - if(!isBuilt()) { - myShapePlane.Nullify(); - for(const Shape &s : myShapes) - findPlane(s.shape,myShapePlane,myTrsf); + if(myShapePlane.IsNull()) { + if(myShapes.empty()) + throw Base::ValueError("no shape added"); + double top_z; + for(auto &s : myShapes) { + if(!findPlane(s.shape,TopAbs_FACE,myShapePlane,myTrsf,top_z) && + !findPlane(s.shape,TopAbs_WIRE,myShapePlane,myTrsf,top_z)) + findPlane(s.shape,TopAbs_EDGE,myShapePlane,myTrsf,top_z); + } if(myShapePlane.IsNull()) throw Base::ValueError("shapes are not planar"); } diff --git a/src/Mod/Path/App/Area.h b/src/Mod/Path/App/Area.h index 3bad23531..de9cca972 100644 --- a/src/Mod/Path/App/Area.h +++ b/src/Mod/Path/App/Area.h @@ -148,6 +148,10 @@ protected: bool isBuilt() const; + static bool findPlane(const TopoDS_Shape &shape, int type, + TopoDS_Shape &plane, gp_Trsf &trsf, double &top_z); + TopoDS_Shape findPlane(const TopoDS_Shape &shape, gp_Trsf &trsf); + public: /** Declare all parameters defined in #AREA_PARAMS_ALL as member variable */ PARAM_ENUM_DECLARE(AREA_PARAMS_ALL) @@ -350,42 +354,6 @@ public: static void toPath(Toolpath &path, const std::list &shapes, const gp_Pnt *pstart=NULL, PARAM_ARGS_DEF(PARAM_FARG,AREA_PARAMS_PATH)); - - /** Explore the shape to find a planar element, and return its transformation - * - * \arg \c shape: shape to explore - * \arg \c type: OCC shape type (TopAbs_ShapeEnum) to explore - * \arg \c plane: returns the sub planar shape found - * \arg \c trsf: the transformation of the plane which will transform the - * plane into XY0 plane. - * - * If there are multiple subshapes on different planes. It will prefer the - * top XY plane. If there is no XY parallel plane, the first planar shape - * encountered will be returned - * - * \return Returns true is there is any subshape of the give type found. - * You should use plane.IsNull() to see if there is any planar shape found. - */ - static bool findPlane(const TopoDS_Shape &shape, int type, - TopoDS_Shape &plane, gp_Trsf &trsf); - - /** Explore the shape with subtype FACE, WIRE and EDGE to find a planar - * subshape - * - * \arg \c shape: shape to explore - * \arg \c plane: returns the sub planar shape found - * \arg \c trsf: the transformation of the plane which will transform the - * plane into XY0 plane. - * - * If there are multiple subshapes on different planes. It will prefer the - * top XY plane. If there is no XY parallel plane, the first planar shape - * encountered will be returned - * - * \return Returns true is there is any subshape is found. You should use - * plane.IsNull() to see if there is any planar shape found. - */ - static bool findPlane(const TopoDS_Shape &shape, - TopoDS_Shape &plane, gp_Trsf &trsf); }; } //namespace Path