handle possible crashes with FaceMaker and fix a few coding flaws

This commit is contained in:
wmayer 2016-10-02 14:47:59 +02:00
parent 65a935f9ae
commit c833136cde
11 changed files with 48 additions and 28 deletions

View File

@ -633,14 +633,18 @@ private:
}
Py::Object makeFace(const Py::Tuple& args)
{
try{
try {
char* className = 0;
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);
FaceMaker* fm = fm_instance.get();
if (!fm) {
std::stringstream out;
out << "Cannot create FaceMaker from abstract type " << className;
throw Base::TypeError(out.str());
}
//dump all supplied shapes to facemaker, no matter what type (let facemaker decide).
if (PySequence_Check(pcPyShapeOrList)){
@ -651,7 +655,7 @@ private:
const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->getShape();
fm->addShape(sh);
} else {
throw Py::Exception(PyExc_TypeError, "Object is not a shape.");
throw Py::TypeError("Object is not a shape.");
}
}
} else if (PyObject_TypeCheck(pcPyShapeOrList, &(Part::TopoShapePy::Type))) {
@ -674,14 +678,12 @@ private:
switch(fm->Shape().ShapeType()){
case TopAbs_FACE:
return Py::asObject(new TopoShapeFacePy(new TopoShape(fm->Shape())));
break;
case TopAbs_COMPOUND:
return Py::asObject(new TopoShapeCompoundPy(new TopoShape(fm->Shape())));
break;
default:
return Py::asObject(new TopoShapePy(new TopoShape(fm->Shape())));
}
} ;
}
throw Py::Exception(Base::BaseExceptionFreeCADError, std::string("Argument type signature not recognized. Should be either (list, string), or (shape, string)"));

View File

@ -136,7 +136,7 @@ std::unique_ptr<Part::FaceMaker> Part::FaceMaker::ConstructFromType(const char*
if (fmType.isBad()){
std::stringstream ss;
ss << "Class '"<< className <<"' not found.";
throw Base::Exception(ss.str().c_str());
throw Base::TypeError(ss.str().c_str());
}
return Part::FaceMaker::ConstructFromType(fmType);
}

View File

@ -47,8 +47,8 @@ class PartExport FaceMaker: public BRepBuilderAPI_MakeShape, public Base::BaseCl
TYPESYSTEM_HEADER();
public:
FaceMaker() {};
virtual ~FaceMaker() {};
FaceMaker() {}
virtual ~FaceMaker() {}
virtual void addWire(const TopoDS_Wire& w);
/**

View File

@ -110,7 +110,7 @@ void FaceMakerBullseye::Build_Essence()
//add wires one by one to current set of faces.
//We go from last to first, to make it so that outer wires come before inner wires.
std::vector< std::unique_ptr<FaceDriller> > faces;
for( int i = wires.size()-1 ; i >= 0 ; --i){
for (int i = static_cast<int>(wires.size())-1; i >= 0; --i) {
TopoDS_Wire &w = wires[i];
//test if this wire is on any of existing faces (if yes, it's a hole;

View File

@ -300,10 +300,14 @@ TopoShape Extrusion::extrudeShape(const TopoShape source, Extrusion::ExtrusionPa
//legacy exclusion: ignore "solid" if extruding a face.
} else {
//new strict behavior. If solid==True => make faces from wires, and if myShape not wires - fail!
std::unique_ptr<FaceMaker> fm_instance = FaceMaker::ConstructFromType(params.faceMakerClass.c_str());
FaceMaker* mkFace = &(*(fm_instance));
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)
if (myShape.ShapeType() == TopAbs_COMPOUND)
mkFace->useCompound(TopoDS::Compound(myShape));
else
mkFace->addShape(myShape);
@ -500,7 +504,7 @@ void Extrusion::makeDraft(ExtrusionParameters params, const TopoDS_Shape& shape,
//----------------------------------------------------------------
TYPESYSTEM_SOURCE(Part::FaceMakerExtrusion, Part::FaceMakerCheese);
TYPESYSTEM_SOURCE(Part::FaceMakerExtrusion, Part::FaceMakerCheese)
std::string FaceMakerExtrusion::getUserFriendlyName() const
{

View File

@ -142,7 +142,7 @@ public:
virtual void Build() override;
protected:
virtual void Build_Essence() override {};
virtual void Build_Essence() override {}
};
} //namespace Part

View File

@ -81,8 +81,12 @@ App::DocumentObjectExecReturn *Face::execute(void)
if (links.empty())
return new App::DocumentObjectExecReturn("No shapes linked");
std::unique_ptr<FaceMaker> fm_instance = FaceMaker::ConstructFromType(this->FaceMakerClass.getValue());
FaceMaker* facemaker = &(*(fm_instance));
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())))

View File

@ -170,8 +170,13 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
Standard_Boolean makeSolid = Solid.getValue() ? Standard_True : Standard_False;
if (makeSolid && strlen(this->FaceMakerClass.getValue())>0){
//new facemaking behavior: use facemaker class
std::unique_ptr<FaceMaker> fm_instance = FaceMaker::ConstructFromType(this->FaceMakerClass.getValue());
FaceMaker* mkFace = &(*(fm_instance));
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)
mkFace->useCompound(TopoDS::Compound(myShape));

View File

@ -2223,11 +2223,11 @@ TopoDS_Shape TopoShape::makeOffset2D(double offset, short joinType, bool fill, b
//so, we just extract all nesting
Handle_TopTools_HSequenceOfShape seq = ShapeExtend_Explorer().SeqFromCompound(offsetShape, Standard_True);
TopoDS_Iterator it(offsetShape);
for(int i = 0 ; i < seq->Length() ; ++i){
for(int i = 0; i < seq->Length(); ++i){
offsetWires.push_back(TopoDS::Wire(seq->Value(i+1)));
}
if(offsetWires.empty())
if (offsetWires.empty())
throw Base::Exception("makeOffset2D: offset result has no wires.");
std::list<TopoDS_Wire> wiresForMakingFaces;
@ -2357,7 +2357,7 @@ TopoDS_Shape TopoShape::makeOffset2D(double offset, short joinType, bool fill, b
ShapeExtend_Explorer xp;
Handle_TopTools_HSequenceOfShape result_leaves = xp.SeqFromCompound(result, Standard_True);
for(int i = 0 ; i < result_leaves->Length() ; ++i)
for(int i = 0; i < result_leaves->Length(); ++i)
shapesToReturn.push_back(result_leaves->Value(i+1));
}
}

View File

@ -251,9 +251,14 @@ int TopoShapeFacePy::PyInit(PyObject* args, PyObject* /*kwd*/)
PyObject* pcPyShapeOrList = nullptr;
PyErr_Clear();
if (PyArg_ParseTuple(args, "Os", &pcPyShapeOrList, &className)) {
try{
try {
std::unique_ptr<FaceMaker> fm_instance = Part::FaceMaker::ConstructFromType(className);
FaceMaker* fm = &(*fm_instance);
FaceMaker* fm = fm_instance.get();
if (!fm) {
std::stringstream out;
out << "Cannot create FaceMaker from abstract type " << className;
throw Base::TypeError(out.str());
}
//dump all supplied shapes to facemaker, no matter what type (let facemaker decide).
if (PySequence_Check(pcPyShapeOrList)){
@ -293,7 +298,7 @@ int TopoShapeFacePy::PyInit(PyObject* args, PyObject* /*kwd*/)
PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
return -1;
}
} ;
}
PyErr_SetString(PartExceptionOCCError,
"Argument list signature is incorrect.\n\nSupported signatures:\n"

View File

@ -321,7 +321,7 @@ void DlgExtrusion::autoSolid()
ShapeExtend_Explorer xp;
Handle_TopTools_HSequenceOfShape leaves = xp.SeqFromCompound(sh, /*recursive= */Standard_True);
int cntClosedWires = 0;
for(int i = 0 ; i < leaves->Length() ; i++){
for(int i = 0; i < leaves->Length(); i++){
const TopoDS_Shape &leaf = leaves->Value(i+1);
if (leaf.IsNull())
return;
@ -333,7 +333,7 @@ void DlgExtrusion::autoSolid()
}
ui->chkSolid->setChecked( cntClosedWires == leaves->Length() );
}
} catch(...){
} catch(...) {
}
}