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 |
83 | static |
84 | Standard_Integer GetIndex(const TopoDS_Shape& theShape, |
85 | const BooleanOperations_ShapesDataStructure& theDS); |
86 | |
87 | static |
88 | void GetAttachedFaces(const Standard_Integer theEdgeIndex, |
89 | const Standard_Integer theFaceIndex, |
90 | const BOPTools_DSFiller& theDSFiller, |
91 | TColStd_ListOfInteger& theListOfFaces); |
92 | |
93 | static |
94 | void 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 | |
101 | static |
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 | |
109 | static |
110 | Standard_Boolean IsEdgeValidForFace(const Standard_Integer theEdgeIndex, |
111 | const Standard_Integer theFaceIndex, |
112 | BOPTools_SSInterference& theFF, |
113 | const BOPTools_DSFiller& theDSFiller); |
114 | |
19d6e40d |
115 | static |
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 | |
121 | static |
122 | Standard_Integer PntInFace(const TopoDS_Face& aF, |
123 | gp_Pnt& theP, |
124 | gp_Pnt2d& theP2D); |
125 | |
126 | static |
127 | Standard_Integer PntHoverFace(const TopoDS_Face& aF, |
128 | gp_Pnt& theP); |
129 | |
130 | static |
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 | //================================================================================= |
141 | void 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 | // ===================================================================================================================== |
239 | Standard_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 | //======================================================================= |
309 | Standard_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 |
391 | Standard_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 | // ------------------------------------------------------------------------------------ |
488 | Standard_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 | // ------------------------------------------------------------------------------------ |
513 | void 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 |
569 | void 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 | // ------------------------------------------------------------------------------------ |
648 | Standard_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 | // ------------------------------------------------------------------------------------ |
756 | Standard_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 | //======================================================================= |
810 | TopAbs_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 | //======================================================================= |
834 | TopAbs_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 | //======================================================================= |
852 | Standard_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 | //======================================================================= |
879 | Standard_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 | |