0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / TopOpeBRep / TopOpeBRep_EdgesIntersector.cxx
1 // File:        TopOpeBRep_EdgesIntersector.cxx
2 // Created:     Fri Oct  7 14:16:31 1994
3 // Author:      Jean Yves LEBEY
4 //              <jyl@bravox>
5
6 #ifdef DRAW
7 #include <TestTopOpeDraw_TTOT.hxx>
8 #include <TopOpeBRepTool_DRAW.hxx>
9 #endif
10
11 #include <TopOpeBRep_EdgesIntersector.ixx>
12
13 #include <TopoDS.hxx>
14 #include <TopoDS_Vertex.hxx>
15 #include <BRep_Tool.hxx>
16 #include <BRepAdaptor_HSurface.hxx>
17 #include <BRepAdaptor_Surface.hxx>
18 #include <Precision.hxx>
19 #include <TopExp.hxx>
20 #include <TopExp_Explorer.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Circ2d.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_Surface.hxx>
25 #include <TopLoc_Location.hxx>
26 #include <Standard_Failure.hxx>
27 #include <OSD_Chronometer.hxx>
28 #include <TopOpeBRepTool_CurveTool.hxx>
29 #include <TopOpeBRepTool_ShapeTool.hxx>
30 #include <GeomTools_CurveSet.hxx>
31 #include <GeomTools_Curve2dSet.hxx>
32 #include <GeomTools_SurfaceSet.hxx>
33 #include <TopOpeBRepTool_2d.hxx>
34 #include <TopOpeBRepTool_TOOL.hxx>
35 #include <TopOpeBRepTool_EXPORT.hxx>
36 #include <TopOpeBRepTool_tol.hxx>
37 #include <TopOpeBRep_Point2d.hxx>
38 #include <TopOpeBRep_define.hxx>
39
40 #ifdef DEB
41 Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceNYI();
42 Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceKRO();
43 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceEDSF();
44 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceDSF();
45 Standard_EXPORT Standard_Boolean TopOpeBRep_GettracePROEDG();
46 Standard_EXPORT Standard_Boolean TopOpeBRep_GetcontextTOL0();
47 Standard_EXPORT Standard_Boolean TopOpeBRep_GetcontextNOFEI();
48 Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceFITOL();
49 Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceEEFF();
50 Standard_EXPORT void debeeff();
51 #include <TopOpeBRepTool_KRO.hxx>
52 Standard_EXPORT TOPKRO KRO_DSFILLER_INTEE("intersection edge/edge");
53 #endif
54
55 // la surface de reference peut etre celle de la 1ere ou la 2eme face 
56 // de l'appel de SetFaces. Ces deux faces sont "SameDomain".
57 // Leurs normales geometriques sont SurfacesSameOriented()
58 // Leurs normales topologiques sont FacesSameOriented()
59 // cas type 1 : 
60 //    face1 FORWARD, normale geometrique Ng1 en +Z 
61 //    face2 REVERSED, normale geometrique Ng2 en -Z 
62 // ==> SurfaceSameOriented = 0, FacesSameOriented = 1
63
64 //=======================================================================
65 //function : TopOpeBRep_EdgesIntersector
66 //purpose  : 
67 //=======================================================================
68 TopOpeBRep_EdgesIntersector::TopOpeBRep_EdgesIntersector()
69 {
70   mySurface1 = new BRepAdaptor_HSurface();
71   mySurface2 = new BRepAdaptor_HSurface();
72   mySurfacesSameOriented = Standard_False;
73   myFacesSameOriented = Standard_False;
74   myTol1 = 0.; // Precision::PConfusion();
75   myTol2 = 0.; // Precision::PIntersection();
76   myDimension = 2;
77   myTolForced = Standard_False;
78   myf1surf1F_sameoriented = Standard_True;
79   myf2surf1F_sameoriented = Standard_True;
80   
81   myNbSegments = 0;
82   myHasSegment = Standard_False;
83   SetSameDomain(Standard_False);
84
85   myNbPoints = 0;
86   myTrueNbPoints = 0;
87   myPointIndex = 0;
88   myip2d = mynp2d = 0;
89   myselectkeep = Standard_True;
90 }
91
92 void TopOpeBRep_EdgesIntersector::Delete()
93 {}
94
95 //=======================================================================
96 //function : SetFaces
97 //purpose  : 
98 //=======================================================================
99 void TopOpeBRep_EdgesIntersector::SetFaces(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
100 {
101   Bnd_Box B1,B2;
102   SetFaces(F1,F2,B1,B2);
103 }
104
105 //=======================================================================
106 //function : SetFaces
107 //purpose  : 
108 //=======================================================================
109 void TopOpeBRep_EdgesIntersector::SetFaces(const TopoDS_Shape& F1,const TopoDS_Shape& F2,const Bnd_Box& B1,const Bnd_Box& B2)
110 {
111   Standard_Boolean computerestriction = Standard_False;
112   
113   Standard_Boolean so11 = Standard_True;
114   Standard_Boolean so21 = Standard_True;
115   myf1surf1F_sameoriented = so11;
116   myf2surf1F_sameoriented = so21;
117   mySurfacesSameOriented = Standard_True;
118   myFacesSameOriented = Standard_True;
119   
120   myFace1 = TopoDS::Face(F1);
121   BRepAdaptor_Surface& S1 = mySurface1->ChangeSurface(); S1.Initialize(myFace1,computerestriction);
122   mySurfaceType1 = S1.GetType();
123   
124   myFace2 = TopoDS::Face(F2);
125   BRepAdaptor_Surface& S2 = mySurface2->ChangeSurface(); S2.Initialize(myFace2,computerestriction);
126   mySurfaceType2 = S2.GetType();
127   
128   TopoDS_Face face1forward = myFace1;
129   face1forward.Orientation(TopAbs_FORWARD);
130   
131   so11 = TopOpeBRepTool_ShapeTool::FacesSameOriented(face1forward,myFace1);
132   myf1surf1F_sameoriented = so11; 
133   
134   so21 = TopOpeBRepTool_ShapeTool::FacesSameOriented(face1forward,myFace2);
135   myf2surf1F_sameoriented = so21;
136   
137   mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2);
138   myFacesSameOriented = TopOpeBRepTool_ShapeTool::FacesSameOriented(myFace1,myFace2);
139
140   if ( !myTolForced ) {
141     FTOL_FaceTolerances2d(B1,B2,myFace1,myFace2,S1,S2,myTol1,myTol2);
142     myTol1 = (myTol1 > 1.e-4)? 1.e-4: myTol1;
143     myTol2 = (myTol2 > 1.e-4)? 1.e-4: myTol2;
144   }
145
146 #ifdef DEB
147   Standard_Integer DEBi = 0;
148   if ( DEBi ) {
149     cout<<"TopOpeBRep_EdgesIntersector::SetFaces : ";
150     cout<<"f1 "; TopAbs::Print(myFace1.Orientation(),cout);
151     cout<< " / f1F : ";
152     if (so11) cout<<"sameoriented"; else cout<<"difforiented"; cout<<endl;
153     cout <<"  ";
154     cout<<"f2 "; TopAbs::Print(myFace2.Orientation(),cout);
155     cout<< " / f1F : ";
156     if (so21) cout<<"sameoriented"; else cout<<"difforiented"; cout<<endl;
157   }
158 #endif
159 }
160
161 //=======================================================================
162 //function : ForceTolerances
163 //purpose  : 
164 //=======================================================================
165 void TopOpeBRep_EdgesIntersector::ForceTolerances(const Standard_Real Tol1,const Standard_Real Tol2)
166 {
167   myTol1 = Tol1;
168   myTol2 = Tol2;
169   myTolForced = Standard_True;
170 }
171
172 #include <IntRes2d_Transition.hxx>
173 static Standard_Boolean TransitionEqualAndExtremity( const IntRes2d_Transition& T1
174                                        ,const IntRes2d_Transition& T2) {
175   if(   T1.PositionOnCurve() == IntRes2d_Head
176      || T1.PositionOnCurve() == IntRes2d_End) {  
177     if(T1.PositionOnCurve() == T2.PositionOnCurve())  {
178       if(T1.TransitionType() == T2.TransitionType()) {
179         if(T1.TransitionType() == IntRes2d_Touch) {
180           if(T1.IsTangent()==T2.IsTangent()) {
181             if(T1.Situation() == T2.Situation()) {
182               if(T1.IsOpposite() == T2.IsOpposite()) {
183                 return(Standard_True);
184               }
185             }
186           }
187         }
188         else {
189           return(Standard_True);
190         }
191       }
192     }
193   }
194   return(Standard_False);
195 }
196
197 //  Modified by Sergey KHROMOV - Fri Jan 11 14:49:48 2002 Begin
198 static Standard_Boolean IsTangentSegment(const IntRes2d_IntersectionPoint &P1,
199                                          const IntRes2d_IntersectionPoint &P2,
200                                          const Geom2dAdaptor_Curve        &aC1,
201                                          const Geom2dAdaptor_Curve        &aC2,
202                                          const Standard_Real               aTolConf) {
203   const gp_Pnt2d            &aP2d1   = P1.Value();
204   const gp_Pnt2d            &aP2d2   = P2.Value();
205   const IntRes2d_Transition &aTrans1 = P1.TransitionOfFirst();
206   const IntRes2d_Transition &aTrans2 = P2.TransitionOfFirst();
207
208   if (aTrans1.TransitionType() == IntRes2d_Touch ||
209       aTrans2.TransitionType() == IntRes2d_Touch) {
210     Standard_Real aSqrDistPP   = aP2d1.SquareDistance(aP2d2);
211
212     if (aSqrDistPP <= aTolConf) {
213       Standard_Real aParDist1 = Abs(P1.ParamOnFirst() - P2.ParamOnFirst());
214       Standard_Real aParDist2 = Abs(P1.ParamOnSecond() - P2.ParamOnSecond());
215       Standard_Real aResol1   = aC1.Resolution(aTolConf);
216       Standard_Real aResol2   = aC2.Resolution(aTolConf);
217
218       if (aParDist1*aParDist1 <= aResol1 &&
219           aParDist2*aParDist2 <= aResol2)
220         return Standard_True;
221     }
222   }
223
224   return Standard_False;
225 }
226 //  Modified by Sergey KHROMOV - Fri Jan 11 14:49:49 2002 End
227
228
229 //------------------------------------------------------------------------
230 Standard_Boolean EdgesIntersector_checkT1D(const TopoDS_Edge& E1,const TopoDS_Edge& E2,const TopoDS_Vertex& vG,
231                               TopOpeBRepDS_Transition& newT)
232 //------------------------------------------------------------------------
233      // E1 sdm E2, interfers with E2 at vertex vG
234      // vG is vertex of E2, but not vertex of E1
235      // purpose : get newT / attached to E1, I1d=(newT(E2),G,E2)
236 {
237 #define FIRST (1)
238 #define LAST  (2)
239 #define CLOSING (3)
240   
241   newT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN);
242   Standard_Integer ovine = FUN_tool_orientVinE(vG,E2);
243   if      (ovine == 0) {
244     return Standard_False;
245   }
246   else if (ovine == CLOSING) {
247     newT.Set(TopAbs_INTERNAL);
248     return Standard_True;
249   }
250
251   Standard_Boolean first = (ovine == FIRST);
252   Standard_Boolean last  = (ovine == LAST);
253
254   TopOpeBRepDS_Config C = TopOpeBRepDS_SAMEORIENTED;
255   Standard_Boolean sso = TopOpeBRepTool_ShapeTool::ShapesSameOriented(E1,E2);
256   if (!sso) C = TopOpeBRepDS_DIFFORIENTED;
257   
258   Standard_Boolean SO = (C == TopOpeBRepDS_SAMEORIENTED);
259   Standard_Boolean DO = (C == TopOpeBRepDS_DIFFORIENTED);
260   TopAbs_Orientation o1 = E1.Orientation();
261   if (o1 == TopAbs_REVERSED) {SO = !SO; DO = !DO;} // relative to E1 FORWARD
262   
263   Standard_Boolean reversed = (SO && first) || (DO && last);
264   Standard_Boolean forward  = (SO && last)  || (DO && first);
265   if (reversed) newT.Set(TopAbs_REVERSED);
266   if (forward)  newT.Set(TopAbs_FORWARD);
267   return (reversed || forward);
268 } // EdgesIntersector_checkT1D
269
270
271 //modified by NIZNHY-PKV Fri Nov  5 12:27:07 1999 from
272 #include <BRepAdaptor_Surface.hxx>
273 //modified by NIZNHY-PKV Fri Nov  5 12:27:10 1999 to
274 //=======================================================================
275 //function : Perform
276 //purpose  : 
277 //=======================================================================
278   void TopOpeBRep_EdgesIntersector::Perform(const TopoDS_Shape& E1,const TopoDS_Shape& E2,const Standard_Boolean ReduceSegment)
279 {
280   mysp2d.Clear();
281   myip2d = 1; mynp2d = 0;
282
283   myEdge1 = TopoDS::Edge(E1);
284   myEdge2 = TopoDS::Edge(E2);
285   
286   Standard_Real first,last,tole,tolpc;
287   gp_Pnt2d pfirst,plast;
288   Handle(Geom2d_Curve) PC1;
289   //modified by NIZNHY-PKV Thu Nov  4 16:08:05 1999 f
290   
291   BRepAdaptor_Surface aSurface1(myFace1), aSurface2(myFace2);
292   GeomAbs_SurfaceType aSurfaceType1=aSurface1.GetType(), 
293                       aSurfaceType2=aSurface2.GetType();
294   
295   if (aSurfaceType1==GeomAbs_Sphere && aSurfaceType2==GeomAbs_Sphere) {
296     PC1 = FC2D_MakeCurveOnSurface (myEdge1,myFace1,first,last,tolpc, Standard_True);
297   }
298   else {
299     PC1 = FC2D_CurveOnSurface(myEdge1,myFace1,first,last,tolpc);
300   }
301   //modified by NIZNHY-PKV Thu Nov  4 15:44:13 1999 to
302
303   if (PC1.IsNull()) 
304     Standard_Failure::Raise("EdgesIntersector::Perform : no 2d curve");
305   
306   myCurve1.Load(PC1);
307   BRep_Tool::UVPoints(myEdge1,myFace1,pfirst,plast);
308   tole = BRep_Tool::Tolerance(myEdge1);
309   myDomain1.SetValues(pfirst,first,tole,plast,last,tole);
310   
311 #ifdef DEB
312   Standard_Boolean trc = Standard_False;
313   if (trc) {
314     cout<<"ed1 on fa1 : {pfirst=("<<pfirst.X()<<" "<<pfirst.Y()<<"), first="<<first<<"\n";
315     cout<<"              plast =("<<plast.X()<<" "<<plast.Y()<<"),last="<<last<<"}"<<endl;}
316 #endif  
317   
318   Standard_Boolean memesfaces = myFace1.IsSame(myFace2);
319   Standard_Boolean memesupport = Standard_False;
320   TopLoc_Location L1,L2;
321   const Handle(Geom_Surface) S1 = BRep_Tool::Surface(myFace1,L1);
322   const Handle(Geom_Surface) S2 = BRep_Tool::Surface(myFace2,L2);
323   if (S1 == S2 && L1 == L2) memesupport=Standard_True;
324   
325   if ( mySurfaceType1 == GeomAbs_Plane || memesfaces || memesupport) {    
326     Handle(Geom2d_Curve) PC2 = FC2D_CurveOnSurface(myEdge2,myFace1,first,last,tolpc);
327     myCurve2.Load(PC2);
328     BRep_Tool::UVPoints(myEdge2,myFace1,pfirst,plast);
329     tole = BRep_Tool::Tolerance(myEdge2);
330     myDomain2.SetValues(pfirst,first,tole,plast,last,tole);
331     
332 #ifdef DEB
333     if (trc) {
334       cout<<"ed2 on fa1 : {pfirst=("<<pfirst.X()<<" "<<pfirst.Y()<<"), first="<<first<<"\n";
335       cout<<"              plast =("<<plast.X()<<" "<<plast.Y()<<"),last="<<last<<"}"<<endl;}
336 #endif
337     
338   }
339
340   else {
341
342     Handle(Geom2d_Curve) PC2on1; Handle(Geom_Curve) NC;
343     Standard_Boolean dgE2 = BRep_Tool::Degenerated(myEdge2);
344     if (dgE2) { //xpu210998 : cto900Q3
345       TopExp_Explorer exv(myEdge2, TopAbs_VERTEX);
346       const TopoDS_Vertex& v2 = TopoDS::Vertex(exv.Current());
347       gp_Pnt pt2 = BRep_Tool::Pnt(v2);
348       gp_Pnt2d uv2; Standard_Real d; Standard_Boolean ok = FUN_tool_projPonF(pt2,myFace1,uv2,d);
349       if (!ok) 
350         return;//nyiRaise
351
352       Handle(Geom_Surface) S1 = BRep_Tool::Surface(myFace1);
353       Standard_Boolean apex = FUN_tool_onapex(uv2,S1);
354       if (apex) {
355         TopoDS_Vertex vf,vl; TopExp::Vertices(myEdge1,vf,vl);
356         gp_Pnt ptf = BRep_Tool::Pnt(vf); Standard_Real df = pt2.Distance(ptf); 
357         gp_Pnt ptl = BRep_Tool::Pnt(vl);
358 #ifdef DEB
359         Standard_Real dl =
360 #endif
361                  pt2.Distance(ptl); 
362         Standard_Real tolf = BRep_Tool::Tolerance(vf);
363 #ifdef DEB
364         Standard_Real toll =
365 #endif
366                    BRep_Tool::Tolerance(vl);
367         Standard_Boolean onf = (df < tolf);
368         TopoDS_Vertex v1 = onf ? vf : vl;
369         TopTools_IndexedDataMapOfShapeListOfShape mapVE; TopExp::MapShapesAndAncestors(myFace1,TopAbs_VERTEX,TopAbs_EDGE,mapVE);
370         const TopTools_ListOfShape& Edsanc = mapVE.FindFromKey(v1);
371         TopTools_ListIteratorOfListOfShape it(Edsanc);
372         for (; it.More(); it.Next()){
373           const TopoDS_Edge& ee = TopoDS::Edge(it.Value());
374           Standard_Boolean dgee = BRep_Tool::Degenerated(ee);
375           if (!dgee) continue;
376 //        Standard_Real f,l;
377           PC2on1 = BRep_Tool::CurveOnSurface(ee,myFace1,first,last);      
378         }
379       }
380       else {} // NYIxpu210998
381     } //dgE2
382     else {
383       // project curve of edge 2 on surface of face 1
384       TopLoc_Location loc ;
385       Handle(Geom_Curve) C = BRep_Tool::Curve(myEdge2,loc,first,last); 
386       NC = Handle(Geom_Curve)::DownCast(C->Transformed(loc.Transformation()));
387       Standard_Real tolreached2d;
388
389       //modified by NIZNHY-PKV Fri Nov  5 12:29:13 1999 from
390       if (aSurfaceType1==GeomAbs_Sphere && aSurfaceType2==GeomAbs_Sphere) {
391         PC2on1 =  FC2D_MakeCurveOnSurface (myEdge2, myFace1, first, last, tolpc, Standard_True);
392       }
393       else { 
394         PC2on1 = TopOpeBRepTool_CurveTool::MakePCurveOnFace(myFace1,NC,tolreached2d);
395       }
396       //modified by NIZNHY-PKV Thu Nov  4 14:52:25 1999 t
397    
398     }
399     
400     if (!PC2on1.IsNull()) {
401       myCurve2.Load(PC2on1);
402       tole = BRep_Tool::Tolerance(myEdge2);
403       PC2on1->D0(first,pfirst);
404       PC2on1->D0(last,plast);
405       myDomain2.SetValues(pfirst,first,tole,plast,last,tole);
406 #ifdef DEB
407       if ( TopOpeBRep_GettracePROEDG() ) {
408         cout<<"------------ projection de curve"<<endl;
409         cout<<"--- Curve : "<<endl;
410         GeomTools_CurveSet::PrintCurve(NC,cout);
411         cout<<"--- nouvelle PCurve : "<<endl;
412         GeomTools_Curve2dSet::PrintCurve2d(PC2on1,cout);
413         Handle(Geom_Surface) S1 = BRep_Tool::Surface(myFace1);
414         cout<<"--- sur surface : "<<endl;
415         GeomTools_SurfaceSet::PrintSurface(S1,cout);
416         cout<<endl;
417       }
418 #endif
419     }
420     else return;
421   }
422   
423   // compute the intersection
424 #ifdef DEB
425   if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTEE.Start();
426 #endif
427   
428   Standard_Real tol1 = myTol1, tol2 = myTol2;
429 // Wrong !!!
430 /*  if ( !myTolForced ) {
431     if ( t1 != t2 ) {
432       //#ifdef DEB // JYL 28/09/98 : temporaire
433       //if ( TopOpeBRep_GetcontextTOL0() ) { // JYL 28/09/98 : temporaire
434       tol1 = 0.; // JYL 28/09/98 : temporaire
435       tol2 = 0.; // JYL 28/09/98 : temporaire
436       //} // JYL 28/09/98 : temporaire
437       //#endif // JYL 28/09/98 : temporaire
438     }
439   }
440 */
441   
442 #ifdef DEB
443   if (TopOpeBRep_GettraceFITOL()) {
444     cout<<"EdgesIntersector : Perform";
445 #ifdef DRAW
446     GeomAbs_CurveType t1 = myCurve1.GetType();
447     GeomAbs_CurveType t2 = myCurve2.GetType();
448     TCollection_AsciiString s1;TestTopOpeDraw_TTOT::CurveToString(t1,s1);cout<<" "<<s1;
449     TCollection_AsciiString s2;TestTopOpeDraw_TTOT::CurveToString(t2,s2);cout<<" "<<s2;
450 #endif
451     cout<<endl;
452     cout<<"                   tol1 = "<<tol1<<endl;
453     cout<<"                   tol2 = "<<tol2<<endl;
454   }
455 #endif
456
457   myIntersector.Perform(myCurve1,myDomain1,myCurve2,myDomain2,tol1,tol2);
458
459   Standard_Integer nbp = myIntersector.NbPoints();
460   Standard_Integer nbs = myIntersector.NbSegments();
461
462   mylpnt.Clear(); mylseg.Clear();
463 //  for (Standard_Integer p=1; p<=nbp; p++) mylpnt.Append(myIntersector.Point(p));
464   Standard_Integer p ;
465   for ( p=1; p<=nbp; p++) mylpnt.Append(myIntersector.Point(p));
466   for (Standard_Integer s=1; s<=nbs; s++) mylseg.Append(myIntersector.Segment(s));
467   
468   Standard_Boolean filter = Standard_True;
469 #ifdef DEB
470   Standard_Boolean nofilter = TopOpeBRep_GetcontextNOFEI(); if (nofilter) filter = Standard_False;
471 #endif
472   
473   //-- Filter :
474   if (filter) {
475     Standard_Boolean fin;
476     do { 
477       fin=Standard_True;
478       for(p=1;p<nbp && fin ;p++) { 
479         const IntRes2d_IntersectionPoint& P1=mylpnt.Value(p);
480         const IntRes2d_IntersectionPoint& P2=mylpnt.Value(p+1);
481         if(   TransitionEqualAndExtremity(P1.TransitionOfFirst(),P2.TransitionOfFirst())
482            || TransitionEqualAndExtremity(P1.TransitionOfSecond(),P2.TransitionOfSecond()) ) { 
483 #ifdef DEB
484           Standard_Boolean TRC = Standard_True;
485           if (TRC) cout<<"\n Egalite de transitions \n"<<endl;
486 #endif
487           fin = Standard_False;
488           mylpnt.Remove(p);
489           nbp--;
490         }
491 //  Modified by Sergey KHROMOV - Fri Jan 11 10:31:38 2002 Begin
492         else if (IsTangentSegment(P1, P2, myCurve1, myCurve2, Max(tol1, tol2))) {
493           const IntRes2d_Transition &aTrans = P2.TransitionOfFirst();
494
495           fin = Standard_False;
496           if (aTrans.TransitionType() == IntRes2d_Touch)
497             mylpnt.Remove(p);
498           else
499             mylpnt.Remove(p + 1);
500           nbp--;
501         }
502 //  Modified by Sergey KHROMOV - Fri Jan 11 10:31:39 2002 End
503       }
504     }
505     while(fin==Standard_False);  
506   }
507   //-- End filter 
508     
509   myNbSegments = mylseg.Length();
510   myHasSegment = (myNbSegments != 0);
511   ComputeSameDomain();
512
513   myNbPoints = mylpnt.Length();
514   myTrueNbPoints = myNbPoints + 2 * myNbSegments;
515   myPointIndex = 0;
516
517 #ifdef DEB
518   if (TopOpeBRep_GettraceEEFF()) debeeff();
519 #endif
520   
521   MakePoints2d();
522   if (ReduceSegment) ReduceSegments();
523   
524   // xpu010998 : cto900J1, e5 sdm e13, IntPatch (Touch,Inside) -> 
525   //             faulty INTERNAL transition at G=v9 :
526   // xpu281098 : cto019D2, e3 sdm e9, faulty EXTERNAL transition
527   Standard_Boolean esd = SameDomain();
528   for (InitPoint();MorePoint();NextPoint()) {
529     TopOpeBRep_Point2d& P2D = mysp2d(myip2d);
530     Standard_Boolean isvertex1 = P2D.IsVertex(1);
531     Standard_Boolean isvertex2 = P2D.IsVertex(2);
532     Standard_Boolean isvertex = isvertex1 || isvertex2;
533     
534     if (isvertex && esd) {
535       TopOpeBRepDS_Transition& T1 = P2D.ChangeTransition(1);
536       TopOpeBRepDS_Transition& T2 = P2D.ChangeTransition(2);
537       
538       Standard_Boolean newT1=Standard_False, newT2=Standard_False;
539       Standard_Boolean isvertex12 = isvertex1 && isvertex2;
540       Standard_Boolean isvertex22 = isvertex2 && !isvertex12;
541       Standard_Boolean isvertex11 = isvertex1 && !isvertex12;
542
543       Standard_Boolean T1INT = (T1.Orientation(TopAbs_IN) == TopAbs_INTERNAL);
544 #ifdef DEB
545       Standard_Boolean T1EXT = (T1.Orientation(TopAbs_IN) == TopAbs_EXTERNAL);
546 #endif
547       if (T1INT && isvertex2 && !isvertex1) {
548         const TopoDS_Vertex& V2 = P2D.Vertex(2);        
549         TopOpeBRepDS_Transition newT; Standard_Boolean computed = ::EdgesIntersector_checkT1D(myEdge1,myEdge2,V2,newT);
550         if (!computed) newT1 = Standard_False;
551         else           T1.Set(newT.Orientation(TopAbs_IN));
552       }
553
554       Standard_Boolean T2INT = (T2.Orientation(TopAbs_IN) == TopAbs_INTERNAL);
555       Standard_Boolean T2EXT = (T2.Orientation(TopAbs_IN) == TopAbs_EXTERNAL);
556       Standard_Boolean INTEXT2 = T2INT || T2EXT;
557       if (INTEXT2 && isvertex1 && !isvertex2) {
558         const TopoDS_Vertex& V1 = P2D.Vertex(1);
559         TopOpeBRepDS_Transition newT; Standard_Boolean computed = ::EdgesIntersector_checkT1D(myEdge2,myEdge1,V1,newT);
560         if (!computed) newT2 = Standard_False;
561         else           T2.Set(newT.Orientation(TopAbs_IN));
562       }      
563       
564       // xpu121098 : cto900I7 (e12on,vG14)
565       TopoDS_Vertex vcl2; Standard_Boolean clE2 = TopOpeBRepTool_TOOL::ClosedE(myEdge2,vcl2);
566       Standard_Boolean nT1 = ( !T1INT && clE2 && isvertex22 && vcl2.IsSame(P2D.Vertex(2)) );
567       if (nT1) T1.Set(TopAbs_INTERNAL);
568       TopoDS_Vertex vcl1; Standard_Boolean clE1 = TopOpeBRepTool_TOOL::ClosedE(myEdge1,vcl1);
569       Standard_Boolean nT2 = ( !T2INT && clE1 && isvertex11 && vcl1.IsSame(P2D.Vertex(1)) );
570       if (nT2) T2.Set(TopAbs_INTERNAL);
571       
572 #ifdef DEB
573       if (trc&&(newT1||nT1)) {cout<<"-> ** newT on e(1) = ";T1.Dump(cout);cout<<endl;}
574       if (trc&&(newT2||nT2)) {cout<<"-> ** newT on e(2) = ";T2.Dump(cout);cout<<endl;}
575 #endif
576     } // (isvertex && esd) 
577   } // MorePoint
578
579
580 #ifdef DEB
581   if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTEE.Stop();
582 #endif
583 } // Perform
584
585 //=======================================================================
586 //function : Dimension
587 //purpose  : 
588 //=======================================================================
589 void TopOpeBRep_EdgesIntersector::Dimension(const Standard_Integer Dim)
590 {
591   if (Dim == 1 || Dim == 2) {
592     myDimension = Dim;
593   }
594 }
595
596 //=======================================================================
597 //function : Dimension
598 //purpose  : 
599 //=======================================================================
600 Standard_Integer TopOpeBRep_EdgesIntersector::Dimension() const
601 {
602   return myDimension;
603 }
604
605 //=======================================================================
606 //function : ComputeSameDomain
607 //purpose  : 
608 //=======================================================================
609 Standard_Boolean TopOpeBRep_EdgesIntersector::ComputeSameDomain()
610 {
611   const Geom2dAdaptor_Curve& C1 = Curve(1);
612   const Geom2dAdaptor_Curve& C2 = Curve(2);
613   GeomAbs_CurveType t1 = C1.GetType();
614   GeomAbs_CurveType t2 = C2.GetType();
615
616   if (!myHasSegment) 
617     return SetSameDomain(Standard_False);
618   
619   Standard_Boolean tt = (t1 == t2);
620   if (!tt) 
621     return SetSameDomain(Standard_False);
622   
623   if (t1 == GeomAbs_Line) 
624     return SetSameDomain(Standard_True);
625   
626   if (t1 != GeomAbs_Circle) {
627 #ifdef DEB
628     if (TopOpeBRepTool_GettraceNYI()) 
629       cout<<"TopOpeBRep_EdgesIntersector : EdgesSameDomain on NYI curve type"<<endl;
630 #endif
631     return SetSameDomain(Standard_False);
632   }
633
634   gp_Circ2d c1 = C1.Circle();
635   gp_Circ2d c2 = C2.Circle();
636   Standard_Real r1 = c1.Radius();
637   Standard_Real r2 = c2.Radius();
638 //  Standard_Boolean rr = (r1 == r2);
639   Standard_Boolean rr = (Abs(r1-r2) < Precision::Confusion()); //xpu281098 (cto019D2) tolerance a revoir
640   if (!rr) return SetSameDomain(Standard_False);
641
642   const gp_Pnt2d& p1 = c1.Location();
643   const gp_Pnt2d& p2 = c2.Location();
644
645   const BRepAdaptor_Surface& BAS1 = Surface(1);
646   Standard_Real u1,v1; p1.Coord(u1,v1); gp_Pnt P1 = BAS1.Value(u1,v1);
647   Standard_Real u2,v2; p2.Coord(u2,v2); gp_Pnt P2 = BAS1.Value(u2,v2);// recall myCurve2=C2d(myEdge2,myFace1);
648   Standard_Real dpp = P1.Distance(P2);
649   Standard_Real tol1 = BRep_Tool::Tolerance(TopoDS::Edge(Edge(1)));
650   Standard_Real tol2 = BRep_Tool::Tolerance(TopoDS::Edge(Edge(2)));
651   Standard_Real tol = tol1 + tol2;
652   Standard_Boolean esd = (dpp <= tol);
653   if (esd) return SetSameDomain(Standard_True);
654
655   return SetSameDomain(Standard_False);
656 } // ComputeSameDomain
657
658 //=======================================================================
659 //function : SetSameDomain
660 //purpose  : 
661 //=======================================================================
662 Standard_Boolean TopOpeBRep_EdgesIntersector::SetSameDomain(const Standard_Boolean B)
663 {
664   mySameDomain = B;
665   return B;
666 }
667
668 //=======================================================================
669 //function : MakePoints2d
670 //purpose  : 
671 //=======================================================================
672 void TopOpeBRep_EdgesIntersector::MakePoints2d()
673 {
674   mysp2d.Clear();
675   TopAbs_Orientation E1ori = myEdge1.Orientation();
676   TopAbs_Orientation E2ori = myEdge2.Orientation();
677   for (InitPoint1();MorePoint1();NextPoint1()) {
678     const IntRes2d_IntersectionPoint& IP = Point1();
679     TopOpeBRep_Point2d p2d;
680     p2d.SetPint(IP);
681     p2d.SetTransition(1,Transition1(1,E2ori));
682     p2d.SetTransition(2,Transition1(2,E1ori));
683     p2d.SetParameter(1,Parameter1(1));
684     p2d.SetParameter(2,Parameter1(2));
685     Standard_Boolean isv1 = IsVertex1(1); p2d.SetIsVertex(1,isv1);
686     if (isv1) p2d.SetVertex(1,TopoDS::Vertex(Vertex1(1)));
687     Standard_Boolean isv2 = IsVertex1(2); p2d.SetIsVertex(2,isv2);
688     if (isv2) p2d.SetVertex(2,TopoDS::Vertex(Vertex1(2)));
689     p2d.SetIsPointOfSegment(IsPointOfSegment1());
690     p2d.SetSegmentAncestors(0,0);
691     p2d.SetStatus(Status1());
692     p2d.SetValue(Value1());
693     p2d.SetValue2d(IP.Value());
694     p2d.SetTolerance(ToleranceMax());
695     p2d.SetEdgesConfig(EdgesConfig1());
696     p2d.SetIndex(Index1());
697     mysp2d.Append(p2d);
698   }
699   myip2d = 1; mynp2d = mysp2d.Length();
700 }
701
702 //=======================================================================
703 //function : ReduceSegment
704 //purpose  : 
705 //=======================================================================
706 Standard_Boolean TopOpeBRep_EdgesIntersector::ReduceSegment(TopOpeBRep_Point2d& psa,
707                                       TopOpeBRep_Point2d& psb,
708                                       TopOpeBRep_Point2d& Pn) const
709 {
710   Standard_Boolean reduced = Standard_False;
711   Standard_Integer ixpsa = psa.Index();
712   Standard_Integer ixpsb = psb.Index();
713   
714   Standard_Boolean pospsa = psa.IsPointOfSegment();
715   TopOpeBRep_P2Dstatus stspsa = psa.Status();
716   Standard_Real tpsa1 = psa.Parameter(1);
717   Standard_Real tpsa2 = psa.Parameter(2);
718   const TopOpeBRepDS_Transition& Tpsa1 = psa.Transition(1);
719   const TopOpeBRepDS_Transition& Tpsa2 = psa.Transition(2);
720   
721   Standard_Boolean pospsb = psb.IsPointOfSegment();
722   TopOpeBRep_P2Dstatus stspsb = psb.Status();
723   Standard_Real tpsb1 = psb.Parameter(1);
724   Standard_Real tpsb2 = psb.Parameter(2);
725   const TopOpeBRepDS_Transition& Tpsb1 = psb.Transition(1);
726   const TopOpeBRepDS_Transition& Tpsb2 = psb.Transition(2);
727   
728   Standard_Boolean conda = (pospsa && (stspsa == TopOpeBRep_P2DSGF));
729   Standard_Boolean condb = (pospsb && (stspsb == TopOpeBRep_P2DSGL));
730   Standard_Boolean cond = (conda && condb);
731   
732   if (cond) {
733     reduced = Standard_True;
734     
735     Standard_Real tm1 = (tpsa1 + tpsb1)/2.; Pn.SetParameter(1,tm1);
736     Standard_Real tm2 = (tpsa2 + tpsb2)/2.; Pn.SetParameter(2,tm2);
737     
738     TopOpeBRepDS_Transition Tn1;
739     Tn1.Before(Tpsa1.Before(),Tpsa1.ShapeBefore());
740     Tn1.After (Tpsb1.After(),Tpsb1.ShapeAfter());
741     Pn.SetTransition(1,Tn1);
742     TopOpeBRepDS_Transition Tn2;
743     Tn2.Before(Tpsa2.Before(),Tpsa2.ShapeBefore());
744     Tn2.After (Tpsb2.After(),Tpsb2.ShapeAfter());
745     Pn.SetTransition(2,Tn2);
746     
747     const gp_Pnt& P3Dpsa = psa.Value();
748     const gp_Pnt& P3Dpsb = psb.Value();
749     gp_Pnt P3Dn((P3Dpsa.X()+P3Dpsb.X())/2,
750                 (P3Dpsa.Y()+P3Dpsb.Y())/2,
751                 (P3Dpsa.Z()+P3Dpsb.Z())/2);
752     Pn.SetValue(P3Dn);
753     const gp_Pnt2d& P2Dpsa = psa.Value2d();
754     const gp_Pnt2d& P2Dpsb = psb.Value2d();
755     gp_Pnt2d P2Dn((P2Dpsa.X()+P2Dpsb.X())/2,
756                   (P2Dpsa.Y()+P2Dpsb.Y())/2);
757     Pn.SetValue2d(P2Dn);
758     
759     Standard_Real tolpsa = psa.Tolerance();
760     Standard_Real tolpsb = psb.Tolerance();
761     Standard_Real toln = (tolpsa + tolpsb)*1.5;
762     Pn.SetTolerance(toln);
763     
764     Pn.SetIsPointOfSegment(Standard_False);
765     Pn.SetSegmentAncestors(ixpsa,ixpsb);
766     psa.SetKeep(Standard_False);
767     psb.SetKeep(Standard_False);
768     
769     TopOpeBRepDS_Config cpsa = psa.EdgesConfig();
770
771     Pn.SetEdgesConfig(cpsa);
772     
773     Standard_Boolean isvpsa1 = psa.IsVertex(1);if (isvpsa1) Pn.SetVertex(1,psa.Vertex(1));
774     Standard_Boolean isvpsa2 = psa.IsVertex(2);if (isvpsa2) Pn.SetVertex(2,psa.Vertex(2));
775     Standard_Boolean isvpsb1 = psb.IsVertex(1);if (isvpsb1) Pn.SetVertex(1,psb.Vertex(1));
776     Standard_Boolean isvpsb2 = psb.IsVertex(2);if (isvpsb2) Pn.SetVertex(2,psb.Vertex(2));
777   }
778   
779   return reduced;
780 } // ReduceSegment
781
782 //=======================================================================
783 //function : ReduceSegments
784 //purpose  : 
785 //=======================================================================
786 void TopOpeBRep_EdgesIntersector::ReduceSegments()
787 {
788   Standard_Boolean condredu = (myHasSegment && !mySameDomain);
789   if (!condredu) return;
790
791 #ifdef DEB
792   Standard_Boolean trc = TopOpeBRepDS_GettraceDSF(); trc = trc || TopOpeBRepDS_GettraceEDSF();
793   if (trc) Dump("AVANT ReduceSegments");
794 #endif
795   
796   Standard_Integer ip = 1;Standard_Integer np = mynp2d;
797   while (ip < np) {
798     TopOpeBRep_Point2d& psa = mysp2d(ip);
799     TopOpeBRep_Point2d& psb = mysp2d(ip+1);
800     TopOpeBRep_Point2d pn;
801     Standard_Boolean reduced = ReduceSegment(psa,psb,pn);
802     if (reduced) {
803       pn.SetIndex(++mynp2d);
804       mysp2d.Append(pn);
805     }
806     ip++;
807   }
808   
809   mylseg.Clear();
810   myNbSegments = mylseg.Length();
811   myHasSegment = (myNbSegments != 0);
812   myTrueNbPoints = myNbPoints + 2 * myNbSegments;
813
814 } // ReduceSegments
815
816
817 //=======================================================================
818 //function : IsEmpty
819 //purpose  : 
820 //=======================================================================
821 Standard_Boolean TopOpeBRep_EdgesIntersector::IsEmpty () 
822 {
823   return (mynp2d == 0);
824 }
825
826 //=======================================================================
827 //function : HasSegment
828 //purpose  : 
829 //=======================================================================
830 Standard_Boolean TopOpeBRep_EdgesIntersector::HasSegment () const 
831 {
832   return myHasSegment;
833 }
834
835 //=======================================================================
836 //function : SameDomain
837 //purpose  : 
838 //=======================================================================
839 Standard_Boolean TopOpeBRep_EdgesIntersector::SameDomain() const
840 {
841   return mySameDomain;
842 }
843
844 //=======================================================================
845 //function : Edge
846 //purpose  : 
847 //=======================================================================
848 const TopoDS_Shape& TopOpeBRep_EdgesIntersector::Edge(const Standard_Integer Index) const 
849 {
850   if      ( Index == 1 ) return myEdge1;
851   else if ( Index == 2 ) return myEdge2;
852   else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Edge");
853   
854   return myEdge1;
855 }
856
857 //=======================================================================
858 //function : Curve
859 //purpose  : 
860 //=======================================================================
861 const Geom2dAdaptor_Curve& TopOpeBRep_EdgesIntersector::Curve(const Standard_Integer Index) const 
862 {
863   if      ( Index == 1 ) return myCurve1;
864   else if ( Index == 2 ) return myCurve2;
865   else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Curve");
866   
867   return myCurve1;
868 }
869
870 //=======================================================================
871 //function : Face
872 //purpose  : 
873 //=======================================================================
874 const TopoDS_Shape& TopOpeBRep_EdgesIntersector::Face(const Standard_Integer Index) const 
875 {
876   if      ( Index == 1 ) return myFace1;
877   else if ( Index == 2 ) return myFace2;
878   else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Face");
879   
880   return myFace1;
881 }
882
883 //=======================================================================
884 //function : Surface
885 //purpose  : 
886 //=======================================================================
887 const BRepAdaptor_Surface& TopOpeBRep_EdgesIntersector::Surface(const Standard_Integer Index) const 
888 {
889   if      ( Index == 1 ) return mySurface1->ChangeSurface();
890   else if ( Index == 2 ) return mySurface2->ChangeSurface();
891   else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Surface");
892   
893   return mySurface1->ChangeSurface();
894 }
895
896 //=======================================================================
897 //function : SurfacesSameOriented
898 //purpose  : 
899 //=======================================================================
900 Standard_Boolean TopOpeBRep_EdgesIntersector::SurfacesSameOriented () const
901 {
902   return mySurfacesSameOriented;
903 }
904
905 //=======================================================================
906 //function : FacesSameOriented
907 //purpose  : 
908 //=======================================================================
909 Standard_Boolean TopOpeBRep_EdgesIntersector::FacesSameOriented () const
910 {
911   return myFacesSameOriented;
912 }
913
914 //=======================================================================
915 //function : InitPoint
916 //purpose  : 
917 //=======================================================================
918 void TopOpeBRep_EdgesIntersector::InitPoint(const Standard_Boolean selectkeep)
919 {
920   myselectkeep = selectkeep;
921   myip2d = 1; mynp2d = mysp2d.Length();
922   Find();
923 }
924
925 //=======================================================================
926 //function : MorePoint
927 //purpose  : 
928 //=======================================================================
929 Standard_Boolean TopOpeBRep_EdgesIntersector::MorePoint() const 
930 {
931   Standard_Boolean b = (myip2d <= mynp2d);
932   return b;
933 }
934
935 //=======================================================================
936 //function : NextPoint
937 //purpose  : 
938 //=======================================================================
939 void TopOpeBRep_EdgesIntersector::NextPoint()
940 {
941   myip2d++;
942   Find();
943 }
944
945 //=======================================================================
946 //function : Find
947 //purpose  : 
948 //=======================================================================
949 void TopOpeBRep_EdgesIntersector::Find()
950 {
951   while (myip2d <= mynp2d) {
952     if (myselectkeep) {
953       Standard_Boolean kf = mysp2d(myip2d).Keep();
954       if (kf) break;
955       else myip2d++;
956     }
957     else {
958       break;
959     }
960   }
961 }
962
963 //=======================================================================
964 //function : Points
965 //purpose  : 
966 //=======================================================================
967 const TopOpeBRep_SequenceOfPoint2d& TopOpeBRep_EdgesIntersector::Points() const
968 {
969   return mysp2d;
970 }
971
972 //=======================================================================
973 //function : Point
974 //purpose  : 
975 //=======================================================================
976 const TopOpeBRep_Point2d& TopOpeBRep_EdgesIntersector::Point() const
977 {
978   return mysp2d(myip2d);
979 }
980
981 //=======================================================================
982 //function : Point
983 //purpose  : 
984 //=======================================================================
985 const TopOpeBRep_Point2d& TopOpeBRep_EdgesIntersector::Point(const Standard_Integer I) const
986 {
987   if (I<1 || I>mysp2d.Length()) Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Point(I)");
988   return mysp2d(I);
989 }
990
991 //=======================================================================
992 //function : ToleranceMax
993 //purpose  : 
994 //=======================================================================
995 Standard_Real TopOpeBRep_EdgesIntersector::ToleranceMax() const 
996 {
997   Standard_Real tol = Max(myTol1,myTol2);
998   return tol;
999 }
1000
1001 //=======================================================================
1002 //function : Tolerances
1003 //purpose  : 
1004 //=======================================================================
1005 void TopOpeBRep_EdgesIntersector::Tolerances(Standard_Real& tol1, Standard_Real& tol2) const 
1006 {
1007   tol1 = myTol1;
1008   tol2 = myTol2;
1009 }
1010
1011 //=======================================================================
1012 //function : NbPoints
1013 //purpose  : (debug)
1014 //=======================================================================
1015 Standard_Integer TopOpeBRep_EdgesIntersector::NbPoints() const 
1016
1017   return myNbPoints;
1018 }
1019
1020 //=======================================================================
1021 //function : NbSegments
1022 //purpose  : (debug)
1023 //=======================================================================
1024 Standard_Integer TopOpeBRep_EdgesIntersector::NbSegments() const 
1025 {
1026   return myNbSegments;
1027 }
1028
1029 //=======================================================================
1030 //function : Dump
1031 //purpose  : 
1032 //=======================================================================
1033 #ifndef DEB
1034 void TopOpeBRep_EdgesIntersector::Dump(const TCollection_AsciiString& ,const Standard_Integer ,const Standard_Integer )
1035 {
1036 #else
1037 void TopOpeBRep_EdgesIntersector::Dump(const TCollection_AsciiString& str,const Standard_Integer E1index,const Standard_Integer E2index)
1038 {
1039   InitPoint();if (!MorePoint()) return;
1040   cout<<endl<<"---- "<<str<<" ---- E/E : "<<NbPoints()<<" p , ";
1041   cout<<NbSegments()<<" s : "<<myTrueNbPoints<<" true points"<<endl;
1042   cout<<"E1 = "<<E1index<<" ";TopAbs::Print(Edge(1).Orientation(),cout)<<", ";
1043   cout<<"E2 = "<<E2index<<" ";TopAbs::Print(Edge(2).Orientation(),cout)<<"  ";
1044   cout<<"hs="<<HasSegment()<<" hsd="<<SameDomain()<<endl;
1045  
1046   for (InitPoint(); MorePoint(); NextPoint()) {
1047     const TopOpeBRep_Point2d P2d = Point();
1048     P2d.Dump(E1index,E2index);
1049     if (P2d.Status() == TopOpeBRep_P2DNEW) {
1050       Standard_Integer ip1,ip2; P2d.SegmentAncestors(ip1,ip2);
1051       Standard_Real d1 = Point(ip1).Value().Distance(Point(ip2).Value());
1052       Standard_Real d2 = d1 + Point(ip1).Tolerance()/2. + Point(ip2).Tolerance()/2.;
1053       cout<<"ancestor segment : d P"<<ip1<<",P"<<ip2<<" = "<<d1<<endl;
1054       cout<<"     t1/2 + d + t2/2 P"<<ip1<<",P"<<ip2<<" = "<<d2<<endl;
1055     }
1056   }
1057   cout<<endl;
1058 #endif
1059 }
1060
1061