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