0025243: BRepFeat_SplitShape algorithm processes incorrect faces with degenerated...
[occt.git] / src / LocOpe / LocOpe_BuildWires.cxx
CommitLineData
b311480e 1// Created on: 1997-05-27
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17// Modified by skv - Mon May 31 12:58:34 2004 OCC5865
18
19#include <LocOpe_BuildWires.ixx>
20
21
22
23#include <BRep_Builder.hxx>
24#include <TopoDS_Compound.hxx>
25#include <TopoDS_Wire.hxx>
26#include <TopoDS_Edge.hxx>
27#include <TopoDS_Vertex.hxx>
28
29#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
30#include <TopTools_IndexedMapOfShape.hxx>
31#include <TopTools_MapOfShape.hxx>
32#include <TopTools_MapIteratorOfMapOfShape.hxx>
33#include <TopTools_ListIteratorOfListOfShape.hxx>
34
35#include <TopoDS.hxx>
36#include <TopExp.hxx>
37
38#include <Standard_ConstructionError.hxx>
39
40
41static Standard_Integer FindFirstEdge
42 (const TopTools_IndexedDataMapOfShapeListOfShape&,
43 const TopTools_MapOfShape&);
44
45
46
47//=======================================================================
48//function : LocOpe_BuildWires
49//purpose :
50//=======================================================================
51
52LocOpe_BuildWires::LocOpe_BuildWires () : myDone(Standard_False)
53{}
54
55
56//=======================================================================
57//function : LocOpe_BuildWires
58//purpose :
59//=======================================================================
60
61// Modified by skv - Mon May 31 12:58:27 2004 OCC5865 Begin
62LocOpe_BuildWires::LocOpe_BuildWires (const TopTools_ListOfShape& L,
59af51e3 63 const Handle(LocOpe_WiresOnShape)& PW)
7fd59977 64{
65 Perform(L, PW);
66}
67// Modified by skv - Mon May 31 12:58:28 2004 OCC5865 End
68
69
70//=======================================================================
71//function : Perform
72//purpose :
73//=======================================================================
74
75// Modified by skv - Mon May 31 12:59:09 2004 OCC5865 Begin
76void LocOpe_BuildWires::Perform(const TopTools_ListOfShape& L,
59af51e3 77 const Handle(LocOpe_WiresOnShape)& PW)
7fd59977 78{
79// Modified by skv - Mon May 31 12:59:10 2004 OCC5865 End
80 myDone = Standard_False;
81 myRes.Clear();
82
83 BRep_Builder B;
84 TopoDS_Compound C;
85 B.MakeCompound(C);
86
87 TopTools_MapOfShape theMap;
88 TopTools_ListIteratorOfListOfShape itl(L);
89 for (; itl.More(); itl.Next()) {
90 const TopoDS_Shape& edg = itl.Value();
91 if (theMap.Add(edg) && edg.ShapeType() == TopAbs_EDGE) {
92 B.Add(C,edg.Oriented(TopAbs_FORWARD)); // orientation importante pour
93 // appel a TopExp::Vertices
94 }
95 }
96
97 TopTools_IndexedDataMapOfShapeListOfShape theMapVE;
98 TopExp::MapShapesAndAncestors(C,TopAbs_VERTEX,TopAbs_EDGE,theMapVE);
99
100 TopTools_MapOfShape Bords;
101// for (Standard_Integer i = 1; i <= theMapVE.Extent(); i++) {
102 Standard_Integer i ;
103 for ( i = 1; i <= theMapVE.Extent(); i++) {
104// Modified by skv - Mon May 31 13:07:50 2004 OCC5865 Begin
105// if (theMapVE(i).Extent() == 1) {
106 TopoDS_Vertex vtx = TopoDS::Vertex(theMapVE.FindKey(i));
107 TopoDS_Edge etmp;
108 Standard_Real partmp;
109
110 if (theMapVE(i).Extent() == 1 || PW->OnEdge(vtx, etmp, partmp)) {
111 Bords.Add(vtx);
112// Modified by skv - Mon May 31 13:07:50 2004 OCC5865 End
113 }
114 }
115
116
117 while ((i=FindFirstEdge(theMapVE,Bords)) <= theMapVE.Extent()) {
118 TopTools_IndexedMapOfShape mapE;
119 TopTools_MapOfShape mapV;
120 const TopoDS_Edge& edgf = TopoDS::Edge(theMapVE(i).First());
121
122 TopoDS_Vertex VF,VL;
123 TopExp::Vertices(edgf,VF,VL);
124
125 if (Bords.Contains(VL) && !Bords.Contains(VF)) {
126 mapE.Add(edgf.Oriented(TopAbs_REVERSED));
127 TopoDS_Vertex temp = VF;
128 VF = VL;
129 VL = temp;
130 }
131 else {
132 mapE.Add(edgf.Oriented(TopAbs_FORWARD));
133 }
134 mapV.Add(VF);
135
136 while (!(mapV.Contains(VL) || Bords.Contains(VL))) {
137 Standard_Integer ind = theMapVE.FindIndex(VL);
138 TopTools_ListIteratorOfListOfShape itl(theMapVE(ind));
139 for (; itl.More(); itl.Next()) {
140 if (!mapE.Contains(itl.Value())) {
141 break;
142 }
143 }
144
145 if (!itl.More()) {
146 Standard_ConstructionError::Raise();
147 }
148 const TopoDS_Edge& theEdge = TopoDS::Edge(itl.Value());
149 TopoDS_Vertex Vf,Vl;
150 TopExp::Vertices(theEdge,Vf,Vl);
151 mapV.Add(VL);
152 if (Vf.IsSame(VL)) {
153 mapE.Add(theEdge.Oriented(TopAbs_FORWARD));
154 VL = Vl;
155 }
156 else { // on doit avoir Vl == VL
157 mapE.Add(theEdge.Oriented(TopAbs_REVERSED));
158 VL = Vf;
159 }
160 }
161
162 TopoDS_Wire newWire;
163 B.MakeWire(newWire);
7fd59977 164
165 if (mapV.Contains(VL)) { // on sort avec une boucle a recreer
166 TopoDS_Vertex Vf;
167// for (Standard_Integer j = 1; j<= mapE.Extent(); j++) {
168 Standard_Integer j ;
169 for ( j = 1; j<= mapE.Extent(); j++) {
170 const TopoDS_Edge& edg = TopoDS::Edge(mapE(j));
171 if (edg.Orientation() == TopAbs_FORWARD) {
172 Vf = TopExp::FirstVertex(edg);
173 }
174 else {
175 Vf = TopExp::LastVertex(edg);
176 }
177 if (Vf.IsSame(VL)) {
178 break;
179 }
180 mapV.Remove(Vf);
181 }
7fd59977 182 for (; j<= mapE.Extent(); j++) {
183 B.Add(newWire,mapE(j));
184 }
185 newWire.Closed(Standard_True);
186 }
187 else { // on sort sur un bord : wire ouvert...
7fd59977 188 mapV.Add(VL);
189 for (Standard_Integer j = 1; j <= mapE.Extent(); j++) {
190 B.Add(newWire,mapE(j));
191 }
192 newWire.Closed(Standard_False);
193 }
194
195 myRes.Append(newWire);
196 TopTools_MapIteratorOfMapOfShape itm;
197 for (itm.Initialize(mapV);
198 itm.More();itm.Next()) {
199 const TopoDS_Vertex& vtx = TopoDS::Vertex(itm.Key());
200 Bords.Add(vtx);
201 Standard_Integer ind = theMapVE.FindIndex(vtx);
202 itl.Initialize(theMapVE(ind));
203 while (itl.More()) {
204 if (mapE.Contains(itl.Value())) {
205 theMapVE(ind).Remove(itl);
206 }
207 else {
208 itl.Next();
209 }
210 }
211 }
212 }
213
214 myDone = Standard_True;
215}
216
217
218
219//=======================================================================
220//function : IsDone
221//purpose :
222//=======================================================================
223
224Standard_Boolean LocOpe_BuildWires::IsDone() const
225{
226 return myDone;
227}
228
229
230
231//=======================================================================
232//function : Result
233//purpose :
234//=======================================================================
235
236const TopTools_ListOfShape& LocOpe_BuildWires::Result () const
237{
238 if (!myDone) {
239 StdFail_NotDone::Raise();
240 }
241 return myRes;
242}
243
244
245//=======================================================================
246//function : FindFirstEdge
247//purpose :
248//=======================================================================
249
250static Standard_Integer FindFirstEdge
251 (const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
252 const TopTools_MapOfShape& theBord)
253{
254 Standard_Integer i = 1;
255
256 for (; i<=theMapVE.Extent(); i++) {
257 if (theMapVE(i).Extent() >0) {
258 break;
259 }
260 }
261
262 if (i>theMapVE.Extent()) {
263 return i;
264 }
265
266 Standard_Integer goodi = i;
267 for (; i <= theMapVE.Extent(); i++) {
268 const TopoDS_Shape& vtx = theMapVE.FindKey(i);
269 if (theMapVE(i).Extent() >0 && theBord.Contains(vtx)) {
270 goodi = i;
271 break;
272 }
273 }
274 return goodi;
275}
276