Part: fix tapered extrusion backward compatibility

This commit is contained in:
Zheng, Lei
2022-09-25 20:25:25 +02:00
committed by Uwe
parent e8547f7588
commit 5fc5203ff7
3 changed files with 74 additions and 40 deletions
+16 -13
View File
@@ -587,18 +587,21 @@ void ExtrusionHelper::makEDraft(const ExtrusionParameters& params,
bool bRev = fabs(params.lengthRev) > Precision::Confusion();
bool bMid = !bFwd || !bRev || params.lengthFwd*params.lengthRev > 0.0; //include the source shape as loft section?
TopoDS_Shape shape = _shape.getShape();
TopoShape shape = _shape;
TopoShape sourceWire;
if (shape.IsNull())
if (shape.isNull())
Standard_Failure::Raise("Not a valid shape");
if (shape.ShapeType() == TopAbs_FACE) {
if (params.solid && !shape.hasSubShape(TopAbs_FACE))
shape = shape.makEFace(nullptr, params.faceMakerClass.c_str());
if (shape.shapeType() == TopAbs_FACE) {
std::vector<TopoShape> wires;
TopoShape outerWire = _shape.splitWires(&wires, TopoShape::ReorientForward);
TopoShape outerWire = shape.splitWires(&wires, TopoShape::ReorientForward);
if (outerWire.isNull())
Standard_Failure::Raise("Missing outer wire");
if (wires.empty())
shape = outerWire.getShape();
shape = outerWire;
else {
unsigned pos = drafts.size();
makEDraft(params, outerWire, drafts, hasher);
@@ -619,18 +622,18 @@ void ExtrusionHelper::makEDraft(const ExtrusionParameters& params,
}
}
if (shape.ShapeType() == TopAbs_WIRE) {
if (shape.shapeType() == TopAbs_WIRE) {
ShapeFix_Wire aFix;
aFix.Load(TopoDS::Wire(shape));
aFix.Load(TopoDS::Wire(shape.getShape()));
aFix.FixReorder();
aFix.FixConnected();
aFix.FixClosed();
sourceWire.setShape(aFix.Wire());
sourceWire.Tag = _shape.Tag;
sourceWire.mapSubElement(_shape);
sourceWire.Tag = shape.Tag;
sourceWire.mapSubElement(shape);
}
else if (shape.ShapeType() == TopAbs_COMPOUND) {
for(auto &s : _shape.getSubTopoShapes())
else if (shape.shapeType() == TopAbs_COMPOUND) {
for(auto &s : shape.getSubTopoShapes())
makEDraft(params, s, drafts, hasher);
}
else {
@@ -699,8 +702,8 @@ void ExtrusionHelper::makEDraft(const ExtrusionParameters& params,
//make loft
BRepOffsetAPI_ThruSections mkGenerator(
params.solid ? Standard_True : Standard_False, /*ruled=*/Standard_True);
for(auto &shape : list_of_sections)
mkGenerator.AddWire(TopoDS::Wire(shape.getShape()));
for(auto &s : list_of_sections)
mkGenerator.AddWire(TopoDS::Wire(s.getShape()));
mkGenerator.Build();
drafts.push_back(TopoShape(0,hasher).makEShape(mkGenerator,list_of_sections));
+58 -23
View File
@@ -72,11 +72,6 @@ Extrusion::Extrusion()
ADD_PROPERTY_TYPE(Symmetric, (false), "Extrude", App::Prop_None, "If true, extrusion is done in both directions to a total of LengthFwd. LengthRev is ignored.");
ADD_PROPERTY_TYPE(TaperAngle, (0.0), "Extrude", App::Prop_None, "Sets the angle of slope (draft) to apply to the sides. The angle is for outward taper; negative value yields inward tapering.");
ADD_PROPERTY_TYPE(TaperAngleRev, (0.0), "Extrude", App::Prop_None, "Taper angle of reverse part of extrusion.");
ADD_PROPERTY_TYPE(InnerTaperAngle,(0.0), "Extrude", App::Prop_None, "Taper angle of inner holes.");
ADD_PROPERTY_TYPE(InnerTaperAngleRev,(0.0), "Extrude", App::Prop_None, "Taper angle of the reverse part for inner holes.");
ADD_PROPERTY_TYPE(UsePipeForDraft,(false), "Extrude", App::Prop_None, "Use pipe (i.e. sweep) operation to create draft angles.");
ADD_PROPERTY_TYPE(Linearize,(false), "Extrude", App::Prop_None,
"Linearize the resut shape by simplify linear edge and planar face into line and plane");
ADD_PROPERTY_TYPE(FaceMakerClass,("Part::FaceMakerExtrusion"), "Extrude", App::Prop_None, "If Solid is true, this sets the facemaker class to use when converting wires to faces. Otherwise, ignored."); //default for old documents. See setupObject for default for new extrusions.
}
@@ -136,8 +131,6 @@ bool Extrusion::fetchAxisLink(const App::PropertyLinkSub& axisLink, Base::Vector
ExtrusionParameters Extrusion::computeFinalParameters()
{
ExtrusionParameters result;
result.usepipe = this->UsePipeForDraft.getValue();
result.linearize = this->Linearize.getValue();
Base::Vector3d dir;
switch (this->DirMode.getValue()) {
case dmCustom:
@@ -187,13 +180,8 @@ ExtrusionParameters Extrusion::computeFinalParameters()
result.taperAngleRev = this->TaperAngleRev.getValue() * M_PI / 180.0;
if (fabs(result.taperAngleRev) > M_PI * 0.5 - Precision::Angular())
throw Base::ValueError("Magnitude of taper angle matches or exceeds 90 degrees. That is too much.");
result.innerTaperAngleFwd = this->InnerTaperAngle.getValue() * M_PI / 180.0;
if (fabs(result.innerTaperAngleFwd) > M_PI * 0.5 - Precision::Angular() )
throw Base::ValueError("Magnitude of inner taper angle matches or exceeds 90 degrees. That is too much.");
result.innerTaperAngleRev = this->InnerTaperAngleRev.getValue() * M_PI / 180.0;
if (fabs(result.innerTaperAngleRev) > M_PI * 0.5 - Precision::Angular() )
throw Base::ValueError("Magnitude of inner taper angle matches or exceeds 90 degrees. That is too much.");
result.innerTaperAngleFwd = -TaperAngle.getValue() * M_PI / 180.0;
result.innerTaperAngleRev = -TaperAngleRev.getValue() * M_PI / 180.0;
result.faceMakerClass = this->FaceMakerClass.getValue();
return result;
@@ -249,18 +237,19 @@ void Extrusion::extrudeShape(TopoShape &result, const TopoShape &source, const E
{
gp_Vec vec = gp_Vec(params.dir).Multiplied(params.lengthFwd + params.lengthRev);//total vector of extrusion
#if 1
if (std::fabs(params.taperAngleFwd) >= Precision::Angular() ||
std::fabs(params.taperAngleRev) >= Precision::Angular()) {
//Tapered extrusion!
#if defined(__GNUC__) && defined (FC_OS_LINUX)
# if defined(__GNUC__) && defined (FC_OS_LINUX)
Base::SignalException se;
#endif
if (source.isNull())
# endif
TopoDS_Shape myShape = source.getShape();
if (myShape.IsNull())
Standard_Failure::Raise("Cannot extrude empty shape");
// #0000910: Circles Extrude Only Surfaces, thus use BRepBuilderAPI_Copy
TopoShape myShape(source.makECopy());
myShape = BRepBuilderAPI_Copy(myShape).Shape();
#ifdef FC_NO_ELEMENT_MAP
std::list<TopoDS_Shape> drafts;
bool isPartDesign = false; // there is an OCC bug with single-edge wires (circles) we need to treat differently for PD and Part
ExtrusionHelper::makeDraft(myShape, params.dir, params.lengthFwd, params.lengthRev,
@@ -279,14 +268,61 @@ void Extrusion::extrudeShape(TopoShape &result, const TopoShape &source, const E
builder.Add(comp, *it);
result = comp;
}
#else
}
else {
//Regular (non-tapered) extrusion!
TopoDS_Shape myShape = source.getShape();
if (myShape.IsNull())
Standard_Failure::Raise("Cannot extrude empty shape");
// #0000910: Circles Extrude Only Surfaces, thus use BRepBuilderAPI_Copy
myShape = BRepBuilderAPI_Copy(myShape).Shape();
//apply reverse part of extrusion by shifting the source shape
if (fabs(params.lengthRev) > Precision::Confusion()) {
gp_Trsf mov;
mov.SetTranslation(gp_Vec(params.dir) * (-params.lengthRev));
TopLoc_Location loc(mov);
myShape.Move(loc);
}
//make faces from wires
if (params.solid) {
//test if we need to make faces from wires. If there are faces - we don't.
TopExp_Explorer xp(myShape, TopAbs_FACE);
if (xp.More()) {
//source shape has faces. Just extrude as-is.
}
else {
std::unique_ptr<FaceMaker> mkFace = FaceMaker::ConstructFromType(params.faceMakerClass.c_str());
if (myShape.ShapeType() == TopAbs_COMPOUND)
mkFace->useCompound(TopoDS::Compound(myShape));
else
mkFace->addShape(myShape);
mkFace->Build();
myShape = mkFace->Shape();
}
}
//extrude!
BRepPrimAPI_MakePrism mkPrism(myShape, vec);
result = mkPrism.Shape();
}
#else // FC_NO_ELEMENT_MAP
if (std::fabs(params.taperAngleFwd) >= Precision::Angular() ||
std::fabs(params.taperAngleRev) >= Precision::Angular()) {
//Tapered extrusion!
# if defined(__GNUC__) && defined (FC_OS_LINUX)
Base::SignalException se;
# endif
std::vector<TopoShape> drafts;
ExtrusionHelper::makEDraft(params, myShape, drafts, result.Hasher);
if (drafts.empty()) {
Standard_Failure::Raise("Drafting shape failed");
}else
result.makECompound(drafts,0,false);
#endif
}
else {
//Regular (non-tapered) extrusion!
@@ -316,6 +352,7 @@ void Extrusion::extrudeShape(TopoShape &result, const TopoShape &source, const E
//extrude!
result.makEPrism(myShape,vec);
}
#endif
if (result.isNull())
throw NullShapeException("Result of extrusion is null shape.");
@@ -412,7 +449,5 @@ void FaceMakerExtrusion::Build()
void Part::Extrusion::setupObject()
{
Part::Feature::setupObject();
UsePipeForDraft.setValue(PartParams::getUsePipeForExtrusionDraft());
Linearize.setValue(Part::PartParams::getLinearizeExtrusionDraft());
this->FaceMakerClass.setValue("Part::FaceMakerBullseye"); //default for newly created features
}
-4
View File
@@ -51,11 +51,7 @@ public:
App::PropertyBool Symmetric;
App::PropertyAngle TaperAngle;
App::PropertyAngle TaperAngleRev;
App::PropertyAngle InnerTaperAngle;
App::PropertyAngle InnerTaperAngleRev;
App::PropertyString FaceMakerClass;
App::PropertyBool UsePipeForDraft;
App::PropertyBool Linearize;
/** @name methods override feature */
//@{