Part: Refactor TopoShape::splitWires (#23096)
This refactors TopoShape::splitWires method to be easier to follow and use variable names that better describe the intent.
This commit is contained in:
@@ -697,15 +697,16 @@ public:
|
||||
/// Make both outer and inner wires reversed
|
||||
ReorientReversed,
|
||||
};
|
||||
|
||||
/** Return the outer and inner wires of a face
|
||||
*
|
||||
* @param inner: optional output of inner wires
|
||||
* @param innerWiresOutput: optional output of inner wires
|
||||
* @param reorient: wire reorientation, see SplitWireReorient
|
||||
*
|
||||
* @return Return the outer wire
|
||||
*/
|
||||
TopoShape splitWires(
|
||||
std::vector<TopoShape>* inner = nullptr,
|
||||
std::vector<TopoShape>* innerWiresOutput = nullptr,
|
||||
SplitWireReorient reorient = Reorient
|
||||
) const;
|
||||
|
||||
|
||||
@@ -5327,14 +5327,15 @@ std::vector<Data::MappedName> TopoShape::decodeElementComboName(
|
||||
/**
|
||||
* Reorient the outer and inner wires of the TopoShape
|
||||
*
|
||||
* @param inner If this is not a nullptr, then any inner wires processed will be returned in this
|
||||
* vector.
|
||||
* @param reorient One of NoReorient, Reorient ( Outer forward, inner reversed ),
|
||||
* ReorientForward ( all forward ), or ReorientReversed ( all reversed )
|
||||
* @param innerWiresOutput If this is not a nullptr, then any inner wires processed will be returned
|
||||
* in this vector.
|
||||
* @param reorient One of NoReorient, Reorient (Outer forward, inner reversed),
|
||||
* ReorientForward (all forward), or ReorientReversed (all reversed)
|
||||
*
|
||||
* @return The outer wire, or an empty TopoShape if this isn't a Face, has no Face subShapes, or the
|
||||
* outer wire isn't found.
|
||||
*/
|
||||
TopoShape TopoShape::splitWires(std::vector<TopoShape>* inner, SplitWireReorient reorient) const
|
||||
TopoShape TopoShape::splitWires(std::vector<TopoShape>* innerWiresOutput, SplitWireReorient reorient) const
|
||||
{
|
||||
// ShapeAnalysis::OuterWire() is un-reliable for some reason. OCC source
|
||||
// code shows it works by creating face using each wire, and then test using
|
||||
@@ -5348,18 +5349,18 @@ TopoShape TopoShape::splitWires(std::vector<TopoShape>* inner, SplitWireReorient
|
||||
// implemented using simple bound box checking. This should be a
|
||||
// reliable method, especially so for a planar face.
|
||||
|
||||
TopoDS_Shape tmp;
|
||||
TopoDS_Shape outerWire;
|
||||
|
||||
if (shapeType(true) == TopAbs_FACE) {
|
||||
tmp = BRepTools::OuterWire(TopoDS::Face(_Shape));
|
||||
outerWire = BRepTools::OuterWire(TopoDS::Face(_Shape));
|
||||
}
|
||||
else if (countSubShapes(TopAbs_FACE) == 1) {
|
||||
tmp = BRepTools::OuterWire(TopoDS::Face(getSubShape(TopAbs_FACE, 1)));
|
||||
outerWire = BRepTools::OuterWire(TopoDS::Face(getSubShape(TopAbs_FACE, 1)));
|
||||
}
|
||||
if (tmp.IsNull()) {
|
||||
|
||||
if (outerWire.IsNull()) {
|
||||
return TopoShape {};
|
||||
}
|
||||
const auto& wires = getSubTopoShapes(TopAbs_WIRE);
|
||||
auto it = wires.begin();
|
||||
|
||||
TopAbs_Orientation orientOuter, orientInner;
|
||||
switch (reorient) {
|
||||
@@ -5375,55 +5376,51 @@ TopoShape TopoShape::splitWires(std::vector<TopoShape>* inner, SplitWireReorient
|
||||
break;
|
||||
}
|
||||
|
||||
auto doReorient = [](TopoShape& s, TopAbs_Orientation orient) {
|
||||
auto reorientIfNecessary = [reorient](TopoShape& shape, TopAbs_Orientation orient) {
|
||||
if (reorient == NoReorient) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Special case of single edge wire. Make sure the edge is in the
|
||||
// required orientation. This is necessary because BRepFill_OffsetWire
|
||||
// has special handling of circular edge offset, which seem to only
|
||||
// respect the edge orientation and disregard the wire orientation. The
|
||||
// orientation is used to determine whether to shrink or expand.
|
||||
if (s.countSubShapes(TopAbs_EDGE) == 1) {
|
||||
TopoDS_Shape e = s.getSubShape(TopAbs_EDGE, 1);
|
||||
if (e.Orientation() == orient) {
|
||||
if (s._Shape.Orientation() == orient) {
|
||||
if (shape.countSubShapes(TopAbs_EDGE) == 1) {
|
||||
TopoDS_Shape edge = shape.getSubShape(TopAbs_EDGE, 1);
|
||||
if (edge.Orientation() == orient) {
|
||||
if (shape._Shape.Orientation() == orient) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
e = e.Oriented(orient);
|
||||
edge = edge.Oriented(orient);
|
||||
}
|
||||
BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(e));
|
||||
s.setShape(mkWire.Shape(), false);
|
||||
|
||||
BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(edge));
|
||||
shape.setShape(mkWire.Shape(), false);
|
||||
}
|
||||
else if (s._Shape.Orientation() != orient) {
|
||||
s.setShape(s._Shape.Oriented(orient), false);
|
||||
else if (shape._Shape.Orientation() != orient) {
|
||||
shape.setShape(shape._Shape.Oriented(orient), false);
|
||||
}
|
||||
};
|
||||
|
||||
for (; it != wires.end(); ++it) {
|
||||
auto& wire = *it;
|
||||
if (wire.getShape().IsSame(tmp)) {
|
||||
if (inner) {
|
||||
for (++it; it != wires.end(); ++it) {
|
||||
inner->push_back(*it);
|
||||
if (reorient) {
|
||||
doReorient(inner->back(), orientInner);
|
||||
}
|
||||
}
|
||||
}
|
||||
auto res = wire;
|
||||
if (reorient) {
|
||||
doReorient(res, orientOuter);
|
||||
}
|
||||
return res;
|
||||
TopoShape outerWireResult {};
|
||||
|
||||
for (auto& wire : getSubTopoShapes(TopAbs_WIRE)) {
|
||||
if (wire.getShape().IsSame(outerWire)) {
|
||||
outerWireResult = wire;
|
||||
reorientIfNecessary(outerWireResult, orientOuter);
|
||||
continue;
|
||||
}
|
||||
if (inner) {
|
||||
inner->push_back(wire);
|
||||
if (reorient) {
|
||||
doReorient(inner->back(), orientInner);
|
||||
}
|
||||
|
||||
if (innerWiresOutput) {
|
||||
innerWiresOutput->push_back(wire);
|
||||
reorientIfNecessary(innerWiresOutput->back(), orientInner);
|
||||
}
|
||||
}
|
||||
return TopoShape {};
|
||||
|
||||
return outerWireResult;
|
||||
}
|
||||
|
||||
bool TopoShape::isLinearEdge() const
|
||||
|
||||
Reference in New Issue
Block a user