1
/***************************************************************************
2
* Copyright (c) 2010 Joachim Zettler <Joachim.Zettler@gmx.de> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
25
# include <BRep_Tool.hxx>
26
# include <BRepAdaptor_Curve.hxx>
29
# include <TopoDS_Vertex.hxx>
32
#include "edgecluster.h"
37
Edgecluster::Edgecluster(const std::vector<TopoDS_Edge>& unsorted_edges)
38
:m_unsortededges(unsorted_edges)
42
m_final_cluster.clear();
45
Edgecluster::~Edgecluster() = default;
47
tEdgeClusterVector Edgecluster::GetClusters()
50
return m_final_cluster;
53
void Edgecluster::Perform()
55
if ( m_unsortededges.empty() )
58
//adds all the vertices to a map, and store the associated edges
59
std::vector<TopoDS_Edge>::iterator aVectorIt;
60
for (aVectorIt = m_unsortededges.begin();aVectorIt != m_unsortededges.end();++aVectorIt)
62
if (IsValidEdge(*aVectorIt))
68
//now, iterate through the edges to sort and cluster them
73
//Lets start with a vertice that only has one edge (that means start or end point of the merged edges!)
74
tMapPntEdge::iterator iter;
76
for(iter=m_vertices.begin();iter!=m_vertices.end();++iter)
78
if (iter->second.size()==1)
85
iter = m_vertices.begin();
86
const gp_Pnt& firstPoint = iter->first;
87
gp_Pnt currentPoint = firstPoint;
88
Standard_Boolean toContinue;
91
toContinue = PerformEdges(currentPoint);
93
while (toContinue == Standard_True);
94
//Store the current adjacent edges as a cluster
95
m_final_cluster.push_back(m_edges);
96
//and continue now with the still existing edges in the m_vertices
98
while (!m_vertices.empty());
103
bool Edgecluster::PerformEdges(gp_Pnt& point)
105
tMapPntEdge::iterator iter = m_vertices.find(point);
106
if ( iter == m_vertices.end() )
109
tEdgeVector& edges = iter->second;
111
tEdgeVector::iterator edgeIt = edges.begin();
114
if ( edgeIt == edges.end() )
116
//Delete also the current vertex
117
m_vertices.erase(iter);
122
TopoDS_Edge theEdge = *edgeIt;
124
//we are storing the edge, so remove it from the vertex association
127
//if no more edges, remove the vertex
129
m_vertices.erase(iter);
133
TopExp::Vertices(theEdge,V1,V2);
134
gp_Pnt P1 = BRep_Tool::Pnt(V1);
135
gp_Pnt P2 = BRep_Tool::Pnt(V2);
136
if ( theEdge.Orientation() == TopAbs_REVERSED )
145
if ( P2.IsEqual(point,0.2) )
147
//need to reverse the edge
158
//need to erase the edge from the second point
159
iter = m_vertices.find(nextPoint);
160
if ( iter != m_vertices.end() )
162
tEdgeVector& nextEdges = iter->second;
163
for ( edgeIt = nextEdges.begin() ; edgeIt != nextEdges.end(); ++edgeIt )
165
if ( theEdge.IsSame(*edgeIt) )
167
nextEdges.erase(edgeIt);
173
//put the edge at the end of the list
174
m_edges.push_back(theEdge);
176
//Update the point for the next do-while loop
182
void Edgecluster::Perform(const TopoDS_Edge& edge)
187
TopExp::Vertices(edge,V1,V2);
188
gp_Pnt P1 = BRep_Tool::Pnt(V1);
189
gp_Pnt P2 = BRep_Tool::Pnt(V2);
191
tEdgeVector emptyList;
193
std::pair<tMapPntEdge::iterator,bool> iter = m_vertices.insert(tMapPntEdgePair(P1,emptyList));
194
iter.first->second.push_back(edge);
195
iter = m_vertices.insert(tMapPntEdgePair(P2,emptyList));
196
iter.first->second.push_back(edge);
200
bool Edgecluster::IsValidEdge(const TopoDS_Edge& edge)
204
if ( BRep_Tool::Degenerated(edge) )
207
BRepAdaptor_Curve bac(edge);
209
Standard_Real fparam = bac.FirstParameter();
210
Standard_Real lparam = bac.LastParameter();
212
gp_Pnt fpoint = bac.Value(fparam);
213
gp_Pnt lpoint = bac.Value(lparam);
215
//do not test the distance first last in case of a full circle edge (fpoint == lastpoint)
216
//if ( fpoint.IsEqual(lpoint,1e-5 ) )
219
gp_Pnt mpoint = bac.Value((fparam+lparam)*0.5);
221
Standard_Real dist = mpoint.Distance(lpoint);
224
dist = mpoint.Distance(fpoint);