From 7b70711fb374d1896d7b7ec5791e68e2833b3855 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 14f6bd341..6928a3d0c 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 de68e9fc8..b2ce2eb90 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 e63f05561..bb63c77bb 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 52b80371b..e98670f5b 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 65f2e247a..dd8d5353b 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 65ced4821..bdd247148 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)){