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