Adding of testing cases from subgroups 937 940 and 941 of CHL group
[occt.git] / src / BOP / BOP_SolidSolid_1.cxx
CommitLineData
b311480e 1// Created on: 2004-06-29
2// Created by: Mikhail KLOKOV
3// Copyright (c) 2004-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 <BOP_SolidSolid.ixx>
23
24#include <TColStd_IndexedMapOfInteger.hxx>
25#include <TColStd_MapOfInteger.hxx>
19d6e40d 26#include <TColStd_ListIteratorOfListOfInteger.hxx>
27#include <TColStd_DataMapOfIntegerListOfInteger.hxx>
28
29#include <gp_Dir.hxx>
30#include <gp_Vec.hxx>
31
32#include <Geom2d_Curve.hxx>
33#include <Geom2d_TrimmedCurve.hxx>
34#include <Geom2d_Line.hxx>
35#include <Geom_Surface.hxx>
36#include <Geom2dHatch_Intersector.hxx>
37#include <Geom2dHatch_Hatcher.hxx>
38#include <Geom2dAdaptor_Curve.hxx>
39#include <HatchGen_Domain.hxx>
7fd59977 40
41#include <TopoDS.hxx>
42#include <TopoDS_Shape.hxx>
43#include <TopoDS_Vertex.hxx>
44#include <TopoDS_Edge.hxx>
45#include <TopoDS_Face.hxx>
46#include <TopoDS_Wire.hxx>
47#include <TopoDS_Shell.hxx>
48#include <TopoDS_Solid.hxx>
49#include <TopoDS_Compound.hxx>
19d6e40d 50#include <BRep_Builder.hxx>
51#include <BRep_Tool.hxx>
52//
53#include <TopExp_Explorer.hxx>
54#include <BRepTools.hxx>
55#include <BRepClass3d_SolidClassifier.hxx>
56
57#include <TopTools_DataMapOfShapeInteger.hxx>
7fd59977 58
59#include <BooleanOperations_ShapesDataStructure.hxx>
60#include <BooleanOperations_StateOfShape.hxx>
19d6e40d 61#include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
7fd59977 62#include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
63
19d6e40d 64#include <IntTools_Tools.hxx>
65#include <IntTools_Context.hxx>
66
7fd59977 67#include <BOPTools_SSInterference.hxx>
68#include <BOPTools_InterferencePool.hxx>
69#include <BOPTools_CArray1OfSSInterference.hxx>
70#include <BOPTools_PaveFiller.hxx>
71#include <BOPTools_DSFiller.hxx>
72#include <BOPTools_PaveBlock.hxx>
73#include <BOPTools_CommonBlock.hxx>
74#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
75#include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
76#include <BOPTools_Curve.hxx>
19d6e40d 77#include <BOPTools_Tools2D.hxx>
7fd59977 78#include <BOPTools_Tools3D.hxx>
19d6e40d 79#include <BOPTools_StateFiller.hxx>
7fd59977 80
81#include <BOP_BuilderTools.hxx>
82
7fd59977 83static
84Standard_Integer GetIndex(const TopoDS_Shape& theShape,
85 const BooleanOperations_ShapesDataStructure& theDS);
86
87static
88void GetAttachedFaces(const Standard_Integer theEdgeIndex,
89 const Standard_Integer theFaceIndex,
90 const BOPTools_DSFiller& theDSFiller,
91 TColStd_ListOfInteger& theListOfFaces);
92
93static
94void GetStatesOfAdjacentFaces(const TColStd_ListOfInteger& theListOfFacesToCheck,
95 const BOPTools_DSFiller& theDSFiller,
96 TColStd_MapOfInteger& theMapOfUsedIndices,
97 Standard_Boolean& bFoundINOUT,
98 Standard_Boolean& bFoundININ,
99 Standard_Boolean& bFoundOUTOUT);
100
101static
19d6e40d 102 Standard_Boolean ComputeStateForAnalyticalSurfaces
103 (const Standard_Integer theFaceIndex,
104 const Standard_Integer theBaseFaceIndex,
105 const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& theFFMap,
106 const BOPTools_DSFiller& theDSFiller,
107 TopAbs_State& theState);
7fd59977 108
109static
110Standard_Boolean IsEdgeValidForFace(const Standard_Integer theEdgeIndex,
111 const Standard_Integer theFaceIndex,
112 BOPTools_SSInterference& theFF,
113 const BOPTools_DSFiller& theDSFiller);
114
19d6e40d 115static
116 TopAbs_State ComputeState(const TopoDS_Face& theF,
117 const TopoDS_Solid& theRef,
118 const Standard_Real theTol,
119 const Handle(IntTools_Context)& theCtx);
120
121static
122 Standard_Integer PntInFace(const TopoDS_Face& aF,
123 gp_Pnt& theP,
124 gp_Pnt2d& theP2D);
125
126static
127 Standard_Integer PntHoverFace(const TopoDS_Face& aF,
128 gp_Pnt& theP);
129
130static
131 TopAbs_State ComputeState(const gp_Pnt& theP,
132 const TopoDS_Solid& theRef,
133 const Standard_Real theTol,
134 const Handle(IntTools_Context)& theCtx);
135
136
7fd59977 137//=================================================================================
138// function: PrepareFaceSplits
139// purpose:
140//=================================================================================
141void BOP_SolidSolid::PrepareFaceSplits()
142{
143 const BooleanOperations_ShapesDataStructure& aDS = myDSFiller->DS();
144 BooleanOperations_ShapesDataStructure* pDS = (BooleanOperations_ShapesDataStructure*)&aDS;
145 BOPTools_InterferencePool* pIntrPool = (BOPTools_InterferencePool*)&myDSFiller->InterfPool();
146 BOPTools_CArray1OfSSInterference& aFFs = pIntrPool->SSInterferences();
147
148 Standard_Integer i, aNb, nF1, iRank;
149 BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap;
150 BOP_BuilderTools::DoMap(aFFs, aFFMap);
151 TopTools_ListOfShape aListOfNewFaces;
152 TopAbs_Orientation anOriF1 = TopAbs_FORWARD;
153
154 TColStd_DataMapOfIntegerListOfInteger& aMapOfFaceSplits = myDSFiller->ChangeSplitFacePool();
155
156 aNb=aFFMap.Extent();
157
158 for (i=1; i<=aNb; i++) {
159 //
160
161 nF1 = aFFMap.FindKey(i);
162 TopoDS_Face aF1 = TopoDS::Face(aDS.Shape(nF1));
163
164 anOriF1 = aF1.Orientation();
165 iRank = aDS.Rank(nF1);
166
167 TopTools_DataMapOfShapeInteger aMapOfEdgeIndex;
168 TopTools_ListOfShape aListOfSplits;
169
170 if(SplitFace(nF1, aMapOfEdgeIndex, aListOfSplits)) {
171
172 DoInternalVertices(nF1, aListOfSplits);
173
174 TopTools_ListIteratorOfListOfShape aFaceIt(aListOfSplits);
175
176 for(; aFaceIt.More(); aFaceIt.Next()) {
177 TopoDS_Shape aShapeF = aFaceIt.Value();
178 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
179 pDS->InsertShapeAndAncestorsSuccessors(aShapeF, anASSeq);
180 //
181 Standard_Integer aNewFaceIndex = pDS->NumberOfInsertedShapes();
182 //
183 pDS->SetState(aNewFaceIndex, BooleanOperations_ON);
184
185 if(!aMapOfFaceSplits.IsBound(nF1)) {
186 TColStd_ListOfInteger thelist;
187 aMapOfFaceSplits.Bind(nF1, thelist);
188 }
189 aMapOfFaceSplits.ChangeFind(nF1).Append(aNewFaceIndex);
190
191 TopAbs_State aState = TopAbs_ON;
192 Standard_Boolean bFoundFaceState = Standard_False;
193
194 if(PropagateFaceStateByEdges(aShapeF, aMapOfEdgeIndex, aState)) {
195
196 if(aState != TopAbs_ON) { // can not determine correctly ON state
197 BooleanOperations_StateOfShape aConvertedState = BOPTools_StateFiller::ConvertState(aState);
198
199 pDS->SetState(aNewFaceIndex, aConvertedState);
200
201 bFoundFaceState = Standard_True;
202 }
203 }
204
205 if(!bFoundFaceState) {
206 //
207 if(ComputeStateByInsidePoints(aNewFaceIndex, nF1, iRank, aFFMap, aState)) {
208
209 if(aState != TopAbs_ON) {
210 BooleanOperations_StateOfShape aConvertedState = BOPTools_StateFiller::ConvertState(aState);
211
212 pDS->SetState(aNewFaceIndex, aConvertedState);
213 }
214 bFoundFaceState = Standard_True;
215 }
216 }
217
218 if(!bFoundFaceState) {
219
220 if(ComputeStateForAnalyticalSurfaces(aNewFaceIndex, nF1, aFFMap, *myDSFiller, aState)) {
221 if(aState != TopAbs_ON) {
222 BooleanOperations_StateOfShape aConvertedState = BOPTools_StateFiller::ConvertState(aState);
223
224 pDS->SetState(aNewFaceIndex, aConvertedState);
225 bFoundFaceState = Standard_True;
226 }
227 }
228 }
229 }
230 }
231 }
232 // end for
233}
234
235// =====================================================================================================================
236// function: PropagateFaceStateByEdges
237// purpose:
238// =====================================================================================================================
239Standard_Boolean BOP_SolidSolid::PropagateFaceStateByEdges(const TopoDS_Shape& theFace,
240 const TopTools_DataMapOfShapeInteger& theMapOfEdgeIndex,
241 TopAbs_State& theState)
242{
243 TopAbs_State aState = TopAbs_UNKNOWN;
244
245 const BooleanOperations_ShapesDataStructure& aDS = myDSFiller->DS();
246
247 if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE))
248 return Standard_False;
249 TopoDS_Face aF1 = TopoDS::Face(theFace);
250
251 Standard_Boolean bFoundNotON = Standard_False;
252 BooleanOperations_StateOfShape aFoundState = BooleanOperations_ON;
253 Standard_Boolean bIsINOUT = Standard_False;
254
255 TopExp_Explorer anExpE(aF1, TopAbs_EDGE);
256
257 for(; anExpE.More(); anExpE.Next()) {
258 const TopoDS_Shape& anEdge = anExpE.Current();
259
260 Standard_Integer nE = 0;
261
262 if(theMapOfEdgeIndex.IsBound(anEdge)) {
263 nE = theMapOfEdgeIndex(anEdge);
264 }
265 else {
266 nE = aDS.ShapeIndex(anEdge, 1);
267 nE = (nE == 0) ? aDS.ShapeIndex(anEdge, 2) : nE;
268 }
269
270 if(nE == 0)
271 continue;
272
273 BooleanOperations_StateOfShape anEdgeState = aDS.GetState(nE);
274
275 if((anEdgeState == BooleanOperations_IN) ||
276 (anEdgeState == BooleanOperations_OUT)) {
277
278 if(!bFoundNotON) {
279 bFoundNotON = Standard_True;
280 aFoundState = anEdgeState;
281 }
282
283 if(aFoundState != anEdgeState) {
284 bIsINOUT = Standard_True;
285 break;
286 }
287 }
288 }
289
290 if(!bIsINOUT && bFoundNotON) {
291 if(aFoundState == BooleanOperations_IN)
292 aState = TopAbs_IN;
293 else if(aFoundState == BooleanOperations_OUT)
294 aState = TopAbs_OUT;
295 }
296
297 if(aState == TopAbs_UNKNOWN)
298 return Standard_False;
299
300 theState = aState;
301
302 return Standard_True;
303}
304
19d6e40d 305//=======================================================================
306//function : ComputeStateByInsidePoints
307//purpose :
308//=======================================================================
309Standard_Boolean BOP_SolidSolid::
310 ComputeStateByInsidePoints(const Standard_Integer theFaceIndex,
311 const Standard_Integer theBaseFaceIndex,
312 const Standard_Integer theFaceRank,
313 const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& theFFMap,
314 TopAbs_State& theState)
7fd59977 315
316{
317 TopAbs_State aState = TopAbs_ON;
318 const BooleanOperations_ShapesDataStructure& aDS = myDSFiller->DS();
319 BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
320 const BOPTools_PaveFiller& aPaveFiller = myDSFiller->PaveFiller();
321 BOPTools_PaveFiller* pPaveFiller = (BOPTools_PaveFiller*)&aPaveFiller;
322 BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
323
324 if(theFaceIndex == 0)
325 return Standard_False;
326
327 const TopoDS_Shape& aS = aDS.Shape(theFaceIndex);
328
329 if(aS.IsNull())
330 return Standard_False;
331 TopoDS_Face aFace = TopoDS::Face(aS);
332 //
333 //
334 Standard_Integer i = 0, j = 0, aNb = 0;
335 aNb = theFFMap.Extent();
336
337 for (i=1; i<=aNb; i++) {
338 //
339 Standard_Integer nF1 = theFFMap.FindKey(i);
340
341 if(nF1 != theBaseFaceIndex)
342 continue;
343
344 const TColStd_IndexedMapOfInteger& aFFIndicesMap=theFFMap.FindFromIndex(i);
345 Standard_Integer aNbj = aFFIndicesMap.Extent();
346
347 for (j=1; j<=aNbj; j++) {
348 Standard_Integer iFF = aFFIndicesMap(j);
349 BOPTools_SSInterference& aFF = aFFs(iFF);
350 Standard_Boolean bIsTouchCase = aFF.IsTangentFaces();
351
352 if (bIsTouchCase) {
353 Standard_Integer nF2 = aFF.OppositeIndex(nF1);
354 const TopoDS_Face& aF2 = TopoDS::Face(aDS.Shape(nF2));
355
4f189102 356 if(BOPTools_Tools3D::CheckSameDomainFaceInside(aFace, aF2, pPaveFiller->Context())) {
7fd59977 357 theState = TopAbs_ON;
358 return Standard_True;
359 }
360 }
361 }
362 }
363 const TopoDS_Shape& aTool = (theFaceRank == 1) ? aDS.Tool() : aDS.Object();
364 TopoDS_Solid aRefSolid;
365
366 if(aTool.ShapeType() == TopAbs_SOLID)
367 aRefSolid = TopoDS::Solid(aTool);
368 else {
369 BRep_Builder aBB;
370 aBB.MakeSolid(aRefSolid);
371
372 TopExp_Explorer anExpSH(aTool, TopAbs_SHELL);
373
374 for(; anExpSH.More(); anExpSH.Next()) {
375 TopoDS_Shape aShell = anExpSH.Current();
376 aBB.Add(aShell, aRefSolid);
377 }
378 }
379
4f189102 380 if(!BOPTools_Tools3D::ComputeFaceState(aFace, aRefSolid, pPaveFiller->Context(), aState)) {
7fd59977 381 return Standard_False;
382 }
383 theState = aState;
384
385 return Standard_True;
386}
19d6e40d 387//=======================================================================
388//function : TakeOnSplit
389//purpose :
390//=======================================================================
7fd59977 391Standard_Boolean BOP_SolidSolid::TakeOnSplit(const Standard_Integer theFaceIndex,
392 const Standard_Integer theBaseFaceIndex) const
393{
394 Standard_Boolean bTake = Standard_False;
395
396 Standard_Boolean binout = Standard_False;
397 Standard_Boolean binin = Standard_False;
398 Standard_Boolean boutout = Standard_False;
399
400 TColStd_MapOfInteger aMapOfUsedIndices;
401 TColStd_ListOfInteger aListOfFacesToCheck;
402 aListOfFacesToCheck.Append(theFaceIndex);
19d6e40d 403 //DEB
404 Handle(IntTools_Context) aCtx;
405 TopAbs_Orientation aOrF1;
406 TopoDS_Face aF1, aFSp;
407 //
408 const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
409 const BOPTools_PaveFiller& aPF =myDSFiller->PaveFiller();
410 BOPTools_PaveFiller* pPF = (BOPTools_PaveFiller*)&aPF;
411 aCtx=pPF->Context();
412 //
413 aF1=TopoDS::Face(aDS.Shape(theBaseFaceIndex));
414 aOrF1=aF1.Orientation();
415 aFSp=TopoDS::Face(aDS.Shape(theFaceIndex));
416 aFSp.Orientation(aOrF1);
417 //
418 GetStatesOfAdjacentFaces(aListOfFacesToCheck,
419 *myDSFiller,
420 aMapOfUsedIndices,
421 binout, binin, boutout);
7fd59977 422
19d6e40d 423 //zzf
424 if (!binout && !binin && !boutout) {
425 Standard_Real aTol;
426 TopAbs_State aState;
427 //
428 aTol=1.e-5;
429 aState=ComputeState(aFSp, myRefTool, aTol, aCtx);
430 //
431 if (aState==TopAbs_IN) {
432 if (myOperation==BOP_FUSE || myOperation==BOP_COMMON) {
433 bTake=Standard_False;
434 }
435 else {
436 bTake=Standard_True;
437 }
438 }
439 //
440 else if (aState==TopAbs_OUT) {
441 if (myOperation==BOP_FUSE || myOperation==BOP_COMMON) {
442 bTake=Standard_True;
443 }
444 else {
445 bTake=Standard_False;
446 }
447 }
448 //
449 return bTake;
450 }//if (!binout && !binin && !boutout) {
451 //zzt
7fd59977 452 switch(myOperation) {
453 case BOP_FUSE: {
454 if(binout || (!binin && !boutout)) {
19d6e40d 455 bTake = Standard_True;
7fd59977 456 }
457 break;
458 }
459 case BOP_COMMON: {
460 if(binout || (!binin && !boutout)) {
461 bTake = Standard_True;
462 }
463 break;
464 }
465 case BOP_CUT: {
466 if((binin || boutout) && !binout) {
467 bTake = Standard_True;
468 }
469 break;
470 }
471 case BOP_CUT21: {
472 if((binin || boutout) && !binout) {
473 bTake = Standard_True;
474 }
475 break;
476 }
477 default: {
478 break;
479 }
480 }
481 return bTake;
482}
483
484// ------------------------------------------------------------------------------------
485// static function: GetIndex
486// purpose:
487// ------------------------------------------------------------------------------------
488Standard_Integer GetIndex(const TopoDS_Shape& theShape,
489 const BooleanOperations_ShapesDataStructure& theDS)
490{
491 Standard_Integer anIndex = 0, i = 0;
492
493 anIndex = theDS.ShapeIndex(theShape, 1);
494 anIndex = (anIndex == 0) ? theDS.ShapeIndex(theShape, 2) : anIndex;
495
496 if(anIndex == 0) {
497
498 for (i = theDS.NumberOfSourceShapes() + 1; i <= theDS.NumberOfInsertedShapes(); i++) {
499 if(theShape.IsSame(theDS.Shape(i))) {
500 anIndex = i;
501 break;
502 }
503 }
504 }
505
506 return anIndex;
507}
508
509// ------------------------------------------------------------------------------------
510// static function: GetAttachedFaces
511// purpose:
512// ------------------------------------------------------------------------------------
513void GetAttachedFaces(const Standard_Integer theEdgeIndex,
514 const Standard_Integer theFaceIndex,
515 const BOPTools_DSFiller& theDSFiller,
516 TColStd_ListOfInteger& theListOfFaces)
517{
518 theListOfFaces.Clear();
519 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller.DS();
520 const TColStd_DataMapOfIntegerListOfInteger& aMap = theDSFiller.SplitFacePool();
521
522 Standard_Integer i = 0;
523
524 for(i = 1; i <= aDS.NumberOfInsertedShapes(); i++) {
525
526 if(aDS.GetShapeType(i) == TopAbs_FACE) {
527 TColStd_ListOfInteger aListOfFaceIndex;
528
529 if(!aMap.IsBound(i)) {
530 if(theFaceIndex == i)
531 continue;
532 aListOfFaceIndex.Append(i);
533 }
534 else {
535 TColStd_ListIteratorOfListOfInteger anIttmp(aMap.Find(i));
536
537 for(; anIttmp.More(); anIttmp.Next()) {
538 if(theFaceIndex == anIttmp.Value())
539 continue;
540 aListOfFaceIndex.Append(anIttmp.Value());
541 }
542 }
543
544 TColStd_ListIteratorOfListOfInteger anIt(aListOfFaceIndex);
545
546 for(; anIt.More(); anIt.Next()) {
547 if(anIt.Value() <= 0)
548 continue;
549 const TopoDS_Shape& aFace = aDS.Shape(anIt.Value());
550 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
551
552 for(; anExpE.More(); anExpE.Next()) {
553 const TopoDS_Shape& anEdge = anExpE.Current();
554 Standard_Integer nE = GetIndex(anEdge, aDS);
555
556 if(theEdgeIndex == nE) {
557 theListOfFaces.Append(anIt.Value());
558 break;
559 }
560 }
561 }
562 }
563 }
564}
19d6e40d 565//=======================================================================
566//function : GetStatesOfAdjacentFaces
567//purpose :
568//=======================================================================
7fd59977 569void GetStatesOfAdjacentFaces(const TColStd_ListOfInteger& theListOfFacesToCheck,
570 const BOPTools_DSFiller& theDSFiller,
571 TColStd_MapOfInteger& theMapOfUsedIndices,
572 Standard_Boolean& bFoundINOUT,
573 Standard_Boolean& bFoundININ,
574 Standard_Boolean& bFoundOUTOUT)
575{
7fd59977 576 TColStd_ListOfInteger aLisOfON;
19d6e40d 577 Standard_Integer nE, nF, nFa;
578 BooleanOperations_StateOfShape aStFa;
579 //
580 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller.DS();
581 //
7fd59977 582 TColStd_ListIteratorOfListOfInteger anItF(theListOfFacesToCheck);
7fd59977 583 for(; anItF.More(); anItF.Next()) {
19d6e40d 584 nF = anItF.Value();
585 const TopoDS_Shape& aF=aDS.Shape(nF);
7fd59977 586
587 if(theMapOfUsedIndices.Contains(nF)) {
588 continue;
589 }
19d6e40d 590 //
7fd59977 591 theMapOfUsedIndices.Add(nF);
19d6e40d 592
7fd59977 593 TopoDS_Shape aFace = aDS.Shape(nF);
594
595 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
596
597 for(; anExpE.More(); anExpE.Next()) {
598 const TopoDS_Shape& anEdge = anExpE.Current();
7fd59977 599 nE = GetIndex(anEdge, aDS);
600
19d6e40d 601 if(nE <= 0) {
7fd59977 602 continue;
19d6e40d 603 }
604 if(theMapOfUsedIndices.Contains(nE)) {
7fd59977 605 continue;
19d6e40d 606 }
607 //
7fd59977 608 theMapOfUsedIndices.Add(nE);
609 TColStd_ListOfInteger aListOfFaces, aListOfIN, aListOfOUT;
610 GetAttachedFaces(nE, nF, theDSFiller, aListOfFaces);
611
612 TColStd_ListIteratorOfListOfInteger anIt(aListOfFaces);
613
614 for(; anIt.More(); anIt.Next()) {
19d6e40d 615 nFa=anIt.Value();
616 aStFa=aDS.GetState(nFa);
617 //
618 const TopoDS_Shape& aFa=aDS.Shape(nFa);
619 if(theMapOfUsedIndices.Contains(nFa)) {
620 continue;
621 }
622 //
623 if(aStFa==BooleanOperations_ON) {
624 aLisOfON.Append(nFa);
625 }
626 if(aStFa==BooleanOperations_IN) {
627 aListOfIN.Append(nFa);
628 }
629 else if(aStFa==BooleanOperations_OUT) {
630 aListOfOUT.Append(nFa);
631 }
7fd59977 632 }
633 bFoundINOUT = bFoundINOUT || (!aListOfIN.IsEmpty() && !aListOfOUT.IsEmpty());
634 bFoundININ = bFoundININ || (!aListOfIN.IsEmpty() && aListOfOUT.IsEmpty());
635 bFoundOUTOUT = bFoundOUTOUT || (aListOfIN.IsEmpty() && !aListOfOUT.IsEmpty());
636 }
637 }
638
639 if(!aLisOfON.IsEmpty() && (theMapOfUsedIndices.Extent() <= aDS.NumberOfInsertedShapes())) {
640 GetStatesOfAdjacentFaces(aLisOfON, theDSFiller, theMapOfUsedIndices, bFoundINOUT, bFoundININ, bFoundOUTOUT);
641 }
642}
643
644// ------------------------------------------------------------------------------------
645// static function: ComputeStateForAnalyticalSurfaces
646// purpose:
647// ------------------------------------------------------------------------------------
648Standard_Boolean ComputeStateForAnalyticalSurfaces(const Standard_Integer theFaceIndex,
649 const Standard_Integer theBaseFaceIndex,
650 const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& theFFMap,
651 const BOPTools_DSFiller& theDSFiller,
652 TopAbs_State& theState)
653{
654 TopAbs_State aState = TopAbs_ON;
655 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller.DS();
656 BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&theDSFiller.InterfPool();
657 const BOPTools_PaveFiller& aPaveFiller = theDSFiller.PaveFiller();
658 BOPTools_PaveFiller* pPaveFiller = (BOPTools_PaveFiller*)&aPaveFiller;
659 BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
660
661 if(theFaceIndex == 0)
662 return Standard_False;
663
664 const TopoDS_Shape& aS = aDS.Shape(theFaceIndex);
665
666 if(aS.IsNull())
667 return Standard_False;
668 TopoDS_Face aFace = TopoDS::Face(aS);
669
670 Standard_Integer j = 0;
671 Standard_Boolean bFound = Standard_False;
672
673 if (theFFMap.Contains(theBaseFaceIndex)) {
674 //
675 Standard_Integer nF1 = theBaseFaceIndex;
676
677 const TColStd_IndexedMapOfInteger& aFFIndicesMap=theFFMap.FindFromKey(theBaseFaceIndex);
678 Standard_Integer aNbj = aFFIndicesMap.Extent();
679
680 for (j=1; (!bFound) && (j<=aNbj); j++) {
681 Standard_Integer iFF = aFFIndicesMap(j);
682 BOPTools_SSInterference& aFF = aFFs(iFF);
683 Standard_Boolean bIsTouchCase = aFF.IsTangentFaces();
684
685 if (!bIsTouchCase) {
686 Standard_Integer nF2 = aFF.OppositeIndex(nF1);
687 const TopoDS_Face& aF2 = TopoDS::Face(aDS.Shape(nF2));
688 //
689 TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
690
691 for(; anExpE.More(); anExpE.Next()) {
692 TopoDS_Edge aSp = TopoDS::Edge(anExpE.Current());
693
694 Standard_Boolean bTestEdge = Standard_False;
695
696 Standard_Integer nE = GetIndex(aSp, aDS);
697 bTestEdge = IsEdgeValidForFace(nE, nF2, aFF, theDSFiller);
698
699 if(bTestEdge) {
700 TopAbs_State aStPF = TopAbs_ON;
701
702 Standard_Boolean bAnalytic = Standard_False;
703 Standard_Real aTolTangent, aTolR;
704 //
705 aTolTangent=0.002;
706 aTolR=0.0000001;
707
708 bAnalytic = BOPTools_Tools3D::TreatedAsAnalytic(aF2, aSp, aFace,
709 aTolTangent, aTolR,
4f189102 710 aStPF, pPaveFiller->Context());
7fd59977 711 if(bAnalytic) {
712 aState = aStPF;
713 bFound = Standard_True;
714 break;
715 }
716 else {
717 gp_Dir aDBF1, aDNF2;
718
719 BOPTools_Tools3D::GetBiNormal (aSp, aFace, aDBF1);
720 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSp, aF2, aDNF2);
721
722 Standard_Real aTolScPr, aScPr;
723
724 aTolScPr=1.e-7;
725 aScPr=aDBF1*aDNF2;
726
727 if (fabs(aScPr) > aTolScPr) {
728 aStPF=TopAbs_OUT;
729
730 if (aScPr<0.) {
731 aStPF=TopAbs_IN;
732 }
733 aState = aStPF;
734 bFound = Standard_True;
735 break;
736 }
737 }
738 }
739 // end if(bTestEdge)
740 }
741 }
742 }
743 }
744
745 if(!bFound) {
746 return Standard_False;
747 }
748 theState = aState;
749 return Standard_True;
750}
751
752// ------------------------------------------------------------------------------------
753// static function: IsEdgeValidForFace
754// purpose:
755// ------------------------------------------------------------------------------------
756Standard_Boolean IsEdgeValidForFace(const Standard_Integer theEdgeIndex,
757 const Standard_Integer theFaceIndex,
758 BOPTools_SSInterference& theFF,
759 const BOPTools_DSFiller& theDSFiller)
760{
761
762 const BOPTools_PaveFiller& aPaveFiller = theDSFiller.PaveFiller();
763 BOPTools_PaveFiller* pPaveFiller = (BOPTools_PaveFiller*)&aPaveFiller;
764 BOPTools_CommonBlockPool& aCBPool = pPaveFiller->ChangeCommonBlockPool();
765
766 BOPTools_SequenceOfCurves& aSCvs=theFF.Curves();
767 Standard_Integer aNbCurves=aSCvs.Length();
768 Standard_Integer i = 0;
769
770 for (i=1; i<=aNbCurves; i++) {
771 BOPTools_Curve& aBC=aSCvs(i);
772 const BOPTools_ListOfPaveBlock& aSectEdges=aBC.NewPaveBlocks();
773
774 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
775
776 for (; aPBIt.More(); aPBIt.Next()) {
777 BOPTools_PaveBlock& aPB = aPBIt.Value();
778
779 if(theEdgeIndex == aPB.Edge())
780 return Standard_True;
781 }
782 }
783
784
785 for(i = 1; i <= aCBPool.Length(); i++) {
786 const BOPTools_ListOfCommonBlock& aCBList = aCBPool.Value(i);
787 BOPTools_ListIteratorOfListOfCommonBlock anItCB(aCBList);
788
789 for (; anItCB.More(); anItCB.Next()) {
790 BOPTools_CommonBlock& aCB=anItCB.Value();
791 Standard_Integer nFace = aCB.Face();
792
793 if(nFace == theFaceIndex) {
794 const BOPTools_PaveBlock& aPB1 = aCB.PaveBlock1();
795 const BOPTools_PaveBlock& aPB2 = aCB.PaveBlock2();
796
797 if((theEdgeIndex == aPB1.Edge()) ||
798 (theEdgeIndex == aPB2.Edge())) {
799 return Standard_True;
800 }
801 }
802 }
803 }
7fd59977 804 return Standard_False;
805}
19d6e40d 806//=======================================================================
807// function: ComputeState
808// purpose:
809//=======================================================================
810TopAbs_State ComputeState(const TopoDS_Face& theF,
811 const TopoDS_Solid& theRef,
812 const Standard_Real theTol,
813 const Handle(IntTools_Context)& theCtx)
814{
815 Standard_Integer iErr;
816 TopAbs_State aRet;
817 gp_Pnt aP;
818 //
819 aRet=TopAbs_UNKNOWN;
820 //
821 iErr=PntHoverFace(theF, aP);
822 if (iErr) {
823 return aRet;
824 }
825 //
826 aRet=ComputeState(aP, theRef, theTol, theCtx);
827 return aRet;
828}
829
830//=======================================================================
831// function: ComputeState
832// purpose:
833//=======================================================================
834TopAbs_State ComputeState(const gp_Pnt& theP,
835 const TopoDS_Solid& theRef,
836 const Standard_Real theTol,
837 const Handle(IntTools_Context)& theCtx)
838{
839 TopAbs_State aState;
840 //
841 BRepClass3d_SolidClassifier& aSC=theCtx->SolidClassifier(theRef);
842 aSC.Perform(theP, theTol);
843 //
844 aState=aSC.State();
845 //
846 return aState;
847}
848//=======================================================================
849//function : PntHoverFace
850//purpose :
851//=======================================================================
852Standard_Integer PntHoverFace(const TopoDS_Face& aF,
853 gp_Pnt& theP)
854{
855 Standard_Integer iErr;
856 Standard_Real aU, aV, aX;
857 gp_Pnt aP;
858 gp_Vec aDN;
859 gp_Pnt2d aP2D;
860 //
861 iErr=PntInFace(aF, aP, aP2D);
862 if (iErr) {
863 return iErr;
864 }
865 //
866 aX=1e-4;
867 //
868 aP2D.Coord(aU, aV);
869 BOPTools_Tools2D::FaceNormal(aF, aU, aV, aDN);
870 //
871 theP.SetXYZ(aP.XYZ()+aX*aDN.XYZ());
872 //
873 return iErr;
874}
875//=======================================================================
876//function : PntInFace
877//purpose :
878//=======================================================================
879Standard_Integer PntInFace(const TopoDS_Face& aF,
880 gp_Pnt& theP,
881 gp_Pnt2d& theP2D)
882{
883 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
884 Standard_Integer iErr, aIx, aNbDomains, i;
885 Standard_Real aUMin, aUMax, aVMin, aVMax;
886 Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
887 Standard_Real aTolArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
888 gp_Dir2d aD2D (0., 1.);
889 gp_Pnt2d aP2D;
890 gp_Pnt aPx;
891 Handle(Geom2d_Curve) aC2D;
892 Handle(Geom2d_TrimmedCurve) aCT2D;
893 Handle(Geom2d_Line) aL2D;
894 Handle(Geom_Surface) aS;
895 TopAbs_Orientation aOrE;
896 TopoDS_Face aFF;
897 TopExp_Explorer aExp;
898 //
899 aTolHatch2D=1.e-8;
900 aTolHatch3D=1.e-8;
901 aTolArcIntr=1.e-10;
902 aTolTangfIntr=1.e-10;
903 //
904 Geom2dHatch_Intersector aIntr(aTolArcIntr, aTolTangfIntr);
905 Geom2dHatch_Hatcher aHatcher(aIntr,
906 aTolHatch2D, aTolHatch3D,
907 Standard_True, Standard_False);
908 //
909 iErr=0;
910 aEpsT=1.e-12;
911 //
912 aFF=aF;
913 aFF.Orientation (TopAbs_FORWARD);
914 //
915 aS=BRep_Tool::Surface(aFF);
916 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
917 //
918 // 1
919 aExp.Init (aFF, TopAbs_EDGE);
920 for (; aExp.More() ; aExp.Next()) {
921 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
922 aOrE=aE.Orientation();
923 //
924 aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
925 if (aC2D.IsNull() ) {
926 iErr=1;
927 return iErr;
928 }
929 if (fabs(aU1-aU2) < aEpsT) {
930 iErr=2;
931 return iErr;
932 }
933 //
934 aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
935 aHatcher.AddElement(aCT2D, aOrE);
936 }// for (; aExp.More() ; aExp.Next()) {
937 //
938 // 2
939 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
940 aP2D.SetCoord(aUx, 0.);
941 aL2D=new Geom2d_Line (aP2D, aD2D);
942 Geom2dAdaptor_Curve aHCur(aL2D);
943 //
944 aIx=aHatcher.AddHatching(aHCur) ;
945 //
946 // 3.
947 aHatcher.Trim();
948 bIsDone=aHatcher.TrimDone(aIx);
949 if (!bIsDone) {
950 iErr=3;
951 return iErr;
952 }
953 //
954 aHatcher.ComputeDomains(aIx);
955 bIsDone=aHatcher.IsDone(aIx);
956 if (!bIsDone) {
957 iErr=4;
958 return iErr;
959 }
960 //
961 // 4.
962 aNbDomains=aHatcher.NbDomains(aIx);
963 for (i=1; i<=aNbDomains; ++i) {
964 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
965 bHasFirstPoint=aDomain.HasFirstPoint();
966 if (!bHasFirstPoint) {
967 iErr=5;
968 return iErr;
969 }
970 //
971 aV1=aDomain.FirstPoint().Parameter();
972 //
973 bHasSecondPoint=aDomain.HasSecondPoint();
974 if (!bHasSecondPoint) {
975 iErr=6;
976 return iErr;
977 }
978 //
979 aV2=aDomain.SecondPoint().Parameter();
980 //
981 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
982 //
983 break;
984 }
985 //
986 aS->D0(aUx, aVx, aPx);
987 //
988 theP2D.SetCoord(aUx, aVx);
989 theP=aPx;
990 //
991 return iErr;
992}
993