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