diff --git a/src/Base/PyObjectBase.cpp b/src/Base/PyObjectBase.cpp index 5b724dc6a8..eecb4ce7e5 100644 --- a/src/Base/PyObjectBase.cpp +++ b/src/Base/PyObjectBase.cpp @@ -177,7 +177,8 @@ PyObject* PyObjectBase::__getattro(PyObject * obj, PyObject *attro) PyObject* value = pyObj->_getattr(attr); #if 1 if (value && PyObject_TypeCheck(value, &(PyObjectBase::Type))) { - if (!static_cast(value)->isConst()) { + if (!static_cast(value)->isConst() && + !static_cast(value)->isNotTracking()) { static_cast(value)->setAttributeOf(attr, pyObj); pyObj->trackAttribute(attr, value); } diff --git a/src/Base/PyObjectBase.h b/src/Base/PyObjectBase.h index 7c8fc60f07..eef000e8c3 100644 --- a/src/Base/PyObjectBase.h +++ b/src/Base/PyObjectBase.h @@ -201,7 +201,8 @@ class BaseExport PyObjectBase : public PyObject enum Status { Valid = 0, Immutable = 1, - Notify = 2 + Notify = 2, + NoTrack = 3 }; protected: @@ -313,6 +314,14 @@ public: void startNotify(); + void setNotTracking(bool on=true) { + StatusBits.set(NoTrack, on); + } + + bool isNotTracking() const { + return StatusBits.test(NoTrack); + } + typedef void* PointerType; private: diff --git a/src/Mod/Part/App/TopoShapeEdgePyImp.cpp b/src/Mod/Part/App/TopoShapeEdgePyImp.cpp index 107f2e28fc..d93ae68683 100644 --- a/src/Mod/Part/App/TopoShapeEdgePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeEdgePyImp.cpp @@ -775,6 +775,7 @@ Py::Object TopoShapeEdgePy::getCurve() const { const TopoDS_Edge& e = TopoDS::Edge(getTopoShapePtr()->getShape()); BRepAdaptor_Curve adapt(e); + Base::PyObjectBase* curve = nullptr; switch(adapt.GetType()) { case GeomAbs_Line: @@ -805,14 +806,16 @@ Py::Object TopoShapeEdgePy::getCurve() const "To suppress the warning set BaseApp/Preferences/Mod/Part/General/LineOld to false"); PyErr_Print(); - return Py::Object(new LineSegmentPy(line),true); // LinePyOld + curve = new LineSegmentPy(line); // LinePyOld + break; } else { GeomLine* line = new GeomLine(); Handle(Geom_Line) this_curv = Handle(Geom_Line)::DownCast (line->handle()); this_curv->SetLin(adapt.Line()); - return Py::Object(new LinePy(line),true); + curve = new LinePy(line); + break; } } case GeomAbs_Circle: @@ -823,7 +826,8 @@ Py::Object TopoShapeEdgePy::getCurve() const this_curv->SetCirc(adapt.Circle()); //Standard_Real dd = adapt.FirstParameter(); //Standard_Real ee = adapt.LastParameter(); - return Py::Object(new CirclePy(circle),true); + curve = new CirclePy(circle); + break; } case GeomAbs_Ellipse: { @@ -831,7 +835,8 @@ Py::Object TopoShapeEdgePy::getCurve() const Handle(Geom_Ellipse) this_curv = Handle(Geom_Ellipse)::DownCast (elips->handle()); this_curv->SetElips(adapt.Ellipse()); - return Py::Object(new EllipsePy(elips),true); + curve = new EllipsePy(elips); + break; } case GeomAbs_Hyperbola: { @@ -839,7 +844,8 @@ Py::Object TopoShapeEdgePy::getCurve() const Handle(Geom_Hyperbola) this_curv = Handle(Geom_Hyperbola)::DownCast (hypr->handle()); this_curv->SetHypr(adapt.Hyperbola()); - return Py::Object(new HyperbolaPy(hypr),true); + curve = new HyperbolaPy(hypr); + break; } case GeomAbs_Parabola: { @@ -847,17 +853,20 @@ Py::Object TopoShapeEdgePy::getCurve() const Handle(Geom_Parabola) this_curv = Handle(Geom_Parabola)::DownCast (parab->handle()); this_curv->SetParab(adapt.Parabola()); - return Py::Object(new ParabolaPy(parab),true); + curve = new ParabolaPy(parab); + break; } case GeomAbs_BezierCurve: { - GeomBezierCurve* curve = new GeomBezierCurve(adapt.Bezier()); - return Py::Object(new BezierCurvePy(curve),true); + GeomBezierCurve* bezier = new GeomBezierCurve(adapt.Bezier()); + curve = new BezierCurvePy(bezier); + break; } case GeomAbs_BSplineCurve: { - GeomBSplineCurve* curve = new GeomBSplineCurve(adapt.BSpline()); - return Py::Object(new BSplineCurvePy(curve),true); + GeomBSplineCurve* bspline = new GeomBSplineCurve(adapt.BSpline()); + curve = new BSplineCurvePy(bspline); + break; } #if OCC_VERSION_HEX >= 0x070000 case GeomAbs_OffsetCurve: @@ -866,8 +875,9 @@ Py::Object TopoShapeEdgePy::getCurve() const Handle(Geom_Curve) c = BRep_Tool::Curve(e, first, last); Handle(Geom_OffsetCurve) off = Handle(Geom_OffsetCurve)::DownCast(c); if (!off.IsNull()) { - GeomOffsetCurve* curve = new GeomOffsetCurve(off); - return Py::Object(new OffsetCurvePy(curve),true); + GeomOffsetCurve* offset = new GeomOffsetCurve(off); + curve = new OffsetCurvePy(offset); + break; } else { throw Py::RuntimeError("Failed to convert to offset curve"); @@ -878,6 +888,11 @@ Py::Object TopoShapeEdgePy::getCurve() const break; } + if (curve) { + curve->setNotTracking(); + return Py::asObject(curve); + } + throw Py::TypeError("undefined curve type"); } diff --git a/src/Mod/Part/App/TopoShapeFacePyImp.cpp b/src/Mod/Part/App/TopoShapeFacePyImp.cpp index 8201f66885..b3d5c2da1f 100644 --- a/src/Mod/Part/App/TopoShapeFacePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeFacePyImp.cpp @@ -695,6 +695,7 @@ Py::Object TopoShapeFacePy::getSurface() const { const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->getShape()); BRepAdaptor_Surface adapt(f); + Base::PyObjectBase* surface = 0; switch(adapt.GetType()) { case GeomAbs_Plane: @@ -703,7 +704,8 @@ Py::Object TopoShapeFacePy::getSurface() const Handle(Geom_Plane) this_surf = Handle(Geom_Plane)::DownCast (plane->handle()); this_surf->SetPln(adapt.Plane()); - return Py::Object(new PlanePy(plane),true); + surface = new PlanePy(plane); + break; } case GeomAbs_Cylinder: { @@ -711,7 +713,8 @@ Py::Object TopoShapeFacePy::getSurface() const Handle(Geom_CylindricalSurface) this_surf = Handle(Geom_CylindricalSurface)::DownCast (cylinder->handle()); this_surf->SetCylinder(adapt.Cylinder()); - return Py::Object(new CylinderPy(cylinder),true); + surface = new CylinderPy(cylinder); + break; } case GeomAbs_Cone: { @@ -719,7 +722,8 @@ Py::Object TopoShapeFacePy::getSurface() const Handle(Geom_ConicalSurface) this_surf = Handle(Geom_ConicalSurface)::DownCast (cone->handle()); this_surf->SetCone(adapt.Cone()); - return Py::Object(new ConePy(cone),true); + surface = new ConePy(cone); + break; } case GeomAbs_Sphere: { @@ -727,7 +731,8 @@ Py::Object TopoShapeFacePy::getSurface() const Handle(Geom_SphericalSurface) this_surf = Handle(Geom_SphericalSurface)::DownCast (sphere->handle()); this_surf->SetSphere(adapt.Sphere()); - return Py::Object(new SpherePy(sphere),true); + surface = new SpherePy(sphere); + break; } case GeomAbs_Torus: { @@ -735,17 +740,20 @@ Py::Object TopoShapeFacePy::getSurface() const Handle(Geom_ToroidalSurface) this_surf = Handle(Geom_ToroidalSurface)::DownCast (toroid->handle()); this_surf->SetTorus(adapt.Torus()); - return Py::Object(new ToroidPy(toroid),true); + surface = new ToroidPy(toroid); + break; } case GeomAbs_BezierSurface: { GeomBezierSurface* surf = new GeomBezierSurface(adapt.Bezier()); - return Py::Object(new BezierSurfacePy(surf),true); + surface = new BezierSurfacePy(surf); + break; } case GeomAbs_BSplineSurface: { GeomBSplineSurface* surf = new GeomBSplineSurface(adapt.BSpline()); - return Py::Object(new BSplineSurfacePy(surf),true); + surface = new BSplineSurfacePy(surf); + break; } case GeomAbs_SurfaceOfRevolution: { @@ -757,7 +765,8 @@ Py::Object TopoShapeFacePy::getSurface() const } if (!rev.IsNull()) { GeomSurfaceOfRevolution* surf = new GeomSurfaceOfRevolution(rev); - return Py::Object(new SurfaceOfRevolutionPy(surf),true); + surface = new SurfaceOfRevolutionPy(surf); + break; } else { throw Py::RuntimeError("Failed to convert to surface of revolution"); @@ -773,7 +782,8 @@ Py::Object TopoShapeFacePy::getSurface() const } if (!ext.IsNull()) { GeomSurfaceOfExtrusion* surf = new GeomSurfaceOfExtrusion(ext); - return Py::Object(new SurfaceOfExtrusionPy(surf),true); + surface = new SurfaceOfExtrusionPy(surf); + break; } else { throw Py::RuntimeError("Failed to convert to surface of extrusion"); @@ -789,7 +799,8 @@ Py::Object TopoShapeFacePy::getSurface() const } if (!off.IsNull()) { GeomOffsetSurface* surf = new GeomOffsetSurface(off); - return Py::Object(new OffsetSurfacePy(surf),true); + surface = new OffsetSurfacePy(surf); + break; } else { throw Py::RuntimeError("Failed to convert to offset surface"); @@ -799,6 +810,11 @@ Py::Object TopoShapeFacePy::getSurface() const break; } + if (surface) { + surface->setNotTracking(); + return Py::asObject(surface); + } + throw Py::TypeError("undefined surface type"); } diff --git a/src/Mod/Part/App/TopoShapePyImp.cpp b/src/Mod/Part/App/TopoShapePyImp.cpp index 5255b92fb8..dc1deb386e 100644 --- a/src/Mod/Part/App/TopoShapePyImp.cpp +++ b/src/Mod/Part/App/TopoShapePyImp.cpp @@ -2862,7 +2862,9 @@ Py::List TopoShapePy::getFaces(void) const for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); - ret.append(Py::Object(new TopoShapeFacePy(new TopoShape(shape)),true)); + Base::PyObjectBase* face = new TopoShapeFacePy(new TopoShape(shape)); + face->setNotTracking(); + ret.append(Py::asObject(face)); } return ret; @@ -2883,7 +2885,9 @@ Py::List TopoShapePy::getVertexes(void) const for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); - ret.append(Py::Object(new TopoShapeVertexPy(new TopoShape(shape)),true)); + Base::PyObjectBase* vertex = new TopoShapeVertexPy(new TopoShape(shape)); + vertex->setNotTracking(); + ret.append(Py::asObject(vertex)); } return ret; @@ -2904,7 +2908,9 @@ Py::List TopoShapePy::getShells(void) const for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); - ret.append(Py::Object(new TopoShapeShellPy(new TopoShape(shape)),true)); + Base::PyObjectBase* shell = new TopoShapeShellPy(new TopoShape(shape)); + shell->setNotTracking(); + ret.append(Py::asObject(shell)); } return ret; @@ -2925,7 +2931,9 @@ Py::List TopoShapePy::getSolids(void) const for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); - ret.append(Py::Object(new TopoShapeSolidPy(new TopoShape(shape)),true)); + Base::PyObjectBase* solid = new TopoShapeSolidPy(new TopoShape(shape)); + solid->setNotTracking(); + ret.append(Py::asObject(solid)); } return ret; @@ -2946,7 +2954,9 @@ Py::List TopoShapePy::getCompSolids(void) const for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); - ret.append(Py::Object(new TopoShapeCompSolidPy(new TopoShape(shape)),true)); + Base::PyObjectBase* comps = new TopoShapeCompSolidPy(new TopoShape(shape)); + comps->setNotTracking(); + ret.append(Py::asObject(comps)); } return ret; @@ -2967,7 +2977,9 @@ Py::List TopoShapePy::getEdges(void) const for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); - ret.append(Py::Object(new TopoShapeEdgePy(new TopoShape(shape)),true)); + Base::PyObjectBase* edge = new TopoShapeEdgePy(new TopoShape(shape)); + edge->setNotTracking(); + ret.append(Py::asObject(edge)); } return ret; @@ -2988,7 +3000,9 @@ Py::List TopoShapePy::getWires(void) const for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); - ret.append(Py::Object(new TopoShapeWirePy(new TopoShape(shape)),true)); + Base::PyObjectBase* wire = new TopoShapeWirePy(new TopoShape(shape)); + wire->setNotTracking(); + ret.append(Py::asObject(wire)); } return ret; @@ -3009,7 +3023,9 @@ Py::List TopoShapePy::getCompounds(void) const for (Standard_Integer k = 1; k <= M.Extent(); k++) { const TopoDS_Shape& shape = M(k); - ret.append(Py::Object(new TopoShapeCompoundPy(new TopoShape(shape)),true)); + Base::PyObjectBase* comp = new TopoShapeCompoundPy(new TopoShape(shape)); + comp->setNotTracking(); + ret.append(Py::asObject(comp)); } return ret; @@ -3054,19 +3070,25 @@ PyObject *TopoShapePy::getCustomAttributes(const char* attr) const std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(attr))); TopoDS_Shape Shape = s->Shape; - return new TopoShapeFacePy(new TopoShape(Shape)); + TopoShapeFacePy* face = new TopoShapeFacePy(new TopoShape(Shape)); + face->setNotTracking(); + return face; } else if (name.size() > 4 && name.substr(0,4) == "Edge" && name[4]>=48 && name[4]<=57) { std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(attr))); TopoDS_Shape Shape = s->Shape; - return new TopoShapeEdgePy(new TopoShape(Shape)); + TopoShapeEdgePy* edge = new TopoShapeEdgePy(new TopoShape(Shape)); + edge->setNotTracking(); + return edge; } else if (name.size() > 6 && name.substr(0,6) == "Vertex" && name[6]>=48 && name[6]<=57) { std::unique_ptr s(static_cast (getTopoShapePtr()->getSubElementByName(attr))); TopoDS_Shape Shape = s->Shape; - return new TopoShapeVertexPy(new TopoShape(Shape)); + TopoShapeVertexPy* vertex = new TopoShapeVertexPy(new TopoShape(Shape)); + vertex->setNotTracking(); + return vertex; } } catch (Standard_Failure& e) {