[TD] avoid memory leaks by using shared_ptr

TD geometry objects are sometimes double deleted.  This
change uses shared_ptr instead of raw pointers to manage
deletions.
This commit is contained in:
Wanderer Fan
2022-01-02 10:12:56 -05:00
committed by WandererFan
parent ad2169e5ae
commit 28c5890bc9
34 changed files with 290 additions and 279 deletions

View File

@@ -106,7 +106,7 @@ Wire::Wire(const TopoDS_Wire &w)
TopExp_Explorer edges(w, TopAbs_EDGE);
for (; edges.More(); edges.Next()) {
const auto edge( TopoDS::Edge(edges.Current()) );
BaseGeom* bg = BaseGeom::baseFactory(edge);
BaseGeomPtr bg = BaseGeom::baseFactory(edge);
if (bg != nullptr) {
geoms.push_back(bg);
} else {
@@ -117,9 +117,7 @@ Wire::Wire(const TopoDS_Wire &w)
Wire::~Wire()
{
for(auto it : geoms) {
delete it;
}
//shared_ptr to geoms should free memory when ref count goes to zero
geoms.clear();
}
@@ -186,9 +184,9 @@ BaseGeom::BaseGeom() :
cosmeticTag = std::string();
}
BaseGeom* BaseGeom::copy()
BaseGeomPtr BaseGeom::copy()
{
BaseGeom* result = nullptr;
BaseGeomPtr result;
if (!occEdge.IsNull()) {
result = baseFactory(occEdge);
if (result != nullptr) {
@@ -203,7 +201,7 @@ BaseGeom* BaseGeom::copy()
result->cosmeticTag = cosmeticTag;
}
} else {
result = new BaseGeom();
result = std::make_shared<BaseGeom>();
result->extractType = extractType;
result->classOfEdge = classOfEdge;
result->hlrVisible = hlrVisible;
@@ -388,7 +386,7 @@ double BaseGeom::minDist(Base::Vector3d p)
}
//!find point on me nearest to p
Base::Vector3d BaseGeom::nearPoint(const BaseGeom* p)
Base::Vector3d BaseGeom::nearPoint(const BaseGeomPtr p)
{
Base::Vector3d result(0.0, 0.0, 0.0);
TopoDS_Edge pEdge = p->occEdge;
@@ -449,9 +447,8 @@ bool BaseGeom::closed(void)
//! Convert 1 OCC edge into 1 BaseGeom (static factory method)
BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
BaseGeomPtr BaseGeom::baseFactory(TopoDS_Edge edge)
{
std::unique_ptr<BaseGeom> result;
if (edge.IsNull()) {
Base::Console().Message("BG::baseFactory - input edge is NULL \n");
}
@@ -460,7 +457,7 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
return nullptr;
}
result = std::make_unique<Generic>(edge);
BaseGeomPtr result = std::make_shared<Generic> (edge);
BRepAdaptor_Curve adapt(edge);
switch(adapt.GetType()) {
@@ -474,9 +471,9 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
//if first to last is > 1 radian? are circles parameterize by rotation angle?
//if start and end points are close?
if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
result = std::make_unique<Circle>(edge);
result = std::make_shared<Circle>(edge);
} else {
result = std::make_unique<AOC>(edge);
result = std::make_shared<AOC>(edge);
}
} break;
case GeomAbs_Ellipse: {
@@ -485,15 +482,15 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
gp_Pnt s = adapt.Value(f);
gp_Pnt e = adapt.Value(l);
if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
result = std::make_unique<Ellipse>(edge);
result = std::make_shared<Ellipse>(edge);
} else {
result = std::make_unique<AOE>(edge);
result = std::make_shared<AOE>(edge);
}
} break;
case GeomAbs_BezierCurve: {
Handle(Geom_BezierCurve) bez = adapt.Bezier();
//if (bez->Degree() < 4) {
result = std::make_unique<BezierSegment>(edge);
result = std::make_shared<BezierSegment>(edge);
if (edge.Orientation() == TopAbs_REVERSED) {
result->reversed = true;
}
@@ -501,25 +498,24 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
// OCC is quite happy with Degree > 3 but QtGui handles only 2,3
} break;
case GeomAbs_BSplineCurve: {
std::unique_ptr<BSpline> bspline;
TopoDS_Edge circEdge;
bool isArc = false;
try {
bspline = std::make_unique<BSpline>(edge);
BSplinePtr bspline = std::make_shared<BSpline>(edge);
if (bspline->isLine()) {
result = std::make_unique<Generic>(edge);
result = std::make_shared<Generic>(edge);
} else {
circEdge = bspline->asCircle(isArc);
if (!circEdge.IsNull()) {
if (isArc) {
result = std::make_unique<AOC>(circEdge);
result = std::make_shared<AOC>(circEdge);
} else {
result = std::make_unique<Circle>(circEdge);
result = std::make_shared<Circle>(circEdge);
}
} else {
// Base::Console().Message("Geom::baseFactory - circEdge is Null\n");
result = std::move(bspline);
result = bspline;
}
}
break;
@@ -538,8 +534,8 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
result = std::make_unique<Generic>(edge);
} break;
}
return result.release();
return result;
}
bool BaseGeom::validateEdge(TopoDS_Edge edge)
@@ -1011,7 +1007,7 @@ double Generic::slope(void)
return slope;
}
Base::Vector3d Generic::apparentInter(Generic* g)
Base::Vector3d Generic::apparentInter(GenericPtr g)
{
Base::Vector3d dir0 = asVector();
Base::Vector3d dir1 = g->asVector();
@@ -1575,7 +1571,7 @@ BaseGeomPtrVector GeometryUtils::chainGeoms(BaseGeomPtrVector geoms)
for (unsigned int i = 1; i < geoms.size(); i++) { //do size-1 more edges
auto next( nextGeom(atPoint, geoms, used, Precision::Confusion()) );
if (next.index) { //found an unused edge with vertex == atPoint
BaseGeom* nextEdge = geoms.at(next.index);
BaseGeomPtr nextEdge = geoms.at(next.index);
used[next.index] = true;
nextEdge->reversed = next.reversed;
result.push_back(nextEdge);
@@ -1621,7 +1617,7 @@ BaseGeomPtrVector GeometryUtils::chainGeoms(BaseGeomPtrVector geoms)
return result;
}
TopoDS_Edge GeometryUtils::edgeFromGeneric(TechDraw::Generic* g)
TopoDS_Edge GeometryUtils::edgeFromGeneric(TechDraw::GenericPtr g)
{
// Base::Console().Message("GU::edgeFromGeneric()\n");
//TODO: note that this isn't quite right as g can be a polyline!
@@ -1635,7 +1631,7 @@ TopoDS_Edge GeometryUtils::edgeFromGeneric(TechDraw::Generic* g)
return e;
}
TopoDS_Edge GeometryUtils::edgeFromCircle(TechDraw::Circle* c)
TopoDS_Edge GeometryUtils::edgeFromCircle(TechDraw::CirclePtr c)
{
gp_Pnt loc(c->center.x, c->center.y, c->center.z);
gp_Dir dir(0,0,1);
@@ -1649,7 +1645,7 @@ TopoDS_Edge GeometryUtils::edgeFromCircle(TechDraw::Circle* c)
return e;
}
TopoDS_Edge GeometryUtils::edgeFromCircleArc(TechDraw::AOC* c)
TopoDS_Edge GeometryUtils::edgeFromCircleArc(TechDraw::AOCPtr c)
{
gp_Pnt loc(c->center.x, c->center.y, c->center.z);
gp_Dir dir(0,0,1);