ec6b96d3d1e5107c69fec1a48d40970784a3668d
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_EXPORT.cxx
1 // Created on: 1997-12-15
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified by xpu, Wed May 20 10:47:38 1998
18
19 #include <gp_Dir.hxx>
20 #include <gp_Pnt.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Geom_Curve.hxx>
23 #include <TopoDS.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepTools.hxx>
26 #include <TopExp.hxx>
27 #include <TopExp_Explorer.hxx>
28 #include <Precision.hxx>
29 #include <GeomAdaptor_Surface.hxx>
30 #include <TColStd_DataMapOfIntegerInteger.hxx>
31 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
32
33 #include <TopOpeBRepTool_CurveTool.hxx>
34 #include <TopOpeBRepTool_ShapeTool.hxx>
35 #include <TopOpeBRepTool_TOOL.hxx>
36 #include <TopOpeBRepTool_EXPORT.hxx>
37 #include <TopOpeBRepTool_SC.hxx>
38 #include <TopOpeBRepTool_makeTransition.hxx>
39 #include <Standard_ProgramError.hxx>
40
41 #include <TopOpeBRepDS_InterferenceTool.hxx>
42 #include <TopOpeBRepDS_BuildTool.hxx>
43 #include <TopOpeBRepDS_PointIterator.hxx>
44 #include <TopOpeBRepDS_BuildTool.hxx>
45 #include <TopOpeBRepDS_EXPORT.hxx>
46 #include <TopOpeBRepDS_connex.hxx>
47 #include <TopOpeBRepDS_TKI.hxx>
48 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
49 #include <TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State.hxx>
50 #include <TopOpeBRepDS_TOOL.hxx>
51 #include <TopOpeBRepDS_define.hxx>
52
53 #define M_IN(st)  (st == TopAbs_IN)
54 #define M_ON(st)  (st == TopAbs_ON)
55 #define M_OUT(st) (st == TopAbs_OUT)
56 #define M_FORWARD(st)  (st == TopAbs_FORWARD)
57 #define M_UNKNOWN(st)  (st == TopAbs_UNKNOWN)
58 #define M_REVERSED(st) (st == TopAbs_REVERSED)
59 #define M_INTERNAL(st) (st == TopAbs_INTERNAL)
60 #define M_EXTERNAL(st) (st == TopAbs_EXTERNAL)
61
62 //------------------------------------------------------
63 Standard_EXPORT void FDS_SetT(TopOpeBRepDS_Transition& T, const TopOpeBRepDS_Transition& T0)
64 //------------------------------------------------------
65
66   TopAbs_State stb = T0.Before(), sta = T0.After();
67   T.Before(stb); T.After(sta);
68 }
69
70 //------------------------------------------------------
71 Standard_EXPORT Standard_Boolean FDS_hasUNK(const TopOpeBRepDS_Transition& T)
72 //------------------------------------------------------
73 {
74   TopAbs_State stb = T.Before(), sta = T.After();
75   Standard_Boolean hasunknown = (M_UNKNOWN(stb) || M_UNKNOWN(sta));
76   return hasunknown;
77 }
78
79 //------------------------------------------------------
80 Standard_EXPORT void FDS_copy(const TopOpeBRepDS_ListOfInterference& LI, TopOpeBRepDS_ListOfInterference& LII)
81 //------------------------------------------------------
82 {
83   for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) LII.Append(it.Value());
84 }
85
86 //------------------------------------------------------
87 Standard_EXPORT void FDS_copy(const TopTools_ListOfShape& LI, TopTools_ListOfShape& LII)
88 //------------------------------------------------------
89 {
90   for (TopTools_ListIteratorOfListOfShape it(LI); it.More(); it.Next()) LII.Append(it.Value());
91 }
92 //------------------------------------------------------
93 Standard_EXPORT void FDS_assign(const TopOpeBRepDS_ListOfInterference& LI, TopOpeBRepDS_ListOfInterference& LII)
94 //------------------------------------------------------
95 {
96   LII.Clear(); FDS_copy(LI,LII);
97 }
98
99 //------------------------------------------------------
100 Standard_EXPORT void FDS_assign(const TopTools_ListOfShape& LI, TopTools_ListOfShape& LII)
101 //------------------------------------------------------
102 {
103   LII.Clear(); FDS_copy(LI,LII);
104 }
105
106 //------------------------------------------------------
107 Standard_EXPORT void FUN_ds_samRk(const TopOpeBRepDS_DataStructure& BDS, const Standard_Integer Rk,
108                                   TopTools_ListOfShape& LI, TopTools_ListOfShape & LIsrk)
109 //------------------------------------------------------
110 {
111   LIsrk.Clear();
112   TopTools_ListIteratorOfListOfShape it(LI); 
113   while (it.More()) {
114     const TopoDS_Shape& S = it.Value(); Standard_Integer rk = BDS.AncestorRank(S);
115     if (rk == Rk) {LIsrk.Append(S);LI.Remove(it);}
116     else it.Next();
117   }
118 }
119
120 //------------------------------------------------------
121 Standard_EXPORT void FDS_Tdata
122 //------------------------------------------------------
123 (const Handle(TopOpeBRepDS_Interference)& I,TopAbs_ShapeEnum& SB,Standard_Integer& IB,TopAbs_ShapeEnum& SA,Standard_Integer& IA)
124 {       
125   if (I.IsNull()) return;
126   const TopOpeBRepDS_Transition T = I->Transition();
127   SB = T.ShapeBefore(); IB = T.IndexBefore();
128   SA = T.ShapeAfter();  IA = T.IndexAfter();
129 }
130
131 //------------------------------------------------------
132 Standard_EXPORT void FDS_data
133 //------------------------------------------------------
134 (const Handle(TopOpeBRepDS_Interference)& I,TopOpeBRepDS_Kind& GT1,Standard_Integer& G1,TopOpeBRepDS_Kind& ST1,Standard_Integer& S1)
135 {       
136   if (I.IsNull()) return;
137   GT1 = I->GeometryType(); G1 = I->Geometry();
138   ST1 = I->SupportType();  S1 = I->Support(); 
139 }
140
141 // true si la transition de l'interference courante es UNKNOWN
142 //------------------------------------------------------
143 Standard_EXPORT Standard_Boolean FDS_data
144 //------------------------------------------------------
145 (const TopOpeBRepDS_ListIteratorOfListOfInterference& it1,Handle(TopOpeBRepDS_Interference)& I1,TopOpeBRepDS_Kind& GT1,Standard_Integer& G1,TopOpeBRepDS_Kind& ST1,Standard_Integer& S1)
146 {
147   if (!it1.More()) return Standard_False;
148   I1 = it1.Value(); const TopOpeBRepDS_Transition& T1 = I1->Transition();
149   FDS_data(I1,GT1,G1,ST1,S1); 
150   Standard_Boolean isunk1 = T1.IsUnknown();
151   return isunk1;
152 }
153
154 //------------------------------------------------------
155 Standard_EXPORT void FDS_Idata
156 //------------------------------------------------------
157 (const Handle(TopOpeBRepDS_Interference)& I,TopAbs_ShapeEnum& SB,Standard_Integer& IB,TopAbs_ShapeEnum& SA,Standard_Integer& IA,
158  TopOpeBRepDS_Kind& GT1,Standard_Integer& G1,TopOpeBRepDS_Kind& ST1,Standard_Integer& S1)
159 {       
160   if (I.IsNull()) return;
161   FDS_Tdata(I,SB,IB,SA,IA);
162   FDS_data(I,GT1,G1,ST1,S1);
163 }
164
165 //------------------------------------------------------
166 Standard_EXPORT Standard_Boolean FUN_ds_getVsdm
167 (const TopOpeBRepDS_DataStructure& BDS, const Standard_Integer iV, Standard_Integer& iVsdm)
168 //------------------------------------------------------
169 {
170   iVsdm = 0;
171   Standard_Boolean found = Standard_False;
172   // getting <Vsdm> shape same domain with <V>.
173   Standard_Integer imax = BDS.NbShapes();
174   Standard_Boolean undef = (iV < 1) || (iV > imax);
175   if (undef) return Standard_False;
176   const TopoDS_Shape& V = BDS.Shape(iV);
177   TopTools_ListIteratorOfListOfShape issdm(BDS.ShapeSameDomain(V));
178   for (; issdm.More(); issdm.Next()){
179     const TopoDS_Shape& VV = issdm.Value();
180     if (V.IsSame(VV)) continue;
181     iVsdm = BDS.Shape(VV); 
182     found = Standard_True; break;
183   }
184   return found;
185 }
186
187 //------------------------------------------------------
188 Standard_EXPORT Standard_Boolean FUN_ds_sdm
189 (const TopOpeBRepDS_DataStructure& BDS, const TopoDS_Shape& s1, const TopoDS_Shape& s2)
190 //------------------------------------------------------
191 {
192   if (!BDS.HasShape(s1) || !BDS.HasShape(s2)) return Standard_False;
193   const TopTools_ListOfShape& sdm1 = BDS.ShapeSameDomain(s1);
194   TopTools_ListIteratorOfListOfShape it1(sdm1);
195   for (; it1.More(); it1.Next()) 
196     if (it1.Value().IsSame(s2)) return Standard_True;
197   return Standard_False;
198 }
199
200 // True si les faces isb1,isb2, issues du meme shape origine, connexes par l'arete SI, sont tangentes.
201 // 1/ analyse du codage SameDomain dans la DS.
202 // 2/ si pas de codage SameDomain dans la DS, analyse geometrique.
203 //    cette deuxieme analyse est necessaire car l'info SameDomain n'est pas recherchee entre les
204 //    faces d'un meme shape origine.
205 //------------------------------------------------------------------------------------
206 Standard_EXPORT Standard_Boolean FDS_aresamdom(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Shape& ES,const TopoDS_Shape& F1,const TopoDS_Shape& F2)
207 //------------------------------------------------------------------------------------
208 {
209   Standard_Boolean trfa_samdom = Standard_False;
210   const TopTools_ListOfShape& ls = BDS.ShapeSameDomain(F1);
211   TopTools_ListIteratorOfListOfShape it(ls);
212   for(;it.More();it.Next()) { // NYI : syntaxe rapide de BDS IsShapeSameDomainofShape
213     const TopoDS_Shape& ss = it.Value();
214     trfa_samdom = ss.IsSame(F2);
215     if (trfa_samdom) break;
216   }
217   if ( !trfa_samdom ) {
218     Handle(Geom_Surface) su1 = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F1));
219     GeomAdaptor_Surface gs1(su1); GeomAbs_SurfaceType st1 = gs1.GetType();
220     Handle(Geom_Surface) su2 = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F2));
221     GeomAdaptor_Surface gs2(su2); GeomAbs_SurfaceType st2 = gs2.GetType();
222     Standard_Boolean plpl = (st1 == GeomAbs_Plane) && ( st2 == GeomAbs_Plane);
223     if (plpl) {
224       // NYI a arranger
225       gp_Pnt2d p2d1,p2d2; BRep_Tool::UVPoints(TopoDS::Edge(ES),TopoDS::Face(F1),p2d1,p2d2);
226       gp_Dir d1 = FUN_tool_ngS(p2d1,su1);      
227       gp_Dir d2 = FUN_tool_ngS(p2d2,su2);      
228       Standard_Real tola = Precision::Angular();
229       Standard_Real dot = d1.Dot(d2);
230       trfa_samdom = (Abs(1. - Abs(dot)) < tola);
231     }
232   }
233   return trfa_samdom;
234 }
235
236 // True si les faces isb1,isb2, issues du meme shape origine, connexes par l'arete SI, sont tangentes.
237 // 1/ analyse du codage SameDomain dans la DS.
238 // 2/ si pas de codage SameDomain dans la DS, analyse geometrique.
239 //    cette deuxieme analyse est necessaire car l'info SameDomain n'est pas recherchee entre les
240 //    faces d'un meme shape origine.
241 //------------------------------------------------------------------------------------
242 Standard_EXPORT Standard_Boolean FDS_aresamdom(const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer SI,const Standard_Integer isb1,const Standard_Integer isb2)
243 //------------------------------------------------------------------------------------
244 {
245   Standard_Boolean trfa_samdom = Standard_False;
246   const TopoDS_Shape& ES = BDS.Shape(SI); // edge de F1 et F2
247   if (ES.ShapeType() != TopAbs_EDGE) return Standard_False;
248   const TopoDS_Shape& F1 = BDS.Shape(isb1);
249   if (F1.ShapeType() != TopAbs_FACE) return Standard_False;
250   const TopoDS_Shape& F2 = BDS.Shape(isb2);
251   if (F2.ShapeType() != TopAbs_FACE) return Standard_False;
252   trfa_samdom = FDS_aresamdom(BDS,ES,F1,F2);
253   return trfa_samdom;
254 }
255
256 //----------------------------------------------------
257 Standard_EXPORT Standard_Boolean FDS_EdgeIsConnexToSameDomainFaces
258 (const TopoDS_Shape& E,const Handle(TopOpeBRepDS_HDataStructure)& HDS)  // not used
259 //----------------------------------------------------
260 {
261   const TopOpeBRepDS_DataStructure& BDS = HDS->DS();
262   const TopTools_ListOfShape& lf = FDSCNX_EdgeConnexitySameShape(E,HDS);
263   Standard_Integer nlf = lf.Extent();
264   if (nlf < 2) return Standard_False;
265
266   Standard_Boolean samdom = Standard_False;
267   TopTools_ListIteratorOfListOfShape i1(lf);
268   for(;i1.More();i1.Next()) {
269     const TopoDS_Shape& f1 = i1.Value();
270     TopTools_ListIteratorOfListOfShape i2(i1);
271     for(;i2.More();i2.Next()) {
272       const TopoDS_Shape& f2 = i2.Value();
273       samdom = FDS_aresamdom(BDS,E,f1,f2);
274       if (samdom) break;
275     }
276     if (samdom) break;
277   }
278   if (samdom) return Standard_True;
279   return Standard_False;
280 } // not used
281
282
283 // T si ShapeIndex SI est la GeometrieIndex d'une Interference
284 // d'un Shape (Before ou After) de la Transition de I
285 //----------------------------------------------------
286 Standard_EXPORT Standard_Boolean FDS_SIisGIofIofSBAofTofI(const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer SI,const Handle(TopOpeBRepDS_Interference)& I)
287 //----------------------------------------------------
288 {
289   if (SI == 0) return Standard_False;
290   if (I.IsNull()) return Standard_False;
291   Standard_Boolean ya = Standard_False;
292
293   TopAbs_ShapeEnum SB1 = TopAbs_SHAPE, SA1 = TopAbs_SHAPE; Standard_Integer IB1 = 0, IA1 = 0; TopOpeBRepDS_Kind GT1 = TopOpeBRepDS_UNKNOWN, ST1 = TopOpeBRepDS_UNKNOWN; Standard_Integer G1 = 0, S1 = 0;
294   FDS_Idata(I,SB1,IB1,SA1,IA1,GT1,G1,ST1,S1);
295   
296   if (SB1 == TopAbs_FACE) {
297     const TopOpeBRepDS_ListOfInterference& Bloi = BDS.ShapeInterferences(IB1);
298     TopOpeBRepDS_ListIteratorOfListOfInterference it(Bloi);
299     for(; it.More(); it.Next()) {
300       const Handle(TopOpeBRepDS_Interference)& IB = it.Value();
301       TopAbs_ShapeEnum SBB = TopAbs_SHAPE, SAB = TopAbs_SHAPE; Standard_Integer IBB = 0, IAB = 0; TopOpeBRepDS_Kind GTB = TopOpeBRepDS_UNKNOWN, STB = TopOpeBRepDS_UNKNOWN; Standard_Integer GB = 0, SB = 0;
302       FDS_Idata(IB,SBB,IBB,SAB,IAB,GTB,GB,STB,SB);
303       if (GTB == TopOpeBRepDS_EDGE && GB == SI) {
304         // la face IB1 a une interference dont la geometrie est l'arete SI.
305         ya = Standard_True;
306         break;
307       }
308     }
309   } // SB1 == FACE
310   else if (SA1 == TopAbs_FACE) {
311     const TopOpeBRepDS_ListOfInterference& Aloi = BDS.ShapeInterferences(IA1);
312     TopOpeBRepDS_ListIteratorOfListOfInterference it(Aloi);
313     for(; it.More(); it.Next()) {
314       const Handle(TopOpeBRepDS_Interference)& IA = it.Value();
315       TopAbs_ShapeEnum SBA = TopAbs_SHAPE, SAA = TopAbs_SHAPE;Standard_Integer IBA = 0, IAA = 0; TopOpeBRepDS_Kind GTA = TopOpeBRepDS_UNKNOWN, STA = TopOpeBRepDS_UNKNOWN; Standard_Integer GA = 0, SA = 0;
316       FDS_Idata(IA,SBA,IBA,SAA,IAA,GTA,GA,STA,SA);
317       if (GTA == TopOpeBRepDS_EDGE && GA == SI) {
318         // la face IA1 a une interference dont la geometrie est l'arete IS.
319         ya = Standard_True;
320         break;
321       }
322     }
323   } // SA1 == FACE
324   
325   return ya;
326 }
327
328 //---------------------------------------------------------
329 Standard_EXPORT Standard_Boolean FDS_Parameter(const Handle(TopOpeBRepDS_Interference)& I, Standard_Real& par)
330 //---------------------------------------------------------
331 {
332   Standard_Boolean isEVI = I->IsKind(STANDARD_TYPE(TopOpeBRepDS_EdgeVertexInterference));
333   Standard_Boolean isCPI = I->IsKind(STANDARD_TYPE(TopOpeBRepDS_CurvePointInterference));
334   if (!isEVI && !isCPI) return Standard_False;
335   par = FDS_Parameter(I);
336   return Standard_True;
337 }
338
339 //----------------------------------------------------
340 Standard_EXPORT Standard_Real FDS_Parameter(const Handle(TopOpeBRepDS_Interference)& I)
341 //----------------------------------------------------
342
343   Standard_Real p = 0; 
344   if      ( I->IsKind(STANDARD_TYPE(TopOpeBRepDS_EdgeVertexInterference)) )
345     p = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I)->Parameter();
346   else if ( I->IsKind(STANDARD_TYPE(TopOpeBRepDS_CurvePointInterference)) )
347     p = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I)->Parameter();
348   else {
349     throw Standard_Failure("FDS_Parameter");
350   }
351   return p;
352 }
353
354 //----------------------------------------------------------------------
355 Standard_EXPORT Standard_Boolean FDS_HasSameDomain3d(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Shape& E,TopTools_ListOfShape* PLSD)
356 //-----------------------------------------------------------------------
357 {
358   const TopTools_ListOfShape& lssd = BDS.ShapeSameDomain(E);
359   Standard_Boolean hsd = (! lssd.IsEmpty());
360   if (PLSD != NULL) PLSD->Clear();
361   if (!hsd) return Standard_False;
362
363   Standard_Boolean hsd3d = Standard_False;
364   TopTools_ListIteratorOfListOfShape it(lssd);
365   for (; it.More(); it.Next()) {
366     const TopoDS_Shape& esd = it.Value();
367     TopOpeBRepDS_Config c = BDS.SameDomainOri(esd);
368     Standard_Boolean ok = Standard_True;
369     ok = ok && (c == TopOpeBRepDS_UNSHGEOMETRY);
370     if (ok) {
371       hsd3d = Standard_True; 
372       if (PLSD != NULL) PLSD->Append(esd);
373       else break;
374     }
375   }
376   return hsd3d;
377 }
378
379 //-----------------------------------------------------------------------
380 Standard_EXPORT Standard_Boolean FDS_Config3d(const TopoDS_Shape& E1,const TopoDS_Shape& E2,TopOpeBRepDS_Config& c)
381 //-----------------------------------------------------------------------
382 {
383   Standard_Boolean same = Standard_True;
384
385   gp_Pnt PE1;Standard_Real pE1;
386   Standard_Boolean ok1 = FUN_tool_findPinE(TopoDS::Edge(E1),PE1,pE1);
387   gp_Vec VE1; if (ok1) ok1 = TopOpeBRepTool_TOOL::TggeomE(pE1,TopoDS::Edge(E1),VE1);
388
389   Standard_Real pE2,dE2;
390   Standard_Boolean ok2 = FUN_tool_projPonE(PE1,TopoDS::Edge(E2),pE2,dE2);
391   gp_Vec VE2; if (ok2) ok2 = TopOpeBRepTool_TOOL::TggeomE(pE2,TopoDS::Edge(E2),VE2);
392   
393   if (!ok1 || !ok2) return Standard_False;
394   
395   gp_Dir DE1(VE1);
396   gp_Dir DE2(VE2);
397   Standard_Real dot = DE1.Dot(DE2);
398   same = (dot > 0);
399   c = (same) ? TopOpeBRepDS_SAMEORIENTED : TopOpeBRepDS_DIFFORIENTED;
400   return Standard_True;
401 }
402
403 //----------------------------------------------------------------------
404 Standard_EXPORT Standard_Boolean FDS_HasSameDomain2d(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Shape& E,TopTools_ListOfShape* PLSD)
405 //-----------------------------------------------------------------------
406 {
407   const TopTools_ListOfShape& lssd = BDS.ShapeSameDomain(E);
408   Standard_Boolean hsd = (! lssd.IsEmpty());
409   if (PLSD != NULL) PLSD->Clear();
410   if (!hsd) return Standard_False;
411
412   Standard_Boolean hsd2d = Standard_False;
413   TopTools_ListIteratorOfListOfShape it(lssd);
414   for (; it.More(); it.Next()) {
415     const TopoDS_Shape& esd = it.Value();
416     TopOpeBRepDS_Config c = BDS.SameDomainOri(esd);
417     Standard_Boolean ok = (c == TopOpeBRepDS_SAMEORIENTED || c == TopOpeBRepDS_DIFFORIENTED);
418     if (ok) {
419       hsd2d = Standard_True; 
420       if (PLSD != NULL) PLSD->Append(esd);
421       else break;
422     }
423   }
424   return hsd2d;
425 }
426
427 //-----------------------------------------------------------------------
428 Standard_EXPORT void FDS_getupperlower
429 (const Handle(TopOpeBRepDS_HDataStructure)& HDS,
430  const Standard_Integer edgeIndex,
431  const Standard_Real paredge,
432  Standard_Real& p1, Standard_Real& p2)
433 //-----------------------------------------------------------------------
434 {
435   TopoDS_Edge E = TopoDS::Edge(HDS->Shape(edgeIndex));
436   FUN_tool_bounds(E,p1,p2);
437
438   // get p1, p2, p1<paredge<p2 with pmin, pmax nearest parameters
439   Standard_Real par;
440   TopOpeBRepDS_PointIterator pIte = HDS->EdgePoints(E);
441   for (;pIte.More();pIte.Next()) {
442     par = pIte.Parameter();
443     Standard_Boolean parsup1 = (par > p1), parinfe = (par < paredge);
444     Standard_Boolean parinf2 = (par < p2), parsupe = (par > paredge);
445     if (parsup1 && parinfe) p1 = par;
446     if (parinf2 && parsupe) p2 = par;
447   } 
448 }
449
450 // ----------------------------------------------------------------------
451 Standard_EXPORT Standard_Boolean FUN_ds_getoov(const TopoDS_Shape& v, const TopOpeBRepDS_DataStructure& BDS, TopoDS_Shape& oov)
452 //-----------------------------------------------------------------------
453 {
454   // prequesitory : the DS binds at most 2 vertices same domain
455   TopoDS_Shape nullS; oov = nullS;
456   const TopTools_ListOfShape& vsd = BDS.ShapeSameDomain(v);
457   TopTools_ListIteratorOfListOfShape itlov(vsd);
458   for (; itlov.More(); itlov.Next()){
459     const TopoDS_Shape& vcur = itlov.Value();
460     if (vcur.IsSame(v)) continue;
461     oov = vcur;
462     return Standard_True;
463   }
464   return Standard_False;
465 }
466
467 // ----------------------------------------------------------------------
468 Standard_EXPORT Standard_Boolean FUN_ds_getoov(const TopoDS_Shape& v, const Handle(TopOpeBRepDS_HDataStructure)& HDS, TopoDS_Shape& oov)
469 //-----------------------------------------------------------------------
470 {
471   // prequesitory : the DS binds at most 2 vertices same domain
472   TopoDS_Shape nullS; oov = nullS;
473   if (HDS->HasSameDomain(v)) {
474     TopTools_ListIteratorOfListOfShape itlov(HDS->SameDomain(v));
475     for (; itlov.More(); itlov.Next()){
476       const TopoDS_Shape& vcur = itlov.Value();
477       if (vcur.IsSame(v)) continue;
478       oov = vcur;
479       return Standard_True;
480     }
481   }
482   return Standard_False;
483 }
484  
485 Standard_EXPORT Standard_Boolean FUN_selectTRAINTinterference(const TopOpeBRepDS_ListOfInterference& li, TopOpeBRepDS_ListOfInterference& liINTERNAL)
486 {
487   liINTERNAL.Clear();
488   TopOpeBRepDS_ListIteratorOfListOfInterference it(li);
489   for (; it.More(); it.Next()){
490     const Handle(TopOpeBRepDS_Interference)& I = it.Value();
491     const TopAbs_Orientation ori = I->Transition().Orientation(TopAbs_IN);
492     if (M_INTERNAL(ori)) liINTERNAL.Append(I);
493   }
494   Standard_Boolean hasINT = !liINTERNAL.IsEmpty();
495   return hasINT;
496 }
497
498 static Standard_Boolean FUN_ds_hasSDMancestorfaces
499 (const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Edge& E1,const TopoDS_Edge& E2, TopoDS_Face& Fsd1,TopoDS_Face& Fsd2)
500 {
501   const TopOpeBRepDS_DataStructure& BDS = HDS->DS();
502
503   const TopTools_ListOfShape& lFcE1 = FDSCNX_EdgeConnexitySameShape(E1,HDS);
504   const TopTools_ListOfShape& lFcE2 = FDSCNX_EdgeConnexitySameShape(E2,HDS);
505
506   TopTools_IndexedMapOfShape mapfcE2; 
507   TopTools_ListIteratorOfListOfShape it2(lFcE2);
508   for (; it2.More(); it2.Next()) mapfcE2.Add(it2.Value());
509
510   TopTools_ListIteratorOfListOfShape it1(lFcE1);
511   for (; it1.More(); it1.Next()){
512     const TopoDS_Shape& fcE1 = it1.Value();
513     Standard_Boolean hsdm1 = HDS->HasSameDomain(fcE1);
514     if (!hsdm1) continue;
515     const TopTools_ListOfShape& fsdm2 = BDS.ShapeSameDomain(fcE1);
516     it2.Initialize(fsdm2);
517     for (; it2.More(); it2.Next()){
518       const TopoDS_Shape& f2 = it2.Value();
519       Standard_Boolean isb2 = mapfcE2.Contains(f2);
520       if (!isb2) continue;
521       Fsd1 = TopoDS::Face(fcE1); Fsd2 = TopoDS::Face(f2);
522       return Standard_True;
523     }
524   }
525   return Standard_False;
526 }
527
528 // ----------------------------------------------------------------------
529 Standard_EXPORT void FUN_ds_PURGEforE9(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
530 // ----------------------------------------------------------------------
531 {
532   // xpu040998 : line gives myLineINL=true, interference on geometry
533   //             edge/face describing contact on geometry -> EPIe + EPIf = 3dI
534   //             EPIf is faulty if edge is in face's geometry  
535   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
536   Standard_Integer ns = BDS.NbShapes();
537   for (Standard_Integer i = 1; i <= ns; i++) {
538     const TopoDS_Shape& EE = BDS.Shape(i);
539     if (EE.ShapeType() != TopAbs_EDGE) continue;
540  
541     const TopoDS_Edge& E = TopoDS::Edge(EE);
542     Standard_Boolean isdgE = BRep_Tool::Degenerated(E); 
543     if (isdgE) continue;
544
545     Standard_Integer IE = BDS.Shape(E);
546     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(E); 
547     TopOpeBRepDS_ListOfInterference LIcopy; FDS_assign(LI,LIcopy);
548     TopOpeBRepDS_ListOfInterference l3dF; Standard_Integer n3dF = FUN_selectSKinterference(LIcopy,TopOpeBRepDS_FACE,l3dF);    
549     if (n3dF == 0) continue;
550     
551     const TopTools_ListOfShape& lfcxE = FDSCNX_EdgeConnexitySameShape(E,HDS);
552     Standard_Integer nlfcxE = lfcxE.Extent();
553     if (nlfcxE == 0) continue; // NYIRaise
554     TopTools_ListIteratorOfListOfShape itf(lfcxE);
555     TopTools_IndexedMapOfShape mapf; for (; itf.More(); itf.Next()) mapf.Add(itf.Value());
556
557     Standard_Boolean removed = Standard_False;
558     TopOpeBRepDS_ListIteratorOfListOfInterference it(l3dF);
559     while (it.More()) {
560       const Handle(TopOpeBRepDS_Interference)& I = it.Value();
561       TopAbs_ShapeEnum SB = TopAbs_SHAPE, SA = TopAbs_SHAPE;Standard_Integer IB = 0, IA = 0;TopOpeBRepDS_Kind GT = TopOpeBRepDS_UNKNOWN, ST = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0, S = 0;
562       FDS_Idata(I,SB,IB,SA,IA,GT,G,ST,S);      
563       Standard_Boolean FhasGE = FDS_SIisGIofIofSBAofTofI(BDS,IE,I);
564       if (FhasGE) {removed = Standard_True; l3dF.Remove(it); continue;} // E has split ON F (cto904A3;e19,f14)
565       const TopoDS_Shape& F = BDS.Shape(S);
566       Standard_Boolean hsdm = HDS->HasSameDomain(F);
567       if (!hsdm) {it.Next(); continue;}
568       TopTools_ListIteratorOfListOfShape issdm(BDS.ShapeSameDomain(F));
569       Standard_Boolean foundinsdm = Standard_False;
570       for (; issdm.More(); issdm.Next())
571         if (mapf.Contains(issdm.Value())) {foundinsdm = Standard_True; break;}
572       if (!foundinsdm) {it.Next(); continue;} // E is IN geometry(F) (cto002D2;e33,f31)
573
574       // E is edge of FF sdm with F
575       removed = Standard_True; l3dF.Remove(it);
576     } //it(l3dF)
577
578     if (!removed) continue;
579     TopOpeBRepDS_ListOfInterference& LII = BDS.ChangeShapeInterferences(E); 
580     LII.Clear(); LII.Append(LIcopy); LII.Append(l3dF);
581   } //i=1..ns
582 } // PURGEforE9
583
584 // ----------------------------------------------------------------------
585 Standard_EXPORT void FUN_ds_completeforSE1(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
586 // ----------------------------------------------------------------------
587 {
588   // xpu160398 complement for INTERNAL transitions on section edge
589   // recall : we add geometry G on section edge SE only if 
590   //             SE has ISE=(T(face F),G,edge ES),
591   //          && F  has IF =(T,SE,S).
592   //
593   // purpose : SE has ISE=(T(face F'),G,edge),
594   //           F' has no interference with support==SE 
595   //          => looking for F / F and F' share ES, 
596   //                             F sdm with Fanc (one face ancestor of ES)
597   //                             F has I' = (T,SE,S).
598   // cto 009 D1
599   
600   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
601   Standard_Integer nse = BDS.NbSectionEdges();
602
603   for (Standard_Integer i = 1; i <= nse; i++) {
604     const TopoDS_Edge& SE = BDS.SectionEdge(i);
605     Standard_Integer ISE = BDS.Shape(SE);
606     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(SE);    
607
608     TopOpeBRepDS_TKI tki;
609     tki.FillOnGeometry(LI);  
610     for (tki.Init(); tki.More(); tki.Next()) {     
611
612       // ISE = (INTERNAL(FACE),G,EDGE) :
613       TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
614       TopOpeBRepDS_ListOfInterference loicopy; FDS_assign(loi,loicopy);
615       TopOpeBRepDS_ListOfInterference lI1; Standard_Boolean hasINT = ::FUN_selectTRAINTinterference(loicopy,lI1);
616       if (!hasINT) continue;
617       TopOpeBRepDS_ListOfInterference lI2; Standard_Integer nI = FUN_selectTRASHAinterference(lI1,TopAbs_FACE,lI2);
618       if (nI < 1) continue; 
619       TopOpeBRepDS_ListOfInterference lI3; nI = FUN_selectSKinterference(lI2,TopOpeBRepDS_EDGE,lI3);
620       if (nI < 1) continue; 
621
622       Standard_Boolean keepI = Standard_False;            
623 //      for (TopOpeBRepDS_ListIteratorOfListOfInterference it(lI3) ;it.More(); it.Next()){
624       TopOpeBRepDS_ListIteratorOfListOfInterference it(lI3) ;
625       for ( ;it.More(); it.Next()){
626         const Handle(TopOpeBRepDS_Interference)& I = it.Value();
627         keepI = FDS_SIisGIofIofSBAofTofI(BDS,ISE,I);
628         if (keepI) break;
629       }
630       if (keepI) continue; 
631       
632       // ISE = (INTERNAL(F),G,ES), F has no I with G==SE
633       // find fSE / fSE (SE's ancestor face) has  IfSE = (T,SE,support)  
634       //            - fSE sdm & fES (ES's ancestor face) -
635 //      for (it.Initialize(lI3) ;it.More(); it.Next()){
636       it.Initialize(lI3) ;
637       for ( ;it.More(); it.Next()){
638         const Handle(TopOpeBRepDS_Interference)& I = it.Value();
639         TopOpeBRepDS_Kind GT = TopOpeBRepDS_UNKNOWN, ST = TopOpeBRepDS_UNKNOWN;
640         Standard_Integer G1 = 0, S = 0;
641         FDS_data(I,GT,G1,ST,S);
642         TopAbs_ShapeEnum tsb,tsa; Standard_Integer isb,isa; FDS_Tdata(I,tsb,isb,tsa,isa);
643         const TopoDS_Edge& ES = TopoDS::Edge(BDS.Shape(S)); 
644         TopoDS_Face fSE,fES; Standard_Boolean sdmf = ::FUN_ds_hasSDMancestorfaces(HDS,SE,ES, fSE,fES);
645         if (!sdmf) continue;
646         Standard_Integer IfES = BDS.Shape(fES);
647
648         const TopOpeBRepDS_ListOfInterference& LIf = BDS.ShapeInterferences(fES);
649         TopOpeBRepDS_ListOfInterference LIfcopy; FDS_copy(LIf,LIfcopy);
650         TopOpeBRepDS_ListOfInterference LIfound; Standard_Integer nfound = FUN_selectGIinterference(LIfcopy,ISE,LIfound);
651         if (nfound < 1) continue; 
652
653         // cto 009 B1 : Ifor=(FORWARD(IfES),G1,S) && Irev=(REVERSED(IfES),G1,S)
654         //         -> do NOT reduce to I = (INTERNAL(IfES),G1,S) (we can have EXTERNAL Tr)       
655         FDS_copy(loi,loicopy); 
656         TopOpeBRepDS_ListOfInterference lI4;
657         FUN_selectITRASHAinterference(loicopy,IfES,lI4);
658         Standard_Boolean hasFORREV=Standard_False;
659         TopOpeBRepDS_ListOfInterference lfor; Standard_Integer nFOR = FUN_selectTRAORIinterference(lI4,TopAbs_FORWARD,lfor);
660         TopOpeBRepDS_ListOfInterference lrev; Standard_Integer nREV = FUN_selectTRAORIinterference(lI4,TopAbs_REVERSED,lrev);
661         hasFORREV = (nFOR > 0) || (nREV > 0); 
662         if (hasFORREV) break;
663
664         // newI : 
665         // -----
666         TopOpeBRepDS_Transition newT(TopAbs_INTERNAL);
667         newT.Index(IfES);
668         Standard_Real par = FDS_Parameter(I);
669         Standard_Boolean isevi = I->IsKind(STANDARD_TYPE(TopOpeBRepDS_EdgeVertexInterference));
670         Standard_Boolean B = Standard_False;
671         if (isevi) B = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I)->GBound();
672         Handle(TopOpeBRepDS_Interference) newI = MakeEPVInterference(newT,S,G1,par,K,TopOpeBRepDS_EDGE,B);
673         HDS->StoreInterference(newI,SE); 
674         break;
675       } // it(lI3) 
676     } // tki    
677   } // i=1..nse
678 } // completeforSE1
679
680 // ----------------------------------------------------------------------
681 Standard_EXPORT void FUN_ds_completeforSE2(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
682 // ----------------------------------------------------------------------
683 {
684   // xpu250398 compute 3dI
685   // recall : to have spOUT(SE) / spIN(SE) with SE section edge on bound G
686   //          we need IF = (T(F),G,F) with G not SE bound. 
687   //   
688   // purpose : Sometimes for gap's reasons we can miss such interference.
689   //           attached to ES, IFE = (T(FTRA),G,ES) with G not Gbound 
690   //           we find no IF = (T(FTRA),G,FTRA) 
691   //           1. look for FCX / FCX shares ES with FTA (recall : rkG==rkFCX)
692   //           2. compute I3d = (T2(FCX),G,FCX)
693   //   !!! if SE has splits ON F near G (if we have a 2dI near G) -> do NOT add I3d
694   // PRO12696 : on se 46 (create FEI/ f50) 
695         
696   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
697   Standard_Integer nse = BDS.NbSectionEdges();
698
699   for (Standard_Integer i = 1; i <= nse; i++) {
700     const TopoDS_Edge& SE = TopoDS::Edge(BDS.SectionEdge(i));
701     Standard_Integer rkSE = BDS.AncestorRank(SE);
702     BDS.Shape(SE);
703     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(SE);    
704
705     TopOpeBRepDS_TKI tki;
706     tki.FillOnGeometry(LI);      
707     for (tki.Init(); tki.More(); tki.Next()) {     
708
709       TopOpeBRepDS_Kind K; Standard_Integer G; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);   
710       Standard_Boolean point  = (K == TopOpeBRepDS_POINT);
711       Standard_Boolean vertex = (K == TopOpeBRepDS_VERTEX);
712
713       // interferences on GBound=1 not treated
714       Standard_Boolean try1 = Standard_True;
715       if (vertex) {
716         const TopoDS_Vertex& vG = TopoDS::Vertex(BDS.Shape(G));
717         TopoDS_Vertex OOv; Standard_Boolean hasOO = FUN_ds_getoov(vG,HDS,OOv);
718         Standard_Integer ovSE = FUN_tool_orientVinE(vG,SE);
719         if ((ovSE == 0) && hasOO) ovSE = FUN_tool_orientVinE(OOv,SE);
720         if (ovSE != 0) try1 = Standard_False;
721       }
722       if (!try1) continue;
723     
724       // SE has    {I=(T(face),    G not Gbound, edge)}
725       //    has NO {I'=(T'(face'), G not Gbound, face')}
726       TopOpeBRepDS_ListOfInterference loicopy; FDS_assign(loi,loicopy);
727       TopOpeBRepDS_ListOfInterference l1;
728       FUN_selectTRASHAinterference(loicopy,TopAbs_FACE,l1);
729       TopOpeBRepDS_ListOfInterference lF; Standard_Integer nF = FUN_selectSKinterference(l1,TopOpeBRepDS_FACE,lF);
730       if (nF > 1) continue;
731       TopOpeBRepDS_ListOfInterference lFE; Standard_Integer nFE = FUN_selectSKinterference(l1,TopOpeBRepDS_EDGE,lFE);
732       if (nFE == 0) continue;  
733
734       // I = (T(FTRA),G not Gbound, ES)
735       const Handle(TopOpeBRepDS_Interference)& I = lFE.First();
736       Standard_Real par = FDS_Parameter(I);
737
738       TopOpeBRepDS_Kind ST = TopOpeBRepDS_UNKNOWN; Standard_Integer S = 0; FDS_data(I,K,G,ST,S);
739       TopAbs_ShapeEnum tsb = TopAbs_SHAPE, tsa = TopAbs_SHAPE; Standard_Integer isb = 0, isa = 0; FDS_Tdata(I,tsb,isb,tsa,isa);
740       const TopoDS_Face& FTRA= TopoDS::Face(BDS.Shape(isb));
741       const TopoDS_Edge& ES = TopoDS::Edge(BDS.Shape(S)); 
742
743       // lfCX = {fCX / fCX shares ES with FTRA}
744       const TopTools_ListOfShape& lfCX = FDSCNX_EdgeConnexitySameShape(ES,HDS);      
745       for (TopTools_ListIteratorOfListOfShape itfcx(lfCX); itfcx.More(); itfcx.Next()){
746         const TopoDS_Face& FCX = TopoDS::Face(itfcx.Value());
747         Standard_Integer IFCX = BDS.Shape(FCX);
748         if (FCX.IsSame(FTRA)) continue;
749
750         // xpu140498 : NYI check SE has part ON FCX(with bound G) 
751         TopOpeBRepDS_ListOfInterference l2; Standard_Integer n2 = FUN_selectITRASHAinterference(lFE,IFCX,l2);
752         if (n2 > 0) continue;
753
754         Standard_Real OOpar = 0.;
755         if (point) {
756           gp_Pnt p3d = BDS.Point(G).Point(); 
757           Standard_Real t1 = BDS.Point(G).Tolerance(); Standard_Real t2 = FUN_tool_maxtol(ES);
758           Standard_Real t = (t1 > t2) ? t1 : t2;
759           Standard_Real d = 1.e1;Standard_Boolean ok = FUN_tool_projPonE(p3d,ES,OOpar,d);
760           if (!ok) {continue;}
761           if (d > t) {continue;}
762         }
763         if (vertex) { // rkG == rkES
764           const TopoDS_Vertex& vG = TopoDS::Vertex(BDS.Shape(G));
765           Standard_Integer rkG = BDS.AncestorRank(G);
766
767           // modified by NIZHNY-MKK  Mon Apr  2 15:38:11 2001.BEGIN
768           //      if (rkG == rkSE) OOpar = BRep_Tool::Parameter(vG,ES);
769           if (rkG == rkSE) {
770             Standard_Integer hasvG = FUN_tool_orientVinE(vG,ES);
771             if(hasvG==0) {
772               continue;
773             }
774             OOpar = BRep_Tool::Parameter(vG,ES);
775           }
776           // modified by NIZHNY-MKK  Mon Apr  2 15:38:30 2001.END
777           else {
778             TopoDS_Shape oov; Standard_Boolean hasoov = FUN_ds_getoov(vG,BDS,oov);
779             if (!hasoov) {
780               Standard_Real t1 = BRep_Tool::Tolerance(vG); Standard_Real t2 = FUN_tool_maxtol(ES);
781               Standard_Real t = (t1 > t2) ? t1 : t2;
782               gp_Pnt p = BRep_Tool::Pnt(vG);
783               Standard_Real parES,dd=1.e1;
784               Standard_Boolean ok = FUN_tool_projPonE(p,ES,parES,dd);
785               if (!ok) {continue;}
786               if (dd > t) {continue;}
787               OOpar = parES;
788             }
789             else         OOpar = BRep_Tool::Parameter(TopoDS::Vertex(oov),ES);
790           }
791         }
792
793         gp_Pnt2d OOuv; Standard_Boolean ok = FUN_tool_paronEF(ES,OOpar,FCX,OOuv); 
794         if (!ok) {continue;}
795
796         TopOpeBRepDS_Transition newT; 
797         // -------
798         Standard_Boolean isonper = false; Standard_Real par1 = 0.0, par2 = 0.0; Standard_Real factor = 1.e-4;
799         FDS_LOIinfsup(BDS,SE,par,K,G,
800                         BDS.ShapeInterferences(SE),par1,par2,isonper);
801
802         TopOpeBRepTool_makeTransition MKT; 
803         TopAbs_State stb = TopAbs_UNKNOWN,sta = TopAbs_UNKNOWN; 
804         ok = MKT.Initialize(SE,par1,par2,par, FCX,OOuv, factor);
805         if (ok) ok = MKT.SetRest(ES,OOpar);
806         if (ok) ok = MKT.MkTonE(stb,sta);
807         if (!ok) {continue;}
808         newT.Before(stb); newT.After(sta); newT.Index(IFCX);
809
810         Handle(TopOpeBRepDS_Interference) newI;
811         // --------     
812         Standard_Boolean B = Standard_False;
813         if (vertex) B = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I)->GBound();
814         newI = MakeEPVInterference(newT,IFCX,G,par,K,TopOpeBRepDS_FACE,B);
815         HDS->StoreInterference(newI,SE);
816       } // itfcx
817     } // tki
818   } // nse
819 } // completeforSE2
820
821
822 static Standard_Boolean FUN_ds_completeforSE3(const TopOpeBRepDS_DataStructure& BDS, const TopoDS_Edge& SE,
823                                  const TopOpeBRepDS_Kind K,
824 //                                 const Standard_Integer G,
825                                  const Standard_Integer ,
826                                  const TopOpeBRepDS_ListOfInterference& loi,
827                                  Standard_Real& parE, Standard_Integer& IES, Standard_Integer& ITRASHA, TopOpeBRepDS_Transition& Tr)
828 {        
829   if (K == TopOpeBRepDS_VERTEX) return Standard_False;
830   Standard_Integer ISE = BDS.Shape(SE);  
831
832   TopOpeBRepDS_ListOfInterference loicopy; FDS_assign(loi,loicopy);  
833   TopOpeBRepDS_ListOfInterference lINT; Standard_Integer nINT = FUN_selectTRAORIinterference(loicopy,TopAbs_INTERNAL,lINT);
834   TopOpeBRepDS_ListOfInterference lEXT; Standard_Integer nEXT = FUN_selectTRAORIinterference(loicopy,TopAbs_EXTERNAL,lEXT);
835   Standard_Integer n1 = nINT + nEXT;
836   if (n1 < 1) return Standard_False; 
837   TopOpeBRepDS_ListOfInterference l1; l1.Append(lINT); l1.Append(lEXT);
838   
839   // b. I = (INT/EXT(F),G,S), F has I with G==ES
840   TopOpeBRepDS_ListOfInterference l2; Standard_Integer n2 = FUN_selectTRASHAinterference(l1,TopAbs_FACE,l2);
841   if (n2 < 1) return Standard_False;
842   Standard_Boolean okb = Standard_False;
843   for (TopOpeBRepDS_ListIteratorOfListOfInterference it2(l2); it2.More(); it2.Next()){
844     const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
845     okb = FDS_SIisGIofIofSBAofTofI(BDS,ISE,I2);
846     if (okb) break;
847   }
848   if (!okb) return Standard_False;
849   
850   // a. I3d = IFE+IF     
851   TopOpeBRepDS_ListOfInterference l2e; Standard_Integer n2e = FUN_selectSKinterference(l2,TopOpeBRepDS_EDGE,l2e);
852   TopOpeBRepDS_ListOfInterference l2f; Standard_Integer n2f = FUN_selectSKinterference(l2,TopOpeBRepDS_FACE,l2f);
853   if ((n2e == 0) || (n2f == 0)) return Standard_False;  
854   Standard_Integer sI3d = l2f.First()->Support();
855   TopOpeBRepDS_ListOfInterference l3d; Standard_Integer n3d = FUN_selectITRASHAinterference(l2e,sI3d,l3d);
856   if (n3d < 1) return Standard_False;
857   
858   // Tr
859   //---
860   const Handle(TopOpeBRepDS_Interference)& I3 = l3d.First();
861   TopOpeBRepDS_Kind K3 = TopOpeBRepDS_UNKNOWN, ST3 = TopOpeBRepDS_UNKNOWN; Standard_Integer G3 = 0, S3 = 0; FDS_data(I3,K3,G3,ST3,S3);
862   TopAbs_ShapeEnum tsb3 = TopAbs_SHAPE, tsa3 = TopAbs_SHAPE; Standard_Integer isb3 = 0, isa3 = 0; FDS_Tdata(I3,tsb3,isb3,tsa3,isa3);
863   IES = S3; ITRASHA = isb3;
864   
865   const TopoDS_Edge& Eline = TopoDS::Edge(BDS.Shape(IES));
866   const TopoDS_Face& F     = TopoDS::Face(BDS.Shape(ITRASHA));
867   parE = FDS_Parameter(I3);
868
869   Standard_Real parline = 0.0; Standard_Boolean ok = FUN_tool_parE(SE,parE,Eline,parline);
870   if (!ok) {return Standard_False;}
871   gp_Pnt2d uv;    ok = FUN_tool_paronEF(Eline,parline,F,uv);
872   if (!ok) {return Standard_False;}
873   Standard_Real par1 = 0.0, par2 = 0.0; FUN_tool_bounds(SE,par1,par2);
874   Standard_Real factor = 1.e-4;
875
876
877   TopOpeBRepTool_makeTransition MKT; TopAbs_State stb = TopAbs_UNKNOWN,sta = TopAbs_UNKNOWN; 
878   ok = MKT.Initialize(SE,par1,par2,parE, F,uv, factor);
879   if (ok) ok = MKT.SetRest(Eline,parline);
880   if (ok) ok = MKT.MkTonE(stb,sta);
881   if (!ok) {return Standard_False;}
882   Tr.Before(stb); Tr.After(sta); Tr.Index(ITRASHA);
883   return Standard_True;
884 }
885
886 // ----------------------------------------------------------------------
887 Standard_EXPORT void FUN_ds_completeforSE3(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
888 // ----------------------------------------------------------------------
889 {
890   // xpu170498 : t3 (splits of e7)
891   // prequesitory :
892   //  edge SE - a. is tangent to FTRA on ES at G, has NO SPLIT ON FTRA (near G). 
893   //          - b. has splitON FCX (FCX and FTRA share ES)  
894   //  a. IFE=(T(FTRA),Gpoint,ES) && IF=(T(FTRA),Gpoint,FTRA)
895   //     T describes T3d
896   //  b. IFE=(T'(FCX),Gpoint,S) / FCX has I=(T'',SE,SS) 
897   // 
898   // purpose : when T(FTRA) is INTERNAL/EXTERNAL, the compute of spIN/spOU fails, 
899   //           => compute interference I3d=IFE + IF with T==FORWARD/REVERSED.
900         
901   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
902   Standard_Integer nse = BDS.NbSectionEdges();
903   for (Standard_Integer i = 1; i <= nse; i++) {
904     const TopoDS_Edge& SE = BDS.SectionEdge(i);
905     Standard_Integer ISE = BDS.Shape(SE);
906     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(SE);    
907
908     TopOpeBRepDS_ListOfInterference newLI; Standard_Boolean hasnewLI = Standard_False;
909     TopOpeBRepDS_TKI tki;
910     tki.FillOnGeometry(LI);      
911     for (tki.Init(); tki.More(); tki.Next()) {     
912
913       TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
914       Standard_Real parE = 0.0; Standard_Integer IES=0, ITRASHA=0; TopOpeBRepDS_Transition Tr;
915       Standard_Boolean ok = FUN_ds_completeforSE3(BDS,SE,K,G,loi,parE,IES,ITRASHA,Tr);
916       
917       TopOpeBRepDS_ListOfInterference loicopy; FDS_assign(loi,loicopy);      
918       if (!ok) {newLI.Append(loicopy); continue;}
919       
920       // delete interferences =(T(face IF),G,S)
921       TopOpeBRepDS_ListOfInterference lIdel;
922       FUN_selectITRASHAinterference(loicopy,ITRASHA,lIdel);      
923
924       Handle(TopOpeBRepDS_Interference) TrFE, TrFF;
925       //--------------
926       hasnewLI = Standard_True;
927       TrFE = MakeEPVInterference(Tr, ISE,G,parE,K,TopOpeBRepDS_EDGE,Standard_False);
928       TrFF = MakeEPVInterference(Tr,ITRASHA,G,parE,K,TopOpeBRepDS_FACE,Standard_False);
929       newLI.Append(TrFF); newLI.Append(TrFE); newLI.Append(loicopy);
930     } // tki
931
932     if (hasnewLI) {
933       TopOpeBRepDS_ListOfInterference& LII = BDS.ChangeShapeInterferences(SE); LII.Clear(); 
934       LII.Append(newLI);
935     }
936     
937   } //i=1..nse
938 } // completeforSE3
939
940 // ----------------------------------------------------------------------
941 Standard_EXPORT Standard_Boolean FUN_ds_shareG
942 (const Handle(TopOpeBRepDS_HDataStructure)& HDS, const Standard_Integer iF1,const Standard_Integer iF2,
943  const Standard_Integer iE2, const TopoDS_Edge& Esp, Standard_Boolean& shareG)
944 // ----------------------------------------------------------------------
945 // F1 sdm F2, share Esp (split of E2)
946 {
947   const TopOpeBRepDS_DataStructure& BDS = HDS->DS();
948   Standard_Boolean hsdm = HDS->HasSameDomain(BDS.Shape(iE2));
949   if (!hsdm) return Standard_False; 
950
951   const TopoDS_Face& F1 = TopoDS::Face(BDS.Shape(iF1));
952   const TopoDS_Face& F2 = TopoDS::Face(BDS.Shape(iF2));
953   const TopoDS_Edge& E2 = TopoDS::Edge(BDS.Shape(iE2));
954
955   Standard_Real tol = Precision::Confusion()*1.e3;
956   Standard_Real f = 0.0, l = 0.0; FUN_tool_bounds(Esp,f,l);
957   Standard_Real x = 0.45678; Standard_Real par = (1-x)*f + x*l;
958   gp_Pnt P; Standard_Boolean ok = FUN_tool_value(par,Esp,P);
959   if (!ok) return Standard_False;
960   
961   Standard_Real d2 = 0.0, par2 = 0.0; ok = FUN_tool_projPonE(P,E2,par2,d2);
962   if (!ok) return Standard_False;
963   if (d2 > tol)  return Standard_False;    
964
965   gp_Vec nggeomF2; ok = FUN_tool_nggeomF(par2,E2,F2,nggeomF2);
966   if (!ok) return Standard_False;
967   gp_Dir nxx2; ok = FUN_tool_getxx(F2,E2,par2,nggeomF2,nxx2);
968   if (!ok) return Standard_False;
969     
970
971   TopTools_IndexedMapOfShape mE1; TopExp::MapShapes(F1,TopAbs_EDGE,mE1);
972   const TopTools_ListOfShape& sdmE1 = BDS.ShapeSameDomain(iE2);
973   for (TopTools_ListIteratorOfListOfShape it(sdmE1); it.More(); it.Next()){
974     const TopoDS_Edge& E1 = TopoDS::Edge(it.Value());
975     Standard_Boolean isb = mE1.Contains(E1);
976     if (!isb) continue;
977
978     Standard_Real d1 = 0.0, par1 = 0.0; ok = FUN_tool_projPonE(P,E1,par1,d1);
979     if (!ok) continue;
980     if (d1 > tol) continue;
981
982     // E1 on F1, E2 on F2, E1 and E2 share split Esp(nyi : check it)    
983     gp_Vec nggeomF1; ok = FUN_tool_nggeomF(par1,E1,F1,nggeomF1);
984     if (!ok) return Standard_False;
985     gp_Dir nxx1; ok = FUN_tool_getxx(F1,E1,par1,nggeomF1,nxx1);
986     if (!ok) return Standard_False;
987
988     Standard_Real prod = nxx1.Dot(nxx2);
989     shareG =  (prod > 0.);
990     return Standard_True;
991   }
992   return Standard_False;
993 }
994 // ----------------------------------------------------------------------
995 Standard_EXPORT Standard_Boolean FUN_ds_mkTonFsdm
996 (const Handle(TopOpeBRepDS_HDataStructure)& HDS, const Standard_Integer iF1, const Standard_Integer iF2, const Standard_Integer iE2, 
997  const Standard_Integer iEG, const Standard_Real paronEG, const TopoDS_Edge& Esp, const Standard_Boolean pardef, 
998  TopOpeBRepDS_Transition& T)
999 // ----------------------------------------------------------------------
1000 // =================================
1001 // prequesitory : F1 and F2 are SDSO
1002 // =================================
1003 // F1 sdm F2,  EG has split ON F1 shared by F2
1004 //
1005 // EG and E2 share geometric point G (of param paronEG)
1006 // pardef = Standard_True : paronEG is defined
1007 // else         : use Esp to find paronEG, Esp is split of EG
1008 // (!! we can have EG==E2)
1009 //
1010 // purpose : computes 2d transition of F1 when crossing EG relative to 
1011 //           2dmatter(F2) limited by E2 :
1012 //        -> 2d FEI attached to F1 = (T(F2), G=EG, S=F2)
1013 {
1014   const TopOpeBRepDS_DataStructure& BDS = HDS->DS();
1015   Standard_Boolean hsdm = HDS->HasSameDomain(BDS.Shape(iE2));
1016   if (!hsdm) return Standard_False; 
1017
1018   const TopoDS_Face& F1 = TopoDS::Face(BDS.Shape(iF1));
1019   const TopoDS_Face& F2 = TopoDS::Face(BDS.Shape(iF2));
1020   const TopoDS_Edge& E2 = TopoDS::Edge(BDS.Shape(iE2));
1021   const TopoDS_Edge& EG = TopoDS::Edge(BDS.Shape(iEG));
1022
1023   Standard_Boolean EGisE2 = (iEG == iE2);
1024   Standard_Real tol = Precision::Confusion()*1.e3;
1025
1026   // beafter :
1027   // ---------
1028   Standard_Boolean ok = Standard_False;
1029   gp_Pnt P; Standard_Real parEG = 0.0;
1030   if (pardef) parEG = paronEG;
1031   else {
1032     Standard_Real f = 0.0, l = 0.0; FUN_tool_bounds(Esp,f,l);
1033     Standard_Real dEG = 0.0; ok = FUN_tool_projPonE(P,EG,parEG,dEG);
1034     if (!ok) return Standard_False;
1035     if (dEG > tol)  return Standard_False; 
1036   }
1037   ok = FUN_tool_value(parEG,EG,P);
1038   if (!ok) return Standard_False;
1039   gp_Vec tgtEG ; ok = TopOpeBRepTool_TOOL::TggeomE(parEG,EG,tgtEG);
1040   if (!ok) return Standard_False;
1041   gp_Vec ngF1; ok = FUN_tool_nggeomF(parEG,EG,F1,ngF1);
1042   if (!ok) return Standard_False;
1043   gp_Vec beafter = ngF1^tgtEG;
1044   
1045   // nxx2 :
1046   // ------
1047   Standard_Real par2 = 0.0;
1048   if (EGisE2) par2 = parEG;
1049   else {
1050     Standard_Real d2 = 0.0; ok = FUN_tool_projPonE(P,E2,par2,d2);
1051     if (!ok) return Standard_False;
1052     if (d2 > tol)  return Standard_False;    
1053   }
1054   gp_Vec ngF2; ok = FUN_tool_nggeomF(par2,E2,F2,ngF2);
1055   if (!ok) return Standard_False;
1056   gp_Dir nxx2; ok = FUN_tool_getxx(F2,E2,par2,ngF2,nxx2);
1057   if (!ok) return Standard_False;
1058
1059   // T :
1060   // ---
1061   Standard_Boolean sdmEGE2 = EGisE2;
1062   if (!sdmEGE2) sdmEGE2 = FUN_ds_sdm(BDS,EG,E2);
1063   if (!sdmEGE2) return Standard_False;
1064   
1065   Standard_Real prod = beafter.Dot(nxx2);
1066   Standard_Real tola = Precision::Angular()*1.e3;
1067   ok = (Abs(1- Abs(prod)) < tola);
1068   if (!ok) return Standard_False;
1069
1070   if (prod > 0.) T = TopOpeBRepDS_Transition(TopAbs_OUT,TopAbs_IN);
1071   else           T = TopOpeBRepDS_Transition(TopAbs_IN,TopAbs_OUT);
1072   return Standard_True;
1073 }
1074
1075 #define UNKNOWN    (0)
1076 #define ONSAMESHA  (1)
1077 #define CLOSESAME  (11)
1078 #define ONOPPOSHA  (2)
1079 #define CLOSEOPPO  (22)
1080 #define FORREVOPPO (222)
1081
1082 Standard_EXPORT Standard_Integer FUN_ds_oriEinF(const TopOpeBRepDS_DataStructure& BDS, const TopoDS_Edge& E, const TopoDS_Shape& F,
1083                                    TopAbs_Orientation& O)
1084 // purpose :
1085 //  * E is edge of F :returns orientation of E in F 
1086 //  * E is edge of Fsd : Fsd sdm with F, 
1087 //  returns orientation of E in F /E describes the same 2d area in F as in Fsd
1088 //  * !! if E is closing edge, returns CLOSESAME or CLOSEOPPO
1089 {
1090   O = TopAbs_EXTERNAL;
1091   Standard_Integer rkF = BDS.AncestorRank(F);
1092   Standard_Integer rkE = BDS.AncestorRank(E);
1093
1094   const TopoDS_Edge& EE = TopoDS::Edge(E);
1095   const TopoDS_Face& FF = TopoDS::Face(F);
1096   Standard_Integer iF = BDS.Shape(F);
1097   TopAbs_Orientation oF = BDS.Shape(iF).Orientation();
1098   
1099   if (rkF == rkE) {
1100     Standard_Boolean samsha = FUN_tool_orientEinFFORWARD(EE,FF,O);
1101     if (samsha) {
1102       Standard_Boolean iscE = BRep_Tool::IsClosed(EE,FF);
1103       if (iscE) return CLOSESAME;
1104       else      return ONSAMESHA;
1105     }
1106     else        return UNKNOWN;
1107   }
1108   else {    
1109     const TopTools_ListOfShape& sdmFs = BDS.ShapeSameDomain(FF);
1110     Standard_Boolean hsdm = (sdmFs.Extent() > 0);
1111
1112     if (hsdm) {
1113       Standard_Boolean hasFOR=Standard_False, hasREV=Standard_False; // xpu120898 (PRO14785 : e36 shared by f34 & f39,
1114                                   // faces sdm with f16)
1115       TopOpeBRepDS_Config C = BDS.SameDomainOri(FF);
1116
1117       for (TopTools_ListIteratorOfListOfShape it(sdmFs); it.More(); it.Next()){
1118         const TopoDS_Face& Fsdm = TopoDS::Face(it.Value());
1119         Standard_Integer iFsdm = BDS.Shape(Fsdm);
1120         Standard_Integer rksdm = BDS.AncestorRank(Fsdm);
1121         if (rksdm == rkF) continue;
1122         
1123         Standard_Boolean samsha = FUN_tool_orientEinFFORWARD(EE,Fsdm,O);
1124         if (!samsha) continue;
1125
1126         Standard_Boolean iscE = BRep_Tool::IsClosed(EE,Fsdm);
1127         if (iscE) return CLOSEOPPO;
1128         else {
1129           TopOpeBRepDS_Config Csdm = BDS.SameDomainOri(Fsdm);
1130           Standard_Boolean toreverse1 = (Csdm != C) && (!M_INTERNAL(O)) && (!M_EXTERNAL(O));
1131           if (toreverse1) O = TopAbs::Complement(O);
1132           
1133           TopAbs_Orientation oFsdm = BDS.Shape(iFsdm).Orientation();
1134           Standard_Boolean toreverse2 = (oF != oFsdm) && (!M_INTERNAL(oFsdm)) && (!M_EXTERNAL(oFsdm));
1135           if (toreverse2) O = TopAbs::Complement(O);
1136           if (!hasFOR) hasFOR = M_FORWARD(O);
1137           if (!hasREV) hasREV = M_REVERSED(O);
1138         }
1139       } // it(sdmFs)
1140       if (hasFOR && hasREV) return FORREVOPPO;
1141       if (hasFOR || hasREV) {
1142         O = hasFOR ? TopAbs_FORWARD : TopAbs_REVERSED;
1143         return ONOPPOSHA;
1144       }
1145     }
1146     else return UNKNOWN;
1147   }
1148   return UNKNOWN;
1149 }
1150
1151 #define NONE        (0)
1152 #define EREFandESUP (2)
1153 #define FIRST (1)
1154 #define LAST  (2)
1155 static Standard_Integer FUN_EisSE2(const TopOpeBRepDS_DataStructure& BDS,
1156 //                                   const TopTools_MapOfShape& Fsdm,
1157                                    const TopTools_MapOfShape& ,
1158                                    const TopoDS_Edge& E,
1159                                    const Handle(TopOpeBRepDS_Interference)& I)
1160 {
1161   const TopOpeBRepDS_Transition& T = I->Transition();
1162   const TopAbs_Orientation O = T.Orientation(TopAbs_IN);
1163   TopAbs_ShapeEnum SB = TopAbs_SHAPE, SA = TopAbs_SHAPE;Standard_Integer IB = 0, IA = 0;TopOpeBRepDS_Kind GT = TopOpeBRepDS_UNKNOWN, ST = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0, S = 0;
1164   FDS_Idata(I,SB,IB,SA,IA,GT,G,ST,S);
1165   if (GT != TopOpeBRepDS_VERTEX) return NONE;
1166   if (M_EXTERNAL(O)) return NONE;
1167
1168   // E sdm ES
1169   if (SB != TopAbs_EDGE) return NONE;
1170 //  BDS.Shape(S);
1171
1172   Standard_Integer rkE = BDS.AncestorRank(E);
1173   Standard_Integer rkG = BDS.AncestorRank(G);   
1174   const TopoDS_Vertex& VG   = TopoDS::Vertex(BDS.Shape(G));
1175   Standard_Integer Gsd = 0; Standard_Boolean Ghsd = FUN_ds_getVsdm(BDS,G,Gsd);
1176   Standard_Integer oGinE = 0;
1177   if (Ghsd) {
1178     const TopoDS_Vertex& VGsd = TopoDS::Vertex(BDS.Shape(Gsd));
1179     if (rkE == rkG)  oGinE = FUN_tool_orientVinE(VG,E);
1180     else             oGinE = FUN_tool_orientVinE(VGsd,E);    
1181   }
1182   else oGinE = FUN_tool_orientVinE(VG,E);
1183
1184   if (oGinE == 0) return EREFandESUP; // G in IN E
1185
1186   Standard_Boolean noshare = ((oGinE == LAST) && M_FORWARD(O));
1187   noshare = noshare || ((oGinE == FIRST) && M_REVERSED(O));
1188   if (noshare) return NONE;
1189
1190   if (SB == TopAbs_EDGE) {// E sdm edge(ST)
1191     if (!Ghsd) return EREFandESUP; 
1192     return EREFandESUP;    
1193   }
1194   
1195   return NONE;
1196 }
1197 Standard_EXPORT void FUN_ds_FillSDMFaces(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1198 {
1199   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1200   Standard_Integer ns = BDS.NbShapes();
1201   
1202   for (Standard_Integer i= 1; i <= ns; i++) {
1203     const TopoDS_Shape& S = BDS.Shape(i);
1204     if (S.ShapeType() != TopAbs_FACE) continue;
1205
1206     Standard_Integer rkS = BDS.AncestorRank(S);
1207     TopTools_MapOfShape Fsdm;
1208     TopTools_ListIteratorOfListOfShape itf(BDS.ShapeSameDomain(S));
1209     for (; itf.More(); itf.Next()){
1210       const TopoDS_Shape& f = itf.Value();
1211       Standard_Integer rkf = BDS.AncestorRank(f);
1212       if (rkf != rkS) Fsdm.Add(f);
1213     }
1214     Standard_Boolean hsd = (Fsdm.Extent() > 0);
1215     if (!hsd) continue;
1216     
1217     TopExp_Explorer ex(S, TopAbs_EDGE);
1218     for (; ex.More(); ex.Next()){
1219       const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
1220       Standard_Boolean hase = BDS.HasShape(E); 
1221       if (!hase) continue;
1222       Standard_Boolean isse = BDS.IsSectionEdge(E); 
1223       if (isse) continue;      
1224       const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(E);
1225       Standard_Integer nI = LI.Extent();
1226       if (nI < 1) continue;
1227       
1228       TopOpeBRepDS_ListIteratorOfListOfInterference it;
1229       for (it.Initialize(LI); it.More(); it.Next()){
1230         const Handle(TopOpeBRepDS_Interference)& I = it.Value();
1231         Standard_Integer isSE2 = FUN_EisSE2(BDS,Fsdm,E,I);
1232         if (isSE2 == NONE) continue;
1233         BDS.AddSectionEdge(E);
1234         if (isSE2 == EREFandESUP) {
1235           Standard_Integer ST = I->Support();
1236           const TopoDS_Edge& ES = TopoDS::Edge(BDS.Shape(ST));
1237           BDS.AddSectionEdge(ES);
1238         }
1239         break;
1240       }
1241     } // ex(S, TopAbs_EDGE);
1242   } // i = i..ns
1243 }
1244
1245 Standard_EXPORT void FUN_ds_addSEsdm1d(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1246 {
1247   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1248   Standard_Integer ns = BDS.NbShapes();
1249   for (Standard_Integer i= 1; i <= ns; i++) {
1250     const TopoDS_Shape& S = BDS.Shape(i);
1251     if (S.ShapeType() != TopAbs_EDGE) continue;
1252     const TopoDS_Edge& E = TopoDS::Edge(S);
1253     Standard_Boolean dgE = BRep_Tool::Degenerated(E);
1254     if (dgE) continue;
1255
1256     Standard_Boolean isse = BDS.IsSectionEdge(E); 
1257     if (isse) continue;  
1258     Standard_Integer rkE = BDS.AncestorRank(E);
1259     if (rkE != 1) continue;
1260
1261     Standard_Boolean shareG = Standard_False;
1262     TopTools_ListOfShape lsd;
1263     TopOpeBRepDS_TOOL::EShareG(HDS,E,lsd);
1264     TopTools_ListIteratorOfListOfShape itsd(lsd); 
1265     if (itsd.More()) shareG = Standard_True;
1266     for (; itsd.More(); itsd.Next()) BDS.AddSectionEdge(TopoDS::Edge(itsd.Value()));
1267     if (shareG) BDS.AddSectionEdge(E);
1268   }//i=1..ns
1269 }// FUN_ds_addSEsdm1d
1270
1271 Standard_EXPORT Standard_Integer FUN_ds_hasI2d(
1272 //                              const Standard_Integer EIX,
1273                               const Standard_Integer ,
1274                               const TopOpeBRepDS_ListOfInterference& LLI,
1275                               TopOpeBRepDS_ListOfInterference& LI2d)
1276 {
1277   // LI : attached to EIX at given G
1278   // recall : I3d if I1=(T(FTRA),G,FTRA) && I2=(T(FTRA),G,E)
1279   //          I2d if only I=(T(FTRA),G,E) (=>EIX is on FF sdm with FTRA)
1280
1281   TopOpeBRepDS_ListOfInterference LI; FDS_assign(LLI,LI);
1282   TopOpeBRepDS_ListOfInterference L1dE; FUN_selectTRASHAinterference(LI,TopAbs_EDGE,L1dE); 
1283   TopOpeBRepDS_ListOfInterference LIF;FUN_selectSKinterference(LI,TopOpeBRepDS_FACE,LIF);
1284   TopOpeBRepDS_ListOfInterference LIE;FUN_selectSKinterference(LI,TopOpeBRepDS_EDGE,LIE);
1285   LI.Append(L1dE);
1286   TopOpeBRepDS_ListIteratorOfListOfInterference itE(LIE);
1287   for (; itE.More(); itE.Next()){
1288     const Handle(TopOpeBRepDS_Interference)& IE = itE.Value();
1289     TopOpeBRepDS_Kind GTE = TopOpeBRepDS_UNKNOWN, STE = TopOpeBRepDS_UNKNOWN; Standard_Integer GE = 0, SE = 0; FDS_data(IE,GTE,GE,STE,SE);
1290     TopAbs_ShapeEnum tsb = TopAbs_SHAPE, tsa = TopAbs_SHAPE; Standard_Integer isb = 0, isa = 0; FDS_Tdata(IE,tsb,isb,tsa,isa);
1291     
1292     TopOpeBRepDS_ListIteratorOfListOfInterference itF(LIF);
1293     Standard_Boolean is3d = Standard_False;
1294     for (; itF.More(); itF.Next()){
1295       const Handle(TopOpeBRepDS_Interference)& IF = itF.Value();
1296       TopOpeBRepDS_Kind GTF = TopOpeBRepDS_UNKNOWN, STF = TopOpeBRepDS_UNKNOWN;
1297       Standard_Integer GF=0,SF=0;
1298       FDS_data(IF,GTF,GF,STF,SF);
1299       if (GE != GF) continue;
1300       if (SF==isb) {
1301         is3d = Standard_True;
1302         break;
1303       }      
1304     } // itF
1305     if (!is3d) LI2d.Append(IE);
1306   } // itE
1307   Standard_Integer nLI2d = LI2d.Extent();
1308   return nLI2d;
1309 }
1310
1311 // ----------------------------------------------------------------------
1312 Standard_EXPORT void FUN_ds_completeforSE4(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1313 // ----------------------------------------------------------------------
1314 // xpu160698 : section edge SE intersects ES at G=point
1315 //             ES closing edge on FTRA
1316 //             we need to have transitions :
1317 //             T1=(OU/IN(FTRA),GP,ES)
1318 //             T2=(IN/OU(FTRA),GP,ES), for the compute of splitON     
1319 // PRO6965, (SE=e13,F=f6,ES=e12)
1320 {
1321   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1322   Standard_Integer nse = BDS.NbSectionEdges();
1323   for (Standard_Integer i = 1; i <= nse; i++) {
1324     const TopoDS_Edge& SE = BDS.SectionEdge(i);
1325     BDS.Shape(SE);
1326     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(SE);    
1327
1328     TopOpeBRepDS_ListOfInterference newLI;
1329     TopOpeBRepDS_TKI tki;
1330     tki.FillOnGeometry(LI);      
1331     for (tki.Init(); tki.More(); tki.Next()) {     
1332       TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
1333       if (K != TopOpeBRepDS_POINT) continue;
1334
1335       TopOpeBRepDS_ListOfInterference loicopy; FDS_assign(loi,loicopy);
1336       TopOpeBRepDS_ListOfInterference l1;
1337       FUN_selectSKinterference(loicopy,TopOpeBRepDS_EDGE,l1);
1338       TopOpeBRepDS_ListOfInterference l2; Standard_Integer n2 = FUN_selectTRASHAinterference(l1,TopAbs_FACE,l2);
1339       if (n2 < 1) continue;
1340
1341       const Handle(TopOpeBRepDS_Interference)& I = l2.First();
1342       TopOpeBRepDS_Kind GT = TopOpeBRepDS_UNKNOWN, ST = TopOpeBRepDS_UNKNOWN; Standard_Integer S = 0; FDS_data(I,GT,G,ST,S);
1343       TopAbs_ShapeEnum tsb = TopAbs_SHAPE, tsa = TopAbs_SHAPE; Standard_Integer isb = 0, isa = 0; FDS_Tdata(I,tsb,isb,tsa,isa);
1344       const TopoDS_Edge& ES = TopoDS::Edge(BDS.Shape(S));
1345       const TopoDS_Face& FTRA = TopoDS::Face(BDS.Shape(isb));
1346
1347       Standard_Boolean closing = FUN_tool_IsClosingE(ES,FTRA,FTRA);
1348       if (!closing) continue;
1349
1350       Standard_Boolean hasFOR=Standard_False,hasREV=Standard_False;
1351       for (TopOpeBRepDS_ListIteratorOfListOfInterference it(l2); it.More(); it.Next()){
1352         const Handle(TopOpeBRepDS_Interference)& I2 = it.Value();
1353         TopOpeBRepDS_Kind GT2 = TopOpeBRepDS_UNKNOWN, ST2 = TopOpeBRepDS_UNKNOWN; Standard_Integer G2 = 0, S2 = 0; FDS_data(I2,GT2,G2,ST2,S2);
1354         TopAbs_ShapeEnum tsb2 = TopAbs_SHAPE, tsa2 = TopAbs_SHAPE; Standard_Integer isb2 = 0, isa2 = 0; FDS_Tdata(I2,tsb2,isb2,tsa2,isa2);
1355         Standard_Boolean error = (S2 != S) || (isb2 != isb);
1356         if (error) return; // nyi raise
1357         TopAbs_Orientation O2 = I2->Transition().Orientation(TopAbs_IN);
1358         if (!hasFOR) hasFOR = M_FORWARD(O2);
1359         if (!hasREV) hasREV = M_REVERSED(O2);
1360       }
1361       if (!hasFOR && !hasREV) continue;
1362       if ( hasFOR && hasREV ) continue;
1363       TopAbs_Orientation newO = hasFOR ? TopAbs_REVERSED : TopAbs_FORWARD;
1364       TopOpeBRepDS_Transition newT(newO); newT.Index(isb);
1365       Standard_Real par = FDS_Parameter(I);
1366       Handle(TopOpeBRepDS_Interference) newI = MakeEPVInterference(newT,S,G,par,K,Standard_False);
1367       HDS->StoreInterference(newI,SE); 
1368     } // tki
1369   } // i=1..nse
1370 }//completeforSE4
1371
1372 // ----------------------------------------------------------------------
1373 Standard_EXPORT void FUN_ds_completeforSE5(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1374 // ----------------------------------------------------------------------
1375 // xpu190698 : section edge SE has spON face F,
1376 //             FCX is tangent to F at G (FCX and F are on same shape)
1377 //             SE has I  = (T(F),G,S),         T=(OUT,OUT) 
1378 //                    I' = (T'(Fsd),G,Sedge), T' FORWARD or REVERSED
1379 //             T describes states (ON/OUT) or (OUT/ON)
1380 // PRO12695 (SE20,P1,FCX16,F29)
1381 // xpu131098 : SE has I  = (T(F),G,S),         T=(IN,IN)
1382 //                    I' = (T'(Fsd),G,Sedge), T' FORWARD or REVERSED
1383 //             T describes states (ON/IN) or (OUT/IN)
1384 //
1385 //    recall : for the compute of spOU/IN(ES), we need to interferences 
1386 //             TskFACE = (T(FF),G,FF) T=FORWARD/REVERSED
1387 // cto 902 D9 (SE17,P4,F29,FCX4)
1388 {
1389   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1390   Standard_Integer nse = BDS.NbSectionEdges();
1391   for (Standard_Integer i = 1; i <= nse; i++) {
1392     const TopoDS_Edge& SE = BDS.SectionEdge(i);
1393     BDS.Shape(SE);
1394     const TopOpeBRepDS_ListOfInterference& LOI = BDS.ShapeInterferences(SE);    
1395
1396     // xpu020399 : cto901A2 (e26)
1397     TopOpeBRepDS_ListOfInterference LOIc; FDS_copy(LOI,LOIc);
1398     TopOpeBRepDS_ListOfInterference LI; Standard_Integer nI = FUN_selectSKinterference(LOIc,TopOpeBRepDS_EDGE,LI);
1399     if (nI < 1) continue;
1400
1401     TopOpeBRepDS_ListOfInterference newLI; Standard_Boolean hasnewLI = Standard_False;
1402     TopOpeBRepDS_TKI tki;
1403     tki.FillOnGeometry(LI);      
1404     for (tki.Init(); tki.More(); tki.Next()) {     
1405       TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
1406       if (K != TopOpeBRepDS_POINT) {FDS_copy(loi,newLI); continue;}
1407
1408       TopOpeBRepDS_ListOfInterference loicopy; FDS_assign(loi,loicopy);
1409       TopOpeBRepDS_ListOfInterference lext; Standard_Integer iext = FUN_selectTRAORIinterference(loicopy,TopAbs_EXTERNAL,lext);
1410       Standard_Boolean hasext = (iext > 0);
1411       TopOpeBRepDS_ListOfInterference lint; Standard_Integer iint = FUN_selectTRAORIinterference(loicopy,TopAbs_INTERNAL,lint);
1412       Standard_Boolean hasint = (iint > 0);
1413       if (!hasext && !hasint) {FDS_copy(loi,newLI); continue;}
1414       if (hasext && hasint) {FDS_copy(loi,newLI); continue;} // nyiFUN_RAISE : incoherent data
1415                                                              // ------------------------------
1416
1417       // NYI : only select among 2dI!!! ******************************
1418       TopOpeBRepDS_ListOfInterference lfor; Standard_Integer ifor = FUN_selectTRAORIinterference(loicopy,TopAbs_FORWARD,lfor);
1419       TopOpeBRepDS_ListOfInterference lrev; Standard_Integer irev = FUN_selectTRAORIinterference(loicopy,TopAbs_REVERSED,lrev);
1420       Standard_Boolean hasrev=(irev > 0), hasfor=(ifor > 0);
1421       if (!hasrev && !hasfor) {FDS_copy(loi,newLI); continue;}
1422       if (hasrev && hasfor)   {FDS_copy(loi,newLI); continue;} // nyiFUN_RAISE : incoherent data
1423
1424       // newO : 
1425       // -----
1426       Handle(TopOpeBRepDS_Interference) I2d = hasfor ? lfor.First() : lrev.First();
1427       Standard_Integer S2 = I2d->Support(); Standard_Integer iF2 = I2d->Transition().Index();      
1428       const TopoDS_Edge& E2 = TopoDS::Edge(BDS.Shape(S2)); Standard_Real parSE = FDS_Parameter(I2d);
1429       const TopoDS_Face& F2 = TopoDS::Face(BDS.Shape(iF2));
1430       Standard_Real parE2; Standard_Boolean ok = FUN_tool_parE(SE,parSE,E2,parE2); 
1431       if (!ok) return;
1432       gp_Pnt2d uv2; ok = FUN_tool_paronEF(E2,parE2,F2,uv2); 
1433       if (!ok) return;
1434       gp_Dir ngF2 = FUN_tool_nggeomF(uv2,F2);
1435       gp_Dir xxF2; ok = FUN_tool_getxx(F2,E2,parE2,ngF2,xxF2); 
1436       if (!ok) return;
1437         
1438       Handle(TopOpeBRepDS_Interference) I3d = hasext ? lext.First() : lint.First();
1439       Standard_Integer iF3 = I3d->Transition().Index();
1440       const TopoDS_Face& F3 = TopoDS::Face(BDS.Shape(iF3));
1441       // recall : G is a point => E2 = edge(S3) (I3d : {(T,G,S3),(T,G,F3)})
1442       gp_Pnt2d uv3; ok = FUN_tool_paronEF(E2,parE2,F3,uv3); 
1443       if (!ok) return;
1444       gp_Dir ngF3 = FUN_tool_nggeomF(uv3,F3);
1445       gp_Dir xxF3; ok = FUN_tool_getxx(F3,E2,parE2,ngF3,xxF3); 
1446       if (!ok) return;
1447       
1448       Standard_Real dot = xxF2.Dot(xxF3);
1449       Standard_Boolean positive = (dot > 0); // as F and FCX are tangent, dot= +1 or -1
1450       if (positive) continue;
1451
1452       TopAbs_Orientation newO = hasfor ? TopAbs_FORWARD : TopAbs_REVERSED;
1453       if (hasint) newO = TopAbs::Complement(newO);
1454
1455       TopOpeBRepDS_ListIteratorOfListOfInterference it; 
1456       if (hasint) it.Initialize(lint);
1457       else        it.Initialize(lext);
1458       for (; it.More(); it.Next()){
1459         const Handle(TopOpeBRepDS_Interference)& I = it.Value();
1460         Handle(TopOpeBRepDS_Interference) newI = I; newI->ChangeTransition().Set(newO);
1461         newLI.Append(I);
1462         hasnewLI = Standard_True;
1463       } // it
1464       newLI.Append(lrev); 
1465       newLI.Append(lfor);
1466       newLI.Append(loicopy);
1467     } // tki
1468     if (hasnewLI) { 
1469       newLI.Append(LOIc);
1470       TopOpeBRepDS_ListOfInterference& LII = BDS.ChangeShapeInterferences(SE); LII.Clear(); 
1471       LII.Append(newLI);
1472     }
1473   } // i=1..nse
1474 }//completeforSE5
1475
1476 // ----------------------------------------------------------------------
1477 Standard_EXPORT void FUN_ds_completeforSE6(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1478 // ----------------------------------------------------------------------
1479 // xpu280798 : - section edge E sdm3d Esd, 
1480 //             - E has I2d(T(F),VG,E'), 
1481 //             - VG vertex of Esd, VG not sdm
1482 //             - Esd edge of F
1483 //             => add newI1d(newT(Esd),VG,Esd)
1484 //  cto902B4 (e15,v22)
1485 {
1486   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1487   Standard_Integer nse = BDS.NbSectionEdges();
1488   for (Standard_Integer i = 1; i <= nse; i++) {
1489     const TopoDS_Edge& SE = BDS.SectionEdge(i);
1490     Standard_Integer ISE = BDS.Shape(SE);  
1491     TopTools_ListOfShape lEsd3d; Standard_Boolean hassd3d = FDS_HasSameDomain3d(BDS,SE,&lEsd3d);
1492     if (!hassd3d) continue;
1493
1494     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(SE); 
1495     TopOpeBRepDS_ListOfInterference LIcopy; 
1496     TopOpeBRepDS_ListOfInterference LIa; FDS_assign(LI,LIcopy); Standard_Integer na = FUN_selectGKinterference(LIcopy,TopOpeBRepDS_VERTEX,LIa);
1497     if (na == 0) continue;
1498     TopOpeBRepDS_ListOfInterference LIb;
1499     for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LIa); it.More(); it.Next()){
1500       const Handle(TopOpeBRepDS_Interference)& Ia = it.Value();
1501       Standard_Integer G = Ia->Geometry();
1502       TopoDS_Shape vGsd; Standard_Boolean hassd = FUN_ds_getoov(BDS.Shape(G), HDS, vGsd);
1503       if (!hassd) LIb.Append(Ia);
1504     }
1505    
1506     TopOpeBRepDS_ListOfInterference l2dFE; FDS_assign(LIb,LIcopy);
1507     FUN_ds_hasI2d(ISE,LIcopy,l2dFE);
1508     TopOpeBRepDS_ListOfInterference l1dE;  FDS_assign(LIb,LIcopy);
1509     FUN_selectTRASHAinterference(LIcopy,TopAbs_EDGE,l1dE); 
1510
1511     // attached to SE : l1dE  = {I1d=(T(Esd),vG,Esd) / vG !hsd}
1512     //                  l2dFE = {I2dF=(T(F),vG,E) / vG !hsd}
1513     
1514     for (TopTools_ListIteratorOfListOfShape itsd3(lEsd3d); itsd3.More(); itsd3.Next()){
1515       const TopoDS_Edge& Esd = TopoDS::Edge(itsd3.Value());
1516       TopoDS_Vertex vf,vl; TopExp::Vertices(Esd,vf,vl);
1517       Standard_Boolean degen = BRep_Tool::Degenerated(Esd); 
1518       if (degen) continue;
1519
1520       Standard_Boolean closed = vf.IsSame(vl);
1521       Standard_Integer iEsd = BDS.Shape(Esd);
1522       Standard_Integer ivf = BDS.Shape(vf); 
1523       Standard_Integer ivl = BDS.Shape(vl);
1524       
1525       for (Standard_Integer iv = 1; iv <= 2; iv++) {
1526         Standard_Integer G = (iv == 1)? ivf : ivl;
1527         if (G == 0) continue;
1528         const TopoDS_Vertex& vG = TopoDS::Vertex(BDS.Shape(G));
1529         TopoDS_Shape vGsd; Standard_Boolean hassd = FUN_ds_getoov(vG, HDS, vGsd);
1530         if (hassd) continue;
1531
1532         TopOpeBRepDS_ListOfInterference l1dG;
1533         FUN_selectGIinterference(l1dE,G,l1dG);
1534         TopOpeBRepDS_ListOfInterference l2dG; Standard_Integer n2dG = FUN_selectGIinterference(l2dFE,G,l2dG);
1535         if (n2dG == 0) continue; // no 2dI at G
1536         
1537         TopOpeBRepDS_ListOfInterference l1dGEsd; Standard_Integer n1dGEsd = FUN_selectITRASHAinterference(l1dG,iEsd,l1dGEsd);
1538         if (n1dGEsd != 0) continue; // 1dI(Esd) at G exists already
1539
1540         for (TopOpeBRepDS_ListIteratorOfListOfInterference it2d(l2dG); it2d.More(); it2d.Next()){ 
1541           const Handle(TopOpeBRepDS_Interference)& I2d = it2d.Value();
1542           Standard_Integer iTRASHA = I2d->Transition().IndexBefore();
1543           TopAbs_Orientation O = I2d->Transition().Orientation(TopAbs_IN);
1544           const TopoDS_Face& F = TopoDS::Face(BDS.Shape(iTRASHA));
1545           TopAbs_Orientation dum; Standard_Boolean EsdofF = FUN_tool_orientEinF(Esd,F,dum);
1546           if (!EsdofF) continue;
1547           
1548           // we found I2d = (T(F),vG,E'), vG is vertex of Esd, vG !hsdm, Esd is edge of F
1549           // compute newI1d=(newT(Esd),vG,Esd)
1550           TopOpeBRepDS_Transition newT(TopAbs_OUT,TopAbs_OUT, TopAbs_EDGE,TopAbs_EDGE);
1551           Standard_Real parE = FDS_Parameter(I2d);
1552           if (closed) newT.Set(TopAbs_INTERNAL);
1553           else {
1554             if      (M_FORWARD(O) || M_REVERSED(O)) {newT.Set(O);}
1555             else if (M_EXTERNAL(O))                 {newT.Set(O);}
1556             else if (M_INTERNAL(O))                 {
1557               Standard_Real parEsd   = BRep_Tool::Parameter(vG,Esd);
1558               gp_Vec tgEsd; TopOpeBRepTool_TOOL::TggeomE(parEsd,Esd,tgEsd); // dir
1559               gp_Vec tgE  ; TopOpeBRepTool_TOOL::TggeomE(parE,SE,tgE);      // dir
1560               Standard_Real dot = tgEsd.Dot(tgE);
1561               Standard_Boolean SO = (dot > 0.);
1562               Standard_Boolean isvf = (iv == 1);
1563               Standard_Boolean isforw = (SO && isvf) || (!SO && !isvf);
1564               if (isforw) {newT.Set(TopAbs_FORWARD);}
1565               else        {newT.Set(TopAbs_REVERSED);}
1566             }
1567           }
1568           newT.Index(iEsd);
1569           Handle(TopOpeBRepDS_Interference) newI1d = MakeEPVInterference(newT,iEsd,G,parE,TopOpeBRepDS_VERTEX,Standard_False);
1570           HDS->StoreInterference(newI1d,SE);
1571         } // it2d(l2dFE)
1572
1573       }
1574     } //itsd3
1575
1576   } //i=1..nse
1577 }// completeforSE6
1578
1579 // ----------------------------------------------------------------------
1580 Standard_EXPORT void FUN_ds_completeforE7(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1581 // ----------------------------------------------------------------------
1582 // xpu130898 : attached to edge E, lI3d = {I=(FOR/REV(F),G,F)}
1583 //             reduction of lI3d if it describes INTERNAL/EXTERNAL transitions
1584 // purpose : I3dFOR/REV => faulty spIN/OU of E on G                  
1585 // CTS21199 (E6, G=v7/p3, FTR=f5)
1586 {
1587   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1588   Standard_Integer ns = BDS.NbShapes();
1589   for (Standard_Integer i = 1; i <= ns; i++) {
1590     const TopoDS_Shape& EE = BDS.Shape(i);
1591     if (EE.ShapeType() != TopAbs_EDGE) continue;
1592  
1593     const TopoDS_Edge& E = TopoDS::Edge(EE);
1594     Standard_Boolean isdgE = BRep_Tool::Degenerated(E); 
1595     if (isdgE) continue;
1596     BDS.Shape(E);
1597     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(E); 
1598
1599     TopOpeBRepDS_TKI tki;
1600     tki.FillOnGeometry(LI);  
1601     for (tki.Init(); tki.More(); tki.Next()) {     
1602       TopOpeBRepDS_Kind K; Standard_Integer G; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);      
1603       TopOpeBRepDS_ListOfInterference loicopy; FDS_assign(loi,loicopy);
1604       TopOpeBRepDS_ListOfInterference l1;
1605       FUN_selectSKinterference(loicopy,TopOpeBRepDS_FACE,l1);
1606       TopOpeBRepDS_ListOfInterference lFOR; Standard_Integer nFOR = FUN_selectTRAORIinterference(l1,TopAbs_FORWARD,lFOR);
1607       TopOpeBRepDS_ListOfInterference lREV; Standard_Integer nREV = FUN_selectTRAORIinterference(l1,TopAbs_REVERSED,lREV);
1608       if ((nFOR == 0) || (nREV == 0)) continue;
1609
1610       TopOpeBRepDS_ListOfInterference lnewI; Standard_Integer iFS=0;
1611       TopOpeBRepDS_ListIteratorOfListOfInterference it(lFOR);
1612       for (; it.More(); it.Next()){
1613         const Handle(TopOpeBRepDS_Interference)& IFOR = it.Value();
1614         Standard_Integer IFS = IFOR->Support(); const TopoDS_Face& FS = TopoDS::Face(BDS.Shape(IFS));
1615         TopOpeBRepDS_ListOfInterference lFS; Standard_Integer nFS = FUN_selectSIinterference(loicopy,IFS,lREV);
1616         if (nFS == 0) continue;
1617         
1618         TopOpeBRepDS_ListOfInterference lFSE; Standard_Integer nFSE = FUN_selectITRASHAinterference(loicopy,IFS,lFSE);
1619         Standard_Real par = FDS_Parameter(IFOR);
1620         Standard_Boolean isonper = false; Standard_Real par1 = 0.0, par2 = 0.0; Standard_Real factor = 1.e-4;
1621         FDS_LOIinfsup(BDS,E,par,K,G,BDS.ShapeInterferences(E),par1,par2,isonper);
1622
1623         TopOpeBRepDS_Transition newT;
1624         // -------
1625         // we have IFOR=(FORWARD(FS),G,FS) + IREV=(REVERSED(FS),G,FS)
1626         Standard_Integer IES = 0;       
1627         if (nFSE == 0) {
1628           gp_Pnt2d uvFS; Standard_Boolean ok = FUN_tool_parF(E,par,FS,uvFS);
1629           if (!ok) {continue;}
1630           
1631           TopOpeBRepTool_makeTransition MKT; TopAbs_State stb = TopAbs_UNKNOWN,sta = TopAbs_UNKNOWN; 
1632           ok = MKT.Initialize(E,par1,par2,par, FS,uvFS, factor);
1633           if (ok) ok = MKT.MkTonE(stb,sta);
1634           if (!ok) {continue;}
1635           newT.Before(stb); newT.After(sta);   
1636         }
1637         else  {
1638           IES = lFSE.First()->Support();
1639           const TopoDS_Edge& ES = TopoDS::Edge(BDS.Shape(IES));   
1640           Standard_Real parES; Standard_Boolean ok = FUN_tool_parE(E,par,ES,parES);
1641           if (!ok) {continue;}
1642           gp_Pnt2d uvFS; ok = FUN_tool_paronEF(ES,parES,FS,uvFS);
1643           if (!ok) {continue;}
1644
1645           TopOpeBRepTool_makeTransition MKT; TopAbs_State stb = TopAbs_UNKNOWN,sta = TopAbs_UNKNOWN; 
1646           ok = MKT.Initialize(E,par1,par2,par, FS,uvFS, factor);
1647           if (ok) ok = MKT.SetRest(ES,parES);
1648           if (ok) ok = MKT.MkTonE(stb,sta);
1649           if (!ok) {continue;}
1650           newT.Before(stb); newT.After(sta);   
1651         }
1652
1653         // newI :
1654         //------
1655         iFS = IFS;
1656         newT.Index(IFS);
1657         Standard_Boolean B = Standard_False;
1658         if (K == TopOpeBRepDS_VERTEX) B = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(IFOR)->GBound();        
1659         Handle(TopOpeBRepDS_Interference) newI = MakeEPVInterference(newT,IFS,G,par,K,TopOpeBRepDS_FACE,B);
1660         lnewI.Append(newI);
1661         if (nFSE != 0) {
1662           Handle(TopOpeBRepDS_Interference) newIFE = MakeEPVInterference(newT,IES,G,par,K,TopOpeBRepDS_EDGE,B);
1663           lnewI.Append(newIFE);
1664         }
1665       } // it(lFOR)
1666
1667       if (iFS != 0) {
1668         TopOpeBRepDS_ListOfInterference& loii = tki.ChangeValue(K,G);
1669         TopOpeBRepDS_ListOfInterference lEFS;
1670         FUN_selectITRASHAinterference(loii,iFS,lEFS);
1671         for (TopOpeBRepDS_ListIteratorOfListOfInterference iti(lnewI); iti.More(); iti.Next()) {
1672           Handle(TopOpeBRepDS_Interference) newI = iti.Value();
1673           loii.Append(newI);
1674         } 
1675       }
1676     } // tki     
1677
1678     TopOpeBRepDS_ListOfInterference& LII = BDS.ChangeShapeInterferences(E); 
1679     LII.Clear(); 
1680     for (tki.Init(); tki.More(); tki.Next()) {   
1681       TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
1682       FDS_copy(loi,LII);
1683     }    
1684   } //i = 1..ns
1685 } //completeforE7
1686
1687 // ----------------------------------------------------------------------
1688 Standard_EXPORT void FUN_ds_completeforSE8(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1689 // ----------------------------------------------------------------------
1690 // xpu020998 : Attached to section edge SE :
1691 //  - {I1d=(Tr(Esd),vG,Esd), I2d=(Tr(F),vG,E)}
1692 //  - E and Esd are F edges
1693 //   I2d may be incomplete, "reduce" 2d/1d -> {I1d,newI2d}
1694 // cto902A6 (ES5,Esd10,vG7,F35)
1695 // prequesitory : A vertex is shared by at most 2 edges in the same face.
1696 //                An edge is shared by at most 2 faces of same rank.
1697 {
1698   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1699   Standard_Integer nse = BDS.NbSectionEdges();
1700
1701   for (Standard_Integer i = 1; i <= nse; i++) {
1702     const TopoDS_Edge& SE = BDS.SectionEdge(i);
1703     Standard_Integer ISE = BDS.Shape(SE);
1704     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(SE);    
1705
1706     Standard_Boolean hasnew = Standard_False;
1707     TopOpeBRepDS_TKI tki;
1708     tki.FillOnGeometry(LI);  
1709     for (tki.Init(); tki.More(); tki.Next()) {     
1710       TopOpeBRepDS_Kind KK; Standard_Integer GG; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(KK,GG);      
1711       Standard_Boolean isvertex = (KK == TopOpeBRepDS_VERTEX);
1712
1713       if (isvertex) {
1714         Standard_Boolean Ghsdm = HDS->HasSameDomain(BDS.Shape(GG));
1715         if (Ghsdm) continue;
1716       }
1717       // li -> l1dE + l2dFE + lFE(<=>l3dFE) + li(<=>lFF)
1718       TopOpeBRepDS_ListOfInterference li; FDS_assign(loi,li);
1719       TopOpeBRepDS_ListOfInterference l1dE;  Standard_Integer n1d = FUN_selectTRASHAinterference(li,TopAbs_EDGE,l1dE);  // li->l1dE+li(<=>lF?)
1720       TopOpeBRepDS_ListOfInterference lFE;
1721       FUN_selectSKinterference(li,TopOpeBRepDS_EDGE,lFE); // li(<=>lF?)->lFE+li(<=>lFF)
1722       TopOpeBRepDS_ListOfInterference l2dFE; Standard_Integer n2d = FUN_selectpure2dI(li,lFE,l2dFE);                    // lFE->l2dFE+lFE(<=>l3dFE)
1723       Standard_Boolean redu2d = (n1d > 0)&&(n2d > 0);
1724       // -------------------------------
1725       if (redu2d) { // {I1d=(Tr(Esd),vG,Esd), I2d=(Tr(F),vG,E)} 
1726         TopOpeBRepDS_ListIteratorOfListOfInterference it(l2dFE); TopOpeBRepDS_ListOfInterference al2dFE;
1727         while (it.More()) {
1728           Handle(TopOpeBRepDS_Interference)& I2dFE = it.Value();
1729           TopOpeBRepDS_Transition newT2d; Standard_Boolean ok = FUN_ds_redu2d1d(BDS,ISE,I2dFE,l1dE, newT2d);
1730           if (!ok) {it.Next(); continue;}
1731           I2dFE->ChangeTransition() = newT2d; al2dFE.Append(I2dFE);
1732           l2dFE.Remove(it); 
1733         }
1734         l2dFE.Append(al2dFE);
1735       } // redu2d
1736
1737       TopOpeBRepDS_ListOfInterference& loii = tki.ChangeValue(KK,GG);     
1738       loii.Clear();
1739       loii.Append(l1dE); loii.Append(lFE); loii.Append(l2dFE); loii.Append(li); 
1740     }// tki
1741
1742     if (!hasnew) continue;
1743     TopOpeBRepDS_ListOfInterference& LII = BDS.ChangeShapeInterferences(SE); 
1744     LII.Clear();
1745     for (tki.Init(); tki.More(); tki.Next()) {  
1746       TopOpeBRepDS_Kind KK = TopOpeBRepDS_UNKNOWN; Standard_Integer GG = 0; TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(KK,GG);
1747       LII.Append(loi);
1748     }
1749   }// i=1..nse
1750 }// completeforSE8
1751
1752 // ----------------------------------------------------------------------
1753 Standard_EXPORT void FUN_ds_completeforSE9(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1754 // ----------------------------------------------------------------------
1755 // xpu011098 : CTS21180(ES13)
1756 // purpose : ES Section edge, sdm with EsdSE={Esd}, ES has no interference
1757 //   compute interferences for ES.
1758 {
1759   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1760   Standard_Integer nse = BDS.NbSectionEdges();  
1761
1762   for (Standard_Integer i = 1; i <= nse; i++) {
1763     const TopoDS_Edge& SE = BDS.SectionEdge(i);
1764     Standard_Integer rkSE = BDS.AncestorRank(SE);
1765     Standard_Integer ISE = BDS.Shape(SE);   
1766     Standard_Boolean hsd = HDS->HasSameDomain(SE);
1767     if (!hsd) continue;
1768     if (!BDS.ShapeInterferences(SE).IsEmpty()) continue;
1769
1770     const TopTools_ListOfShape& EsdSE = BDS.ShapeSameDomain(SE);
1771     TopTools_ListIteratorOfListOfShape ite(EsdSE);
1772     for (; ite.More(); ite.Next()){
1773       const TopoDS_Edge& Esd = TopoDS::Edge(ite.Value()); Standard_Integer iEsd = BDS.Shape(Esd);
1774       Standard_Integer rkEsd = BDS.AncestorRank(Esd);
1775       if (rkEsd == rkSE) continue;
1776       const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(Esd); 
1777       if (LI.IsEmpty()) continue;
1778      
1779       TopOpeBRepDS_ListOfInterference LIcopy; FDS_assign(LI,LIcopy);
1780       TopOpeBRepDS_ListOfInterference LISE;
1781       FUN_selectSIinterference(LIcopy,ISE,LISE);
1782       
1783       TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LISE);  
1784       for (tki.Init(); tki.More(); tki.Next()) {     
1785         TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN;
1786         Standard_Integer G = 0;
1787 //        const TopOpeBRepDS_ListOfInterference& loi = 
1788         tki.Value(K,G); 
1789         const TopoDS_Vertex& vG = TopoDS::Vertex(BDS.Shape(G));
1790         Standard_Boolean hsd1 = HDS->HasSameDomain(vG);
1791         if (hsd1) continue; //nyixpu011098
1792         Standard_Integer rkG = BDS.AncestorRank(G);
1793         if (rkG != rkSE) continue; //nyixpu011098
1794
1795         // newI : 
1796         // -----
1797         TopOpeBRepDS_Transition newT(TopAbs_IN,TopAbs_IN,TopAbs_EDGE,TopAbs_EDGE); newT.Index(iEsd);
1798         // modified by NIZHNY-MKK  Mon Apr  2 15:39:14 2001.BEGIN
1799         Standard_Integer hasvG = FUN_tool_orientVinE(vG,SE);
1800         if(hasvG==0) {
1801           continue;
1802         }
1803         // modified by NIZHNY-MKK  Mon Apr  2 15:39:17 2001.END
1804
1805         Standard_Real par = BRep_Tool::Parameter(vG,SE);
1806         Handle(TopOpeBRepDS_Interference) newI = MakeEPVInterference(newT,iEsd,G,par,TopOpeBRepDS_VERTEX,TopOpeBRepDS_EDGE,Standard_True);
1807         HDS->StoreInterference(newI,SE); 
1808       } 
1809     }//ite(EsdSE)
1810   }//i=1..nse
1811 } //completeforSE9 
1812
1813 // ----------------------------------------------------------------------
1814 Standard_EXPORT void FUN_ds_PointToVertex(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1815 // ----------------------------------------------------------------------
1816 // xpu090698 : for gap reasons, intersector IntPatch can find a intersection
1817 // point POINT, whereas it should be a VERTEX,
1818 // if we find edge eb / eb : EPI(T1,G,ea1),
1819 //                           EPI(T2,G,a2) with rk(ea1) = rk(ea2), 
1820 // then G should be VERTEX (2 edges of same shape cannot 
1821 // intersect) - recall : in the DS, we do not bind twice the same closing edge-
1822 // CTS20339
1823 {  
1824   Standard_Integer i ;
1825   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1826   Standard_Integer ns = BDS.NbShapes();
1827   TColStd_DataMapOfIntegerInteger iPiV;
1828
1829   for ( i = 1; i <= ns; i++) {
1830     const TopoDS_Shape& s = BDS.Shape(i);
1831     if (s.ShapeType() != TopAbs_EDGE) continue;
1832     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(s);
1833     if (LI.IsEmpty()) continue;
1834
1835     TopOpeBRepDS_TKI tki;
1836     tki.FillOnGeometry(LI);      
1837     for (tki.Init(); tki.More(); tki.Next()) {     
1838       TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
1839       if (K == TopOpeBRepDS_VERTEX) continue;
1840       
1841       Standard_Integer Scur = 0; Standard_Boolean Gfaulty = Standard_False;
1842       for (TopOpeBRepDS_ListIteratorOfListOfInterference it(loi); it.More(); it.Next()){
1843         const Handle(TopOpeBRepDS_Interference)& I = it.Value();
1844         TopOpeBRepDS_Kind GT = TopOpeBRepDS_UNKNOWN, ST = TopOpeBRepDS_UNKNOWN;
1845         Standard_Integer G1 = 0, S = 0;
1846         FDS_data(I,GT,G1,ST,S);
1847         if (ST != TopOpeBRepDS_EDGE) continue;
1848         if (Scur == 0) {
1849           Scur = S;
1850         }
1851         if (S != Scur) {
1852           Gfaulty = Standard_True; break;
1853         }
1854       } // it     
1855       if (Gfaulty) {
1856         // in DS : pG --> vG
1857         gp_Pnt pG = BDS.Point(G).Point();
1858         Standard_Integer rkES = BDS.AncestorRank(Scur);
1859         const TopoDS_Edge& ES = TopoDS::Edge(BDS.Shape(Scur));
1860         TopoDS_Vertex vf,vl; TopExp::Vertices(ES,vf,vl);
1861         gp_Pnt pf = BRep_Tool::Pnt(vf); gp_Pnt pl = BRep_Tool::Pnt(vl);
1862         Standard_Real df = pf.Distance(pG); Standard_Real dl = pl.Distance(pG);
1863         TopoDS_Vertex vG; 
1864         if (df < dl) vG = vf;
1865         else         vG = vl;
1866         
1867         Standard_Integer ivG = BDS.AddShape(vG,rkES);
1868         iPiV.Bind(G,ivG);
1869       } // Gfaulty    
1870     } // tki 
1871   } // i
1872
1873   if (iPiV.IsEmpty()) return;
1874   for (i = 1; i <= ns; i++) {
1875     const TopoDS_Shape& s = BDS.Shape(i);
1876     if (s.ShapeType() != TopAbs_EDGE) continue;
1877     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(s);
1878     if (LI.IsEmpty()) continue;
1879
1880     TopOpeBRepDS_ListOfInterference newLI;
1881     Standard_Integer rks = BDS.AncestorRank(s);
1882     TopOpeBRepDS_TKI tki;
1883     tki.FillOnGeometry(LI);   
1884     for (tki.Init(); tki.More(); tki.Next()) {     
1885       TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN;
1886       Standard_Integer G = 0;
1887       const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);  
1888       Standard_Boolean Gisbound = iPiV.IsBound(G);
1889       if (!Gisbound) {
1890         FDS_copy(loi,newLI);
1891         continue;
1892       }
1893
1894       Standard_Integer ivG = iPiV.Find(G);
1895       const TopoDS_Vertex& vG = TopoDS::Vertex(BDS.Shape(ivG));
1896       Standard_Integer rkG = BDS.AncestorRank(ivG);      
1897       Standard_Boolean Gbound = (rkG == rks);      
1898   
1899       for (TopOpeBRepDS_ListIteratorOfListOfInterference itl(loi); itl.More(); itl.Next()){
1900         const Handle(TopOpeBRepDS_Interference)& I = itl.Value();
1901         Handle(TopOpeBRepDS_CurvePointInterference) CPI (Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I));
1902         if (CPI.IsNull()) continue;
1903
1904         Standard_Real par = CPI->Parameter(); 
1905         TopOpeBRepDS_Kind GT = TopOpeBRepDS_UNKNOWN, ST = TopOpeBRepDS_UNKNOWN;
1906         Standard_Integer G1 = 0, S = 0;
1907         FDS_data(I,GT,G1,ST,S);
1908         const TopOpeBRepDS_Transition& T = I->Transition();
1909         Standard_Real parvG = 0.0; Standard_Boolean ok = FUN_tool_parVonE(vG,TopoDS::Edge(s),parvG);
1910         // modified by NIZHNY-MKK  Mon Apr  2 15:39:59 2001.BEGIN
1911         //      if (!ok) par = parvG;
1912         if (!ok) 
1913           continue;
1914         par = parvG;
1915         // modified by NIZHNY-MKK  Mon Apr  2 15:40:04 2001.END
1916         Handle(TopOpeBRepDS_Interference) newI = MakeEPVInterference(T,S,ivG,par,TopOpeBRepDS_VERTEX,ST,Gbound);
1917         newLI.Append(newI);
1918       }     
1919     } // tki
1920     TopOpeBRepDS_ListOfInterference& LII = BDS.ChangeShapeInterferences(s);
1921     LII.Clear(); LII.Append(newLI);
1922   } // i
1923
1924   TColStd_DataMapIteratorOfDataMapOfIntegerInteger itm(iPiV);
1925   for (; itm.More(); itm.Next()){
1926     Standard_Integer G = itm.Key();
1927     BDS.RemovePoint(G);
1928   }  
1929 }//PointToVertex
1930
1931 static Standard_Boolean FUN_redusamshaonE(const TopOpeBRepDS_DataStructure& BDS,const Handle(TopOpeBRepDS_Interference)& I,const Standard_Integer EIX, Handle(TopOpeBRepDS_Interference)& newI)
1932 // attached to edge(EIX) : IFOR=(FORWARD(ES),G,ES) + IREV=(REVERSED(ES),G,ES)
1933 {
1934   newI.Nullify();
1935   TopAbs_ShapeEnum SB = TopAbs_SHAPE, SA = TopAbs_SHAPE;Standard_Integer IB = 0, IA = 0; TopOpeBRepDS_Kind GT = TopOpeBRepDS_UNKNOWN, ST = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0, S = 0;
1936   FDS_Idata(I,SB,IB,SA,IA,GT,G,ST,S); 
1937   const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(EIX));
1938   Standard_Real parE = FDS_Parameter(I); Standard_Real f,l; FUN_tool_bounds(E,f,l);
1939   const TopoDS_Edge& ES = TopoDS::Edge(BDS.Shape(S));
1940   const TopoDS_Face& FTRA = TopoDS::Face(BDS.Shape(IB));
1941   Standard_Real parES = 0.0; Standard_Boolean ok = FUN_tool_parE(E,parE,ES,parES);
1942   if (!ok) return Standard_False;
1943   gp_Pnt2d uv; ok = FUN_tool_paronEF(ES,parES,FTRA,uv);
1944   if (!ok) return Standard_False;
1945
1946   Standard_Real factor = 1.e-2; TopAbs_State stb = TopAbs_UNKNOWN,sta = TopAbs_UNKNOWN; 
1947   TopOpeBRepTool_makeTransition MKT; 
1948   ok = MKT.Initialize(E,f,l,parE, FTRA,uv, factor);
1949   if (ok) ok = MKT.SetRest(ES,parES);
1950   if (ok) ok = MKT.MkTonE(stb,sta); 
1951   if (!ok) return Standard_False;
1952   TopOpeBRepDS_Transition newT; newT.Index(IB); newT.Before(stb);newT.After(sta);   
1953
1954   ok = FDS_stateEwithF2d(BDS,E,parE,GT,G,FTRA,newT);
1955   if (!ok) return Standard_False;
1956
1957   Standard_Boolean B = Standard_False; if (GT == TopOpeBRepDS_VERTEX) B = Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I)->GBound();
1958   newI = MakeEPVInterference(newT,S,G,parE,GT,TopOpeBRepDS_EDGE,B);
1959   return Standard_True;
1960 }//FUN_redusamshaonE
1961
1962 // ----------------------------------------------------------------------
1963 Standard_EXPORT void FUN_ds_redusamsha(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
1964 // ----------------------------------------------------------------------
1965 // xpu201098 : reduce 2d interferences on same G and same S :
1966 //   {I1=(OU/IN(F),G,ES), I2=(IN/OU(F),G,ES)}
1967 // cto009K1 (SE7,ES8,G2,FTRA27)
1968 //xpu050299 (FRA60618 e13,ftrasha14)
1969 {  
1970   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
1971   Standard_Integer ns = BDS.NbShapes(); 
1972
1973   for (Standard_Integer i = 1; i <= ns; i++) {
1974     if (BDS.Shape(i).ShapeType() != TopAbs_EDGE) continue;
1975
1976     const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(i));
1977     Standard_Integer IE = BDS.Shape(E);   
1978     TopOpeBRepDS_TKI tki;
1979     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(i);
1980     tki.FillOnGeometry(LI);      
1981     for (tki.Init(); tki.More(); tki.Next()) {     
1982       TopOpeBRepDS_Kind K = TopOpeBRepDS_UNKNOWN; Standard_Integer G = 0; const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
1983       TopOpeBRepDS_ListOfInterference loicopy; FDS_copy(loi,loicopy); // loi -> l1+l2
1984       TopOpeBRepDS_ListOfInterference l0;
1985       FUN_selectTRASHAinterference(loicopy,TopAbs_EDGE,l0);//xpu091198(cylcong)
1986       TopOpeBRepDS_ListOfInterference l1; Standard_Integer nfound = FUN_selectTRASHAinterference(loicopy,TopAbs_FACE,l1);
1987       TopOpeBRepDS_ListOfInterference l2; nfound = FUN_selectSKinterference(l1,TopOpeBRepDS_EDGE,l2);
1988       // l2 = {I=(T(faceTRASHA),G,Sedge)}
1989       if (nfound == 0) continue;
1990
1991       //***    
1992       TopOpeBRepDS_TKI tkis; tkis.FillOnSupport(l2);    
1993       for (tkis.Init(); tkis.More(); tkis.Next()) {  
1994         TopOpeBRepDS_Kind k = TopOpeBRepDS_UNKNOWN; Standard_Integer s = 0; TopOpeBRepDS_ListOfInterference& li = tkis.ChangeValue(k,s);
1995         Standard_Integer nli = li.Extent();
1996         if (nli < 2) continue; 
1997
1998         Handle(TopOpeBRepDS_Interference) newI;
1999         TopOpeBRepDS_ListIteratorOfListOfInterference it1(li);
2000         while (it1.More()) {
2001           const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
2002           const TopOpeBRepDS_Transition& T1 = I1->Transition();
2003           TopAbs_Orientation O1 = T1.Orientation(TopAbs_IN);
2004           if (!M_FORWARD(O1) && !M_REVERSED(O1)) {it1.Next(); continue;}
2005           TopAbs_ShapeEnum SB1 = TopAbs_SHAPE, SA1 = TopAbs_SHAPE; Standard_Integer IB1 = 0, IA1 = 0; TopOpeBRepDS_Kind GT1 = TopOpeBRepDS_UNKNOWN, ST1 = TopOpeBRepDS_UNKNOWN; Standard_Integer G1 = 0, S1 = 0;
2006           FDS_Idata(I1,SB1,IB1,SA1,IA1,GT1,G1,ST1,S1);
2007           if (IB1 != IA1) {it1.Next(); continue;}
2008           
2009           Standard_Boolean oppofound = Standard_False;
2010           TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1); it2.Next();
2011           while (it2.More()) {
2012             const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
2013             const TopOpeBRepDS_Transition& T2 = I2->Transition();
2014             TopAbs_Orientation O2 = T2.Orientation(TopAbs_IN);
2015             TopAbs_ShapeEnum SB2 = TopAbs_SHAPE, SA2 = TopAbs_SHAPE; Standard_Integer IB2 = 0, IA2 = 0; TopOpeBRepDS_Kind GT2 = TopOpeBRepDS_UNKNOWN, ST2 = TopOpeBRepDS_UNKNOWN; Standard_Integer G2 = 0, S2 = 0;
2016             FDS_Idata(I2,SB2,IB2,SA2,IA2,GT2,G2,ST2,S2);
2017             if (IB2 != IA2) {it2.Next(); continue;}
2018             if (IB1 != IB2) {it2.Next(); continue;} // same fTRASHA
2019             if (S1 != S2)   {it2.Next(); continue;} // same Sedge
2020             
2021             if (O1 == TopAbs::Complement(O2)) {oppofound=Standard_True; break;}
2022             else {it2.Next(); continue;}
2023           } // it2(it1)
2024
2025           if (!oppofound) {it1.Next(); continue;}
2026           Standard_Boolean ok = FUN_redusamshaonE(BDS,I1,IE,newI);
2027           if (!ok) {it1.Next(); continue;}
2028           else break;
2029         } //it1(li)
2030         if (newI.IsNull()) continue;
2031         li.Clear(); li.Append(newI);
2032       }//tkis(l2)      
2033       //***
2034       
2035       TopOpeBRepDS_ListOfInterference& newloi = tki.ChangeValue(K,G); newloi.Clear();
2036       for (tkis.Init(); tkis.More(); tkis.Next()) {  
2037         TopOpeBRepDS_Kind k = TopOpeBRepDS_UNKNOWN; Standard_Integer g = 0; TopOpeBRepDS_ListOfInterference& li = tkis.ChangeValue(k,g);
2038         newloi.Append(li);
2039       }  
2040       newloi.Append(l0); newloi.Append(l1);
2041     }// tki(LI)
2042
2043     TopOpeBRepDS_ListOfInterference& newLI = BDS.ChangeShapeInterferences(E);
2044     newLI.Clear();
2045     for (tki.Init(); tki.More(); tki.Next()) {  
2046       TopOpeBRepDS_Kind KK = TopOpeBRepDS_UNKNOWN; Standard_Integer GG = 0; TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(KK,GG);
2047       newLI.Append(loi);
2048     }
2049   }// i=1..nse  
2050 } //FUN_ds_redusamsha
2051
2052 Standard_EXPORT Standard_Boolean FUN_ds_hasFEI(const TopOpeBRepDS_PDataStructure& pDS2d, const TopoDS_Shape& F, const Standard_Integer GI, const Standard_Integer ITRA)
2053 {
2054   Standard_Boolean hasF = pDS2d->HasShape(F);
2055   if (!hasF) return Standard_False;
2056
2057   const TopOpeBRepDS_ListOfInterference& LI = pDS2d->ShapeInterferences(F);
2058   for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()){
2059     const Handle(TopOpeBRepDS_Interference)& I = it.Value();
2060     const TopOpeBRepDS_Transition& T = I->Transition();
2061     TopOpeBRepDS_Kind GT,ST; Standard_Integer G,S; FDS_data(I,GT,G,ST,S);
2062     Standard_Boolean found = (G == GI) && (T.Index() == ITRA);
2063     if (found) return Standard_True;
2064   }
2065   return Standard_False;
2066 } //FUN_ds_hasFEI
2067
2068 Standard_EXPORT Standard_Boolean FUN_ds_ONesd(const TopOpeBRepDS_DataStructure& BDS, const Standard_Integer IE, const TopoDS_Shape& EspON, Standard_Integer& IEsd)
2069 {
2070   const TopoDS_Shape& E = BDS.Shape(IE);
2071   TopTools_ListIteratorOfListOfShape it(BDS.ShapeSameDomain(E));
2072   Standard_Real f = 0.0, l = 0.0; FUN_tool_bounds(TopoDS::Edge(EspON),f,l);
2073   Standard_Real x = 0.456789; Standard_Real par = (1-x)*f + x*l;
2074   gp_Pnt p3d; Standard_Boolean ok = FUN_tool_value(par,TopoDS::Edge(EspON),p3d);
2075   if (!ok) return Standard_False;
2076
2077   for (; it.More(); it.Next()) {
2078     const TopoDS_Edge& esd = TopoDS::Edge(it.Value());
2079     Standard_Real d=0., parp; ok = FUN_tool_projPonE(p3d,esd,parp,d);
2080     if (!ok) continue;
2081     Standard_Real tolesd = BRep_Tool::Tolerance(esd);
2082     ok = (d < tolesd*1.e3); //nyi checktole
2083     if (!ok) continue;
2084     IEsd = BDS.Shape(esd);
2085     return Standard_True;
2086   }
2087   return Standard_False;
2088 } //FUN_ds_ONesd
2089
2090 /*#define FIRST (1)
2091 #define LAST  (2)
2092 static Standard_Boolean FUN_oriTOsta(const Standard_Integer o, const TopAbs_State sta, TopAbs_Orientation& ori)
2093 {
2094   Standard_Boolean ok = (sta == TopAbs_OUT) || (sta == TopAbs_IN);
2095   if (!ok) return Standard_False;
2096   ok = (o == FIRST) || (o == LAST);
2097   if (!ok) return Standard_False;
2098
2099   ori = TopAbs_EXTERNAL;
2100   if (o == FIRST) ori = TopAbs_FORWARD;
2101   if (o == LAST)  ori = TopAbs_REVERSED;
2102   if (sta == TopAbs_OUT) ori = TopAbs::Complement(ori);
2103   return Standard_True;
2104 } //FUN_oriTOsta
2105
2106 Standard_EXPORT void FUN_ds_unkeepEVIonGb1(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopAbs_State sta)
2107 // xpu290698 :
2108 // Completing filter process for edges : delete of interferences
2109 // EVI on gbound1, we keep only interferences on Gb1 describing transitions 
2110 // on e / e is IN the solid (if sta = IN)
2111 //        e is OU the solid (if sta = OU)
2112 {
2113   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
2114   Standard_Integer ns = BDS.NbShapes();
2115   for (Standard_Integer i = 1; i <= ns; i++) {   
2116     const TopoDS_Shape& s = BDS.Shape(i);
2117     if (s.ShapeType() != TopAbs_EDGE) continue;
2118
2119     const TopoDS_Edge& E = TopoDS::Edge(s);
2120     TopOpeBRepDS_ListOfInterference& LI = BDS.ChangeShapeInterferences(s);
2121     if (LI.IsEmpty()) continue;
2122
2123     Standard_Boolean dgE = BRep_Tool::Degenerated(E);
2124     if (dgE) continue;
2125     TopoDS_Vertex dum; Standard_Boolean closed = FUN_tool_ClosedE(E,dum);
2126     if (closed) continue;
2127     
2128     TopOpeBRepDS_Kind K; Standard_Integer G; Standard_Boolean ok = Standard_False;
2129     TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LI);
2130
2131     for (tki.Init(); tki.More(); tki.Next()) {
2132       tki.Value(K,G);
2133       if (K != TopOpeBRepDS_VERTEX) break;
2134       ok = Standard_True;
2135     } // tki   
2136     if (!ok) continue;
2137
2138     TopOpeBRepDS_ListOfInterference newLI;
2139     for (tki.Init(); tki.More(); tki.Next()) {
2140       tki.Value(K,G);
2141       const TopOpeBRepDS_ListOfInterference& loi = tki.Value(K,G);
2142
2143       const TopoDS_Vertex& V = TopoDS::Vertex(BDS.Shape(G));
2144       Standard_Integer o = FUN_tool_orientVinE(V,E);
2145       if (o == 0) {FDS_copy(loi,newLI); continue;}
2146       TopAbs_Orientation ori; Standard_Boolean okk = FUN_oriTOsta(o,sta,ori);
2147       if (!okk)   {FDS_copy(loi,newLI); continue;}
2148
2149       // attached to E at G : loi = {I} / I is EVIonGb1      
2150       TopOpeBRepDS_ListOfInterference newloi;
2151       for (TopOpeBRepDS_ListIteratorOfListOfInterference it(loi); it.More(); it.Next()) {
2152         const Handle(TopOpeBRepDS_Interference)& I = it.Value();
2153         const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN);
2154         if (O == ori) { 
2155           newloi.Append(I);
2156           continue;
2157         }   
2158       }      
2159       Standard_Integer nnewI = newloi.Extent();
2160       Standard_Integer nI = loi.Extent();
2161       Standard_Boolean ko = (nnewI > 1) && (nnewI != nI); // complex transitions at G
2162                                              // NYI : correcting reducing cto 001 W3 (e35)
2163       if (!ko) newLI.Append(newloi);    
2164 //      newLI.Append(newloi); //xpu280898 : cto905J1 (e25,v8)
2165     } // tki
2166     LI.Clear(); LI.Append(newLI);
2167
2168   } // i=1..ns
2169 } //FUN_ds_unkeepEVIonGb1*/
2170
2171 Standard_EXPORT Standard_Boolean FDS_LOIinfsup(
2172                                     const TopOpeBRepDS_DataStructure&,
2173                                     const TopoDS_Edge& E,
2174                                     const Standard_Real pE,
2175                                     const TopOpeBRepDS_Kind KDS,
2176                                     const Standard_Integer GDS,
2177                                     const TopOpeBRepDS_ListOfInterference& LOI,
2178                                     Standard_Real& pbef,
2179                                     Standard_Real& paft,
2180                                     Standard_Boolean& isonboundper)
2181 {
2182   Standard_Real f = 0.0, l = 0.0; FUN_tool_bounds(E,f,l);
2183   pbef = f; paft = l;
2184   Standard_Integer n = LOI.Extent(); 
2185   if (n == 0) return Standard_True;
2186
2187
2188   TopOpeBRepDS_ListOfInterference LOIsansGDS;
2189   TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LOI);
2190
2191   for(tki.Init();tki.More();tki.Next()) {
2192     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
2193     Standard_Boolean PV =(K==TopOpeBRepDS_POINT)||(K==TopOpeBRepDS_VERTEX);if (!PV) continue;
2194     Standard_Boolean mk = (K == KDS); Standard_Boolean mg = (G == GDS); 
2195     Standard_Boolean mkg = (mk && mg); if ( mkg ) continue;
2196
2197     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G);
2198
2199     for (TopOpeBRepDS_ListIteratorOfListOfInterference it(loi);it.More();it.Next()) {
2200       const Handle(TopOpeBRepDS_Interference)& I = it.Value();
2201       TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; TopAbs_ShapeEnum tsb1,tsa1; Standard_Integer isb1,isa1; 
2202       FDS_Idata(I,tsb1,isb1,tsa1,isa1,GT1,G1,ST1,S1);
2203       if (tsb1 != TopAbs_FACE) continue;
2204       if (tsa1 != TopAbs_FACE) continue;
2205       Handle(TopOpeBRepDS_CurvePointInterference) cpi (Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I));
2206       Handle(TopOpeBRepDS_EdgeVertexInterference) evi (Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I));
2207       if (cpi.IsNull() && evi.IsNull()) continue;
2208       LOIsansGDS.Append(I);
2209       break;
2210     }
2211   }
2212   
2213   n = LOIsansGDS.Extent();  
2214   if (n == 0) return Standard_True;
2215
2216   TopoDS_Vertex v; Standard_Boolean Eclosed = TopOpeBRepTool_TOOL::ClosedE(E,v);
2217   Standard_Real tole = BRep_Tool::Tolerance(E);
2218   Standard_Real tol = Precision::Parametric(tole);
2219   isonboundper = Standard_False;
2220   if (Eclosed) {
2221     Standard_Real tolv = BRep_Tool::Tolerance(v);
2222     tolv = Precision::Parametric(tolv);
2223     if (tolv > tol) tol = tolv;
2224     Standard_Boolean pEisEf = (Abs(pE-f) <= tol);
2225     Standard_Boolean pEisEl = (Abs(pE-l) <= tol);
2226     isonboundper = pEisEf || pEisEl;
2227   }
2228
2229   if (isonboundper) {    
2230     for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LOIsansGDS);it.More();it.Next()) {
2231       const Handle(TopOpeBRepDS_Interference)& I = it.Value();
2232       Standard_Real p = FDS_Parameter(I);
2233       // pbef > paft
2234       if (p > pbef) pbef = p;
2235       if (p < paft) paft = p;
2236     }    
2237     return Standard_True;
2238   }
2239   else {
2240     for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LOIsansGDS);it.More();it.Next()) {
2241       const Handle(TopOpeBRepDS_Interference)& I = it.Value();
2242       Standard_Real p = FDS_Parameter(I);
2243       if (p > pbef && p < pE) pbef = p;
2244       if (p < paft && p > pE) paft = p;
2245     }
2246   }
2247   return Standard_True;
2248 } // FDS_LOIinfsup
2249
2250 // sur arete E : pbef < pE < paft, calcul de p1,t2 / :
2251 // p1 dans [pbef,pE[
2252 // p2 dans ]pE,paft]
2253 // si isonboundper = T, les bornes pbef et paft sont prises sur les bornes de E.
2254 Standard_EXPORT Standard_Boolean FDS_parbefaft(
2255 //                                    const TopOpeBRepDS_DataStructure& BDS,
2256                                     const TopOpeBRepDS_DataStructure& ,
2257                                     const TopoDS_Edge& E,
2258                                     const Standard_Real pE,
2259                                     const Standard_Real& pbef,
2260                                     const Standard_Real& paft,
2261                                     const Standard_Boolean& isonboundper,
2262                                     Standard_Real& p1, Standard_Real& p2)
2263 {
2264   Standard_Real t = 0.3178947713;
2265   Standard_Real f,l; FUN_tool_bounds(E,f,l);
2266   if (isonboundper) {
2267     p1 = (1-t)*pbef + t*l;
2268     p2 = (1-t)*f + t*paft;
2269   }
2270   else {
2271     p1 = (1-t)*pbef + t*pE;
2272     p2 = (1-t)*pE + t*paft; 
2273   }
2274   return Standard_True;
2275 } // FDS_parbefaft
2276
2277 Standard_EXPORT Standard_Boolean FDS_stateEwithF2d(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& E,const Standard_Real pE,
2278                                       const TopOpeBRepDS_Kind KDS,const Standard_Integer GDS,
2279                                       const TopoDS_Face& F1,
2280                                       TopOpeBRepDS_Transition& TrmemeS)
2281 {
2282   const TopOpeBRepDS_ListOfInterference& LOI = BDS.ShapeInterferences(E);
2283   Standard_Real pbef = 0.0, paft = 0.0; Standard_Boolean isonper = false; Standard_Boolean ok = FDS_LOIinfsup(BDS,E,pE,KDS,GDS,LOI,pbef,paft,isonper);
2284   if (!ok) return Standard_False;
2285   Standard_Real t1 = 0.0, t2 = 0.0; ok = FDS_parbefaft(BDS,E,pE,pbef,paft,isonper,t1,t2);
2286   gp_Pnt P1; Standard_Boolean ok1 = FUN_tool_value(t1,E,P1);
2287   gp_Pnt P2; Standard_Boolean ok2 = FUN_tool_value(t2,E,P2);
2288   if (!ok1 || !ok2) return Standard_False;
2289
2290   TopOpeBRepTool_ShapeClassifier& PSC = FSC_GetPSC(F1);
2291   TopAbs_State sta1 = FSC_StatePonFace(P1,F1,PSC);
2292   TopAbs_State sta2 = FSC_StatePonFace(P2,F1,PSC);
2293
2294   // xpu190898 : cto014I2 (e5,fTRASHA14,vG7,eS10)
2295   if (sta1 == TopAbs_ON) sta1 = TopAbs_IN;
2296   if (sta2 == TopAbs_ON) sta2 = TopAbs_IN;
2297
2298   TrmemeS.Before(sta1,TopAbs_FACE);
2299   TrmemeS.After (sta2,TopAbs_FACE);
2300   return Standard_True;
2301 }//FDS_stateEwithF2d
2302
2303 #define SAMEORIENTED (1)
2304 #define DIFFORIENTED (2)
2305 Standard_EXPORT void FUN_ds_FEIGb1TO0(Handle(TopOpeBRepDS_HDataStructure)& HDS,
2306                                       const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEspON)
2307 {
2308   //xpu250199 :  F has FEI(Gb1,  EG, FS), EG sdm Esd
2309   //            -> to prevent from the loss of information, replace interference with
2310   //                   FEI'(Gb0, EGsd, FS)
2311   //CTS21754, f26 has FEI(Gb1,EG=e13, FS=f16), EG13 sd Esd11
2312   
2313   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
2314   Standard_Integer ns = BDS.NbShapes();
2315   for (Standard_Integer I=1; I<=ns; I++) {
2316
2317     const TopoDS_Shape& F = BDS.Shape(I);
2318     if (F. ShapeType() != TopAbs_FACE) continue;
2319     const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(F);    
2320     TopOpeBRepDS_ListOfInterference LGb1; // LI = LII + LGb1 (= {FEI with GB1})
2321     TopOpeBRepDS_ListOfInterference LII; FDS_copy(LI,LII);
2322     TopOpeBRepDS_ListIteratorOfListOfInterference it(LII);
2323     while (it.More()) {
2324       const Handle(TopOpeBRepDS_Interference)& Intf = it.Value();
2325       Handle(TopOpeBRepDS_FaceEdgeInterference) FEI =
2326         Handle(TopOpeBRepDS_FaceEdgeInterference)::DownCast(Intf);
2327       if (FEI.IsNull()) {
2328         it.Next();
2329         continue;
2330       }
2331       Standard_Boolean GB = FEI->GBound();
2332       if (GB != 1) {
2333         it.Next();
2334         continue;
2335       }
2336       LGb1.Append(Intf);
2337       LII.Remove(it);
2338     }//it(LII)
2339     Standard_Integer nGb1 = LGb1.Extent();
2340     if (nGb1 == 0) continue;
2341
2342     TopOpeBRepDS_ListOfInterference LGb0; // LGb1={FEIGb1(EG,FS)} -> LGb0={FEIGb0(Esd,FS)}
2343     it.Initialize(LGb1);
2344     while (it.More()) {
2345       Handle(TopOpeBRepDS_FaceEdgeInterference) IGb1 = Handle(TopOpeBRepDS_FaceEdgeInterference)::DownCast(it.Value());
2346       Standard_Integer S = IGb1->Support(); const TopoDS_Face& FS = TopoDS::Face(BDS.Shape(S));
2347       Standard_Integer G = IGb1->Geometry();
2348       Standard_Integer Gsd; Standard_Boolean findSD = TopOpeBRepDS_TOOL::GetEsd(HDS,FS,G,Gsd);
2349       if (!findSD) {it.Next(); continue;}
2350
2351       // IGb0 is already stored in the list of interferences :
2352       TopOpeBRepDS_ListIteratorOfListOfInterference itt(LII); Standard_Boolean stored = Standard_False;
2353       for (; itt.More(); itt.Next()){
2354         const Handle(TopOpeBRepDS_Interference)& II = itt.Value();
2355         Standard_Boolean isfound = (II->Support() == S)&&(II->Geometry() == Gsd);
2356         if (isfound) {stored = Standard_True; break;}
2357       }//itt(LII)      
2358       if (stored) {LGb1.Remove(it); continue;}
2359
2360       TopOpeBRepDS_Transition newT = IGb1->Transition();
2361       TopAbs_Orientation newO = newT.Orientation(TopAbs_IN);
2362       if (M_INTERNAL(newO) || M_EXTERNAL(newO)) {
2363         // nothing's done
2364       }
2365       else {
2366         Standard_Integer conf = 0; Standard_Boolean ok = TopOpeBRepDS_TOOL::GetConfig(HDS,MEspON,G,Gsd,conf);
2367         if (!ok) {it.Next(); continue;}
2368         if (conf == DIFFORIENTED) newO = TopAbs::Complement(newO);
2369       }
2370       newT.Set(newO);
2371       IGb1->SetGeometry(Gsd); IGb1->SetGBound(Standard_False); IGb1->Transition(newT);
2372       LGb0.Append(IGb1); LGb1.Remove(it);      
2373     }//it(LGb1)
2374     
2375     if (LGb0.IsEmpty()) continue;
2376     TopOpeBRepDS_ListOfInterference& newLI = BDS.ChangeShapeInterferences(F);
2377     newLI.Clear();
2378     newLI.Append(LII); newLI.Append(LGb1); newLI.Append(LGb0);
2379   }//i=1..ns  
2380 }//FUN_ds_FEIGb1TO0
2381
2382 // ----------------------------------------------------------------------
2383 Standard_EXPORT void FUN_ds_complete1dForSESDM(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
2384 // ----------------------------------------------------------------------
2385 // MSV 25.03.2002 : OCC251
2386 // purpose : SE Section edge, SDM with Esd, SE has no interference
2387 //   for one of vertices of Esd while should.
2388 {
2389   TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
2390   Standard_Integer nse = BDS.NbSectionEdges();  
2391
2392   for (Standard_Integer is = 1; is <= nse; is++) {
2393     const TopoDS_Edge& SE = BDS.SectionEdge(is);
2394     if (BRep_Tool::Degenerated(SE)) continue;
2395     Standard_Integer rkSE = BDS.AncestorRank(SE);
2396     Standard_Integer iSE = BDS.Shape(SE);   
2397     Standard_Boolean hsd = HDS->HasSameDomain(SE);
2398     if (!hsd) continue;
2399     const TopTools_ListOfShape& LEsd = BDS.ShapeSameDomain(SE);
2400     if (LEsd.IsEmpty()) continue;
2401
2402     Standard_Real tolSE = BRep_Tool::Tolerance(SE);
2403     // map of vertices of SE or same domain with them
2404     TopTools_MapOfShape aGBMap;
2405     TopoDS_Vertex VSE[2];
2406     TopExp::Vertices(SE,VSE[0],VSE[1]);
2407     Standard_Integer i;
2408     for (i=0; i < 2; i++)
2409       if (!VSE[i].IsNull()) {
2410         aGBMap.Add(VSE[i]);
2411         const TopTools_ListOfShape& LV = BDS.ShapeSameDomain(VSE[i]);
2412         TopTools_ListIteratorOfListOfShape it(LV);
2413         for (; it.More(); it.Next())
2414           aGBMap.Add(it.Value());
2415       }
2416
2417     TopTools_ListIteratorOfListOfShape ite(LEsd);
2418     for (; ite.More(); ite.Next()){
2419       const TopoDS_Edge& Esd = TopoDS::Edge(ite.Value());
2420       Standard_Integer iEsd = BDS.Shape(Esd);
2421       Standard_Integer rkEsd = BDS.AncestorRank(Esd);
2422       if (rkEsd == rkSE) continue;
2423
2424       if (BRep_Tool::Degenerated(Esd)) continue;
2425       Standard_Boolean isSO = false;
2426       Standard_Boolean ok = FUN_tool_curvesSO(Esd,SE,isSO);
2427       if (!ok) continue;
2428
2429       Standard_Real tolEsd = Max (BRep_Tool::Tolerance(Esd), tolSE);
2430       // prepare the list of interferences of SE with Esd
2431       const TopOpeBRepDS_ListOfInterference& LIall = BDS.ShapeInterferences(iSE);
2432       TopOpeBRepDS_ListOfInterference LI,LI1;
2433       FDS_assign(LIall,LI);
2434       Standard_Integer ni = FUN_selectTRAUNKinterference(LI,LI1);
2435       LI1.Clear(); ni = FUN_selectTRASHAinterference(LI,TopAbs_EDGE,LI1);
2436       LI.Clear(); ni = FUN_selectITRASHAinterference(LI1,iEsd,LI);
2437       LI1.Clear(); ni = FUN_selectSKinterference(LI,TopOpeBRepDS_EDGE,LI1);
2438       LI.Clear(); ni = FUN_selectSIinterference(LI1,iEsd,LI);
2439       LI1.Clear(); ni = FUN_selectGKinterference(LI,TopOpeBRepDS_VERTEX,LI1);
2440       LI.Clear(); LI.Append(LI1);
2441
2442       // process vertices of Esd
2443       TopoDS_Vertex Vsd[2];
2444       TopExp::Vertices(Esd,Vsd[0],Vsd[1]);
2445       for (i=0; i < 2; i++) {
2446         const TopoDS_Vertex& aV = Vsd[i];
2447         if (aV.IsNull()) continue;
2448         // do not create interferences on GBound
2449         if (aGBMap.Contains(aV)) continue;
2450
2451         TopAbs_Orientation ori = aV.Orientation();
2452         if (!isSO) ori = TopAbs::Reverse(ori);
2453
2454         // check that SE has no yet interference with geometry aV oriented ori
2455         if (ni) {
2456           TopOpeBRepDS_ListOfInterference LI2;
2457           FDS_assign(LI,LI1);
2458           Standard_Integer nio = FUN_selectTRAORIinterference(LI1,ori,LI2);
2459           if (nio) {
2460             TopTools_MapOfShape aVGMap;
2461             aVGMap.Add(aV);
2462             const TopTools_ListOfShape& LV = BDS.ShapeSameDomain(aV);
2463             TopTools_ListIteratorOfListOfShape it(LV);
2464             for (; it.More(); it.Next())
2465               aVGMap.Add(it.Value());
2466             TopOpeBRepDS_ListIteratorOfListOfInterference iti(LI2);
2467             for (; iti.More(); iti.Next()) {
2468               const Handle(TopOpeBRepDS_Interference)& I1 = iti.Value();
2469               Standard_Integer gi = I1->Geometry();
2470               const TopoDS_Shape& aVG = BDS.Shape(gi);
2471               if (aVGMap.Contains(aVG)) break;
2472             }
2473             if (iti.More()) continue; // has already
2474           }
2475         }
2476
2477         // make new interference
2478         Standard_Real par = 0.0;
2479         Standard_Real tol = Max (BRep_Tool::Tolerance(aV), tolEsd);
2480         Standard_Real parEsd = BRep_Tool::Parameter(aV,Esd);
2481         ok = FUN_tool_parE (Esd,parEsd,SE,par,tol);
2482         if (!ok) continue;
2483         TopOpeBRepDS_Transition aT(ori);
2484         aT.ShapeBefore(TopAbs_EDGE); aT.ShapeAfter(TopAbs_EDGE);
2485         aT.Index(iEsd);
2486         Standard_Integer iV = BDS.AddShape(aV,rkEsd);
2487         Standard_Boolean isGBound = Standard_False;
2488         TopOpeBRepDS_Config aConfig = (isSO
2489                                        ? TopOpeBRepDS_SAMEORIENTED
2490                                        : TopOpeBRepDS_DIFFORIENTED);
2491         Handle(TopOpeBRepDS_Interference) aI = 
2492           TopOpeBRepDS_InterferenceTool::MakeEdgeVertexInterference
2493             (aT,iEsd,iV,isGBound,aConfig,par);
2494         HDS->StoreInterference(aI,SE);
2495       }
2496     }
2497   }
2498 }