[TD]New face finder algo
This commit is contained in:
@@ -27,8 +27,6 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <boost/graph/boyer_myrvold_planar_test.hpp>
|
||||
#include <boost/graph/is_kuratowski_subgraph.hpp>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <Bnd_Box.hxx>
|
||||
@@ -38,19 +36,19 @@
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <BRepGProp.hxx>
|
||||
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
|
||||
#include <boost/graph/boyer_myrvold_planar_test.hpp>
|
||||
#include <boost/graph/is_kuratowski_subgraph.hpp>
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
|
||||
#include "DrawUtil.h"
|
||||
#include "EWTOLERANCE.h"
|
||||
#include "EdgeWalker.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
@@ -69,19 +67,18 @@ void edgeVisitor::next_edge(Edge e)
|
||||
we.v2 = t;
|
||||
we.ed = e;
|
||||
we.idx = get(edge_index, m_g, e);
|
||||
//Base::Console().Message("TRACE - EV::next_Edge - visiting (%d, %d) idx: %d\n", s,t, we.idx);
|
||||
wireEdges.push_back(we);
|
||||
}
|
||||
|
||||
void edgeVisitor::begin_face()
|
||||
{
|
||||
//Base::Console().Message("TRACE - EV::begin_face()\n");
|
||||
// Base::Console().Message("EV::begin_face()\n");
|
||||
wireEdges.clear();
|
||||
}
|
||||
|
||||
void edgeVisitor::end_face()
|
||||
{
|
||||
//Base::Console().Message("TRACE - EV::end_face()\n");
|
||||
// Base::Console().Message("EV::end_face()\n");
|
||||
graphWires.push_back(wireEdges);
|
||||
}
|
||||
|
||||
@@ -99,11 +96,6 @@ void edgeVisitor::setGraph(TechDraw::graph& g)
|
||||
//* EdgeWalker methods
|
||||
//*******************************************************
|
||||
|
||||
//some shapes are being passed in where edges that should be connected are in fact
|
||||
//separated by more than 2*Precision::Confusion (expected tolerance for 2 TopoDS_Vertex)
|
||||
#define EWTOLERANCE 0.00001 //arbitrary number that seems to give good results for drawing
|
||||
|
||||
|
||||
EdgeWalker::EdgeWalker()
|
||||
{
|
||||
}
|
||||
@@ -115,7 +107,7 @@ EdgeWalker::~EdgeWalker()
|
||||
//loads a list of unique edges into the traversal mechanism
|
||||
bool EdgeWalker::loadEdges(std::vector<TechDraw::WalkerEdge>& edges)
|
||||
{
|
||||
//Base::Console().Message("TRACE -EW::loadEdges(we)\n");
|
||||
// Base::Console().Message("EW::loadEdges(we) - WEdgesIn: %d\n", edges.size());
|
||||
int idx = 0;
|
||||
for (auto& e: edges) {
|
||||
std::pair<edge_t, bool> p;
|
||||
@@ -131,7 +123,7 @@ bool EdgeWalker::loadEdges(std::vector<TechDraw::WalkerEdge>& edges)
|
||||
|
||||
bool EdgeWalker::loadEdges(std::vector<TopoDS_Edge> edges)
|
||||
{
|
||||
//Base::Console().Message("TRACE -EW::loadEdges(TopoDS)\n");
|
||||
// Base::Console().Message("EW::loadEdges(TopoDS) - edges: %d\n", edges.size());
|
||||
if (edges.empty()) {
|
||||
throw Base::ValueError("EdgeWalker has no edges to load\n");
|
||||
}
|
||||
@@ -146,19 +138,19 @@ bool EdgeWalker::loadEdges(std::vector<TopoDS_Edge> edges)
|
||||
|
||||
return true;
|
||||
}
|
||||
bool EdgeWalker::setSize(int size)
|
||||
bool EdgeWalker::setSize(std::size_t size)
|
||||
{
|
||||
m_g.clear();
|
||||
for (int i = 0; i < size; i++) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
boost::adjacency_list<>::vertex_descriptor vd = boost::add_vertex(m_g);
|
||||
(void)vd;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EdgeWalker::perform()
|
||||
bool EdgeWalker::prepare()
|
||||
{
|
||||
//Base::Console().Message("TRACE - EW::perform()\n");
|
||||
//Base::Console().Message("TRACE - EW::prepare()\n");
|
||||
// Initialize the interior edge index
|
||||
property_map<TechDraw::graph, edge_index_t>::type e_index = get(edge_index, m_g);
|
||||
graph_traits<TechDraw::graph>::edges_size_type edge_count = 0;
|
||||
@@ -198,16 +190,16 @@ bool EdgeWalker::perform()
|
||||
std::back_inserter(kEdges));
|
||||
if (!isPlanar) {
|
||||
//TODO: remove kura subgraph to make planar??
|
||||
Base::Console().Log("LOG - EW::perform - input is NOT planar\n");
|
||||
Base::Console().Message("EW::prepare - input is NOT planar\n");
|
||||
ki_end = kEdges.end();
|
||||
std::stringstream ss;
|
||||
ss << "EW::perform - obstructing edges: ";
|
||||
ss << "EW::prepare - obstructing edges: ";
|
||||
for(ki = kEdges.begin(); ki != ki_end; ++ki) {
|
||||
e1 = *ki;
|
||||
ss << boost::get(edge_index, m_g, e1) << ", ";
|
||||
}
|
||||
ss << std::endl;
|
||||
Base::Console().Log("LOG - %s\n", ss.str().c_str());
|
||||
Base::Console().Message("%s\n", ss.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -217,6 +209,18 @@ bool EdgeWalker::perform()
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Wire> EdgeWalker::execute(std::vector<TopoDS_Edge> edgeList, bool biggie)
|
||||
{
|
||||
std::vector<TopoDS_Wire> sortedWires;
|
||||
loadEdges(edgeList);
|
||||
bool success = prepare();
|
||||
if (success) {
|
||||
std::vector<TopoDS_Wire> rw = getResultNoDups();
|
||||
sortedWires = sortStrip(rw, biggie);
|
||||
}
|
||||
return sortedWires;
|
||||
}
|
||||
|
||||
ewWireList EdgeWalker::getResult()
|
||||
{
|
||||
//Base::Console().Message("TRACE - EW::getResult()\n");
|
||||
@@ -242,7 +246,7 @@ std::vector<TopoDS_Wire> EdgeWalker::getResultWires()
|
||||
TopoDS_Edge e = m_saveInEdges.at((*iEdge).idx);
|
||||
topoEdges.push_back(e);
|
||||
}
|
||||
TopoDS_Wire w = makeCleanWire(topoEdges); //make 1 clean wire from its edges
|
||||
TopoDS_Wire w = makeCleanWire(topoEdges, EWTOLERANCE); //make 1 clean wire from its edges
|
||||
fw.push_back(w);
|
||||
}
|
||||
return fw;
|
||||
@@ -267,8 +271,8 @@ std::vector<TopoDS_Wire> EdgeWalker::getResultNoDups()
|
||||
TopoDS_Edge e = m_saveInEdges.at((*iEdge).idx);
|
||||
topoEdges.push_back(e);
|
||||
}
|
||||
TopoDS_Wire w = makeCleanWire(topoEdges); //make 1 clean wire from its edges
|
||||
fw.push_back(w);
|
||||
TopoDS_Wire w = makeCleanWire(topoEdges, EWTOLERANCE); //make 1 clean wire from its edges
|
||||
fw.push_back(w);
|
||||
}
|
||||
return fw;
|
||||
}
|
||||
@@ -289,43 +293,50 @@ TopoDS_Wire EdgeWalker::makeCleanWire(std::vector<TopoDS_Edge> edges, double tol
|
||||
|
||||
Handle(ShapeFix_Wire) fixer = new ShapeFix_Wire;
|
||||
fixer->Load(wireData);
|
||||
fixer->Perform();
|
||||
fixer->FixReorder();
|
||||
fixer->SetPrecision(2.0 * EWTOLERANCE);
|
||||
fixer->SetMaxTolerance(tol);
|
||||
fixer->ClosedWireMode() = Standard_True;
|
||||
fixer->FixConnected(Precision::Confusion());
|
||||
fixer->FixClosed(Precision::Confusion());
|
||||
fixer->ModifyGeometryMode() = Standard_True;
|
||||
fixer->ModifyTopologyMode() = Standard_False;
|
||||
fixer->FixSelfIntersectingEdgeMode() = Standard_True;
|
||||
fixer->FixIntersectingEdgesMode() = Standard_True;
|
||||
fixer->FixIntersectingEdgesMode() = Standard_True;
|
||||
fixer->FixConnectedMode() = Standard_True;
|
||||
fixer->FixReorderMode() = Standard_True;
|
||||
fixer->Perform();
|
||||
|
||||
for (int i = 1; i <= wireData->NbEdges(); i ++) {
|
||||
TopoDS_Edge edge = fixer->WireData()->Edge(i);
|
||||
sTol.SetTolerance(edge, tol, TopAbs_VERTEX);
|
||||
mkWire.Add(edge);
|
||||
}
|
||||
result = fixer->WireAPIMake();
|
||||
|
||||
result = mkWire.Wire();
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Vertex> EdgeWalker:: makeUniqueVList(std::vector<TopoDS_Edge> edges)
|
||||
{
|
||||
//Base::Console().Message("TRACE - EW::makeUniqueVList()\n");
|
||||
// Base::Console().Message("TRACE - EW::makeUniqueVList() - edgesIn: %d\n", edges.size());
|
||||
std::vector<TopoDS_Vertex> uniqueVert;
|
||||
for(auto& e:edges) {
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex(e);
|
||||
Base::Vector3d v1 = DrawUtil::vertex2Vector(TopExp::FirstVertex(e));
|
||||
Base::Vector3d v2 = DrawUtil::vertex2Vector(TopExp::LastVertex(e));
|
||||
bool addv1 = true;
|
||||
bool addv2 = true;
|
||||
for (const auto& v:uniqueVert) {
|
||||
if (DrawUtil::isSamePoint(v, v1, EWTOLERANCE))
|
||||
//check if we've already added this vertex
|
||||
for (const auto& v: uniqueVert) {
|
||||
Base::Vector3d v3d = DrawUtil::vertex2Vector(v);
|
||||
if (v3d.IsEqual(v1, EWTOLERANCE)) {
|
||||
addv1 = false;
|
||||
if (DrawUtil::isSamePoint(v, v2, EWTOLERANCE))
|
||||
}
|
||||
if (v3d.IsEqual(v2, EWTOLERANCE)) {
|
||||
addv2 = false;
|
||||
}
|
||||
}
|
||||
if (addv1) {
|
||||
uniqueVert.push_back(TopExp::FirstVertex(e));
|
||||
}
|
||||
if (addv2) {
|
||||
uniqueVert.push_back(TopExp::LastVertex(e));
|
||||
}
|
||||
if (addv1)
|
||||
uniqueVert.push_back(v1);
|
||||
if (addv2)
|
||||
uniqueVert.push_back(v2);
|
||||
}
|
||||
// Base::Console().Message("EW::makeUniqueVList - verts out: %d\n", uniqueVert.size());
|
||||
return uniqueVert;
|
||||
}
|
||||
|
||||
@@ -333,17 +344,24 @@ std::vector<TopoDS_Vertex> EdgeWalker:: makeUniqueVList(std::vector<TopoDS_Edge>
|
||||
std::vector<WalkerEdge> EdgeWalker::makeWalkerEdges(std::vector<TopoDS_Edge> edges,
|
||||
std::vector<TopoDS_Vertex> verts)
|
||||
{
|
||||
// Base::Console().Message("TRACE - EW::makeWalkerEdges()\n");
|
||||
// Base::Console().Message("TRACE - EW::makeWalkerEdges() - edges: %d verts: %d\n", edges.size(), verts.size());
|
||||
m_saveInEdges = edges;
|
||||
std::vector<WalkerEdge> walkerEdges;
|
||||
for (const auto& e:edges) {
|
||||
TopoDS_Vertex ev1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex ev2 = TopExp::LastVertex(e);
|
||||
int v1dx = findUniqueVert(ev1, verts);
|
||||
int v2dx = findUniqueVert(ev2, verts);
|
||||
TopoDS_Vertex edgeVertex1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex edgeVertex2 = TopExp::LastVertex(e);
|
||||
std::size_t vertex1Index = findUniqueVert(edgeVertex1, verts);
|
||||
if (vertex1Index == SIZE_MAX) {
|
||||
continue;
|
||||
}
|
||||
std::size_t vertex2Index = findUniqueVert(edgeVertex2, verts);
|
||||
if (vertex2Index == SIZE_MAX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WalkerEdge we;
|
||||
we.v1 = v1dx;
|
||||
we.v2 = v2dx;
|
||||
we.v1 = vertex1Index;
|
||||
we.v2 = vertex2Index;
|
||||
we.idx = 0;
|
||||
walkerEdges.push_back(we);
|
||||
}
|
||||
@@ -352,18 +370,20 @@ std::vector<WalkerEdge> EdgeWalker::makeWalkerEdges(std::vector<TopoDS_Edge> edg
|
||||
return walkerEdges;
|
||||
}
|
||||
|
||||
int EdgeWalker::findUniqueVert(TopoDS_Vertex vx, std::vector<TopoDS_Vertex> &uniqueVert)
|
||||
size_t EdgeWalker::findUniqueVert(TopoDS_Vertex vx, std::vector<TopoDS_Vertex> &uniqueVert)
|
||||
{
|
||||
// Base::Console().Message("TRACE - EW::findUniqueVert()\n");
|
||||
int idx = 0;
|
||||
int result = 0;
|
||||
for(auto& v:uniqueVert) { //we're always going to find vx, right?
|
||||
if (DrawUtil::isSamePoint(v, vx, EWTOLERANCE)) {
|
||||
std::size_t idx = 0;
|
||||
std::size_t result = SIZE_MAX;
|
||||
Base::Vector3d vx3d = DrawUtil::vertex2Vector(vx);
|
||||
for(auto& v : uniqueVert) {
|
||||
Base::Vector3d v3d = DrawUtil::vertex2Vector(v);
|
||||
if (vx3d.IsEqual(v3d, EWTOLERANCE)) {
|
||||
result = idx;
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
} //if idx >= uniqueVert.size() TARFU
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -377,8 +397,8 @@ std::vector<TopoDS_Wire> EdgeWalker::sortStrip(std::vector<TopoDS_Wire> fw, bool
|
||||
}
|
||||
std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(closedWires, false); //biggest 1st
|
||||
if (sortedWires.empty()) {
|
||||
Base::Console().Log("INFO - EW::sortStrip - no sorted Wires!\n");
|
||||
return sortedWires; // might happen in the middle of changes?
|
||||
Base::Console().Message("EW::sortStrip - no sorted Wires!\n");
|
||||
return sortedWires;
|
||||
}
|
||||
|
||||
if (!includeBiggest) {
|
||||
@@ -415,30 +435,34 @@ std::vector<embedItem> EdgeWalker::makeEmbedding(const std::vector<TopoDS_Edge>
|
||||
// edges.size(), uniqueVList.size());
|
||||
std::vector<embedItem> result;
|
||||
|
||||
int iv = 0;
|
||||
std::size_t iVert = 0;
|
||||
//make an embedItem for each vertex in uniqueVList
|
||||
//for each vertex v
|
||||
// find all the edges that have v as first or last vertex
|
||||
for (auto& v: uniqueVList) {
|
||||
int ie = 0;
|
||||
TopoDS_Vertex cv = v; //v is const but we need non-const for vertexEqual
|
||||
std::size_t iEdge = 0;
|
||||
std::vector<incidenceItem> iiList;
|
||||
for (auto& e: edges) {
|
||||
double angle = 0;
|
||||
if (DrawUtil::isFirstVert(e, v,EWTOLERANCE)) {
|
||||
angle = DrawUtil::angleWithX(e, v,EWTOLERANCE);
|
||||
incidenceItem ii(ie, angle, m_saveWalkerEdges[ie].ed);
|
||||
TopoDS_Vertex edgeVertex1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex edgeVertex2 = TopExp::LastVertex(e);
|
||||
if (DrawUtil::vertexEqual(cv, edgeVertex1)) {
|
||||
angle = DrawUtil::incidenceAngleAtVertex(e,v,EWTOLERANCE);
|
||||
incidenceItem ii(iEdge, angle, m_saveWalkerEdges[iEdge].ed);
|
||||
iiList.push_back(ii);
|
||||
} else if (DrawUtil::isLastVert(e, v,EWTOLERANCE)) {
|
||||
angle = DrawUtil::angleWithX(e, v,EWTOLERANCE);
|
||||
incidenceItem ii(ie, angle, m_saveWalkerEdges[ie].ed);
|
||||
} else if (DrawUtil::vertexEqual(cv, edgeVertex2)) {
|
||||
angle = DrawUtil::incidenceAngleAtVertex(e,v,EWTOLERANCE);
|
||||
incidenceItem ii(iEdge, angle, m_saveWalkerEdges[iEdge].ed);
|
||||
iiList.push_back(ii);
|
||||
} else {
|
||||
//Base::Console().Message("TRACE - EW::makeEmbedding - neither first nor last\n");
|
||||
}
|
||||
ie++;
|
||||
iEdge++;
|
||||
}
|
||||
//sort incidenceList by angle
|
||||
iiList = embedItem::sortIncidenceList(iiList, false);
|
||||
embedItem embed(iv, iiList);
|
||||
embedItem embed(iVert, iiList);
|
||||
result.push_back(embed);
|
||||
iv++;
|
||||
iVert++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -523,7 +547,7 @@ void ewWire::push_back(WalkerEdge w)
|
||||
wedges.push_back(w);
|
||||
}
|
||||
|
||||
int ewWire::size()
|
||||
std::size_t ewWire::size(void)
|
||||
{
|
||||
return wedges.size();
|
||||
}
|
||||
@@ -560,7 +584,7 @@ void ewWireList::push_back(ewWire w)
|
||||
wires.push_back(w);
|
||||
}
|
||||
|
||||
int ewWireList::size()
|
||||
std::size_t ewWireList::size(void)
|
||||
{
|
||||
return wires.size();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user