FreeCAD

Форк
0
/
edgecluster.cpp 
229 строк · 6.7 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2010 Joachim Zettler <Joachim.Zettler@gmx.de>           *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
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.      *
10
 *                                                                         *
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.                  *
15
 *                                                                         *
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                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
# include <BRep_Tool.hxx>
26
# include <BRepAdaptor_Curve.hxx>
27
# include <TopExp.hxx>
28
# include <TopoDS.hxx>
29
# include <TopoDS_Vertex.hxx>
30
#endif
31

32
#include "edgecluster.h"
33

34

35
using namespace Part;
36

37
Edgecluster::Edgecluster(const std::vector<TopoDS_Edge>& unsorted_edges)
38
        :m_unsortededges(unsorted_edges)
39
{
40
    m_edges.clear();
41
    m_vertices.clear();
42
    m_final_cluster.clear();
43
}
44

45
Edgecluster::~Edgecluster() = default;
46

47
tEdgeClusterVector Edgecluster::GetClusters()
48
{
49
    Perform();
50
    return m_final_cluster;
51
}
52

53
void Edgecluster::Perform()
54
{
55
    if ( m_unsortededges.empty() )
56
        return;
57

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)
61
    {
62
        if (IsValidEdge(*aVectorIt))
63
        {
64
            Perform(*aVectorIt);
65
        }
66
    }
67

68
    //now, iterate through the edges to sort and cluster them
69

70
    do
71
    {
72
        m_edges.clear();
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;
75
        bool closed = true;
76
        for(iter=m_vertices.begin();iter!=m_vertices.end();++iter)
77
        {
78
            if (iter->second.size()==1)
79
            {
80
                closed = false;
81
                break;
82
            }
83
        }
84
        if(closed)
85
            iter = m_vertices.begin();
86
        const gp_Pnt& firstPoint = iter->first;
87
        gp_Pnt currentPoint = firstPoint;
88
        Standard_Boolean toContinue;
89
        do
90
        {
91
            toContinue = PerformEdges(currentPoint);
92
        }
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
97
    }
98
    while (!m_vertices.empty());
99

100
    m_done = true;
101
}
102

103
bool Edgecluster::PerformEdges(gp_Pnt& point)
104
{
105
    tMapPntEdge::iterator iter = m_vertices.find(point);
106
    if ( iter == m_vertices.end() )
107
        return false;
108

109
    tEdgeVector& edges = iter->second;
110

111
    tEdgeVector::iterator edgeIt = edges.begin();
112

113
    //no more edges. pb
114
    if ( edgeIt == edges.end() )
115
    {
116
        //Delete also the current vertex
117
        m_vertices.erase(iter);
118

119
        return false;
120
    }
121

122
    TopoDS_Edge theEdge = *edgeIt;
123

124
    //we are storing the edge, so remove it from the vertex association
125
    edges.erase(edgeIt);
126

127
    //if no more edges, remove the vertex
128
    if ( edges.empty() )
129
        m_vertices.erase(iter);
130

131

132
    TopoDS_Vertex V1,V2;
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 )
137
    {
138
        //switch the points
139
        gp_Pnt tmpP = P1;
140
        P1 = P2;
141
        P2 = tmpP;
142
    }
143

144
    gp_Pnt nextPoint;
145
    if ( P2.IsEqual(point,0.2) )
146
    {
147
        //need to reverse the edge
148

149
        theEdge.Reverse();
150
        nextPoint = P1;
151
    }
152
    else
153
    {
154
        nextPoint = P2;
155
    }
156

157

158
    //need to erase the edge from the second point
159
    iter = m_vertices.find(nextPoint);
160
    if ( iter != m_vertices.end() )
161
    {
162
        tEdgeVector& nextEdges = iter->second;
163
        for ( edgeIt = nextEdges.begin() ; edgeIt != nextEdges.end(); ++edgeIt )
164
        {
165
            if ( theEdge.IsSame(*edgeIt) )
166
            {
167
                nextEdges.erase(edgeIt);
168
                break;
169
            }
170
        }
171
    }
172

173
    //put the edge at the end of the list
174
    m_edges.push_back(theEdge);
175

176
    //Update the point for the next do-while loop
177
    point = nextPoint;
178
    return true;
179

180
}
181

182
void Edgecluster::Perform(const TopoDS_Edge& edge)
183
{
184
    if ( edge.IsNull() )
185
        return;
186
    TopoDS_Vertex V1,V2;
187
    TopExp::Vertices(edge,V1,V2);
188
    gp_Pnt P1 = BRep_Tool::Pnt(V1);
189
    gp_Pnt P2 = BRep_Tool::Pnt(V2);
190

191
    tEdgeVector emptyList;
192

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);
197
}
198

199

200
bool Edgecluster::IsValidEdge(const TopoDS_Edge& edge)
201
{
202
    if ( edge.IsNull() )
203
        return false;
204
    if ( BRep_Tool::Degenerated(edge) )
205
        return false;
206

207
    BRepAdaptor_Curve bac(edge);
208

209
    Standard_Real fparam = bac.FirstParameter();
210
    Standard_Real lparam = bac.LastParameter();
211

212
    gp_Pnt fpoint = bac.Value(fparam);
213
    gp_Pnt lpoint = bac.Value(lparam);
214

215
    //do not test the distance first last in case of a full circle edge (fpoint == lastpoint)
216
    //if ( fpoint.IsEqual(lpoint,1e-5 ) )
217
    //      return false;
218

219
    gp_Pnt mpoint = bac.Value((fparam+lparam)*0.5);
220

221
    Standard_Real dist = mpoint.Distance(lpoint);
222
    if ( dist <= 1e-5 )
223
        return false;
224
    dist = mpoint.Distance(fpoint);
225
    if ( dist <= 1e-5 )
226
        return false;
227

228
    return true;
229
}
230

231

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.