Part/Toponaming: Linter cleanup of makeElementWires

This commit is contained in:
Chris Hennes
2024-01-15 16:35:24 -06:00
parent 77c68ecb93
commit f66a4e57d2
3 changed files with 80 additions and 57 deletions

View File

@@ -636,6 +636,11 @@ public:
bool force = true);
enum class ConnectionPolicy {
REQUIRE_SHARED_VERTEX,
MERGE_WITH_TOLERANCE
};
/** Make a compound of wires by connecting input edges
*
* @param shapes: input shapes. Can be any type of shape. Edges will be
@@ -664,6 +669,7 @@ public:
bool shared = false,
TopoShapeMap* output = nullptr);
/** Make a compound of wires by connecting input edges
*
* @param shape: input shape. Can be any type of shape. Edges will be
@@ -673,8 +679,8 @@ public:
* @param keepOrder: whether to respect the order of the input edges
* @param tol: tolerance for checking the distance of two vertex to decide
* if two edges are connected
* @param shared: if true, then only connect edges if they shared the same
* vertex, or else use \c tol to check for connection.
* @param policy: if REQUIRE_SHARED_VERTEX, then only connect edges if they shared the same
* vertex. If MERGE_WITH_TOLERANCE use \c tol to check for connection.
* @param output: optional output mapping from wire edges to input edge.
* Note that edges may be modified after adding to the wire,
* so the output edges may not be the same as the input
@@ -689,7 +695,7 @@ public:
TopoShape& makeElementWires(const TopoShape& shape,
const char* op = nullptr,
double tol = 0.0,
bool shared = false,
ConnectionPolicy policy = ConnectionPolicy::MERGE_WITH_TOLERANCE,
TopoShapeMap* output = nullptr);
/** Make a compound of wires by connecting input edges in the given order
@@ -888,6 +894,7 @@ private:
*/
static std::deque<TopoShape>
sortEdges(std::list<TopoShape>& edges, bool keepOrder = false, double tol = 0.0);
static TopoShape reverseEdge (const TopoShape& edge);
};
/// Shape hasher that ignore orientation

View File

@@ -695,6 +695,40 @@ struct EdgePoints
}
};
TopoShape TopoShape::reverseEdge (const TopoShape& edge) {
Standard_Real first = NAN;
Standard_Real last = NAN;
const Handle(Geom_Curve)& curve =
BRep_Tool::Curve(TopoDS::Edge(edge.getShape()), first, last);
first = curve->ReversedParameter(first);
last = curve->ReversedParameter(last);
TopoShape res(BRepBuilderAPI_MakeEdge(curve->Reversed(), last, first));
auto edgeName = Data::IndexedName::fromConst("Edge", 1);
if (auto mapped = edge.getMappedName(edgeName)) {
res.elementMap()->setElementName(edgeName, mapped, res.Tag);
}
auto v1Name = Data::IndexedName::fromConst("Vertex", 1);
auto v2Name = Data::IndexedName::fromConst("Vertex", 2);
auto v1 = edge.getMappedName(v1Name);
auto v2 = edge.getMappedName(v2Name);
if (v1 && v2) {
res.elementMap()->setElementName(v1Name, v2, res.Tag);
res.elementMap()->setElementName(v2Name, v1, res.Tag);
}
else if (v1 && edge.countSubShapes(TopAbs_EDGE) == 1) {
// It's possible an edge has only one vertex, so no need to reverse
// the name
res.elementMap()->setElementName(v1Name, v1, res.Tag);
}
else if (v1) {
res.elementMap()->setElementName(v2Name, v1, res.Tag);
}
else if (v2) {
res.elementMap()->setElementName(v1Name, v2, res.Tag);
}
return res;
};
std::deque<TopoShape> TopoShape::sortEdges(std::list<TopoShape>& edges, bool keepOrder, double tol)
{
if (tol < Precision::Confusion()) {
@@ -702,67 +736,33 @@ std::deque<TopoShape> TopoShape::sortEdges(std::list<TopoShape>& edges, bool kee
}
double tol3d = tol * tol;
std::list<EdgePoints> edge_points;
std::list<EdgePoints> edgePoints;
for (auto it = edges.begin(); it != edges.end(); ++it) {
edge_points.emplace_back(it, tol3d);
edgePoints.emplace_back(it, tol3d);
}
std::deque<TopoShape> sorted;
if (edge_points.empty()) {
if (edgePoints.empty()) {
return sorted;
}
gp_Pnt first;
gp_Pnt last;
first = edge_points.front().v1;
last = edge_points.front().v2;
first = edgePoints.front().v1;
last = edgePoints.front().v2;
sorted.push_back(*edge_points.front().edge);
edges.erase(edge_points.front().it);
if (edge_points.front().closed) {
sorted.push_back(*edgePoints.front().edge);
edges.erase(edgePoints.front().it);
if (edgePoints.front().closed) {
return sorted;
}
edge_points.erase(edge_points.begin());
edgePoints.erase(edgePoints.begin());
auto reverseEdge = [](const TopoShape& edge) {
Standard_Real first = NAN;
Standard_Real last = NAN;
const Handle(Geom_Curve)& curve =
BRep_Tool::Curve(TopoDS::Edge(edge.getShape()), first, last);
first = curve->ReversedParameter(first);
last = curve->ReversedParameter(last);
TopoShape res(BRepBuilderAPI_MakeEdge(curve->Reversed(), last, first));
auto edgeName = Data::IndexedName::fromConst("Edge", 1);
if (auto mapped = edge.getMappedName(edgeName)) {
res.elementMap()->setElementName(edgeName, mapped, res.Tag);
}
auto v1Name = Data::IndexedName::fromConst("Vertex", 1);
auto v2Name = Data::IndexedName::fromConst("Vertex", 2);
auto v1 = edge.getMappedName(v1Name);
auto v2 = edge.getMappedName(v2Name);
if (v1 && v2) {
res.elementMap()->setElementName(v1Name, v2, res.Tag);
res.elementMap()->setElementName(v2Name, v1, res.Tag);
}
else if (v1 && edge.countSubShapes(TopAbs_EDGE) == 1) {
// It's possible an edge has only one vertex, so no need to reverse
// the name
res.elementMap()->setElementName(v1Name, v1, res.Tag);
}
else if (v1) {
res.elementMap()->setElementName(v2Name, v1, res.Tag);
}
else if (v2) {
res.elementMap()->setElementName(v1Name, v2, res.Tag);
}
return res;
};
while (!edge_points.empty()) {
while (!edgePoints.empty()) {
// search for adjacent edge
std::list<EdgePoints>::iterator pEI;
for (pEI = edge_points.begin(); pEI != edge_points.end(); ++pEI) {
for (pEI = edgePoints.begin(); pEI != edgePoints.end(); ++pEI) {
if (pEI->closed) {
continue;
}
@@ -779,37 +779,37 @@ std::deque<TopoShape> TopoShape::sortEdges(std::list<TopoShape>& edges, bool kee
last = pEI->v2;
sorted.push_back(*pEI->edge);
edges.erase(pEI->it);
edge_points.erase(pEI);
pEI = edge_points.begin();
edgePoints.erase(pEI);
pEI = edgePoints.begin();
break;
}
if (pEI->v2.SquareDistance(first) <= tol3d) {
sorted.push_front(*pEI->edge);
first = pEI->v1;
edges.erase(pEI->it);
edge_points.erase(pEI);
pEI = edge_points.begin();
edgePoints.erase(pEI);
pEI = edgePoints.begin();
break;
}
if (pEI->v2.SquareDistance(last) <= tol3d) {
last = pEI->v1;
sorted.push_back(reverseEdge(*pEI->edge));
edges.erase(pEI->it);
edge_points.erase(pEI);
pEI = edge_points.begin();
edgePoints.erase(pEI);
pEI = edgePoints.begin();
break;
}
if (pEI->v1.SquareDistance(first) <= tol3d) {
first = pEI->v2;
sorted.push_front(reverseEdge(*pEI->edge));
edges.erase(pEI->it);
edge_points.erase(pEI);
pEI = edge_points.begin();
edgePoints.erase(pEI);
pEI = edgePoints.begin();
break;
}
}
if ((pEI == edge_points.end()) || (last.SquareDistance(first) <= tol3d)) {
if ((pEI == edgePoints.end()) || (last.SquareDistance(first) <= tol3d)) {
// no adjacent edge found or polyline is closed
return sorted;
}

View File

@@ -161,4 +161,20 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundTwoCubes)
// 26 subshapes each
}
TEST_F(TopoShapeExpansionTest, makeElementWiresCombinesAdjacent)
{
// Arrange
auto edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
auto edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(1.0, 0.0, 0.0), gp_Pnt(2.0, 0.0, 0.0)).Edge();
Part::TopoShape topoShape;
std::vector<Part::TopoShape> shapes {edge1, edge2};
// Act
topoShape.makeElementWires(shapes);
// Assert
auto elementMap = topoShape.getElementMap();
EXPECT_EQ(6, elementMap.size());
}
// NOLINTEND(readability-magic-numbers,cppcoreguidelines-avoid-magic-numbers)