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