Integration of OCCT 6.5.0 from SVN
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_EIR.cxx
1 // File: TopOpeBRepDS_EIR.cxx
2
3 #include <TopOpeBRepDS_EIR.ixx>
4 #include <BRep_Tool.hxx>
5 #include <TopExp.hxx>
6 #include <TopOpeBRepDS_CurvePointInterference.hxx>
7 #include <TopOpeBRepDS_Dumper.hxx>
8 #include <TopOpeBRepDS_Edge3dInterferenceTool.hxx>
9 #include <TopOpeBRepDS_EdgeInterferenceTool.hxx>
10 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
11 #include <TopOpeBRepDS_Interference.hxx>
12 #include <TopOpeBRepDS_TKI.hxx>
13 #include <TopoDS.hxx>
14 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
15 #include <TopOpeBRepTool_EXPORT.hxx>
16 #include <TopOpeBRepDS_EXPORT.hxx>
17 #include <TopOpeBRepDS_define.hxx>
18 #include <TopOpeBRepDS_repvg.hxx>
19 #include <TopOpeBRepDS_connex.hxx>
20 #include <TopOpeBRepTool_TOOL.hxx>
21 #ifdef DEB
22 #include <TopOpeBRepDS_reDEB.hxx>
23 Standard_EXPORT void debredpnc(const Standard_Integer ie){cout<<"+++ debredpnc e"<<ie<<endl;}
24 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GetcontextNOPNC();
25 #endif
26
27 #define M_FORWARD(O)  (O == TopAbs_FORWARD)
28 #define M_REVERSED(O) (O == TopAbs_REVERSED)
29 #define M_INTERNAL(O) (O == TopAbs_INTERNAL)
30 #define M_EXTERNAL(O) (O == TopAbs_EXTERNAL)
31
32 // modified by NIZHNY-MKK  Mon Apr  2 15:34:28 2001.BEGIN
33 static Standard_Boolean CheckInterferenceIsValid(const Handle(TopOpeBRepDS_Interference)& I, 
34                                                  const TopoDS_Edge&                       theEdge, 
35                                                  const TopoDS_Edge&                       theSupportEdge, 
36                                                  const TopoDS_Vertex&                     theVertex);
37 // modified by NIZHNY-MKK  Mon Apr  2 15:34:32 2001.END
38
39 //------------------------------------------------------
40 static void FDS_reduceONFACEinterferences(TopOpeBRepDS_ListOfInterference& LI,
41                                           const TopOpeBRepDS_DataStructure& /*BDS*/,
42                                           const Standard_Integer
43 #ifdef DEB
44                                                                   EIX
45 #endif
46                                           )
47 //------------------------------------------------------
48 {
49 #ifdef DEB
50   Standard_Boolean TRC=DSREDUEDGETRCE(EIX);
51   TRC = Standard_False; //MOINSTRACE
52   if (TRC) cout<<endl<<"reduceONFACEinterferences on "<<EIX<<" <- "<<LI.Extent()<<endl;
53 #endif
54
55   TopOpeBRepDS_ListIteratorOfListOfInterference it1;  // set hasONFACE = True if LI contains interfs with (ON,FACE) transition(s).
56   Standard_Boolean hasONFACE = Standard_False;
57   for (it1.Initialize(LI); it1.More(); it1.Next() ) {
58     Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
59     TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
60     if ( GT1 == TopOpeBRepDS_POINT ) {
61       hasONFACE = FUN_hasStateShape(I1->Transition(),TopAbs_ON,TopAbs_FACE);
62       if ( hasONFACE ) break;
63     }
64   }
65
66 #ifdef DEB
67   if(TRC){if( hasONFACE)cout<<"egde "<<EIX<<" has (ON,FACE)"<<endl;}
68   if(TRC){if(!hasONFACE)cout<<"egde "<<EIX<<" has no (ON,FACE)"<<endl;}
69 #endif
70
71   if ( hasONFACE ) {
72     // LI has (ON,FACE) : remove all other interf (POINT,(not(ON,FACE)))
73     it1.Initialize(LI);
74     while( it1.More() ) {
75       Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
76       TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
77       if ( GT1 == TopOpeBRepDS_POINT ) {
78         hasONFACE = FUN_hasStateShape(I1->Transition(),TopAbs_ON,TopAbs_FACE);
79         if ( ! hasONFACE ) {
80           LI.Remove(it1);
81         }
82         else it1.Next();
83       }
84       else it1.Next();
85     }
86   }
87
88 #ifdef DEB
89   if (TRC) cout<<"reduceONFACEinterferences E"<<EIX<<" -> "<<LI.Extent()<<endl<<endl;
90 #endif
91 }
92
93 //------------------------------------------------------
94 static void FUN_ReducerEdge3d(const Standard_Integer SIX, TopOpeBRepDS_DataStructure& BDS,
95                               TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& reducedLI)   
96 //------------------------------------------------------
97 // <LI> = { I3d = (TonFACE, G=POINT/VERTEX, S=EDGE) }
98 // {I3d} --reducing processing-> I3d' = (TonFACE, G=POINT/VERTEX, S=FACE) 
99 // <LI> -> <reducedLI> + <LI>
100 {
101   reducedLI.Clear();
102 #ifdef DEB
103   Standard_Boolean TRC=DSREDUEDGETRCE(SIX); 
104   TRC = Standard_False; //MOINSTRACE
105   if(TRC) {cout<<endl; debreducer3d(SIX);}
106   if (TRC) cout<<endl<<"ReducerEdge3d E"<<SIX<<" <- "<<LI.Extent()<<endl;
107 #endif
108   Standard_Integer n3d = LI.Extent(); 
109   if (n3d <= 1) return;
110   const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(SIX));
111   Standard_Integer rankE  = BDS.AncestorRank(E);
112   TopoDS_Shape OOv; Standard_Integer Gsta = 0;
113   
114   TopOpeBRepDS_ListIteratorOfListOfInterference it1;
115   it1.Initialize(LI);
116
117   // <-- jyl 231198 : cts21797
118   Standard_Integer nLI = LI.Extent();
119   if (nLI >= 1) {
120     while (it1.More()) {
121       const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
122       TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
123       TopAbs_ShapeEnum SB1,SA1; Standard_Integer IB1,IA1; FDS_Tdata(I1,SB1,IB1,SA1,IA1);
124       Standard_Boolean torem = Standard_False;
125       if (ST1 == TopOpeBRepDS_EDGE) {
126         const TopoDS_Edge& EE = TopoDS::Edge(BDS.Shape(S1));
127         const TopoDS_Face& FF = TopoDS::Face(BDS.Shape(IB1));
128         TopAbs_Orientation o; Standard_Boolean ok = FUN_tool_orientEinFFORWARD(EE,FF,o);
129         if (ok && (o == TopAbs_EXTERNAL)) torem = Standard_True;
130       }
131       if (torem) LI.Remove(it1);
132       else it1.Next();
133     }
134     nLI = LI.Extent();
135     if (nLI <= 1) return;
136   }
137   // --> jyl 231198 : cts21797
138
139   it1.Initialize(LI); 
140   while (it1.More()){
141
142     Standard_Boolean isComplex = Standard_False;
143     TopOpeBRepDS_Edge3dInterferenceTool EFITool;
144     const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
145     TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
146     TopAbs_ShapeEnum SB1,SA1; Standard_Integer IB1,IA1; FDS_Tdata(I1,SB1,IB1,SA1,IA1);
147
148     // modified by NIZHNY-MKK  Mon Apr  2 15:35:58 2001.BEGIN
149     TopoDS_Vertex aVertex;
150
151     if((GT1 == TopOpeBRepDS_VERTEX) && G1!=0) {
152       aVertex = TopoDS::Vertex(BDS.Shape(G1));
153     }
154
155     if(!CheckInterferenceIsValid(I1, E, TopoDS::Edge(BDS.Shape(S1)), aVertex)) {
156       LI.Remove(it1);
157       continue;
158     }
159     // modified by NIZHNY-MKK  Mon Apr  2 15:36:02 2001.END
160
161     TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1);
162     if (it2.More()) it2.Next();
163     else return;
164
165     while ( it2.More()){
166       const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
167       TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; FDS_data(I2,GT2,G2,ST2,S2);
168       TopAbs_ShapeEnum SB2,SA2; Standard_Integer IB2,IA2; FDS_Tdata(I2,SB2,IB2,SA2,IA2);
169
170       // modified by NIZHNY-MKK  Mon Apr  2 15:36:42 2001.BEGIN
171       aVertex.Nullify();
172
173       if((GT2 == TopOpeBRepDS_VERTEX) && G2!=0) {
174         aVertex = TopoDS::Vertex(BDS.Shape(G2));
175       }
176       
177       if(!CheckInterferenceIsValid(I2, E, TopoDS::Edge(BDS.Shape(S2)), aVertex)) {
178         LI.Remove(it2);
179         continue;
180       }
181       // modified by NIZHNY-MKK  Mon Apr  2 15:36:45 2001.END
182         
183       Standard_Boolean sameG = (GT2 == GT1) && (G2 == G1);
184       if (!sameG) break;
185
186       // <Gsta>, <OOv>
187       if (GT1 == TopOpeBRepDS_VERTEX) {
188         TopoDS_Vertex vG1 = TopoDS::Vertex(BDS.Shape(G1));
189         Standard_Integer rankvG1 = BDS.AncestorRank(vG1);
190         Standard_Integer sdG1; Standard_Boolean G1hsd = FUN_ds_getVsdm(BDS,G1,sdG1);    
191         if (rankvG1 != rankE) { // vG1 not on E
192           OOv = vG1;
193           Gsta = G1hsd? 3: 2;
194         }
195         else { // vG on E
196           if (G1hsd) OOv = BDS.Shape(sdG1); 
197           Gsta = G1hsd? 3: 1;
198         }
199       }      
200
201       const TopoDS_Face& F1 = TopoDS::Face(BDS.Shape(IB1));
202       const TopoDS_Face& F2 = TopoDS::Face(BDS.Shape(IB2)); // F2 != F1
203
204       Standard_Boolean sameS = (ST2 == ST1) && (S2 == S1);
205       if (!sameS) {
206         TopoDS_Shape Eshared; Standard_Boolean foundsh = FUN_tool_Eshared(OOv,F1,F2,Eshared);
207         if (!foundsh) return;
208
209         // modified by NIZHNY-MKK  Mon Apr  2 15:37:12 2001.BEGIN
210         if(!BDS.HasShape(Eshared)) {
211           return;
212         }
213         // modified by NIZHNY-MKK  Mon Apr  2 15:37:15 2001.END
214
215         S1 = S2 = BDS.Shape(Eshared);
216       }
217
218       const TopoDS_Edge& E1 = TopoDS::Edge(BDS.Shape(S1)); 
219       const TopoDS_Edge& E2 = TopoDS::Edge(BDS.Shape(S2)); // E2 == E1
220
221       Standard_Boolean sdm = FUN_ds_sdm(BDS,E,E1);
222       if (sdm) {
223 #ifdef DEB
224           if (TRC) cout<<"  NO I3d : e"<<SIX<<" same domain with e"<<S1<<endl;
225 #endif
226         it2.Next(); continue;
227       }
228
229       Standard_Boolean init = !isComplex;
230       Standard_Boolean isvertex = (GT1 == TopOpeBRepDS_VERTEX); 
231       init = init || isvertex; // !!!KK a revoir!!!!
232
233       if (init) {
234
235         // xpu : 04-03-98 : !!!KK a revoir!!!!
236         if (isComplex) {
237           Handle(TopOpeBRepDS_Interference) IBID = new TopOpeBRepDS_Interference();
238           EFITool.Transition(IBID);
239           I1->ChangeTransition().Set(IBID->Transition().Orientation(TopAbs_IN));
240         }
241         // !!!KK a revoir!!!!
242
243         if (!isComplex) EFITool.InitPointVertex(Gsta,OOv);
244         isComplex = Standard_True;
245         EFITool.Init(E,E1,F1,I1); 
246         EFITool.Add(E,E1,F1,I1);
247 #ifdef DEB
248         if(TRC){cout<<endl<<"complex T3d E"<<SIX<<endl;I1->Dump(cout,"init :","\n");} 
249 #endif  
250       } // !isComplex
251       
252 #ifdef DEB
253       if(TRC) I2->Dump(cout,"add : ","\n");
254 #endif    
255       EFITool.Add(E,E2,F2,I2);
256       LI.Remove(it2);
257       
258 #ifdef DEB
259       if(TRC){cout<<"resulting : "; Handle(TopOpeBRepDS_Interference) IBID = new TopOpeBRepDS_Interference();
260               EFITool.Transition(IBID);IBID->Transition().Dump(cout);cout<<endl;}
261 #endif  
262     } // it2
263
264     if (isComplex) {
265       Handle(TopOpeBRepDS_Interference) newI;
266       Handle(TopOpeBRepDS_Interference) IIBID = new TopOpeBRepDS_Interference();
267       EFITool.Transition(IIBID); 
268       TopOpeBRepDS_Transition T = IIBID->Transition(); T.Index(IB1);
269
270       Standard_Boolean isevi = I1->IsKind(STANDARD_TYPE(TopOpeBRepDS_EdgeVertexInterference));
271       Standard_Boolean iscpi = I1->IsKind(STANDARD_TYPE(TopOpeBRepDS_CurvePointInterference));
272       if (isevi) {
273         const Handle(TopOpeBRepDS_EdgeVertexInterference)& EVI = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I1);
274         newI = new TopOpeBRepDS_EdgeVertexInterference(T,TopOpeBRepDS_FACE,IB1,G1,EVI->GBound(),
275                           TopOpeBRepDS_UNSHGEOMETRY,EVI->Parameter());    
276       }
277       if (iscpi) {
278         const Handle(TopOpeBRepDS_CurvePointInterference)& CPI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I1);
279         newI = new TopOpeBRepDS_CurvePointInterference(T,TopOpeBRepDS_FACE,IB1,TopOpeBRepDS_POINT,G1,CPI->Parameter());         
280       }
281
282 #ifdef DEB
283       if (TRC){cout<<"reduced T E"<<SIX<<" ";newI->Dump(cout);cout<<endl;}
284 #endif
285       if (!newI.IsNull()) {
286         reducedLI.Append(newI);
287         LI.Remove(it1);
288       }
289     }
290     else 
291       it1.Next();
292   } // it1
293
294 #ifdef DEB
295   if (TRC) {
296     cout<<"ReducerEdge3d E"<<SIX<<" -> nIreduced "<<reducedLI.Extent();
297     cout<<" + nInonreduced "<<LI.Extent()<<endl<<endl;
298   }
299 #endif
300 }
301
302 //------------------------------------------------------
303 static void FUN_ReducerEdge(const Standard_Integer SIX,const TopOpeBRepDS_DataStructure& BDS,
304                             TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& reducedLI)
305 //------------------------------------------------------
306 {
307 #ifdef DEB
308   Standard_Boolean TRC=DSREDUEDGETRCE(SIX);
309 //  TRC = Standard_False; //MOINSTRACE
310   if (TRC) cout<<endl<<"ReducerEdge E"<<SIX<<" <- nI "<<LI.Extent()<<endl;
311 #endif
312   
313   FDS_repvg(BDS,SIX,TopOpeBRepDS_VERTEX,LI,reducedLI);
314   FDS_reduceONFACEinterferences(LI,BDS,SIX);
315   FDS_repvg(BDS,SIX,TopOpeBRepDS_POINT,LI,reducedLI);
316   
317 #ifdef DEB
318   if (TRC) cout<<"ReducerEdge E"<<SIX<<" -> nI "<<LI.Extent()<<endl<<endl;
319 #endif
320 }
321
322 //------------------------------------------------------
323 static void FUN_ReducerSDEdge(const Standard_Integer SIX,const TopOpeBRepDS_DataStructure& BDS,
324                               TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& reducedLI)
325 //------------------------------------------------------
326 {
327   reducedLI.Clear();
328   Standard_Integer nI = LI.Extent();
329 #ifdef DEB
330   Standard_Boolean TRC=DSREDUEDGETRCE(SIX);
331   TRC = Standard_False; //MOINSTRACE
332   if (TRC) cout<<endl<<"ReducerSDEdge E"<<SIX<<" <- nI "<<nI<<endl;  
333 #endif
334   if (nI <= 1) return;
335
336   TopOpeBRepDS_ListOfInterference newLI;
337   const TopoDS_Shape& EIX = BDS.Shape(SIX);
338   TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LI);
339   for (tki.Init(); tki.More(); tki.Next()) {
340     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
341     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G); TopOpeBRepDS_ListOfInterference Rloi;
342     
343     TopOpeBRepDS_ListIteratorOfListOfInterference it1(loi);
344     while (it1.More()) {
345       const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value(); const TopOpeBRepDS_Transition& T1 = I1->Transition();
346       TopAbs_Orientation O1 = T1.Orientation(TopAbs_IN); Standard_Integer IB1 = T1.Index();
347       Standard_Boolean cond1 = FUN_ds_sdm(BDS,EIX,BDS.Shape(IB1));  
348       if (!cond1) {newLI.Append(I1); it1.Next(); continue;}  
349  
350       Standard_Boolean complex1d = Standard_False;
351       TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1);
352       if (it2.More()) it2.Next();
353       else break;
354
355       TopOpeBRepDS_Transition T(TopAbs_IN,TopAbs_IN,TopAbs_EDGE,TopAbs_EDGE);
356       while (it2.More()){
357         const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value(); const TopOpeBRepDS_Transition& T2 = I2->Transition();
358         TopAbs_Orientation O2 = T2.Orientation(TopAbs_IN); Standard_Integer IB2 = T2.Index();
359         Standard_Boolean cond2 = FUN_ds_sdm(BDS,EIX,BDS.Shape(IB2));  
360         if (!cond2) {newLI.Append(I2); it2.Next(); continue;} 
361
362         complex1d =              (M_FORWARD(O1) && M_REVERSED(O2));
363         complex1d = complex1d || (M_FORWARD(O2) && M_REVERSED(O1)); 
364         if (!complex1d) {newLI.Append(I2); it2.Next(); continue;}
365
366         if (complex1d) {
367           Standard_Integer IB = (M_REVERSED(O1)) ? IB1 : IB2; T.IndexBefore(IB); 
368           Standard_Integer IA = (M_REVERSED(O1)) ? IB2 : IB1; T.IndexAfter(IA); 
369         }
370         loi.Remove(it2);
371         break; // no more than 2 interferences on sdmTRASHA at same G
372       } // it2
373
374       if (complex1d) {
375         const Handle(TopOpeBRepDS_EdgeVertexInterference)& EVI = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I1);
376         TopOpeBRepDS_Config cEIX=BDS.SameDomainOri(SIX), c1=BDS.SameDomainOri(IB1); 
377         TopOpeBRepDS_Config Conf = (cEIX == c1) ? TopOpeBRepDS_SAMEORIENTED : TopOpeBRepDS_DIFFORIENTED;
378         Handle(TopOpeBRepDS_Interference) newI = new TopOpeBRepDS_EdgeVertexInterference(T,TopOpeBRepDS_EDGE,IB1,G,EVI->GBound(),Conf,EVI->Parameter());        
379         reducedLI.Append(newI);
380         it1.Next();
381       }
382       else {
383         newLI.Append(I1);
384         loi.Remove(it1);
385       }
386     } // it1    
387   } // tki
388   
389   LI.Clear(); LI.Append(newLI);
390
391 #ifdef DEB
392   if (TRC) cout<<"ReducerSDEdge E"<<SIX<<" -> nI "<<LI.Extent()<<endl<<endl;
393 #endif
394 }
395
396 //------------------------------------------------------
397 static void FUN_reclSE2(const Standard_Integer SIX,const TopOpeBRepDS_DataStructure& BDS,
398                         TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& reducedLI)
399 //------------------------------------------------------
400 // reducing LI = {I = (T(edge),G0,edge)}
401 //  edge <SIX> is same domain with edge <SE>
402 //  {I1 = (OU/IN(SE),VG,SE) 
403 //  I2 = (IN/OU(SE),VG,SE))} -> Ir = (IN/IN(SE),VG,SE)
404 {
405   reducedLI.Clear();
406   Standard_Integer nI = LI.Extent(); // DEB
407
408   const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(SIX));
409
410 #ifdef DEB
411   Standard_Boolean TRC=DSREDUEDGETRCE(SIX);
412   TRC = Standard_False; //MOINSTRACE
413   if (TRC) cout<<endl<<"reclSE2 E"<<SIX<<" <- nI "<<nI<<endl;
414 #endif   
415
416     TopOpeBRepDS_ListIteratorOfListOfInterference it1(LI);
417     while (it1.More()) {
418       const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
419       TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I1,GT1,G1,ST1,S1);
420
421       const TopOpeBRepDS_Transition& T1 = I1->Transition(); TopAbs_Orientation O1 = T1.Orientation(TopAbs_IN);
422       if (M_INTERNAL(O1) || M_EXTERNAL(O1)) {it1.Next(); continue;}
423       TopAbs_Orientation cO1 = TopAbs::Complement(O1);
424
425       const TopoDS_Vertex& v1 = TopoDS::Vertex(BDS.Shape(G1));      
426       const TopoDS_Edge& E1 = TopoDS::Edge(BDS.Shape(S1));
427       TopoDS_Vertex vclo1; Standard_Boolean iscE1 = TopOpeBRepTool_TOOL::ClosedE(E1,vclo1);
428       if (!iscE1)            {it1.Next(); continue;}
429       if (!vclo1.IsSame(v1)) {it1.Next(); continue;}
430
431       Standard_Boolean sdm = FUN_ds_sdm(BDS,E,E1);
432       if (!sdm) {it1.Next(); continue;}
433
434       Standard_Boolean hascO = Standard_False;
435       TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1); 
436       if (it2.More()) it2.Next(); 
437       else {it1.Next(); continue;}
438       while ( it2.More()){ 
439         const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
440         const TopOpeBRepDS_Transition& T2 = I2->Transition(); TopAbs_Orientation O2 = T2.Orientation(TopAbs_IN);
441         TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; FDS_data(I2,GT2,G2,ST2,S2);
442         
443         if (S1 != S2)  {it2.Next(); continue;}
444         if (O2 != cO1) {it2.Next(); continue;}
445         
446         LI.Remove(it2);
447         nI = LI.Extent(); // DEB
448         hascO = Standard_True; break;
449       } //it2
450       
451       if (hascO) {
452         I1->ChangeTransition().Set(TopAbs_INTERNAL);
453         reducedLI.Append(I1); LI.Remove(it1);
454         nI = LI.Extent(); // DEB
455       }
456       else it1.Next();
457     } //it1
458
459 #ifdef DEB
460   if (TRC) cout<<"reclSE2 E"<<SIX<<" -> nI "<<LI.Extent()<<endl<<endl;
461 #endif
462 } // FUN_reclSE2
463
464 //------------------------------------------------------
465 Standard_EXPORT void FUN_reclSE(const Standard_Integer EIX,const TopOpeBRepDS_DataStructure& BDS,
466                                 TopOpeBRepDS_ListOfInterference& LOI,TopOpeBRepDS_ListOfInterference& RLOI)
467 //------------------------------------------------------
468 {
469   TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LOI);
470 #ifdef DEB
471   Standard_Boolean TRC=DSREDUEDGETRCE(EIX);
472   TRC = Standard_False; //MOINSTRACE
473   if (TRC) cout<<endl<<"reclSE E"<<EIX<<" <- "<<LOI.Extent()<<endl;
474   if (TRC) tki.DumpTKIIterator("","\n");
475 #endif
476
477   LOI.Clear();
478   for (tki.Init(); tki.More(); tki.Next()) {
479     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
480     if (K != TopOpeBRepDS_VERTEX) continue; 
481     
482 #ifdef DEB
483     if (TRC) {tki.DumpTKI(K,G,"","\n");}
484 #endif
485     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G); TopOpeBRepDS_ListOfInterference Rloi;
486     Standard_Integer nloi = loi.Extent();
487     if      (nloi == 0) continue;
488     else if (nloi == 1) LOI.Append(loi);
489     else {
490       FUN_reclSE2(EIX,BDS,loi,Rloi);  
491       LOI.Append(loi); RLOI.Append(Rloi);
492     }
493   }
494
495 #ifdef DEB
496   if (TRC) cout<<"reclSE E"<<EIX<<" -> reste "<<LOI.Extent()<<" + reduit "<<RLOI.Extent()<<endl<<endl;
497 #endif
498 } // FUN_reclSE
499
500 //------------------------------------------------------
501 static void FUN_unkeepEVIonGb1(const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer EIX,TopOpeBRepDS_ListOfInterference& LI)
502 //------------------------------------------------------
503 // LI = {I attached to <E> = (T,G,S)}, unkeep I = EVI with G = vertex of <E>
504 {
505
506 #ifdef DEB
507   Standard_Boolean TRC=DSREDUEDGETRCE(EIX);
508   TRC = Standard_False; //MOINSTRACE
509   if (TRC) {cout<<endl;debreducerE(EIX);}
510 #endif
511
512   const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(EIX));
513   
514   TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
515   while (it.More()) {
516     const Handle(TopOpeBRepDS_Interference)& I = it.Value();
517     Standard_Boolean evi = I->IsKind(STANDARD_TYPE(TopOpeBRepDS_EdgeVertexInterference));
518     if (!evi) {it.Next(); continue;}
519     TopOpeBRepDS_Kind GT,ST; Standard_Integer G,S; FDS_data(I,GT,G,ST,S);
520     if (GT != TopOpeBRepDS_VERTEX){it.Next(); continue;}
521
522     const TopoDS_Vertex& V = TopoDS::Vertex(BDS.Shape(G));
523     Standard_Integer o = FUN_tool_orientVinE(V,E);
524     if (o == 0){it.Next(); continue;}
525 #ifdef DEB
526     if (TRC) {cout<<"-> rejet EVI on Gb 1 on "<<EIX<<" : ";I->Dump(cout);cout<<endl;}
527 #endif
528     LI.Remove(it);
529   }
530 }
531
532 // ---------------------------------------------------------
533 //unreferenced function, commented
534 /*#ifdef DEB
535 static void FUN_reorder(const Standard_Integer EIX, const Handle(TopOpeBRepDS_HDataStructure)& HDS,TopOpeBRepDS_ListOfInterference& LIR, TopOpeBRepDS_ListOfInterference& LI, TopOpeBRepDS_ListOfInterference& LIend)
536 // ---------------------------------------------------------
537 // at same G :in <LI>  I  =(T, G, S)
538 //            in <LRI> Ir =(Tr,G,Sr)
539 // I gives less information than reduced Ir   
540 {
541
542   Standard_Boolean TRC=DSREDUEDGETRCE(EIX);
543   TRC = Standard_False; //MOINSTRACE
544   if (TRC) cout<<endl<<"FUN_reorder :"<<endl;
545   TopOpeBRepDS_Dumper DSD(HDS); 
546
547   LIend.Clear();
548
549   TopOpeBRepDS_TKI tki;
550   tki.FillOnGeometry(LI);
551
552   TopOpeBRepDS_TKI tkiR;
553   tkiR.FillOnGeometry(LIR); 
554   
555   for (tkiR.Init(); tkiR.More(); tkiR.Next()) {
556     TopOpeBRepDS_Kind K; Standard_Integer G; tkiR.Value(K,G);
557
558     tki.Init();
559     Standard_Boolean isbound = tki.IsBound(K,G);
560     if (!isbound) continue;
561
562     TopOpeBRepDS_ListOfInterference& loiR = tkiR.ChangeValue(K,G);
563     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G);
564 #ifdef DEB
565     if (TRC) {TCollection_AsciiString bb("lIreduced");bb += TCollection_AsciiString(G);DSD.DumpLOI(loiR,cout,bb);
566               TCollection_AsciiString aa("lI");aa+=TCollection_AsciiString(G);DSD.DumpLOI(loi,cout,aa);}
567 #endif
568     loiR.Append(loi);
569   }
570   
571 #ifdef DEB
572     if (TRC) cout<<"-> ordered :"<<endl;
573 #endif
574   for (tkiR.Init(); tkiR.More(); tkiR.Next()) {
575     TopOpeBRepDS_Kind K; Standard_Integer G; TopOpeBRepDS_ListOfInterference& loi = tkiR.ChangeValue(K,G);
576 #ifdef DEB
577     if (TRC) {TCollection_AsciiString aa("lI");aa+=TCollection_AsciiString(G);DSD.DumpLOI(loi,cout,aa);}
578 #endif
579     LIend.Append(loi);
580   }
581
582 #ifdef DEB
583     if (TRC) cout<<"-> residual :"<<endl;
584 #endif
585   for (tki.Init(); tki.More(); tki.Next()) {
586     TopOpeBRepDS_Kind K; Standard_Integer G; TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G);
587 #ifdef DEB
588     if (TRC) {TCollection_AsciiString aa("lI");aa+=TCollection_AsciiString(G);DSD.DumpLOI(loi,cout,aa);}
589 #endif
590     LIend.Append(loi);
591   }
592 }
593 #endif
594 */
595
596 static void FUN_keepl3dF(const Standard_Integer
597 #ifdef DEB
598                                                 SIX
599 #endif
600                          ,const Handle(TopOpeBRepDS_HDataStructure)&
601 #ifdef DEB
602                                                 HDS
603 #endif
604                          ,const TopOpeBRepDS_ListOfInterference& l3dF
605                          ,const TopOpeBRepDS_ListOfInterference& LR3dFE,
606                          TopOpeBRepDS_ListOfInterference& l3dFkeep)
607 //purpose : soit I de l3dF, on cherche IR interf dans LR3dFE de meme geometrie
608 //          si on n'en trouve pas, l3dFkeep += I
609 {
610 #ifdef DEB
611   Standard_Boolean TRC=DSREDUEDGETRCE(SIX);
612   TRC = Standard_False; //MOINSTRACE
613   if (TRC) cout<<endl<<"keepl3dF E"<<SIX<<endl;
614   TopOpeBRepDS_Dumper DSD(HDS); 
615 #endif
616
617   TopOpeBRepDS_TKI tki;
618   tki.FillOnGeometry(l3dF);
619
620   TopOpeBRepDS_TKI tkiR;
621   tkiR.FillOnGeometry(LR3dFE); 
622   
623   for (tki.Init(); tki.More(); tki.Next()) {
624     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
625     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G);
626     tkiR.Init();
627     Standard_Boolean isbound = tkiR.IsBound(K,G);
628     if (!isbound) {l3dFkeep.Append(loi);}
629
630 #ifdef DEB
631     if (TRC) {TCollection_AsciiString bb("l3dFkeep");bb += TCollection_AsciiString(G);DSD.DumpLOI(loi,cout,bb);cout<<endl;}
632 #endif
633   }  
634 } // FUN_keepl3dF
635
636 static void FUN_reducepure2dI0(TopOpeBRepDS_ListOfInterference& LI, TopOpeBRepDS_ListOfInterference& RLI)
637 // xpu210798 : CTS21216 (e7,G=P3,S=E9,FTRASHA=f8,f10)
638 //  LI attached to section edge
639 //  2dI1=(REVERSED(ftrasha1),G,ES), 2dI2=(FORWARD(ftrasha2),G,ES)
640 //  for the compute of splitON(EIX), reduce 2dI1+2dI2 -> 2dR=(IN(ftrasha1,ftrasha2)
641 // LI-> RLI + LI
642 {
643   const Handle(TopOpeBRepDS_Interference)& I1 = LI.First();
644   TopAbs_Orientation O1 = I1->Transition().Orientation(TopAbs_IN);
645   TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; TopAbs_ShapeEnum tsb1,tsa1; Standard_Integer isb1,isa1; 
646   FDS_Idata(I1,tsb1,isb1,tsa1,isa1,GT1,G1,ST1,S1);
647   
648   const Handle(TopOpeBRepDS_Interference)& I2 = LI.Last();
649   TopAbs_Orientation O2 = I2->Transition().Orientation(TopAbs_IN);
650   TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; TopAbs_ShapeEnum tsb2,tsa2; Standard_Integer isb2,isa2; 
651   FDS_Idata(I2,tsb2,isb2,tsa2,isa2,GT2,G2,ST2,S2);
652   
653   if (isb1 == isb2) return; //xpu170898 FOR+REV ->INT/EXT (cto009B1(es6,p1,f9))
654
655   // recall : G1==G2 && ST1==ST2==EDGE
656   Standard_Boolean ok = (G1==G2);
657   ok = ok && (tsb1 == TopAbs_FACE) && (tsb1==tsb2) && (isb1==isa1) && (isb2==isa2);
658   if (!ok) return;
659
660   Standard_Boolean int12 = M_REVERSED(O1) && M_FORWARD(O2);
661   Standard_Boolean int21 = M_REVERSED(O2) && M_FORWARD(O1);
662   ok = int12 || int21;
663   if (!ok) return;
664
665   TopOpeBRepDS_Transition newT(TopAbs_INTERNAL);
666   Standard_Integer bef = int12? isb1 : isb2;
667   Standard_Integer aft = int21? isb1 : isb2; 
668   newT.IndexBefore(bef); newT.IndexAfter(aft);
669   I1->ChangeTransition() = newT;
670   RLI.Append(I1);
671   LI.Clear();
672 } // FUN_reducepure2dI0
673
674 static void FUN_reducepure2dI(TopOpeBRepDS_ListOfInterference& LI, TopOpeBRepDS_ListOfInterference& RLI)
675 {  
676   TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LI);
677   TopOpeBRepDS_ListOfInterference newLI;
678   for (tki.Init(); tki.More(); tki.Next()) {
679     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
680     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G); TopOpeBRepDS_ListOfInterference Rloi;
681     Standard_Integer nloi = loi.Extent();
682     Standard_Boolean ok = (nloi == 2) && (K == TopOpeBRepDS_POINT);
683     if (ok) ::FUN_reducepure2dI0(loi,Rloi);
684     RLI.Append(Rloi);
685     newLI.Append(loi);
686   }
687   LI.Clear(); LI.Append(newLI);
688 } // FUN_reducepure2dI
689
690 //=======================================================================
691 //function : TopOpeBRepDS_EIR
692 //purpose  : 
693 //=======================================================================
694 TopOpeBRepDS_EIR::TopOpeBRepDS_EIR
695 (const Handle(TopOpeBRepDS_HDataStructure)& HDS) : myHDS(HDS)
696 {}
697
698 //=======================================================================
699 //function : ProcessEdgeInterferences
700 //purpose  : 
701 //=======================================================================
702 void TopOpeBRepDS_EIR::ProcessEdgeInterferences()
703 {
704   TopOpeBRepDS_DataStructure& BDS = myHDS->ChangeDS();
705   Standard_Integer i,nshape = BDS.NbShapes();
706   for (i = 1; i <= nshape; i++) {
707     const TopoDS_Shape& S = BDS.Shape(i);
708     if(S.IsNull()) continue;
709     if ( S.ShapeType() == TopAbs_EDGE ) {
710       ProcessEdgeInterferences(i);
711     }
712   }
713 }
714 static void FUN_ProcessEdgeInterferences(const Standard_Integer EIX
715                                          , const TopOpeBRepDS_Kind
716 #ifdef DEB
717                                                                  K
718 #endif
719                                          ,const Standard_Integer
720 #ifdef DEB
721                                                                  G
722 #endif
723                                          , const Handle(TopOpeBRepDS_HDataStructure)& HDS, 
724                                          TopOpeBRepDS_ListOfInterference& LI)
725 {
726   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
727   const TopoDS_Shape& E = BDS.Shape(EIX);
728 #ifdef DEB
729   Standard_Boolean TRC=DSREDUEDGETRCE(EIX);
730   if (TRC) {
731     cout<<endl;debreducerE(EIX);cout<<"EIR E"<<EIX;
732     if(K==TopOpeBRepDS_POINT)cout<<",point";
733     else                     cout<<",vertex";
734     cout<<G<<endl;
735   }
736 #endif
737
738   Standard_Integer nF = 0, nE = 0, nFE = 0;
739
740   // LI -> (lF + lFE) + lE + [LI]
741   // lF  = {interference on edge <EIX> :  (T(face),G=POINT/VERTEX,S)
742   // lFE = {interference on edge <EIX> :  (T(face),G=POINT/VERTEX,S=EDGE)
743   // lE  = {interference on edge <EIX> :  (T(edge),G=POINT/VERTEX,S)
744   TopOpeBRepDS_ListOfInterference lF; nF = FUN_selectTRASHAinterference(LI,TopAbs_FACE,lF);
745   TopOpeBRepDS_ListOfInterference lFE; nFE = FUN_selectSKinterference(lF,TopOpeBRepDS_EDGE,lFE);
746   TopOpeBRepDS_ListOfInterference lE; nE = FUN_selectTRASHAinterference(LI,TopAbs_EDGE,lE);
747
748 #ifdef DEB 
749   TopOpeBRepDS_Dumper DSD(HDS);       
750   Standard_Boolean trcl = TRC;
751 //  trcl = Standard_False; // MOINSTRACE
752 #endif
753
754   // xpu210798 : CTS21216 (e7,G=P3,S=E9,FTRASHA=f8,f10)
755   //   EIX is section edge
756   //   2dI1=(REVERSED(ftrasha1),G,ES), 2dI2=(FORWARD(ftrasha2),G,ES)
757   //   for the compute of splitON(EIX), reduce 2dI1+2dI2 -> 2dR=(IN(ftrasha1,ftrasha2)
758   Standard_Boolean isse = BDS.IsSectionEdge(TopoDS::Edge(E));
759   if (isse) {
760     TopOpeBRepDS_ListOfInterference lI2dFE,lRI2dFE;
761     // lF  -> lF
762     // lFE -> lI2dFE + [lFE] / lI2dFE={FEI=(T(FTRASHA),G,SE) : no FFI=(T(FTRASHA),G,FTRASHA)}
763     FUN_selectpure2dI(lF,lFE,lI2dFE);
764 #ifdef DEB
765     if (trcl) {
766       cout<<endl<<"lI2dFE -> lRI2dFE + lI2dFE"<<endl;
767       TCollection_AsciiString aa("lI2dFE  :"); DSD.DumpLOI(lI2dFE,cout,aa);
768     }
769 #endif    
770     ::FUN_reducepure2dI(lI2dFE,lRI2dFE); // lI2dFE -> lRI2dFE + lI2dFE
771 #ifdef DEB
772     if (trcl) { TCollection_AsciiString bb("lRI2dFE  :"); DSD.DumpLOI(lRI2dFE,cout,bb);}
773 #endif
774     lFE.Append(lI2dFE); lFE.Append(lRI2dFE);
775   }
776
777   // I -> 3dI +2dI + 1dI:
778   // -------------------
779   // lFE -> l3dFE [+l3dFEresi] +l2dFE [+lFE (+lFEresi)]
780   //    : l3dFE={I3d } to reduce; for I3dFE=(T(F),G,SE) there is I3dF=(T(F),G,F)
781   //      l2dFE={I2d} to reduce
782   //      lFEresi to remove 
783   // lF  -> l3dF [+lF] : l3dF to remove
784
785   // lE  -> l1dE +l1dEsd [+lE}
786   //    : l1dE={I1d=(T(ETRA),G,ETRA)/same ETRA} to reduce
787   //      l2dEsd={I1dsd=(T(ETRA),G,ETRA)/ E sdm ETRA}
788
789   TopOpeBRepDS_ListOfInterference lFEresi,l3dFE,l3dF,l3dFEresi,l2dFE;
790   FUN_select3dinterference(EIX,BDS,lF,l3dF,
791                            lFE,lFEresi,l3dFE,l3dFEresi,
792                            l2dFE);
793   TopOpeBRepDS_ListOfInterference l1dE; FUN_select2dI(EIX,BDS,TopAbs_EDGE,lE,l1dE);
794   TopOpeBRepDS_ListOfInterference l1dEsd; FUN_select1dI(EIX,BDS,lE,l1dEsd);
795
796 #ifdef DEB
797   if (trcl) {
798     cout<<"lFE("<<EIX<<") -> l3dFE (S=EDGE) [+l3dFEresi] + l2dFE  + [lFE +lFEresi]"<<endl;
799     TCollection_AsciiString oo("lFE :");DSD.DumpLOI(lFE,cout,oo);
800     TCollection_AsciiString pp("lFEresi :");DSD.DumpLOI(lFEresi,cout,pp);
801     TCollection_AsciiString bb("l3dFE :");DSD.DumpLOI(l3dFE,cout,bb);
802     TCollection_AsciiString bb1("l3dFEresi :");DSD.DumpLOI(l3dFEresi,cout,bb1);
803     TCollection_AsciiString ll("l2dFE :");DSD.DumpLOI(l2dFE,cout,ll);
804     cout<<"lF("<<EIX<<")  -> l3dF  (S=FACE)          [+lF]"<<endl;
805     TCollection_AsciiString cc("lF :");   DSD.DumpLOI(lF,cout,cc);
806     TCollection_AsciiString aa("l3dF :"); DSD.DumpLOI(l3dF,cout,aa);
807     cout<<"lE("<<EIX<<")  -> l1dE + lE"<<endl;
808     TCollection_AsciiString ee("lE :");   DSD.DumpLOI(lE,cout,ee);
809     TCollection_AsciiString ff("l1dE :"); DSD.DumpLOI(l1dE,cout,ff);
810     TCollection_AsciiString gg("l1dEsd :"); DSD.DumpLOI(l1dEsd,cout,gg);}
811 #endif
812
813   // reducer3d :
814   // ----------
815   // l3dFE -> lR3dFE [+l3dFE (non reduced 3dI)]
816   TopOpeBRepDS_ListOfInterference lR3dFE; FUN_ReducerEdge3d(EIX,BDS,l3dFE,lR3dFE);
817 #ifdef DEB
818   if (trcl) { cout<<"l3dFE("<<EIX<<") -> lR3dFE + l3dFE"<<endl;
819               TCollection_AsciiString aa("lR3dFE :");DSD.DumpLOI(lR3dFE,cout,aa);
820               TCollection_AsciiString bb("l3dFE :"); DSD.DumpLOI(l3dFE,cout,bb);}
821 #endif
822
823 //  FUN_unkeepEVIonGb1(BDS,EIX,l1dE);  // filter : 
824 //  FUN_unkeepEVIonGb1(BDS,EIX,l2dFE); // filter : 
825
826   // no reduction on G : we keep l3dF(G)
827   TopOpeBRepDS_ListOfInterference l3dFkeep; FUN_keepl3dF(EIX,HDS,l3dF,lR3dFE,l3dFkeep);
828   lF.Append(l3dFkeep);
829
830   // reducer2d :
831   // ----------
832   // l2dFE -> LR2dFE + l2dFE (non reduced 2dI)
833   TopOpeBRepDS_ListOfInterference LR2dFE; FUN_ReducerEdge(EIX,BDS,l2dFE,LR2dFE);
834
835   // reducer1d :
836   // ----------
837   // xpu210498 : reduce interferences I1(T1(esd1),VG,esd1), I2(T2(esd2),VG,esd2)
838   // if EIX sdm {esd1,esd2}
839   // - t2_2 e32 has I1(in/ou(e32),v30,e20) && I2(ou/in(e20),v30,e20) -
840   TopOpeBRepDS_ListOfInterference lR1dEsd; FUN_ReducerSDEdge(EIX,BDS,l1dEsd,lR1dEsd);
841
842   // xpu190298 : edge <EIX> same domain with closed support edge <SE>
843   // at same G = vertex <VG>  = closing vertex of <SE>
844   //  (I1 = (OU/IN(SE),VG,SE) && I2 = (IN/OU(SE),VG,SE)) -> Ir = (IN/IN(SE),VG,SE)
845   TopOpeBRepDS_ListOfInterference lR1dclosedSE; FUN_reclSE(EIX,BDS,l1dE,lR1dclosedSE);  
846
847   // l1dE  -> LR1dE + l1dE (non reduced 2dI)
848   TopOpeBRepDS_ListOfInterference LR1dE;  FUN_ReducerEdge(EIX,BDS,l1dE,LR1dE);
849
850   //  attached to edge <EIX>,
851   //  at same G : I  =(T,  G,S)   gives less information than
852   //              Ir =(Tr,G,Sr) -reduced interference- with valid Tr 
853   //  -> unkeep I.
854   // using reduced I : lR3dFE, LR2dFE, LR1dE
855   TopOpeBRepDS_ListOfInterference LRI; 
856   LRI.Append(lR1dEsd); LRI.Append(LR1dE); LRI.Append(lR1dclosedSE);
857   LRI.Append(LR2dFE);
858   LRI.Append(lR3dFE);
859
860   lF.Append(lFE); lF.Append(l3dFE); lF.Append(l2dFE);// lF += LFE + l3dFE + l2dFE
861   lE.Append(l1dE);                                   // lE += l1dE
862   lE.Append(l1dEsd);                                 // lE += l1dEsd xpu210498
863 //  TopOpeBRepDS_ListOfInterference LItmp; LItmp.Append(lF); LItmp.Append(lE);
864
865   // xpu : 23-01-98 : attached to edge <EIX>,
866   //  at same G : I  =(T, G, S) gives less information than
867   //              Ir =(Tr,G,Sr) -reduced interference- 
868   //  -> I is added after Ir to help the edge builder.
869   LI.Clear(); 
870   LI.Append(LRI);LI.Append(lE);LI.Append(lF);
871 //  FUN_reorder(EIX,HDS,LRI, LItmp, LI); 
872   
873   // xpu260698 : cto902A5, spOU(e6)
874   //             cto801G1, spON(se26) 
875   if (isse) {
876     FUN_unkeepEVIonGb1(BDS,EIX,LI);  // filter : 
877   }
878 //FUN_unkeepEVIonGb1(BDS,EIX,LI);  // filter : 
879   
880 #ifdef DEB
881   if (TRC){TCollection_AsciiString aa("reduced->");DSD.DumpLOI(LI,cout,aa);}
882 #endif
883 } // ProcessEdgeInterferences
884
885 //=======================================================================
886 //function : ProcessEdgeInterferences
887 //purpose  : 
888 //=======================================================================
889 void TopOpeBRepDS_EIR::ProcessEdgeInterferences(const Standard_Integer EIX)
890 {
891   TopOpeBRepDS_DataStructure& BDS = myHDS->ChangeDS();
892
893 #ifdef DEB
894   TopOpeBRepDS_Dumper DSD(myHDS);       
895   Standard_Boolean TRC=DSREDUEDGETRCE(EIX);
896   if (TRC) {cout<<endl;debreducerE(EIX);}
897 #endif
898
899   // E is the edge, LI is list of interferences to compact
900   const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(EIX));
901   Standard_Boolean isdg = BRep_Tool::Degenerated(E);
902   if (isdg) return;
903
904   TopOpeBRepDS_ListOfInterference& LI = BDS.ChangeShapeInterferences(EIX);
905   TopOpeBRepDS_TKI newtki; newtki.FillOnGeometry(LI);
906   TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LI);
907   for (tki.Init(); tki.More(); tki.Next()) {
908     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
909     const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
910     if (K==TopOpeBRepDS_POINT) continue;
911     const TopoDS_Shape& vG = BDS.Shape(G);
912     TopoDS_Shape oovG; Standard_Boolean sdm = FUN_ds_getoov(vG,BDS,oovG);
913     if (!sdm) continue;
914     Standard_Integer OOG=BDS.Shape(oovG);
915     if (OOG == 0) continue;//NYIRaise
916
917     Standard_Boolean isb = newtki.IsBound(K,OOG);
918
919     // xpu201098 : cto904F6, e10,v6
920     Standard_Boolean isbound = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(loi.First())->GBound();
921     if (isbound) { // replacing vG with oovG
922       TopOpeBRepDS_ListIteratorOfListOfInterference it(loi); TopOpeBRepDS_ListOfInterference newloi;
923       for (; it.More(); it.Next()){
924         const Handle(TopOpeBRepDS_Interference)& I = it.Value();
925         TopOpeBRepDS_Kind GT,ST;
926         Standard_Integer G1,S;
927         FDS_data(I,GT,G1,ST,S);
928         Standard_Real par = FDS_Parameter(I);
929         Handle(TopOpeBRepDS_Interference) newI = MakeEPVInterference(I->Transition(),S,OOG,par,K,ST,Standard_False);
930         newloi.Append(newI);
931 #ifdef DEB
932         if (TRC) {cout<<"on e"<<EIX;I->Dump(cout);cout<<"gives ";newI->Dump(cout);cout<<endl;}
933 #endif
934       }
935       newtki.ChangeInterferences(K,G).Clear();
936       if (!isb) newtki.Add(K,OOG);
937       newtki.ChangeInterferences(K,OOG).Append(newloi);
938       continue;
939     }
940
941     if (!isb) continue;
942     TopOpeBRepDS_ListOfInterference& li = newtki.ChangeInterferences(K,OOG);
943     newtki.ChangeInterferences(K,G).Append(li);
944   } // tki
945
946   TopOpeBRepDS_ListOfInterference LInew;
947   for (newtki.Init(); newtki.More(); newtki.Next()) {
948     TopOpeBRepDS_Kind K; Standard_Integer G; newtki.Value(K,G);
949     TopOpeBRepDS_ListOfInterference& loi = newtki.ChangeValue(K,G);
950     ::FUN_ProcessEdgeInterferences(EIX,K,G,myHDS,loi);
951     LInew.Append(loi);
952   }
953   LI.Clear();
954   LI.Append(LInew);
955
956   Standard_Boolean performPNC = Standard_False; // JYL 28/09/98 : temporaire
957 #ifdef DEB
958   if (TopOpeBRepDS_GetcontextNOPNC()) performPNC = Standard_False;
959   if (TRC) debredpnc(EIX);
960 #endif
961   if (!performPNC) return;
962
963   // suppression des I/G(I) n'est accede par aucune courbe
964   // portee par une des faces cnx a EIX.
965   Standard_Boolean isfafa = BDS.Isfafa();
966   if (!isfafa) {
967
968     tki.Clear();
969     tki.FillOnGeometry(LI);
970     LI.Clear();
971
972     for (tki.Init(); tki.More(); tki.Next()) {
973       TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
974       TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G);
975       Standard_Integer nloi = loi.Extent();
976       if (K != TopOpeBRepDS_POINT) {
977         LI.Append(loi);
978         continue;
979       }
980
981       const TopTools_ListOfShape& lfx = FDSCNX_EdgeConnexitySameShape(E,myHDS);
982 #ifdef DEB
983 //      Standard_Integer nlfx = lfx.Extent();
984 #endif
985
986       // nlfx < 2 => 0 ou 1 face accede E => pas d'autre fcx pouvant generer une courbe 3d
987       TopTools_ListIteratorOfListOfShape itlfx(lfx);
988       Standard_Boolean curvefound = Standard_False;
989       for (; itlfx.More();itlfx.Next()) {
990         const TopoDS_Face& fx = TopoDS::Face(itlfx.Value());
991 //                  BDS.Shape(fx);
992         const TopOpeBRepDS_ListOfInterference& lifx = BDS.ShapeInterferences(fx); TopOpeBRepDS_ListIteratorOfListOfInterference itlifx(lifx);
993         if (!itlifx.More()) continue;
994         
995         Handle(TopOpeBRepDS_Interference) I1;TopOpeBRepDS_Kind GT1;Standard_Integer G1;TopOpeBRepDS_Kind ST1;Standard_Integer S1;
996         for (; itlifx.More(); itlifx.Next()) {
997           FDS_data(itlifx,I1,GT1,G1,ST1,S1);
998           Standard_Boolean isfci = (GT1 == TopOpeBRepDS_CURVE);
999           if (!isfci) continue;
1000           
1001           TopOpeBRepDS_ListOfInterference& lic = BDS.ChangeCurveInterferences(G1);
1002           TopOpeBRepDS_ListIteratorOfListOfInterference itlic(lic);
1003           if (!itlic.More()) continue;
1004           
1005           Handle(TopOpeBRepDS_Interference) I2;TopOpeBRepDS_Kind GT2;Standard_Integer G2;TopOpeBRepDS_Kind ST2;Standard_Integer S2;
1006           for (; itlic.More(); itlic.Next()) {
1007             FDS_data(itlic,I2,GT2,G2,ST2,S2);
1008             Standard_Boolean isp = (GT2 == TopOpeBRepDS_POINT);
1009             if (!isp) continue;
1010             if ( G2 != G ) continue;
1011             curvefound = Standard_True;
1012             break;
1013           } // itlic.More()
1014
1015           if (curvefound) break;
1016         } // itlifx.More()
1017
1018         if (curvefound) break;
1019       } // itlfx.More()
1020       
1021       nloi = loi.Extent();
1022 #ifdef DEB
1023 //      Standard_Integer nLI = LI.Extent();
1024 #endif
1025       if (curvefound) {
1026         LI.Append(loi);
1027       } 
1028       else {
1029 #ifdef DEB
1030 //      if (TRC) {
1031 //        debredpnc(EIX);
1032           TCollection_AsciiString ss = "\n--- TopOpeBRepDS_EIR::ProcessEdgeInterferences : suppress pnc of E"; ss = ss + EIX;
1033           DSD.DumpLOI(loi,cout,ss);
1034 //      }
1035 #endif  
1036       }
1037       
1038     } // tki.More()
1039   } // (!isfafa)
1040   
1041 } // ProcessEdgeInterferences
1042
1043 // modified by NIZHNY-MKK  Mon Apr  2 15:34:56 2001.BEGIN
1044 static Standard_Boolean CheckInterferenceIsValid(const Handle(TopOpeBRepDS_Interference)& I, 
1045                                                  const TopoDS_Edge&                       theEdge, 
1046                                                  const TopoDS_Edge&                       theSupportEdge, 
1047                                                  const TopoDS_Vertex&                     theVertex) {
1048   Standard_Real pref = 0. ;
1049   Standard_Boolean ok = Standard_False;
1050   BRepAdaptor_Curve BC(theEdge);
1051
1052   Handle(TopOpeBRepDS_CurvePointInterference) CPI;
1053   CPI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
1054
1055   if(!CPI.IsNull()) {
1056     pref = CPI->Parameter();
1057     ok = Standard_True;
1058   }
1059
1060   if(!ok) {
1061     Handle(TopOpeBRepDS_EdgeVertexInterference) EVI = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I);
1062     if(!EVI.IsNull()) {
1063       pref = EVI->Parameter();
1064       ok = Standard_True;
1065     }
1066   }
1067
1068   if(!ok)
1069     return ok;
1070
1071   gp_Pnt P3d1 = BC.Value(pref);
1072   Standard_Real dist, paronSupportE;      
1073   ok = FUN_tool_projPonE(P3d1,theSupportEdge,paronSupportE,dist);
1074
1075   if(!ok)
1076     return ok;
1077   BRepAdaptor_Curve BCtmp(theSupportEdge);
1078   gp_Pnt P3d2 = BCtmp.Value(paronSupportE);
1079   Standard_Real Tolerance = (BRep_Tool::Tolerance(theEdge) > BRep_Tool::Tolerance(theSupportEdge)) ? BRep_Tool::Tolerance(theEdge) : BRep_Tool::Tolerance(theSupportEdge);
1080   if(!theVertex.IsNull()) {
1081     Tolerance = (BRep_Tool::Tolerance(theVertex) > Tolerance) ? BRep_Tool::Tolerance(theVertex) : Tolerance;
1082   }
1083   if(P3d1.Distance(P3d2) > Tolerance) {
1084     ok = Standard_False;
1085   }
1086   
1087   return ok;
1088 }