diff --git a/src/Mod/PartDesign/App/FeatureGroove.cpp b/src/Mod/PartDesign/App/FeatureGroove.cpp index 503a0f24a..017f93a14 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.cpp +++ b/src/Mod/PartDesign/App/FeatureGroove.cpp @@ -132,24 +132,26 @@ App::DocumentObjectExecReturn *Groove::execute(void) Base::Vector3f v = Axis.getValue(); gp_Dir dir(v.x,v.y,v.z); - TopoDS_Shape aFace = makeFace(wires); - if (aFace.IsNull()) - return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); - - // Rotate the face by half the angle to get Groove symmetric to sketch plane - if (Midplane.getValue()) { - gp_Trsf mov; - mov.SetRotation(gp_Ax1(pnt, dir), Base::toRadians(Angle.getValue()) * (-1.0) / 2.0); - TopLoc_Location loc(mov); - aFace.Move(loc); - } - - this->positionBySketch(); - TopLoc_Location invObjLoc = this->getLocation().Inverted(); - pnt.Transform(invObjLoc.Transformation()); - dir.Transform(invObjLoc.Transformation()); - try { + // TopoDS::Face is not strictly necessary, but it will through an exception for + // invalid wires e.g. intersections or multiple separate wires + TopoDS_Shape aFace = TopoDS::Face(makeFace(wires)); + if (aFace.IsNull()) + return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); + + // Rotate the face by half the angle to get Groove symmetric to sketch plane + if (Midplane.getValue()) { + gp_Trsf mov; + mov.SetRotation(gp_Ax1(pnt, dir), Base::toRadians(Angle.getValue()) * (-1.0) / 2.0); + TopLoc_Location loc(mov); + aFace.Move(loc); + } + + this->positionBySketch(); + TopLoc_Location invObjLoc = this->getLocation().Inverted(); + pnt.Transform(invObjLoc.Transformation()); + dir.Transform(invObjLoc.Transformation()); + // revolve the face to a solid BRepPrimAPI_MakeRevol RevolMaker(aFace.Moved(invObjLoc), gp_Ax1(pnt, dir), angle); @@ -179,7 +181,11 @@ App::DocumentObjectExecReturn *Groove::execute(void) } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); - return new App::DocumentObjectExecReturn(e->GetMessageString()); + if (std::string(e->GetMessageString()) == "TopoDS::Face") + return new App::DocumentObjectExecReturn("Could not create face from sketch.\n" + "Intersecting sketch entities or multiple faces in a sketch are not allowed."); + else + return new App::DocumentObjectExecReturn(e->GetMessageString()); } } diff --git a/src/Mod/PartDesign/App/FeaturePad.cpp b/src/Mod/PartDesign/App/FeaturePad.cpp index 4a62b3726..5a9733b92 100644 --- a/src/Mod/PartDesign/App/FeaturePad.cpp +++ b/src/Mod/PartDesign/App/FeaturePad.cpp @@ -104,14 +104,16 @@ App::DocumentObjectExecReturn *Pad::execute(void) Base::Vector3d SketchVector(0,0,1); SketchOrientation.multVec(SketchVector,SketchVector); - TopoDS_Shape aFace = makeFace(wires); - if (aFace.IsNull()) - return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); - this->positionBySketch(); TopLoc_Location invObjLoc = this->getLocation().Inverted(); try { + // TopoDS::Face is not strictly necessary, but it will through an exception for + // invalid wires e.g. intersections or multiple separate wires + TopoDS_Shape aFace = TopoDS::Face(makeFace(wires)); + if (aFace.IsNull()) + return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); + // extrude the face to a solid TopoDS_Shape prism; bool isSolid = false; // support is a solid? @@ -252,7 +254,7 @@ App::DocumentObjectExecReturn *Pad::execute(void) // set the additive shape property for later usage in e.g. pattern this->AddShape.setValue(prism); - // if the sketch has a support fuse them to get one result object (PAD!) + // if the sketch has a support fuse them to get one result object if (!support.IsNull()) { if (!isSolidChecked) { // we haven't checked for solid, yet @@ -275,7 +277,7 @@ App::DocumentObjectExecReturn *Pad::execute(void) if (!mkFuse.IsDone()) return new App::DocumentObjectExecReturn("Pad: Fusion with support failed"); TopoDS_Shape result = mkFuse.Shape(); - // we have to get the solids (fuse create seldomly compounds) + // we have to get the solids (fuse sometimes creates compounds) TopoDS_Shape solRes = this->getSolid(result); // lets check if the result is a solid if (solRes.IsNull()) @@ -293,7 +295,14 @@ App::DocumentObjectExecReturn *Pad::execute(void) } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); - return new App::DocumentObjectExecReturn(e->GetMessageString()); + if (std::string(e->GetMessageString()) == "TopoDS::Face") + return new App::DocumentObjectExecReturn("Could not create face from sketch.\n" + "Intersecting sketch entities or multiple faces in a sketch are not allowed."); + else + return new App::DocumentObjectExecReturn(e->GetMessageString()); + } + catch (Base::Exception& e) { + return new App::DocumentObjectExecReturn(e.what()); } } diff --git a/src/Mod/PartDesign/App/FeaturePocket.cpp b/src/Mod/PartDesign/App/FeaturePocket.cpp index 60ebcc559..639cf1058 100644 --- a/src/Mod/PartDesign/App/FeaturePocket.cpp +++ b/src/Mod/PartDesign/App/FeaturePocket.cpp @@ -97,30 +97,29 @@ App::DocumentObjectExecReturn *Pocket::execute(void) Base::Vector3d SketchVector(0,0,1); SketchOrientation.multVec(SketchVector,SketchVector); - TopoDS_Shape aFace = makeFace(wires); - if (aFace.IsNull()) - return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); - - // This is a trick to avoid problems with the cut operation. Sometimes a cut doesn't - // work as expected if faces are coincident. Thus, we move the face in normal direction - // but make it longer by one unit in the opposite direction. - // TODO: Isn't one unit (one millimeter) a lot, assuming someone models a really tiny solid? - // What about using 2 * Precision::Confusion() ? - gp_Trsf mov; - mov.SetTranslation(gp_Vec(SketchVector.x,SketchVector.y,SketchVector.z)); - TopLoc_Location loc(mov); - aFace.Move(loc); - - // lengthen the vector - SketchVector *= (Length.getValue()+1); - - // turn around for pockets - SketchVector *= -1; - this->positionBySketch(); TopLoc_Location invObjLoc = this->getLocation().Inverted(); try { + TopoDS_Face aFace = TopoDS::Face(makeFace(wires)); + if (aFace.IsNull()) + return new App::DocumentObjectExecReturn("Pocket: Creating a face from sketch failed"); + // This is a trick to avoid problems with the cut operation. Sometimes a cut doesn't + // work as expected if faces are coincident. Thus, we move the face in normal direction + // but make it longer by one unit in the opposite direction. + // TODO: Isn't one unit (one millimeter) a lot, assuming someone models a really tiny solid? + // What about using 2 * Precision::Confusion() ? + gp_Trsf mov; + mov.SetTranslation(gp_Vec(SketchVector.x,SketchVector.y,SketchVector.z)); + TopLoc_Location loc(mov); + aFace.Move(loc); + + // lengthen the vector + SketchVector *= (Length.getValue()+1); + + // turn around for pockets + SketchVector *= -1; + // extrude the face to a solid TopoDS_Shape prism; @@ -245,7 +244,14 @@ App::DocumentObjectExecReturn *Pocket::execute(void) return App::DocumentObject::StdReturn; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); - return new App::DocumentObjectExecReturn(e->GetMessageString()); + if (std::string(e->GetMessageString()) == "TopoDS::Face") + return new App::DocumentObjectExecReturn("Could not create face from sketch.\n" + "Intersecting sketch entities or multiple faces in a sketch are not allowed."); + else + return new App::DocumentObjectExecReturn(e->GetMessageString()); + } + catch (Base::Exception& e) { + return new App::DocumentObjectExecReturn(e.what()); } } diff --git a/src/Mod/PartDesign/App/FeatureRevolution.cpp b/src/Mod/PartDesign/App/FeatureRevolution.cpp index 7679ca24f..2460b1186 100644 --- a/src/Mod/PartDesign/App/FeatureRevolution.cpp +++ b/src/Mod/PartDesign/App/FeatureRevolution.cpp @@ -133,29 +133,31 @@ App::DocumentObjectExecReturn *Revolution::execute(void) Base::Vector3f v = Axis.getValue(); gp_Dir dir(v.x,v.y,v.z); - TopoDS_Shape aFace = makeFace(wires); - if (aFace.IsNull()) - return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); - - // Rotate the face by half the angle to get revolution symmetric to sketch plane - if (Midplane.getValue()) { - gp_Trsf mov; - mov.SetRotation(gp_Ax1(pnt, dir), Base::toRadians(Angle.getValue()) * (-1.0) / 2.0); - TopLoc_Location loc(mov); - aFace.Move(loc); - } - - this->positionBySketch(); - TopLoc_Location invObjLoc = this->getLocation().Inverted(); - pnt.Transform(invObjLoc.Transformation()); - dir.Transform(invObjLoc.Transformation()); - - // Reverse angle if selected - double angle = Base::toRadians(Angle.getValue()); - if (Reversed.getValue() && !Midplane.getValue()) - angle *= (-1.0); - try { + // TopoDS::Face is not strictly necessary, but it will through an exception for + // invalid wires e.g. intersections or multiple separate wires + TopoDS_Shape aFace = TopoDS::Face(makeFace(wires)); + if (aFace.IsNull()) + return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); + + // Rotate the face by half the angle to get revolution symmetric to sketch plane + if (Midplane.getValue()) { + gp_Trsf mov; + mov.SetRotation(gp_Ax1(pnt, dir), Base::toRadians(Angle.getValue()) * (-1.0) / 2.0); + TopLoc_Location loc(mov); + aFace.Move(loc); + } + + this->positionBySketch(); + TopLoc_Location invObjLoc = this->getLocation().Inverted(); + pnt.Transform(invObjLoc.Transformation()); + dir.Transform(invObjLoc.Transformation()); + + // Reverse angle if selected + double angle = Base::toRadians(Angle.getValue()); + if (Reversed.getValue() && !Midplane.getValue()) + angle *= (-1.0); + // revolve the face to a solid BRepPrimAPI_MakeRevol RevolMaker(aFace.Moved(invObjLoc), gp_Ax1(pnt, dir), angle); @@ -183,7 +185,14 @@ App::DocumentObjectExecReturn *Revolution::execute(void) } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); - return new App::DocumentObjectExecReturn(e->GetMessageString()); + if (std::string(e->GetMessageString()) == "TopoDS::Face") + return new App::DocumentObjectExecReturn("Could not create face from sketch.\n" + "Intersecting sketch entities or multiple faces in a sketch are not allowed."); + else + return new App::DocumentObjectExecReturn(e->GetMessageString()); + } + catch (Base::Exception& e) { + return new App::DocumentObjectExecReturn(e.what()); } }