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