fixes 0003771: Memory leak in Part.Face.Surface

This commit is contained in:
wmayer
2019-01-23 22:38:51 +01:00
parent 86d8372056
commit 2aee1e8368
5 changed files with 98 additions and 35 deletions

View File

@@ -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<PyObjectBase*>(value)->isConst()) {
if (!static_cast<PyObjectBase*>(value)->isConst() &&
!static_cast<PyObjectBase*>(value)->isNotTracking()) {
static_cast<PyObjectBase*>(value)->setAttributeOf(attr, pyObj);
pyObj->trackAttribute(attr, value);
}

View File

@@ -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:

View File

@@ -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");
}

View File

@@ -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");
}

View File

@@ -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<Part::ShapeSegment> s(static_cast<Part::ShapeSegment*>
(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<Part::ShapeSegment> s(static_cast<Part::ShapeSegment*>
(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<Part::ShapeSegment> s(static_cast<Part::ShapeSegment*>
(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) {