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