Skip to content

Commit

Permalink
Part: FaceMaker: check if instance is actually created.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
DeepSOIC authored and wwmayer committed Oct 4, 2016
1 parent 56b1530 commit 7b70711
Show file tree
Hide file tree
Showing 6 changed files with 10 additions and 32 deletions.
8 changes: 1 addition & 7 deletions src/Mod/Part/App/AppPartPy.cpp
Expand Up @@ -638,13 +638,7 @@ class Module : public Py::ExtensionModule<Module>
PyObject* pcPyShapeOrList = nullptr;
PyErr_Clear();
if (PyArg_ParseTuple(args.ptr(), "Os", &pcPyShapeOrList, &className)) {
std::unique_ptr<FaceMaker> 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<FaceMaker> fm = Part::FaceMaker::ConstructFromType(className);

//dump all supplied shapes to facemaker, no matter what type (let facemaker decide).
if (PySequence_Check(pcPyShapeOrList)){
Expand Down
11 changes: 8 additions & 3 deletions src/Mod/Part/App/FaceMaker.cpp
Expand Up @@ -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> facemaker_instance = Part::FaceMaker::ConstructFromType(this->getTypeId());
FaceMaker* facemaker = &(*facemaker_instance); //handy to have plain pointer for intellisense to work =)
std::unique_ptr<FaceMaker> facemaker = Part::FaceMaker::ConstructFromType(this->getTypeId());

facemaker->useCompound(cmp);

Expand Down Expand Up @@ -148,7 +147,13 @@ std::unique_ptr<Part::FaceMaker> 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<FaceMaker>(static_cast<Part::FaceMaker*>(type.createInstance()));
std::unique_ptr<FaceMaker> instance(static_cast<Part::FaceMaker*>(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()
Expand Down
5 changes: 0 additions & 5 deletions src/Mod/Part/App/FeatureExtrusion.cpp
Expand Up @@ -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<FaceMaker> 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));
Expand Down
5 changes: 0 additions & 5 deletions src/Mod/Part/App/FeatureFace.cpp
Expand Up @@ -82,11 +82,6 @@ App::DocumentObjectExecReturn *Face::execute(void)
return new App::DocumentObjectExecReturn("No shapes linked");

std::unique_ptr<FaceMaker> 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<App::DocumentObject*>::iterator it = links.begin(); it != links.end(); ++it) {
if (!(*it && (*it)->isDerivedFrom(Part::Feature::getClassTypeId())))
Expand Down
5 changes: 0 additions & 5 deletions src/Mod/Part/App/FeatureRevolution.cpp
Expand Up @@ -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<FaceMaker> 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)
Expand Down
8 changes: 1 addition & 7 deletions src/Mod/Part/App/TopoShapeFacePyImp.cpp
Expand Up @@ -252,13 +252,7 @@ int TopoShapeFacePy::PyInit(PyObject* args, PyObject* /*kwd*/)
PyErr_Clear();
if (PyArg_ParseTuple(args, "Os", &pcPyShapeOrList, &className)) {
try {
std::unique_ptr<FaceMaker> 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<FaceMaker> fm = Part::FaceMaker::ConstructFromType(className);

//dump all supplied shapes to facemaker, no matter what type (let facemaker decide).
if (PySequence_Check(pcPyShapeOrList)){
Expand Down

0 comments on commit 7b70711

Please sign in to comment.