Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-05-07 |
2 | // Created by: Jean Yves LEBEY | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
17 | #include <TopOpeBRep_ShapeIntersector.ixx> | |
18 | ||
19 | #include <TopAbs.hxx> | |
20 | #include <Bnd_Box.hxx> | |
21 | #include <TopOpeBRepTool_box.hxx> | |
22 | #include <TopOpeBRep_define.hxx> | |
23 | ||
24 | #ifdef DEB | |
1d0a9d4d | 25 | extern Standard_Boolean TopOpeBRep_GettraceSI(); |
26 | extern Standard_Boolean TopOpeBRep_GetcontextFFOR(); | |
27 | extern Standard_Integer SAVFFi1; // FacesIntersector | |
28 | extern Standard_Integer SAVFFi2; // FacesIntersector | |
29 | extern void TopOpeBRep_SettraceEEFF(const Standard_Boolean b); | |
30 | extern Standard_Boolean TopOpeBRep_GettraceEEFF(const Standard_Integer e1,const Standard_Integer e2,const Standard_Integer f1,const Standard_Integer f2); | |
7fd59977 | 31 | void seteeff(const Standard_Boolean b,const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) |
32 | {cout<<"b,e1,e2,f1,f2 : "<<b<<" "<<e1<<","<<e2<<","<<f1<<","<<f2<<endl;TopOpeBRep_SettraceEEFF(b);} | |
33 | void seteefft(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_True,e1,e2,f1,f2);} | |
34 | void seteefff(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_False,e1,e2,f1,f2);} | |
35 | #endif | |
36 | ||
37 | // modified by NIZHNY-OFV Thu Apr 18 17:15:38 2002 (S) | |
38 | #include <TopoDS.hxx> | |
39 | #include <TopoDS_Shape.hxx> | |
40 | #include <TopoDS_Solid.hxx> | |
41 | #include <TopoDS_Shell.hxx> | |
42 | #include <TopoDS_Face.hxx> | |
43 | #include <TopoDS_Wire.hxx> | |
44 | #include <TopoDS_Edge.hxx> | |
45 | #include <TopExp_Explorer.hxx> | |
46 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
47 | #include <TopTools_ListOfShape.hxx> | |
48 | #include <TopExp.hxx> | |
49 | #include <gp_Pnt.hxx> | |
50 | #include <gp_Vec.hxx> | |
51 | #include <BRepLib_MakeEdge.hxx> | |
52 | #include <BRepLib_MakeWire.hxx> | |
53 | #include <BRepLib_MakeFace.hxx> | |
54 | #include <BRep_Builder.hxx> | |
55 | #include <BRepAdaptor_Surface.hxx> | |
56 | static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2); | |
57 | static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F); | |
58 | // modified by NIZHNY-OFV Thu Apr 18 17:16:45 2002 (F) | |
59 | ||
60 | //======================================================================= | |
61 | //function : TopOpeBRep_ShapeIntersector | |
62 | //purpose : | |
63 | //======================================================================= | |
64 | ||
65 | TopOpeBRep_ShapeIntersector::TopOpeBRep_ShapeIntersector() | |
66 | { | |
67 | Reset(); | |
68 | myFFIntersector.GetTolerances(myTol1,myTol2); | |
69 | myHBoxTool = FBOX_GetHBoxTool(); | |
70 | myFaceScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool); | |
71 | myEdgeScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool); | |
72 | } | |
73 | ||
74 | //======================================================================= | |
75 | //function : Reset | |
76 | //purpose : | |
77 | //======================================================================= | |
78 | ||
79 | void TopOpeBRep_ShapeIntersector::Reset() | |
80 | { | |
81 | myIntersectionDone = Standard_False; | |
82 | ||
83 | myFFDone = Standard_False; | |
84 | myFFSameDomain = Standard_False; | |
85 | myEEFFDone = Standard_False; | |
86 | myEFDone = Standard_False; | |
87 | myFEDone = Standard_False; | |
88 | myEEDone = Standard_False; | |
89 | ||
90 | myFFInit = Standard_False; | |
91 | myEEFFInit = Standard_False; | |
92 | myEFInit = Standard_False; | |
93 | myFEInit = Standard_False; | |
94 | myEEInit = Standard_False; | |
95 | } | |
96 | ||
97 | //======================================================================= | |
98 | //function : Init | |
99 | //purpose : | |
100 | //======================================================================= | |
101 | ||
102 | void TopOpeBRep_ShapeIntersector::Init | |
103 | (const TopoDS_Shape& S1, const TopoDS_Shape& S2) | |
104 | { | |
105 | Reset(); | |
106 | myShape1 = S1; | |
107 | myShape2 = S2; | |
108 | } | |
109 | ||
110 | //======================================================================= | |
111 | //function : SetIntersectionDone | |
112 | //purpose : | |
113 | //======================================================================= | |
114 | ||
115 | void TopOpeBRep_ShapeIntersector::SetIntersectionDone() | |
116 | { | |
117 | myIntersectionDone = (myFFDone || | |
118 | myEEFFDone || | |
119 | myFEDone || | |
120 | myEFDone || | |
121 | myEEDone); | |
122 | } | |
123 | ||
124 | ||
125 | //======================================================================= | |
126 | //function : CurrentGeomShape | |
127 | //purpose : | |
128 | //======================================================================= | |
129 | ||
130 | const TopoDS_Shape& TopOpeBRep_ShapeIntersector::CurrentGeomShape | |
131 | (const Standard_Integer Index) const | |
132 | { | |
133 | if ( myIntersectionDone ) { | |
134 | if (myFFDone) { | |
135 | if ( Index == 1 ) return myFaceScanner.Current(); | |
136 | else if ( Index == 2 ) return myFaceExplorer.Current(); | |
137 | } | |
138 | else if (myEEFFDone) { | |
139 | if ( Index == 1 ) return myEdgeScanner.Current(); | |
140 | else if ( Index == 2 ) return myEdgeExplorer.Current(); | |
141 | } | |
142 | else if (myFEDone) { | |
143 | if ( Index == 1 ) return myFaceScanner.Current(); | |
144 | else if ( Index == 2 ) return myEdgeExplorer.Current(); | |
145 | } | |
146 | else if (myEFDone) { | |
147 | if ( Index == 1 ) return myEdgeScanner.Current(); | |
148 | else if ( Index == 2 ) return myFaceExplorer.Current(); | |
149 | } | |
150 | else if (myEEDone) { | |
151 | if ( Index == 1 ) return myEdgeScanner.Current(); | |
152 | else if ( Index == 2 ) return myEdgeExplorer.Current(); | |
153 | } | |
154 | } | |
155 | ||
156 | Standard_Failure::Raise("CurrentGeomShape : no intersection"); | |
157 | TopoDS_Shape* bid = new TopoDS_Shape(); | |
158 | return *bid; | |
159 | } | |
160 | //modified by NIZNHY-PKV Fri Sep 24 11:02:59 1999 from | |
161 | //======================================================================= | |
162 | //function : RejectedFaces | |
163 | //purpose : | |
164 | //======================================================================= | |
165 | void TopOpeBRep_ShapeIntersector::RejectedFaces (const TopoDS_Shape& anObj, | |
166 | const TopoDS_Shape& aReference, | |
167 | TopTools_ListOfShape& aListOfShape) | |
168 | { | |
169 | ||
170 | Standard_Integer isHalfSpace = OneShapeIsHalfSpace( anObj, aReference ); | |
171 | if( isHalfSpace != 0 ) | |
172 | { | |
173 | TopoDS_Face newRejectFace; | |
174 | TopoDS_Solid newSolid; | |
175 | aListOfShape.Clear(); | |
176 | ||
177 | if( isHalfSpace == 1 ) | |
178 | { | |
179 | newSolid = GetNewSolid( anObj, newRejectFace ); | |
180 | Init( newSolid, aReference ); | |
181 | ||
182 | TopAbs_ShapeEnum tscann = TopAbs_SOLID; | |
183 | TopAbs_ShapeEnum texplo = TopAbs_FACE; | |
184 | myFaceScanner.Clear(); | |
185 | myFaceScanner.AddBoxesMakeCOB( aReference, tscann ); | |
186 | myFaceExplorer.Init( newSolid, texplo ); | |
187 | ||
188 | for(; myFaceExplorer.More(); myFaceExplorer.Next()) | |
189 | { | |
190 | TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort(); | |
191 | if(!aBS.Compare(myFaceExplorer.Current()).More()) | |
192 | { | |
193 | const TopoDS_Shape& aS=myFaceExplorer.Current(); | |
194 | aListOfShape.Append (aS); | |
195 | } | |
196 | } | |
197 | ||
198 | texplo = TopAbs_EDGE; | |
199 | myFaceScanner.Clear(); | |
200 | myFaceScanner.AddBoxesMakeCOB( aReference, tscann ); | |
201 | myFaceExplorer.Init( newSolid, texplo ); | |
202 | ||
203 | for(; myFaceExplorer.More(); myFaceExplorer.Next()) | |
204 | { | |
205 | TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort(); | |
206 | if(!aBS.Compare(myFaceExplorer.Current()).More()) | |
207 | { | |
208 | const TopoDS_Shape& aS=myFaceExplorer.Current(); | |
209 | aListOfShape.Append (aS); | |
210 | } | |
211 | } | |
212 | } | |
213 | else | |
214 | { | |
215 | newSolid = GetNewSolid( aReference, newRejectFace ); | |
216 | Init( anObj, newSolid ); | |
217 | ||
218 | TopAbs_ShapeEnum tscann = TopAbs_SOLID; | |
219 | TopAbs_ShapeEnum texplo = TopAbs_FACE; | |
220 | myFaceScanner.Clear(); | |
221 | myFaceScanner.AddBoxesMakeCOB( newSolid, tscann ); | |
222 | myFaceExplorer.Init( anObj, texplo); | |
223 | ||
224 | for(; myFaceExplorer.More(); myFaceExplorer.Next()) | |
225 | { | |
226 | TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort(); | |
227 | if(!aBS.Compare(myFaceExplorer.Current()).More()) | |
228 | { | |
229 | const TopoDS_Shape& aS=myFaceExplorer.Current(); | |
230 | aListOfShape.Append (aS); | |
231 | } | |
232 | } | |
233 | ||
234 | texplo = TopAbs_EDGE; | |
235 | myFaceScanner.Clear(); | |
236 | myFaceScanner.AddBoxesMakeCOB( newSolid, tscann ); | |
237 | myFaceExplorer.Init( anObj, texplo ); | |
238 | ||
239 | for(; myFaceExplorer.More(); myFaceExplorer.Next()) | |
240 | { | |
241 | TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort(); | |
242 | if(!aBS.Compare(myFaceExplorer.Current()).More()) | |
243 | { | |
244 | const TopoDS_Shape& aS=myFaceExplorer.Current(); | |
245 | aListOfShape.Append (aS); | |
246 | } | |
247 | } | |
248 | } | |
249 | // remove all shapes of < newRejectFace > from list | |
250 | TopExp_Explorer ExpRF(newRejectFace, TopAbs_EDGE); | |
251 | for(; ExpRF.More(); ExpRF.Next() ) | |
252 | { | |
253 | const TopoDS_Edge& edgef = TopoDS::Edge( ExpRF.Current() ); | |
254 | TopTools_ListIteratorOfListOfShape it( aListOfShape ); | |
255 | for(; it.More(); it.Next() ) | |
256 | { | |
257 | const TopoDS_Shape& shape = it.Value(); | |
258 | ||
259 | if( shape.ShapeType() != TopAbs_EDGE ) | |
260 | continue; | |
261 | ||
262 | const TopoDS_Edge& edgel = TopoDS::Edge( shape ); | |
263 | if( edgef.IsSame( edgel ) ) | |
264 | { | |
265 | aListOfShape.Remove(it); | |
266 | break; | |
267 | } | |
268 | } | |
269 | } | |
270 | TopTools_ListIteratorOfListOfShape it( aListOfShape ); | |
271 | for(; it.More(); it.Next() ) | |
272 | { | |
273 | const TopoDS_Shape& shape = it.Value(); | |
274 | ||
275 | if( shape.ShapeType() != TopAbs_FACE ) | |
276 | continue; | |
277 | ||
278 | const TopoDS_Face& facel = TopoDS::Face( shape ); | |
279 | if( facel.IsSame( newRejectFace ) ) | |
280 | { | |
281 | aListOfShape.Remove(it); | |
282 | break; | |
283 | } | |
284 | } | |
285 | ||
286 | Init(anObj, aReference); | |
287 | return; | |
288 | } | |
289 | ||
290 | Init(anObj, aReference); | |
291 | ||
292 | aListOfShape.Clear(); | |
293 | //find faces to reject | |
294 | ||
295 | TopAbs_ShapeEnum tscann = TopAbs_SOLID; | |
296 | TopAbs_ShapeEnum texplo = TopAbs_FACE; | |
297 | myFaceScanner.Clear(); | |
298 | myFaceScanner.AddBoxesMakeCOB(aReference,tscann); | |
299 | myFaceExplorer.Init(anObj,texplo); | |
300 | ||
301 | for(; myFaceExplorer.More(); myFaceExplorer.Next()) { | |
302 | TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort(); | |
303 | if(!aBS.Compare(myFaceExplorer.Current()).More()) { | |
304 | const TopoDS_Shape& aS=myFaceExplorer.Current(); | |
305 | aListOfShape.Append (aS); | |
306 | } | |
307 | } | |
308 | ||
309 | //modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000 | |
310 | texplo = TopAbs_EDGE; | |
311 | myFaceScanner.Clear(); | |
312 | myFaceScanner.AddBoxesMakeCOB(aReference,tscann); | |
313 | myFaceExplorer.Init(anObj,texplo); | |
314 | ||
315 | for(; myFaceExplorer.More(); myFaceExplorer.Next()) { | |
316 | TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort(); | |
317 | if(!aBS.Compare(myFaceExplorer.Current()).More()) { | |
318 | const TopoDS_Shape& aS=myFaceExplorer.Current(); | |
319 | aListOfShape.Append (aS); | |
320 | } | |
321 | } | |
322 | ||
323 | //modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000 | |
324 | /* texplo = TopAbs_VERTEX; | |
325 | myFaceScanner.Clear(); | |
326 | myFaceScanner.AddBoxesMakeCOB(aReference,tscann); | |
327 | myFaceExplorer.Init(anObj,texplo); | |
328 | ||
329 | for(; myFaceExplorer.More(); myFaceExplorer.Next()) { | |
330 | TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort(); | |
331 | if(!aBS.Compare(myFaceExplorer.Current()).More()) { | |
332 | const TopoDS_Shape& aS=myFaceExplorer.Current(); | |
333 | aListOfShape.Append (aS); | |
334 | } | |
335 | } | |
336 | */ | |
337 | } | |
338 | //modified by NIZNHY-PKV Fri Sep 24 11:03:02 1999 to | |
339 | ||
340 | ||
341 | ||
342 | ||
343 | //======================================================================= | |
344 | //function : InitIntersection | |
345 | //purpose : | |
346 | //======================================================================= | |
347 | ||
348 | void TopOpeBRep_ShapeIntersector::InitIntersection (const TopoDS_Shape& S1, const TopoDS_Shape& S2) | |
349 | { | |
350 | Init(S1,S2); | |
351 | ||
352 | InitFFIntersection(); | |
353 | if ( MoreFFCouple() ) return; | |
354 | ||
355 | InitFEIntersection(); | |
356 | if ( MoreFECouple() ) return; | |
357 | ||
358 | InitEFIntersection(); | |
359 | if ( MoreEFCouple() ) return; | |
360 | } | |
361 | ||
362 | ||
363 | //======================================================================= | |
364 | //function : InitIntersection | |
365 | //purpose : | |
366 | //======================================================================= | |
367 | ||
368 | void TopOpeBRep_ShapeIntersector::InitIntersection | |
369 | (const TopoDS_Shape& S1, const TopoDS_Shape& S2, | |
370 | const TopoDS_Face& F1, const TopoDS_Face& F2) | |
371 | { | |
372 | Init(S1,S2); | |
373 | ||
374 | myEEFace1 = F1; | |
375 | myEEFace2 = F2; | |
376 | ||
377 | InitEEIntersection(); | |
378 | } | |
379 | ||
380 | ||
381 | //======================================================================= | |
382 | //function : MoreIntersection | |
383 | //purpose : | |
384 | //======================================================================= | |
385 | ||
386 | Standard_Boolean TopOpeBRep_ShapeIntersector::MoreIntersection() const | |
387 | { | |
388 | Standard_Boolean res = myIntersectionDone; | |
389 | ||
390 | #ifdef DEB | |
7fd59977 | 391 | if (TopOpeBRep_GettraceSI() && res) { |
392 | if ( myFFDone ) cout<<"FF : "; | |
393 | else if ( myEEFFDone ) cout<<" EE : "; | |
394 | DumpCurrent(1); | |
395 | DumpCurrent(2); | |
396 | if ( myFFDone && myFFSameDomain ) cout<<"(FF SameDomain)"; | |
397 | else if ( myEEFFDone ) cout<<"(EE of FF SameDomain)"; | |
398 | else if ( myEEDone ) cout<<"EE : "; | |
399 | cout<<endl; | |
400 | if (myEEFFDone) { | |
401 | Standard_Integer ie1 = myEdgeScanner.Index(); | |
402 | Standard_Integer ie2 = myEdgeExplorer.Index(); | |
403 | Standard_Integer if1 = myFaceScanner.Index(); | |
404 | Standard_Integer if2 = myFaceExplorer.Index(); | |
405 | cout<<" trc teeff 1 "<<ie1<<" "<<ie2<<" "<<if1<<" "<<if2<<"; # ie1 ie2 if1 if2"<<endl; | |
406 | Standard_Boolean b = TopOpeBRep_GettraceEEFF(ie1,ie2,if1,if2); | |
407 | if (b) seteefft(ie1,ie2,if1,if2); | |
408 | else seteefff(ie1,ie2,if1,if2); | |
409 | } | |
410 | } | |
411 | #endif | |
412 | ||
413 | return res; | |
414 | } | |
415 | ||
416 | ||
417 | //======================================================================= | |
418 | //function : DumpCurrent | |
419 | //purpose : | |
420 | //======================================================================= | |
421 | ||
498ce76b | 422 | #ifdef DEB |
7fd59977 | 423 | void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer K) const |
424 | { | |
7fd59977 | 425 | if ( myFFDone ) { |
426 | if ( K == 1 ) myFaceScanner.DumpCurrent(cout); | |
427 | else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout); | |
428 | } | |
429 | else if ( myEEFFDone ) { | |
430 | if ( K == 1 ) myEdgeScanner.DumpCurrent(cout); | |
431 | else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout); | |
432 | } | |
433 | else if ( myFEDone ) { | |
434 | if ( K == 1 ) myFaceScanner.DumpCurrent(cout); | |
435 | else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout); | |
436 | } | |
437 | else if ( myEFDone ) { | |
438 | if ( K == 1 ) myEdgeScanner.DumpCurrent(cout); | |
439 | else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout); | |
440 | } | |
441 | else if ( myEEDone ) { | |
442 | if ( K == 1 ) myEdgeScanner.DumpCurrent(cout); | |
443 | else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout); | |
444 | } | |
7fd59977 | 445 | } |
498ce76b | 446 | #else |
447 | void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer) const {} | |
448 | #endif | |
7fd59977 | 449 | |
450 | //======================================================================= | |
451 | //function : Index | |
452 | //purpose : | |
453 | //======================================================================= | |
454 | ||
498ce76b | 455 | #ifdef DEB |
7fd59977 | 456 | Standard_Integer TopOpeBRep_ShapeIntersector::Index |
457 | (const Standard_Integer K)const | |
458 | { | |
459 | Standard_Integer i = 0; | |
498ce76b | 460 | |
7fd59977 | 461 | if ( myFFDone ) { |
462 | if ( K == 1 ) i = myFaceScanner.Index(); | |
463 | else if ( K == 2 ) i = myFaceExplorer.Index(); | |
464 | } | |
465 | else if ( myEEFFDone ) { | |
466 | if ( K == 1 ) i = myEdgeScanner.Index(); | |
467 | else if ( K == 2 ) i = myEdgeExplorer.Index(); | |
468 | } | |
469 | else if ( myFEDone ) { | |
470 | if ( K == 1 ) i = myFaceScanner.Index(); | |
471 | else if ( K == 2 ) i = myEdgeExplorer.Index(); | |
472 | } | |
473 | else if ( myEFDone ) { | |
474 | if ( K == 1 ) i = myEdgeScanner.Index(); | |
475 | else if ( K == 2 ) i = myFaceExplorer.Index(); | |
476 | } | |
477 | else if ( myEEDone ) { | |
478 | if ( K == 1 ) i = myEdgeScanner.Index(); | |
479 | else if ( K == 2 ) i = myEdgeExplorer.Index(); | |
480 | } | |
7fd59977 | 481 | return i; |
482 | } | |
498ce76b | 483 | #else |
484 | Standard_Integer TopOpeBRep_ShapeIntersector::Index (const Standard_Integer)const | |
485 | { | |
486 | return 0; | |
487 | } | |
488 | #endif | |
7fd59977 | 489 | |
490 | ||
491 | //======================================================================= | |
492 | //function : NextIntersection | |
493 | //purpose : | |
494 | //======================================================================= | |
495 | ||
496 | void TopOpeBRep_ShapeIntersector::NextIntersection() | |
497 | { | |
498 | myIntersectionDone = Standard_False; | |
499 | ||
500 | if (myFFSameDomain) { | |
501 | // precedant etat du More() : 2 faces samedomain | |
502 | myFFDone = Standard_False; | |
503 | myFFSameDomain = Standard_False; | |
504 | InitEEFFIntersection(); | |
505 | FindEEFFIntersection(); | |
506 | if ( !myIntersectionDone ) { | |
507 | NextFFCouple(); | |
508 | FindFFIntersection(); | |
509 | } | |
510 | } | |
511 | else if (myFFDone) { | |
512 | NextFFCouple(); | |
513 | FindFFIntersection(); | |
514 | } | |
515 | else if ( myEEFFDone ) { | |
516 | NextEEFFCouple(); | |
517 | FindEEFFIntersection(); | |
518 | if ( !myIntersectionDone ) { | |
519 | NextFFCouple(); | |
520 | FindFFIntersection(); | |
521 | } | |
522 | } | |
523 | else if ( myFEDone ) { | |
524 | NextFECouple(); | |
525 | FindFEIntersection(); | |
526 | } | |
527 | else if ( myEFDone ) { | |
528 | NextEFCouple(); | |
529 | FindEFIntersection(); | |
530 | } | |
531 | else if ( myEEDone ) { | |
532 | NextEECouple(); | |
533 | FindEEIntersection(); | |
534 | } | |
535 | ||
536 | if ( !myIntersectionDone ) { | |
537 | InitFFIntersection(); | |
538 | } | |
539 | ||
540 | if ( !myIntersectionDone ) { | |
541 | InitFEIntersection(); | |
542 | } | |
543 | ||
544 | if ( !myIntersectionDone ) { | |
545 | InitEFIntersection(); | |
546 | } | |
547 | ||
548 | if ( !myIntersectionDone ) { | |
549 | if ( !myEEFace1.IsNull() && !myEEFace2.IsNull() ) { | |
550 | InitEEIntersection(); | |
551 | } | |
552 | } | |
553 | ||
554 | } | |
555 | ||
556 | ||
557 | // ======== | |
558 | // FFFFFFFF | |
559 | // ======== | |
560 | ||
561 | ||
562 | //======================================================================= | |
563 | //function : InitFFIntersection | |
564 | //purpose : | |
565 | //======================================================================= | |
566 | ||
567 | void TopOpeBRep_ShapeIntersector::InitFFIntersection() | |
568 | { | |
569 | if ( !myFFInit) { | |
570 | TopAbs_ShapeEnum tscann = TopAbs_FACE; | |
571 | TopAbs_ShapeEnum texplo = TopAbs_FACE; | |
572 | myFaceScanner.Clear(); | |
573 | myFaceScanner.AddBoxesMakeCOB(myShape1,tscann); | |
574 | myFaceExplorer.Init(myShape2,texplo); | |
575 | myFaceScanner.Init(myFaceExplorer); | |
576 | FindFFIntersection(); | |
577 | } | |
578 | myFFInit = Standard_True; | |
579 | } | |
580 | ||
581 | ||
582 | //======================================================================= | |
583 | //function : FindFFIntersection | |
584 | //purpose : | |
585 | //======================================================================= | |
586 | ||
587 | void TopOpeBRep_ShapeIntersector::FindFFIntersection() | |
588 | { | |
589 | myFFDone = Standard_False; | |
590 | myFFSameDomain = Standard_False ; | |
591 | ||
592 | while ( MoreFFCouple() ) { | |
593 | ||
594 | // The two candidate intersecting GeomShapes GS1,GS2 and their types t1,t2 | |
595 | const TopoDS_Shape& GS1 = myFaceScanner.Current(); | |
596 | const TopoDS_Shape& GS2 = myFaceExplorer.Current(); | |
597 | ||
598 | #ifdef DEB | |
599 | SAVFFi1 = myFaceScanner.Index(); SAVFFi2 = myFaceExplorer.Index(); | |
600 | if (TopOpeBRep_GettraceSI()) { | |
7fd59977 | 601 | cout<<"?? FF : "; |
602 | myFaceScanner.DumpCurrent(cout); myFaceExplorer.DumpCurrent(cout); | |
603 | cout<<endl; | |
604 | } | |
605 | #endif | |
606 | ||
607 | const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort(); | |
608 | const Bnd_Box& B1 = BS.Box(GS1); | |
609 | const Bnd_Box& B2 = BS.Box(GS2); | |
610 | myFFIntersector.Perform(GS1,GS2,B1,B2); | |
611 | Standard_Boolean ok = myFFIntersector.IsDone(); //xpu210998 | |
612 | if (!ok) { | |
613 | NextFFCouple(); | |
614 | continue; | |
615 | } | |
616 | ||
617 | myFFSameDomain = myFFIntersector.SameDomain(); | |
618 | ||
619 | if (myFFSameDomain) { | |
620 | myFFDone = Standard_True; | |
621 | break; | |
622 | } | |
623 | else { | |
624 | myFFDone = ! (myFFIntersector.IsEmpty()); | |
625 | ||
626 | // update face/face intersection tolerances | |
627 | if (myFFDone) { | |
628 | Standard_Real tol1,tol2; | |
629 | myFFIntersector.GetTolerances(tol1,tol2); | |
630 | myTol1 = Max(myTol1,tol1); myTol2 = Max(myTol2,tol2); | |
631 | } | |
632 | ||
633 | if ( myFFDone ) { | |
634 | break; | |
635 | } | |
636 | } | |
637 | ||
638 | NextFFCouple(); | |
639 | } | |
640 | ||
641 | SetIntersectionDone(); | |
642 | } | |
643 | ||
644 | ||
645 | //======================================================================= | |
646 | //function : MoreFFCouple | |
647 | //purpose : | |
648 | //======================================================================= | |
649 | ||
650 | Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFFCouple() const | |
651 | { | |
652 | Standard_Boolean more1 = myFaceScanner.More(); | |
653 | Standard_Boolean more2 = myFaceExplorer.More(); | |
654 | return (more1 && more2); | |
655 | } | |
656 | ||
657 | ||
658 | //======================================================================= | |
659 | //function : NextFFCouple | |
660 | //purpose : | |
661 | //======================================================================= | |
662 | ||
663 | void TopOpeBRep_ShapeIntersector::NextFFCouple() | |
664 | { | |
665 | myFaceScanner.Next(); | |
666 | Standard_Boolean b1,b2; | |
667 | ||
668 | b1 = (!myFaceScanner.More()); | |
669 | b2 = (myFaceExplorer.More()); | |
670 | while ( b1 && b2 ) { | |
671 | myFaceExplorer.Next(); | |
672 | myFaceScanner.Init(myFaceExplorer); | |
673 | b1 = (!myFaceScanner.More()); | |
674 | b2 = (myFaceExplorer.More()); | |
675 | } | |
676 | ||
677 | } | |
678 | ||
679 | ||
680 | // ======== | |
681 | // EEFFEEFF | |
682 | // ======== | |
683 | ||
684 | ||
685 | //======================================================================= | |
686 | //function : InitEEFFIntersection | |
687 | //purpose : | |
688 | //======================================================================= | |
689 | ||
690 | void TopOpeBRep_ShapeIntersector::InitEEFFIntersection() | |
691 | { | |
692 | // prepare exploration of the edges of the two current SameDomain faces | |
693 | TopoDS_Shape face1 = myFaceScanner.Current(); // -26-08-96 | |
694 | TopoDS_Shape face2 = myFaceExplorer.Current(); // -26-08-96 | |
695 | ||
696 | #ifdef DEB | |
697 | if (TopOpeBRep_GetcontextFFOR()) { | |
698 | face1.Orientation(TopAbs_FORWARD); //-05/07 | |
699 | face2.Orientation(TopAbs_FORWARD); //-05/07 | |
700 | cout<<"ctx : InitEEFFIntersection : faces FORWARD"<<endl; | |
701 | } | |
702 | #endif | |
703 | ||
704 | const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort(); | |
705 | const Bnd_Box& B1 = BS.Box(face1); | |
706 | const Bnd_Box& B2 = BS.Box(face2); | |
707 | myEEIntersector.SetFaces(face1,face2,B1,B2); | |
708 | ||
709 | TopAbs_ShapeEnum tscann = TopAbs_EDGE; | |
710 | TopAbs_ShapeEnum texplo = TopAbs_EDGE; | |
711 | myEdgeScanner.Clear(); | |
712 | myEdgeScanner.AddBoxesMakeCOB(face1,tscann); | |
713 | myEdgeExplorer.Init(face2,texplo); | |
714 | myEdgeScanner.Init(myEdgeExplorer); | |
715 | ||
716 | myEEFFInit = Standard_True; | |
717 | } | |
718 | ||
719 | ||
720 | //======================================================================= | |
721 | //function : FindEEFFIntersection | |
722 | //purpose : | |
723 | //======================================================================= | |
724 | ||
725 | void TopOpeBRep_ShapeIntersector::FindEEFFIntersection() | |
726 | { | |
727 | myEEFFDone = Standard_False; | |
728 | while ( MoreEEFFCouple() ) { | |
729 | const TopoDS_Shape& GS1 = myEdgeScanner.Current(); | |
730 | const TopoDS_Shape& GS2 = myEdgeExplorer.Current(); | |
731 | myEEIntersector.Perform(GS1,GS2); | |
732 | ||
733 | #ifdef DEB | |
7fd59977 | 734 | if (TopOpeBRep_GettraceSI() && myEEIntersector.IsEmpty()) { |
735 | cout<<" EE : "; | |
736 | myEdgeScanner.DumpCurrent(cout); | |
737 | myEdgeExplorer.DumpCurrent(cout); | |
738 | cout<<"(EE of FF SameDomain)"; | |
739 | cout<<" : EMPTY INTERSECTION"; | |
740 | cout<<endl; | |
741 | } | |
742 | #endif | |
743 | ||
744 | myEEFFDone = ! (myEEIntersector.IsEmpty()); | |
745 | if (myEEFFDone) break; | |
746 | else NextEEFFCouple(); | |
747 | } | |
748 | SetIntersectionDone(); | |
749 | } | |
750 | ||
751 | ||
752 | //======================================================================= | |
753 | //function : MoreEEFFCouple | |
754 | //purpose : | |
755 | //======================================================================= | |
756 | ||
757 | Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEEFFCouple() const | |
758 | { | |
759 | Standard_Boolean more1 = myEdgeScanner.More(); | |
760 | Standard_Boolean more2 = myEdgeExplorer.More(); | |
761 | return (more1 && more2); | |
762 | } | |
763 | ||
764 | ||
765 | //======================================================================= | |
766 | //function : NextEEFFCouple | |
767 | //purpose : | |
768 | //======================================================================= | |
769 | ||
770 | void TopOpeBRep_ShapeIntersector::NextEEFFCouple() | |
771 | { | |
772 | myEdgeScanner.Next(); | |
773 | while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) { | |
774 | myEdgeExplorer.Next(); | |
775 | myEdgeScanner.Init(myEdgeExplorer); | |
776 | } | |
777 | } | |
778 | ||
779 | ||
780 | // ======== | |
781 | // FEFEFEFE | |
782 | // ======== | |
783 | ||
784 | ||
785 | //======================================================================= | |
786 | //function : InitFEIntersection | |
787 | //purpose : | |
788 | //======================================================================= | |
789 | ||
790 | void TopOpeBRep_ShapeIntersector::InitFEIntersection() | |
791 | { | |
792 | if ( !myFEInit) { | |
793 | TopAbs_ShapeEnum tscann = TopAbs_FACE; | |
794 | TopAbs_ShapeEnum texplo = TopAbs_EDGE; | |
795 | myFaceScanner.Clear(); | |
796 | myFaceScanner.AddBoxesMakeCOB(myShape1,tscann); | |
797 | myEdgeExplorer.Init(myShape2,texplo,TopAbs_FACE); // NYI defaut de spec | |
798 | myFaceScanner.Init(myEdgeExplorer); | |
799 | FindFEIntersection(); | |
800 | } | |
801 | myFEInit = Standard_True; | |
802 | } | |
803 | ||
804 | ||
805 | //======================================================================= | |
806 | //function : FindFEIntersection | |
807 | //purpose : | |
808 | //======================================================================= | |
809 | ||
810 | void TopOpeBRep_ShapeIntersector::FindFEIntersection() | |
811 | { | |
812 | myFEDone = Standard_False; | |
813 | while ( MoreFECouple() ) { | |
814 | const TopoDS_Shape& GS1 = myFaceScanner.Current(); | |
815 | const TopoDS_Shape& GS2 = myEdgeExplorer.Current(); | |
816 | myFEIntersector.Perform(GS1,GS2); | |
817 | myFEDone = ! (myFEIntersector.IsEmpty()); | |
818 | if (myFEDone) break; | |
819 | else NextFECouple(); | |
820 | } | |
821 | SetIntersectionDone(); | |
822 | } | |
823 | ||
824 | ||
825 | //======================================================================= | |
826 | //function : MoreFECouple | |
827 | //purpose : | |
828 | //======================================================================= | |
829 | ||
830 | Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFECouple() const | |
831 | { | |
832 | Standard_Boolean more1 = myFaceScanner.More(); | |
833 | Standard_Boolean more2 = myEdgeExplorer.More(); | |
834 | return (more1 && more2); | |
835 | } | |
836 | ||
837 | ||
838 | //======================================================================= | |
839 | //function : NextFECouple | |
840 | //purpose : | |
841 | //======================================================================= | |
842 | ||
843 | void TopOpeBRep_ShapeIntersector::NextFECouple() | |
844 | { | |
845 | myFaceScanner.Next(); | |
846 | while ( ! myFaceScanner.More() && myEdgeExplorer.More() ) { | |
847 | myEdgeExplorer.Next(); | |
848 | myFaceScanner.Init(myEdgeExplorer); | |
849 | } | |
850 | } | |
851 | ||
852 | ||
853 | // ======== | |
854 | // EFEFEFEF | |
855 | // ======== | |
856 | ||
857 | ||
858 | //======================================================================= | |
859 | //function : InitEFIntersection | |
860 | //purpose : | |
861 | //======================================================================= | |
862 | ||
863 | void TopOpeBRep_ShapeIntersector::InitEFIntersection() | |
864 | { | |
865 | if ( !myEFInit) { | |
866 | TopAbs_ShapeEnum tscann = TopAbs_EDGE; | |
867 | TopAbs_ShapeEnum texplo = TopAbs_FACE; | |
868 | myEdgeScanner.Clear(); | |
869 | myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann, TopAbs_FACE); // NYI defaut de spec | |
870 | myFaceExplorer.Init(myShape2,texplo); | |
871 | myEdgeScanner.Init(myFaceExplorer); | |
872 | FindEFIntersection(); | |
873 | } | |
874 | myEFInit = Standard_True; | |
875 | } | |
876 | ||
877 | //======================================================================= | |
878 | //function : FindEFIntersection | |
879 | //purpose : | |
880 | //======================================================================= | |
881 | ||
882 | void TopOpeBRep_ShapeIntersector::FindEFIntersection() | |
883 | { | |
884 | myEFDone = Standard_False; | |
885 | while ( MoreEFCouple() ) { | |
886 | const TopoDS_Shape& GS1 = myEdgeScanner.Current(); | |
887 | const TopoDS_Shape& GS2 = myFaceExplorer.Current(); | |
888 | myFEIntersector.Perform(GS2,GS1); | |
889 | myEFDone = ! (myFEIntersector.IsEmpty()); | |
890 | if (myEFDone) break; | |
891 | else NextEFCouple(); | |
892 | } | |
893 | SetIntersectionDone(); | |
894 | } | |
895 | ||
896 | ||
897 | //======================================================================= | |
898 | //function : MoreEFCouple | |
899 | //purpose : | |
900 | //======================================================================= | |
901 | ||
902 | Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEFCouple() const | |
903 | { | |
904 | Standard_Boolean more1 = myEdgeScanner.More(); | |
905 | Standard_Boolean more2 = myFaceExplorer.More(); | |
906 | return (more1 && more2); | |
907 | } | |
908 | ||
909 | ||
910 | //======================================================================= | |
911 | //function : NextEFCouple | |
912 | //purpose : | |
913 | //======================================================================= | |
914 | ||
915 | void TopOpeBRep_ShapeIntersector::NextEFCouple() | |
916 | { | |
917 | myEdgeScanner.Next(); | |
918 | while ( ! myEdgeScanner.More() && myFaceExplorer.More() ) { | |
919 | myFaceExplorer.Next(); | |
920 | myEdgeScanner.Init(myFaceExplorer); | |
921 | } | |
922 | } | |
923 | ||
924 | // ======== | |
925 | // EEEEEEEE | |
926 | // ======== | |
927 | ||
928 | //======================================================================= | |
929 | //function : InitEEIntersection | |
930 | //purpose : | |
931 | //======================================================================= | |
932 | ||
933 | void TopOpeBRep_ShapeIntersector::InitEEIntersection() | |
934 | { | |
935 | if ( ! myEEInit ) { | |
936 | TopoDS_Shape face1 = myEEFace1.Oriented(TopAbs_FORWARD); | |
937 | TopoDS_Shape face2 = myEEFace2.Oriented(TopAbs_FORWARD); | |
938 | const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort(); | |
939 | const Bnd_Box& B1 = BS.Box(face1); | |
940 | const Bnd_Box& B2 = BS.Box(face2); | |
941 | myEEIntersector.SetFaces(face1,face2,B1,B2); | |
942 | ||
943 | TopAbs_ShapeEnum tscann = TopAbs_EDGE; | |
944 | TopAbs_ShapeEnum texplo = TopAbs_EDGE; | |
945 | myEdgeScanner.Clear(); | |
946 | myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann); | |
947 | myEdgeExplorer.Init(myShape2,texplo); | |
948 | myEdgeScanner.Init(myEdgeExplorer); | |
949 | FindEEIntersection(); | |
950 | } | |
951 | myEEInit = Standard_True; | |
952 | } | |
953 | ||
954 | ||
955 | //======================================================================= | |
956 | //function : FindEEIntersection | |
957 | //purpose : | |
958 | //======================================================================= | |
959 | ||
960 | void TopOpeBRep_ShapeIntersector::FindEEIntersection() | |
961 | { | |
962 | myEEDone = Standard_False; | |
963 | while ( MoreEECouple() ) { | |
964 | const TopoDS_Shape& GS1 = myEdgeScanner.Current(); | |
965 | const TopoDS_Shape& GS2 = myEdgeExplorer.Current(); | |
966 | myEEIntersector.Perform(GS1,GS2); | |
967 | myEEDone = ! (myEEIntersector.IsEmpty()); | |
968 | if (myEEDone) break; | |
969 | else NextEECouple(); | |
970 | } | |
971 | SetIntersectionDone(); | |
972 | } | |
973 | ||
974 | ||
975 | //======================================================================= | |
976 | //function : MoreEECouple | |
977 | //purpose : | |
978 | //======================================================================= | |
979 | ||
980 | Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEECouple() const | |
981 | { | |
982 | Standard_Boolean more1 = myEdgeScanner.More(); | |
983 | Standard_Boolean more2 = myEdgeExplorer.More(); | |
984 | return (more1 && more2); | |
985 | } | |
986 | ||
987 | ||
988 | //======================================================================= | |
989 | //function : NextEECouple | |
990 | //purpose : | |
991 | //======================================================================= | |
992 | ||
993 | void TopOpeBRep_ShapeIntersector::NextEECouple() | |
994 | { | |
995 | myEdgeScanner.Next(); | |
996 | while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) { | |
997 | myEdgeExplorer.Next(); | |
998 | myEdgeScanner.Init(myEdgeExplorer); | |
999 | } | |
1000 | } | |
1001 | ||
1002 | ||
1003 | //======================================================================= | |
1004 | //function : Shape | |
1005 | //purpose : | |
1006 | //======================================================================= | |
1007 | ||
1008 | const TopoDS_Shape& TopOpeBRep_ShapeIntersector::Shape | |
1009 | ( const Standard_Integer Index )const | |
1010 | { | |
1011 | if ( Index == 1 ) return myShape1; | |
1012 | else if ( Index == 2 ) return myShape2; | |
1013 | ||
1014 | Standard_Failure::Raise("ShapeIntersector : no shape"); | |
1015 | TopoDS_Shape* bid = new TopoDS_Shape(); | |
1016 | return *bid; | |
1017 | } | |
1018 | ||
1019 | ||
1020 | //======================================================================= | |
1021 | //function : ChangeFacesIntersector | |
1022 | //purpose : | |
1023 | //======================================================================= | |
1024 | ||
1025 | TopOpeBRep_FacesIntersector& | |
1026 | TopOpeBRep_ShapeIntersector::ChangeFacesIntersector() | |
1027 | { return myFFIntersector; } | |
1028 | ||
1029 | ||
1030 | //======================================================================= | |
1031 | //function : ChangeEdgesIntersector | |
1032 | //purpose : | |
1033 | //======================================================================= | |
1034 | ||
1035 | TopOpeBRep_EdgesIntersector& | |
1036 | TopOpeBRep_ShapeIntersector::ChangeEdgesIntersector() | |
1037 | { return myEEIntersector; } | |
1038 | ||
1039 | ||
1040 | //======================================================================= | |
1041 | //function : ChangeFaceEdgeIntersector | |
1042 | //purpose : | |
1043 | //======================================================================= | |
1044 | ||
1045 | TopOpeBRep_FaceEdgeIntersector& | |
1046 | TopOpeBRep_ShapeIntersector::ChangeFaceEdgeIntersector() | |
1047 | { return myFEIntersector; } | |
1048 | ||
1049 | ||
1050 | //======================================================================= | |
1051 | //function : GetTolerances | |
1052 | //purpose : | |
1053 | //======================================================================= | |
1054 | ||
1055 | void TopOpeBRep_ShapeIntersector::GetTolerances(Standard_Real& tol1, | |
1056 | Standard_Real& tol2)const | |
1057 | { tol1 = myTol1; tol2 = myTol2; } | |
1058 | ||
1059 | ||
1060 | ||
1061 | ||
1062 | //======================================================================= | |
1063 | //function : IsHalfSpaceShape | |
1064 | //purpose : tries to define if one of solids is a half space object | |
1065 | // returns: | |
1066 | // 0 - no half spaces ( default ) | |
1067 | // 1 - half space is S1 | |
1068 | // 2 - half space is S2 | |
1069 | //======================================================================= | |
1070 | static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2) | |
1071 | { | |
1072 | Standard_Integer result = 0; | |
1073 | ||
1074 | if( S1.ShapeType() == TopAbs_SOLID && S2.ShapeType() == TopAbs_SOLID ) | |
1075 | { | |
1076 | TopExp_Explorer ExpSol1(S1, TopAbs_FACE); | |
1077 | TopExp_Explorer ExpSol2(S2, TopAbs_FACE); | |
1078 | Standard_Integer NbFacesSol1 = 0; | |
1079 | Standard_Integer NbFacesSol2 = 0; | |
1080 | ||
1081 | for(; ExpSol1.More(); ExpSol1.Next() ) | |
1082 | NbFacesSol1++; | |
1083 | ||
1084 | for(; ExpSol2.More(); ExpSol2.Next() ) | |
1085 | NbFacesSol2++; | |
1086 | ||
1087 | if( NbFacesSol1 == 0 || NbFacesSol2 == 0 ) // strange solids!!! | |
1088 | return result; | |
1089 | if( NbFacesSol1 == 1 && NbFacesSol2 == 1 ) // both shapes are half spaces ??? | |
1090 | return result; | |
1091 | ||
1092 | if( (NbFacesSol1 == 1 && NbFacesSol2 >= 2) || (NbFacesSol2 == 1 && NbFacesSol1 >= 2) ) | |
1093 | { | |
1094 | // if one solid has shell consisted of only a face but other one has valid closed | |
1095 | // shell we can detect current boolean operation as operation with half space object. | |
1096 | // if shell of second solid is not valid too we cann't detect what kind of objects | |
1097 | // we try to perform. in this case we do nothing and just return. | |
1098 | ||
1099 | // but before we must avoid shperes, toruses and solids with a face biult on spherical surfaces | |
1100 | // of revolution (SSRFS) - solids with shell of one face: | |
1101 | // sphere (U: 0, 2PI) (V: -PI/2, PI/2), | |
1102 | // torus (U: 0, 2PI) (V: 0, 2PI). | |
1103 | // SSRFS (U period = (PI), 2PI) (V period = (PI), 2PI) | |
1104 | // these solids are not halfspaces. | |
1105 | ||
1106 | TopExp_Explorer SolidExplorer; | |
1107 | TopoDS_Face testFace; | |
1108 | ||
1109 | if( NbFacesSol1 == 1 ) | |
1110 | { | |
1111 | for( SolidExplorer.Init(S1, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() ) | |
1112 | testFace = TopoDS::Face( SolidExplorer.Current() ); | |
1113 | } | |
1114 | else | |
1115 | { | |
1116 | for( SolidExplorer.Init(S2, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() ) | |
1117 | testFace = TopoDS::Face( SolidExplorer.Current() ); | |
1118 | } | |
1119 | ||
1120 | BRepAdaptor_Surface FSurf( testFace ); | |
1121 | Standard_Boolean SolidIsSphereOrTorus = Standard_False; | |
1122 | ||
1123 | if( FSurf.GetType() == GeomAbs_Sphere || FSurf.GetType() == GeomAbs_Torus ) | |
1124 | { | |
1125 | Standard_Real minU = FSurf.FirstUParameter(); | |
1126 | Standard_Real maxU = FSurf.LastUParameter(); | |
1127 | Standard_Real minV = FSurf.FirstVParameter(); | |
1128 | Standard_Real maxV = FSurf.LastVParameter(); | |
c6541a0c | 1129 | Standard_Boolean yesU = ( Abs(minU - 0.) < 1.e-9 && Abs(maxU - 2*M_PI) < 1.e-9 ); |
7fd59977 | 1130 | Standard_Boolean yesV = ( FSurf.GetType() == GeomAbs_Sphere ) ? |
c6541a0c D |
1131 | ( Abs(minV - (-M_PI/2.)) < 1.e-9 && Abs(maxV - M_PI/2.) < 1.e-9 ) : |
1132 | ( Abs(minV - 0.) < 1.e-9 && Abs(maxV - 2*M_PI) < 1.e-9 ); | |
7fd59977 | 1133 | SolidIsSphereOrTorus = ( yesU && yesV ); |
1134 | } | |
1135 | ||
1136 | if( FSurf.GetType() == GeomAbs_SurfaceOfRevolution ) | |
1137 | { | |
1138 | Standard_Boolean areBothPeriodic = ( FSurf.IsUPeriodic() && FSurf.IsVPeriodic() ); | |
1139 | if( areBothPeriodic ) | |
1140 | { | |
c6541a0c D |
1141 | Standard_Boolean yesU = ( Abs(FSurf.UPeriod() - M_PI) < 1.e-9 || Abs(FSurf.UPeriod() - 2*M_PI) < 1.e-9 ); |
1142 | Standard_Boolean yesV = ( Abs(FSurf.VPeriod() - M_PI) < 1.e-9 || Abs(FSurf.VPeriod() - 2*M_PI) < 1.e-9 ); | |
7fd59977 | 1143 | SolidIsSphereOrTorus = ( yesU && yesV ); |
1144 | } | |
1145 | } | |
1146 | ||
1147 | if( SolidIsSphereOrTorus ) | |
1148 | return result; | |
1149 | ||
1150 | Standard_Boolean SecondShellOk = Standard_True; | |
1151 | TopTools_IndexedDataMapOfShapeListOfShape aMapEF; | |
1152 | aMapEF.Clear(); | |
1153 | Standard_Integer NbEdges = 0, NbFaces = 0, iE = 0; | |
1154 | ||
1155 | if( NbFacesSol1 == 1 ) | |
1156 | TopExp::MapShapesAndAncestors(S2, TopAbs_EDGE, TopAbs_FACE, aMapEF); | |
1157 | else | |
1158 | TopExp::MapShapesAndAncestors(S1, TopAbs_EDGE, TopAbs_FACE, aMapEF); | |
1159 | ||
1160 | NbEdges = aMapEF.Extent(); | |
1161 | for( iE = 1; iE <= NbEdges; iE++) | |
1162 | { | |
1163 | const TopTools_ListOfShape& listFaces = aMapEF.FindFromIndex( iE ); | |
1164 | NbFaces = listFaces.Extent(); | |
1165 | if( NbFaces != 2 ) | |
1166 | { | |
1167 | SecondShellOk = Standard_False; | |
1168 | break; | |
1169 | } | |
1170 | } | |
1171 | aMapEF.Clear(); | |
1172 | ||
1173 | if( SecondShellOk ) | |
1174 | result = (NbFacesSol1 == 1) ? 1 : 2; | |
1175 | } | |
1176 | else | |
1177 | { | |
1178 | // ************************** IMPORTANT !!! ************************************ | |
1179 | // both shells are of more than 2 faces. if both solids have invalid shells | |
1180 | // we do nothing and just return. on the other hand if only one shell is valid | |
1181 | // currently we should suppose that solid with invalid shell is a half space too, | |
1182 | // but this is not always true. | |
1183 | // | |
1184 | // so this suggestion must be developed carefully. while we don't classify it! | |
1185 | // ***************************************************************************** | |
1186 | } | |
63c629aa | 1187 | #ifdef TOPOPEBREP_DEB |
7fd59977 | 1188 | if( result != 0 ) |
1189 | cout << "# one of the SOLIDs probably is a HALF SPACE" << endl; | |
1190 | #endif | |
1191 | } | |
1192 | ||
1193 | return result; | |
1194 | } | |
1195 | ||
1196 | //======================================================================= | |
1197 | //function : GetNewSolid | |
1198 | //purpose : rebuild halfspace solid adding new "face on infinity" | |
1199 | // to build correct bounding box to classify carefully | |
1200 | // "rejected shapes". | |
1201 | //======================================================================= | |
1202 | static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F) | |
1203 | { | |
1204 | // "new solid" is a new halfspace solid consists of two faces now: the first face is a face | |
1205 | // used to build halfspace solid and the second face is a new "face on infinity" specially | |
1206 | // created to constuct correct bounding box around halfspace solid with bounds more wide than | |
1207 | // previous one. | |
1208 | ||
1209 | // the following algorithm is used: | |
1210 | // 1. get face used to build halfspace solid and calculate its normal, Min/Max (U,V) parameters, | |
1211 | // four points lying on the surface of the face inside its restrictions, surface, tolerance | |
1212 | // and location. | |
1213 | // 2. define the direction into the halfspace solid and project four points along this direction | |
1214 | // on infinite distance. then use those points to create "face on infinity". | |
1215 | // 3. build new shell with two new faces and new "halfspace solid". | |
1216 | // 4. return this solid and "face on infinity" to remove it and all its subshapes from the list | |
1217 | // of rejected shapes. | |
1218 | ||
1219 | TopExp_Explorer ShapeExplorer; | |
1220 | ||
1221 | TopoDS_Face hsFace; | |
1222 | ||
1223 | for( ShapeExplorer.Init(S, TopAbs_FACE); ShapeExplorer.More(); ShapeExplorer.Next() ) | |
1224 | hsFace = TopoDS::Face( ShapeExplorer.Current() ); | |
1225 | ||
1226 | BRepAdaptor_Surface ASurf( hsFace ); | |
1227 | ||
1228 | Standard_Real MinU = ASurf.FirstUParameter(); | |
1229 | Standard_Real MaxU = ASurf.LastUParameter(); | |
1230 | Standard_Real MinV = ASurf.FirstVParameter(); | |
1231 | Standard_Real MaxV = ASurf.LastUParameter(); | |
1232 | ||
1233 | Standard_Real MidU = (MaxU + MinU) * 0.5; | |
1234 | Standard_Real MidV = (MaxV + MinV) * 0.5; | |
1235 | ||
1236 | gp_Pnt MidP; | |
1237 | gp_Vec SurfDU, SurfDV; | |
1238 | ASurf.D1( MidU, MidV, MidP, SurfDU, SurfDV ); | |
1239 | ||
1240 | gp_Vec Normal = SurfDU.Crossed( SurfDV ); | |
1241 | ||
1242 | if( hsFace.Orientation() == TopAbs_FORWARD ) | |
1243 | Normal *= -1.e+10; | |
1244 | else | |
1245 | Normal *= 1.e+10; | |
1246 | ||
1247 | Standard_Real Pu1 = MinU + Abs( (MaxU - MinU) / 4. ); | |
1248 | Standard_Real Pu2 = MinU + Abs( (MaxU - MinU) / 4. * 3. ); | |
1249 | Standard_Real Pv1 = MinV + Abs( (MaxV - MinV) / 4. ); | |
1250 | Standard_Real Pv2 = MinV + Abs( (MaxV - MinV) / 4. * 3. ); | |
1251 | ||
1252 | gp_Pnt P1, P2, P3, P4; | |
1253 | ASurf.D0( Pu1, Pv1, P1 ); | |
1254 | ASurf.D0( Pu1, Pv2, P2 ); | |
1255 | ASurf.D0( Pu2, Pv1, P3 ); | |
1256 | ASurf.D0( Pu2, Pv2, P4 ); | |
1257 | ||
1258 | P1.Translate( Normal ); | |
1259 | P2.Translate( Normal ); | |
1260 | P3.Translate( Normal ); | |
1261 | P4.Translate( Normal ); | |
1262 | ||
1263 | BRepLib_MakeEdge mke1( P1, P2 ); | |
1264 | BRepLib_MakeEdge mke2( P2, P4 ); | |
1265 | BRepLib_MakeEdge mke3( P4, P3 ); | |
1266 | BRepLib_MakeEdge mke4( P3, P1 ); | |
1267 | ||
1268 | TopoDS_Edge e1 = mke1.Edge(); | |
1269 | TopoDS_Edge e2 = mke2.Edge(); | |
1270 | TopoDS_Edge e3 = mke3.Edge(); | |
1271 | TopoDS_Edge e4 = mke4.Edge(); | |
1272 | ||
1273 | BRepLib_MakeWire mkw( e1, e2, e3, e4 ); | |
1274 | TopoDS_Wire w = mkw.Wire(); | |
1275 | ||
1276 | BRepLib_MakeFace mkf( w ); | |
1277 | TopoDS_Face infFace = mkf.Face(); | |
1278 | ||
1279 | TopoDS_Shell newShell; | |
1280 | TopoDS_Solid newSolid; | |
1281 | ||
1282 | BRep_Builder newShellBuilder; | |
1283 | newShellBuilder.MakeShell( newShell ); | |
1284 | newShellBuilder.Add( newShell, hsFace ); | |
1285 | newShellBuilder.Add( newShell, infFace ); | |
ab860031 | 1286 | newShell.Closed (BRep_Tool::IsClosed (newShell)); |
7fd59977 | 1287 | |
1288 | BRep_Builder newSolidBuilder; | |
1289 | newSolidBuilder.MakeSolid( newSolid ); | |
1290 | newSolidBuilder.Add( newSolid, newShell ); | |
1291 | ||
1292 | F = infFace; | |
1293 | return newSolid; | |
1294 | } |