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