0024096: Eliminate compiler warning C4505 in MSVC++ with warning level 4
[occt.git] / src / TopOpeBRep / TopOpeBRep_vprdeg.cxx
1 // Created on: 1995-08-04
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1995-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
22 #include <TopOpeBRep_FacesFiller.ixx>
23
24 #ifdef DRAW
25 #include <TopOpeBRepDS_DRAW.hxx>
26 #endif
27
28 #include <Geom_Curve.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2d_Curve.hxx>
31
32 #include <TopoDS.hxx>
33 #include <TopExp.hxx>
34 #include <BRepAdaptor_Surface.hxx>
35 #include <BRepAdaptor_Curve.hxx>
36 //#include <BRepAdaptor_Curve2d.hxx>
37 #include <gp_Vec.hxx>
38 #include <BRep_Tool.hxx>
39 #include <TopAbs.hxx>
40 #include <TopExp.hxx>
41 #include <Precision.hxx>
42
43 #include <TopOpeBRepDS_EXPORT.hxx>
44 #include <TopOpeBRep.hxx>
45 #include <TopOpeBRep_define.hxx>
46 #include <TopOpeBRepTool_ShapeTool.hxx>
47 #include <TopOpeBRepTool_TOOL.hxx>
48 #include <TopOpeBRepTool_EXPORT.hxx>
49 #include <TopOpeBRepTool_mkTondgE.hxx>
50
51 #define M_ON(st)       (st == TopAbs_ON) 
52 #define M_REVERSED(st) (st == TopAbs_REVERSED) 
53
54 // modified by NIZHNY-MKK  Tue Nov 21 17:30:23 2000.BEGIN
55 static TopTools_DataMapOfShapeListOfShape aMapOfTreatedVertexListOfEdge;
56 static TopOpeBRep_PLineInter localCurrentLine=NULL;
57
58 static Standard_Boolean local_FindTreatedEdgeOnVertex(const TopoDS_Edge& theEdge,
59                                                       const TopoDS_Vertex& theVertex);
60
61 static void local_ReduceMapOfTreatedVertices(const TopOpeBRep_PLineInter& theCurrentLine);
62
63 static Standard_Boolean local_FindVertex(const TopOpeBRep_VPointInter& theVP,
64                                          const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfVertexEdges,
65                                          TopoDS_Vertex& theVertex);
66 // modified by NIZHNY-MKK  Tue Nov 21 17:30:27 2000.END
67
68 #ifdef DEB
69 extern Standard_Boolean TopOpeBRepDS_GettraceDEGEN();
70 extern Standard_Boolean TopOpeBRepDS_GettraceDSF();
71 Standard_EXPORT Standard_Boolean FUN_debnull(const TopoDS_Shape& s);
72 #endif
73
74 Standard_EXPORT  Handle(TopOpeBRepDS_Interference) MakeEPVInterference
75 (const TopOpeBRepDS_Transition& T, // transition
76  const Standard_Integer S, // curve/edge index
77  const Standard_Integer G, // point/vertex index
78  const Standard_Real P, // parameter of G on S
79  const TopOpeBRepDS_Kind GK,
80  const Standard_Boolean B); // G is a vertex (or not) of the interference master
81
82 Standard_EXPORT Handle(TopOpeBRepDS_Interference) MakeEPVInterference
83 (const TopOpeBRepDS_Transition& T, // transition
84  const Standard_Integer S, // curve/edge index
85  const Standard_Integer G, // point/vertex index
86  const Standard_Real P, // parameter of G on S
87  const TopOpeBRepDS_Kind GK, // POINT/VERTEX
88  const TopOpeBRepDS_Kind SK,
89  const Standard_Boolean B); // G is a vertex (or not) of the interference master
90
91
92 #define M_FINDVP  (0) // only look for new vp
93 #define M_MKNEWVP (1) // only make newvp
94 #define M_GETVP   (2) // steps (0) [+(1) if (O) fails]
95 Standard_EXPORT void FUN_VPIndex
96 (TopOpeBRep_FacesFiller& FF,
97  const TopOpeBRep_LineInter& L,
98  const TopOpeBRep_VPointInter& VP,
99  const Standard_Integer ShapeIndex,
100  const Handle(TopOpeBRepDS_HDataStructure)& HDS,
101  const TopOpeBRepDS_ListOfInterference& DSCIL,
102  TopOpeBRepDS_Kind& PVKind, Standard_Integer& PVIndex, // out
103  Standard_Boolean& EPIfound, Handle(TopOpeBRepDS_Interference)& IEPI, // out 
104  Standard_Boolean& CPIfound, Handle(TopOpeBRepDS_Interference)& ICPI, // out 
105  const Standard_Integer mkVP);
106
107
108 /*
109 // *******************   methods for the compute   **********************
110 // ******************   of interferences on degenerated edge   **********
111
112 // UVonEofF(par) = 2d point of parameter par on edge E in F's  2d representation.
113 // UVonF(E)      = E's pcurve on F
114 // UVonF(V)      = V's UV on F's 2d representation.
115
116 #define UNDEF (0)
117 #define FIRST (1)
118 #define LAST  (2)
119
120 static void FUN_GetVectors(const TopoDS_Face& Fe, const TopoDS_Face& Fi,
121                            const TopoDS_Edge& Ec,
122                            const gp_Pnt2d& p2di, const gp_Pnt2d& p2de,
123                            const TopoDS_Vertex& ve,
124                            gp_Vec& ngFe, gp_Vec& ngFi,
125                            gp_Vec& a, gp_Vec& x)
126 {
127    // geometric normals to Fe and Fi : ngFe,ngFi
128   ngFi = FUN_tool_nggeomF(p2di, Fi);
129   ngFe = FUN_tool_nggeomF(p2de, Fe);
130   // tgEc
131   gp_Vec tgEc;
132 //  Standard_Integer orivine = FUN_tool_orientVinE(ve,Ec);
133 //  Standard_Real parOnEc = BRep_Tool::Parameter(ve,Ec);
134 //  tgEc = FUN_tool_tggeomE(parOnEc,Ec);
135 //  a = tgEc; if (orivine == LAST) a.Reverse();
136   Standard_Integer ovine; Standard_Boolean ok = TopOpeBRepTool_TOOL::TgINSIDE(ve,Ec,a,ovine);  
137
138   x = ngFe^ngFi; 
139 }
140
141 static void FUN_getEofFwithV(const TopoDS_Vertex& v, const TopoDS_Face& Fi, TopTools_ListOfShape& los)
142 {
143   // get <los>, the edges of <Fi> binding vertex <V>
144   los.Clear(); Standard_Integer ned = 0;
145
146   TopExp_Explorer exe(Fi, TopAbs_EDGE);
147   for (; exe.More(); exe.Next()) {
148     const TopoDS_Shape& edge = exe.Current();
149     TopExp_Explorer exv(edge, TopAbs_VERTEX);
150     for (; exv.More(); exv.Next()) {
151       if (exv.Current().IsSame(v)) {
152         los.Append(edge);
153         ned++; break;
154       }
155     }
156     if (ned == 2) return;
157   }
158 }
159  
160 static Standard_Real FUN_getpar(const gp_Dir& a, const gp_Dir& x, const gp_Dir& y, 
161                       const Standard_Boolean& complement)
162 {
163   // Computes the parameter on degenerated edge (on circle) :
164   // <Fe> on spherical surface
165   // <Fi> the incident face
166   // watching our system in a XY space normal to ngFe :
167   // <a> : tangent with tgEc, going OUT the sphere, while
168   //       following the geometry of <Ec>
169   // <x> : normal to ngFi, oriented INSIDE Fi
170   // <y> : normal to <x>, oriented OUTSIDE the matter delimited
171   //       by the oriented face <Fi>.
172   // <par> is the oriented angle (<a>,<x>), computed in the 
173   // anti-trigonometric sense (defined by RONd (<x>,<y>,<z>).
174
175   // If <complement>, nrotation has a direction opposite to z,
176   // parameter on sphere = 2PI - parameter computed.
177
178   Standard_Real x1 = a.Dot(x);
179   Standard_Real x2 = a.Dot(y);
180   Standard_Real par;  
181   Standard_Real tol = Precision::Angular();
182   Standard_Boolean x1null = (Abs(x1) <= tol);
183   Standard_Boolean x2null = (Abs(x2) <= tol);
184
185   if      (x1null) par = (x2 > 0.) ? 3.*M_PI*.5 : M_PI*.5;
186   else if (x2null) par = (x1 > 0.) ? 2.*M_PI    : M_PI;
187   else {
188     Standard_Real ac = ACos(Abs(x1));
189     Standard_Boolean x1pos = (x1 > tol);
190     Standard_Boolean x2pos = (x2 > tol);
191     if (x1pos && x2pos)   par = 2.*M_PI-ac;
192     if (x1pos && !x2pos)  par = ac;
193     if (!x1pos && x2pos)  par = M_PI+ac;
194     if (!x1pos && !x2pos) par = M_PI-ac;
195   }
196
197   if (complement) par = 2.*M_PI - par;
198   return par;
199 }
200
201 static void FUN_getloEi(const gp_Pnt2d& p2d, const TopoDS_Shape& F, TopTools_ListOfShape& loE)
202 {
203   loE.Clear(); Standard_Integer nsol = 0;
204   // looking for restrictions of <F> / <p2d> is ON these restrictions.
205   // if <onlyoneE>, looks get the first restriction solution,
206   //                else looks among all the restrictions for edges solutions
207   Standard_Real tol = Precision::Parametric(Precision::Confusion());
208   TopExp_Explorer ex(F, TopAbs_EDGE);
209   for (; ex.More(); ex.Next()){
210     const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
211     if ( E.Orientation() == TopAbs_INTERNAL )     continue;
212     if ( BRep_Tool::IsClosed(E,TopoDS::Face(F)) ) continue;
213
214     Standard_Real par,dist;
215     Standard_Boolean ok = TopOpeBRepTool_TOOL::ParE2d(p2d,E,TopoDS::Face(F), par,dist);
216     if (!ok) continue;
217     Standard_Real tolp = TopOpeBRepTool_TOOL::TolP(E,TopoDS::Face(F));
218     if (dist < tolp) {loE.Append(E); nsol++;}
219     if (nsol == 2) return;
220   }
221 }
222
223 static Standard_Boolean FUN_paronE(const gp_Pnt2d& p2d, const TopoDS_Shape& E, const TopoDS_Shape& F,
224                       Standard_Real& paronE)
225 {
226   // <p2d> on UVon<F>(<E>)
227   // Purpose : finding out paronE / UVon<E>(paronE) = <p2d>
228   Standard_Real par,dist;
229   Standard_Boolean ok = TopOpeBRepTool_TOOL::ParE2d(p2d,TopoDS::Edge(E),TopoDS::Face(F), par,dist);
230   if (!ok) return Standard_False;
231   Standard_Real tolp = TopOpeBRepTool_TOOL::TolP(TopoDS::Edge(E),TopoDS::Face(F));
232   if (dist < tolp) {paronE = par; return Standard_True;}
233   else             return Standard_False;
234 }
235
236 static Standard_Boolean FUN_nullx(const gp_Vec& x)
237 {
238   Standard_Real tola = Precision::Confusion();
239   Standard_Real mag = x.Magnitude();
240   Standard_Boolean isnull = (mag < tola);
241   return isnull;
242 }
243
244 static Standard_Boolean FUN_OOEi(const gp_Pnt2d& p2di, const TopoDS_Face& Fi,
245                     TopoDS_Edge& OOEi, Standard_Real& paronOOEi)     
246 {
247   // ngFe // ngFi : <Fi> is tangent to the sphere on its
248   // degenerated edge.
249   // vertex is on <Ec> (sphere's closing edge) and <OOEi> (on <Fi>).
250   // <p2di> = UVon<Fi>(<ve>) 
251   Standard_Boolean isplane = FUN_tool_plane(Fi); if (isplane) return Standard_False;
252   
253   // --------------------------------------------------
254   // SUPPLYING INTPATCH :
255   // The geometry of <ve> is on 2 edges <Ec> and <OOEi>
256   // and <OOEi> is not found touched.
257   // --------------------------------------------------
258   // <loEi> is the list of edges of <Fi> not INTERNAL
259   // and non-closing.
260   TopTools_ListOfShape loEi; FUN_getloEi(p2di,Fi,loEi);
261   if (loEi.Extent() != 1) return Standard_False;
262   
263   OOEi = TopoDS::Edge(loEi.First());
264   Standard_Boolean done = FUN_paronE(p2di,OOEi,Fi,paronOOEi); 
265   return done;
266 }
267
268 static void FUN_transitiononedge
269 (const TopAbs_State& staB, const TopAbs_State& staA, TopOpeBRepDS_Transition& T)
270 {
271   T = TopOpeBRepDS_Transition(staB,staA,TopAbs_EDGE,TopAbs_EDGE);
272
273
274 static Standard_Boolean FUN_IEcOOEi
275 (const TopoDS_Vertex& ve, const Standard_Real& paronOOEi, const TopoDS_Edge& OOEi, const TopoDS_Edge& Ec, 
276  TopOpeBRepDS_Transition& TOOEi)
277 {
278   FUN_transitiononedge(TopAbs_UNKNOWN,TopAbs_UNKNOWN,TOOEi);
279   // ------------------------------------------------------------
280   // SUPPLYING INTPATCH :
281   // when tg<OOEi> and tg<Ec> are tangent,
282   // the interference <OOEi> with <Ec> at vertex <v> is not found 
283   // => we have to compute the transition <T> :
284   // following <OOEi>'s geometry, we cross <Ec> at vertex <ve>
285   // and describe the transition <T>.
286   // ------------------------------------------------------------
287   gp_Vec dirOOEi = FUN_tool_tggeomE(paronOOEi,OOEi);
288   
289   Standard_Real paronEc; 
290   Standard_Boolean ok = FUN_tool_parVonE(ve,Ec,paronEc); if (!ok) return Standard_False;
291   gp_Vec dirEc = FUN_tool_tggeomE(paronEc,Ec);
292
293   Standard_Real prod = dirOOEi.Dot(dirEc);
294   Standard_Real tola = Precision::Angular();
295   Standard_Boolean dEctgdOOEi = (Abs(1-Abs(prod)) < tola);
296   if (!dEctgdOOEi) return Standard_False;
297   
298   // get <dparonOOEi>, 
299   // compute <paronOOEi> = point of <OOEi> at param=paronOOEi+dparonOOEi
300   Standard_Real f,l; Handle(Geom_Curve) C = BRep_Tool::Curve(OOEi,f,l);
301   Standard_Real dparonOOEi = (l-f)*0.05; // NYI : find a better value
302   Standard_Real tol = Precision::Parametric( Precision::Confusion());
303   Standard_Boolean islast  = (Abs(paronOOEi-l) < tol);
304   Standard_Boolean isfirst = (Abs(paronOOEi-f) < tol);
305   if (islast || isfirst) return Standard_False;
306   Standard_Real param = paronOOEi+dparonOOEi;
307   gp_Pnt ptonOOEi = C->Value(param);
308   
309   // classify <paronOOEi> IN <Ec>
310   TopAbs_State sta = FUN_tool_staPinE(ptonOOEi,Ec);
311   if (sta == TopAbs_IN)  FUN_transitiononedge(TopAbs_OUT,TopAbs_IN,TOOEi);
312   if (sta == TopAbs_OUT) FUN_transitiononedge(TopAbs_IN,TopAbs_OUT,TOOEi);
313   return Standard_True;
314 }
315
316 #define s_NOTdgE (0) // do NOT compute any transition
317 #define s_TdgE   (1) // compute transition on dgE
318 #define s_TOOEi  (2) // compute transition on OOEi
319
320 // case VP is ON the boundary of <Fi> (on edge <Ei>)
321 static Standard_Integer FUN_parondgEONFi
322 (const TopOpeBRep_VPointInter& VP,
323  const Standard_Boolean visvon12,      
324  const TopoDS_Vertex& ve, 
325  const TopoDS_Vertex& vi,   // dummy if !visvon12
326  const Standard_Integer is,    // rank of <Fe>
327  const TopoDS_Face& Fe,   // contains Ed, Ec
328  const TopoDS_Face& Fi,   // face of shape is, contains Ei
329  const TopoDS_Edge& Ed,   // degenerated edge
330  const TopoDS_Edge& Ei,   // incident edge
331  const TopoDS_Edge& Ec,   // couture edge
332  Standard_Real& paronEd,TopOpeBRepDS_Transition& T,                   // !s_NOTdgE  
333  TopoDS_Edge& OOEi, Standard_Real& paronOOEi, TopOpeBRepDS_Transition& TOOEi) // s_TOOEi
334 {
335   // <Fe>, <Ed>, <ve> are of rank <is>, <Ed> is on face <Fe>
336   // <Fi>, <Ei>, <vi> are of rank <ioo>, <Ei> is on face <Fi>
337   Standard_Integer ioo = (is == 1) ? 2 : 1;
338   Standard_Integer sind = VP.ShapeIndex();
339   
340   // p2di and p2de :
341   gp_Pnt2d p2de = VP.SurfaceParameters(is);
342   
343   gp_Pnt2d p2di = VP.SurfaceParameters(ioo);
344   Standard_Real parOnEi;
345   Standard_Boolean ok = VP.ParonE(Ei,parOnEi);
346   if (!ok) {
347     TopoDS_Vertex voo;
348     if (visvon12) voo = vi;
349     else          voo = ve; // is of rank <is> or <ioo>!
350     ok = FUN_tool_parVonE(voo,Ei,parOnEi);
351   }
352   if (!ok) return s_NOTdgE;
353   
354   // Getting caracteristic vectors describing our system (a,x,y). 
355   // The system is in the plane normal to ngFe :
356   // * <a> is the direction of the tangent vector tgEc, going OUT 
357   // the sphere while following <Ec>
358   // * <x> is normal to ngFi.   
359   //   <x> is oriented INSIDE <Fi> (the matter limited by <Fi>'s boundaries)
360   // * (<x>,<y>,<z>) describe a RONd such that
361   // the geometry of the degenerated edge <Ed> follows (<x>,<y>,<z>),
362   // <y> is oriented OUTSIDE the matter limited by the oriented face <Fi>.
363   // (<Fi> is a plane : <z> is parallel to ngFe)
364
365   gp_Vec ngFe,ngFi,x,a;
366   FUN_GetVectors(Fe,Fi,Ec,p2di,p2de,ve,ngFe,ngFi,a,x);
367
368   // xpu : 24-10-97
369   Standard_Boolean nullx =  FUN_nullx(x);
370   if (nullx) {
371     Standard_Boolean mTOOEi = Standard_False;
372     Standard_Boolean getOOEi = FUN_OOEi(p2di,Fi,OOEi,paronOOEi);
373     if (getOOEi && !OOEi.IsSame(Ei)) mTOOEi = FUN_IEcOOEi(ve,paronOOEi,OOEi,Ec,TOOEi);
374
375     if (!mTOOEi) return s_NOTdgE;
376     else         return s_TOOEi;
377   }
378   // xpu : 24-10-97
379
380   gp_Vec xx = FUN_tool_getgeomxx(Fi,Ei,parOnEi,ngFi);
381   TopAbs_Orientation oriEi; ok = FUN_tool_orientEinFFORWARD(Ei,Fi,oriEi);
382   if (!ok) return s_NOTdgE; // NYI : Raise Error
383   if (oriEi == TopAbs_REVERSED) xx.Reverse();
384   
385   if (x.Dot(xx) < 0.) x.Reverse();
386
387   // when the edge <Ei> is tangent to <Fe> at vertex <v>,
388   // the degenerated edge is not splitted.
389   Standard_Boolean EitangenttoFe = FUN_tool_EitangenttoFe(ngFe,Ei,parOnEi);
390   if (EitangenttoFe) return s_NOTdgE;
391
392   gp_Vec y;
393   if (Fi.Orientation() == TopAbs_FORWARD) y = ngFi;
394   else                                    y = ngFi.Reversed();
395   gp_Vec z(x^y);
396
397 #ifdef DEB
398   Standard_Boolean trc = Standard_False;
399   if (trc) {
400     gp_Pnt p = BRep_Tool::Pnt(ve);
401 #ifdef DRAW
402     TCollection_AsciiString aax("x");     FUN_brep_draw(aax,p,x);
403     TCollection_AsciiString aay("y");     FUN_brep_draw(aay,p,y);
404     TCollection_AsciiString aang("ngFi"); FUN_brep_draw(aang,p,ngFi);
405     TCollection_AsciiString aaa("a");     FUN_brep_draw(aaa,p,a);
406 #endif
407   }
408 #endif
409   
410   // nrotation  = axis describing the sphere's parametrization 
411   Standard_Integer orivine = FUN_tool_orientVinE(ve,Ec);
412   gp_Vec nrotation;
413   if (orivine == LAST) nrotation = ngFe;
414   else                 nrotation = ngFe.Reversed();
415   Standard_Boolean complement = (z.Dot(nrotation) < 0.);
416   paronEd = FUN_getpar(gp_Dir(a),gp_Dir(x),gp_Dir(y),complement);
417
418   // T :
419   // in referential (x,y), following trigonometric sense, while 
420   // crossing axis x (describing Fi), the transition is IN/OUT
421   // (y = ntFi). 
422   // if parametrization follows the trigonometric sense: transition IN/OUT
423   // else, it is OUT/IN.
424   
425   Standard_Boolean inout = !complement;
426   if (inout) T.Set(TopAbs_IN,TopAbs_OUT);
427   else T.Set(TopAbs_OUT,TopAbs_IN);
428   return s_TdgE;
429 }
430
431 static Standard_Boolean FUN_0or2PI(Standard_Real& paronEd, const Standard_Boolean& inout)
432 {
433   Standard_Real tol = Precision::Parametric(Precision::Confusion());
434   Standard_Boolean extre = (Abs(paronEd) < tol);
435   extre = extre && (Abs(2.*M_PI-paronEd) < tol);
436   if (!extre) return Standard_False;
437   paronEd = (inout) ? 2.*M_PI : 0.;
438   return Standard_True;
439 }
440
441 // case VP is IN <Fi>
442 static Standard_Integer FUN_parondgEINFi(const TopOpeBRep_VPointInter& VP,
443                             const TopoDS_Face& Fe,
444                             const TopoDS_Face& Fi,
445                             const TopoDS_Edge& Ed, 
446                             const TopoDS_Edge& Ec,
447                             Standard_Real& par1OnEd,
448                             Standard_Real& par2OnEd,
449                             TopOpeBRepDS_Transition& T1, 
450                             TopOpeBRepDS_Transition& T2,                               // !s_NOTdgE  
451                             TopoDS_Edge& OOEi, Standard_Real& paronOOEi, TopOpeBRepDS_Transition& TOOEi) // s_TdgEandTOOEi 
452 {
453   Standard_Integer is = VP.ShapeIndex();
454   Standard_Integer ioo = (is == 1) ? 2 : 1;
455   Standard_Boolean iis1 = (is == 1) ? Standard_True : Standard_False;
456
457   // VP is on the restriction of shape <i>
458   // and IN the face <Fi>.
459   Standard_Boolean isVon1 = VP.IsVertexOnS1();
460   Standard_Boolean isVon2 = VP.IsVertexOnS2();
461   if (iis1 && !isVon1)  return s_NOTdgE; 
462   if (!iis1 && !isVon2) return s_NOTdgE;
463   TopoDS_Vertex v;
464   if (iis1) v = TopoDS::Vertex(VP.VertexOnS1());
465   else      v = TopoDS::Vertex(VP.VertexOnS2());
466
467   // p2di and p2de
468   gp_Pnt2d p2de = VP.SurfaceParameters(is);
469   gp_Pnt2d p2di = VP.SurfaceParameters(ioo);
470   
471   gp_Vec ngFe,ngFi,x,a;
472   FUN_GetVectors(Fe,Fi,Ec,p2di,p2de,v,ngFe,ngFi,a,x);  
473
474   // xpu : 24-10-97
475   Standard_Boolean nullx =  FUN_nullx(x);
476   if (nullx) {
477     Standard_Boolean mTOOEi = Standard_False;
478     Standard_Boolean getOOEi = FUN_OOEi(p2di,Fi,OOEi,paronOOEi);
479     if (getOOEi) mTOOEi = FUN_IEcOOEi(v,paronOOEi,OOEi,Ec,TOOEi);
480
481     if (!mTOOEi) return s_NOTdgE;
482     else         return s_TOOEi;
483   }
484   // xpu : 24-10-97
485
486   gp_Vec y;
487   if (Fi.Orientation() == TopAbs_FORWARD) y = ngFi;
488   else                                    y = ngFi.Reversed();
489   gp_Vec z(x^y);
490
491 #ifdef DEB
492   Standard_Boolean trc = Standard_False;
493   if (trc) {
494     gp_Pnt p = BRep_Tool::Pnt(v);
495 #ifdef DRAW
496     TCollection_AsciiString aax("x");     FUN_brep_draw(aax,p,x);
497     TCollection_AsciiString aay("y");     FUN_brep_draw(aay,p,y);
498     TCollection_AsciiString aang("ngFi"); FUN_brep_draw(aang,p,ngFi);
499     TCollection_AsciiString aaa("a");     FUN_brep_draw(aaa,p,a);
500 #endif
501   }
502 #endif
503
504   // parameters on <Ed>
505   Standard_Integer orivine = FUN_tool_orientVinE(v,Ec);
506   gp_Vec nrotation;
507   if (orivine == LAST) nrotation = ngFe;
508   else                 nrotation = ngFe.Reversed();
509   Standard_Boolean complement = (z.Dot(nrotation) < 0.);
510
511   Standard_Boolean T1inout = !complement;
512   if (T1inout) T1.Set(TopAbs_IN,TopAbs_OUT);
513   else T1.Set(TopAbs_OUT,TopAbs_IN); 
514   T2 = T1.Complement();
515
516   Standard_Real par = FUN_getpar(a,x,y,complement);
517   par1OnEd = par;
518   par2OnEd = (par > M_PI) ? par-M_PI : par+M_PI;
519
520   // kpart Ec on Fi :
521   Standard_Boolean changedpar1 = FUN_0or2PI(par1OnEd,T1inout);
522   Standard_Boolean changedpar2 = FUN_0or2PI(par2OnEd,!T1inout);
523   
524   return s_TdgE;
525 }
526
527 static Standard_Boolean FUN_PInDegenEd(const Standard_Real& paronEd, const TopoDS_Edge& Ec)
528 {
529   TopoDS_Vertex vf,vl;
530   TopExp::Vertices(Ec,vf,vl);
531   Standard_Real pf = BRep_Tool::Parameter(vf,Ec);
532   Standard_Real pl = BRep_Tool::Parameter(vl,Ec);
533   Standard_Real tol = Precision::Parametric(Precision::Confusion());
534
535   Standard_Boolean kept = (paronEd < pl-tol) ||  (paronEd > pl+tol);
536   kept = kept || (paronEd < pf-tol) ||  (paronEd > pf+tol);
537   return kept;
538 }
539
540 static Standard_Integer FUN_putInterfonDegenEd
541 (const TopOpeBRep_VPointInter& VP,
542  const TopoDS_Face& F1,
543  const TopoDS_Face& F2,
544  TopTools_DataMapOfShapeListOfShape& DataforDegenEd, // const but for copy &
545  const Handle(TopOpeBRepDS_HDataStructure) HDS,
546  Standard_Integer& is,
547  Standard_Integer& makeinterf, // 1,2,3 : compute interf1, or2 or the 2 interfs
548  TopOpeBRepDS_Transition& Trans1, Standard_Real& param1, 
549  TopOpeBRepDS_Transition& Trans2, Standard_Real& param2,
550  TopoDS_Edge& OOEi, Standard_Real& paronOOEi, TopOpeBRepDS_Transition& TOOEi)
551 {
552   // IMPORTANT : NYI : xpu :
553   // -----------------------
554   // The following process is valid when ngFe is normal to ngFi.
555   // It may be unsufficient elsewhere.
556
557   // (kpart : sphere/box, with one sphere's degenerated edge lying on one boxe's 
558   //  face, IN or ON the face)
559   // 1_ if on2edges :
560   //   Ed append EVI of transition(FACE Fi) on G=(VERTEX,V), S=(EDGE,Ei) par = paronEd.
561   // 2_ else :
562   //   Ed append EVI of transition(FACE Fi) on G=(VERTEX,V), S=(FACE,Fi) par = paronEd1  
563   //   Ed append EVI of transition(FACE Fi) on G=(VERTEX,V), S=(FACE,Fi) par = paronEd2  
564   // with Ed the degenerated edge, Ei of Fi interfers with Ed at vertex V.
565   
566 #ifdef DEB
567   Standard_Boolean traceDSF = TopOpeBRepDS_GettraceDSF();
568   Standard_Boolean traceDEGEN = TopOpeBRepDS_GettraceDEGEN();
569   Standard_Boolean trace = traceDSF || traceDEGEN;
570 #endif
571  
572   TopOpeBRepDS_DataStructure& DS = HDS->ChangeDS();
573   Standard_Boolean isvon1 = VP.IsVertexOnS1();
574   Standard_Boolean isvon2 = VP.IsVertexOnS2();
575   Standard_Boolean isvon12 = isvon1 && isvon2;
576   if (!isvon1 && !isvon2) return s_NOTdgE;
577   Standard_Boolean ison1 = VP.IsOnDomS1();
578   Standard_Boolean ison2 = VP.IsOnDomS2();
579
580   TopoDS_Vertex v1, v2;
581   if (isvon1) v1 = TopoDS::Vertex(VP.VertexOnS1());
582   if (isvon2) v2 = TopoDS::Vertex(VP.VertexOnS2());
583
584 #ifdef DRAW
585   Standard_Boolean trcd = Standard_False;
586   if (trcd && isvon1) {TCollection_AsciiString aa("v1"); FUN_brep_draw(aa,v1);}
587   if (trcd && isvon2) {TCollection_AsciiString aa("v2"); FUN_brep_draw(aa,v2);}
588   if (trcd) FUN_DrawMap(DataforDegenEd);
589 #endif
590
591   // VP is lying on at least one vertex vi
592   // !!! : even if isvon1 && isvon2, v1 and v2 are NOT SAME !
593   Standard_Boolean visvon12 = isvon1 ? HDS->HasSameDomain(v1) : HDS->HasSameDomain(v2);
594   if (visvon12 && !isvon12) {
595     TopoDS_Shape oov;
596     if(isvon1) { 
597       Standard_Boolean ok = FUN_ds_getoov(v1,HDS,oov);
598       if (!ok) return s_NOTdgE;
599       v2 = TopoDS::Vertex(oov); 
600     }
601     else { 
602       Standard_Boolean ok = FUN_ds_getoov(v2,HDS,oov); 
603       if (!ok) return s_NOTdgE;
604       v1 = TopoDS::Vertex(oov);
605     }
606     // now, if visvon12, v1 and v2 are defined
607   }
608
609   TopoDS_Vertex v;
610   Standard_Boolean hasdegened;
611   if (isvon1) v = v1;
612   else        v = v2;
613   hasdegened = DataforDegenEd.IsBound(v);  
614   if (!hasdegened && visvon12) {
615     // DataforDegenEd can either bind v1 or v2.
616     if (isvon1) hasdegened = DataforDegenEd.IsBound(v2);
617     else        hasdegened = DataforDegenEd.IsBound(v1);
618     if (hasdegened) {
619       if (isvon1) v = v2;
620       else        v = v1;
621     }
622   }
623   if (!hasdegened) return s_NOTdgE;
624   
625   Standard_Boolean on2edges = (VP.ShapeIndex() == 3);
626   on2edges = on2edges || visvon12;
627
628   TopTools_ListIteratorOfListOfShape itoflos(DataforDegenEd.Find(v));
629   if (!itoflos.More()) return s_NOTdgE;
630   TopoDS_Edge Ec = TopoDS::Edge(itoflos.Value());
631   itoflos.Next(); if (!itoflos.More()) return s_NOTdgE;
632   TopoDS_Edge Ed = TopoDS::Edge(itoflos.Value());
633     
634   // -----------------------------------------
635   // Fe, Ec, Ed and v are on shape <is>,
636   // Fi, Ei are on shape <ioo> = (is == 1) ? 2 :1
637   // -----------------------------------------
638   TopoDS_Edge e1,e2;
639   Standard_Boolean e1isEd = Standard_False, e2isEd = Standard_False;
640   if (ison1) { e1 = TopoDS::Edge(VP.ArcOnS1()); e1isEd = BRep_Tool::Degenerated(e1); }
641   if (ison2) { e2 = TopoDS::Edge(VP.ArcOnS2()); e2isEd = BRep_Tool::Degenerated(e2); } 
642
643   if (!e1isEd && !e2isEd) return s_NOTdgE; // computes transitions only ONCE
644   is = (e1isEd) ? 1 : 2;
645   Standard_Integer ioo = (is == 1) ? 2 : 1;
646   TopoDS_Face Fe;
647   if (is == 1) Fe = F1;
648   else         Fe = F2;
649   TopoDS_Face Fi;
650   if (ioo == 1) Fi = F1;
651   else          Fi = F2;
652   Standard_Integer iv = 0;
653   
654 #ifdef DEB
655   if (FUN_debnull(Fe)) cout<<"Fe is null"<<endl;
656   if (FUN_debnull(Fi)) cout<<"Fi is null"<<endl;
657   if (FUN_debnull(Ec)) cout<<"Ec is null"<<endl;
658   if (FUN_debnull(Ed)) cout<<"Ed is null"<<endl;
659   if (trace) {
660     TopAbs_Orientation Edori = Ed.Orientation();
661   }
662   Standard_Boolean trace3d = Standard_False;
663 #ifdef DRAW
664   if (trace3d) {TCollection_AsciiString afe("Fe");TCollection_AsciiString afi("Fi");TCollection_AsciiString aec("Ec");
665                 FUN_brep_draw(afe,Fe); FUN_brep_draw(afi,Fi); FUN_brep_draw(aec,Ec);}
666 #endif
667 #endif
668
669   Standard_Integer makeI = s_NOTdgE;
670   // case 1 :
671   // -------
672   if (on2edges) {
673   
674     TopTools_ListOfShape loEi;
675     TopoDS_Vertex vi,ve; // vertex on shape ioo sharing same domain with v
676                          // dummy if !visvon12
677     if (visvon12) { 
678       // if isvon12, we have two choices for <Ei>,
679       // we choose the one for which FUN_parondgEONFi returns True.
680       // (recall that prequesitory : ngFi is normal to ngFe)  
681       if (is == 1) ve = v1;
682       else         ve = v2; 
683       if (ioo == 1) vi = v1;
684       else          vi = v2;      
685       FUN_getEofFwithV(vi,Fi,loEi);
686     }
687     else {
688       if (is == 2) loEi.Append (e1);
689       else loEi.Append (e2);
690     }
691                                     
692     Standard_Real paronEd;
693     TopOpeBRepDS_Transition T; 
694     TopTools_ListIteratorOfListOfShape itloei(loEi);
695     
696     TopoDS_Edge tmpOOEi; Standard_Real tmpparonOOEi; TopOpeBRepDS_Transition tmpTOOEi;
697     for (;itloei.More(); itloei.Next()) {
698
699 #ifdef DEB
700       if (FUN_debnull(itloei.Value())) cout<<"Ei is null"<<endl;
701 #ifdef DRAW
702       if (trace3d) {TCollection_AsciiString aa("ecur");FUN_brep_draw(aa,itloei.Value());}
703 #endif
704       TopAbs_ShapeEnum typ = itloei.Value().ShapeType();
705       if (typ != TopAbs_EDGE) cout<<"shape not edge"<<endl;
706 #endif
707
708       TopoDS_Edge Ei = TopoDS::Edge(itloei.Value());
709       if (visvon12) v = ve;
710       makeI = FUN_parondgEONFi (VP,visvon12,v,vi,
711                                 is,Fe,Fi,Ed,Ei,Ec,paronEd,T,
712                                 tmpOOEi,tmpparonOOEi,tmpTOOEi); 
713       if (makeI == s_NOTdgE) continue;
714       if (makeI == s_TOOEi)  {
715         tmpOOEi = OOEi; tmpparonOOEi = paronOOEi; tmpTOOEi = TOOEi;
716         continue;
717       }
718
719       Standard_Boolean keepI = FUN_PInDegenEd(paronEd,Ed);
720       if (keepI) {
721         makeinterf = 1;
722         param1 = paronEd;
723         Trans1.Set(T.Before(), T.After());
724       }
725     } // itloei
726     
727   }
728   // case 2 :
729   // -------
730   else {
731     Standard_Real paronEd1, paronEd2;
732     TopOpeBRepDS_Transition T1, T2;
733
734     makeI = FUN_parondgEINFi (VP,Fe,Fi,Ed,Ec,paronEd1,paronEd2,T1,T2,
735                               OOEi,paronOOEi,TOOEi);
736     if (makeI == s_NOTdgE) return makeI;
737     if (makeI == s_TOOEi)  return makeI;
738
739     Standard_Boolean keepI1 = FUN_PInDegenEd(paronEd1,Ed);
740     Standard_Boolean keepI2 = FUN_PInDegenEd(paronEd2,Ed);
741
742     if (keepI1) {
743       makeinterf = 1;
744       param1 = paronEd1;
745       Trans1.Set(T1.Before(), T1.After());
746     }
747     if (keepI2) {
748       makeinterf = (makeinterf == 1) ? 3 : 2;
749       param2 = paronEd2;
750       Trans2.Set(T2.Before(), T2.After()); 
751     }      
752   }  
753   return makeI;
754 }
755
756
757 static  Standard_Boolean FUN_getEc
758 (const TopOpeBRep_VPointInter& VP,
759  TopTools_DataMapOfShapeListOfShape& DataforDegenEd, 
760  const Handle(TopOpeBRepDS_HDataStructure)& HDS, TopoDS_Shape& Ec)
761 {
762   TopoDS_Vertex v;
763   Standard_Boolean isvon1 = VP.IsVertexOnS1();
764   Standard_Boolean isvon2 = VP.IsVertexOnS2();
765   if (!isvon1 && !isvon2) return Standard_False;
766   if (isvon1) v = TopoDS::Vertex(VP.VertexOnS1());
767   if (isvon2) v = TopoDS::Vertex(VP.VertexOnS2());
768   Standard_Boolean inmap = DataforDegenEd.IsBound(v);
769   if  (!inmap) {
770     if (HDS->HasSameDomain(v)) 
771       {Standard_Boolean ok = FUN_ds_getoov(v,HDS,v); if (!ok) return Standard_False;}
772     inmap = DataforDegenEd.IsBound(v);
773     if (!inmap) return s_NOTdgE;
774   }   
775   const TopTools_ListOfShape& los = DataforDegenEd.Find(v);
776   if (los.Extent() < 2) return Standard_False;
777   Ec = los.First();    
778   return Standard_True;
779 }
780 */
781 Standard_EXPORT void FUN_FillVof12
782 (const TopOpeBRep_LineInter& L,
783  TopOpeBRepDS_PDataStructure pDS)
784 {
785   TopOpeBRep_VPointInterIterator itvp(L);
786   for (; itvp.More(); itvp.Next()) {
787     const TopOpeBRep_VPointInter& vp = itvp.CurrentVP();
788     Standard_Integer sind = vp.ShapeIndex();
789     if (sind != 3) continue;
790     Standard_Boolean isvon1 = vp.IsVertexOnS1();
791     Standard_Boolean isvon2 = vp.IsVertexOnS2();
792     Standard_Boolean isvon12 = isvon1 && isvon2;
793     if (!isvon12) continue;
794     const TopoDS_Shape& v1 = vp.VertexOnS1();
795     const TopoDS_Shape& v2 = vp.VertexOnS2();
796     pDS->FillShapesSameDomain(v1,v2);
797   }      
798 }
799
800 static void FUN_addmapve(TopTools_DataMapOfShapeListOfShape& mapve, const TopoDS_Shape& v, const TopoDS_Shape& e)
801 {
802   Standard_Boolean visb = mapve.IsBound(v);
803   Standard_Boolean eisb = mapve.IsBound(e);
804   if      (!visb && !eisb) 
805     {TopTools_ListOfShape le;le.Append(e);mapve.Bind(v,le); 
806      TopTools_ListOfShape lv;lv.Append(v);mapve.Bind(e,lv);}
807   else if (visb  && !eisb) 
808     {mapve.ChangeFind(v).Append(e); 
809      TopTools_ListOfShape lv;lv.Append(v);mapve.Bind(e,lv);}
810   else if (!visb &&  eisb) 
811     {mapve.ChangeFind(e).Append(v); 
812      TopTools_ListOfShape le;le.Append(e);mapve.Bind(v,le);}
813   else {
814     Standard_Boolean found = Standard_False;
815     TopTools_ListIteratorOfListOfShape it(mapve.Find(v));
816     for (; it.More(); it.Next())
817       if (it.Value().IsSame(e)) {found = Standard_True; break;}
818     if (!found) {mapve.ChangeFind(v).Append(e); mapve.ChangeFind(e).Append(v);}             
819   }
820 }
821
822 Standard_EXPORT void FUN_GetdgData(TopOpeBRepDS_PDataStructure& pDS,const TopOpeBRep_LineInter& L,
823                                    const TopoDS_Face& F1,const TopoDS_Face& F2, TopTools_DataMapOfShapeListOfShape& datamap)
824 {
825   // purpose : fills up map datamap = {(v, (closinge,degeneratede))}
826   //           with shapes with same rank
827
828   TopTools_DataMapOfShapeInteger shaperk;          // rkshape = {shape,rank=1,2}
829   TopTools_DataMapOfShapeListOfShape mapvec, mapved; // mapvec = {(v,lec),(ec,lv)}, mapved = {(v,led),(ed,lv)}
830   TopTools_DataMapOfShapeShape mapvvsd;          // mapvvsd = {(v,v)}
831
832   TopOpeBRep_VPointInterIterator itvp(L);
833   for (; itvp.More(); itvp.Next()) {
834     const TopOpeBRep_VPointInter& vp = itvp.CurrentVP();
835     Standard_Boolean isv1 = vp.IsVertex(1), isv2 = vp.IsVertex(2);
836     Standard_Boolean isv = isv1 || isv2;
837     if (!isv) continue;
838
839     Standard_Integer sind = vp.ShapeIndex();        
840     TopoDS_Shape v = isv1 ? vp.Vertex(1): vp.Vertex(2);
841     for (Standard_Integer i = 1; i <= 2; i++) {
842       TopoDS_Face f = (i == 1)? F1: F2;
843
844       Standard_Boolean isvi = vp.IsVertex(i);
845       if (isvi) {
846         v = vp.Vertex(i);
847         shaperk.Bind(v,i);      
848       }
849
850       TopoDS_Edge e; Standard_Boolean isdg, iscl; isdg = iscl = Standard_False;
851       Standard_Boolean ison = (sind == i)||(sind == 3);
852       if (ison) {
853         e = TopoDS::Edge( vp.Edge(i) );
854         shaperk.Bind(e,i);      
855
856         isdg = BRep_Tool::Degenerated(e);    
857         if (!isdg) iscl = TopOpeBRepTool_ShapeTool::Closed(e,f);
858         if (isdg) FUN_addmapve(mapved,v,e);
859         if (iscl) FUN_addmapve(mapvec,v,e);
860       }//ison      
861     }//i = 1..2
862   }//itvp   
863
864   // filling up map mapvvsd
865   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mapved);
866   for (; itm.More(); itm.Next()){
867     const TopoDS_Shape& v = itm.Key();
868     if (v.ShapeType() != TopAbs_VERTEX) continue;
869     Standard_Integer rkv = shaperk.Find(v);
870
871     TopTools_ListIteratorOfListOfShape ite(itm.Value());
872     for (; ite.More(); ite.Next()){
873       const TopoDS_Edge& e = TopoDS::Edge( ite.Value() );
874       Standard_Integer rke = shaperk.Find(e);
875       if (rke != rkv) {
876         TopExp_Explorer ex(e, TopAbs_VERTEX);
877         const TopoDS_Shape& vsd = ex.Current(); 
878         // recall : if vsd is not bound in shaperk,
879         //          it is not bound in <L> either
880         mapvvsd.Bind(v,vsd); mapvvsd.Bind(vsd,v);
881       }      
882     }
883   }//itm(mapved)
884   
885   itm.Initialize(mapved);
886   for (; itm.More(); itm.Next()){
887     const TopoDS_Shape& dge = itm.Key();
888     Standard_Integer rk = shaperk.Find(dge);
889     TopoDS_Face f = (rk == 1)? F1: F2;
890     if (dge.ShapeType() != TopAbs_EDGE) continue;
891
892     TopExp_Explorer ex(dge, TopAbs_VERTEX);
893     const TopoDS_Vertex& v = TopoDS::Vertex( ex.Current() ); 
894     Standard_Integer rkv = shaperk.Find(v);
895     Standard_Boolean hassd = mapvvsd.IsBound(v);
896     TopoDS_Vertex vsd; if (hassd) vsd = TopoDS::Vertex( mapvvsd.Find(v) );
897     
898     Standard_Boolean hasecl = Standard_False; TopoDS_Shape cle;
899     Standard_Boolean isbv = mapvec.IsBound(v), isbvsd= hassd ? mapvec.IsBound(vsd) : Standard_False;
900     if (!isbv && !isbvsd) {
901       // **************************************************
902       // interference with closing edge is not found,
903       // adding new information to the ds
904       // **************************************************
905       TopTools_IndexedDataMapOfShapeListOfShape mapve; TopExp::MapShapesAndAncestors(f,TopAbs_VERTEX,TopAbs_EDGE,mapve);
906       TopTools_ListIteratorOfListOfShape iteds(mapve.FindFromKey(v));
907       for (; iteds.More(); iteds.Next()){
908         const TopoDS_Edge& ee = TopoDS::Edge(iteds.Value());
909         if (ee.IsSame(dge)) continue;
910         Standard_Boolean iscl = TopOpeBRepTool_ShapeTool::Closed(ee,f);
911         if (!iscl) continue;
912         isbv = Standard_True; cle = ee; hasecl = Standard_True; break;
913       }
914     }
915     if (!hasecl && (isbv || isbvsd)) {
916       TopoDS_Vertex vv = isbv ? v : vsd;
917       TopTools_ListIteratorOfListOfShape ite;
918       if (isbv) ite.Initialize(mapvec.Find(v));
919       for (; ite.More(); ite.Next()){
920         const TopoDS_Shape& e = ite.Value();
921         Standard_Integer rke = shaperk.Find(e);
922         if (rke == rk) {cle = e; hasecl = Standard_True; break;}
923       }
924     }
925     if (!hasecl) continue;
926
927     TopoDS_Vertex vv = (rkv == rk) ? v : vsd;
928     TopTools_ListOfShape ls; ls.Append(cle); ls.Append(dge); 
929     datamap.Bind(vv,ls);
930   }//itm(mapved)
931
932   // filling sdm shapes
933   TopTools_DataMapIteratorOfDataMapOfShapeShape ittm(mapvvsd);
934   for (; ittm.More(); ittm.Next()){
935     const TopoDS_Vertex& v  = TopoDS::Vertex( ittm.Value() );
936     const TopoDS_Vertex& ov = TopoDS::Vertex( mapvvsd.Find(v) );
937     Standard_Integer rkv = shaperk.Find(v);
938     TopoDS_Vertex v1 = (rkv == 1) ? v : ov;
939     TopoDS_Vertex v2 = (rkv == 2) ? v : ov;
940     pDS->FillShapesSameDomain(v1,v2);
941   }
942 }//FUN_GetdgData
943
944 #define NOI      (0)
945 #define MKI1     (1)
946 #define MKI2     (2)
947 #define MKI12    (3)
948
949 static Standard_Integer FUN_putInterfonDegenEd
950 (const TopOpeBRep_VPointInter& VP,
951  const TopoDS_Face& F1, const TopoDS_Face& F2,
952  TopTools_DataMapOfShapeListOfShape& DataforDegenEd, // const but for copy &
953  Handle(TopOpeBRepDS_HDataStructure)& HDS,
954  Standard_Integer& is, TopoDS_Edge& dgE,
955 // Standard_Integer& makeinterf, // 1,2,3 : compute interf1, or2 or the 2 interfs
956  Standard_Integer& , // 1,2,3 : compute interf1, or2 or the 2 interfs
957  TopOpeBRepDS_Transition& Trans1, Standard_Real& param1, 
958  TopOpeBRepDS_Transition& Trans2, Standard_Real& param2,
959  TopoDS_Edge& OOEi, Standard_Real& paronOOEi, Standard_Boolean hasOOEi,
960  Standard_Boolean& isT2d)
961 {  
962   OOEi.Nullify();
963
964   Standard_Boolean on3 = (VP.ShapeIndex() == 3);// <VP> is shared by edge of 1 and edge of 2.
965   Standard_Boolean onv12 = VP.IsVertexOnS1() && VP.IsVertexOnS2();
966
967   const TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
968   TopoDS_Vertex v; Standard_Integer rkv = 0;
969 //  Standard_Integer iv;
970   TopoDS_Vertex ov;
971   for (Standard_Integer ShapeIndex = 1; ShapeIndex <= 2; ShapeIndex++) {
972     Standard_Boolean isv = (ShapeIndex == 1) ? (VP.IsVertexOnS1()) : (VP.IsVertexOnS2());
973     if (!isv) continue;
974     v = (ShapeIndex == 1) ? TopoDS::Vertex(VP.VertexOnS1()) : TopoDS::Vertex(VP.VertexOnS2());
975     Standard_Boolean hasdegened = DataforDegenEd.IsBound(v);  
976     if (!hasdegened) continue;
977     rkv = ShapeIndex; break;
978   }//ShapeIndex = 1..2
979   if (rkv == 0) return NOI;// compute interference once only.
980   Standard_Boolean isvsd = HDS->HasSameDomain(v);
981     
982   // edges dge, cle on shape<rkdg>
983   const TopTools_ListOfShape& loe = DataforDegenEd.Find(v);
984   const TopoDS_Edge& cle = TopoDS::Edge(loe.First());
985   const TopoDS_Edge& dge = TopoDS::Edge(loe.Last()); dgE = dge;
986   Standard_Integer rkdg = 0;
987   if (BDS.HasShape(dge)) rkdg = BDS.AncestorRank(dge); 
988   else {
989     Standard_Boolean vindge = FUN_tool_inS(v,dge);
990     if (vindge) rkdg = rkv;
991     else        rkdg = (rkv == 1) ? 2 : 1;
992   }
993   is = rkdg;
994   Standard_Integer rki = (rkdg == 1) ? 2 : 1;
995
996   gp_Pnt2d uvi; TopoDS_Face fi,f; 
997   { 
998     //     Standard_Real u,v; 
999     //     if (rki == 1) VP.ParametersOnS1(u,v); 
1000     //     else          VP.ParametersOnS2(u,v);
1001     //     uvi = gp_Pnt2d(u,v);
1002     // modified by NIZHNY-MKK  Tue Nov 21 17:44:56 2000.BEGIN
1003     Standard_Real upar, vpar; 
1004     if (rki == 1) VP.ParametersOnS1(upar, vpar);
1005     else          VP.ParametersOnS2(upar, vpar);
1006     uvi = gp_Pnt2d(upar, vpar);
1007     // modified by NIZHNY-MKK  Tue Nov 21 17:44:59 2000.END
1008     fi = (rki == 1)  ? F1 : F2;
1009     f  = (rkdg == 1) ? F1 : F2;
1010   }
1011   TopOpeBRepTool_mkTondgE mktdg;
1012   Standard_Boolean ok = mktdg.Initialize(dge, f, uvi, fi);
1013   if (!ok) return NOI;
1014   ok = mktdg.SetclE(cle);
1015   if (!ok) return NOI;
1016
1017   if (onv12 || isvsd) {
1018     if (onv12)
1019       ov = (rkv == 2) ? TopoDS::Vertex(VP.VertexOnS1()) : TopoDS::Vertex(VP.VertexOnS2());
1020     else     {
1021       // modified by NIZHNY-MKK  Tue Nov 21 17:45:46 2000.BEGIN
1022       //       Standard_Boolean ok = FUN_ds_getoov(v,HDS,ov); 
1023       //       if (!ok) return Standard_False;
1024       Standard_Boolean found = FUN_ds_getoov(v,HDS,ov); 
1025       if (!found) return NOI;
1026       // modified by NIZHNY-MKK  Tue Nov 21 17:45:50 2000.END
1027     }
1028     if (rkv != rkdg) {TopoDS_Vertex tmp = v; v = ov; ov = tmp; rkv = rkdg;} // ensure v is vertex of dge
1029   }
1030
1031   Standard_Boolean setrest = Standard_False;
1032   Standard_Integer mkt = 0; Standard_Real par1,par2;
1033   if (on3) {
1034     TopoDS_Edge ei = (rki == 1) ? TopoDS::Edge(VP.ArcOnS1()) : TopoDS::Edge(VP.ArcOnS2());
1035     Standard_Real pari = (rki == 1) ? VP.ParameterOnArc1() : VP.ParameterOnArc2();
1036     // if okrest, ei interfers in the compute of transitions for dge
1037     setrest = mktdg.SetRest(pari,ei);
1038     ok = mktdg.MkTonE(ei,mkt, par1,par2);  
1039     if ((!ok) || (mkt == NOI)) return NOI;      
1040     OOEi = ei; paronOOEi = pari; hasOOEi = Standard_True;
1041   }//on3
1042   else     {
1043     // modified by NIZHNY-MKK  Tue Nov 21 17:31:14 2000.BEGIN
1044     // This search, compute and check the data which was not computed by intersector.
1045     if((rki == 1 && VP.IsOnDomS1()) || (rki == 2 && VP.IsOnDomS2())) {
1046       TopoDS_Edge ei = (rki == 1) ? TopoDS::Edge(VP.ArcOnS1()) : TopoDS::Edge(VP.ArcOnS2());
1047       Standard_Real pari = (rki == 1) ? VP.ParameterOnArc1() : VP.ParameterOnArc2();
1048       mktdg.SetRest(pari,ei);
1049       ok = mktdg.MkTonE(ei,mkt, par1,par2);
1050       if(ok && mkt!=NOI) {
1051         OOEi = ei; paronOOEi = pari; hasOOEi = Standard_True;
1052       }
1053     }
1054     else {
1055       Standard_Boolean edgefound = Standard_False;
1056       TopoDS_Face aFace = (rki == 1) ? F1 : F2;
1057       TopTools_IndexedDataMapOfShapeListOfShape aMapOfVertexEdges;
1058       TopExp::MapShapesAndAncestors(aFace, TopAbs_VERTEX, TopAbs_EDGE, aMapOfVertexEdges);
1059       TopoDS_Vertex aVertex;
1060       Standard_Boolean vertexfound = local_FindVertex(VP, aMapOfVertexEdges, aVertex);
1061       
1062       if(vertexfound && !aVertex.IsNull()) {
1063         TopTools_ListIteratorOfListOfShape anIt(aMapOfVertexEdges.FindFromKey(aVertex));
1064         for(; !edgefound && anIt.More(); anIt.Next()) {   
1065           const TopoDS_Edge& ei = TopoDS::Edge(anIt.Value());
1066           Standard_Real pari = BRep_Tool::Parameter(aVertex, ei);
1067           if(!BRep_Tool::Degenerated(ei)) {
1068             edgefound = !local_FindTreatedEdgeOnVertex(ei, aVertex);
1069           }
1070           if(edgefound) {
1071             mktdg.SetRest(pari,ei);
1072             ok = mktdg.MkTonE(ei,mkt, par1,par2);
1073             if(ok && mkt!=NOI) {
1074               OOEi = ei; paronOOEi = pari; hasOOEi = Standard_True;
1075             }
1076             if(!aMapOfTreatedVertexListOfEdge.IsBound(aVertex)) {
1077               TopTools_ListOfShape thelist;
1078               aMapOfTreatedVertexListOfEdge.Bind(aVertex, thelist);
1079             }
1080             aMapOfTreatedVertexListOfEdge(aVertex).Append(ei);
1081           }
1082         }
1083       }
1084       if(!edgefound) {
1085         ok = mktdg.MkTonE(mkt, par1,par2);
1086       }
1087     }
1088     // modified by NIZHNY-MKK  Tue Nov 21 17:31:36 2000.END
1089     if ((!ok) || (mkt == NOI)) return NOI;
1090   }
1091   isT2d = mktdg.IsT2d();
1092
1093   if ((mkt == MKI1)||(mkt == MKI12)) {Trans1.Set(TopAbs_FORWARD); param1 = par1;}
1094   if ((mkt == MKI2)||(mkt == MKI12)) {Trans2.Set(TopAbs_REVERSED); param2 = par2;}
1095   return mkt;
1096 //  **********   iterate on restrictions of fi  **********
1097 //  TopTools_ListOfShape lei; mktdg.GetAllRest(lei);
1098 //  TopTools_ListIteratorOfListOfShape ite(lei);
1099 //  for (; ite.More(); ite.Next()){
1100 //    Standard_Boolean oki = mktdg.MkTonE(ei,mkt,par1,par2);
1101 //    ... NYI
1102 //  }
1103 }//FUN_putInterfonDegenEd
1104
1105 //=======================================================================
1106 //function : ProcessVPondgE
1107 //purpose  : SUPPLYING INTPATCH when a degenerated edge is touched.
1108 //=======================================================================
1109
1110 #define s_NOIdgE       (0) // do NOT compute any interference
1111 #define s_IdgE         (1) // compute interference(s) on dgE
1112 #define s_IOOEi        (2) // compute interference(s) on OOEi
1113
1114 Standard_Boolean TopOpeBRep_FacesFiller::ProcessVPondgE
1115 (const TopOpeBRep_VPointInter& VP,
1116  const Standard_Integer ShapeIndex, 
1117  TopOpeBRepDS_Kind& PVKind, Standard_Integer& PVIndex, // out
1118  Standard_Boolean& EPIfound, Handle(TopOpeBRepDS_Interference)& IEPI, // out 
1119  Standard_Boolean& CPIfound, Handle(TopOpeBRepDS_Interference)& ICPI) // out
1120 {
1121 #ifdef DEB
1122   Standard_Boolean traceDSF = TopOpeBRepDS_GettraceDSF();
1123   Standard_Boolean traceDEGEN = TopOpeBRepDS_GettraceDEGEN();
1124 #endif
1125
1126   if (PVIndex == 0) FUN_VPIndex ((*this),(*myLine),VP,ShapeIndex,myHDS,myDSCIL, //in
1127                                  PVKind,PVIndex, // out
1128                                  EPIfound,IEPI,  // out
1129                                  CPIfound,ICPI,  // out  
1130                                  M_FINDVP);
1131  
1132   // kpart : sphere/box, with one sphere's degenerated edge lying on one boxe's 
1133   // face, IN or ON the face
1134   // if (mIdgEorOOEi), adds interferences on degenerated edge
1135
1136   // If interferences should be added, finds out <VP>'s geometry
1137   // in existing interferences (see out parameters <EPIfound>..);
1138   // adds a new point/vertex to the DS if necessary.
1139
1140
1141   Standard_Boolean hasOOEi=Standard_False; TopoDS_Edge OOEi; Standard_Real parOOEi; 
1142   TopOpeBRepDS_Transition T1ondg, T2ondg; 
1143   Standard_Integer rankdg=0, Iiondg=0; 
1144   Standard_Real par1ondg, par2ondg;  
1145   Standard_Boolean hasdgdata = !myDataforDegenEd.IsEmpty();
1146   if (!hasdgdata) {
1147     return Standard_False; 
1148   } 
1149
1150   // modified by NIZHNY-MKK  Tue Nov 21 17:35:29 2000
1151   local_ReduceMapOfTreatedVertices(myLine);
1152
1153   Standard_Boolean isT2d = Standard_False; TopoDS_Edge dgEd;   
1154   Standard_Integer makeI = FUN_putInterfonDegenEd (VP,myF1,myF2,myDataforDegenEd,myHDS,
1155                                       rankdg,dgEd, Iiondg,T1ondg,par1ondg,T2ondg,par2ondg,
1156                                       OOEi,parOOEi,hasOOEi, isT2d);
1157   if (makeI == NOI) {
1158     return Standard_False; 
1159   }  
1160
1161   // -------------------------------------------------------------------
1162   //             --- DS geometry Management --- 
1163   // -------------------------------------------------------------------
1164   
1165   if (PVIndex == 0) FUN_VPIndex ((*this),(*myLine),VP,ShapeIndex,myHDS,myDSCIL, //in
1166                                  PVKind,PVIndex, // out
1167                                  EPIfound,IEPI,  // out
1168                                  CPIfound,ICPI,  // out
1169                                  M_MKNEWVP);
1170
1171   // -------------------------------------------------------------------
1172   //             --- EVI on degenerated edge ---
1173   //             ---       on OOEi           ---
1174   // -------------------------------------------------------------------    
1175
1176   Standard_Integer rankFi = (rankdg == 1) ? 2 : 1;
1177 //  TopoDS_Shape dgEd = VP.Edge(rankdg);
1178   TopoDS_Face Fi;
1179   if (rankFi == 1) Fi = myF1;
1180   else             Fi = myF2;
1181   Standard_Integer iFi = myDS->AddShape(Fi,rankFi);
1182 #ifdef DEB
1183   Standard_Integer iEd =
1184 #endif
1185             myDS->AddShape(dgEd,rankdg);
1186   Standard_Integer iOOEi = 0;
1187   if (hasOOEi) iOOEi = myDS->AddShape(OOEi,rankFi);
1188
1189 #ifdef DEB
1190   Standard_Boolean trace = traceDSF || traceDEGEN;
1191   if (trace) cout<<" VP is on degenerated edge "<<iEd<<" :"<<endl;
1192 #endif
1193   Standard_Integer rkv = myDS->AncestorRank(myDS->Shape(PVIndex));
1194
1195   if ((makeI == MKI1)||(makeI == MKI12)) {
1196     T1ondg.Index(iFi);
1197     Standard_Boolean isvertex1 = (rkv == 1);
1198
1199     if (hasOOEi) {
1200       Handle(TopOpeBRepDS_Interference) EVI1i = ::MakeEPVInterference(T1ondg,iOOEi,PVIndex,par1ondg,
1201                                           TopOpeBRepDS_VERTEX,TopOpeBRepDS_EDGE,isvertex1);
1202       myHDS->StoreInterference(EVI1i,dgEd);
1203     }
1204     if (!isT2d) {      
1205       Handle(TopOpeBRepDS_Interference) EVI1 = ::MakeEPVInterference(T1ondg,iFi,PVIndex,par1ondg,
1206                                          TopOpeBRepDS_VERTEX,TopOpeBRepDS_FACE,isvertex1);
1207       myHDS->StoreInterference(EVI1,dgEd);
1208     }
1209   }
1210   if ((makeI == MKI2)||(makeI == MKI12)) {
1211     T2ondg.Index(iFi);
1212     Standard_Boolean isvertex2 = (rkv == 2);
1213
1214     if (hasOOEi) {
1215       Handle(TopOpeBRepDS_Interference) EVI2i = ::MakeEPVInterference(T2ondg,iOOEi,PVIndex,par2ondg,
1216                                           TopOpeBRepDS_VERTEX,TopOpeBRepDS_EDGE,isvertex2);
1217       myHDS->StoreInterference(EVI2i,dgEd);
1218     }
1219     if (!isT2d) {      
1220       Handle(TopOpeBRepDS_Interference) EVI2 = ::MakeEPVInterference(T2ondg,iFi,PVIndex,par2ondg,
1221                                          TopOpeBRepDS_VERTEX,TopOpeBRepDS_FACE,isvertex2);
1222       myHDS->StoreInterference(EVI2,dgEd);
1223     }
1224   }
1225
1226   return Standard_True;  
1227 } // ProcessVPondgE
1228
1229
1230 // modified by NIZHNY-MKK  Tue Nov 21 17:32:52 2000.BEGIN
1231 static Standard_Boolean local_FindTreatedEdgeOnVertex(const TopoDS_Edge& theEdge,
1232                                                 const TopoDS_Vertex& theVertex) {
1233   Standard_Boolean found = Standard_False;
1234   if(aMapOfTreatedVertexListOfEdge.IsBound(theVertex)) {
1235     TopTools_ListIteratorOfListOfShape anIt(aMapOfTreatedVertexListOfEdge(theVertex));
1236     for(; !found && anIt.More(); anIt.Next()) {
1237       if(theEdge.IsSame(anIt.Value())) {
1238         found = Standard_True;
1239       }
1240     }
1241   }
1242   return found;
1243 }
1244
1245 static Standard_Boolean local_FindVertex(const TopOpeBRep_VPointInter& theVP,
1246                                          const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfVertexEdges,
1247                                          TopoDS_Vertex& theVertex) {
1248   gp_Pnt aVPPoint = theVP.Value();
1249   Standard_Real aVPTolerance = theVP.Tolerance();
1250   Standard_Boolean vertexfound = Standard_False;
1251   for(Standard_Integer itVertex=1; !vertexfound && itVertex<=theMapOfVertexEdges.Extent(); itVertex++) {
1252     theVertex = TopoDS::Vertex(theMapOfVertexEdges.FindKey(itVertex));
1253     gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
1254     if(aVPPoint.IsEqual(aPoint, aVPTolerance)) {
1255         vertexfound = Standard_True;
1256       }
1257   }
1258   return vertexfound;
1259 }
1260
1261 static void local_ReduceMapOfTreatedVertices(const TopOpeBRep_PLineInter& theCurrentLine) {
1262
1263   if(localCurrentLine==NULL) {
1264     localCurrentLine = theCurrentLine;
1265     aMapOfTreatedVertexListOfEdge.Clear();
1266   }
1267   else {
1268     if(localCurrentLine != theCurrentLine) {
1269       localCurrentLine = theCurrentLine;
1270       aMapOfTreatedVertexListOfEdge.Clear();
1271     }
1272   }
1273 }
1274 // modified by NIZHNY-MKK  Tue Nov 21 17:32:55 2000.END