84062a849ebdfb7560bb892394bae73bc12f49e6
[occt.git] / src / TopOpeBRep / TopOpeBRep_vpr.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 <Standard_DomainError.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom_Curve.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Precision.hxx>
33 #include <TopoDS.hxx>
34 #include <TopExp.hxx>
35 #include <BRep_Tool.hxx>
36 #include <gp_Vec.hxx>
37
38 #include <TopOpeBRepTool_EXPORT.hxx>
39 #include <TopOpeBRepTool_SC.hxx>
40 #include <TopOpeBRepTool_TOOL.hxx>
41 #include <TopOpeBRepTool_ShapeTool.hxx>
42 #include <TopOpeBRepTool_makeTransition.hxx>
43
44 #include <TopOpeBRepDS_define.hxx>
45 #include <TopOpeBRepDS_EXPORT.hxx>
46 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
47 #include <TopOpeBRepDS_Config.hxx>
48 #include <TopOpeBRepDS_Curve.hxx>
49 #include <TopOpeBRepDS_PointIterator.hxx>
50 #include <TopOpeBRepDS_Dumper.hxx>
51
52 #include <TopOpeBRep_define.hxx>
53 #include <TopOpeBRep_FFTransitionTool.hxx>
54 #include <TopOpeBRep_PointGeomTool.hxx>
55 #include <TopOpeBRep.hxx>
56
57 #define M_ON(st)       (st == TopAbs_ON) 
58 #define M_UNKNOWN(st)  (st == TopAbs_UNKNOWN) 
59 #define M_REVERSED(st) (st == TopAbs_REVERSED) 
60
61 #ifdef DEB
62 extern Standard_Boolean TopOpeBRepDS_GettraceISTO();
63 extern Standard_Boolean TopOpeBRepDS_GettraceDSF();
64 extern Standard_Boolean TopOpeBRepDS_GettraceDSP();
65 extern Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer i);
66 extern Standard_Boolean TopOpeBRep_GettraceNVP(Standard_Integer a,Standard_Integer b,Standard_Integer c,Standard_Integer d,Standard_Integer e);
67 extern Standard_Boolean GLOBAL_bvpr = Standard_False;void debvpr(){};
68 void debvprmess(Standard_Integer f1,Standard_Integer f2,Standard_Integer il,Standard_Integer vp,Standard_Integer si)
69 {cout<<"f1,f2,il,vp,si : "<<f1<<","<<f2<<","<<il<<","<<vp<<","<<si<<endl;cout.flush();debvpr();}
70 void debpoint(Standard_Integer i) {cout<<"+ debpoint"<<i<<endl;}
71 void debvertex(Standard_Integer i){cout<<"+ debvertex"<<i<<endl;}
72
73 Standard_EXPORT void debarc(const Standard_Integer i)   {cout<<"+ debarc "<<i<<endl;}
74 Standard_EXPORT void debooarc(const Standard_Integer i) {cout<<"+ debooarc "<<i<<endl;}
75 #endif
76
77 Standard_EXPORT Standard_Boolean FDS_LOIinfsup(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& E,const Standard_Real pE,const Standard_Integer GIP,
78                                     const TopOpeBRepDS_ListOfInterference& LOI, Standard_Real& pbef, Standard_Real& paft, Standard_Boolean& isonboundper);
79 Standard_EXPORT Standard_Boolean FUNBREP_topokpart
80 (const Handle(TopOpeBRepDS_Interference)& Ifound,const TopOpeBRepDS_ListOfInterference& DSCIL,
81  const TopOpeBRep_LineInter& L,const TopOpeBRep_VPointInter& VP,
82  const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Shape& E,const TopoDS_Shape& F,const Standard_Real toluv,
83  Standard_Real& parline,TopOpeBRepDS_Transition& transLine);
84
85 //-----------------------------------------------------------------------
86 // Search, among a list of interferences accessed by the iterator <IT>,
87 // a geometry whose parameter on edge point is identical to <par>.
88 // return True if such an interference has been found, False else.
89 // if True, iterator <IT> points (by the Value() method) on the first 
90 // interference found.
91 //-----------------------------------------------------------------------
92
93 Standard_EXPORT Standard_Boolean FUN_GetGonParameter
94 (TopOpeBRepDS_ListIteratorOfListOfInterference& it, const Standard_Real& par, const Standard_Real& tolp,
95  Standard_Integer& G, TopOpeBRepDS_Kind& GT)
96 {
97   while (it.More()) {
98     const Handle(TopOpeBRepDS_Interference)& I = it.Value();
99     Standard_Real ipar; Standard_Boolean haspar = FDS_Parameter(I,ipar);
100     if (!haspar) {it.Next(); continue;}
101     Standard_Boolean samepar = (Abs(par-ipar) < tolp);
102     if (!samepar){it.Next(); continue;}
103     TopOpeBRepDS_Kind ST; Standard_Integer S; FDS_data(I,GT,G,ST,S);
104     return Standard_True;
105   }
106   return Standard_False;
107 }   
108
109 static Standard_Boolean FUN_INlos(const TopoDS_Shape& S, const TopTools_ListOfShape& loS)
110 {
111   TopTools_ListIteratorOfListOfShape it(loS);
112   for (; it.More(); it.Next())
113     if (it.Value().IsSame(S)) return Standard_True;
114   return Standard_False;
115 }
116  
117 //=======================================================================
118 //function : ProcessVPIonR
119 //purpose  : 
120 //=======================================================================
121
122 void TopOpeBRep_FacesFiller::ProcessVPIonR
123 (TopOpeBRep_VPointInterIterator& VPI,
124  const TopOpeBRepDS_Transition& Trans,
125  const TopoDS_Shape& Face,
126  const Standard_Integer ShapeIndex) //1,2
127 {
128   const TopOpeBRep_VPointInter& VP = VPI.CurrentVP();
129   ProcessVPonR(VP,Trans,Face,ShapeIndex);
130 } // ProcessVPIonR
131
132 //-----------------------------------------------------------------------
133 static void FUN_transForWL
134 (const TopOpeBRep_LineInter& L,
135  const Standard_Integer iVP,
136  const Standard_Integer ShapeIndex,
137  TopOpeBRepDS_Transition& transLine)
138 //-----------------------------------------------------------------------
139 {
140   // premier VP avec indetermine : on prend le complement 
141   // du suivant determine
142   TopOpeBRep_VPointInterIterator VPIbis;
143   for (VPIbis.Init(L); 
144        VPIbis.More(); VPIbis.Next()) {
145     const TopOpeBRep_VPointInter& VPbis = VPIbis.CurrentVP();
146     Standard_Boolean tokeep = VPbis.Keep();
147     if ( !tokeep ) continue;
148     Standard_Integer iVPbis = VPIbis.CurrentVPIndex();
149     if ( iVPbis <= iVP ) continue;
150     Standard_Integer absindexbis = VPbis.ShapeIndex(); // 0,1,2,3
151     Standard_Integer shapeindexbis = (absindexbis == 3) ? ShapeIndex : absindexbis;
152     if ( shapeindexbis == 0 ) continue;
153     const TopoDS_Shape& edgebis = VPbis.Edge(shapeindexbis);
154     TopAbs_Orientation edgeoribis = edgebis.Orientation();
155     TopOpeBRepDS_Transition transLinebis;
156     transLinebis = 
157       TopOpeBRep_FFTransitionTool::ProcessLineTransition
158         (VPbis,shapeindexbis,edgeoribis);
159     Standard_Boolean trliunkbis = transLinebis.IsUnknown();
160     if ( trliunkbis ) continue;
161     transLine = transLinebis.Complement();
162     break;
163   }
164 }
165
166 //-----------------------------------------------------------------------
167 static void FUN_VPgeometryfound
168 (TopOpeBRep_FacesFiller& FF,
169  const TopOpeBRep_LineInter& L,
170  const TopOpeBRep_VPointInter& VP,
171  const Standard_Integer ShapeIndex,
172  const Handle(TopOpeBRepDS_HDataStructure)& HDS,
173  const TopOpeBRepDS_ListOfInterference& DSCIL,
174  TopOpeBRepDS_Kind& PVKind, Standard_Integer& PVIndex,
175  Standard_Boolean& EPIfound, Handle(TopOpeBRepDS_Interference)& IEPI,
176  Standard_Boolean& CPIfound, Handle(TopOpeBRepDS_Interference)& ICPI,
177  Standard_Boolean& OOEPIfound, Handle(TopOpeBRepDS_Interference)& IOOEPI) // (only if on2edges)
178 //-----------------------------------------------------------------------
179 {
180   Standard_Boolean Lrest = (L.TypeLineCurve() == TopOpeBRep_RESTRICTION);
181   TopoDS_Shape Erest; Standard_Real parErest=0; Standard_Integer rkErest=0;
182   if (Lrest) {
183     Erest = L.Arc(); parErest = VP.ParameterOnLine();
184     Standard_Boolean isedge1 = L.ArcIsEdge(1); Standard_Boolean isedge2 = L.ArcIsEdge(2);
185     rkErest = (isedge1) ? 1 : (isedge2) ? 2 : 0;
186   }
187   
188   Standard_Integer absindex = VP.ShapeIndex();
189   Standard_Integer OOabsindex = (absindex == 1) ? 2 : 1; 
190   Standard_Boolean OOShapeIndex = (ShapeIndex == 1) ? 2 : 1;
191   Standard_Boolean on2edges = (absindex == 3) || (Lrest && (rkErest == OOabsindex));
192   TopoDS_Shape edge = (rkErest == ShapeIndex)? Erest : VP.Edge(ShapeIndex);
193
194   PVIndex = 0;  // POINT or VERTEX index
195   EPIfound = CPIfound = OOEPIfound = Standard_False;
196   Standard_Real par = (rkErest == ShapeIndex)? parErest : VP.EdgeParameter(ShapeIndex); 
197   Standard_Real tole = FUN_tool_maxtol(edge);
198   Standard_Real tolp =  Precision::Parametric(tole);
199   
200   const TopOpeBRepDS_DataStructure& BDS = HDS->DS();
201   if (BDS.HasShape(edge)) {
202     const TopOpeBRepDS_ListOfInterference& EPIL = BDS.ShapeInterferences(edge);
203     TopOpeBRepDS_ListIteratorOfListOfInterference itEPIL(EPIL);
204     EPIfound = FF.GetGeometry(itEPIL,VP,PVIndex,PVKind);
205     if (!EPIfound) {
206       itEPIL.Initialize(EPIL);
207       EPIfound = FUN_GetGonParameter(itEPIL,par,tolp,PVIndex,PVKind);
208     }
209     if (EPIfound) IEPI = itEPIL.Value();
210   }
211
212   TopOpeBRepDS_ListIteratorOfListOfInterference itCPIL(DSCIL);
213 #ifdef DEB
214   Standard_Boolean trc = Standard_False;
215   if (trc) {TopOpeBRepDS_Dumper DSD(HDS); TCollection_AsciiString aa("DSCIL :");
216             DSD.DumpLOI(DSCIL,cout,aa);}
217 #endif
218   CPIfound = FF.GetGeometry(itCPIL,VP,PVIndex,PVKind);
219   if (CPIfound) ICPI = itCPIL.Value();
220     
221   // - <VP> is of shapeindex 3 : is on <edge> and <OOedge>,
222   // - <VP> is of shapeindex <ShapeIndex> and <VP> is given ON another edge <OOedge>
223   // If <OOedge> is defined, we look among the list of interferences attached 
224   // to the other edge <OOedge> for an interference of geometry falling into <VP>'s.
225
226   Standard_Boolean hasOOedge = Standard_True;
227   if (on2edges) hasOOedge = Standard_True;
228   else          hasOOedge = (VP.State(OOShapeIndex) == TopAbs_ON);
229   if ( hasOOedge ) {  
230     TopoDS_Shape OOedge;
231 #ifndef DEB
232     if (on2edges) OOedge = ((signed) rkErest == (signed) OOShapeIndex)? Erest : VP.Edge(OOShapeIndex);
233 #else
234     if (on2edges) OOedge = (rkErest == OOShapeIndex)? Erest : VP.Edge(OOShapeIndex);
235 #endif
236     else          OOedge = VP.EdgeON(OOShapeIndex);    
237     Standard_Real OOpar = 0.;
238 #ifndef DEB
239     if (on2edges) OOpar = ((signed) rkErest == (signed) OOShapeIndex)? parErest : VP.EdgeParameter(OOShapeIndex);
240 #else
241     if (on2edges) OOpar = (rkErest == OOShapeIndex)? parErest : VP.EdgeParameter(OOShapeIndex);
242 #endif
243     else          OOpar = VP.EdgeONParameter(OOShapeIndex); 
244     Standard_Real tolOOe = FUN_tool_maxtol(OOedge);
245     Standard_Real OOtolp = Precision::Parametric(tolOOe);
246     if (BDS.HasShape(OOedge)) {
247       const TopOpeBRepDS_ListOfInterference& OOEPIL = BDS.ShapeInterferences(OOedge);
248       TopOpeBRepDS_ListIteratorOfListOfInterference OOitEPIL(OOEPIL);
249       OOEPIfound = FF.GetGeometry(OOitEPIL,VP,PVIndex,PVKind);
250       if (!OOEPIfound) {
251         OOitEPIL.Initialize(OOEPIL);
252         FUN_GetGonParameter(OOitEPIL,OOpar,OOtolp,PVIndex,PVKind);
253       }
254       if (OOEPIfound) IOOEPI = OOitEPIL.Value();
255     }
256   }        
257 }
258
259 #define M_FINDVP  (0) // only look for new vp
260 #define M_MKNEWVP (1) // only make newvp
261 #define M_GETVP   (2) // steps (0) [+(1) if (O) fails]
262
263 //-----------------------------------------------------------------------
264 Standard_EXPORT void FUN_VPIndex
265 (TopOpeBRep_FacesFiller& FF,
266  const TopOpeBRep_LineInter& L,
267  const TopOpeBRep_VPointInter& VP,
268  const Standard_Integer ShapeIndex,
269  const Handle(TopOpeBRepDS_HDataStructure)& HDS,
270  const TopOpeBRepDS_ListOfInterference& DSCIL,
271  TopOpeBRepDS_Kind& PVKind, Standard_Integer& PVIndex, // out
272  Standard_Boolean& EPIfound, Handle(TopOpeBRepDS_Interference)& IEPI, // out 
273  Standard_Boolean& CPIfound, Handle(TopOpeBRepDS_Interference)& ICPI, // out
274  const Standard_Integer mkVP)
275 //-----------------------------------------------------------------------
276 {
277   PVIndex = 0;  // POINT or VERTEX index
278   Standard_Integer OOShapeIndex = (ShapeIndex == 1) ? 2 : 1; 
279   Standard_Boolean SIisvertex = VP.IsVertex(ShapeIndex);
280   Standard_Boolean OOisvertex = VP.IsVertex(OOShapeIndex);
281   
282   // search for an interference with a equal 3D geometry
283   // if found, set PVIndex to index of geometry found
284   // if not found, make a new geometry PVIndex with 3d point or vertex  
285     
286   Standard_Boolean OOEPIfound = Standard_False; 
287   Handle(TopOpeBRepDS_Interference) IOOEPI;
288   if ((mkVP == M_FINDVP)||(mkVP == M_GETVP)) {
289     FUN_VPgeometryfound (FF,L,VP,ShapeIndex,HDS,DSCIL, //in
290                          PVKind,PVIndex, // out
291                          EPIfound,IEPI, // out
292                          CPIfound,ICPI, // out
293                          OOEPIfound,IOOEPI); // out (only if on2edges)
294     if (mkVP == M_FINDVP) {
295       //JMB 27 Dec 1999
296       //modified by NIZHNY-MZV  Tue Apr 25 09:27:15 2000
297       if (!EPIfound && !CPIfound && !OOEPIfound)
298         PVIndex = 0; // if we just want to find (M_FINDVP) then we must readjust PVIndex to 0
299                                    // because OOEPIfound is not treated in the upper function. The upper function
300                                    // will detect that we found a geometry because PVIndex != 0 but as EPIfound and
301                                    // CPIfound are FALSE, the resulting VP geometry give unpredictable results.
302       return;
303     }
304   }
305   // Gfound = VP corresponds with an existing geometry of ShapeIndex
306   Standard_Boolean Gfound = ( EPIfound || CPIfound);
307   // Gfound =             or with an existing geometry of OOShapeIndex
308   Gfound = Gfound || OOEPIfound;
309   
310   Standard_Boolean on2edges = (VP.ShapeIndex() == 3);
311   Standard_Boolean hasOOedge = Standard_True;
312   if (on2edges) hasOOedge = Standard_True;
313   else          hasOOedge = (VP.State(OOShapeIndex) == TopAbs_ON);
314   // If v shares same domain with a vertex of the other shape,
315   // v has already been stored in the DS
316   
317   if (PVIndex == 0) PVKind = (SIisvertex || OOisvertex) ? TopOpeBRepDS_VERTEX : TopOpeBRepDS_POINT;
318
319   if ( hasOOedge && !Gfound ) {
320     if ( !OOEPIfound )  { 
321       if      ( SIisvertex ) PVIndex = FF.MakeGeometry(VP,ShapeIndex,PVKind);
322       else if ( OOisvertex ) PVIndex = FF.MakeGeometry(VP,OOShapeIndex,PVKind);
323       else                   PVIndex = FF.MakeGeometry(VP,ShapeIndex,PVKind);
324     }
325   }
326   if ( !hasOOedge && !Gfound ) {
327     Standard_Boolean found = FF.GetFFGeometry(VP,PVKind,PVIndex);
328     if ( !found) {
329       if      ( SIisvertex ) PVIndex = FF.MakeGeometry(VP,ShapeIndex,PVKind);
330       else if ( OOisvertex ) PVIndex = FF.MakeGeometry(VP,OOShapeIndex,PVKind);
331       else                   PVIndex = FF.MakeGeometry(VP,ShapeIndex,PVKind);
332     }
333   }
334 } // FUN_VPIndex
335
336 //-----------------------------------------------------------------------
337 static Standard_Boolean FUN_LineRestF
338 (const TopoDS_Face& F, const TopOpeBRep_LineInter& L, 
339  const TopTools_ListOfShape& ERL, TopoDS_Edge& ER)
340 //-----------------------------------------------------------------------
341 {
342   // returns true if <L> is ON a restriction <ER> of <F>
343   // <ERL> is the list of the faces intersector.
344   // prequesitory : <L> is on edge
345   TopTools_IndexedMapOfShape mapE;
346   TopExp::MapShapes(F,TopAbs_EDGE,mapE);
347   TopTools_ListIteratorOfListOfShape itER(ERL);
348   TopTools_ListOfShape ERLonF;
349   for (; itER.More(); itER.Next()){
350     const TopoDS_Shape& e = itER.Value();
351     if (mapE.Contains(e)) ERLonF.Append(e);
352   }
353   itER.Initialize(ERLonF);
354   TopTools_ListOfShape ERLonFonL;
355   for (; itER.More(); itER.Next()){
356     const TopoDS_Shape& e = itER.Value();
357     TopTools_ListOfShape eL; eL.Append(e);
358     Standard_Boolean isonL = TopOpeBRep_FacesFiller::LSameDomainERL(L,eL);
359     if (isonL) ERLonFonL.Append(e);
360   }
361   // <L> is on at most one edge restriction.
362   if (ERLonFonL.Extent() != 1) return Standard_False;
363   ER = TopoDS::Edge(ERLonFonL.First());
364   return Standard_True;
365 }
366
367 //-----------------------------------------------------------------------
368 Standard_EXPORT Standard_Boolean FUN_newtransEdge
369 (const Handle(TopOpeBRepDS_HDataStructure) HDS,
370  const TopOpeBRep_FacesFiller& FF,
371  const TopOpeBRep_LineInter& L,
372  const Standard_Boolean& Lonrest,
373  const TopOpeBRep_VPointInter& VP, 
374  const TopOpeBRepDS_Kind PVKind,const Standard_Integer PVIndex,
375  const Standard_Integer& OOShapeIndex,
376  const TopoDS_Edge& edge, const TopTools_ListOfShape& ERL, TopOpeBRepDS_Transition& T)
377 //-----------------------------------------------------------------------
378 {
379   T.Before(TopAbs_UNKNOWN); T.After(TopAbs_UNKNOWN);
380   const TopoDS_Face& OOface = FF.Face(OOShapeIndex);
381   TopoDS_Face FIE = OOface;
382   {
383     TopAbs_Orientation oFIE = FIE.Orientation();
384     if (oFIE == TopAbs_INTERNAL || oFIE == TopAbs_EXTERNAL) {
385       T.Set(oFIE);
386       return Standard_True;
387     }
388   }
389
390   // compute of transition on edge <edge> while crossing <VP>.
391   // <VP> given by <paredge> on <edge>, <uv> on <OOface>, 
392   //               <paronline> on Line.
393
394   // <C>, <pf>, <pl>, <paredge> :
395   Standard_Real paredge; Standard_Boolean ok = VP.ParonE(edge,paredge); if (!ok) return Standard_False;
396
397   Standard_Real par1,par2; 
398   if (HDS->HasShape(edge)) {
399     Standard_Boolean isonper;
400     if (PVIndex == 0) FDS_getupperlower(HDS,HDS->DS().Shape(edge),paredge,par1,par2);
401     else              FDS_LOIinfsup(HDS->DS(),edge,paredge,PVKind,PVIndex,
402                                       HDS->DS().ShapeInterferences(edge),
403                                       par1,par2,isonper); 
404   }
405   else
406     FUN_tool_bounds(edge,par1,par2);
407   
408   gp_Pnt2d uv = VP.SurfaceParameters(OOShapeIndex);
409   
410 #ifdef DEB
411   TopOpeBRepDS_Transition Tr; 
412 #endif
413   //       <Tr> relative to 3d <OOface> matter,
414   //       we take into account <Tr> / 2d <OOface> only if <edge> is normal to <OOface>  
415   Standard_Real tola = Precision::Angular()*1.e+4; //dealing with tolerances
416   Standard_Boolean EtgOOF = FUN_tool_EtgF(paredge,edge,uv,OOface,tola);   
417   Standard_Boolean inERL = FUN_INlos(edge,ERL);
418   Standard_Boolean isse = HDS->DS().IsSectionEdge(edge);
419   Standard_Boolean rest = inERL || isse;
420   Standard_Boolean interf2d = EtgOOF && Lonrest && rest;
421   Standard_Boolean interf3dtg = EtgOOF && rest && !interf2d; // xpu260898 :cto902D6,(e15,p3,f9)
422
423   Standard_Real factor = 1.e-2; 
424   TopOpeBRepTool_makeTransition MKT; 
425   ok = MKT.Initialize(edge,par1,par2,paredge, OOface,uv, factor);
426   if (!ok) return Standard_False;
427   Standard_Boolean isT2d = MKT.IsT2d();
428   interf2d = interf2d && isT2d;
429   
430   TopAbs_State stb,sta; 
431   if (interf2d) {
432     // <tgLine> :
433     TopoDS_Edge OOER; Standard_Boolean onOOface = Standard_False;
434     TopOpeBRep_TypeLineCurve typL = L.TypeLineCurve();
435     if (typL == TopOpeBRep_RESTRICTION) {onOOface = Standard_True; OOER = TopoDS::Edge(L.Arc());}
436     else                                {onOOface = ::FUN_LineRestF(OOface,L,ERL,OOER);}
437     if (!onOOface) return Standard_False;
438     
439     Standard_Real OOpar; ok = VP.ParonE(OOER,OOpar);
440     if (!ok) ok = FUN_tool_parE(edge,paredge,OOER,OOpar);
441     if (!ok) return Standard_False;  
442
443     //xpu051098 : cto900L4 (edge18,OOface5)
444     ok = MKT.SetRest(OOER,OOpar);
445     if (!ok) return Standard_False; 
446   }
447   else if (interf3dtg) {
448     Standard_Integer absindex = VP.ShapeIndex(); // 0,1,2,3
449     Standard_Boolean on2edges = (absindex == 3);
450     Standard_Boolean hasONedge = (VP.State(OOShapeIndex) == TopAbs_ON);
451     Standard_Boolean hasOOedge = (on2edges) ? Standard_True : hasONedge;
452     
453     if ( hasOOedge ) {
454       TopoDS_Edge OOedge; Standard_Real OOpar = 1.e7;
455       if (on2edges) 
456         {OOedge = TopoDS::Edge(VP.Edge(OOShapeIndex)); OOpar = VP.EdgeParameter(OOShapeIndex);}
457       else          
458         {OOedge = TopoDS::Edge(VP.EdgeON(OOShapeIndex)); OOpar = VP.EdgeONParameter(OOShapeIndex);}
459
460       ok = MKT.SetRest(OOedge,OOpar);
461       if (!ok) return Standard_False;       
462     }
463   }
464  
465   ok = MKT.MkTonE(stb,sta);
466   if (!ok) return Standard_False;
467   T.Before(stb); T.After(sta);
468   return Standard_True;
469 } // FUN_newtransEdge
470
471 //-----------------------------------------------------------------------
472 static void FUN_ScanInterfList(const TopOpeBRepDS_Point& PDS, const Handle(TopOpeBRepDS_HDataStructure) HDS,
473                                const TopOpeBRepDS_ListOfInterference& loI, TopOpeBRepDS_ListOfInterference& loIfound)
474 //-----------------------------------------------------------------------
475 {
476   // looks among the list of interferences <loI> for interferences
477   // of geometry falling into <PDS>, add them to <loIfound>
478   TopOpeBRepDS_ListIteratorOfListOfInterference it(loI);
479   while ( it.More()) {
480     Standard_Boolean found = HDS->ScanInterfList(it,PDS);
481     if (found) {
482       loIfound.Append(it.Value());
483       if (it.More()) it.Next();
484     }
485     else return;
486   }
487 }
488
489 static Standard_Boolean FUN_selectTRAISHAinterference(const TopOpeBRepDS_ListOfInterference& lI, const Standard_Integer ITRASHA,
490                                          TopOpeBRepDS_ListOfInterference& lITRAonISHA)
491 // purpose : <lITRAonISHA> = {I = (T on ITRASHA,G,S)}
492 {
493   lITRAonISHA.Clear();
494   TopOpeBRepDS_ListIteratorOfListOfInterference it(lI);
495   for (; it.More(); it.Next()) {
496     const Handle(TopOpeBRepDS_Interference)& I = it.Value();
497     const TopOpeBRepDS_Transition& T = I->Transition(); 
498     Standard_Integer iTRASHA = T.Index();
499 // BUG :
500 //POP : pb  : comparaison entre 2 enum differentes : on prend la valeur correspondante 
501     if (T.Orientation(TopAbs_IN) == TopAbs_EXTERNAL) continue; //xpu030998
502 //    if (T.Orientation(TopAbs_IN) == TopAbs_UNKNOWN) continue; //xpu030998
503     if (iTRASHA == ITRASHA) lITRAonISHA.Append(I);
504   }
505   Standard_Boolean noIfound = lITRAonISHA.IsEmpty();
506   return !noIfound;
507 }
508
509 static Standard_Boolean FUN_selectGinterference(const TopOpeBRepDS_ListOfInterference& lI, const Standard_Integer G,
510                                    TopOpeBRepDS_ListOfInterference& lIonG)
511 {
512   lIonG.Clear();
513   TopOpeBRepDS_ListIteratorOfListOfInterference it(lI);
514   for (; it.More(); it.Next()) {
515     const Handle(TopOpeBRepDS_Interference)& I = it.Value();
516     if (I->Geometry() == G) lIonG.Append(I);
517   }
518   Standard_Boolean noIfound = lIonG.IsEmpty();
519   return !noIfound;  
520 }
521
522 static Standard_Boolean FUN_sameGsameS(const TopOpeBRepDS_ListOfInterference& loI, const Standard_Integer& G, const Standard_Integer& S,
523                           TopOpeBRepDS_ListOfInterference& loIfound)
524 {
525   loIfound.Clear();
526   // Gets among the list <loI> the interferences of :
527   //  geometry <G>, and support <S>
528   TopOpeBRepDS_PointIterator PI(loI);   
529   for (; PI.More(); PI.Next()) {
530     Handle(TopOpeBRepDS_Interference) EPI = PI.Value();    
531     Standard_Integer GEPI = EPI->Geometry(); Standard_Integer SEPI = EPI->Support();      
532     if (GEPI == G && SEPI == S) loIfound.Append(EPI);
533   }
534   return (loIfound.Extent() > 0);
535 }
536
537 //-----------------------------------------------------------------------
538 static void FUN_processCPI
539 (TopOpeBRep_FacesFiller& FF,
540  const TopOpeBRep_VPointInter& VP,
541  const TopoDS_Shape& F,
542  const Standard_Integer ShapeIndex, 
543  const TopOpeBRep_LineInter& L,
544  TopOpeBRepDS_PDataStructure pDS,
545  const TopOpeBRepDS_Transition& transLine,
546  const TopOpeBRepDS_ListOfInterference& DSCIL,
547  const Handle(TopOpeBRepDS_Interference)& Ifound,
548  const Standard_Boolean& Gfound,
549  const TopOpeBRepDS_Kind& PVKind,const Standard_Integer& PVIndex,
550  Standard_Integer& keptVPnbr)
551 //-----------------------------------------------------------------------
552 {    
553   Standard_Integer OOShapeIndex = (ShapeIndex == 1) ? 2 : 1;
554
555   TopOpeBRepDS_Transition ttransLine = transLine;
556   // prequesitory : current line is not on edge.  
557   Standard_Real parline = VP.ParameterOnLine();
558   Standard_Boolean SIisvertex = VP.IsVertex(ShapeIndex);
559   Standard_Boolean OOisvertex = VP.IsVertex(OOShapeIndex);
560   const TopoDS_Shape& E = VP.Edge(ShapeIndex);
561   
562   // xpu010299 : we do not keep interferences with same parameters on curve 
563   //             PRO16120(f3,f4 -> null c1)
564   if (!DSCIL.IsEmpty()) {
565     Standard_Real par = FDS_Parameter(DSCIL.Last()); // parameter on curve
566     Standard_Real dd = Abs(par-parline); // en fait, ce sont des entiers
567     if (dd == 0) return;
568   }
569
570   // dist(p2d1,p2d2) < toluv => p2d1, p2d2 are considered equal.
571   // NYI : compute uvtol with the original faces. By default, we set toluv = TolClass
572   Standard_Real toluv = 1.e-8;
573   Standard_Boolean keep = FUNBREP_topokpart(Ifound,DSCIL,L,VP,(*pDS),E,F,toluv,parline,ttransLine);
574     
575 #ifdef DEB
576   Standard_Integer trc=TopOpeBRepDS_GettraceDSF();
577   if (trc){if(keep)cout<<"\t-> on garde";else cout<<"\t-> on jette";cout<<endl;}
578 #endif  
579   
580   if (keep) {
581     keptVPnbr++;
582     if (keptVPnbr > 2) keep = Standard_False;
583   }
584   if (!keep) return;
585   
586   Handle(TopOpeBRepDS_Interference) CPI;
587   {
588     TopOpeBRepDS_Kind GKCPV;
589     if (Gfound) GKCPV = PVKind;
590     else GKCPV = (SIisvertex || OOisvertex) ? TopOpeBRepDS_VERTEX : TopOpeBRepDS_POINT;
591
592     CPI = ::MakeCPVInterference(ttransLine,0,PVIndex,parline,GKCPV);
593     FF.StoreCurveInterference(CPI);
594   }
595 }
596
597 static Standard_Boolean FUN_onedge(const TopOpeBRepDS_Point& PDS, const TopoDS_Edge& E)
598 {
599   gp_Pnt P = PDS.Point();
600   Standard_Real tolP = PDS.Tolerance(); Standard_Real tolE = BRep_Tool::Tolerance(E);
601   Standard_Real tol = Max(tolP,tolE);
602   TopoDS_Vertex vf,vl; TopExp::Vertices(E,vf,vl);
603   gp_Pnt pf = BRep_Tool::Pnt(vf); Standard_Boolean isonf = P.IsEqual(pf,tol);
604   gp_Pnt pl = BRep_Tool::Pnt(vl); Standard_Boolean isonl = P.IsEqual(pl,tol);
605   return isonf || isonl;
606 }
607
608 #ifdef DEB
609 Standard_EXPORT void funraise() {cout<<"!!!!!!!!!! PVIndex = 0 !!!!!!!!!!"<<endl;}
610 #endif
611
612 //=======================================================================
613 //function : ProcessVPonR
614 //purpose  : 
615 //=======================================================================
616
617 void TopOpeBRep_FacesFiller::ProcessVPonR
618 (const TopOpeBRep_VPointInter& VP,
619  const TopOpeBRepDS_Transition& Trans,
620 // const TopoDS_Shape& GFace,
621  const TopoDS_Shape& ,
622  const Standard_Integer ShapeIndex) //1,2
623 {
624   Standard_Integer absindex = VP.ShapeIndex(); // 0,1,2,3
625   Standard_Integer iVP = VP.Index();
626   Standard_Boolean OOShapeIndex = (ShapeIndex == 1) ? 2 : 1;
627   Standard_Boolean on2edges = (absindex == 3);
628   Standard_Boolean hasONedge = (VP.State(OOShapeIndex) == TopAbs_ON);
629   Standard_Boolean hasOOedge = (on2edges) ? Standard_True : hasONedge;
630
631   TopoDS_Face Face = (*this).Face(ShapeIndex);
632   Standard_Integer iSIFace = myDS->Shape(Face);
633   if (iSIFace == 0) iSIFace = myDS->AddShape(Face,ShapeIndex);
634   TopoDS_Face OOFace = (*this).Face(OOShapeIndex);
635   Standard_Integer iOOFace = myDS->Shape(OOFace);
636   if (iOOFace == 0)  iOOFace = myDS->AddShape(OOFace,OOShapeIndex);
637
638   // current VPoint is on <edge>
639   Standard_Integer SIedgeIndex = 0;
640   const TopoDS_Edge& edge = TopoDS::Edge(VP.Edge(ShapeIndex));
641   if (myDS->HasShape(edge)) SIedgeIndex = myDS->Shape(edge);
642   Standard_Real paredge = VP.EdgeParameter(ShapeIndex);
643   Standard_Boolean isrest = myDS->IsSectionEdge(edge);
644   Standard_Boolean closing = TopOpeBRepTool_ShapeTool::Closed(edge,Face);
645   Standard_Boolean dge = BRep_Tool::Degenerated(edge);
646   
647   // dummy if !<hasOOedge>
648   Standard_Integer OOedgeIndex = 0; 
649   Standard_Boolean OOclosing,OOisrest; OOclosing = OOisrest = Standard_False;
650   TopoDS_Edge OOedge; Standard_Real OOparedge = 0.; Standard_Boolean dgOOe = Standard_False;
651   if ( hasOOedge ) {
652     if (on2edges) OOparedge = VP.EdgeParameter(OOShapeIndex);
653     else          OOparedge = VP.EdgeONParameter(OOShapeIndex);
654     TopoDS_Shape OOe;
655     if (on2edges) OOe = VP.Edge(OOShapeIndex);
656     else          OOe = VP.EdgeON(OOShapeIndex);
657     OOedge = TopoDS::Edge(OOe);
658     if (myDS->HasShape(OOedge)) OOedgeIndex = myDS->Shape(OOedge);
659     OOisrest = myDS->IsSectionEdge(OOedge);
660     OOclosing = TopOpeBRepTool_ShapeTool::Closed(OOedge,OOFace);
661     dgOOe = BRep_Tool::Degenerated(OOedge);
662   }
663
664 #ifdef DEB
665   Standard_Boolean traceDSF = TopOpeBRepDS_GettraceDSF();
666   Standard_Boolean traceDSP = TopOpeBRepDS_GettraceDSP();
667   Standard_Integer ili=myLine->Index(),ivp=iVP,isi=ShapeIndex;
668   if(traceDSF || traceDSP){
669     cout<<endl;
670     cout<<"trc tnvp 1 "<<myexF1<<" "<<myexF2<<" "<<ili<<" "<<ivp<<" "<<isi;
671     cout<<"; # VPonR "<<iVP<<" on "<<ShapeIndex<<" from "<<absindex<<endl;
672   }
673   GLOBAL_bvpr = TopOpeBRep_GettraceNVP(myexF1,myexF2,ili,ivp,isi);
674   if (TopOpeBRepDS_GettraceISTO()) {
675     cout<<"f1,f2,l,vp,si : ";
676     cout<<myexF1<<","<<myexF2<<","<<ili<<","<<ivp<<","<<isi<<endl;
677   }
678   if (GLOBAL_bvpr) debvprmess(myexF1,myexF2,ili,ivp,isi);
679   if (traceDSF){
680     cout<<"VP is on";if (closing) cout<<" CLOSING";
681     cout<<" edge "<<SIedgeIndex; 
682     if(isrest) cout<<" RESTRICTION"; cout<<endl;
683     if (OOclosing) cout<<"      on CLOSING OOedge "<<OOedgeIndex; 
684     if(OOisrest) cout<<" RESTRICTION"; cout<<endl;
685   }
686 #endif
687
688   // degenerated edge processing 
689   // ---------------------------
690   Standard_Integer PVIndex = 0; // POINT or VERTEX index
691   TopOpeBRepDS_Kind PVKind;
692   Standard_Boolean EPIfound,CPIfound;
693   EPIfound = CPIfound = Standard_False;
694   Handle(TopOpeBRepDS_Interference) IEPI,ICPI;
695   ProcessVPondgE(VP, ShapeIndex,
696                  PVKind,PVIndex, // out
697                  EPIfound,IEPI,  // out
698                  CPIfound,ICPI); // out
699   Standard_Boolean foundPVIndex = (PVIndex != 0);
700   
701   
702   // ===================================================================
703   //              <TransLine>, <transEdge>
704   // ===================================================================
705   
706   Standard_Boolean wline = (myLine->TypeLineCurve() == TopOpeBRep_WALKING);
707   Standard_Boolean grestriction = (myLine->TypeLineCurve() == TopOpeBRep_RESTRICTION);
708   Standard_Boolean glinenotoned = !wline && !grestriction && !myLineIsonEdge;
709   
710   // lasttransLine (for walking line)
711   // -------------
712   // set lasttransLine for a WALKING line
713   Standard_Boolean dscilempty = myDSCIL.IsEmpty();
714   Standard_Boolean setlastonwl = wline && !dscilempty;
715   if (setlastonwl) { //xpu171198, FRA61896 (f7,f13-> null DSC1)
716     Standard_Real parline = VP.ParameterOnLine();
717     Standard_Real par = FDS_Parameter(myDSCIL.Last()); // parameter on curve
718     Standard_Real dd = Abs(par-parline); // en fait, ce sont des entiers
719     if (dd == 0) setlastonwl=Standard_False;
720   }
721   TopOpeBRepDS_Transition lasttransLine; if (setlastonwl) lasttransLine = myDSCIL.Last()->Transition();
722   
723   // edgeori, transLine
724   // ------------------
725   TopAbs_Orientation edgeori = edge.Orientation();
726   TopOpeBRepDS_Transition transLine; 
727   transLine = TopOpeBRep_FFTransitionTool::ProcessLineTransition
728     (VP,ShapeIndex,edgeori);
729   Standard_Boolean trliunk = transLine.IsUnknown();
730   
731   // 1_ If vpmin has transition OUT/IN, and vpmax is UNKNOWN, 
732   //    we change vpmax transition as IN/OUT
733   //
734   // 2_ If vpmin is UNKNOWN (if vp is first on line and transition is UNKNOWN,
735   //    vpmin's transition is ON/ON the OOshape)
736   //    we change vpmin transition as OUT/IN
737   //
738   // (kpart : sphere/box, with the sphere's sewing edge lying on one boxe's 
739   //  face and one of the edge's vertices IN the same face)
740   
741   Standard_Integer iINON1,iINONn,nINON; myLine->VPBounds(iINON1,iINONn,nINON);
742   Standard_Boolean islastvp = (iVP == iINONn);
743   Standard_Boolean isfirstvp = (iVP == iINON1);
744   
745   Standard_Boolean keepvp = Standard_False;
746   Standard_Boolean ret1 = Standard_False; 
747   if ( trliunk ) {
748     // <transLine> is unknown :
749     //  for a walking -> 
750     //     - if <myDSCIL> is not empty,
751     //                   we set it as the last transition complemented
752     //     - else, 
753     //          we look after an determinate transition on VP(i>iVP)
754     //          and set transLine as this last complemented.
755     //
756     //  for a gline not on edge -> 
757     //     - if the transition on edge is unknown too and !<keepvp>,
758     //       we do not keep it.
759     //  elsewhere -> we do not keep <VP>
760     
761     if      ( wline ) {
762       if (setlastonwl) transLine = lasttransLine.Complement();
763       else             ::FUN_transForWL(*myLine,iVP,ShapeIndex,transLine);
764
765       //  walki vpfirst on 3, vplast on 0, nvpkept = 2 kept
766       if (transLine.IsUnknown()) {
767         //modified by NIZHNY-MKK  Mon Jul  3 11:30:03 2000.BEGIN
768         Standard_Boolean keepvpfirst = dscilempty && isfirstvp && (nINON == 2);
769         if(absindex==3)
770           keepvpfirst = keepvpfirst && myLastVPison0;
771         //modified by NIZHNY-MKK  Mon Jul  3 11:30:21 2000.END
772         if (keepvpfirst) transLine.Set(TopAbs_FORWARD);
773 #ifdef DEB
774         if (traceDSF) cout<<"myLastVPison0 ->"<<endl;
775 #endif
776         ret1 = Standard_False;
777       }
778     }
779     else if ( glinenotoned ) {
780       //       if (islastvp)  keepvp = !dscilempty;
781       //       if (isfirstvp) keepvp = Standard_True;
782       if (isfirstvp) keepvp = Standard_True;
783       else {
784         if (islastvp)  keepvp = !dscilempty;
785         else {
786           if(!dge && !dgOOe && (VP.IsVertexOnS1() || VP.IsVertexOnS2())) {
787             // If VP is on vertex we should compute at least one interference for the edge.
788             // This interference is necessary at least to indicate that the edge intersect something.
789             const TopOpeBRep_VPointInter& aFirstPoint = myLine->VPoint(iINON1);
790             const TopOpeBRep_VPointInter& aLastPoint = myLine->VPoint(iINONn);
791
792             for(Standard_Integer faceindex = 1; !keepvp && faceindex <=2; faceindex++) {
793               Standard_Boolean VPIsVertex = (faceindex==1) ? VP.IsVertexOnS1() : VP.IsVertexOnS2();
794               Standard_Boolean FirstPointIsVertex = (faceindex==1) ? aFirstPoint.IsVertexOnS1() : aFirstPoint.IsVertexOnS2();
795               Standard_Boolean LastPointIsVertex =  (faceindex==1) ? aLastPoint.IsVertexOnS1() : aLastPoint.IsVertexOnS2();
796               if(VPIsVertex) {
797                 const TopoDS_Shape& aV1 =  (faceindex==1) ? VP.VertexOnS1() : VP.VertexOnS2();
798                 if(FirstPointIsVertex) {                  
799                   const TopoDS_Shape& aV2 =  (faceindex==1) ? aFirstPoint.VertexOnS1(): aFirstPoint.VertexOnS2();
800                   if(aV1.IsSame(aV2)) {
801                     keepvp = Standard_True;
802                   }
803                 }
804                 if(!keepvp && LastPointIsVertex) {
805                   const TopoDS_Shape& aV2 =  (faceindex==1) ? aLastPoint.VertexOnS1() : aLastPoint.VertexOnS2();
806                   if(aV1.IsSame(aV2)) {
807                     keepvp = !dscilempty;
808                   }
809                 }
810               }
811             }
812           }
813         }
814       }      
815       ret1 = !keepvp;
816     }
817     else 
818       ret1 = Standard_True;
819   }
820   trliunk = transLine.IsUnknown();
821   if (ret1) return;
822
823   // Transori, transEdge
824   // -------------------
825   TopAbs_Orientation Transori = Trans.Orientation(TopAbs_IN);
826   TopOpeBRepDS_Transition transEdge = TopOpeBRep_FFTransitionTool::ProcessEdgeTransition(VP,ShapeIndex,Transori);  
827 #ifdef DEB
828   if(traceDSF){cout<<"trans edge on f"<<ShapeIndex<<" / f"<<OOShapeIndex<<" : ";
829                transEdge.Dump(cout);cout<<endl;}
830 #endif
831
832   Standard_Boolean Tunknown = FDS_hasUNK(transEdge);
833   TopOpeBRepDS_Point PDS = TopOpeBRep_PointGeomTool::MakePoint(VP);// <VP>'s geometry  
834   TopOpeBRepDS_ListOfInterference lITOOFonVP; // {I on <edge> = (T on <OOface>, G on <VP>, S)}
835   Standard_Boolean found = Standard_False;
836   if (SIedgeIndex != 0) {
837     TopOpeBRepDS_ListOfInterference lI; 
838     const TopOpeBRepDS_ListOfInterference& lIedge = myDS->ShapeInterferences(edge);
839     if (PVIndex == 0) ::FUN_ScanInterfList(PDS,myHDS,lIedge,lI);
840     else              ::FUN_selectGinterference(lIedge,PVIndex,lI);
841     found = ::FUN_selectTRAISHAinterference(lI,iOOFace,lITOOFonVP);    
842   }
843
844 //  if (found && myLineINL && Tunknown) return; //xpu220998 : cto cylcong A1 (edge8,OOface4)
845
846   // <Transori> = INTERNAL or EXTERNAL (tangent cases), compute <transEdge>
847   Standard_Boolean newtransEdge = (Transori == TopAbs_INTERNAL) || (Transori == TopAbs_EXTERNAL);
848   TopAbs_Orientation otransEdge = transEdge.Orientation(TopAbs_IN);
849   Standard_Boolean allINT = (Transori == TopAbs_INTERNAL) || (otransEdge == TopAbs_INTERNAL);
850   Standard_Boolean allEXT = (Transori == TopAbs_EXTERNAL) || (otransEdge == TopAbs_EXTERNAL);
851
852
853   newtransEdge = newtransEdge && (!allINT) && (!allEXT);
854   newtransEdge = newtransEdge || Tunknown;
855   // -> intersection fails for closing edges
856   // 1. <edge> touches closing <OOedge> at <VP> && <OOedge> is tangent to <OOFace>,
857   // intersection -> 1 forward && 1 reversed instead of internal/external.
858   // 2. if <edge> is tangent to <OOFace> at <VP> on walking
859   newtransEdge = newtransEdge || closing || OOclosing;
860   newtransEdge = newtransEdge && (!myLineINL); 
861   if (newtransEdge){
862 #ifdef DEB
863     Standard_Integer iedge =
864 #endif
865                 myDS->Shape(edge);
866     newtransEdge = !found;
867     if (found) { 
868       // Getting first transition found
869       // prequesitory : transition on edge / <OOF> on same geometry point is unchanged
870       TopOpeBRepDS_Transition Tr = lITOOFonVP.First()->Transition();
871       transEdge.Before(Tr.Before()); transEdge.After(Tr.After());
872     }
873     if (newtransEdge) {
874       // Compute of <transEdge> : transition on <edge> at geometry <VP> / <OOface>
875       // if line on a restriction OOedge of <OOface> : gets <edge> transition/<OOface> when
876       //                                               at <VP> on OOedge.
877       // if line is not on restriction : gets <edge> transition/<OOface>.
878       TopOpeBRepDS_Transition Tr;
879       Standard_Boolean ok = FUN_newtransEdge(myHDS,(*this),(*myLine),myLineIsonEdge,VP,
880                                 PVKind,PVIndex,OOShapeIndex,edge,myERL,Tr);
881       if (ok) {transEdge.Before(Tr.Before()); transEdge.After(Tr.After());}
882       newtransEdge = ok;
883     }
884 #ifdef DEB
885     if (traceDSF && (found || newtransEdge)) 
886       {if (found) cout<<"*-> found "; if (newtransEdge) cout<<"*-> new ";
887        cout<<"transEdge (edge "<<iedge<<",face"<<iOOFace<<") = "; TopAbs::Print(transEdge.Before(),cout);
888        cout<<" ";TopAbs::Print(transEdge.After(),cout);cout<<endl;}
889 #endif
890   } // newtransEdge
891
892   Standard_Boolean tredunk = transEdge.IsUnknown();
893   Standard_Boolean ret2 = Standard_False;
894   if ( tredunk ) {
895     if (!trliunk) transEdge = transLine.Complement();
896     if (trliunk && !keepvp) ret2 = Standard_True;
897   }
898   if (ret2) return;
899   tredunk = transEdge.IsUnknown();
900
901   // ===================================================================
902   //              DS geometry Management
903   // ===================================================================
904   // SI*** : data issued from shape ShapeIndex
905   // OO*** : data issued from other shape
906     
907   if (SIedgeIndex == 0) SIedgeIndex = myDS->AddShape(edge,ShapeIndex);
908 #ifdef DEB
909   Standard_Boolean trce = TopOpeBRepDS_GettraceSPSX(SIedgeIndex); if(trce) debarc(SIedgeIndex);
910 #endif
911
912   Standard_Boolean SIisvertex = VP.IsVertex(ShapeIndex);
913   Standard_Boolean OOisvertex = VP.IsVertex(OOShapeIndex);
914     
915   // <PVIndex>, <PVKind> :
916   // --------------------
917   // search for an interference with a equal 3D geometry
918   // if found, set <PVIndex> to index of geometry found
919   // if not found, make a new geometry PVIndex with 3d point or vertex      
920
921   // modified by NIZHNY-MKK  Tue Apr  3 12:08:38 2001.BEGIN
922   Standard_Boolean ismultiplekind = foundPVIndex && !EPIfound && !CPIfound && 
923     (SIisvertex || OOisvertex) && (PVKind == TopOpeBRepDS_POINT);
924
925   //   if (!foundPVIndex) FUN_VPIndex ((*this),(*myLine),VP,ShapeIndex,myHDS,myDSCIL, //in
926   if (!foundPVIndex || ismultiplekind) FUN_VPIndex ((*this),(*myLine),VP,ShapeIndex,myHDS,myDSCIL, //in
927   // modified by NIZHNY-MKK  Tue Apr  3 12:13:17 2001.END
928                                                     PVKind,PVIndex, // out
929                                                     EPIfound,IEPI,  // out
930                                                     CPIfound,ICPI,  // out
931                                                     M_MKNEWVP);
932   if (PVIndex == 0){
933 #ifdef DEB
934     funraise();
935 #endif
936   }
937   
938   Standard_Boolean VPonedge=Standard_False; if (PVKind == TopOpeBRepDS_VERTEX) VPonedge=::FUN_onedge(PDS,edge);
939   if (myLineINL) {
940     Standard_Real tolang = Precision::Angular()*1.e5;//=1.e-7 NYITOLXPU
941
942     gp_Vec tgE = FUN_tool_tggeomE(paredge,edge);
943     gp_Pnt2d OOuv; Standard_Boolean ok = Standard_False;
944     if (VPonedge) {OOuv = VP.SurfaceParameters(OOShapeIndex); ok = Standard_True;}
945     else          {ok = FUN_tool_paronEF(OOedge,OOparedge,OOFace, OOuv);} 
946     gp_Vec ntOOF;
947     if (ok) ntOOF = FUN_tool_nggeomF(OOuv,OOFace);
948     if (OOFace.Orientation() == TopAbs_REVERSED) ntOOF.Reverse();       
949     
950     Standard_Real tol = 1.e-7;
951     if (ok) ok = (tgE.Magnitude() > tol)&&(ntOOF.Magnitude() > tol);
952     Standard_Real dot = 1.e7; if (ok) dot = gp_Dir(tgE).Dot(gp_Dir(ntOOF));
953       
954
955     Handle(Geom_Surface) su = BRep_Tool::Surface(OOFace);
956     Standard_Boolean apex = FUN_tool_onapex(OOuv,su);      
957     TopOpeBRepDS_Transition T;
958     if (!apex && ok && (Abs(dot) > tolang)) {  
959       TopAbs_Orientation ori = (dot < 0.) ? TopAbs_FORWARD : TopAbs_REVERSED;
960       T.Set(ori);
961     }
962
963     if (VPonedge && (!dge)) {
964       //xpu231098 : cto904C8(edge11)
965       // xpu131198 : CTS21802(edge31)
966       if (iOOFace == 0) iOOFace = myDS->AddShape(OOFace,OOShapeIndex);
967       Handle(TopOpeBRepDS_Interference) EPIf;
968       {
969         T.Index(iOOFace);
970         EPIf = MakeEPVInterference(T,iOOFace,PVIndex,paredge,PVKind,TopOpeBRepDS_FACE,SIisvertex);
971       }
972       myHDS->StoreInterference(EPIf,edge);
973       if (on2edges || hasONedge) {
974         if (OOedgeIndex == 0) OOedgeIndex = myDS->AddShape(OOedge,OOShapeIndex);
975         Handle(TopOpeBRepDS_Interference) EPI;
976         {
977           T.Index(iOOFace);
978           EPI = MakeEPVInterference(T,OOedgeIndex,PVIndex,paredge,PVKind,SIisvertex);
979         }
980         myHDS->StoreInterference(EPI,edge);
981       }
982       return;
983     }//VPonedge
984     else {
985       // compute interferences later on
986       //modified by NIZHNY-MZV  Thu Dec 23 13:27:10 1999
987       if(!T.IsUnknown()) {
988         transEdge.Before(T.Before()); 
989         transEdge.After(T.After());
990       }
991     }
992   }//myLineINL
993
994   TopOpeBRepDS_Kind SKEPI; if(EPIfound) SKEPI=IEPI->SupportType();
995   TopOpeBRepDS_Kind SKCPI; if(CPIfound) SKCPI=ICPI->SupportType();
996
997   // Gfound = VP corresponds with an existing geometry of ShapeIndex
998   Standard_Boolean Gfound = ( EPIfound || CPIfound );  
999 #ifdef DEB
1000   Standard_Boolean trcpv = TopOpeBRepDS_GettraceSPSX(PVIndex);
1001   Standard_Boolean ispoint = (PVKind == TopOpeBRepDS_POINT);
1002   if(trcpv && ispoint)  debpoint(PVIndex);
1003   if(trcpv && !ispoint) debvertex(PVIndex);
1004   if (GLOBAL_bvpr) debvprmess(myexF1,myexF2,ili,ivp,isi);
1005 #endif
1006
1007   // ===================================================================
1008   //          Current VPoint VP is kept
1009   // ===================================================================  
1010
1011   // ------------------------------------------
1012   // -- Curve/(POINT,VERTEX) Interference (CPI)
1013   // ------------------------------------------
1014   
1015   Standard_Boolean noCPI = myLineIsonEdge;
1016   noCPI = noCPI || (!on2edges && hasOOedge && (OOisrest || isrest)); 
1017
1018   Standard_Boolean condi = (!noCPI);
1019   condi = condi && (!myLineINL); // INL
1020   if (condi) {
1021     Standard_Integer keptVPnbr = mykeptVPnbr;
1022     FUN_processCPI((*this),VP,Face,ShapeIndex,(*myLine),myDS,
1023                    transLine,myDSCIL,ICPI,Gfound,PVKind,PVIndex,
1024                    keptVPnbr);
1025     mykeptVPnbr = keptVPnbr;
1026   }
1027   
1028   // ------------------------------------------
1029   // --- Edge/(POINT,VERTEX) Interference (EPI) 
1030   // ------------------------------------------
1031
1032 //  if (on2edges && !Gfound && !closing) {
1033   Standard_Boolean condi2 = (on2edges && !closing);
1034   condi2 = condi2 || (hasONedge && !closing); 
1035   if (condi2 && (!dge)) {
1036     if (OOedgeIndex == 0) OOedgeIndex = myDS->AddShape(OOedge,OOShapeIndex);
1037     
1038     Handle(TopOpeBRepDS_Interference) EPI;
1039     {
1040       TopOpeBRepDS_Transition T = transEdge;
1041       if (iOOFace == 0) iOOFace = myDS->AddShape(OOFace,OOShapeIndex);
1042       T.Index(iOOFace);
1043       EPI = MakeEPVInterference(T,OOedgeIndex,PVIndex,paredge,PVKind,SIisvertex);
1044     }
1045     myHDS->StoreInterference(EPI,edge);
1046   } //condi2
1047
1048   // ===================================================================
1049   // manip corrective d'un pb. d'intersection
1050   // - le VPoint est donne sur une restriction de ShapeIndex (1 ou 2),
1051   // - le VPoint est ON une restriction de l'autre shape (OOShapeIndex)
1052   // --> le VPoint n'est PAS donne sur restriction de OOShapeIndex NYI
1053   //     par les intersections (a ameliorer). NYI             
1054   // L'etat ON sur OOShapeIndex indique que le point est sur une 
1055   // de ses restrictions :
1056   // - on ne met PAS le point dans les CPIs
1057   // - on met le point dans les EPIs de l'arete de OOShapeIndex
1058   // ===================================================================
1059
1060   Standard_Boolean correctON = !on2edges && hasONedge && !dgOOe;
1061   Standard_Boolean correctedON = Standard_False;
1062   if ( correctON ) {  
1063     TopOpeBRepDS_ListOfInterference lITFonVP; Standard_Boolean OOfound = Standard_False;
1064     if (OOedgeIndex != 0) {
1065       const TopOpeBRepDS_ListOfInterference& lIOOedge = myDS->ShapeInterferences(OOedge); 
1066       TopOpeBRepDS_ListOfInterference lI; ::FUN_ScanInterfList(PDS,myHDS,lIOOedge,lI);
1067       OOfound = ::FUN_selectTRAISHAinterference(lI,iSIFace,lITFonVP);
1068       correctON = !OOfound;        
1069     }
1070   }   
1071   if ( correctON ) {  
1072 #ifdef DEB
1073     Standard_Boolean trcooe=TopOpeBRepDS_GettraceSPSX(OOedgeIndex);if (trcooe) debooarc(OOedgeIndex);
1074 #endif
1075     if (OOedgeIndex == 0) OOedgeIndex = myDS->AddShape(OOedge,OOShapeIndex);
1076     
1077     // VP a ete classifie ON sur l'edge <OOedge>.
1078     // calcul de la transition <tOOedge> sur l'arete <OOedge> 
1079     // (de l'autre face en jeu, OOShapeIndex) ou le VP est donne ON.
1080     // On tient compte de l'orientation de <edge> dans <Face>.
1081     // (bug IntPatch_Line : VP n'a pas de donnees en OOShapeIndex 
1082     // alors qu'il est dessus)
1083     
1084     TopOpeBRepDS_Transition tOOedge;
1085     // distinguish wether OOedge is the edge on which geometric line lies.
1086     // OOedge == edge(line) ==> tOOedge = f(orientation of <edge> in <Face> FORWARD)
1087     // OOedge != edge(line) ==> tOOedge = f(orientation of <Face>)    
1088     Standard_Real OOpar1,OOpar2; Standard_Boolean isonper; FDS_LOIinfsup((*myDS),OOedge,OOparedge,PVKind,PVIndex,
1089                                                     myDS->ShapeInterferences(OOedge),
1090                                                     OOpar1,OOpar2,isonper);
1091     //FDS_getupperlower(myHDS,OOedgeIndex,OOparedge,par1,par2);
1092     gp_Pnt2d OOuv = VP.SurfaceParameters(ShapeIndex);
1093     
1094     //       <Tr> relative to 3d <OOface> matter,
1095     //       we take into account <Tr> / 2d <OOface> only if <edge> is normal to <OOface> 
1096     Standard_Real tola = Precision::Angular()*1.e+2; //dealing with tolerances 
1097
1098     // KK : supplying tolerances pbm (tola too small)
1099     Standard_Boolean EsdmEofF = myHDS->HasSameDomain(OOedge);
1100     if (EsdmEofF) {
1101       TopExp_Explorer ex;
1102       for (ex.Init(Face, TopAbs_EDGE); ex.More(); ex.Next())
1103         if (FUN_ds_sdm(*myDS,ex.Current(),OOedge)) {EsdmEofF = Standard_True; break;}
1104     }
1105     Standard_Boolean OOEtgF = Standard_True;
1106     if (!EsdmEofF) OOEtgF = FUN_tool_EtgF(OOparedge,OOedge,OOuv,Face,tola);  
1107     Standard_Boolean OOrest = FUN_INlos(edge,myERL);
1108     Standard_Boolean interf2d = OOEtgF && (OOisrest || OOrest);
1109     
1110     Standard_Real factor = 1.e-2;
1111     TopOpeBRepTool_makeTransition MKT; 
1112     Standard_Boolean ok = MKT.Initialize(OOedge,OOpar1,OOpar2,OOparedge,Face,OOuv, factor);
1113
1114     if (ok && !(interf2d && !MKT.IsT2d())) {
1115       MKT.SetRest(edge,paredge);
1116       TopAbs_State stb,sta; ok = MKT.MkTonE(stb,sta); 
1117       if (ok) {
1118         tOOedge.Before(stb); tOOedge.After(sta);
1119 #ifdef DEB
1120         if(traceDSF){
1121           cout<<"* !on2edges && TopAbs_ON *\n";
1122           if(OOisrest) cout<<"* edge "<<OOedgeIndex<<" RESTRICTION *\n";
1123           cout<<"Transition sur <OOedge> "<<OOedgeIndex<<" croisant <edge> "<<SIedgeIndex<<" ";
1124           TopAbs::Print(edgeori,cout);cout<<" ";tOOedge.Dump(cout);cout<<endl;}
1125 #endif      
1126         Handle(TopOpeBRepDS_Interference) OOEPIe;
1127         {
1128           if (iSIFace == 0) iSIFace = myDS->AddShape(Face,ShapeIndex); 
1129           TopOpeBRepDS_Transition OOT = tOOedge; OOT.Index(iSIFace);      
1130           OOEPIe = MakeEPVInterference(OOT,SIedgeIndex,PVIndex,OOparedge,PVKind,OOisvertex);
1131         }
1132         myHDS->StoreInterference(OOEPIe,OOedge);
1133       
1134         // xpu : 09-03-98
1135         // hsd3d => interf2d  : only IwithSkEDGE interf 
1136         // elsewhere            : add an IwithSkFACE interference.
1137         Standard_Boolean addEPIf = !myLineIsonEdge;
1138         TopTools_ListOfShape dummy; Standard_Boolean hsd3d = FDS_HasSameDomain3d(*myDS,OOedge,&dummy);
1139         if (hsd3d) addEPIf = Standard_False;
1140         if (addEPIf) {
1141           TopOpeBRepDS_Transition OOT = tOOedge; OOT.Index(iSIFace); 
1142           Handle(TopOpeBRepDS_Interference) OOEPIf = MakeEPVInterference(OOT,iSIFace,PVIndex,OOparedge,PVKind,
1143                                                                          TopOpeBRepDS_FACE,OOisvertex);
1144           myHDS->StoreInterference(OOEPIf,OOedge);
1145         }
1146         // xpu : 09-03-98    
1147         correctedON = Standard_True;
1148       } // ok
1149     }
1150   } // correctON
1151
1152   if (correctON && !correctedON && noCPI && !myLineIsonEdge) {
1153     // MSV: correct ON failed, so store CPI
1154     Standard_Integer keptVPnbr = mykeptVPnbr;
1155     FUN_processCPI((*this),VP,Face,ShapeIndex,(*myLine),myDS,
1156                    transLine,myDSCIL,ICPI,Gfound,PVKind,PVIndex,
1157                    keptVPnbr);
1158     mykeptVPnbr = keptVPnbr;
1159   }
1160
1161   // closing edge processing 
1162   // -----------------------
1163   if ((OOclosing || closing)&& !found) {
1164     ProcessVPonclosingR(VP,Face,ShapeIndex,
1165                         transEdge,
1166                         PVKind,PVIndex,
1167                         EPIfound,IEPI);
1168     return;
1169   }
1170
1171   // VP processing 
1172   // -------------
1173   
1174   Standard_Boolean addEPI = Standard_False;
1175   if (!Gfound) {
1176     addEPI = Standard_True; 
1177   } 
1178   else { // EPIfound
1179     TopAbs_Orientation otransEdge = transEdge.Orientation(TopAbs_IN);
1180
1181     Standard_Boolean opporifound,memorifound; opporifound = memorifound = Standard_False;
1182     TopOpeBRepDS_ListOfInterference loIfound; 
1183     const TopOpeBRepDS_ListOfInterference& EPIL = myDS->ShapeInterferences(edge);
1184     Standard_Boolean ok = FUN_sameGsameS(EPIL,PVIndex,iOOFace,loIfound);
1185     if (ok) {
1186       TopOpeBRepDS_PointIterator PI(loIfound); 
1187       // on cree une EPI orientee <transEdge> ssi :
1188       // - il en existe deja une d'orientation opposee a TransEdge
1189       // - il n'en existe pas deja une d'orientation identique a TransEdge
1190       for (; PI.More(); PI.Next()){
1191         TopAbs_Orientation oEPI = PI.Value()->Transition().Orientation(TopAbs_IN);
1192         if (!memorifound) memorifound = ( oEPI == otransEdge );
1193         if (!opporifound) opporifound = ( oEPI == TopAbs::Complement(otransEdge) );
1194         addEPI = (opporifound && ! memorifound);
1195         if (addEPI) break;
1196       }
1197     }
1198     if (!ok) addEPI = Standard_True;
1199   } // EPIfound
1200   
1201 #ifdef DEB
1202   if (GLOBAL_bvpr) debvprmess(myexF1,myexF2,ili,ivp,isi);
1203 #endif  
1204
1205   // xpu030998 : edge has restriction on OOface, do NOT append EPIf
1206   //     cto904A3 (edge19,OOface14,vG16), 
1207   if (myLineINL) {
1208     Standard_Real tola = Precision::Angular()*1.e+4; //dealing with tolerances
1209     gp_Pnt2d uv = VP.SurfaceParameters(OOShapeIndex);
1210     Standard_Boolean EtgOOF = FUN_tool_EtgF(paredge,edge,uv,OOFace,tola);    
1211     Standard_Boolean inERL = FUN_INlos(edge,myERL);
1212     if (EtgOOF && inERL) return; // cto904A3
1213   }
1214   
1215   if ( addEPI && (!dge)) {
1216     // ShapeIndex = 1,2 --> OOShapeIndex = 2,1
1217     // point est sur une seule arete <edge> de <ShapeIndex>
1218     // le Support de l'interference est l'autre 
1219     // face (OOShapeIndex) / ShapeIndex
1220     if (iOOFace == 0) iOOFace = myDS->AddShape(OOFace,OOShapeIndex);
1221     Handle(TopOpeBRepDS_Interference) EPIf;
1222     {
1223       TopOpeBRepDS_Transition T = transEdge; T.Index(iOOFace);
1224       EPIf = MakeEPVInterference(T,iOOFace,PVIndex,paredge,PVKind,TopOpeBRepDS_FACE,SIisvertex);
1225     }
1226     myHDS->StoreInterference(EPIf,edge);
1227   } // addEPI  
1228
1229 } // ProcessVPonR