1 // Created on: 1997-02-14
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 #include <TopOpeBRepDS_InterferenceTool.hxx>
18 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
19 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
20 #include <TopOpeBRepDS_InterferenceIterator.hxx>
21 #include <TopOpeBRepDS_TKI.hxx>
22 #include <TopoDS.hxx>
23 #include <BRepLProp_SLProps.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25 //#include <BRepAdaptor_Curve2d.hxx>
26 #include <BRep_Tool.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <gp_Vec.hxx>
29 #include <gp_Dir.hxx>
30 #include <Precision.hxx>
31 #include <TColStd_MapOfInteger.hxx>
32 #include <Standard_ProgramError.hxx>
33 #include <TopOpeBRepDS_define.hxx>
34 #include <TopOpeBRepTool_TOOL.hxx>
35 #include <TopOpeBRepTool_EXPORT.hxx>
36 #include <TopOpeBRepDS_EXPORT.hxx>
37 
38 //-----------------------------------------------------------------------
Handle(TopOpeBRepDS_Interference)39 Standard_EXPORT Handle(TopOpeBRepDS_Interference) MakeCPVInterference
40 (const TopOpeBRepDS_Transition& T, // transition
41  const Standard_Integer SI, // curve/edge index
42  const Standard_Integer GI, // point/vertex index
43  const Standard_Real P, // parameter of G on S
44  const TopOpeBRepDS_Kind GK) // POINT/VERTEX
45 //-----------------------------------------------------------------------
46 {
47   Handle(TopOpeBRepDS_Interference) I;
48   TopOpeBRepDS_Kind SK = TopOpeBRepDS_CURVE;
49   I = TopOpeBRepDS_InterferenceTool::MakeCurveInterference(T,SK,SI,GK,GI,P);
50   return I;
51 }
52 
53 //-----------------------------------------------------------------------
Handle(TopOpeBRepDS_Interference)54 Standard_EXPORT Handle(TopOpeBRepDS_Interference) MakeEPVInterference
55 (const TopOpeBRepDS_Transition& T, // transition
56  const Standard_Integer SI, // curve/edge index
57  const Standard_Integer GI, // point/vertex index
58  const Standard_Real P, // parameter of G on S
59  const TopOpeBRepDS_Kind GK,
60  const Standard_Boolean B) // G is a vertex (or not) of the interference master
61 //-----------------------------------------------------------------------
62 {
63   Handle(TopOpeBRepDS_Interference) I;
64   TopOpeBRepDS_Kind SK = TopOpeBRepDS_EDGE;
65   if      ( GK == TopOpeBRepDS_POINT ) {
66     I = TopOpeBRepDS_InterferenceTool::MakeEdgeInterference(T,SK,SI,GK,GI,P);
67   }
68   else if ( GK == TopOpeBRepDS_VERTEX ) {
69     I = TopOpeBRepDS_InterferenceTool::MakeEdgeVertexInterference(T,SI,GI,B,TopOpeBRepDS_UNSHGEOMETRY,P);
70     I->GeometryType(GK);
71   }
72   return I;
73 }
74 
75 //-----------------------------------------------------------------------
Handle(TopOpeBRepDS_Interference)76 Standard_EXPORT Handle(TopOpeBRepDS_Interference) MakeEPVInterference
77 (const TopOpeBRepDS_Transition& T, // transition
78  const Standard_Integer S, // curve/edge index
79  const Standard_Integer G, // point/vertex index
80  const Standard_Real P, // parameter of G on S
81  const TopOpeBRepDS_Kind GK, // POINT/VERTEX
82  const TopOpeBRepDS_Kind SK,
83  const Standard_Boolean B) // G is a vertex (or not) of the interference master
84 //-----------------------------------------------------------------------
85 {
86   Handle(TopOpeBRepDS_Interference) I = ::MakeEPVInterference(T,S,G,P,GK,B);
87   I->SupportType(SK);
88   return I;
89 }
90 
91 //------------------------------------------------------
FUN_hasStateShape(const TopOpeBRepDS_Transition & T,const TopAbs_State state,const TopAbs_ShapeEnum shape)92 Standard_EXPORT Standard_Boolean FUN_hasStateShape
93 //------------------------------------------------------
94 // FUN_hasStateShape : True if transition T is (state,shape) before or after
95 (const TopOpeBRepDS_Transition& T,
96  const TopAbs_State state,
97  const TopAbs_ShapeEnum shape)
98 {
99   TopAbs_State     staB = T.Before(), staA = T.After();
100   TopAbs_ShapeEnum shaB = T.ShapeBefore(), shaA = T.ShapeAfter();
101   Standard_Boolean B = ( staB == state ) && ( shaB == shape);
102   Standard_Boolean A = ( staA == state ) && ( shaA == shape);
103   Standard_Boolean result = B || A;
104   return result;
105 }
106 
107 //------------------------------------------------------
FUN_selectTRASHAinterference(TopOpeBRepDS_ListOfInterference & L1,const TopAbs_ShapeEnum sha2,TopOpeBRepDS_ListOfInterference & L2)108 Standard_EXPORT Standard_Integer FUN_selectTRASHAinterference
109 //------------------------------------------------------
110 // selection des interf (sha2) de L1 dans L2. retourne leur nombre.
111 (TopOpeBRepDS_ListOfInterference& L1,const TopAbs_ShapeEnum sha2, TopOpeBRepDS_ListOfInterference& L2)
112 {
113   TopOpeBRepDS_ListIteratorOfListOfInterference it1(L1);
114   while (it1.More()) {
115     Handle(TopOpeBRepDS_Interference) I1 = it1.Value();
116     const TopOpeBRepDS_Transition& T1 = I1->Transition();
117 
118     TopAbs_ShapeEnum shab = T1.ShapeBefore(), shaa = T1.ShapeAfter();
119     Standard_Boolean sel=((shab==sha2)||(shaa==sha2));
120     if (sel) {
121       L2.Append(I1);
122       L1.Remove(it1);
123     }
124     else it1.Next();
125   }
126   Standard_Integer n2 = L2.Extent();
127   return n2;
128 }
129 
130 //------------------------------------------------------
FUN_selectITRASHAinterference(TopOpeBRepDS_ListOfInterference & L1,const Standard_Integer Index,TopOpeBRepDS_ListOfInterference & L2)131 Standard_EXPORT Standard_Integer FUN_selectITRASHAinterference
132 //------------------------------------------------------
133 // selection des interf (sha2) de L1 dans L2. retourne leur nombre.
134 (TopOpeBRepDS_ListOfInterference& L1,const Standard_Integer Index, TopOpeBRepDS_ListOfInterference& L2)
135 {
136   if (Index == 0) return 0;
137   TopOpeBRepDS_ListIteratorOfListOfInterference it1(L1);
138   while (it1.More()) {
139     Handle(TopOpeBRepDS_Interference) I1 = it1.Value();
140     const TopOpeBRepDS_Transition& T1 = I1->Transition();
141     Standard_Integer Ind = T1.Index();
142     if (Ind == Index) {
143       L2.Append(I1);
144       L1.Remove(it1);
145     }
146     else it1.Next();
147   }
148   Standard_Integer n2 = L2.Extent();
149   return n2;
150 }
151 
152 //------------------------------------------------------
FUN_selectTRAUNKinterference(TopOpeBRepDS_ListOfInterference & L1,TopOpeBRepDS_ListOfInterference & L2)153 Standard_EXPORT Standard_Integer FUN_selectTRAUNKinterference
154 //------------------------------------------------------
155 // selection des interf de transition (UNK,UNK) de L1 dans L2. retourne leur nombre.
156 (TopOpeBRepDS_ListOfInterference& L1,TopOpeBRepDS_ListOfInterference& L2)
157 {
158   TopOpeBRepDS_ListIteratorOfListOfInterference it1(L1);
159   while (it1.More()) {
160     Handle(TopOpeBRepDS_Interference) I1 = it1.Value();
161     const TopOpeBRepDS_Transition& T1 = I1->Transition();
162     Standard_Boolean sel = T1.IsUnknown();
163     if (sel) {
164       L2.Append(I1);
165       L1.Remove(it1);
166     }
167     else it1.Next();
168   }
169   Standard_Integer n2 = L2.Extent();
170   return n2;
171 }
172 
173 //------------------------------------------------------
FUN_selectTRAORIinterference(TopOpeBRepDS_ListOfInterference & L1,const TopAbs_Orientation O,TopOpeBRepDS_ListOfInterference & L2)174 Standard_EXPORT Standard_Integer FUN_selectTRAORIinterference
175 //------------------------------------------------------
176 // selection des interf d'orientation donnee O de L1 dans L2. retourne leur nombre.
177 (TopOpeBRepDS_ListOfInterference& L1, const TopAbs_Orientation O, TopOpeBRepDS_ListOfInterference& L2)
178 {
179   TopOpeBRepDS_ListIteratorOfListOfInterference it1(L1);
180   while (it1.More()) {
181     Handle(TopOpeBRepDS_Interference) I1 = it1.Value();
182     const TopOpeBRepDS_Transition& T1 = I1->Transition();
183     TopAbs_Orientation ori = T1.Orientation(TopAbs_IN);
184     Standard_Boolean sel = (ori ==O);
185     if (sel) {
186       L2.Append(I1);
187       L1.Remove(it1);
188     }
189     else it1.Next();
190   }
191   Standard_Integer n2 = L2.Extent();
192   return n2;
193 }
194 
195 //------------------------------------------------------
FUN_selectGKinterference(TopOpeBRepDS_ListOfInterference & L1,const TopOpeBRepDS_Kind GK,TopOpeBRepDS_ListOfInterference & L2)196 Standard_EXPORT Standard_Integer FUN_selectGKinterference
197 //------------------------------------------------------
198 (TopOpeBRepDS_ListOfInterference& L1,const TopOpeBRepDS_Kind GK,TopOpeBRepDS_ListOfInterference& L2)
199 {
200   TopOpeBRepDS_ListIteratorOfListOfInterference it1(L1);
201   while (it1.More()) {
202     TopOpeBRepDS_Kind gki = it1.Value()->GeometryType();
203     if (gki == GK) {
204       L2.Append(it1.Value());
205       L1.Remove(it1);
206     }
207     else it1.Next();
208   }
209   Standard_Integer n2 = L2.Extent();
210   return n2;
211 }
212 
213 //------------------------------------------------------
FUN_selectSKinterference(TopOpeBRepDS_ListOfInterference & L1,const TopOpeBRepDS_Kind SK,TopOpeBRepDS_ListOfInterference & L2)214 Standard_EXPORT Standard_Integer FUN_selectSKinterference
215 //------------------------------------------------------
216 // selection des interf de type de support SK de L1 dans L2. retourne leur nombre.
217 (TopOpeBRepDS_ListOfInterference& L1,const TopOpeBRepDS_Kind SK,TopOpeBRepDS_ListOfInterference& L2)
218 {
219   TopOpeBRepDS_ListIteratorOfListOfInterference it1(L1);
220   while (it1.More()) {
221     TopOpeBRepDS_Kind ski = it1.Value()->SupportType();
222     if (ski == SK) {
223       L2.Append(it1.Value());
224       L1.Remove(it1);
225     }
226     else it1.Next();
227   }
228   Standard_Integer n2 = L2.Extent();
229   return n2;
230 }
231 
232 //------------------------------------------------------
FUN_selectGIinterference(TopOpeBRepDS_ListOfInterference & L1,const Standard_Integer GI,TopOpeBRepDS_ListOfInterference & L2)233 Standard_EXPORT Standard_Integer FUN_selectGIinterference
234 //------------------------------------------------------
235 // selection des interf d' index de geometrie GI de L1 dans L2. retourne leur nombre.
236 (TopOpeBRepDS_ListOfInterference& L1,const Standard_Integer GI,TopOpeBRepDS_ListOfInterference& L2)
237 {
238   if (GI == 0) return 0;
239   TopOpeBRepDS_ListIteratorOfListOfInterference it1(L1);
240   while (it1.More()) {
241     Standard_Integer gi = it1.Value()->Geometry();
242     if (gi == GI) {
243       L2.Append(it1.Value());
244       L1.Remove(it1);
245     }
246     else it1.Next();
247   }
248   Standard_Integer n2 = L2.Extent();
249   return n2;
250 }
251 
252 //------------------------------------------------------
FUN_selectSIinterference(TopOpeBRepDS_ListOfInterference & L1,const Standard_Integer SI,TopOpeBRepDS_ListOfInterference & L2)253 Standard_EXPORT Standard_Integer FUN_selectSIinterference
254 //------------------------------------------------------
255 // selection des interf d' index de support SI de L1 dans L2. retourne leur nombre.
256 (TopOpeBRepDS_ListOfInterference& L1,const Standard_Integer SI,TopOpeBRepDS_ListOfInterference& L2)
257 {
258   if (SI == 0) return 0;
259   TopOpeBRepDS_ListIteratorOfListOfInterference it1(L1);
260   while (it1.More()) {
261     Standard_Integer si = it1.Value()->Support();
262     if (si == SI) {
263       L2.Append(it1.Value());
264       L1.Remove(it1);
265     }
266     else it1.Next();
267   }
268   Standard_Integer n2 = L2.Extent();
269   return n2;
270 }
271 
272 //------------------------------------------------------
FUN_interfhassupport(const TopOpeBRepDS_DataStructure & DS,const Handle (TopOpeBRepDS_Interference)& I,const TopoDS_Shape & S)273 Standard_EXPORT Standard_Boolean FUN_interfhassupport
274 //------------------------------------------------------
275 // FUN_interfhassupport : True si shape support de l 'interf I est IsSame(S).
276 (const TopOpeBRepDS_DataStructure& DS,const Handle(TopOpeBRepDS_Interference)& I,const TopoDS_Shape& S)
277 {
278   Standard_Boolean h = Standard_True;
279   const Standard_Integer index = I->Support();
280   const TopoDS_Shape& SofI = DS.Shape(index);
281   if ( SofI.IsSame(S) ) h =  Standard_True;
282   else                  h =  Standard_False;
283   return h;
284 }
285 
286 //------------------------------------------------------
FUN_transitionEQUAL(const TopOpeBRepDS_Transition & T1,const TopOpeBRepDS_Transition & T2)287 Standard_EXPORT Standard_Boolean FUN_transitionEQUAL
288 //------------------------------------------------------
289 (const TopOpeBRepDS_Transition& T1,const TopOpeBRepDS_Transition& T2)
290 {
291   Standard_Boolean id1 = FUN_transitionSTATEEQUAL(T1,T2);
292   Standard_Boolean id2 = FUN_transitionSHAPEEQUAL(T1,T2);
293   Standard_Boolean id3 = FUN_transitionINDEXEQUAL(T1,T2);
294   Standard_Boolean id = id1 && id2 && id3;
295   return id;
296 }
297 
298 //------------------------------------------------------
FUN_transitionSTATEEQUAL(const TopOpeBRepDS_Transition & T1,const TopOpeBRepDS_Transition & T2)299 Standard_EXPORT Standard_Boolean FUN_transitionSTATEEQUAL
300 //------------------------------------------------------
301 (const TopOpeBRepDS_Transition& T1,const TopOpeBRepDS_Transition& T2)
302 {
303   Standard_Boolean id = T1.Before()==T2.Before() && T1.After()==T2.After();
304   return id;
305 }
306 
307 //------------------------------------------------------
FUN_transitionSHAPEEQUAL(const TopOpeBRepDS_Transition & T1,const TopOpeBRepDS_Transition & T2)308 Standard_EXPORT Standard_Boolean FUN_transitionSHAPEEQUAL
309 //------------------------------------------------------
310 (const TopOpeBRepDS_Transition& T1,const TopOpeBRepDS_Transition& T2)
311 {
312   Standard_Boolean id = T1.ShapeBefore()==T2.ShapeBefore() && T1.ShapeAfter()==T2.ShapeAfter();
313   return id;
314 }
315 
316 //------------------------------------------------------
FUN_transitionINDEXEQUAL(const TopOpeBRepDS_Transition & T1,const TopOpeBRepDS_Transition & T2)317 Standard_EXPORT Standard_Boolean FUN_transitionINDEXEQUAL
318 //------------------------------------------------------
319 (const TopOpeBRepDS_Transition& T1,const TopOpeBRepDS_Transition& T2)
320 {
321   Standard_Boolean id = T1.IndexBefore()==T2.IndexBefore() && T1.IndexAfter()==T2.IndexAfter();
322   return id;
323 }
324 
325 //------------------------------------------------------
FUN_reducedoublons(TopOpeBRepDS_ListOfInterference & LI,const TopOpeBRepDS_DataStructure & BDS,const Standard_Integer SIX)326 Standard_EXPORT void FUN_reducedoublons
327 //------------------------------------------------------
328 (TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer SIX)
329 {
330 
331   const TopoDS_Shape& E = BDS.Shape(SIX);
332   TopOpeBRepDS_ListIteratorOfListOfInterference it1;
333 
334   // process interferences of LI with VERTEX geometry
335   it1.Initialize(LI);
336   while (it1.More() ) {
337     Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
338     const TopOpeBRepDS_Transition& T1 = I1->Transition();
339     TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
340     TopAbs_ShapeEnum tsb1,tsa1; Standard_Integer isb1,isa1;
341     FDS_Tdata(I1,tsb1,isb1,tsa1,isa1);
342 
343     TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1); it2.Next();
344     while ( it2.More() ) {
345 
346       const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
347       const TopOpeBRepDS_Transition& T2 = I2->Transition();
348       TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; FDS_data(I2,GT2,G2,ST2,S2);
349       TopAbs_ShapeEnum tsb2,tsa2; Standard_Integer isb2,isa2;
350       FDS_Tdata(I2,tsb2,isb2,tsa2,isa2);
351 
352       Standard_Boolean idGS = (GT2 == GT1 && G2 == G1 && ST2 == ST1 && S2 == S1);
353       if (idGS) {
354 
355 	Standard_Boolean id1 = FUN_transitionSTATEEQUAL(T1,T2);
356 	Standard_Boolean id2 = FUN_transitionSHAPEEQUAL(T1,T2);
357 	Standard_Boolean id3 = FUN_transitionINDEXEQUAL(T1,T2);
358 	Standard_Boolean idT = id1 && id2 && id3;
359 
360 	if ( idT ) {
361 	  const Handle(TopOpeBRepDS_EdgeVertexInterference) EVI1 = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I1);
362 	  const Handle(TopOpeBRepDS_EdgeVertexInterference) EVI2 = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I2);
363 	  Standard_Boolean evi = (!EVI1.IsNull()) && (!EVI2.IsNull());
364 	  if (evi) {
365 	    //xpu130898 : if vG is on E's closing vertex -> filter
366 	    const TopoDS_Vertex& vG = TopoDS::Vertex(BDS.Shape(G1));
367 	    TopoDS_Vertex OOv;  Standard_Boolean hasOO = FUN_ds_getoov(vG,BDS,OOv);
368 	    TopoDS_Vertex vclo; Standard_Boolean Eclosed = TopOpeBRepTool_TOOL::ClosedE(TopoDS::Edge(E),vclo);
369 	    Standard_Boolean onvclo = Standard_False;
370 	    if (Eclosed) {
371 	      onvclo = vG.IsSame(vG);
372 	      if (hasOO && !onvclo) onvclo = vG.IsSame(OOv);
373 	    }
374 	    if (onvclo) idT = Standard_True;
375 	    else {
376 	      //xpu100697 : if interf are EVI compare parameters
377 	      Standard_Real tolE = FUN_tool_maxtol(E); Standard_Real t = Precision::Parametric(tolE);
378 	      Standard_Real t1 = EVI1->Parameter(); Standard_Real t2 = EVI2->Parameter();
379 	      Standard_Real dd = t1-t2;
380 	      Standard_Boolean samepar = (Abs(dd) <= t);
381 	      idT = samepar;
382 	    }
383 	  } // evi
384 	}
385 	if (idT) {
386 	  // les 2 interferences I1 et I2 sont identiques : on supprime I2
387 	  LI.Remove(it2);
388 	}
389 	else it2.Next();
390       }
391       else it2.Next();
392     }
393     it1.Next();
394   } // it1.More()
395 } // reducedoublons
396 
397 //------------------------------------------------------
FUN_unkeepUNKNOWN(TopOpeBRepDS_ListOfInterference & LI,TopOpeBRepDS_DataStructure &,const Standard_Integer)398 Standard_EXPORT void FUN_unkeepUNKNOWN
399 //------------------------------------------------------
400   (TopOpeBRepDS_ListOfInterference& LI,
401    TopOpeBRepDS_DataStructure& /*BDS*/,
402    const Standard_Integer)
403 {
404 //                 BDS.Shape(SIX);
405   TopOpeBRepDS_ListIteratorOfListOfInterference it1;
406 
407   // process interferences of LI with UNKNOWN transition
408 
409   it1.Initialize(LI);
410   while (it1.More() ) {
411     Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
412     const TopOpeBRepDS_Transition& T1 = I1->Transition();
413     Standard_Boolean isunk = T1.IsUnknown();
414 
415     if (isunk) {
416       LI.Remove(it1);
417     }
418     else it1.Next();
419   } // it1.More()
420 } // unkeepUNKNOWN
421 
422 // -----------------------------------------------------------
FUN_select3dI(const Standard_Integer SIX,TopOpeBRepDS_DataStructure & BDS,TopOpeBRepDS_ListOfInterference & lFE,TopOpeBRepDS_ListOfInterference & lFEresi,TopOpeBRepDS_ListOfInterference & l3dFE)423 static Standard_Integer FUN_select3dI(const Standard_Integer SIX, TopOpeBRepDS_DataStructure& BDS,
424 			 TopOpeBRepDS_ListOfInterference& lFE, TopOpeBRepDS_ListOfInterference& lFEresi, TopOpeBRepDS_ListOfInterference& l3dFE)
425 //------------------------------------------------------
426 {
427   l3dFE.Clear();
428   lFEresi.Clear();
429   Standard_Integer n3d = 0;
430   Standard_Integer nFE = lFE.Extent();
431   if (nFE <= 1) return n3d;
432 
433   const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(SIX));
434   Standard_Integer rankE  = BDS.AncestorRank(E);
435   TopoDS_Shape OOv; Standard_Integer OOG = 0, Gsta = 0;
436 
437   // attached to a given edge :
438   // <lFE> = {I=(T(face),G=POINT,S=EDGE)}/ {I=(T(face),G=VERTEX,S=EDGE)}
439   //             = set of interferences of same geometry kind.
440   //    -> <l3dFE> + <lFE>
441   // <l3dFE> = sets of interferences with same geometry,
442   //           describing 3d complex transitions.
443 
444   TopOpeBRepDS_ListIteratorOfListOfInterference it1(lFE);
445   while (it1.More()) {
446 
447     Standard_Boolean complex3d=Standard_False;
448     const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
449     TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
450     TopAbs_ShapeEnum SB1,SA1; Standard_Integer IB1,IA1; FDS_Tdata(I1,SB1,IB1,SA1,IA1);
451     Standard_Boolean vertex1 = (GT1 == TopOpeBRepDS_VERTEX);
452 
453     TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1);
454     if (it2.More()) it2.Next();
455     else break;
456 
457     // <Gsta>, <OOv>
458     if (vertex1) {
459       TopoDS_Vertex vG1 = TopoDS::Vertex(BDS.Shape(G1)); Standard_Integer rankvG1 = BDS.AncestorRank(vG1);
460       Standard_Boolean G1hsd = FUN_ds_getVsdm(BDS,G1,OOG);
461       if (rankvG1 != rankE) // vG1 not on E
462 	{OOv = vG1; Gsta = G1hsd? 3: 2;}
463       else // vG on E
464 	{if (G1hsd) OOv = BDS.Shape(OOG); Gsta = G1hsd? 3: 1;}
465     }
466 
467     while (it2.More()){
468       const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
469       TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; FDS_data(I2,GT2,G2,ST2,S2);
470       TopAbs_ShapeEnum SB2,SA2; Standard_Integer IB2,IA2; FDS_Tdata(I2,SB2,IB2,SA2,IA2);
471 
472       Standard_Boolean sameG = (GT2 == GT1);
473       if (!sameG) break;
474       sameG = (G2 == G1) || (G2 == OOG);
475 
476       const TopoDS_Face& F1 = TopoDS::Face(BDS.Shape(IB1));
477       const TopoDS_Face& F2 = TopoDS::Face(BDS.Shape(IB2));
478 
479       // same domain faces, -> 2d interferences
480       Standard_Boolean sdmFT = (IB1==IB2) || FUN_ds_sdm(BDS,F1,F2);
481 //      if (sdmFT) {it2.Next(); continue;}
482       if (sdmFT) {lFEresi.Append(I2); lFE.Remove(it2); continue;}
483 
484       // a. if (S2 == S1) ->ok
485       // b. else :
486       //     if (G is POINT on Fi i = 1,2) ->continue
487       //     else : look for E1(edge S1) on F1(IB1) shared by F2(IB2)
488       //            with bound G.
489       Standard_Boolean sameS = (ST2 == ST1) && (S2 == S1);
490 
491       Standard_Boolean sameSorsharedEbyTRASHA = sameS;
492       Standard_Boolean hasOOv = (Gsta > 1);
493       if (!sameSorsharedEbyTRASHA && hasOOv) {
494 	TopoDS_Shape Eshared; Standard_Boolean foundsh = FUN_tool_Eshared(OOv,F1,F2,Eshared);
495 	if (!foundsh) {it2.Next(); continue;}
496 
497 	sameSorsharedEbyTRASHA = Standard_True;
498 	if (!BDS.HasShape(Eshared))
499 	  {Standard_Integer OOrank = BDS.AncestorRank(OOv); BDS.AddShape(Eshared,OOrank);}
500 	S1 = BDS.Shape(Eshared); S2 = S1;
501       }
502 
503       if (sameSorsharedEbyTRASHA) { // xpu : 09-03-98
504 	Standard_Boolean sdm = FUN_ds_sdm(BDS,BDS.Shape(SIX),BDS.Shape(S1));
505 	if (sdm) {
506 	  it2.Next(); continue;
507 	}
508       } // xpu : 09-03-98
509 
510       if (sameSorsharedEbyTRASHA) {l3dFE.Append(I2); lFE.Remove(it2); complex3d=Standard_True;}
511       else                        it2.Next();
512     } // it2(it1);
513 
514     if (complex3d) {l3dFE.Append(I1); lFE.Remove(it1);}
515     else           it1.Next();
516   } // it1(lFE);
517 
518   // xpu170898 : cto009H1 (I1(T1(F),G,S1),I1'(T2(F),G,S2), I2)
519   //             (I1,I2) -> to reduce => I1' to delete
520   n3d = l3dFE.Extent();
521   Standard_Integer nresi = lFEresi.Extent();
522   if (nresi == 0) return n3d;
523 
524   if      (n3d != 0) {
525     TopOpeBRepDS_ListIteratorOfListOfInterference it(lFEresi);
526     while (it.More()){
527       const Handle(TopOpeBRepDS_Interference)& I = it.Value();
528       Standard_Integer TRA = I->Transition().Index();
529       TopOpeBRepDS_ListOfInterference lcopy; FDS_assign(l3dFE,lcopy);
530       TopOpeBRepDS_ListOfInterference lfound; Standard_Integer nfound = FUN_selectITRASHAinterference(lcopy,TRA,lfound);
531       if (nfound == 0) lFE.Remove(it);
532       else             it.Next();
533     }
534   }
535   else lFE.Append(lFEresi);
536   return n3d;
537 }
538 
FUN_find3dISEsameISF(const Handle (TopOpeBRepDS_Interference)& I1,TopOpeBRepDS_ListIteratorOfListOfInterference & it2)539 static Standard_Boolean FUN_find3dISEsameISF(const Handle(TopOpeBRepDS_Interference)& I1, TopOpeBRepDS_ListIteratorOfListOfInterference& it2)
540 // I1 = (T0,G0,S)
541 // looking among interferences of <it2> for I2/
542 // I2 = (T0,G0,S')
543 {
544   TopAbs_Orientation O1 = I1->Transition().Orientation(TopAbs_IN);
545   TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
546   TopAbs_ShapeEnum SB1,SA1; Standard_Integer IB1,IA1; FDS_Tdata(I1,SB1,IB1,SA1,IA1);
547 
548   while ( it2.More()){
549     Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
550     TopAbs_Orientation O2 = I2->Transition().Orientation(TopAbs_IN);
551     TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; FDS_data(I2,GT2,G2,ST2,S2);
552     TopAbs_ShapeEnum SB2,SA2; Standard_Integer IB2,IA2; FDS_Tdata(I2,SB2,IB2,SA2,IA2);
553     Standard_Boolean sameT = (SB1 == SB2) && (IB1 == IB2) && (O1 == O2);
554     Standard_Boolean sameG = (GT1 == GT2) && (G1 == G2);
555     if (sameT && sameG) return Standard_True;
556     else                it2.Next();
557   } // it2
558   return Standard_False;
559 }
560 
561 // ------------------------------------------------------------
FUN_select3dISEsameISF(TopOpeBRepDS_ListOfInterference & lFE,TopOpeBRepDS_ListOfInterference & l3dFE,TopOpeBRepDS_ListOfInterference & l3dFEresi,TopOpeBRepDS_ListOfInterference & lF,TopOpeBRepDS_ListOfInterference & l3dF)562 static Standard_Integer FUN_select3dISEsameISF
563 (TopOpeBRepDS_ListOfInterference& lFE, TopOpeBRepDS_ListOfInterference& l3dFE, TopOpeBRepDS_ListOfInterference& l3dFEresi,
564  TopOpeBRepDS_ListOfInterference& lF, TopOpeBRepDS_ListOfInterference& l3dF)
565 //-------------------------------------------------------------
566 {
567   //    I3d in <l3dFE>, I3d = (T(face),G=POINT/VERTEX,S=EDGE)
568   // <->I3d' in <l3dF>,  I3d'= (T(face),G=POINT/VERTEX,S=FACE)
569 
570   // <l3dFEold> -> {I3d} + <l3dFEnew>
571   // <lFEold>   -> <lFE> + (<l3dFEold> - <l3dFEnew>)
572   // <lFold>    -> {I3d'}+ <lFnew>;    {I3d'}=<l3dF>
573 
574   TopOpeBRepDS_ListIteratorOfListOfInterference it1(l3dFE);
575   while (it1.More()) {
576     const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
577 //    TopAbs_Orientation O1 = I1->Transition().Orientation(TopAbs_IN);
578 //    TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
579 //    TopAbs_ShapeEnum SB1,SA1; Standard_Integer IB1,IA1; FDS_Tdata(I1,SB1,IB1,SA1,IA1);
580 
581 //    Standard_Boolean found = Standard_False;
582 //    TopOpeBRepDS_ListIteratorOfListOfInterference it2(lF);
583 //    while ( it2.More()){
584 //      Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
585 //      TopAbs_Orientation O2 = I2->Transition().Orientation(TopAbs_IN);
586 //      TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; FDS_data(I2,GT2,G2,ST2,S2);
587 //      TopAbs_ShapeEnum SB2,SA2; Standard_Integer IB2,IA2; FDS_Tdata(I2,SB2,IB2,SA2,IA2);
588 //      Standard_Boolean sameT = (SB1 == SB2) && (IB1 == IB2) && (O1 == O2);
589 //      Standard_Boolean sameG = (GT1 == GT2) && (G1 == G2);
590 //      if (sameT && sameG) {found = Standard_True; l3dF.Append(I2); lF.Remove(it2);break;}
591 //      else                it2.Next();
592 //    } // it2
593 //    if (found) it1.Next();
594 //    else       {lFE.Append(I1); l3dFE.Remove(it1);}
595 
596     // {IFE = (T0,G0,Sedge); IFF = (T0,G0,Sface)}
597     // => l3dFE += IFE, l3dF += iFF
598     TopOpeBRepDS_ListIteratorOfListOfInterference it2(lF);
599     Standard_Boolean found = FUN_find3dISEsameISF(I1,it2);
600 
601     if (found) {
602       l3dF.Append(it2.Value());
603       lF.Remove(it2);
604       it1.Next();
605     }
606     else       {
607       // xpu : 16-02-98 :
608       // IFE1 = (T0,G0,Sedge1), IFE2 = (T0,G0,Sedge2)
609       // IFF = (T0,G0,Sface)
610       // => l3dFE += IFE1, l3dF += iFF,
611       //    l3dFEresi += IFE2
612       TopOpeBRepDS_ListIteratorOfListOfInterference it3(l3dF);
613       found = FUN_find3dISEsameISF(I1,it3);
614 
615       if (found) l3dFEresi.Append(I1);
616       else       lFE.Append(I1);
617       l3dFE.Remove(it1);
618 
619     }
620   } // it1
621   return l3dF.Extent();
622 }
623 
624 //------------------------------------------------------
FUN_select2dI(const Standard_Integer SIX,TopOpeBRepDS_DataStructure & BDS,const TopAbs_ShapeEnum TRASHAk,TopOpeBRepDS_ListOfInterference & lI,TopOpeBRepDS_ListOfInterference & l2dI)625 Standard_EXPORT Standard_Integer FUN_select2dI
626 (const Standard_Integer SIX, TopOpeBRepDS_DataStructure& BDS,const TopAbs_ShapeEnum TRASHAk,TopOpeBRepDS_ListOfInterference& lI,TopOpeBRepDS_ListOfInterference& l2dI)
627 //------------------------------------------------------
628 // <lI> -> <l2dI> + <lI>
629 // TRASHAk = TopAbs_FACE : <l2dI> = {I2d = (T on same domain faces, G,S)}
630 // TRASHAk = TopAbs_EDGE : <l2dI> = {I2d = (T on same edge, G,S)}
631 {
632   l2dI.Clear();
633   Standard_Integer n2d = 0;
634   Standard_Integer nFE = lI.Extent();
635   if (nFE <=1) return n2d;
636 
637   Standard_Boolean TonFace = (TRASHAk == TopAbs_FACE);
638 
639   // xpu201098 : check FEI is not 3dFEI (cto904F6,SIX10,G6)
640   TColStd_MapOfInteger mapftra;
641   TopOpeBRepDS_ListOfInterference lIE; FDS_copy(BDS.ShapeInterferences(SIX),lIE);
642   TopOpeBRepDS_ListOfInterference l3dF;
643   FUN_selectSKinterference(lIE,TopOpeBRepDS_FACE,l3dF);
644   for (TopOpeBRepDS_ListIteratorOfListOfInterference itt(l3dF); itt.More(); itt.Next()) mapftra.Add(itt.Value()->Support());
645   TopOpeBRepDS_ListOfInterference lII; TopOpeBRepDS_ListIteratorOfListOfInterference it1(lI);
646   while (it1.More()) {
647     const Handle(TopOpeBRepDS_Interference)& I = it1.Value();
648     Standard_Integer ITRASHA = I->Transition().Index();
649     if (mapftra.Contains(ITRASHA)) {it1.Next();}
650     else                           {lII.Append(I);lI.Remove(it1);}
651   }
652 
653   it1.Initialize(lII);
654   while (it1.More()) {
655     const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
656     TopOpeBRepDS_Kind GT1,ST1;  Standard_Integer G1,S1;   FDS_data(I1,GT1,G1,ST1,S1);
657     TopAbs_ShapeEnum SB1,SA1; Standard_Integer IB1,IA1; FDS_Tdata(I1,SB1,IB1,SA1,IA1);
658 
659     if (SB1 != TRASHAk) {it1.Next(); continue;}
660 
661     Standard_Boolean complex2d = Standard_False;
662     TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1);
663     if (it2.More()) it2.Next();
664     else break;
665     while (it2.More()){
666       const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
667       TopOpeBRepDS_Kind GT2,ST2;  Standard_Integer G2,S2;   FDS_data(I2,GT2,G2,ST2,S2);
668       TopAbs_ShapeEnum SB2,SA2; Standard_Integer IB2,IA2; FDS_Tdata(I2,SB2,IB2,SA2,IA2);
669 
670       Standard_Boolean cond = (SB1 == SB2) && (IB1 == IB2) && (IA1 == IA2);
671       if (!cond) {it2.Next(); continue;}
672 
673       Standard_Boolean sameG = (GT2 == GT1) && (G2 == G1);
674       Standard_Boolean sameST = (ST2 == ST1);
675       cond = sameG && sameST;
676       if (!cond) {it2.Next(); continue;}
677 
678       complex2d = (IB1==IB2);
679       if (TonFace) {
680 	const TopoDS_Face& F1 = TopoDS::Face(BDS.Shape(IB1));
681 	const TopoDS_Face& F2 = TopoDS::Face(BDS.Shape(IB2));
682 	complex2d = complex2d || FUN_ds_sdm(BDS,F1,F2);
683       }
684       if (complex2d) {l2dI.Append(I2); lII.Remove(it2);}
685       else           it2.Next();
686     } // it2
687     if (complex2d) {l2dI.Append(I1); lII.Remove(it1);}
688     else           it1.Next();
689   } // it1
690   lI.Append(lII);
691   n2d = l2dI.Extent();
692   return n2d;
693 }
694 
695 //------------------------------------------------------
FUN_selectpure2dI(const TopOpeBRepDS_ListOfInterference & lF,TopOpeBRepDS_ListOfInterference & lFE,TopOpeBRepDS_ListOfInterference & l2dFE)696 Standard_EXPORT Standard_Integer FUN_selectpure2dI
697 (const TopOpeBRepDS_ListOfInterference& lF, TopOpeBRepDS_ListOfInterference& lFE, TopOpeBRepDS_ListOfInterference& l2dFE)
698 //------------------------------------------------------
699 // <lFE> -> <lFE> + <l2dFE>
700 // <l2dFE> = {I2dFE = (T(face),G,S=edge) / we cannot find (T(face),G,face)}
701 {
702   l2dFE.Clear();
703   TopOpeBRepDS_ListIteratorOfListOfInterference itFE(lFE);
704   while (itFE.More()) {
705     const Handle(TopOpeBRepDS_Interference)& IFE = itFE.Value();
706     const TopOpeBRepDS_Transition& TFE = IFE->Transition();
707     Standard_Integer IB = TFE.IndexBefore(), IA = TFE.IndexAfter();
708     if (IB != IA) {itFE.Next(); continue;}
709 
710     Standard_Boolean foundIF = Standard_False;
711     for (TopOpeBRepDS_ListIteratorOfListOfInterference itF(lF); itF.More(); itF.Next()){
712       const Handle(TopOpeBRepDS_Interference)& IF = itF.Value();
713       Standard_Integer S = IF->Support();
714       if (S == IB) {foundIF = Standard_True; break;}
715     }
716     if (foundIF) {itFE.Next(); continue;}
717 
718     l2dFE.Append(IFE); lFE.Remove(itFE);
719   }
720   Standard_Integer n2dFE = l2dFE.Extent();
721   return n2dFE;
722 } // selectpure2dI
723 
724 //------------------------------------------------------
FUN_select1dI(const Standard_Integer SIX,TopOpeBRepDS_DataStructure & BDS,TopOpeBRepDS_ListOfInterference & LI,TopOpeBRepDS_ListOfInterference & l1dI)725 Standard_EXPORT Standard_Integer FUN_select1dI(const Standard_Integer SIX, TopOpeBRepDS_DataStructure& BDS,TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& l1dI)
726 //------------------------------------------------------
727 // attached to edge E : <lI>={I=(T(ES),G,ES)} -> <l1dI> + <lI>
728 // l1dI contains {(I1,I2) / I1=(T1(ES1),VG,ES1), I2=(T2(ES2),VG,ES2),
729 //                          E sdm ES1, ES2}
730 {
731   l1dI.Clear();
732   Standard_Integer n1d = 0;
733   Standard_Integer nFE = LI.Extent();
734   if (nFE <=1) return n1d;
735 
736   TopOpeBRepDS_ListOfInterference newLI;
737   const TopoDS_Shape& EIX = BDS.Shape(SIX);
738   TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LI);
739   for (tki.Init(); tki.More(); tki.Next()) {
740     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
741     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G); TopOpeBRepDS_ListOfInterference Rloi;
742     Standard_Integer nloi = loi.Extent();
743 
744     Standard_Boolean ok =   (K == TopOpeBRepDS_VERTEX);
745     ok = ok && (nloi > 1);
746     if (!ok) {newLI.Append(loi); continue;}
747 
748     TopOpeBRepDS_ListIteratorOfListOfInterference it1(loi);
749     while (it1.More()) {
750       const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
751       TopOpeBRepDS_Kind GT1,ST1;  Standard_Integer G1,S1;   FDS_data(I1,GT1,G1,ST1,S1);
752       TopAbs_ShapeEnum SB1,SA1; Standard_Integer IB1,IA1; FDS_Tdata(I1,SB1,IB1,SA1,IA1);
753 
754       Standard_Boolean cond1 = (SB1 == TopAbs_EDGE) && (IB1 == IA1);
755       if (!cond1) {newLI.Append(I1); it1.Next(); continue;}
756       cond1 = FUN_ds_sdm(BDS,EIX,BDS.Shape(S1));
757       if (!cond1) {newLI.Append(I1); it1.Next(); continue;}
758 
759       Standard_Boolean complex1d = Standard_False;
760       TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1);
761       if (it2.More()) it2.Next();
762       else break;
763       while (it2.More()){
764 	const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
765 	TopOpeBRepDS_Kind GT2,ST2;  Standard_Integer G2,S2;   FDS_data(I2,GT2,G2,ST2,S2);
766 	TopAbs_ShapeEnum SB2,SA2; Standard_Integer IB2,IA2; FDS_Tdata(I2,SB2,IB2,SA2,IA2);
767 
768 	Standard_Boolean cond2 = (SB1 == SB2) && (IB2 == IA2);
769 	if (!cond2) {newLI.Append(I2); it2.Next(); continue;}
770 	complex1d = FUN_ds_sdm(BDS,EIX,BDS.Shape(S2));
771 	if (!complex1d) {newLI.Append(I2); it2.Next(); continue;}
772 //                 LI.Extent(); //deb
773 	l1dI.Append(I2); it2.Next();
774       } // it2
775       if (complex1d) {l1dI.Append(I1); it1.Next();}
776       else           it1.Next();
777     } // it1
778   } // tki
779   LI.Clear(); LI.Append(newLI);
780   n1d = l1dI.Extent();
781   return n1d;
782 } // select1dI
783 
784 //------------------------------------------------------
FUN_select3dinterference(const Standard_Integer SIX,TopOpeBRepDS_DataStructure & BDS,TopOpeBRepDS_ListOfInterference & lF,TopOpeBRepDS_ListOfInterference & l3dF,TopOpeBRepDS_ListOfInterference & lFE,TopOpeBRepDS_ListOfInterference & lFEresi,TopOpeBRepDS_ListOfInterference & l3dFE,TopOpeBRepDS_ListOfInterference & l3dFEresi,TopOpeBRepDS_ListOfInterference & l2dFE)785 Standard_EXPORT void FUN_select3dinterference
786 (const Standard_Integer SIX, TopOpeBRepDS_DataStructure& BDS,
787  TopOpeBRepDS_ListOfInterference& lF, TopOpeBRepDS_ListOfInterference& l3dF,
788  TopOpeBRepDS_ListOfInterference& lFE, TopOpeBRepDS_ListOfInterference& lFEresi, TopOpeBRepDS_ListOfInterference& l3dFE, TopOpeBRepDS_ListOfInterference& l3dFEresi,
789  TopOpeBRepDS_ListOfInterference& l2dFE)
790 //------------------------------------------------------
791 {
792   const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(SIX));
793   Standard_Boolean isdg = BRep_Tool::Degenerated(E);
794   if (isdg) return;
795 
796   l3dF.Clear(); l3dFE.Clear();
797   // attached to an edge the list of interferences :
798   // IN  : <lF>  = {I=(T(face),G=POINT/VERTEX,S=FACE)}
799   //       <lFE> = {I=(T(face),G=POINT/VERTEX,S=EDGE)}
800 
801   // OUT : <lFE> -> <l3dFE> = {I describing 3d interferences on S=EDGE}
802   //                   is the list of 3d interferences to reduce
803   //                +<lFE> +lFEresi
804   //       <lF>  -> <l3dF> = {I describing 3d interferences on S=FACE}
805   //                +<lF>
806   //     I  = (T(face),G=POINT/VERTEX,S=EDGE) in <l3dFE>
807   // <-> I' = (T(face),G=POINT/VERTEX,S=FACE) in <l3dF>
808 
809   ::FUN_select3dI(SIX,BDS,lFE,lFEresi,l3dFE);
810   ::FUN_select3dISEsameISF(lFE,l3dFE,l3dFEresi,lF,l3dF);
811   FUN_select2dI(SIX,BDS,TopAbs_FACE,lFE,l2dFE);
812 }
813