fixes #0002512 Allow multi-face part design tools

This commit is contained in:
Stefan Tröger 2016-05-18 19:49:05 +02:00 committed by wmayer
parent 4f8973fe8e
commit 83ce80f133
16 changed files with 63 additions and 52 deletions

View File

@ -165,7 +165,7 @@ App::DocumentObjectExecReturn *Boolean::execute(void)
result = mkTrf.Shape(); result = mkTrf.Shape();
} }
this->Shape.setValue(result); this->Shape.setValue(getSolid(result));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }

View File

@ -115,7 +115,7 @@ App::DocumentObjectExecReturn *Chamfer::execute(void)
return new App::DocumentObjectExecReturn("Resulting shape is invalid"); return new App::DocumentObjectExecReturn("Resulting shape is invalid");
} }
this->Shape.setValue(shape); this->Shape.setValue(getSolid(shape));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }
catch (Standard_Failure) { catch (Standard_Failure) {

View File

@ -302,7 +302,7 @@ App::DocumentObjectExecReturn *Draft::execute(void)
if (shape.IsNull()) if (shape.IsNull())
return new App::DocumentObjectExecReturn("Resulting shape is null"); return new App::DocumentObjectExecReturn("Resulting shape is null");
this->Shape.setValue(shape); this->Shape.setValue(getSolid(shape));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }
catch (Standard_Failure) { catch (Standard_Failure) {

View File

@ -106,7 +106,7 @@ App::DocumentObjectExecReturn *Fillet::execute(void)
return new App::DocumentObjectExecReturn("Resulting shape is invalid"); return new App::DocumentObjectExecReturn("Resulting shape is invalid");
} }
this->Shape.setValue(shape); this->Shape.setValue(getSolid(shape));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }
catch (Standard_Failure) { catch (Standard_Failure) {

View File

@ -129,8 +129,13 @@ App::DocumentObjectExecReturn *Groove::execute(void)
sketchshape.Move(invObjLoc); sketchshape.Move(invObjLoc);
// Check distance between sketchshape and axis - to avoid failures and crashes // Check distance between sketchshape and axis - to avoid failures and crashes
if (checkLineCrossesFace(gp_Lin(pnt, dir), TopoDS::Face(sketchshape))) TopExp_Explorer xp;
xp.Init(sketchshape, TopAbs_FACE);
for (;xp.More(); xp.Next()) {
if (checkLineCrossesFace(gp_Lin(pnt, dir), TopoDS::Face(xp.Current())))
return new App::DocumentObjectExecReturn("Revolve axis intersects the sketch"); return new App::DocumentObjectExecReturn("Revolve axis intersects the sketch");
}
// revolve the face to a solid // revolve the face to a solid
BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle); BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle);
@ -164,7 +169,7 @@ App::DocumentObjectExecReturn *Groove::execute(void)
Handle_Standard_Failure e = Standard_Failure::Caught(); Handle_Standard_Failure e = Standard_Failure::Caught();
if (std::string(e->GetMessageString()) == "TopoDS::Face") if (std::string(e->GetMessageString()) == "TopoDS::Face")
return new App::DocumentObjectExecReturn("Could not create face from sketch.\n" return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
"Intersecting sketch entities or multiple faces in a sketch are not allowed."); "Intersecting sketch entities in a sketch are not allowed.");
else else
return new App::DocumentObjectExecReturn(e->GetMessageString()); return new App::DocumentObjectExecReturn(e->GetMessageString());
} }

View File

@ -136,7 +136,7 @@ App::DocumentObjectExecReturn *Hole::execute(void)
// // 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 (PAD!)
// if (SupportObject) { // if (SupportObject) {
// // Set the subtractive shape property for later usage in e.g. pattern // // Set the subtractive shape property for later usage in e.g. pattern
// this->SubShape.setValue(PrismMaker.Shape()); // this->SubShape.setValue(getSolid(PrismMaker.Shape()));
// const TopoDS_Shape& support = SupportObject->Shape.getValue(); // const TopoDS_Shape& support = SupportObject->Shape.getValue();
// if (support.IsNull()) // if (support.IsNull())
// return new App::DocumentObjectExecReturn("Support shape is invalid"); // return new App::DocumentObjectExecReturn("Support shape is invalid");
@ -148,7 +148,7 @@ App::DocumentObjectExecReturn *Hole::execute(void)
// // Let's check if the fusion has been successful // // Let's check if the fusion has been successful
// if (!mkCut.IsDone()) // if (!mkCut.IsDone())
// return new App::DocumentObjectExecReturn("Cut with support failed"); // return new App::DocumentObjectExecReturn("Cut with support failed");
// this->Shape.setValue(mkCut.Shape()); // this->Shape.setValue(getSolid(mkCut.Shape()));
// } // }
// else{ // else{
// return new App::DocumentObjectExecReturn("Cannot create a tool out of sketch with no support"); // return new App::DocumentObjectExecReturn("Cannot create a tool out of sketch with no support");

View File

@ -178,7 +178,7 @@ App::DocumentObjectExecReturn *Loft::execute(void)
AddSubShape.setValue(result); AddSubShape.setValue(result);
if(base.IsNull()) { if(base.IsNull()) {
Shape.setValue(result); Shape.setValue(getSolid(result));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }
@ -194,7 +194,7 @@ App::DocumentObjectExecReturn *Loft::execute(void)
return new App::DocumentObjectExecReturn("Loft: Resulting shape is not a solid"); return new App::DocumentObjectExecReturn("Loft: Resulting shape is not a solid");
boolOp = refineShapeIfActive(boolOp); boolOp = refineShapeIfActive(boolOp);
Shape.setValue(boolOp); Shape.setValue(getSolid(boolOp));
} }
else if(getAddSubType() == FeatureAddSub::Subtractive) { else if(getAddSubType() == FeatureAddSub::Subtractive) {
@ -208,7 +208,7 @@ App::DocumentObjectExecReturn *Loft::execute(void)
return new App::DocumentObjectExecReturn("Loft: Resulting shape is not a solid"); return new App::DocumentObjectExecReturn("Loft: Resulting shape is not a solid");
boolOp = refineShapeIfActive(boolOp); boolOp = refineShapeIfActive(boolOp);
Shape.setValue(boolOp); Shape.setValue(getSolid(boolOp));
} }
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;

View File

@ -213,7 +213,7 @@ App::DocumentObjectExecReturn *Pad::execute(void)
if (!base.IsNull()) { if (!base.IsNull()) {
// auto obj = getDocument()->addObject("Part::Feature", "prism"); // auto obj = getDocument()->addObject("Part::Feature", "prism");
// static_cast<Part::Feature*>(obj)->Shape.setValue(prism); // static_cast<Part::Feature*>(obj)->Shape.setValue(getSolid(prism));
// Let's call algorithm computing a fuse operation: // Let's call algorithm computing a fuse operation:
BRepAlgoAPI_Fuse mkFuse(base, prism); BRepAlgoAPI_Fuse mkFuse(base, prism);
// Let's check if the fusion has been successful // Let's check if the fusion has been successful
@ -226,9 +226,9 @@ App::DocumentObjectExecReturn *Pad::execute(void)
if (solRes.IsNull()) if (solRes.IsNull())
return new App::DocumentObjectExecReturn("Pad: Resulting shape is not a solid"); return new App::DocumentObjectExecReturn("Pad: Resulting shape is not a solid");
solRes = refineShapeIfActive(solRes); solRes = refineShapeIfActive(solRes);
this->Shape.setValue(solRes); this->Shape.setValue(getSolid(solRes));
} else { } else {
this->Shape.setValue(prism); this->Shape.setValue(getSolid(prism));
} }
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;

View File

@ -285,7 +285,7 @@ App::DocumentObjectExecReturn *Pipe::execute(void)
AddSubShape.setValue(result); AddSubShape.setValue(result);
if(base.IsNull()) { if(base.IsNull()) {
Shape.setValue(result); Shape.setValue(getSolid(result));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }
@ -301,7 +301,7 @@ App::DocumentObjectExecReturn *Pipe::execute(void)
return new App::DocumentObjectExecReturn("Resulting shape is not a solid"); return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
boolOp = refineShapeIfActive(boolOp); boolOp = refineShapeIfActive(boolOp);
Shape.setValue(boolOp); Shape.setValue(getSolid(boolOp));
} }
else if(getAddSubType() == FeatureAddSub::Subtractive) { else if(getAddSubType() == FeatureAddSub::Subtractive) {
@ -315,7 +315,7 @@ App::DocumentObjectExecReturn *Pipe::execute(void)
return new App::DocumentObjectExecReturn("Resulting shape is not a solid"); return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
boolOp = refineShapeIfActive(boolOp); boolOp = refineShapeIfActive(boolOp);
Shape.setValue(boolOp); Shape.setValue(getSolid(boolOp));
} }
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;

View File

@ -94,10 +94,10 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
return new App::DocumentObjectExecReturn("Pocket: Length of pocket too small"); return new App::DocumentObjectExecReturn("Pocket: Length of pocket too small");
Part::Feature* obj = 0; Part::Feature* obj = 0;
TopoDS_Face face; TopoDS_Shape profileshape;
try { try {
obj = getVerifiedObject(); obj = getVerifiedObject();
face = getVerifiedFace(); profileshape = getVerifiedFace();
} catch (const Base::Exception& e) { } catch (const Base::Exception& e) {
return new App::DocumentObjectExecReturn(e.what()); return new App::DocumentObjectExecReturn(e.what());
} }
@ -126,9 +126,9 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
gp_Dir dir(SketchVector.x,SketchVector.y,SketchVector.z); gp_Dir dir(SketchVector.x,SketchVector.y,SketchVector.z);
dir.Transform(invObjLoc.Transformation()); dir.Transform(invObjLoc.Transformation());
if (face.IsNull()) if (profileshape.IsNull())
return new App::DocumentObjectExecReturn("Pocket: Creating a face from sketch failed"); return new App::DocumentObjectExecReturn("Pocket: Creating a face from sketch failed");
face.Move(invObjLoc); profileshape.Move(invObjLoc);
std::string method(Type.getValueAsString()); std::string method(Type.getValueAsString());
if (method == "UpToFirst" || method == "UpToFace") { if (method == "UpToFirst" || method == "UpToFace") {
@ -148,7 +148,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
getUpToFaceFromLinkSub(upToFace, UpToFace); getUpToFaceFromLinkSub(upToFace, UpToFace);
upToFace.Move(invObjLoc); upToFace.Move(invObjLoc);
} }
getUpToFace(upToFace, base, supportface, face, method, dir, Offset.getValue()); getUpToFace(upToFace, base, supportface, profileshape, method, dir, Offset.getValue());
// BRepFeat_MakePrism(..., 2, 1) in combination with PerForm(upToFace) is buggy when the // BRepFeat_MakePrism(..., 2, 1) in combination with PerForm(upToFace) is buggy when the
// prism that is being created is contained completely inside the base solid // prism that is being created is contained completely inside the base solid
@ -161,7 +161,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
if (!Ex.More()) if (!Ex.More())
supportface = TopoDS_Face(); supportface = TopoDS_Face();
BRepFeat_MakePrism PrismMaker; BRepFeat_MakePrism PrismMaker;
PrismMaker.Init(base, face, supportface, dir, 0, 1); PrismMaker.Init(base, profileshape, supportface, dir, 0, 1);
PrismMaker.Perform(upToFace); PrismMaker.Perform(upToFace);
if (!PrismMaker.IsDone()) if (!PrismMaker.IsDone())
@ -175,10 +175,10 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
// FIXME: In some cases this affects the Shape property: It is set to the same shape as the SubShape!!!! // FIXME: In some cases this affects the Shape property: It is set to the same shape as the SubShape!!!!
TopoDS_Shape result = refineShapeIfActive(mkCut.Shape()); TopoDS_Shape result = refineShapeIfActive(mkCut.Shape());
this->AddSubShape.setValue(result); this->AddSubShape.setValue(result);
this->Shape.setValue(prism); this->Shape.setValue(getSolid(prism));
} else { } else {
TopoDS_Shape prism; TopoDS_Shape prism;
generatePrism(prism, face, method, dir, L, 0.0, generatePrism(prism, profileshape, method, dir, L, 0.0,
Midplane.getValue(), Reversed.getValue()); Midplane.getValue(), Reversed.getValue());
if (prism.IsNull()) if (prism.IsNull())
return new App::DocumentObjectExecReturn("Pocket: Resulting shape is empty"); return new App::DocumentObjectExecReturn("Pocket: Resulting shape is empty");
@ -198,7 +198,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
return new App::DocumentObjectExecReturn("Pocket: Resulting shape is not a solid"); return new App::DocumentObjectExecReturn("Pocket: Resulting shape is not a solid");
solRes = refineShapeIfActive(solRes); solRes = refineShapeIfActive(solRes);
remapSupportShape(solRes); remapSupportShape(solRes);
this->Shape.setValue(solRes); this->Shape.setValue(getSolid(solRes));
} }
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;

View File

@ -103,7 +103,7 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri
AddSubShape.setValue(primitiveShape); AddSubShape.setValue(primitiveShape);
if(getAddSubType() == FeatureAddSub::Additive) if(getAddSubType() == FeatureAddSub::Additive)
Shape.setValue(primitiveShape); Shape.setValue(getSolid(primitiveShape));
else else
return new App::DocumentObjectExecReturn("Cannot subtract primitive feature without base feature"); return new App::DocumentObjectExecReturn("Cannot subtract primitive feature without base feature");
@ -122,7 +122,7 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri
return new App::DocumentObjectExecReturn("Resulting shape is not a solid"); return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
boolOp = refineShapeIfActive(boolOp); boolOp = refineShapeIfActive(boolOp);
Shape.setValue(boolOp); Shape.setValue(getSolid(boolOp));
AddSubShape.setValue(primitiveShape); AddSubShape.setValue(primitiveShape);
} }
else if(getAddSubType() == FeatureAddSub::Subtractive) { else if(getAddSubType() == FeatureAddSub::Subtractive) {
@ -137,7 +137,7 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri
return new App::DocumentObjectExecReturn("Resulting shape is not a solid"); return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
boolOp = refineShapeIfActive(boolOp); boolOp = refineShapeIfActive(boolOp);
Shape.setValue(boolOp); Shape.setValue(getSolid(boolOp));
AddSubShape.setValue(primitiveShape); AddSubShape.setValue(primitiveShape);
} }

View File

@ -131,8 +131,12 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
sketchshape.Move(invObjLoc); sketchshape.Move(invObjLoc);
// Check distance between sketchshape and axis - to avoid failures and crashes // Check distance between sketchshape and axis - to avoid failures and crashes
if (checkLineCrossesFace(gp_Lin(pnt, dir), TopoDS::Face(sketchshape))) TopExp_Explorer xp;
xp.Init(sketchshape, TopAbs_FACE);
for (;xp.More(); xp.Next()) {
if (checkLineCrossesFace(gp_Lin(pnt, dir), TopoDS::Face(xp.Current())))
return new App::DocumentObjectExecReturn("Revolve axis intersects the sketch"); return new App::DocumentObjectExecReturn("Revolve axis intersects the sketch");
}
// revolve the face to a solid // revolve the face to a solid
BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle); BRepPrimAPI_MakeRevol RevolMaker(sketchshape, gp_Ax1(pnt, dir), angle);
@ -153,7 +157,7 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
result = refineShapeIfActive(result); result = refineShapeIfActive(result);
} }
this->Shape.setValue(result); this->Shape.setValue(getSolid(result));
} }
else else
return new App::DocumentObjectExecReturn("Could not revolve the sketch!"); return new App::DocumentObjectExecReturn("Could not revolve the sketch!");
@ -164,7 +168,7 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
Handle_Standard_Failure e = Standard_Failure::Caught(); Handle_Standard_Failure e = Standard_Failure::Caught();
if (std::string(e->GetMessageString()) == "TopoDS::Face") if (std::string(e->GetMessageString()) == "TopoDS::Face")
return new App::DocumentObjectExecReturn("Could not create face from sketch.\n" return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
"Intersecting sketch entities or multiple faces in a sketch are not allowed."); "Intersecting sketch entities in a sketch are not allowed.");
else else
return new App::DocumentObjectExecReturn(e->GetMessageString()); return new App::DocumentObjectExecReturn(e->GetMessageString());
} }

View File

@ -192,7 +192,7 @@ Part::Feature* ProfileBased::getVerifiedObject(bool silent) const {
return static_cast<Part::Feature*>(result); return static_cast<Part::Feature*>(result);
} }
TopoDS_Face ProfileBased::getVerifiedFace(bool silent) const { TopoDS_Shape ProfileBased::getVerifiedFace(bool silent) const {
App::DocumentObject* result = Profile.getValue(); App::DocumentObject* result = Profile.getValue();
const char* err = nullptr; const char* err = nullptr;
@ -203,7 +203,7 @@ TopoDS_Face ProfileBased::getVerifiedFace(bool silent) const {
if (result->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) { if (result->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) {
auto wires = getProfileWires(); auto wires = getProfileWires();
return TopoDS::Face(makeFace(wires)); return makeFace(wires);
} }
else if(result->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { else if(result->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
if(Profile.getSubValues().empty()) if(Profile.getSubValues().empty())
@ -1233,18 +1233,20 @@ Base::Vector3d ProfileBased::getProfileNormal() const {
SketchOrientation.multVec(SketchVector,SketchVector); SketchOrientation.multVec(SketchVector,SketchVector);
} }
else { else {
TopoDS_Face face = getVerifiedFace(true); TopoDS_Shape shape = getVerifiedFace(true);
BRepAdaptor_Surface adapt(face); if(shape.ShapeType() == TopAbs_FACE) {
BRepAdaptor_Surface adapt(TopoDS::Face(shape));
double u = adapt.FirstUParameter() + (adapt.LastUParameter() - adapt.FirstUParameter())/2.; double u = adapt.FirstUParameter() + (adapt.LastUParameter() - adapt.FirstUParameter())/2.;
double v = adapt.FirstVParameter() + (adapt.LastVParameter() - adapt.FirstVParameter())/2.; double v = adapt.FirstVParameter() + (adapt.LastVParameter() - adapt.FirstVParameter())/2.;
BRepLProp_SLProps prop(adapt,u,v,2,Precision::Confusion()); BRepLProp_SLProps prop(adapt,u,v,2,Precision::Confusion());
if(prop.IsNormalDefined()) { if(prop.IsNormalDefined()) {
gp_Pnt pnt; gp_Vec vec; gp_Pnt pnt; gp_Vec vec;
// handles the orientation state of the shape // handles the orientation state of the shape
BRepGProp_Face(face).Normal(u,v,pnt,vec); BRepGProp_Face(TopoDS::Face(shape)).Normal(u,v,pnt,vec);
SketchVector = Base::Vector3d(vec.X(), vec.Y(), vec.Z()); SketchVector = Base::Vector3d(vec.X(), vec.Y(), vec.Z());
} }
} }
}
return SketchVector; return SketchVector;
} }

View File

@ -85,11 +85,11 @@ public:
/** /**
* Verifies the linked Object and returns the shape used as profile * Verifies the linked Object and returns the shape used as profile
* @param silent if profile property is malformed and the parameter is true * @param silent if profirle property is malformed and the parameter is true
* silently returns nullptr, otherwice throw a Base::Exception. * silently returns nullptr, otherwice throw a Base::Exception.
* Default is false. * Default is false.
*/ */
TopoDS_Face getVerifiedFace(bool silent = false) const; TopoDS_Shape getVerifiedFace(bool silent = false) const;
/// Returns the wires the sketch is composed of /// Returns the wires the sketch is composed of
std::vector<TopoDS_Wire> getProfileWires() const; std::vector<TopoDS_Wire> getProfileWires() const;

View File

@ -85,8 +85,8 @@ App::DocumentObjectExecReturn *Thickness::execute(void)
join = 2; join = 2;
if (fabs(thickness) > 2*tol) if (fabs(thickness) > 2*tol)
this->Shape.setValue(TopShape.makeThickSolid(closingFaces, thickness, tol, false, false, mode, join)); this->Shape.setValue(getSolid(TopShape.makeThickSolid(closingFaces, thickness, tol, false, false, mode, join)));
else else
this->Shape.setValue(TopShape._Shape); this->Shape.setValue(getSolid(TopShape._Shape));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }

View File

@ -358,7 +358,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
for (trsf_it::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) for (trsf_it::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
rejected[it->first].push_back(**it2); rejected[it->first].push_back(**it2);
this->Shape.setValue(support); this->Shape.setValue(getSolid(support));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }