b311480e |
1 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
2 | // |
3 | // The content of this file is subject to the Open CASCADE Technology Public |
4 | // License Version 6.5 (the "License"). You may not use the content of this file |
5 | // except in compliance with the License. Please obtain a copy of the License |
6 | // at http://www.opencascade.org and read it completely before using this file. |
7 | // |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
10 | // |
11 | // The Original Code and all software distributed under the License is |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
13 | // Initial Developer hereby disclaims all such warranties, including without |
14 | // limitation, any warranties of merchantability, fitness for a particular |
15 | // purpose or non-infringement. Please see the License for the specific terms |
16 | // and conditions governing the rights and limitations under the License. |
17 | |
7fd59977 |
18 | #include <QANewModTopOpe_Tools.ixx> |
19 | |
7fd59977 |
20 | #include <BRepAlgoAPI_Cut.hxx> |
21 | #include <BRepAlgoAPI_Common.hxx> |
22 | |
23 | #include <TopoDS.hxx> |
24 | #include <TopoDS_Face.hxx> |
25 | #include <TopoDS_Edge.hxx> |
7fd59977 |
26 | |
27 | #include <BRepTools.hxx> |
28 | #include <BRep_Tool.hxx> |
29 | #include <BRep_Builder.hxx> |
30 | #include <Geom_Surface.hxx> |
4e57c75e |
31 | #include <BOPInt_Context.hxx> |
7fd59977 |
32 | #include <TopExp_Explorer.hxx> |
33 | #include <TopExp.hxx> |
34 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
35 | #include <TopTools_IndexedMapOfShape.hxx> |
36 | #include <TopTools_DataMapOfIntegerShape.hxx> |
37 | |
38 | #include <TCollection_CompareOfReal.hxx> |
39 | #include <SortTools_QuickSortOfReal.hxx> |
40 | |
41 | #include <TColStd_Array1OfReal.hxx> |
42 | #include <TColStd_IndexedMapOfReal.hxx> |
43 | #include <TColStd_ListOfInteger.hxx> |
44 | #include <TColStd_ListIteratorOfListOfInteger.hxx> |
45 | |
4e57c75e |
46 | #include <BOPAlgo_PaveFiller.hxx> |
47 | #include <BOPDS_DS.hxx> |
48 | #include <BOPAlgo_Builder.hxx> |
49 | #include <BOPAlgo_BOP.hxx> |
50 | #include <IntTools_CommonPrt.hxx> |
51 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
52 | #include <BOPDS_CommonBlock.hxx> |
53 | #include <BOPTools_AlgoTools3D.hxx> |
54 | |
7fd59977 |
55 | static Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape, |
4e57c75e |
56 | const TopoDS_Shape& theNewShape, |
57 | TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap); |
7fd59977 |
58 | |
59 | static void FillEdgeHistoryMap(BRepAlgoAPI_BooleanOperation& theBOP, |
4e57c75e |
60 | TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap); |
7fd59977 |
61 | |
62 | static void SortVertexOnEdge(const TopoDS_Edge& theEdge, |
4e57c75e |
63 | const TopTools_ListOfShape& theListOfVertex, |
64 | TopTools_ListOfShape& theListOfVertexSorted); |
65 | |
66 | static TopAbs_State GetEdgeState(const BOPDS_PDS& pDS, |
67 | const Handle(BOPDS_PaveBlock)& aPB); |
7fd59977 |
68 | |
69 | // ======================================================================================== |
70 | // function: NbPoints |
71 | // purpose: |
72 | // ======================================================================================== |
4e57c75e |
73 | Standard_Integer QANewModTopOpe_Tools::NbPoints(const BOPAlgo_PPaveFiller& theDSFiller) |
7fd59977 |
74 | { |
4e57c75e |
75 | Standard_Integer i, anbpoints, aNb; |
76 | // |
77 | const BOPDS_PDS& pDS = theDSFiller->PDS(); |
78 | anbpoints = 0; |
7fd59977 |
79 | |
4e57c75e |
80 | //FF |
81 | BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF(); |
82 | aNb=aFFs.Extent(); |
83 | for (i = 0; i < aNb; ++i) { |
84 | BOPDS_InterfFF& aFF=aFFs(i); |
85 | const BOPDS_VectorOfPoint& aVP=aFF.Points(); |
86 | anbpoints += aVP.Extent(); |
87 | } |
7fd59977 |
88 | |
4e57c75e |
89 | //EF |
90 | BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF(); |
91 | aNb = aEFs.Extent(); |
92 | for (i = 0; i < aNb; ++i) { |
93 | BOPDS_InterfEF& aEF=aEFs(i); |
94 | IntTools_CommonPrt aCP = aEF.CommonPart(); |
95 | if(aCP.Type() == TopAbs_VERTEX) { |
7fd59977 |
96 | anbpoints++; |
4e57c75e |
97 | } |
7fd59977 |
98 | } |
4e57c75e |
99 | |
100 | //EE |
101 | BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE(); |
7fd59977 |
102 | aNb = aEEs.Extent(); |
4e57c75e |
103 | for (i = 0; i < aNb; ++i) { |
104 | BOPDS_InterfEE& aEE=aEEs(i); |
105 | IntTools_CommonPrt aCP = aEE.CommonPart(); |
106 | if(aCP.Type() == TopAbs_VERTEX) { |
7fd59977 |
107 | anbpoints++; |
4e57c75e |
108 | } |
7fd59977 |
109 | } |
4e57c75e |
110 | |
7fd59977 |
111 | return anbpoints; |
112 | } |
113 | |
114 | // ======================================================================================== |
115 | // function: NewVertex |
116 | // purpose: |
117 | // ======================================================================================== |
4e57c75e |
118 | TopoDS_Shape QANewModTopOpe_Tools::NewVertex(const BOPAlgo_PPaveFiller& theDSFiller, |
119 | const Standard_Integer theIndex) |
7fd59977 |
120 | { |
121 | TopoDS_Shape aVertex; |
4e57c75e |
122 | Standard_Integer i, j, anbpoints, aNb, aNbP; |
123 | // |
124 | const BOPDS_PDS& pDS = theDSFiller->PDS(); |
125 | anbpoints = 0; |
7fd59977 |
126 | |
4e57c75e |
127 | //FF |
128 | BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF(); |
129 | aNb=aFFs.Extent(); |
130 | for (i = 0; i < aNb; ++i) { |
131 | BOPDS_InterfFF& aFF=aFFs(i); |
132 | const BOPDS_VectorOfPoint& aVP=aFF.Points(); |
133 | aNbP = aVP.Extent(); |
134 | for(j = 0; j < aNbP; ++j) { |
7fd59977 |
135 | anbpoints++; |
4e57c75e |
136 | // |
137 | if (theIndex == anbpoints) { |
138 | const BOPDS_Point& aNP = aVP(j); |
139 | return pDS->Shape(aNP.Index()); |
7fd59977 |
140 | } |
141 | } |
142 | } |
7fd59977 |
143 | |
4e57c75e |
144 | //EF |
145 | BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF(); |
146 | aNb = aEFs.Extent(); |
147 | for (i = 0; i < aNb; ++i) { |
148 | BOPDS_InterfEF& aEF=aEFs(i); |
149 | IntTools_CommonPrt aCP = aEF.CommonPart(); |
150 | if(aCP.Type() == TopAbs_VERTEX) { |
7fd59977 |
151 | anbpoints++; |
4e57c75e |
152 | // |
153 | if (theIndex == anbpoints) { |
154 | return pDS->Shape(aEF.IndexNew()); |
7fd59977 |
155 | } |
156 | } |
157 | } |
4e57c75e |
158 | |
159 | //EE |
160 | BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE(); |
7fd59977 |
161 | aNb = aEEs.Extent(); |
4e57c75e |
162 | for (i = 0; i < aNb; ++i) { |
163 | BOPDS_InterfEE& aEE=aEEs(i); |
164 | IntTools_CommonPrt aCP = aEE.CommonPart(); |
165 | if(aCP.Type() == TopAbs_VERTEX) { |
7fd59977 |
166 | anbpoints++; |
4e57c75e |
167 | // |
168 | if (theIndex == anbpoints) { |
169 | return pDS->Shape(aEE.IndexNew()); |
7fd59977 |
170 | } |
171 | } |
172 | } |
4e57c75e |
173 | |
7fd59977 |
174 | return aVertex; |
175 | } |
176 | |
4e57c75e |
177 | |
7fd59977 |
178 | // ======================================================================================== |
4e57c75e |
179 | // function: HasDomain |
7fd59977 |
180 | // purpose: |
181 | // ======================================================================================== |
4e57c75e |
182 | Standard_Boolean QANewModTopOpe_Tools::HasSameDomain(const BOPAlgo_PBOP& theBuilder, |
183 | const TopoDS_Shape& theFace) |
7fd59977 |
184 | { |
4e57c75e |
185 | Standard_Integer bRet; |
186 | bRet = Standard_False; |
7fd59977 |
187 | // |
4e57c75e |
188 | if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE)) |
189 | return bRet; |
7fd59977 |
190 | |
4e57c75e |
191 | BOPCol_ListIteratorOfListOfShape aIt; |
192 | const BOPCol_DataMapOfShapeListOfShape& aImages = theBuilder->Images(); |
193 | if (!aImages.IsBound(theFace)) { |
194 | return bRet; |
195 | } |
196 | const BOPCol_ListOfShape& aLF=aImages.Find(theFace); |
197 | |
198 | if (aLF.Extent() == 0) { |
199 | return bRet; |
200 | } |
201 | const BOPCol_DataMapOfShapeShape& aShapesSD = theBuilder->ShapesSD(); |
7fd59977 |
202 | |
4e57c75e |
203 | aIt.Initialize(aLF); |
204 | for (; aIt.More(); aIt.Next()) { |
205 | const TopoDS_Shape& aFsp = aIt.Value(); |
206 | if (aShapesSD.IsBound(aFsp)) { |
207 | bRet = Standard_True; |
208 | break; |
7fd59977 |
209 | } |
210 | } |
4e57c75e |
211 | |
212 | return bRet; |
7fd59977 |
213 | } |
214 | |
215 | // ======================================================================================== |
216 | // function: SameDomain |
217 | // purpose: |
218 | // ======================================================================================== |
4e57c75e |
219 | void QANewModTopOpe_Tools::SameDomain(const BOPAlgo_PBOP& theBuilder, |
220 | const TopoDS_Shape& theFace, |
221 | TopTools_ListOfShape& theResultList) |
7fd59977 |
222 | { |
223 | theResultList.Clear(); |
224 | |
225 | if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE)) |
226 | return; |
7fd59977 |
227 | |
4e57c75e |
228 | BOPCol_ListIteratorOfListOfShape aIt; |
229 | const BOPCol_ListOfShape& aLF=theBuilder->Splits().Find(theFace); |
230 | |
231 | if (aLF.Extent() == 0) { |
232 | return; |
233 | } |
234 | const BOPCol_DataMapOfShapeShape& aShapesSD = theBuilder->ShapesSD(); |
235 | const BOPCol_DataMapOfShapeShape& aOrigins = theBuilder->Origins(); |
236 | |
237 | aIt.Initialize(aLF); |
238 | for (; aIt.More(); aIt.Next()) { |
239 | const TopoDS_Shape& aFSp = aIt.Value(); |
240 | if (aShapesSD.IsBound(aFSp)) { |
241 | const TopoDS_Shape& aFSD = aShapesSD.Find(aFSp); |
242 | const TopoDS_Shape& aFOr = aOrigins.Find(aFSD); |
243 | if (theFace.IsEqual(aFOr)) { |
244 | BOPCol_DataMapIteratorOfDataMapOfShapeShape aItSD; |
245 | aItSD.Initialize(aShapesSD); |
246 | for (; aItSD.More(); aItSD.Next()) { |
247 | const TopoDS_Shape& aS = aItSD.Value(); |
248 | if (aFSD.IsEqual(aS)) { |
249 | const TopoDS_Shape& aSK = aItSD.Key(); |
250 | const TopoDS_Shape& aSKOr = aOrigins.Find(aSK); |
251 | if (!aSKOr.IsEqual(theFace)) { |
252 | theResultList.Append(aSKOr); |
253 | } |
254 | } |
255 | } |
256 | } else { |
257 | theResultList.Append(aFOr); |
7fd59977 |
258 | } |
259 | } |
260 | } |
261 | } |
262 | |
263 | // ======================================================================================== |
264 | // function: IsSplit |
265 | // purpose: |
266 | // ======================================================================================== |
4e57c75e |
267 | Standard_Boolean QANewModTopOpe_Tools::IsSplit(const BOPAlgo_PPaveFiller& theDSFiller, |
268 | const TopoDS_Shape& theEdge, |
269 | const TopAbs_State theState) |
7fd59977 |
270 | { |
271 | if(theEdge.IsNull() || (theEdge.ShapeType() != TopAbs_EDGE)) |
272 | return Standard_False; |
7fd59977 |
273 | |
4e57c75e |
274 | Standard_Integer index, nSp; |
275 | // |
276 | const BOPDS_PDS& pDS = theDSFiller->PDS(); |
277 | index = pDS->Index(theEdge); |
278 | if (index == -1) { |
279 | return Standard_False; |
280 | } |
7fd59977 |
281 | |
4e57c75e |
282 | const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(index); |
283 | BOPDS_ListIteratorOfListOfPaveBlock aPBIt; |
284 | aPBIt.Initialize(aLPB); |
7fd59977 |
285 | for (; aPBIt.More(); aPBIt.Next()) { |
4e57c75e |
286 | const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value(); |
287 | nSp = aPB->Edge(); |
288 | |
289 | TopAbs_State aSplitState = GetEdgeState(pDS, aPB); |
7fd59977 |
290 | |
4e57c75e |
291 | if(aSplitState == theState) { |
7fd59977 |
292 | return Standard_True; |
4e57c75e |
293 | } |
7fd59977 |
294 | } |
295 | |
7fd59977 |
296 | return Standard_False; |
297 | } |
298 | |
299 | // ======================================================================================== |
300 | // function: Splits |
301 | // purpose: |
302 | // ======================================================================================== |
4e57c75e |
303 | void QANewModTopOpe_Tools::Splits(const BOPAlgo_PPaveFiller& theDSFiller, |
304 | const TopoDS_Shape& theEdge, |
305 | const TopAbs_State theState, |
306 | TopTools_ListOfShape& theResultList) |
7fd59977 |
307 | { |
308 | theResultList.Clear(); |
309 | |
310 | if(theEdge.IsNull() || (theEdge.ShapeType() != TopAbs_EDGE)) |
311 | return; |
7fd59977 |
312 | |
4e57c75e |
313 | Standard_Integer index, nSp; |
314 | // |
315 | const BOPDS_PDS& pDS = theDSFiller->PDS(); |
316 | index = pDS->Index(theEdge); |
317 | if (index == -1) { |
318 | return; |
319 | } |
7fd59977 |
320 | |
4e57c75e |
321 | const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(index); |
322 | BOPDS_ListIteratorOfListOfPaveBlock aPBIt; |
323 | aPBIt.Initialize(aLPB); |
7fd59977 |
324 | for (; aPBIt.More(); aPBIt.Next()) { |
4e57c75e |
325 | const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value(); |
326 | nSp = aPB->Edge(); |
327 | |
328 | TopAbs_State aSplitState = GetEdgeState(pDS, aPB); |
7fd59977 |
329 | |
330 | if(aSplitState == theState) { |
4e57c75e |
331 | TopoDS_Shape aSplit = pDS->Shape(nSp); |
7fd59977 |
332 | theResultList.Append(aSplit); |
7fd59977 |
333 | } |
334 | } |
7fd59977 |
335 | } |
336 | |
337 | // ======================================================================================== |
338 | // function: SplitE |
339 | // purpose: |
340 | // ======================================================================================== |
341 | Standard_Boolean QANewModTopOpe_Tools::SplitE(const TopoDS_Edge& theEdge, |
4e57c75e |
342 | TopTools_ListOfShape& theSplits) |
7fd59977 |
343 | { |
344 | // prequesitory : <Eanc> is a valid edge. |
345 | TopAbs_Orientation oEanc = theEdge.Orientation(); |
346 | TopoDS_Shape aLocalShape = theEdge.Oriented(TopAbs_FORWARD); |
347 | TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape); |
348 | TopTools_ListOfShape aListOfVertex; |
349 | TopExp_Explorer exv(EFOR,TopAbs_VERTEX); |
350 | |
351 | for (;exv.More(); exv.Next()) { |
352 | const TopoDS_Shape& v = exv.Current(); |
353 | aListOfVertex.Append(v); |
354 | } |
355 | Standard_Integer nv = aListOfVertex.Extent(); |
356 | |
357 | if (nv <= 2) return Standard_False; |
358 | TopTools_ListOfShape aListOfVertexSorted; |
359 | |
360 | SortVertexOnEdge(EFOR, aListOfVertex, aListOfVertexSorted); |
361 | |
362 | TopoDS_Vertex v0; |
363 | TopTools_ListIteratorOfListOfShape anIt(aListOfVertexSorted); |
364 | |
365 | if (anIt.More()) { |
366 | v0 = TopoDS::Vertex(anIt.Value()); |
367 | anIt.Next(); |
368 | } |
369 | else return Standard_False; |
370 | |
371 | for (; anIt.More(); anIt.Next()) { |
372 | TopoDS_Vertex v = TopoDS::Vertex(anIt.Value()); |
373 | |
374 | // prequesitory: par0 < par |
375 | Standard_Real par0 = BRep_Tool::Parameter(v0, EFOR); |
376 | Standard_Real par = BRep_Tool::Parameter(v, EFOR); |
377 | |
378 | // here, ed has the same geometries than Ein, but with no subshapes. |
379 | TopoDS_Edge ed = TopoDS::Edge(EFOR.EmptyCopied()); |
380 | BRep_Builder BB; |
381 | v0.Orientation(TopAbs_FORWARD); |
382 | BB.Add(ed, v0); |
383 | v.Orientation(TopAbs_REVERSED); |
384 | BB.Add(ed, v); |
385 | BB.Range(ed, par0, par); |
386 | |
387 | theSplits.Append(ed.Oriented(oEanc)); |
388 | v0 = v; |
389 | } |
390 | return Standard_True; |
391 | } |
392 | |
393 | |
394 | // ======================================================================================== |
395 | // function: EdgeCurveAncestors |
396 | // purpose: |
397 | // ======================================================================================== |
4e57c75e |
398 | Standard_Boolean QANewModTopOpe_Tools::EdgeCurveAncestors(const BOPAlgo_PPaveFiller& theDSFiller, |
399 | const TopoDS_Shape& theEdge, |
400 | TopoDS_Shape& theFace1, |
401 | TopoDS_Shape& theFace2) |
7fd59977 |
402 | { |
403 | theFace1.Nullify(); |
404 | theFace2.Nullify(); |
4e57c75e |
405 | // |
406 | Standard_Integer i, j, aNb, aNbC, nE, nF1, nF2; |
407 | BOPDS_ListIteratorOfListOfPaveBlock aIt; |
7fd59977 |
408 | |
4e57c75e |
409 | const BOPDS_PDS& pDS = theDSFiller->PDS(); |
410 | BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF(); |
7fd59977 |
411 | |
4e57c75e |
412 | aNb=aFFs.Extent(); |
413 | for (i = 0; i < aNb; ++i) { |
414 | BOPDS_InterfFF& aFF=aFFs(i); |
415 | |
416 | const BOPDS_VectorOfCurve& aVC = aFF.Curves(); |
417 | aNbC = aVC.Extent(); |
418 | for (j = 0; j < aNbC; ++j) { |
419 | const BOPDS_Curve& aNC = aVC(j); |
420 | const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks(); |
421 | aIt.Initialize(aLPB); |
422 | for (; aIt.More(); aIt.Next()) { |
423 | const Handle(BOPDS_PaveBlock)& aPB = aIt.Value(); |
424 | nE = aPB->Edge(); |
425 | const TopoDS_Shape& aE = pDS->Shape(nE); |
426 | if (theEdge.IsSame(aE)) { |
427 | aFF.Indices(nF1, nF2); |
428 | theFace1 = pDS->Shape(nF1); |
429 | theFace2 = pDS->Shape(nF2); |
430 | return Standard_True; |
431 | } |
7fd59977 |
432 | } |
433 | } |
434 | } |
4e57c75e |
435 | |
7fd59977 |
436 | return Standard_False; |
437 | } |
438 | |
439 | // ======================================================================================== |
440 | // function: EdgeSectionAncestors |
441 | // purpose: |
442 | // ======================================================================================== |
4e57c75e |
443 | Standard_Boolean QANewModTopOpe_Tools::EdgeSectionAncestors(const BOPAlgo_PPaveFiller& theDSFiller, |
444 | const TopoDS_Shape& theEdge, |
445 | TopTools_ListOfShape& LF1, |
446 | TopTools_ListOfShape& LF2, |
447 | TopTools_ListOfShape& LE1, |
448 | TopTools_ListOfShape& LE2) |
7fd59977 |
449 | { |
450 | if(theEdge.ShapeType() != TopAbs_EDGE) |
451 | return Standard_False; |
4e57c75e |
452 | |
453 | const BOPDS_PDS& pDS = theDSFiller->PDS(); |
454 | Standard_Integer i = 0, nb = 0, nF, nE, nEOr; |
455 | BOPCol_MapOfInteger aMIF; |
456 | nb = pDS->NbSourceShapes(); |
457 | |
458 | nE = pDS->Index(theEdge); |
459 | const BOPDS_ListOfPaveBlock& aLPB1 = pDS->PaveBlocks(nE); |
460 | if (!aLPB1.Extent()) { |
461 | return Standard_False; |
462 | } |
7fd59977 |
463 | |
4e57c75e |
464 | const Handle(BOPDS_PaveBlock)& aPB1 = aLPB1.First(); |
5a77460e |
465 | const Handle(BOPDS_CommonBlock)& aCB=pDS->CommonBlock(aPB1); |
4e57c75e |
466 | if (aCB.IsNull()) { |
467 | return Standard_False; |
468 | } |
469 | |
470 | const BOPCol_ListOfInteger& aLIF = aCB->Faces(); |
471 | BOPCol_ListIteratorOfListOfInteger aItLI; |
472 | aItLI.Initialize(aLIF); |
473 | for ( ; aItLI.More(); aItLI.Next()) { |
474 | nF = aItLI.Value(); |
475 | if(pDS->Rank(nF) == 0) |
476 | LF1.Append(pDS->Shape(nF)); |
477 | else |
478 | LF2.Append(pDS->Shape(nF)); |
7fd59977 |
479 | |
4e57c75e |
480 | aMIF.Add(nF); |
481 | } |
7fd59977 |
482 | |
4e57c75e |
483 | const BOPDS_ListOfPaveBlock& aLPB = aCB->PaveBlocks(); |
484 | BOPDS_ListIteratorOfListOfPaveBlock aItPB; |
485 | aItPB.Initialize(aLPB); |
486 | for (; aItPB.More(); aItPB.Next()) { |
487 | const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value(); |
488 | nEOr = aPB->OriginalEdge(); |
7fd59977 |
489 | |
4e57c75e |
490 | if(pDS->Rank(nEOr) == 0) |
491 | LE1.Append(pDS->Shape(nEOr)); |
492 | else |
493 | LE2.Append(pDS->Shape(nEOr)); |
7fd59977 |
494 | |
4e57c75e |
495 | //find edge ancestors |
496 | for(i = 0; i < nb; ++i) { |
497 | const BOPDS_ShapeInfo& aSI = pDS->ShapeInfo(i); |
498 | if(aSI.ShapeType() != TopAbs_FACE) { |
499 | continue; |
7fd59977 |
500 | } |
4e57c75e |
501 | const BOPCol_ListOfInteger& aSubShapes = aSI.SubShapes(); |
502 | aItLI.Initialize(aSubShapes); |
503 | for (; aItLI.More(); aItLI.Next()) { |
504 | if (nEOr == aItLI.Value()) { |
505 | if (aMIF.Add(i)) { |
506 | if(pDS->Rank(i) == 0) LF1.Append(pDS->Shape(i)); |
507 | else LF2.Append(pDS->Shape(i)); |
508 | }//if (aMIF.Add(i)) { |
509 | }//if (nEOr == aItLI.Value()) { |
510 | }//for (; aItLI.More(); aItLI.Next()) { |
511 | }//for(i = 0; i < nb; ++i) { |
7fd59977 |
512 | } |
4e57c75e |
513 | |
7fd59977 |
514 | Standard_Boolean r = (!LF1.IsEmpty() && !LF2.IsEmpty()); |
515 | r = r && (!LE1.IsEmpty() || !LE2.IsEmpty()); |
516 | return r; |
517 | } |
518 | |
519 | // ======================================================================================== |
520 | // function: BoolOpe |
521 | // purpose: |
522 | // ======================================================================================== |
523 | Standard_Boolean QANewModTopOpe_Tools::BoolOpe(const TopoDS_Shape& theFace1, |
4e57c75e |
524 | const TopoDS_Shape& theFace2, |
525 | Standard_Boolean& IsCommonFound, |
526 | TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) |
7fd59977 |
527 | { |
528 | IsCommonFound = Standard_False; |
529 | theHistoryMap.Clear(); |
4e57c75e |
530 | gp_Dir aDNF1, aDNF2; |
531 | Standard_Integer iSenseFlag; |
7fd59977 |
532 | |
4e57c75e |
533 | BOPAlgo_PaveFiller aDSFiller; |
534 | BOPCol_ListOfShape aLS; |
535 | aLS.Append(theFace1); |
536 | aLS.Append(theFace2); |
537 | aDSFiller.SetArguments(aLS); |
538 | |
539 | aDSFiller.Perform(); |
540 | if (aDSFiller.ErrorStatus()) { |
7fd59977 |
541 | return Standard_False; |
542 | } |
4e57c75e |
543 | |
544 | const BOPDS_PDS& pDS = aDSFiller.PDS(); |
545 | |
546 | Standard_Integer aNb = 0, aNbSps; |
302f96fb |
547 | Standard_Integer i = 0; |
7fd59977 |
548 | TopTools_IndexedMapOfShape aMapV; |
4e57c75e |
549 | |
7fd59977 |
550 | { |
551 | BRepAlgoAPI_Common aCommon(theFace1, theFace2, aDSFiller); |
552 | |
553 | if(!aCommon.IsDone()) { |
554 | return Standard_False; |
555 | } |
4e57c75e |
556 | |
7fd59977 |
557 | TopExp_Explorer anExp(aCommon.Shape(), TopAbs_FACE); |
7fd59977 |
558 | if(!anExp.More()) { |
559 | IsCommonFound = Standard_False; |
560 | return Standard_True; |
561 | } |
4e57c75e |
562 | |
7fd59977 |
563 | IsCommonFound = Standard_True; |
564 | TopExp::MapShapes(aCommon.Shape(), TopAbs_VERTEX, aMapV); |
565 | // fill edge history.begin |
566 | FillEdgeHistoryMap(aCommon, theHistoryMap); |
567 | // fill edge history.end |
568 | |
569 | // fill face history.begin |
4e57c75e |
570 | BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF(); |
7fd59977 |
571 | aNb = aFFs.Extent(); |
572 | Standard_Boolean bReverseFlag = Standard_True; |
573 | Standard_Boolean fillhistory = Standard_True; |
574 | |
4e57c75e |
575 | for (i=0; i<aNb; ++i) { |
576 | BOPDS_InterfFF& aFF = aFFs(i); |
577 | Standard_Integer nF1, nF2; |
578 | aFF.Indices(nF1, nF2); |
579 | |
580 | const TopoDS_Face& aF1 = *(TopoDS_Face*)(&pDS->Shape(nF1)); |
581 | const TopoDS_Face& aF2 = *(TopoDS_Face*)(&pDS->Shape(nF2)); |
582 | |
583 | BOPCol_ListOfInteger aLSE; |
584 | pDS->SharedEdges(nF1, nF2, aLSE, aDSFiller.Allocator()); |
585 | aNbSps = aLSE.Extent(); |
586 | |
587 | if (!aNbSps) { |
588 | fillhistory = Standard_False; |
589 | continue; |
590 | } |
591 | |
592 | Standard_Integer nE = aLSE.First(); |
593 | const TopoDS_Edge& aSpE = *(TopoDS_Edge*)(&pDS->Shape(nE)); |
594 | |
595 | BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1); |
596 | BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2); |
597 | iSenseFlag=BOPTools_AlgoTools3D::SenseFlag (aDNF1, aDNF2); |
7fd59977 |
598 | |
4e57c75e |
599 | if(iSenseFlag == 1) { |
600 | fillhistory = Standard_True; |
601 | bReverseFlag = Standard_False; |
7fd59977 |
602 | } |
4e57c75e |
603 | else if(iSenseFlag == -1) { |
604 | fillhistory = Standard_True; |
605 | bReverseFlag = Standard_True; |
7fd59977 |
606 | } |
607 | else |
4e57c75e |
608 | fillhistory = Standard_False; |
7fd59977 |
609 | } |
610 | |
611 | if(fillhistory) { |
612 | |
613 | for(; anExp.More(); anExp.Next()) { |
4e57c75e |
614 | TopoDS_Shape aResShape = anExp.Current(); |
615 | |
616 | if(theFace1.Orientation() == aResShape.Orientation()) { |
617 | AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap); |
618 | |
619 | if(bReverseFlag) |
620 | aResShape.Reverse(); |
621 | AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap); |
622 | } |
623 | else if(theFace2.Orientation() == aResShape.Orientation()) { |
624 | AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap); |
625 | |
626 | if(bReverseFlag) |
627 | aResShape.Reverse(); |
628 | AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap); |
629 | } |
630 | else { |
631 | aResShape.Orientation(theFace1.Orientation()); |
632 | AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap); |
633 | aResShape.Orientation(theFace2.Orientation()); |
634 | |
635 | if(bReverseFlag) |
636 | aResShape.Reverse(); |
637 | AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap); |
638 | } |
7fd59977 |
639 | } |
640 | } |
641 | // fill face history.end |
642 | } |
643 | { |
644 | BRepAlgoAPI_Cut aCut1(theFace1, theFace2, aDSFiller); |
645 | |
646 | if(!aCut1.IsDone()) |
647 | return Standard_False; |
648 | TopExp::MapShapes(aCut1.Shape(), TopAbs_VERTEX, aMapV); |
649 | // fill edge history.begin |
650 | FillEdgeHistoryMap(aCut1, theHistoryMap); |
651 | // fill edge history.end |
652 | |
653 | // fill face history.begin |
654 | TopExp_Explorer anExp(aCut1.Shape(), TopAbs_FACE); |
655 | |
656 | for(; anExp.More(); anExp.Next()) { |
657 | TopoDS_Shape aResShape = anExp.Current(); |
658 | aResShape.Orientation(theFace1.Orientation()); |
659 | AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap); |
660 | } |
661 | // fill face history.end |
662 | } |
663 | |
664 | { |
665 | BRepAlgoAPI_Cut aCut2(theFace1, theFace2, aDSFiller, Standard_False); |
666 | |
667 | if(!aCut2.IsDone()) |
668 | return Standard_False; |
669 | TopExp::MapShapes(aCut2.Shape(), TopAbs_VERTEX, aMapV); |
670 | // fill edge history.begin |
671 | FillEdgeHistoryMap(aCut2, theHistoryMap); |
672 | // fill edge history.end |
673 | |
674 | // fill face history.begin |
675 | TopExp_Explorer anExp(aCut2.Shape(), TopAbs_FACE); |
676 | |
677 | for(; anExp.More(); anExp.Next()) { |
678 | TopoDS_Shape aResShape = anExp.Current(); |
679 | aResShape.Orientation(theFace2.Orientation()); |
680 | AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap); |
681 | } |
682 | // fill face history.end |
683 | } |
684 | |
685 | // fill vertex history.begin |
4e57c75e |
686 | BOPDS_VectorOfInterfVV& aVVs = pDS->InterfVV(); |
7fd59977 |
687 | aNb = aVVs.Extent(); |
688 | |
4e57c75e |
689 | for (i = 0; i < aNb; ++i) { |
690 | BOPDS_InterfVV& aVVi = aVVs(i); |
691 | if (!aVVi.HasIndexNew()) { |
7fd59977 |
692 | continue; |
4e57c75e |
693 | } |
694 | Standard_Integer aNewShapeIndex = aVVi.IndexNew(); |
7fd59977 |
695 | |
4e57c75e |
696 | const TopoDS_Shape& aNewVertex = pDS->Shape(aNewShapeIndex); |
697 | |
698 | if(!aMapV.Contains(aNewVertex)) { |
7fd59977 |
699 | continue; |
4e57c75e |
700 | } |
701 | |
702 | const TopoDS_Shape& aV1 = pDS->Shape(aVVi.Index1()); |
703 | const TopoDS_Shape& aV2 = pDS->Shape(aVVi.Index2()); |
7fd59977 |
704 | AddShapeToHistoryMap(aV1, aNewVertex, theHistoryMap); |
705 | AddShapeToHistoryMap(aV2, aNewVertex, theHistoryMap); |
706 | } |
7fd59977 |
707 | |
4e57c75e |
708 | BOPDS_VectorOfInterfVE& aVEs = pDS->InterfVE(); |
709 | aNb = aVEs.Extent(); |
7fd59977 |
710 | |
4e57c75e |
711 | for (i = 0; i < aNb; ++i) { |
712 | BOPDS_InterfVE& aVEi = aVEs(i); |
713 | |
714 | Standard_Integer anIndex = aVEi.Index1(); |
715 | const TopoDS_Shape& aNewVertex = pDS->Shape(anIndex); |
7fd59977 |
716 | |
717 | if(!aMapV.Contains(aNewVertex)) |
718 | continue; |
7fd59977 |
719 | |
4e57c75e |
720 | AddShapeToHistoryMap(aNewVertex, aNewVertex, theHistoryMap); |
7fd59977 |
721 | } |
4e57c75e |
722 | |
723 | BOPDS_VectorOfInterfVF& aVSs = pDS->InterfVF(); |
7fd59977 |
724 | aNb = aVSs.Extent(); |
725 | |
4e57c75e |
726 | for (i = 0; i < aNb; ++i) { |
727 | BOPDS_InterfVF& aVSi = aVSs(i); |
7fd59977 |
728 | |
4e57c75e |
729 | Standard_Integer anIndex = aVSi.Index1(); |
730 | const TopoDS_Shape& aNewVertex = pDS->Shape(anIndex); |
7fd59977 |
731 | |
732 | if(!aMapV.Contains(aNewVertex)) |
733 | continue; |
7fd59977 |
734 | |
4e57c75e |
735 | AddShapeToHistoryMap(aNewVertex, aNewVertex, theHistoryMap); |
7fd59977 |
736 | } |
737 | // fill vertex history.end |
738 | return Standard_True; |
739 | } |
740 | |
7fd59977 |
741 | // -------------------------------------------------------------------------------------------- |
742 | // static function: AddShapeToHistoryMap |
743 | // purpose: |
744 | // -------------------------------------------------------------------------------------------- |
745 | Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape, |
4e57c75e |
746 | const TopoDS_Shape& theNewShape, |
747 | TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) { |
7fd59977 |
748 | |
749 | if(!theHistoryMap.Contains(theOldShape)) { |
750 | TopTools_ListOfShape aList; |
751 | aList.Append(theNewShape); |
752 | theHistoryMap.Add(theOldShape, aList); |
753 | return Standard_True; |
754 | } |
755 | |
756 | Standard_Boolean found = Standard_False; |
757 | TopTools_ListOfShape& aList = theHistoryMap.ChangeFromKey(theOldShape); |
758 | TopTools_ListIteratorOfListOfShape aVIt(aList); |
759 | |
760 | for(; aVIt.More(); aVIt.Next()) { |
761 | if(theNewShape.IsSame(aVIt.Value())) { |
762 | found = Standard_True; |
763 | break; |
764 | } |
765 | } |
766 | |
767 | if(!found) { |
768 | aList.Append(theNewShape); |
769 | } |
770 | return !found; |
771 | } |
772 | |
773 | // -------------------------------------------------------------------------------------------- |
774 | // static function: FillEdgeHistoryMap |
775 | // purpose: |
776 | // -------------------------------------------------------------------------------------------- |
777 | void FillEdgeHistoryMap(BRepAlgoAPI_BooleanOperation& theBOP, |
4e57c75e |
778 | TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) { |
7fd59977 |
779 | |
780 | TopExp_Explorer anExp; |
781 | anExp.Init(theBOP.Shape1(), TopAbs_EDGE); |
782 | |
783 | for(; anExp.More(); anExp.Next()) { |
784 | const TopTools_ListOfShape& aList = theBOP.Modified(anExp.Current()); |
785 | TopTools_ListIteratorOfListOfShape anIt(aList); |
786 | |
787 | for(; anIt.More(); anIt.Next()) { |
788 | AddShapeToHistoryMap(anExp.Current(), anIt.Value(), theHistoryMap); |
789 | } |
790 | } |
791 | |
792 | anExp.Init(theBOP.Shape2(), TopAbs_EDGE); |
793 | |
794 | for(; anExp.More(); anExp.Next()) { |
795 | const TopTools_ListOfShape& aList = theBOP.Modified(anExp.Current()); |
796 | TopTools_ListIteratorOfListOfShape anIt(aList); |
797 | |
798 | for(; anIt.More(); anIt.Next()) { |
799 | AddShapeToHistoryMap(anExp.Current(), anIt.Value(), theHistoryMap); |
800 | } |
801 | } |
802 | } |
803 | |
804 | // -------------------------------------------------------------------------------------------- |
805 | // static function: SortVertexOnEdge |
806 | // purpose: |
807 | // -------------------------------------------------------------------------------------------- |
808 | void SortVertexOnEdge(const TopoDS_Edge& theEdge, |
4e57c75e |
809 | const TopTools_ListOfShape& theListOfVertex, |
810 | TopTools_ListOfShape& theListOfVertexSorted) { |
7fd59977 |
811 | |
812 | TopTools_DataMapOfIntegerShape mapiv;// mapiv.Find(iV) = V |
813 | TColStd_IndexedMapOfReal mappar; // mappar.FindIndex(parV) = iV |
814 | TopTools_ListIteratorOfListOfShape itlove(theListOfVertex); |
815 | |
816 | for (; itlove.More(); itlove.Next()){ |
817 | const TopoDS_Vertex& v = TopoDS::Vertex(itlove.Value()); |
818 | Standard_Real par = BRep_Tool::Parameter(v, theEdge); |
819 | Standard_Integer iv = mappar.Add(par); |
820 | mapiv.Bind(iv,v); |
821 | } |
822 | Standard_Integer nv = mapiv.Extent(); |
823 | TColStd_Array1OfReal tabpar(1,nv); |
824 | Standard_Integer i = 0; |
825 | |
826 | for ( i = 1; i <= nv; i++) { |
827 | Standard_Real p = mappar.FindKey(i); |
828 | tabpar.SetValue(i,p); |
829 | } |
830 | theListOfVertexSorted.Clear(); |
831 | TCollection_CompareOfReal compare; |
832 | SortTools_QuickSortOfReal::Sort(tabpar, compare); |
833 | |
834 | for (i = 1; i <= nv; i++) { |
835 | Standard_Real par = tabpar.Value(i); |
836 | Standard_Integer iv = mappar.FindIndex(par); |
837 | const TopoDS_Shape& v = mapiv.Find(iv); |
838 | theListOfVertexSorted.Append(v); |
839 | } |
840 | } |
4e57c75e |
841 | |
842 | // -------------------------------------------------------------------------------------------- |
843 | // static function: GetEdgeState |
844 | // purpose: |
845 | // -------------------------------------------------------------------------------------------- |
846 | static TopAbs_State GetEdgeState(const BOPDS_PDS& pDS, |
847 | const Handle(BOPDS_PaveBlock)& aPB) |
848 | { |
849 | Standard_Integer j, aNbFI; |
850 | Standard_Boolean bIn; |
851 | TopAbs_State aState = TopAbs_ON; |
852 | // |
853 | const BOPDS_VectorOfFaceInfo& aVFI = pDS->FaceInfoPool(); |
854 | aNbFI = aVFI.Extent(); |
855 | // |
856 | for (j = 0; j < aNbFI; ++j) { |
857 | const BOPDS_FaceInfo& aFI = aVFI(j); |
858 | bIn = aFI.PaveBlocksIn().Contains(aPB); |
859 | if (bIn) { |
860 | aState = TopAbs_IN; |
861 | break; |
862 | } |
863 | } |
864 | return aState; |
865 | } |