0021762: Integration of new Boolean Operation algorithm to OCCT.
[occt.git] / src / BOPAlgo / BOPAlgo_WireSplitter.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
19
20#include <BOPAlgo_WireSplitter.ixx>
21
22#include <TopoDS_Shape.hxx>
23#include <TopoDS_Iterator.hxx>
24#include <TopoDS_Edge.hxx>
25#include <TopoDS.hxx>
26#include <TopoDS_Wire.hxx>
27
28#include <BRep_Tool.hxx>
29#include <BRep_Builder.hxx>
30
31#include <BOPCol_ListOfShape.hxx>
32#include <BOPCol_IndexedMapOfShape.hxx>
33#include <BOPCol_MapOfShape.hxx>
34#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
35
36#include <BOPTools.hxx>
37
38
39//=======================================================================
40//function :
41//purpose :
42//=======================================================================
43 BOPAlgo_WireSplitter::BOPAlgo_WireSplitter()
44:
45 BOPAlgo_Algo(),
46 myWES(NULL),
47 myLCB(myAllocator)
48{
49}
50//=======================================================================
51//function :
52//purpose :
53//=======================================================================
54 BOPAlgo_WireSplitter::BOPAlgo_WireSplitter(const Handle(NCollection_BaseAllocator)& theAllocator)
55:
56 BOPAlgo_Algo(theAllocator),
57 myWES(NULL),
58 myLCB(myAllocator)
59{
60}
61//=======================================================================
62//function : ~
63//purpose :
64//=======================================================================
65 BOPAlgo_WireSplitter::~BOPAlgo_WireSplitter()
66{
67}
68//=======================================================================
69//function : SetWES
70//purpose :
71//=======================================================================
72 void BOPAlgo_WireSplitter::SetWES(const BOPAlgo_WireEdgeSet& theWES)
73{
74 myWES=(BOPAlgo_WireEdgeSet*)&theWES;
75}
76//=======================================================================
77//function : WES
78//purpose :
79//=======================================================================
80 BOPAlgo_WireEdgeSet& BOPAlgo_WireSplitter::WES()
81{
82 return *myWES;
83}
84//=======================================================================
85// function: CheckData
86// purpose:
87//=======================================================================
88 void BOPAlgo_WireSplitter::CheckData()
89{
90 myErrorStatus=0;
91 if (!myWES) {
92 myErrorStatus=10;
93 return;
94 }
95}
96//=======================================================================
97//function : Perform
98//purpose :
99//=======================================================================
100 void BOPAlgo_WireSplitter::Perform()
101{
102 myErrorStatus=0;
103 //
104 CheckData();
105 if (myErrorStatus) {
106 return;
107 }
108 //
109 MakeConnexityBlocks();
110 MakeWires();
111}
112//=======================================================================
113//function : MakeWires
114//purpose :
115//=======================================================================
116 void BOPAlgo_WireSplitter::MakeWires()
117{
118 Standard_Boolean bIsRegular;
119 TopoDS_Wire aW;
120 BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
121 BOPCol_ListIteratorOfListOfShape aIt;
122 //
123 aItCB.Initialize(myLCB);
124 for (; aItCB.More(); aItCB.Next()) {
125 BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
126 bIsRegular=aCB.IsRegular();
127 if (bIsRegular) {
128 BOPCol_ListOfShape& aLE=aCB.ChangeShapes();
129 BOPAlgo_WireSplitter::MakeWire(aLE, aW);
130 myWES->AddShape(aW);
131 }
132 else {
133 SplitBlock(aCB);
134 //
135 const BOPCol_ListOfShape& aLW=aCB.Loops();
136 aIt.Initialize(aLW);
137 for (; aIt.More(); aIt.Next()) {
138 const TopoDS_Shape& aWx=aIt.Value();
139 myWES->AddShape(aWx);
140 }
141 }
142 }
143}
144//=======================================================================
145//function : MakeConnexityBlocks
146//purpose :
147//=======================================================================
148 void BOPAlgo_WireSplitter::MakeConnexityBlocks()
149{
150 Standard_Boolean bRegular, bClosed;
151 Standard_Integer i, j, aNbV, aNbVS, aNbVP, k;
152 TopoDS_Iterator aItE;
153 TopoDS_Shape aER;
154 BOPCol_ListIteratorOfListOfShape aIt;
155 BOPCol_MapIteratorOfMapOfShape aItM;
156 //
157 BOPCol_IndexedDataMapOfShapeListOfShape aMVE(100, myAllocator);
158 BOPCol_IndexedMapOfShape aMVP(100, myAllocator);
159 BOPCol_IndexedMapOfShape aMEC(100, myAllocator);
160 BOPCol_MapOfShape aMER(100, myAllocator);
161 BOPCol_MapOfShape aMEP(100, myAllocator);
162 BOPCol_IndexedMapOfShape aMVAdd(100, myAllocator);
163 BOPCol_MapOfShape aMVS(100, myAllocator);
164 //
165 myLCB.Clear();
166 //
167 const BOPCol_ListOfShape& aLSE=myWES->StartElements();
168 aIt.Initialize(aLSE);
169 for (; aIt.More(); aIt.Next()) {
170 const TopoDS_Shape& aE=aIt.Value();
171 if (aMEP.Add(aE)) {
172 BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
173 }
174 else {
175 aMER.Add(aE);
176 }
177 }
178 //
179 // 2
180 aNbV=aMVE.Extent();
181 for (i=1; i<=aNbV; ++i) {
182 aNbVS=aMVS.Extent();
183 if (aNbVS==aNbV) {
184 break;
185 }
186 //
187 const TopoDS_Shape& aV=aMVE.FindKey(i);
188 //
189 if (!aMVS.Add(aV)) {
190 continue;
191 }
192 // aMVS - globally processed vertices
193 //
194 //------------------------------------- goal: aMEC
195 aMEC.Clear(); // aMEC - edges of CB
196 aMVP.Clear(); // aMVP - vertices to process right now
197 aMVAdd.Clear(); // aMVAdd vertices to process on next step of while(1)
198 //
199 aMVP.Add(aV);
200 //
201 while(1) {
202 aNbVP=aMVP.Extent();
203 for (k=1; k<=aNbVP; ++k) {
204 const TopoDS_Shape& aVP=aMVP(k);
205 const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aVP);
206 aIt.Initialize(aLE);
207 for (; aIt.More(); aIt.Next()) {
208 const TopoDS_Shape& aE=aIt.Value();
209 if (aMEC.Add(aE)) {
210 aItE.Initialize(aE);
211 for (; aItE.More(); aItE.Next()) {
212 const TopoDS_Shape& aVE=aItE.Value();
213 if (aMVS.Add(aVE)) {
214 aMVAdd.Add(aVE);
215 }
216 }
217 }
218 }
219 }//for (; aItM.More(); aItM.Next()) {
220 //
221 aNbVP=aMVAdd.Extent();
222 if (!aNbVP) {
223 break; // from while(1)
224 }
225 //
226 aMVP.Clear();
227 //
228 for (k=1; k<=aNbVP; ++k) {
229 const TopoDS_Shape& aVE=aMVAdd(k);
230 aMVP.Add(aVE);
231 }
232 aMVAdd.Clear();
233 }// while(1) {
234
235 //-------------------------------------
236 BOPTools_ConnexityBlock aCB(myAllocator);
237 BOPCol_ListOfShape& aLEC=aCB.ChangeShapes();
238
239 BOPCol_IndexedDataMapOfShapeListOfShape aMVER(100, myAllocator);
240 //
241 bRegular=Standard_True;
242 Standard_Integer aNbCB = aMEC.Extent();
243 for (j = 1; j <= aNbCB; j++) {
244 aER = aMEC(j);
245 //
246 if (aMER.Contains(aER)) {
247 aER.Orientation(TopAbs_FORWARD);
248 aLEC.Append(aER);
249 aER.Orientation(TopAbs_REVERSED);
250 aLEC.Append(aER);
251 bRegular=Standard_False;
252 }
253 else {
254 aLEC.Append(aER);
255 }
256 //
257 if (bRegular) {
258 BOPTools::MapShapesAndAncestors(aER, TopAbs_VERTEX, TopAbs_EDGE, aMVER);
259 }
260 }
261 //
262 if (bRegular) {
263 Standard_Integer k, aNbVR, aNbER;
264 //
265 aNbVR=aMVER.Extent();
266 for (k=1; k<=aNbVR; ++k) {
267 const BOPCol_ListOfShape& aLER=aMVER(k);
268 aNbER=aLER.Extent();
269 if (aNbER==1) {
270 const TopoDS_Edge& aEx=TopoDS::Edge(aER);
271 bClosed=BRep_Tool::IsClosed(aEx, myWES->Face());
272 if (!bClosed) {
273 bRegular=!bRegular;
274 break;
275 }
276 }
277 if (aNbER>2) {
278 bRegular=!bRegular;
279 break;
280 }
281 }
282 }
283 //
284 aCB.SetRegular(bRegular);
285 myLCB.Append(aCB);
286 }
287}