Toponaming: Remove all FC_USE_TNP_FIX protected old code
This commit is contained in:
@@ -65,273 +65,6 @@ short Loft::mustExecute() const
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
App::DocumentObjectExecReturn *Loft::execute()
|
||||
{
|
||||
auto getSectionShape =
|
||||
[](App::DocumentObject* feature, const std::vector<std::string> &subs) -> TopoDS_Shape {
|
||||
if (!feature ||
|
||||
!feature->isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
throw Base::TypeError("Loft: Invalid profile/section");
|
||||
|
||||
auto subName = subs.empty() ? "" : subs.front();
|
||||
|
||||
// only take the entire shape when we have a sketch selected, but
|
||||
// not a point of the sketch
|
||||
if (feature->isDerivedFrom(Part::Part2DObject::getClassTypeId()) &&
|
||||
subName.compare(0, 6, "Vertex") != 0)
|
||||
return static_cast<Part::Part2DObject*>(feature)->Shape.getValue();
|
||||
else {
|
||||
if(subName.empty())
|
||||
throw Base::ValueError("No valid subelement linked in Part::Feature");
|
||||
return static_cast<Part::Feature*>(feature)->Shape.getShape().getSubShape(subName.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
auto addWiresToWireSections =
|
||||
[](TopoDS_Shape& section,
|
||||
std::vector<std::vector<TopoDS_Shape>>& wiresections) -> size_t {
|
||||
TopExp_Explorer ex;
|
||||
size_t i=0;
|
||||
bool initialWireSectionsEmpty = wiresections.empty();
|
||||
for (ex.Init(section, TopAbs_WIRE); ex.More(); ex.Next(), ++i) {
|
||||
// if profile was just a point then this is where we can first set our list
|
||||
if (i>=wiresections.size()) {
|
||||
if (initialWireSectionsEmpty)
|
||||
wiresections.emplace_back(1, ex.Current());
|
||||
else
|
||||
throw Base::ValueError("Loft: Sections need to have the same amount of inner wires (except profile and last section, which can be points)");
|
||||
}
|
||||
else
|
||||
wiresections[i].push_back(TopoDS::Wire(ex.Current()));
|
||||
}
|
||||
return i;
|
||||
};
|
||||
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
TopoDS_Shape profilePoint;
|
||||
|
||||
// if the Base property has a valid shape, fuse the pipe into it
|
||||
TopoDS_Shape base;
|
||||
try {
|
||||
base = getBaseShape();
|
||||
} catch (const Base::Exception&) {
|
||||
base = TopoDS_Shape();
|
||||
}
|
||||
|
||||
try {
|
||||
// setup the location
|
||||
this->positionByPrevious();
|
||||
TopLoc_Location invObjLoc = this->getLocation().Inverted();
|
||||
if (!base.IsNull())
|
||||
base.Move(invObjLoc);
|
||||
|
||||
// build up multisections
|
||||
auto multisections = Sections.getSubListValues();
|
||||
if (multisections.empty())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: At least one section is needed"));
|
||||
|
||||
TopoDS_Shape profileShape = getSectionShape(Profile.getValue(),
|
||||
Profile.getSubValues());
|
||||
if (profileShape.IsNull())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Could not obtain profile shape"));
|
||||
|
||||
std::vector<std::vector<TopoDS_Shape>> wiresections;
|
||||
|
||||
size_t numWires = addWiresToWireSections(profileShape, wiresections);
|
||||
if (numWires == 0) {
|
||||
// profileShape had no wires so only other valid option is point section
|
||||
TopExp_Explorer ex;
|
||||
size_t i = 0;
|
||||
for (ex.Init(profileShape, TopAbs_VERTEX); ex.More(); ex.Next(), ++i) {
|
||||
profilePoint = ex.Current();
|
||||
}
|
||||
if (i > 1)
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: When using points for profile/sections, the sketch should have a single point"));
|
||||
}
|
||||
|
||||
bool isLastSectionVertex = false;
|
||||
|
||||
size_t subSetCnt=0;
|
||||
for (const auto & subSet : multisections) {
|
||||
if (!subSet.first->isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: All sections need to be part features"));
|
||||
|
||||
// if the selected subvalue is a point, pick that even if we have a sketch
|
||||
TopoDS_Shape shape = getSectionShape(subSet.first, subSet.second);
|
||||
if (shape.IsNull())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Could not obtain section shape"));
|
||||
|
||||
size_t numWiresAdded = addWiresToWireSections(shape, wiresections);
|
||||
if (numWiresAdded == 0) {
|
||||
// The shape of the given object doesn't contain any wires, though it still might be valid if it is a vertex (or a COMPOUND consisting a single vertex)
|
||||
TopoDS_Shape vertexShape;
|
||||
TopExp_Explorer ex{shape, TopAbs_VERTEX};
|
||||
if (ex.More()) {
|
||||
vertexShape = ex.Current();
|
||||
ex.Next();
|
||||
if (ex.More()) { // some additional vertexes in the shape, we shouldn't use it
|
||||
vertexShape.Nullify();
|
||||
}
|
||||
}
|
||||
|
||||
if (vertexShape.IsNull())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: A section doesn't contain any wires nor is a single vertex"));
|
||||
if (subSetCnt != multisections.size()-1)
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Only the profile and the last section can be vertices"));
|
||||
if (Closed.getValue())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: For closed lofts only the profile can be a vertex"));
|
||||
|
||||
// all good; push vertex to all wiresection list
|
||||
for (auto &wires : wiresections)
|
||||
wires.push_back(vertexShape);
|
||||
isLastSectionVertex = true;
|
||||
} else if (numWiresAdded != wiresections.size())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: all loft sections need to have the same amount of inner wires"));
|
||||
subSetCnt++;
|
||||
}
|
||||
|
||||
if (Closed.getValue()) {
|
||||
// For a closed loft add starting sketch again at the end
|
||||
if (profilePoint.IsNull()) {
|
||||
size_t numWiresAdded = addWiresToWireSections(profileShape, wiresections);
|
||||
assert (numWiresAdded == wiresections.size());
|
||||
boost::ignore_unused(numWiresAdded);
|
||||
} else { // !profilePoint.IsNull()
|
||||
for (auto &wires : wiresections)
|
||||
wires.push_back(profilePoint);
|
||||
}
|
||||
}
|
||||
|
||||
// build all shells
|
||||
std::vector<TopoDS_Shape> shells;
|
||||
|
||||
TopoDS_Shape copyProfilePoint(profilePoint);
|
||||
if (!profilePoint.IsNull())
|
||||
copyProfilePoint.Move(invObjLoc);
|
||||
|
||||
for (auto& wires : wiresections) {
|
||||
BRepOffsetAPI_ThruSections mkTS(false, Ruled.getValue(), Precision::Confusion());
|
||||
|
||||
if (!profilePoint.IsNull())
|
||||
mkTS.AddVertex(TopoDS::Vertex(copyProfilePoint));
|
||||
|
||||
for (auto& shape : wires) {
|
||||
shape.Move(invObjLoc);
|
||||
if (shape.ShapeType() == TopAbs_VERTEX)
|
||||
mkTS.AddVertex(TopoDS::Vertex(shape));
|
||||
else
|
||||
mkTS.AddWire(TopoDS::Wire(shape));
|
||||
}
|
||||
|
||||
mkTS.Build();
|
||||
if (!mkTS.IsDone())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft could not be built"));
|
||||
|
||||
// build the shell use simulate to get the top and bottom wires in an easy way
|
||||
shells.push_back(mkTS.Shape());
|
||||
}
|
||||
|
||||
// build the top and bottom faces (where possible), sew the shell,
|
||||
// and build the final solid
|
||||
BRepBuilderAPI_Sewing sewer;
|
||||
sewer.SetTolerance(Precision::Confusion());
|
||||
if (!Closed.getValue()) {
|
||||
if (profilePoint.IsNull()) {
|
||||
TopoDS_Shape front = getVerifiedFace();
|
||||
front.Move(invObjLoc);
|
||||
sewer.Add(front);
|
||||
}
|
||||
if (!isLastSectionVertex) {
|
||||
std::vector<TopoDS_Wire> backwires;
|
||||
for (auto& wires : wiresections)
|
||||
backwires.push_back(TopoDS::Wire(wires.back()));
|
||||
TopoDS_Shape back = Part::FaceMakerCheese::makeFace(backwires);
|
||||
sewer.Add(back);
|
||||
}
|
||||
}
|
||||
for (TopoDS_Shape& s : shells)
|
||||
sewer.Add(s);
|
||||
|
||||
sewer.Perform();
|
||||
|
||||
// build the solid
|
||||
BRepBuilderAPI_MakeSolid mkSolid;
|
||||
mkSolid.Add(TopoDS::Shell(sewer.SewedShape()));
|
||||
if (!mkSolid.IsDone())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Result is not a solid"));
|
||||
|
||||
TopoDS_Shape result = mkSolid.Shape();
|
||||
BRepClass3d_SolidClassifier SC(result);
|
||||
SC.PerformInfinitePoint(Precision::Confusion());
|
||||
if ( SC.State() == TopAbs_IN) {
|
||||
result.Reverse();
|
||||
}
|
||||
|
||||
AddSubShape.setValue(result);
|
||||
|
||||
if (base.IsNull()) {
|
||||
if (getAddSubType() == FeatureAddSub::Subtractive)
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: There is nothing to subtract from"));
|
||||
|
||||
Shape.setValue(getSolid(result));
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
if (getAddSubType() == FeatureAddSub::Additive) {
|
||||
|
||||
BRepAlgoAPI_Fuse mkFuse(base, result);
|
||||
if (!mkFuse.IsDone())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Adding the loft failed"));
|
||||
|
||||
// we have to get the solids (fuse sometimes creates compounds)
|
||||
TopoDS_Shape boolOp = this->getSolid(mkFuse.Shape());
|
||||
|
||||
// lets check if the result is a solid
|
||||
if (boolOp.IsNull())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
|
||||
|
||||
if (!isSingleSolidRuleSatisfied(boolOp)) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
|
||||
boolOp = refineShapeIfActive(boolOp);
|
||||
Shape.setValue(getSolid(boolOp));
|
||||
}
|
||||
else if (getAddSubType() == FeatureAddSub::Subtractive) {
|
||||
|
||||
BRepAlgoAPI_Cut mkCut(base, result);
|
||||
if (!mkCut.IsDone())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Subtracting the loft failed"));
|
||||
|
||||
// we have to get the solids (fuse sometimes creates compounds)
|
||||
TopoDS_Shape boolOp = this->getSolid(mkCut.Shape());
|
||||
|
||||
// lets check if the result is a solid
|
||||
if (boolOp.IsNull())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
|
||||
|
||||
if (!isSingleSolidRuleSatisfied(boolOp)) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
|
||||
boolOp = refineShapeIfActive(boolOp);
|
||||
Shape.setValue(getSolid(boolOp));
|
||||
}
|
||||
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
return new App::DocumentObjectExecReturn(e.GetMessageString());
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
catch (...) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: A fatal error occurred when making the loft"));
|
||||
}
|
||||
}
|
||||
#else
|
||||
std::vector<Part::TopoShape>
|
||||
Loft::getSectionShape(const char *name,
|
||||
App::DocumentObject *obj,
|
||||
@@ -533,8 +266,6 @@ App::DocumentObjectExecReturn *Loft::execute()
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
PROPERTY_SOURCE(PartDesign::AdditiveLoft, PartDesign::Loft)
|
||||
AdditiveLoft::AdditiveLoft() {
|
||||
addSubType = Additive;
|
||||
|
||||
Reference in New Issue
Block a user