Part: fix tapered extrusion backward compatibility
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
//@{
|
||||
|
||||
Reference in New Issue
Block a user