5184b4d2399f76d68f6ec38447ee7d659d8bcbba
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_FIR.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
7 // under the terms of the GNU Lesser General Public 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 // Robert Boehne 30 May 2000 : Dec Osf
16
17 #include <TopOpeBRepDS_FIR.ixx>
18 #include <TopOpeBRepDS_define.hxx>
19 #include <TopOpeBRepTool_EXPORT.hxx>
20 #include <TopOpeBRepTool_SC.hxx>
21
22 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
23 #include <TopoDS.hxx>
24 #include <TopExp_Explorer.hxx>
25 #include <TopOpeBRepDS_FaceInterferenceTool.hxx>
26 #include <TopOpeBRepDS_CurvePointInterference.hxx>
27 #include <TopOpeBRepDS_ShapeShapeInterference.hxx>
28 #include <TopOpeBRepDS_ShapeData.hxx>
29 #include <TopOpeBRepDS_MapOfShapeData.hxx>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <BRep_Builder.hxx>
32 #include <BRep_Tool.hxx>
33 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
34 #include <TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State.hxx>
35
36 #define MDSke TopOpeBRepDS_EDGE
37 #define MDSkf TopOpeBRepDS_FACE
38
39 #ifdef DEB
40 void debrededg(const Standard_Integer I) {cout<<"+++ debrededg f"<<I<<endl;}
41 void debredfac(const Standard_Integer I) {cout<<"+++ debredfac f"<<I<<endl;}
42 void FUN_dumploiS(const TopoDS_Shape& SG,const TopOpeBRepDS_ListOfInterference& loi,const TopOpeBRepDS_DataStructure& BDS,TCollection_AsciiString str) 
43 {
44   cout<<str<<"   G : "<<BDS.Shape(SG)<<"   S : ";
45   for(TopOpeBRepDS_ListIteratorOfListOfInterference it(loi);it.More();it.Next()) cout<<it.Value()->Support()<<" "; 
46   cout<<endl;cout.flush();
47 }
48 void FUN_dumpmosd(TopOpeBRepDS_MapOfShapeData& mosd,const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer F,TCollection_AsciiString str) 
49 {
50   cout<<str<<"GmapS sur ";TopAbs::Print(BDS.Shape(F).ShapeType(),cout);
51   cout<<" "<<F<<" : "<<mosd.Extent()<<" (GK EDGE)(SK FACE)"<<endl;
52   for(Standard_Integer i=1,n=mosd.Extent();i<=n;i++) {
53     FUN_dumploiS(mosd.FindKey(i),mosd.FindFromIndex(i).Interferences(),BDS,str);
54   }
55 }
56 #endif
57
58 #ifdef DEB
59 extern Standard_Boolean TopOpeBRepDS_GettraceSTRANGE();
60 extern Standard_Boolean TopOpeBRepDS_GettracePEI();
61 extern Standard_Boolean TopOpeBRepDS_GettracePFI();
62 extern Standard_Boolean TopOpeBRepDS_GettracePI();
63 extern Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer);
64 static Standard_Boolean FTRCF(const Standard_Integer F) {
65   Standard_Boolean b1 = TopOpeBRepDS_GettracePFI();
66   Standard_Boolean b2 = TopOpeBRepDS_GettracePI();
67   Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(F);
68   return (b1 || b2 || b3);
69 }
70 static Standard_Boolean FTRCE(const Standard_Integer E) {
71   Standard_Boolean b1 = TopOpeBRepDS_GettracePEI();
72   Standard_Boolean b2 = TopOpeBRepDS_GettracePI();
73   Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(E);
74   return (b1 || b2 || b3);
75 }
76 #endif
77
78 Standard_EXPORT Standard_Boolean FUN_Parameters(const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v);
79 Standard_EXPORT Standard_Boolean FUN_edgeofface(const TopoDS_Shape& E,const TopoDS_Shape& F);
80
81 //------------------------------------------------------
82 Standard_Boolean FUN_isPonF(const TopOpeBRepDS_ListOfInterference& LIF,const gp_Pnt& P,const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& E)
83 {
84   Standard_Boolean Pok = Standard_True;
85   TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1;
86
87   TopOpeBRepDS_ListIteratorOfListOfInterference itF(LIF);
88   for (;itF.More();itF.Next()) {
89     Handle(TopOpeBRepDS_Interference)& IF = itF.Value(); FDS_data(IF,GT1,G1,ST1,S1);
90     const TopoDS_Face& F = TopoDS::Face(BDS.Shape(S1));
91     TopAbs_Orientation oEinF; Standard_Boolean edonfa = FUN_tool_orientEinFFORWARD(E,F,oEinF );
92     if ( edonfa ) Pok = Standard_True;
93     else {
94       // P est NOK pour une face de LIF : arret
95       Standard_Real u,v; Pok = FUN_Parameters(P,F,u,v);
96       if (!Pok) break;
97     }
98   }
99   return Pok;
100 }
101
102 //------------------------------------------------------
103 Standard_Boolean FUN_findPonF(const TopoDS_Edge& E,const TopOpeBRepDS_DataStructure& BDS, const TopOpeBRepDS_ListOfInterference& LIF,gp_Pnt& P,Standard_Real& par)
104 {
105   Standard_Boolean Pok = Standard_False;
106   BRepAdaptor_Curve BAC(E);
107   const TopOpeBRepDS_ListOfInterference& LIE = BDS.ShapeInterferences(E);
108   TopOpeBRepDS_ListIteratorOfListOfInterference itI; itI.Initialize(LIE);
109
110   if ( !itI.More() ) {
111     Pok = FUN_tool_findPinBAC(BAC,P,par);
112     Pok = FUN_isPonF(LIF,P,BDS,E);
113     return Pok;
114   }
115   
116   TopOpeBRepDS_Kind GT1,ST1;Standard_Integer G1,S1;
117   for (;itI.More();itI.Next()) {
118     Standard_Boolean pardef = Standard_False;
119     
120     Handle(TopOpeBRepDS_Interference)& I = itI.Value(); FDS_data(I,GT1,G1,ST1,S1);        
121     const Handle(TopOpeBRepDS_CurvePointInterference)& CPI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
122     const Handle(TopOpeBRepDS_ShapeShapeInterference)& SSI = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I);
123     if      (!CPI.IsNull()) {
124       par = CPI->Parameter(); pardef = Standard_True;
125     }
126     else if (!SSI.IsNull()) {
127       Standard_Boolean gb = SSI->GBound();
128       if (gb) {
129         const TopoDS_Vertex& V = TopoDS::Vertex(BDS.Shape(G1));
130         P = BRep_Tool::Pnt(V); par = BRep_Tool::Parameter(V,E); pardef = Standard_True;
131       }
132       else {
133         pardef = Standard_False;
134         if      (GT1 == TopOpeBRepDS_POINT)  P = BDS.Point(G1).Point();
135         else if (GT1 == TopOpeBRepDS_VERTEX) P = BRep_Tool::Pnt(TopoDS::Vertex(BDS.Shape(G1)));
136         if (pardef) { 
137           Standard_Real dist; pardef = FUN_tool_projPonC(P,BAC,par,dist);
138         }
139       }
140     }
141     else {
142       continue;
143     }
144
145     if (!pardef) {
146       continue;
147     }
148
149     BAC.D0(par,P);
150     Pok = FUN_isPonF(LIF,P,BDS,E);
151     // P est OK pour toutes les faces de LIF : on arrete de chercher
152     if (Pok) {
153       break;
154     }
155   }
156   return Pok;
157 }
158
159 // --------------------------------------------------------
160 static void FDS_DUMPTRANSITION(const Standard_Boolean
161 #ifdef DEB
162                                                       TRCF
163 #endif 
164                                ,const TCollection_AsciiString&
165 #ifdef DEB
166                                                       str
167 #endif 
168                                ,const Standard_Integer
169 #ifdef DEB
170                                                       iFI
171 #endif 
172                                ,TopOpeBRepDS_FaceInterferenceTool&
173 #ifdef DEB
174                                                                    FITool
175 #endif 
176                                )
177 {
178 #ifdef DEB
179   if (TRCF) {
180     cout<<str<<iFI<<endl;
181     Handle(TopOpeBRepDS_Interference) IBID = new TopOpeBRepDS_Interference();
182     FITool.Transition(IBID);
183     IBID->Transition().Dump(cout);cout<<endl;
184   }
185 #endif
186 }
187
188 // --------------------------------------------------------
189 static void FDS_ADDEDGE
190 (const Standard_Boolean
191 #ifdef DEB
192                         TRCF
193 #endif 
194  ,const TCollection_AsciiString&
195 #ifdef DEB
196                                  str
197 #endif 
198  ,const Standard_Integer
199 #ifdef DEB
200                         iFI // DEB args
201 #endif 
202  ,TopOpeBRepDS_FaceInterferenceTool& FITool
203  ,const TopoDS_Shape& FI
204  ,const TopoDS_Shape& F
205  ,const TopoDS_Shape& Ecpx
206  ,const Standard_Boolean isEGsp
207  ,const Handle(TopOpeBRepDS_Interference)& I
208 )
209 {
210 #ifdef DEB
211   if (TRCF) {TCollection_AsciiString cr("\n"),s=str+iFI+cr;I->Dump(cout,s,cr);}
212 #endif 
213   FITool.Add(FI,F,Ecpx,isEGsp,I);
214 #ifdef DEB
215   FDS_DUMPTRANSITION(TRCF,"--> resultat partiel sur face ",iFI,FITool);
216 #endif
217 }
218
219 //------------------------------------------------------
220 // EGsp = edge splittee de iEG ( Null si iEG n'est pas splittee)
221 void FUN_reduceEDGEgeometry1
222 (TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer iFI,const Standard_Integer iEG,const TopoDS_Shape& EGsp,
223 // const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp)
224  const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& )
225 {
226   Standard_Boolean TRCF = Standard_False;
227 #ifdef DEB
228   Standard_Boolean TRCE = Standard_False;
229   TRCE = FTRCE(iEG);if (TRCE) debrededg(iEG);
230   TRCF = FTRCF(iFI);if (TRCF) debredfac(iFI);
231 #endif
232
233   TopOpeBRepDS_ListIteratorOfListOfInterference ili(LI); if (!ili.More()) return; 
234
235   // choix de l'arete Ecpx, lieu de resolution de la transition complexe
236   const TopoDS_Face& FI = TopoDS::Face(BDS.Shape(iFI));
237   Standard_Boolean isEGsp = (! EGsp.IsNull());
238   TopoDS_Edge Ecpx;
239   if (isEGsp) Ecpx = TopoDS::Edge(EGsp);
240   else        Ecpx = TopoDS::Edge(BDS.Shape(iEG));
241
242   TopOpeBRepDS_PDataStructure pbds = (TopOpeBRepDS_PDataStructure)(void*)&BDS;
243   TopOpeBRepDS_FaceInterferenceTool FITool(pbds);
244   gp_Pnt Pok; Standard_Boolean isPok = Standard_False; Standard_Real parPok;
245   if ( LI.Extent() >= 2) {
246     if ( isEGsp ) isPok = FUN_tool_findPinE(Ecpx,Pok,parPok);
247     else          isPok = FUN_findPonF(Ecpx,BDS,LI,Pok,parPok); // NYI pas necessaire
248     if (!isPok) { LI.Clear(); return; }
249     FITool.SetEdgePntPar(Pok,parPok);
250   }
251
252   // xpu :090498 : 
253   //      CTS20205 : sp(e5) = sp(e4 of rank=1) and c3d(e5) c3d(e4) are diff oriented
254   //            As transitions on face<iFI> are given relative to the geometry of e5,
255   //            we have to complement them.
256 //  Standard_Boolean toreverse = Standard_False;
257 //  Standard_Boolean hsdm = !BDS.ShapeSameDomain(iEG).IsEmpty();
258 //  if (hsdm) {
259 //    Standard_Boolean sameoriented = Standard_False;
260 //    Standard_Boolean ok = FUN_tool_curvesSO(TopoDS::Edge(Ecpx),parPok,TopoDS::Edge(BDS.Shape(iEG)),
261 //                             sameoriented); 
262 //    if (ok) toreverse = !sameoriented;
263 //  }
264   // xpu :090498
265
266   // FI = face de reference (shape), iFI (indice)
267   // E = arete geometrie d'interference (shape), iEG (indice)
268   // LI = liste d'interf de geom iEG et dont les Support() sont a transitionner complexe
269
270   Handle(TopOpeBRepDS_Interference) I1,I2; TopOpeBRepDS_Kind GT1,ST1,GT2,ST2; Standard_Integer G1,S1,G2,S2;
271   TopOpeBRepDS_ListIteratorOfListOfInterference it1; it1.Initialize(LI);
272   while (it1.More()) {
273     Standard_Boolean u1 = FDS_data(it1,I1,GT1,G1,ST1,S1);if (u1) {it1.Next();continue;}
274     Standard_Boolean ya1 = (GT1 == MDSke); if (!ya1) {it1.Next();continue;}
275     
276     Standard_Boolean isComplex = Standard_False; // True if at least two interfs on the same edge
277     const TopoDS_Face& F1 = TopoDS::Face(BDS.Shape(S1));
278     
279     TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1); it2.Next();
280     while (it2.More()) {
281       Standard_Boolean u2 = FDS_data(it2,I2,GT2,G2,ST2,S2);if (u2) {it2.Next();continue;}
282       Standard_Boolean ya2 = (GT2==GT1 && G2==G1 && ST2==ST1); if (!ya2) {it2.Next();continue;}
283       const TopoDS_Face& F2 = TopoDS::Face(BDS.Shape(S2));
284       if (!isComplex) {
285         isComplex = Standard_True;
286
287          
288 //      TopOpeBRepDS_Transition T1 = I1->Transition(); TopAbs_Orientation O1 = T1.Orientation(TopAbs_IN); // xpu :090498        
289 //      Standard_Boolean revT1 = toreverse && (M_FORWARD(O1) || M_REVERSED(O1));      // xpu :090498    
290 #ifdef DEB
291 //      if ((TRCE || TRCF) && revT1) cout<<"-> REVERSE T"<<endl;
292 #endif
293 //      if (revT1) I1->ChangeTransition() = T1.Complement();  //xpu :090498
294         FITool.Init(FI,Ecpx,isEGsp,I1);
295         FDS_ADDEDGE(TRCF,"\ninit transition complexe F",iFI,FITool,FI,F1,Ecpx,isEGsp,I1);
296 //      if (revT1) I1->ChangeTransition() = T1.Complement();  //xpu :090498
297       }
298     
299 //      TopOpeBRepDS_Transition T2 = I2->Transition(); TopAbs_Orientation O2 = T2.Orientation(TopAbs_IN);  // xpu :090498 
300 //      Standard_Boolean revT2 = toreverse && (M_FORWARD(O2) || M_REVERSED(O2));       // xpu :090498       
301 #ifdef DEB
302 //      if ((TRCE || TRCF) && revT2) cout<<"-> REVERSE T"<<endl;
303 #endif 
304 //      if (revT2) I2->ChangeTransition() = T2.Complement();  //xpu :090498
305       FDS_ADDEDGE(TRCF,"add transition complexe F",iFI,FITool,FI,F2,Ecpx,isEGsp,I2);
306 //      if (revT2) I2->ChangeTransition() = T2.Complement();  //xpu :090498 
307
308       LI.Remove(it2);
309     }
310     if (isComplex) {
311       FITool.Transition(I1);
312       FDS_DUMPTRANSITION(TRCF,"--> result transition on face ",iFI,FITool); // DEB
313     }
314     it1.Next();
315   }  // it1.More()
316 } // FUN_reduceEDGEgeometry1
317
318 //------------------------------------------------------
319 void FUN_GmapS(TopOpeBRepDS_ListOfInterference& LI, const TopOpeBRepDS_DataStructure& BDS, TopOpeBRepDS_MapOfShapeData& mosd)
320 {
321   mosd.Clear();
322   TopOpeBRepDS_Kind GT1,ST1;Standard_Integer G1,S1;
323   for (TopOpeBRepDS_ListIteratorOfListOfInterference it1(LI);it1.More();it1.Next()) {
324     Handle(TopOpeBRepDS_Interference)& I1=it1.Value(); FDS_data(I1,GT1,G1,ST1,S1); 
325     if ( GT1 != MDSke || ST1 != MDSkf ) continue;
326     const TopoDS_Shape& SG1 = BDS.Shape(G1);
327     TopOpeBRepDS_ShapeData thedata;
328     if (!mosd.Contains(SG1)) mosd.Add(SG1, thedata);
329     mosd.ChangeFromKey(SG1).ChangeInterferences().Append(I1);
330   }
331
332
333 //------------------------------------------------------
334 TopAbs_State FUN_stateedgeface(const TopoDS_Shape& E, const TopoDS_Shape& F, gp_Pnt& P)
335 {
336   TopAbs_State state = TopAbs_UNKNOWN;
337   Standard_Real par; FUN_tool_findPinE(E,P,par);
338   Standard_Real u,v; Standard_Boolean Pok = FUN_Parameters(P,F,u,v);
339   if (Pok) { // classifier u,v dans F
340     TopOpeBRepTool_ShapeClassifier& PSC = FSC_GetPSC(F);
341     gp_Pnt2d Puv(u,v);
342     PSC.StateP2DReference(Puv);
343     state = PSC.State();
344   }
345   return state;
346 }
347
348 #define  M_IN(ssstate) ((ssstate) == TopAbs_IN)
349 #define  M_ON(ssstate) ((ssstate) == TopAbs_ON)
350 #define M_OUT(ssstate) ((ssstate) == TopAbs_OUT)
351 #define M_UNK(ssstate) ((ssstate) == TopAbs_UNK)
352
353 //------------------------------------------------------
354 void FUN_reduceEDGEgeometry
355 (TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer iFI,
356 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp)
357 {
358   if (!LI.Extent()) return;
359   
360   TopOpeBRepDS_MapOfShapeData mosd; 
361   FUN_GmapS(LI,BDS,mosd);
362
363 #ifdef DEB
364   Standard_Boolean TRC = FTRCF(iFI); 
365   if (TRC) FUN_dumpmosd(mosd,BDS,iFI,"");
366   if (TRC) debredfac(iFI);
367 #endif
368   
369   TopOpeBRepDS_ListOfInterference LIout;
370   //modified by NIZNHY-PKV Thu Mar 16 09:44:24 2000 f
371   Standard_Integer i, aN;
372   aN=mosd.Extent();
373   //for(Standard_Integer i=1,n=mosd.Extent(); i<=n; i++) {
374   //modified by NIZNHY-PKV Thu Mar 16 09:44:27 2000 t
375   for(i=1 ; i<=aN; i++) {
376     const TopoDS_Shape& EG = mosd.FindKey(i); 
377     Standard_Integer iEG = BDS.Shape(EG);
378
379     // donnees samedomain attachees a l'arete iEG
380     const TopTools_ListOfShape& esdeg = BDS.ShapeSameDomain(iEG);
381     Standard_Boolean egissect = BDS.IsSectionEdge(TopoDS::Edge(EG));
382     Standard_Boolean eghasesd = (! esdeg.IsEmpty());
383
384 #ifdef DEB
385 //    Standard_Integer egiref = BDS.SameDomainRef(iEG);
386 //    Standard_Integer egisref = (iEG == egiref);
387 //    TopOpeBRepDS_Config egc = BDS.SameDomainOri(iEG);
388 #endif
389
390     TopOpeBRepDS_ListOfInterference& LIEG = mosd.ChangeFromKey(EG).ChangeInterferences();
391     Standard_Integer nExt = LIEG.Extent();
392     // LIEG = toutes les interferences dont le Support() est une 
393     // face possedant une interference dont la Geometry() est EG.
394     
395 #ifdef DEB
396     if (TRC) FUN_dumploiS(EG,LIEG,BDS,"   ");
397 #endif
398     
399     if      (nExt == 0) {
400       continue;
401     }
402     if      (nExt == 1) {
403       LIout.Append(LIEG);
404     }
405     
406     else if (nExt >= 2) {
407       Standard_Boolean isEGsp = MEsp.IsBound(EG);
408       //modified by NIZNHY-PKV Thu Mar 16 11:03:44 2000 from
409       //Standard_Integer nEGsp = 0;
410       //modified by NIZNHY-PKV Thu Mar 16 11:03:49 2000 to
411       if (isEGsp) {
412         const TopOpeBRepDS_ListOfShapeOn1State& los1 = MEsp.Find(EG);
413         isEGsp = los1.IsSplit();
414         //modified by NIZNHY-PKV Thu Mar 16 11:02:40 2000 from
415         //if ( isEGsp ) {
416         //  const TopTools_ListOfShape& los = los1.ListOnState();
417         //  nEGsp = los.Extent();
418         //}
419         //modified by NIZNHY-PKV Thu Mar 16 11:02:46 2000 to
420       }
421       
422       if ( isEGsp ) {
423         const TopTools_ListOfShape& los = MEsp.Find(EG).ListOnState();
424         TopTools_ListIteratorOfListOfShape itlos(los);
425         for(;itlos.More();itlos.Next()) {
426           // EGsp est une arete splitee de EG.
427           const TopoDS_Shape& EGsp = itlos.Value();
428           
429           // LISFIN = liste des interferences de LI dont le Support()
430           // est une face contenant geometriquement l'arete EGsp
431           TopOpeBRepDS_ListOfInterference LISFIN;
432           TopOpeBRepDS_ListIteratorOfListOfInterference itLIEG(LIEG);
433           for(; itLIEG.More(); itLIEG.Next()) {
434             const Handle(TopOpeBRepDS_Interference)& ILIEG = itLIEG.Value();
435             Standard_Integer  iS = ILIEG->Support();
436             TopOpeBRepDS_Kind kS = ILIEG->SupportType();
437             if ( kS == MDSkf ) {
438               const TopoDS_Shape& SFILIEG = BDS.Shape(iS);
439               gp_Pnt P; 
440               TopAbs_State staef = FUN_stateedgeface(EGsp,SFILIEG,P);
441               
442               Standard_Boolean Pok = M_IN(staef);
443               if ( eghasesd || egissect ) {
444                 Pok = Pok || M_ON(staef);
445               }
446
447               if (Pok) {
448                 LISFIN.Append(ILIEG);
449               }
450             }
451           } // itLIEG.More
452
453           Standard_Integer nLISFIN = LISFIN.Extent();
454           if (nLISFIN >= 2 ) {
455             Standard_Boolean gb;
456             gb = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(LISFIN.First())->GBound();
457             
458             if (gb) {
459               //modified by NIZNHY-PKV Thu Mar 16 10:40:57 2000 f
460               // we have to rest at least one  Interference on the face.
461               // To kill all of them is too bravely. 
462               Handle(TopOpeBRepDS_Interference) anInterference = LISFIN.First();
463               LISFIN.Clear();
464               LISFIN.Append(anInterference);
465               //modified by NIZNHY-PKV Thu Mar 16 10:41:01 2000 t
466             }
467             else    
468               FUN_reduceEDGEgeometry1(LISFIN,BDS,iFI,iEG,EGsp,MEsp);
469           }
470
471           nLISFIN = LISFIN.Extent();
472           if (nLISFIN) 
473             LIout.Append(LISFIN);
474         }
475       } // isEGsp
476       else {
477         // iFI = face de reference (indice)
478         // E = arete geometrie d'interference (shape), iEG (indice)
479         // LIEG = liste d'interferences de geometrie EG
480         //        et dont les Support() sont a transitionner complexe
481         TopoDS_Shape Enull;
482         FUN_reduceEDGEgeometry1(LIEG,BDS,iFI,iEG,Enull,MEsp);
483         LIout.Append(LIEG);
484       }
485     }
486   }
487
488   LI.Clear();
489   LI.Append(LIout);
490 } // FUN_reduceEDGEgeometry
491
492 //=======================================================================
493 //function : TopOpeBRepDS_FIR
494 //purpose  : 
495 //=======================================================================
496 TopOpeBRepDS_FIR::TopOpeBRepDS_FIR
497 (const Handle(TopOpeBRepDS_HDataStructure)& HDS) : myHDS(HDS)
498 {}
499
500 //=======================================================================
501 //function : ProcessFaceInterferences
502 //purpose  : 
503 //=======================================================================
504 void TopOpeBRepDS_FIR::ProcessFaceInterferences(const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& M)
505 {
506   TopOpeBRepDS_DataStructure& BDS = myHDS->ChangeDS();
507   Standard_Integer i,nshape = BDS.NbShapes();
508   for (i = 1; i <= nshape; i++) {
509     const TopoDS_Shape& S = BDS.Shape(i);
510     if(S.IsNull()) continue;
511     if ( S.ShapeType() == TopAbs_FACE ) {
512       ProcessFaceInterferences(i,M);
513     }
514   }
515 }
516
517 //=======================================================================
518 //function : ProcessFaceInterferences
519 //purpose  : 
520 //=======================================================================
521 void TopOpeBRepDS_FIR::ProcessFaceInterferences
522 (const Standard_Integer SIX,const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp)
523 {
524   TopOpeBRepDS_DataStructure& BDS = myHDS->ChangeDS();
525
526 #ifdef DEB
527   Standard_Boolean TRC = FTRCF(SIX);
528   if (TRC) debredfac(SIX);
529 #endif
530   // F is the Face, LI is list of interferences to compact
531 #ifdef DEB
532 //  const TopoDS_Shape& F = BDS.Shape(SIX);
533 #endif
534   TopOpeBRepDS_ListOfInterference& LI = BDS.ChangeShapeInterferences(SIX);
535   TopOpeBRepDS_ListOfInterference lw, lE, lFE, lFEF, lF; lw.Assign(LI);
536
537   Standard_Integer nF = ::FUN_selectTRASHAinterference(lw,TopAbs_FACE,lF);
538   Standard_Integer nFE = ::FUN_selectGKinterference(lF,MDSke,lFE);
539   Standard_Integer nFEF = ::FUN_selectSKinterference(lFE,MDSkf,lFEF);
540   Standard_Integer nE = ::FUN_selectTRASHAinterference(lw,TopAbs_EDGE,lE);
541
542   nF = lF.Extent();
543   nFE = lFE.Extent();
544   nFEF = lFEF.Extent();
545   nE = lE.Extent();
546 #ifdef DEB
547   if(TRC){
548     if(nF||nFE||nFEF||nE){cout<<endl;cout<<"-----------------------"<<endl;}
549     if(nF) {cout<<"FACE "<<SIX<<" (FACE) : "<<nF<<endl;FDS_dumpLI(lF,"  ");}
550     if(nFE){cout<<"FACE "<<SIX<<" (FACE)(GK EDGE) : "<<nFE<<endl;FDS_dumpLI(lFE,"  ");}
551     if(nFEF){cout<<"FACE "<<SIX<<" (FACE)(GK EDGE)(SK FACE) : "<<nFEF<<endl;FDS_dumpLI(lFEF,"  ");}
552     if(nE) {cout<<"FACE "<<SIX<<" (EDGE) : "<<nE<<endl;FDS_dumpLI(lE,"  ");}
553   }
554 #endif
555
556   FUN_reduceEDGEgeometry(lFEF,BDS,SIX,MEsp);
557
558   nF = lF.Extent();
559   nFE = lFE.Extent();
560   nFEF = lFEF.Extent();
561   nE = lE.Extent();
562 #ifdef DEB
563   if(TRC){
564     if(nF||nFE||nFEF||nE)cout<<endl;
565     if(nF) {cout<<"FACE "<<SIX<<" (FACE) : "<<nF<<endl;FDS_dumpLI(lF,"  ");}
566     if(nFE){cout<<"FACE "<<SIX<<" (FACE)(GK EDGE) : "<<nFE<<endl;FDS_dumpLI(lFE,"  ");}
567     if(nFEF){cout<<"FACE "<<SIX<<" (FACE)(GK EDGE)(SK FACE) : "<<nFEF<<endl;FDS_dumpLI(lFEF,"  ");}
568     if(nE) {cout<<"FACE "<<SIX<<" (EDGE) : "<<nE<<endl;FDS_dumpLI(lE,"  ");}
569     cout<<"-----------------------"<<endl;
570   }
571 #endif
572
573   LI.Clear();
574   LI.Append(lF);
575   LI.Append(lFE);
576   LI.Append(lFEF);
577   LI.Append(lE);
578   // MSV: filter duplicates
579   ::FUN_reducedoublons(LI,BDS,SIX);
580 }