From 115c7e4f882fcef594ff3266bb9880070c66f5b4 Mon Sep 17 00:00:00 2001 From: DeepSOIC Date: Sun, 2 Oct 2016 21:10:46 +0300 Subject: [PATCH] Part: FaceMaker: check if instance is actually created. Part::FaceMaker::ConstructFromType() could return null pointer if abstract class type is supplied. Here, it is fixed by checking for null pointer in facemaker itself, rather than in every place ConstructFromType is being used. --- src/Mod/Part/App/AppPartPy.cpp | 8 +------- src/Mod/Part/App/FaceMaker.cpp | 11 ++++++++--- src/Mod/Part/App/FeatureExtrusion.cpp | 5 ----- src/Mod/Part/App/FeatureFace.cpp | 5 ----- src/Mod/Part/App/FeatureRevolution.cpp | 5 ----- src/Mod/Part/App/TopoShapeFacePyImp.cpp | 8 +------- 6 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp index 14f6bd341b..6928a3d0c2 100644 --- a/src/Mod/Part/App/AppPartPy.cpp +++ b/src/Mod/Part/App/AppPartPy.cpp @@ -638,13 +638,7 @@ private: PyObject* pcPyShapeOrList = nullptr; PyErr_Clear(); if (PyArg_ParseTuple(args.ptr(), "Os", &pcPyShapeOrList, &className)) { - std::unique_ptr fm_instance = Part::FaceMaker::ConstructFromType(className); - FaceMaker* fm = fm_instance.get(); - if (!fm) { - std::stringstream out; - out << "Cannot create FaceMaker from abstract type " << className; - throw Base::TypeError(out.str()); - } + std::unique_ptr fm = Part::FaceMaker::ConstructFromType(className); //dump all supplied shapes to facemaker, no matter what type (let facemaker decide). if (PySequence_Check(pcPyShapeOrList)){ diff --git a/src/Mod/Part/App/FaceMaker.cpp b/src/Mod/Part/App/FaceMaker.cpp index de68e9fc85..b2ce2eb904 100644 --- a/src/Mod/Part/App/FaceMaker.cpp +++ b/src/Mod/Part/App/FaceMaker.cpp @@ -93,8 +93,7 @@ void Part::FaceMaker::Build() this->Build_Essence();//adds stuff to myShapesToReturn for(const TopoDS_Compound& cmp : this->myCompounds){ - std::unique_ptr facemaker_instance = Part::FaceMaker::ConstructFromType(this->getTypeId()); - FaceMaker* facemaker = &(*facemaker_instance); //handy to have plain pointer for intellisense to work =) + std::unique_ptr facemaker = Part::FaceMaker::ConstructFromType(this->getTypeId()); facemaker->useCompound(cmp); @@ -148,7 +147,13 @@ std::unique_ptr Part::FaceMaker::ConstructFromType(Base::Type t ss << "Class '" << type.getName() << "' is not derived from Part::FaceMaker."; throw Base::TypeError(ss.str().c_str()); } - return std::unique_ptr(static_cast(type.createInstance())); + std::unique_ptr instance(static_cast(type.createInstance())); + if (!instance){ + std::stringstream ss; + ss << "Cannot create FaceMaker from abstract type '" << type.getName() << "'"; + throw Base::TypeError(ss.str().c_str()); + } + return instance; } void Part::FaceMaker::throwNotImplemented() diff --git a/src/Mod/Part/App/FeatureExtrusion.cpp b/src/Mod/Part/App/FeatureExtrusion.cpp index e63f05561a..bb63c77bb6 100644 --- a/src/Mod/Part/App/FeatureExtrusion.cpp +++ b/src/Mod/Part/App/FeatureExtrusion.cpp @@ -301,11 +301,6 @@ TopoShape Extrusion::extrudeShape(const TopoShape source, Extrusion::ExtrusionPa } else { //new strict behavior. If solid==True => make faces from wires, and if myShape not wires - fail! std::unique_ptr mkFace = FaceMaker::ConstructFromType(params.faceMakerClass.c_str()); - if (!mkFace) { - std::stringstream out; - out << "Cannot create FaceMaker from abstract type " << params.faceMakerClass.c_str(); - throw Base::TypeError(out.str()); - } if (myShape.ShapeType() == TopAbs_COMPOUND) mkFace->useCompound(TopoDS::Compound(myShape)); diff --git a/src/Mod/Part/App/FeatureFace.cpp b/src/Mod/Part/App/FeatureFace.cpp index 52b80371b9..e98670f5b7 100644 --- a/src/Mod/Part/App/FeatureFace.cpp +++ b/src/Mod/Part/App/FeatureFace.cpp @@ -82,11 +82,6 @@ App::DocumentObjectExecReturn *Face::execute(void) return new App::DocumentObjectExecReturn("No shapes linked"); std::unique_ptr facemaker = FaceMaker::ConstructFromType(this->FaceMakerClass.getValue()); - if (!facemaker) { - std::stringstream out; - out << "Cannot create FaceMaker from abstract type " << this->FaceMakerClass.getValue(); - throw Base::TypeError(out.str()); - } for (std::vector::iterator it = links.begin(); it != links.end(); ++it) { if (!(*it && (*it)->isDerivedFrom(Part::Feature::getClassTypeId()))) diff --git a/src/Mod/Part/App/FeatureRevolution.cpp b/src/Mod/Part/App/FeatureRevolution.cpp index 65f2e247ae..dd8d5353be 100644 --- a/src/Mod/Part/App/FeatureRevolution.cpp +++ b/src/Mod/Part/App/FeatureRevolution.cpp @@ -171,11 +171,6 @@ App::DocumentObjectExecReturn *Revolution::execute(void) if (makeSolid && strlen(this->FaceMakerClass.getValue())>0){ //new facemaking behavior: use facemaker class std::unique_ptr mkFace = FaceMaker::ConstructFromType(this->FaceMakerClass.getValue()); - if (!mkFace) { - std::stringstream out; - out << "Cannot create FaceMaker from abstract type " << this->FaceMakerClass.getValue(); - throw Base::TypeError(out.str()); - } TopoDS_Shape myShape = sourceShape.getShape(); if(myShape.ShapeType() == TopAbs_COMPOUND) diff --git a/src/Mod/Part/App/TopoShapeFacePyImp.cpp b/src/Mod/Part/App/TopoShapeFacePyImp.cpp index 65ced48219..bdd2471485 100644 --- a/src/Mod/Part/App/TopoShapeFacePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeFacePyImp.cpp @@ -252,13 +252,7 @@ int TopoShapeFacePy::PyInit(PyObject* args, PyObject* /*kwd*/) PyErr_Clear(); if (PyArg_ParseTuple(args, "Os", &pcPyShapeOrList, &className)) { try { - std::unique_ptr fm_instance = Part::FaceMaker::ConstructFromType(className); - FaceMaker* fm = fm_instance.get(); - if (!fm) { - std::stringstream out; - out << "Cannot create FaceMaker from abstract type " << className; - throw Base::TypeError(out.str()); - } + std::unique_ptr fm = Part::FaceMaker::ConstructFromType(className); //dump all supplied shapes to facemaker, no matter what type (let facemaker decide). if (PySequence_Check(pcPyShapeOrList)){