Test for 0022778: Bug in BRepMesh
[occt.git] / src / BOPTools / BOPTools_WireStateFiller.cxx
CommitLineData
b311480e 1// Created on: 2002-02-04
2// Created by: Peter KURNEV
3// Copyright (c) 2002-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21
22#include <BOPTools_WireStateFiller.ixx>
23
24#include <TopoDS.hxx>
25#include <TopoDS_Shape.hxx>
26
27#include <TopExp.hxx>
28#include <TopTools_IndexedMapOfShape.hxx>
29
30#include <TopAbs_ShapeEnum.hxx>
31
32#include <BRep_Tool.hxx>
33
34#include <BooleanOperations_ShapesDataStructure.hxx>
35#include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
36#include <BooleanOperations_StateOfShape.hxx>
37
38#include <BOPTools_SplitShapesPool.hxx>
39#include <BOPTools_CommonBlockPool.hxx>
40#include <BOPTools_CommonBlock.hxx>
41#include <BOPTools_PaveBlock.hxx>
42#include <BOPTools_ListOfPaveBlock.hxx>
43#include <BOPTools_ListOfCommonBlock.hxx>
44#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
45#include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
46#include <BOPTools_InterferencePool.hxx>
47
48
49//=======================================================================
50// function: BOPTools_WireStateFiller::BOPTools_WireStateFiller
51// purpose:
52//=======================================================================
b311480e 53BOPTools_WireStateFiller::BOPTools_WireStateFiller(const BOPTools_PaveFiller& aFiller)
7fd59977 54:
55 BOPTools_StateFiller(aFiller)
56{
57}
58
59//=======================================================================
60// function: Do
61// purpose:
62//=======================================================================
63 void BOPTools_WireStateFiller::Do()
64{
65 TopAbs_ShapeEnum aT1, aT2;
66
67 aT1=(myDS->Object()).ShapeType();
68 aT2=(myDS->Tool()).ShapeType();
69
70 myIsDone=Standard_True;
71
72 if (aT1==TopAbs_WIRE && aT2==TopAbs_WIRE){
73 DoWires(1);
74 DoWires(2);
75 }
76 else if (aT1==TopAbs_WIRE && aT2==TopAbs_SHELL){
77 DoWires(1);
78 }
79 else if (aT2==TopAbs_WIRE && aT1==TopAbs_SHELL){
80 DoWires(2);
81 }
82 else if (aT1==TopAbs_WIRE && aT2==TopAbs_SOLID){
83 DoWireSolid(1);
84 }
85 else if (aT2==TopAbs_WIRE && aT1==TopAbs_SOLID){
86 DoWireSolid(2);
87 }
88 else {
89 myIsDone=!myIsDone;
90 }
91
92}
93
94//=======================================================================
95// function: DoWires
96// purpose:
97//=======================================================================
98 void BOPTools_WireStateFiller::DoWires (const Standard_Integer iRankObj)
99{
100 const TopoDS_Shape& anObj=(iRankObj==1) ? myDS->Object() : myDS->Tool();
101 //
102 const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap=myDS->ShapeIndexMap(iRankObj);
103 const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
104 const BOPTools_CommonBlockPool& aCommonBlockPool=myFiller->CommonBlockPool();
105 //
106 Standard_Integer i, aNbPaveBlocks, nSp, aNbE, nE;
107 BooleanOperations_StateOfShape aSt;
108 BOPTools_ListIteratorOfListOfPaveBlock anItPB;
109 BOPTools_ListIteratorOfListOfCommonBlock anItCB;
110 TopTools_IndexedMapOfShape aEM;
111 //
112 TopExp::MapShapes(anObj, TopAbs_EDGE, aEM);
113 aNbE=aEM.Extent();
114 //
115 // 1
116 for (i=1; i<=aNbE; i++) {
117 const TopoDS_Edge& aE=TopoDS::Edge(aEM(i));
118 nE=aDSMap.FindFromKey(aE);
119 //
120 if (BRep_Tool::Degenerated(aE)){
121 continue;
122 }
123 //
124 const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(myDS->RefEdge(nE));
125 //
126 anItCB.Initialize(aLCB);
127 for (; anItCB.More(); anItCB.Next()) {
128 BOPTools_CommonBlock& aCB=anItCB.Value();
129 BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nE);
130 nSp=aPB.Edge();
131 myDS->SetState(nSp, BooleanOperations_ON);
132 }
133 }
134 //
135 // 2
136 for (i=1; i<=aNbE; i++) {
137 const TopoDS_Edge& aE=TopoDS::Edge(aEM(i));
138 nE=aDSMap.FindFromKey(aE);
139 //
140 if (BRep_Tool::Degenerated(aE)){
141 continue;
142 }
143 //
144 const BOPTools_ListOfPaveBlock& aLPB=aSplitShapesPool(myDS->RefEdge(nE));
145 //
146 aNbPaveBlocks=aLPB.Extent();
147
148 if (!aNbPaveBlocks) {
149 myDS->SetState(nE, BooleanOperations_OUT);
150 continue;
151 }
152 //
153 anItPB.Initialize(aLPB);
154 for (; anItPB.More(); anItPB.Next()) {
155 const BOPTools_PaveBlock& aPB=anItPB.Value();
156 nSp=aPB.Edge();
157 aSt=myDS-> GetState(nSp);
158 if (aSt!=BooleanOperations_ON) {
159 myDS->SetState(nSp, BooleanOperations_OUT);
160 }
161 }
162 }
163}
164//=======================================================================
165
166#include <TopoDS_Shape.hxx>
167#include <TopoDS_Compound.hxx>
168#include <TopExp.hxx>
169#include <TopExp_Explorer.hxx>
170#include <TopTools_ListIteratorOfListOfShape.hxx>
171
172#include <TopTools_IndexedMapOfShape.hxx>
173#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
174
175#include <BRep_Builder.hxx>
176
177#include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
178
179#include <BOPTools_SplitShapesPool.hxx>
180#include <BOPTools_CommonBlockPool.hxx>
181#include <BOPTools_ListOfPaveBlock.hxx>
182#include <BOPTools_ListOfCommonBlock.hxx>
183#include <BOPTools_PaveBlock.hxx>
184#include <BOPTools_CommonBlock.hxx>
185#include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
186#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
187#include <BOPTools_IndexedDataMapOfShapeWithState.hxx>
188#include <BOPTools_StateFiller.hxx>
189
190static
191 void PropagateState(const TopoDS_Shape& aS,
192 const BooleanOperations_StateOfShape aState,
193 BooleanOperations_ShapesDataStructure* pDS,
194 const Standard_Integer iRank,
195 BOPTools_IndexedDataMapOfShapeWithState& aSWS,
196 TopTools_IndexedMapOfShape& aProcessedShapes);
197
198static
199 Standard_Boolean HasConnexity(const TopoDS_Shape& aS,
200 const BOPTools_IndexedDataMapOfShapeWithState& aSWS,
201 const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
202 BooleanOperations_StateOfShape& aState);
203
204//=======================================================================
205// function: DoWireSolid
206// purpose:
207//=======================================================================
208 void BOPTools_WireStateFiller::DoWireSolid (const Standard_Integer iRankObj)
209{
210 const TopoDS_Shape& anObj=(iRankObj==1) ? myDS->Object() : myDS->Tool();
211 const TopoDS_Shape& aTool=(iRankObj==1) ? myDS->Tool() : myDS->Object();
212 //
213 const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap=myDS->ShapeIndexMap(iRankObj);
214 const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
215 const BOPTools_CommonBlockPool& aCommonBlockPool=myFiller->CommonBlockPool();
216 //
217 Standard_Integer i, aNb, nE, aNbPB;
218 BooleanOperations_StateOfShape aState;
219 TopTools_IndexedMapOfShape aEM, anIntersectedShapes, aNonIntersectedShapes;
220 TopTools_IndexedDataMapOfShapeListOfShape aM, aMVE;
221
222 //
223 // aM Map
224 TopExp::MapShapesAndAncestors (anObj, TopAbs_EDGE , TopAbs_WIRE , aM);
225 // VE Map
226 TopExp::MapShapesAndAncestors (anObj, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
227 //
228 // 1.2. Edges that have Split parts
229 TopExp::MapShapes(anObj, TopAbs_EDGE, aEM);
230 aNb=aEM.Extent();
231 for (i=1; i<=aNb; i++) {
232 const TopoDS_Shape& aE=aEM(i);
233 nE=aDSMap.FindFromKey(aE);
234 const BOPTools_ListOfPaveBlock& aLPB=aSplitShapesPool(myDS->RefEdge(nE));
235 aNbPB=aLPB.Extent();
236 //
237 if (!aNbPB) {
238 continue;
239 }
240 //
241 if (aNbPB==1) {
242 const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(myDS->RefEdge(nE));
243 if (!aLCB.Extent()) {
244 const BOPTools_PaveBlock& aPB=aLPB.First();
245 Standard_Integer nEB=aPB.Edge();
246 if (nEB==aPB.OriginalEdge()) {
247 Standard_Boolean bHasInterference=Standard_False;// Wng in Gcc 3.0
248 Standard_Integer j, aNbSuc, nV;
249 aNbSuc=myDS->NumberOfSuccessors(nEB);
250 for (j=1; j<=aNbSuc; j++) {
251 nV=myDS->GetSuccessor(nE, j);
252 bHasInterference=myIntrPool->HasInterference(nV);
253 if (bHasInterference) {
254 break;
255 }
256 }
257 if (!bHasInterference) {
258 continue;
259 }
260 }
261 }
262 }
263 anIntersectedShapes.Add(aE);
264 }// for (i=1; i<=aNb; i++)
265 //
266 // 1.3. Write Intersected state for anIntersectedShapes to the DS
267 aNb=anIntersectedShapes.Extent();
268 for (i=1; i<=aNb; i++) {
269 const TopoDS_Shape& aS=anIntersectedShapes(i);
270 nE=aDSMap.FindFromKey(aS);
271 myDS->SetState(nE, BooleanOperations_INTERSECTED);
272 }
273 //
274 // 2. aNonIntersectedShapes
275 //
276 aNb=aM.Extent();
277 for (i=1; i<=aNb; i++) {
278 const TopoDS_Shape& aS=aM.FindKey(i);
279 if (!anIntersectedShapes.Contains(aS)) {
280 aNonIntersectedShapes.Add(aS);
281 }
282 }
283 //
284 // 2.1. Processing of Non-intersected shapes
285 BRep_Builder BB;
286 TopoDS_Compound aCompound;
287 BB.MakeCompound(aCompound);
288 aNb=aNonIntersectedShapes.Extent();
289 for (i=1; i<=aNb; i++) {
290 const TopoDS_Shape& aS=aNonIntersectedShapes(i);
291 BB.Add(aCompound, aS);
292 }
293 //
294 TopTools_IndexedMapOfShape aProcessedShapes;
295 BOPTools_IndexedDataMapOfShapeWithState aSWS;
296 Standard_Boolean bHasConnexity;
297 //
298 aEM.Clear();
299 TopExp::MapShapes(aCompound, TopAbs_EDGE, aEM);
300 aNb=aEM.Extent();
301 for (i=1; i<=aNb; i++) {
302 const TopoDS_Shape& aS=aEM(i);
303 if (!aProcessedShapes.Contains(aS)) {
304 bHasConnexity=HasConnexity(aS, aSWS, aMVE, aState);
305 if (!bHasConnexity) {
306 aState=BOPTools_StateFiller::ClassifyShapeByRef (aS, aTool);
307 }
308 aSWS.Add(aS, aState);
309 aProcessedShapes.Add(aS);
310 PropagateState(aS, aState, myDS, iRankObj, aSWS, aProcessedShapes);
311 }
312 }
313 //
314 // 2.2. Write Stats for Non-intersected Shapes to the DS
315 aNb=aSWS.Extent();
316 for (i=1; i<=aNb; i++) {
317 const TopoDS_Shape& aS=aSWS.FindKey(i);
318 aState=aSWS.FindFromIndex(i);
319 nE=aDSMap.FindFromKey(aS);
320 myDS->SetState(nE, aState);
321 }
322 //---------------------------------------------------
323 //
324 // 3. Intersected Edges' Processing
325 //
326 //---------------------------------------------------
327 Standard_Integer nSp, aNBVertices, nV1, nV2;
328 BooleanOperations_StateOfShape aStV1, aStV2;
329
330 aNb=anIntersectedShapes.Extent();
331 for (i=1; i<=aNb; i++) {
332 const TopoDS_Shape& aS=anIntersectedShapes(i);
333 if (aS.ShapeType()==TopAbs_EDGE) {
334 nE=aDSMap.FindFromKey(aS);
335 //
336 // 3.1. On Parts Processing
337 const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(myDS->RefEdge(nE));
338 BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
339 for (; anItCB.More(); anItCB.Next()) {
340 const BOPTools_CommonBlock& aCB=anItCB.Value();
341 BOPTools_CommonBlock* pCB=(BOPTools_CommonBlock*) &aCB;
342 BOPTools_PaveBlock& aPB=pCB->PaveBlock1(nE);
343 nSp=aPB.Edge();
344 myDS->SetState(nSp, BooleanOperations_ON);
345 }
346 //
347 // 3.2. IN, OUT Parts Processing
348 const BOPTools_ListOfPaveBlock& aSplits=aSplitShapesPool(myDS->RefEdge(nE));
349 BOPTools_ListIteratorOfListOfPaveBlock anItPB(aSplits);
350 for (; anItPB.More(); anItPB.Next()) {
351 const BOPTools_PaveBlock& aPB=anItPB.Value();
352 nSp=aPB.Edge();
353 const TopoDS_Shape& aSplit=myDS->Shape(nSp);
354
355 aState=myDS->GetState(nSp);
356 if (aState==BooleanOperations_UNKNOWN|| aState==BooleanOperations_INTERSECTED){
357 aNBVertices=myDS->NumberOfSuccessors(nE);
358 if (aNBVertices==2) {
359 nV1=myDS->GetSuccessor(nSp, 1);
360 aStV1=myDS->GetState(nV1);
361 nV2=myDS->GetSuccessor(nSp, 2);
362 aStV2=myDS->GetState(nV2);
363 if ((aStV1==BooleanOperations_IN || aStV1==BooleanOperations_OUT)
364 && (aStV2==BooleanOperations_ON)) {
365 myDS->SetState(nSp, aStV1);
366 }
367 else if ((aStV2==BooleanOperations_IN || aStV2==BooleanOperations_OUT)
368 && (aStV1==BooleanOperations_ON)) {
369 myDS->SetState(nSp, aStV2);
370 }
371 else {
372 aState=BOPTools_StateFiller::ClassifyShapeByRef(aSplit, aTool);
373 myDS->SetState(nSp, aState);
374 if (aStV1==BooleanOperations_UNKNOWN) {
375 myDS->SetState(nV1, aState);
376 }
377 if (aStV2==BooleanOperations_UNKNOWN) {
378 myDS->SetState(nV2, aState);
379 }
380 }
381 }// if (aNBVertices==2)
382 else {
383 aState=BOPTools_StateFiller::ClassifyShapeByRef(aSplit, aTool);
384 myDS->SetState(nSp, aState);
385 }
386 }// if (aState==BooleanOperations_UNKNOWN || BooleanOperations_INTERSECTED)
387 }//for (; anItPB.More(); anItPB.Next())
388 }// if (aS.ShapeType()==TopAbs_EDGE)
389 }// next "Intersected" Edge
390
391}
392
393//=======================================================================
394// function: HasConnexity
395// purpose:
396//=======================================================================
397 Standard_Boolean HasConnexity(const TopoDS_Shape& aS,
398 const BOPTools_IndexedDataMapOfShapeWithState& aSWS,
399 const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
400 BooleanOperations_StateOfShape& aState)
401{
402 TopAbs_ShapeEnum aType;
403 BooleanOperations_StateOfShape aSt;
404 aType=aS.ShapeType();
405 if (aType!=TopAbs_EDGE) {
406 Standard_Integer i, aNb;
407 TopTools_IndexedMapOfShape aME;
408 TopExp::MapShapes(aS, TopAbs_EDGE, aME);
409 aNb=aME.Extent();
410 for (i=1; i<=aNb; i++) {
411 const TopoDS_Shape& aE=aME(i);
412 if (aSWS.Contains(aE)){
413 aSt=aSWS.FindFromKey(aE);
414 aState=aSt;
415 return Standard_True;
416 }
417 }
418 }
419 else {
420 TopExp_Explorer anExp (aS, TopAbs_VERTEX);
421 for (; anExp.More(); anExp.Next()) {
422 const TopoDS_Shape& aV=anExp.Current();
423 if (aMVE.Contains(aV)) {
424 const TopTools_ListOfShape& anEdgesList=aMVE.FindFromKey(aV);
425 TopTools_ListIteratorOfListOfShape anIt(anEdgesList);
426 for (; anIt.More(); anIt.Next()) {
427 const TopoDS_Shape& aEx=anIt.Value();
428 if (aSWS.Contains(aEx)) {
429 aSt=aSWS.FindFromKey(aEx);
430 aState=aSt;
431 return Standard_True;
432 }
433 }
434 }
435 }
436 }
437
438 aState=BooleanOperations_UNKNOWN;
439 return Standard_False;
440}
441
442//=======================================================================
443// function: PropagateState
444// purpose:
445//=======================================================================
446void PropagateState(const TopoDS_Shape& aSS,
447 const BooleanOperations_StateOfShape aState,
448 BooleanOperations_ShapesDataStructure* pDS,
449 const Standard_Integer iRank,
450 BOPTools_IndexedDataMapOfShapeWithState& aSWS,
451 TopTools_IndexedMapOfShape& aProcessedShapes)
452{
453 TopAbs_ShapeEnum aSubType;
454
455 aSubType=BOPTools_StateFiller::SubType(aSS);
456
457 if (aSubType==TopAbs_SHAPE) {
458 return;
459 }
460
461 const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap= pDS->ShapeIndexMap(iRank);
462
463 TopTools_IndexedMapOfShape aSubMap;
464 TopExp::MapShapes(aSS, aSubType, aSubMap);
465
466 Standard_Integer i, aNb, nV;
467 aNb=aSubMap.Extent();
468 for (i=1; i<=aNb; i++) {
469 const TopoDS_Shape& aS=aSubMap(i);
470 if (!aProcessedShapes.Contains(aS)) {
471 if (aSubType==TopAbs_VERTEX) {
472 nV=aDSMap.FindFromKey(aS);
473 BooleanOperations_StateOfShape aSt=pDS->GetState(nV);
474 if (aSt!=BooleanOperations_UNKNOWN){
475 aProcessedShapes.Add(aS);
476 continue;
477 }
478 }
479 aSWS.Add(aS, aState);
480 aProcessedShapes.Add(aS);
481 PropagateState (aS, aState, pDS, iRank, aSWS, aProcessedShapes);
482 }
483 }
484}