0024428: Implementation of LGPL license
[occt.git] / src / BOPAlgo / BOPAlgo_WireSplitter.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
4e57c75e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
4e57c75e 5//
973c2be1 6// This library is free software; you can redistribute it and / or modify it
7// under the terms of the GNU Lesser General Public version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
4e57c75e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
4e57c75e 14
15#include <BOPAlgo_WireSplitter.ixx>
16
17#include <TopoDS_Shape.hxx>
18#include <TopoDS_Iterator.hxx>
19#include <TopoDS_Edge.hxx>
20#include <TopoDS.hxx>
21#include <TopoDS_Wire.hxx>
22
23#include <BRep_Tool.hxx>
24#include <BRep_Builder.hxx>
25
26#include <BOPCol_ListOfShape.hxx>
27#include <BOPCol_IndexedMapOfShape.hxx>
28#include <BOPCol_MapOfShape.hxx>
29#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
30
31#include <BOPTools.hxx>
32
33
34//=======================================================================
35//function :
36//purpose :
37//=======================================================================
38 BOPAlgo_WireSplitter::BOPAlgo_WireSplitter()
39:
40 BOPAlgo_Algo(),
41 myWES(NULL),
42 myLCB(myAllocator)
43{
44}
45//=======================================================================
46//function :
47//purpose :
48//=======================================================================
49 BOPAlgo_WireSplitter::BOPAlgo_WireSplitter(const Handle(NCollection_BaseAllocator)& theAllocator)
50:
51 BOPAlgo_Algo(theAllocator),
52 myWES(NULL),
53 myLCB(myAllocator)
54{
55}
56//=======================================================================
57//function : ~
58//purpose :
59//=======================================================================
60 BOPAlgo_WireSplitter::~BOPAlgo_WireSplitter()
61{
62}
63//=======================================================================
64//function : SetWES
65//purpose :
66//=======================================================================
67 void BOPAlgo_WireSplitter::SetWES(const BOPAlgo_WireEdgeSet& theWES)
68{
69 myWES=(BOPAlgo_WireEdgeSet*)&theWES;
70}
71//=======================================================================
72//function : WES
73//purpose :
74//=======================================================================
75 BOPAlgo_WireEdgeSet& BOPAlgo_WireSplitter::WES()
76{
77 return *myWES;
78}
79//=======================================================================
80// function: CheckData
81// purpose:
82//=======================================================================
83 void BOPAlgo_WireSplitter::CheckData()
84{
85 myErrorStatus=0;
86 if (!myWES) {
87 myErrorStatus=10;
88 return;
89 }
90}
91//=======================================================================
92//function : Perform
93//purpose :
94//=======================================================================
95 void BOPAlgo_WireSplitter::Perform()
96{
97 myErrorStatus=0;
98 //
99 CheckData();
100 if (myErrorStatus) {
101 return;
102 }
103 //
104 MakeConnexityBlocks();
105 MakeWires();
106}
107//=======================================================================
108//function : MakeWires
109//purpose :
110//=======================================================================
111 void BOPAlgo_WireSplitter::MakeWires()
112{
113 Standard_Boolean bIsRegular;
114 TopoDS_Wire aW;
115 BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
116 BOPCol_ListIteratorOfListOfShape aIt;
117 //
118 aItCB.Initialize(myLCB);
119 for (; aItCB.More(); aItCB.Next()) {
120 BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
121 bIsRegular=aCB.IsRegular();
122 if (bIsRegular) {
123 BOPCol_ListOfShape& aLE=aCB.ChangeShapes();
124 BOPAlgo_WireSplitter::MakeWire(aLE, aW);
125 myWES->AddShape(aW);
126 }
127 else {
128 SplitBlock(aCB);
129 //
130 const BOPCol_ListOfShape& aLW=aCB.Loops();
131 aIt.Initialize(aLW);
132 for (; aIt.More(); aIt.Next()) {
133 const TopoDS_Shape& aWx=aIt.Value();
134 myWES->AddShape(aWx);
135 }
136 }
137 }
138}
139//=======================================================================
140//function : MakeConnexityBlocks
141//purpose :
142//=======================================================================
143 void BOPAlgo_WireSplitter::MakeConnexityBlocks()
144{
145 Standard_Boolean bRegular, bClosed;
146 Standard_Integer i, j, aNbV, aNbVS, aNbVP, k;
147 TopoDS_Iterator aItE;
148 TopoDS_Shape aER;
149 BOPCol_ListIteratorOfListOfShape aIt;
150 BOPCol_MapIteratorOfMapOfShape aItM;
151 //
152 BOPCol_IndexedDataMapOfShapeListOfShape aMVE(100, myAllocator);
153 BOPCol_IndexedMapOfShape aMVP(100, myAllocator);
154 BOPCol_IndexedMapOfShape aMEC(100, myAllocator);
155 BOPCol_MapOfShape aMER(100, myAllocator);
156 BOPCol_MapOfShape aMEP(100, myAllocator);
157 BOPCol_IndexedMapOfShape aMVAdd(100, myAllocator);
158 BOPCol_MapOfShape aMVS(100, myAllocator);
159 //
160 myLCB.Clear();
161 //
162 const BOPCol_ListOfShape& aLSE=myWES->StartElements();
163 aIt.Initialize(aLSE);
164 for (; aIt.More(); aIt.Next()) {
165 const TopoDS_Shape& aE=aIt.Value();
166 if (aMEP.Add(aE)) {
167 BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
168 }
169 else {
170 aMER.Add(aE);
171 }
172 }
173 //
174 // 2
175 aNbV=aMVE.Extent();
176 for (i=1; i<=aNbV; ++i) {
177 aNbVS=aMVS.Extent();
178 if (aNbVS==aNbV) {
179 break;
180 }
181 //
182 const TopoDS_Shape& aV=aMVE.FindKey(i);
183 //
184 if (!aMVS.Add(aV)) {
185 continue;
186 }
187 // aMVS - globally processed vertices
188 //
189 //------------------------------------- goal: aMEC
190 aMEC.Clear(); // aMEC - edges of CB
191 aMVP.Clear(); // aMVP - vertices to process right now
192 aMVAdd.Clear(); // aMVAdd vertices to process on next step of while(1)
193 //
194 aMVP.Add(aV);
195 //
302f96fb 196 for(;;) {
4e57c75e 197 aNbVP=aMVP.Extent();
198 for (k=1; k<=aNbVP; ++k) {
199 const TopoDS_Shape& aVP=aMVP(k);
200 const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aVP);
201 aIt.Initialize(aLE);
202 for (; aIt.More(); aIt.Next()) {
203 const TopoDS_Shape& aE=aIt.Value();
204 if (aMEC.Add(aE)) {
205 aItE.Initialize(aE);
206 for (; aItE.More(); aItE.Next()) {
207 const TopoDS_Shape& aVE=aItE.Value();
208 if (aMVS.Add(aVE)) {
209 aMVAdd.Add(aVE);
210 }
211 }
212 }
213 }
214 }//for (; aItM.More(); aItM.Next()) {
215 //
216 aNbVP=aMVAdd.Extent();
217 if (!aNbVP) {
218 break; // from while(1)
219 }
220 //
221 aMVP.Clear();
222 //
223 for (k=1; k<=aNbVP; ++k) {
224 const TopoDS_Shape& aVE=aMVAdd(k);
225 aMVP.Add(aVE);
226 }
227 aMVAdd.Clear();
228 }// while(1) {
229
230 //-------------------------------------
231 BOPTools_ConnexityBlock aCB(myAllocator);
232 BOPCol_ListOfShape& aLEC=aCB.ChangeShapes();
233
234 BOPCol_IndexedDataMapOfShapeListOfShape aMVER(100, myAllocator);
235 //
236 bRegular=Standard_True;
237 Standard_Integer aNbCB = aMEC.Extent();
238 for (j = 1; j <= aNbCB; j++) {
239 aER = aMEC(j);
240 //
241 if (aMER.Contains(aER)) {
242 aER.Orientation(TopAbs_FORWARD);
243 aLEC.Append(aER);
244 aER.Orientation(TopAbs_REVERSED);
245 aLEC.Append(aER);
246 bRegular=Standard_False;
247 }
248 else {
249 aLEC.Append(aER);
250 }
251 //
252 if (bRegular) {
253 BOPTools::MapShapesAndAncestors(aER, TopAbs_VERTEX, TopAbs_EDGE, aMVER);
254 }
255 }
256 //
257 if (bRegular) {
258 Standard_Integer k, aNbVR, aNbER;
259 //
260 aNbVR=aMVER.Extent();
261 for (k=1; k<=aNbVR; ++k) {
262 const BOPCol_ListOfShape& aLER=aMVER(k);
263 aNbER=aLER.Extent();
264 if (aNbER==1) {
265 const TopoDS_Edge& aEx=TopoDS::Edge(aER);
266 bClosed=BRep_Tool::IsClosed(aEx, myWES->Face());
267 if (!bClosed) {
268 bRegular=!bRegular;
269 break;
270 }
271 }
272 if (aNbER>2) {
273 bRegular=!bRegular;
274 break;
275 }
276 }
277 }
278 //
279 aCB.SetRegular(bRegular);
280 myLCB.Append(aCB);
281 }
282}