1 // Created on: 1994-10-07
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <TestTopOpeDraw_TTOT.hxx>
19 #include <TopOpeBRepTool_DRAW.hxx>
23 #include <Bnd_Box.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepAdaptor_HSurface.hxx>
26 #include <BRepAdaptor_Surface.hxx>
27 #include <Geom2dAdaptor_Curve.hxx>
28 #include <Geom_Curve.hxx>
29 #include <Geom_Surface.hxx>
30 #include <GeomTools_Curve2dSet.hxx>
31 #include <GeomTools_CurveSet.hxx>
32 #include <GeomTools_SurfaceSet.hxx>
33 #include <gp_Circ2d.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <IntRes2d_IntersectionPoint.hxx>
37 #include <IntRes2d_IntersectionSegment.hxx>
38 #include <Precision.hxx>
39 #include <Standard_Failure.hxx>
40 #include <TCollection_AsciiString.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopLoc_Location.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Vertex.hxx>
47 #include <TopOpeBRep_define.hxx>
48 #include <TopOpeBRep_EdgesIntersector.hxx>
49 #include <TopOpeBRep_Point2d.hxx>
50 #include <TopOpeBRepDS_Transition.hxx>
51 #include <TopOpeBRepTool_2d.hxx>
52 #include <TopOpeBRepTool_CurveTool.hxx>
53 #include <TopOpeBRepTool_EXPORT.hxx>
54 #include <TopOpeBRepTool_ShapeTool.hxx>
55 #include <TopOpeBRepTool_tol.hxx>
56 #include <TopOpeBRepTool_TOOL.hxx>
59 extern Standard_Boolean TopOpeBRepTool_GettraceNYI();
60 extern Standard_Boolean TopOpeBRepTool_GettraceKRO();
61 extern Standard_Boolean TopOpeBRep_GettracePROEDG();
62 extern Standard_Boolean TopOpeBRep_GetcontextTOL0();
63 extern Standard_Boolean TopOpeBRep_GetcontextNOFEI();
64 extern Standard_Boolean TopOpeBRep_GettraceFITOL();
65 extern Standard_Boolean TopOpeBRep_GettraceEEFF();
66 extern void debeeff();
67 #include <TopOpeBRepTool_KRO.hxx>
68 Standard_EXPORT TOPKRO KRO_DSFILLER_INTEE("intersection edge/edge");
71 // la surface de reference peut etre celle de la 1ere ou la 2eme face
72 // de l'appel de SetFaces. Ces deux faces sont "SameDomain".
73 // Leurs normales geometriques sont SurfacesSameOriented()
74 // Leurs normales topologiques sont FacesSameOriented()
76 // face1 FORWARD, normale geometrique Ng1 en +Z
77 // face2 REVERSED, normale geometrique Ng2 en -Z
78 // ==> SurfaceSameOriented = 0, FacesSameOriented = 1
80 //=======================================================================
81 //function : TopOpeBRep_EdgesIntersector
83 //=======================================================================
84 TopOpeBRep_EdgesIntersector::TopOpeBRep_EdgesIntersector()
86 mySurface1 = new BRepAdaptor_HSurface();
87 mySurface2 = new BRepAdaptor_HSurface();
88 mySurfacesSameOriented = Standard_False;
89 myFacesSameOriented = Standard_False;
90 myTol1 = 0.; // Precision::PConfusion();
91 myTol2 = 0.; // Precision::PIntersection();
93 myTolForced = Standard_False;
94 myf1surf1F_sameoriented = Standard_True;
95 myf2surf1F_sameoriented = Standard_True;
98 myHasSegment = Standard_False;
99 SetSameDomain(Standard_False);
105 myselectkeep = Standard_True;
108 TopOpeBRep_EdgesIntersector::~TopOpeBRep_EdgesIntersector()
111 //=======================================================================
112 //function : SetFaces
114 //=======================================================================
115 void TopOpeBRep_EdgesIntersector::SetFaces(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
118 SetFaces(F1,F2,B1,B2);
121 //=======================================================================
122 //function : SetFaces
124 //=======================================================================
125 void TopOpeBRep_EdgesIntersector::SetFaces(const TopoDS_Shape& F1,const TopoDS_Shape& F2,const Bnd_Box& B1,const Bnd_Box& B2)
127 Standard_Boolean computerestriction = Standard_False;
129 Standard_Boolean so11 = Standard_True;
130 Standard_Boolean so21 = Standard_True;
131 myf1surf1F_sameoriented = so11;
132 myf2surf1F_sameoriented = so21;
133 mySurfacesSameOriented = Standard_True;
134 myFacesSameOriented = Standard_True;
136 myFace1 = TopoDS::Face(F1);
137 BRepAdaptor_Surface& S1 = mySurface1->ChangeSurface(); S1.Initialize(myFace1,computerestriction);
138 mySurfaceType1 = S1.GetType();
140 myFace2 = TopoDS::Face(F2);
141 BRepAdaptor_Surface& S2 = mySurface2->ChangeSurface(); S2.Initialize(myFace2,computerestriction);
142 mySurfaceType2 = S2.GetType();
144 TopoDS_Face face1forward = myFace1;
145 face1forward.Orientation(TopAbs_FORWARD);
147 so11 = TopOpeBRepTool_ShapeTool::FacesSameOriented(face1forward,myFace1);
148 myf1surf1F_sameoriented = so11;
150 so21 = TopOpeBRepTool_ShapeTool::FacesSameOriented(face1forward,myFace2);
151 myf2surf1F_sameoriented = so21;
153 mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2);
154 myFacesSameOriented = TopOpeBRepTool_ShapeTool::FacesSameOriented(myFace1,myFace2);
156 if ( !myTolForced ) {
157 FTOL_FaceTolerances2d(B1,B2,myFace1,myFace2,S1,S2,myTol1,myTol2);
158 myTol1 = (myTol1 > 1.e-4)? 1.e-4: myTol1;
159 myTol2 = (myTol2 > 1.e-4)? 1.e-4: myTol2;
163 Standard_Integer DEBi = 0;
165 cout<<"TopOpeBRep_EdgesIntersector::SetFaces : ";
166 cout<<"f1 "; TopAbs::Print(myFace1.Orientation(),cout);
168 if (so11) cout<<"sameoriented"; else cout<<"difforiented"; cout<<endl;
170 cout<<"f2 "; TopAbs::Print(myFace2.Orientation(),cout);
172 if (so21) cout<<"sameoriented"; else cout<<"difforiented"; cout<<endl;
177 //=======================================================================
178 //function : ForceTolerances
180 //=======================================================================
181 void TopOpeBRep_EdgesIntersector::ForceTolerances(const Standard_Real Tol1,const Standard_Real Tol2)
185 myTolForced = Standard_True;
188 #include <IntRes2d_Transition.hxx>
189 static Standard_Boolean TransitionEqualAndExtremity( const IntRes2d_Transition& T1
190 ,const IntRes2d_Transition& T2) {
191 if( T1.PositionOnCurve() == IntRes2d_Head
192 || T1.PositionOnCurve() == IntRes2d_End) {
193 if(T1.PositionOnCurve() == T2.PositionOnCurve()) {
194 if(T1.TransitionType() == T2.TransitionType()) {
195 if(T1.TransitionType() == IntRes2d_Touch) {
196 if(T1.IsTangent()==T2.IsTangent()) {
197 if(T1.Situation() == T2.Situation()) {
198 if(T1.IsOpposite() == T2.IsOpposite()) {
199 return(Standard_True);
205 return(Standard_True);
210 return(Standard_False);
213 // Modified by Sergey KHROMOV - Fri Jan 11 14:49:48 2002 Begin
214 static Standard_Boolean IsTangentSegment(const IntRes2d_IntersectionPoint &P1,
215 const IntRes2d_IntersectionPoint &P2,
216 const Geom2dAdaptor_Curve &aC1,
217 const Geom2dAdaptor_Curve &aC2,
218 const Standard_Real aTolConf) {
219 const gp_Pnt2d &aP2d1 = P1.Value();
220 const gp_Pnt2d &aP2d2 = P2.Value();
221 const IntRes2d_Transition &aTrans1 = P1.TransitionOfFirst();
222 const IntRes2d_Transition &aTrans2 = P2.TransitionOfFirst();
224 if (aTrans1.TransitionType() == IntRes2d_Touch ||
225 aTrans2.TransitionType() == IntRes2d_Touch) {
226 Standard_Real aSqrDistPP = aP2d1.SquareDistance(aP2d2);
228 if (aSqrDistPP <= aTolConf) {
229 Standard_Real aParDist1 = Abs(P1.ParamOnFirst() - P2.ParamOnFirst());
230 Standard_Real aParDist2 = Abs(P1.ParamOnSecond() - P2.ParamOnSecond());
231 Standard_Real aResol1 = aC1.Resolution(aTolConf);
232 Standard_Real aResol2 = aC2.Resolution(aTolConf);
234 if (aParDist1*aParDist1 <= aResol1 &&
235 aParDist2*aParDist2 <= aResol2)
236 return Standard_True;
240 return Standard_False;
242 // Modified by Sergey KHROMOV - Fri Jan 11 14:49:49 2002 End
245 //------------------------------------------------------------------------
246 Standard_Boolean EdgesIntersector_checkT1D(const TopoDS_Edge& E1,const TopoDS_Edge& E2,const TopoDS_Vertex& vG,
247 TopOpeBRepDS_Transition& newT)
248 //------------------------------------------------------------------------
249 // E1 sdm E2, interfers with E2 at vertex vG
250 // vG is vertex of E2, but not vertex of E1
251 // purpose : get newT / attached to E1, I1d=(newT(E2),G,E2)
257 newT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN);
258 Standard_Integer ovine = FUN_tool_orientVinE(vG,E2);
260 return Standard_False;
262 else if (ovine == CLOSING) {
263 newT.Set(TopAbs_INTERNAL);
264 return Standard_True;
267 Standard_Boolean first = (ovine == FIRST);
268 Standard_Boolean last = (ovine == LAST);
270 TopOpeBRepDS_Config C = TopOpeBRepDS_SAMEORIENTED;
271 Standard_Boolean sso = TopOpeBRepTool_ShapeTool::ShapesSameOriented(E1,E2);
272 if (!sso) C = TopOpeBRepDS_DIFFORIENTED;
274 Standard_Boolean SO = (C == TopOpeBRepDS_SAMEORIENTED);
275 Standard_Boolean DO = (C == TopOpeBRepDS_DIFFORIENTED);
276 TopAbs_Orientation o1 = E1.Orientation();
277 if (o1 == TopAbs_REVERSED) {SO = !SO; DO = !DO;} // relative to E1 FORWARD
279 Standard_Boolean reversed = (SO && first) || (DO && last);
280 Standard_Boolean forward = (SO && last) || (DO && first);
281 if (reversed) newT.Set(TopAbs_REVERSED);
282 if (forward) newT.Set(TopAbs_FORWARD);
283 return (reversed || forward);
284 } // EdgesIntersector_checkT1D
287 //modified by NIZNHY-PKV Fri Nov 5 12:27:07 1999 from
288 #include <BRepAdaptor_Surface.hxx>
289 //modified by NIZNHY-PKV Fri Nov 5 12:27:10 1999 to
290 //=======================================================================
293 //=======================================================================
294 void TopOpeBRep_EdgesIntersector::Perform(const TopoDS_Shape& E1,const TopoDS_Shape& E2,const Standard_Boolean ReduceSegment)
297 myip2d = 1; mynp2d = 0;
299 myEdge1 = TopoDS::Edge(E1);
300 myEdge2 = TopoDS::Edge(E2);
302 Standard_Real first,last,tole,tolpc;
303 gp_Pnt2d pfirst,plast;
304 Handle(Geom2d_Curve) PC1;
305 //modified by NIZNHY-PKV Thu Nov 4 16:08:05 1999 f
307 BRepAdaptor_Surface aSurface1(myFace1), aSurface2(myFace2);
308 GeomAbs_SurfaceType aSurfaceType1=aSurface1.GetType(),
309 aSurfaceType2=aSurface2.GetType();
311 if (aSurfaceType1==GeomAbs_Sphere && aSurfaceType2==GeomAbs_Sphere) {
312 PC1 = FC2D_MakeCurveOnSurface (myEdge1,myFace1,first,last,tolpc, Standard_True);
315 PC1 = FC2D_CurveOnSurface(myEdge1,myFace1,first,last,tolpc);
317 //modified by NIZNHY-PKV Thu Nov 4 15:44:13 1999 to
320 Standard_Failure::Raise("EdgesIntersector::Perform : no 2d curve");
323 BRep_Tool::UVPoints(myEdge1,myFace1,pfirst,plast);
324 tole = BRep_Tool::Tolerance(myEdge1);
325 myDomain1.SetValues(pfirst,first,tole,plast,last,tole);
328 Standard_Boolean trc = Standard_False;
330 cout<<"ed1 on fa1 : {pfirst=("<<pfirst.X()<<" "<<pfirst.Y()<<"), first="<<first<<"\n";
331 cout<<" plast =("<<plast.X()<<" "<<plast.Y()<<"),last="<<last<<"}"<<endl;}
334 Standard_Boolean memesfaces = myFace1.IsSame(myFace2);
335 Standard_Boolean memesupport = Standard_False;
336 TopLoc_Location L1,L2;
337 const Handle(Geom_Surface) S1 = BRep_Tool::Surface(myFace1,L1);
338 const Handle(Geom_Surface) S2 = BRep_Tool::Surface(myFace2,L2);
339 if (S1 == S2 && L1 == L2) memesupport=Standard_True;
341 if ( mySurfaceType1 == GeomAbs_Plane || memesfaces || memesupport) {
342 Handle(Geom2d_Curve) PC2 = FC2D_CurveOnSurface(myEdge2,myFace1,first,last,tolpc);
344 BRep_Tool::UVPoints(myEdge2,myFace1,pfirst,plast);
345 tole = BRep_Tool::Tolerance(myEdge2);
346 myDomain2.SetValues(pfirst,first,tole,plast,last,tole);
350 cout<<"ed2 on fa1 : {pfirst=("<<pfirst.X()<<" "<<pfirst.Y()<<"), first="<<first<<"\n";
351 cout<<" plast =("<<plast.X()<<" "<<plast.Y()<<"),last="<<last<<"}"<<endl;}
358 Handle(Geom2d_Curve) PC2on1; Handle(Geom_Curve) NC;
359 Standard_Boolean dgE2 = BRep_Tool::Degenerated(myEdge2);
360 if (dgE2) { //xpu210998 : cto900Q3
361 TopExp_Explorer exv(myEdge2, TopAbs_VERTEX);
362 const TopoDS_Vertex& v2 = TopoDS::Vertex(exv.Current());
363 gp_Pnt pt2 = BRep_Tool::Pnt(v2);
364 gp_Pnt2d uv2; Standard_Real d; Standard_Boolean ok = FUN_tool_projPonF(pt2,myFace1,uv2,d);
368 Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(myFace1);
369 Standard_Boolean apex = FUN_tool_onapex(uv2, aSurf1);
371 TopoDS_Vertex vf,vl; TopExp::Vertices(myEdge1,vf,vl);
372 gp_Pnt ptf = BRep_Tool::Pnt(vf); Standard_Real df = pt2.Distance(ptf);
374 Standard_Real tolf = BRep_Tool::Tolerance(vf);
376 Standard_Boolean onf = (df < tolf);
377 TopoDS_Vertex v1 = onf ? vf : vl;
378 TopTools_IndexedDataMapOfShapeListOfShape mapVE; TopExp::MapShapesAndAncestors(myFace1,TopAbs_VERTEX,TopAbs_EDGE,mapVE);
379 const TopTools_ListOfShape& Edsanc = mapVE.FindFromKey(v1);
380 TopTools_ListIteratorOfListOfShape it(Edsanc);
381 for (; it.More(); it.Next()){
382 const TopoDS_Edge& ee = TopoDS::Edge(it.Value());
383 Standard_Boolean dgee = BRep_Tool::Degenerated(ee);
385 // Standard_Real f,l;
386 PC2on1 = BRep_Tool::CurveOnSurface(ee,myFace1,first,last);
389 else {} // NYIxpu210998
392 // project curve of edge 2 on surface of face 1
393 TopLoc_Location loc ;
394 Handle(Geom_Curve) C = BRep_Tool::Curve(myEdge2,loc,first,last);
395 NC = Handle(Geom_Curve)::DownCast(C->Transformed(loc.Transformation()));
396 Standard_Real tolreached2d;
398 //modified by NIZNHY-PKV Fri Nov 5 12:29:13 1999 from
399 if (aSurfaceType1==GeomAbs_Sphere && aSurfaceType2==GeomAbs_Sphere) {
400 PC2on1 = FC2D_MakeCurveOnSurface (myEdge2, myFace1, first, last, tolpc, Standard_True);
403 PC2on1 = TopOpeBRepTool_CurveTool::MakePCurveOnFace(myFace1,NC,tolreached2d);
405 //modified by NIZNHY-PKV Thu Nov 4 14:52:25 1999 t
409 if (!PC2on1.IsNull()) {
410 myCurve2.Load(PC2on1);
411 tole = BRep_Tool::Tolerance(myEdge2);
412 PC2on1->D0(first,pfirst);
413 PC2on1->D0(last,plast);
414 myDomain2.SetValues(pfirst,first,tole,plast,last,tole);
416 if ( TopOpeBRep_GettracePROEDG() ) {
417 cout<<"------------ projection de curve"<<endl;
418 cout<<"--- Curve : "<<endl;
419 GeomTools_CurveSet::PrintCurve(NC,cout);
420 cout<<"--- nouvelle PCurve : "<<endl;
421 GeomTools_Curve2dSet::PrintCurve2d(PC2on1,cout);
422 Handle(Geom_Surface) aS1 = BRep_Tool::Surface(myFace1);
423 cout<<"--- sur surface : "<<endl;
424 GeomTools_SurfaceSet::PrintSurface(aS1,cout);
432 // compute the intersection
434 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTEE.Start();
437 Standard_Real tol1 = myTol1, tol2 = myTol2;
439 /* if ( !myTolForced ) {
441 //#ifdef OCCT_DEBUG // JYL 28/09/98 : temporaire
442 //if ( TopOpeBRep_GetcontextTOL0() ) { // JYL 28/09/98 : temporaire
443 tol1 = 0.; // JYL 28/09/98 : temporaire
444 tol2 = 0.; // JYL 28/09/98 : temporaire
445 //} // JYL 28/09/98 : temporaire
446 //#endif // JYL 28/09/98 : temporaire
452 if (TopOpeBRep_GettraceFITOL()) {
453 cout<<"EdgesIntersector : Perform";
455 GeomAbs_CurveType t1 = myCurve1.GetType();
456 GeomAbs_CurveType t2 = myCurve2.GetType();
457 TCollection_AsciiString s1;TestTopOpeDraw_TTOT::CurveToString(t1,s1);cout<<" "<<s1;
458 TCollection_AsciiString s2;TestTopOpeDraw_TTOT::CurveToString(t2,s2);cout<<" "<<s2;
461 cout<<" tol1 = "<<tol1<<endl;
462 cout<<" tol2 = "<<tol2<<endl;
466 myIntersector.Perform(myCurve1,myDomain1,myCurve2,myDomain2,tol1,tol2);
468 Standard_Integer nbp = myIntersector.NbPoints();
469 Standard_Integer nbs = myIntersector.NbSegments();
471 mylpnt.Clear(); mylseg.Clear();
472 // for (Standard_Integer p=1; p<=nbp; p++) mylpnt.Append(myIntersector.Point(p));
474 for ( p=1; p<=nbp; p++) mylpnt.Append(myIntersector.Point(p));
475 for (Standard_Integer s=1; s<=nbs; s++) mylseg.Append(myIntersector.Segment(s));
477 Standard_Boolean filter = Standard_True;
479 Standard_Boolean nofilter = TopOpeBRep_GetcontextNOFEI(); if (nofilter) filter = Standard_False;
484 Standard_Boolean fin;
487 for(p=1;p<nbp && fin ;p++) {
488 const IntRes2d_IntersectionPoint& P1=mylpnt.Value(p);
489 const IntRes2d_IntersectionPoint& P2=mylpnt.Value(p+1);
490 if( TransitionEqualAndExtremity(P1.TransitionOfFirst(),P2.TransitionOfFirst())
491 || TransitionEqualAndExtremity(P1.TransitionOfSecond(),P2.TransitionOfSecond()) ) {
493 Standard_Boolean TRC = Standard_True;
494 if (TRC) cout<<"\n Egalite de transitions \n"<<endl;
496 fin = Standard_False;
500 // Modified by Sergey KHROMOV - Fri Jan 11 10:31:38 2002 Begin
501 else if (IsTangentSegment(P1, P2, myCurve1, myCurve2, Max(tol1, tol2))) {
502 const IntRes2d_Transition &aTrans = P2.TransitionOfFirst();
504 fin = Standard_False;
505 if (aTrans.TransitionType() == IntRes2d_Touch)
508 mylpnt.Remove(p + 1);
511 // Modified by Sergey KHROMOV - Fri Jan 11 10:31:39 2002 End
514 while(fin==Standard_False);
518 myNbSegments = mylseg.Length();
519 myHasSegment = (myNbSegments != 0);
522 myNbPoints = mylpnt.Length();
523 myTrueNbPoints = myNbPoints + 2 * myNbSegments;
527 if (TopOpeBRep_GettraceEEFF()) debeeff();
531 if (ReduceSegment) ReduceSegments();
533 // xpu010998 : cto900J1, e5 sdm e13, IntPatch (Touch,Inside) ->
534 // faulty INTERNAL transition at G=v9 :
535 // xpu281098 : cto019D2, e3 sdm e9, faulty EXTERNAL transition
536 Standard_Boolean esd = SameDomain();
537 for (InitPoint();MorePoint();NextPoint()) {
538 TopOpeBRep_Point2d& P2D = mysp2d(myip2d);
539 Standard_Boolean isvertex1 = P2D.IsVertex(1);
540 Standard_Boolean isvertex2 = P2D.IsVertex(2);
541 Standard_Boolean isvertex = isvertex1 || isvertex2;
543 if (isvertex && esd) {
544 TopOpeBRepDS_Transition& T1 = P2D.ChangeTransition(1);
545 TopOpeBRepDS_Transition& T2 = P2D.ChangeTransition(2);
547 Standard_Boolean isvertex12 = isvertex1 && isvertex2;
548 Standard_Boolean isvertex22 = isvertex2 && !isvertex12;
549 Standard_Boolean isvertex11 = isvertex1 && !isvertex12;
551 Standard_Boolean T1INT = (T1.Orientation(TopAbs_IN) == TopAbs_INTERNAL);
553 if (T1INT && isvertex2 && !isvertex1) {
554 const TopoDS_Vertex& V2 = P2D.Vertex(2);
555 TopOpeBRepDS_Transition newT; Standard_Boolean computed = ::EdgesIntersector_checkT1D(myEdge1,myEdge2,V2,newT);
556 if (computed) T1.Set(newT.Orientation(TopAbs_IN));
559 Standard_Boolean T2INT = (T2.Orientation(TopAbs_IN) == TopAbs_INTERNAL);
560 Standard_Boolean T2EXT = (T2.Orientation(TopAbs_IN) == TopAbs_EXTERNAL);
561 Standard_Boolean INTEXT2 = T2INT || T2EXT;
562 if (INTEXT2 && isvertex1 && !isvertex2) {
563 const TopoDS_Vertex& V1 = P2D.Vertex(1);
564 TopOpeBRepDS_Transition newT; Standard_Boolean computed = ::EdgesIntersector_checkT1D(myEdge2,myEdge1,V1,newT);
565 if (computed) T2.Set(newT.Orientation(TopAbs_IN));
568 // xpu121098 : cto900I7 (e12on,vG14)
569 TopoDS_Vertex vcl2; Standard_Boolean clE2 = TopOpeBRepTool_TOOL::ClosedE(myEdge2,vcl2);
570 Standard_Boolean nT1 = ( !T1INT && clE2 && isvertex22 && vcl2.IsSame(P2D.Vertex(2)) );
571 if (nT1) T1.Set(TopAbs_INTERNAL);
572 TopoDS_Vertex vcl1; Standard_Boolean clE1 = TopOpeBRepTool_TOOL::ClosedE(myEdge1,vcl1);
573 Standard_Boolean nT2 = ( !T2INT && clE1 && isvertex11 && vcl1.IsSame(P2D.Vertex(1)) );
574 if (nT2) T2.Set(TopAbs_INTERNAL);
576 } // (isvertex && esd)
581 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTEE.Stop();
585 //=======================================================================
586 //function : Dimension
588 //=======================================================================
589 void TopOpeBRep_EdgesIntersector::Dimension(const Standard_Integer Dim)
591 if (Dim == 1 || Dim == 2) {
596 //=======================================================================
597 //function : Dimension
599 //=======================================================================
600 Standard_Integer TopOpeBRep_EdgesIntersector::Dimension() const
605 //=======================================================================
606 //function : ComputeSameDomain
608 //=======================================================================
609 Standard_Boolean TopOpeBRep_EdgesIntersector::ComputeSameDomain()
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();
617 return SetSameDomain(Standard_False);
619 Standard_Boolean tt = (t1 == t2);
621 return SetSameDomain(Standard_False);
623 if (t1 == GeomAbs_Line)
624 return SetSameDomain(Standard_True);
626 if (t1 != GeomAbs_Circle) {
628 if (TopOpeBRepTool_GettraceNYI())
629 cout<<"TopOpeBRep_EdgesIntersector : EdgesSameDomain on NYI curve type"<<endl;
631 return SetSameDomain(Standard_False);
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);
642 const gp_Pnt2d& p1 = c1.Location();
643 const gp_Pnt2d& p2 = c2.Location();
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);
655 return SetSameDomain(Standard_False);
656 } // ComputeSameDomain
658 //=======================================================================
659 //function : SetSameDomain
661 //=======================================================================
662 Standard_Boolean TopOpeBRep_EdgesIntersector::SetSameDomain(const Standard_Boolean B)
668 //=======================================================================
669 //function : MakePoints2d
671 //=======================================================================
672 void TopOpeBRep_EdgesIntersector::MakePoints2d()
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;
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());
699 myip2d = 1; mynp2d = mysp2d.Length();
702 //=======================================================================
703 //function : ReduceSegment
705 //=======================================================================
706 Standard_Boolean TopOpeBRep_EdgesIntersector::ReduceSegment(TopOpeBRep_Point2d& psa,
707 TopOpeBRep_Point2d& psb,
708 TopOpeBRep_Point2d& Pn) const
710 Standard_Boolean reduced = Standard_False;
711 Standard_Integer ixpsa = psa.Index();
712 Standard_Integer ixpsb = psb.Index();
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);
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);
728 Standard_Boolean conda = (pospsa && (stspsa == TopOpeBRep_P2DSGF));
729 Standard_Boolean condb = (pospsb && (stspsb == TopOpeBRep_P2DSGL));
730 Standard_Boolean cond = (conda && condb);
733 reduced = Standard_True;
735 Standard_Real tm1 = (tpsa1 + tpsb1)/2.; Pn.SetParameter(1,tm1);
736 Standard_Real tm2 = (tpsa2 + tpsb2)/2.; Pn.SetParameter(2,tm2);
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);
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);
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);
759 Standard_Real tolpsa = psa.Tolerance();
760 Standard_Real tolpsb = psb.Tolerance();
761 Standard_Real toln = (tolpsa + tolpsb)*1.5;
762 Pn.SetTolerance(toln);
764 Pn.SetIsPointOfSegment(Standard_False);
765 Pn.SetSegmentAncestors(ixpsa,ixpsb);
766 psa.SetKeep(Standard_False);
767 psb.SetKeep(Standard_False);
769 TopOpeBRepDS_Config cpsa = psa.EdgesConfig();
771 Pn.SetEdgesConfig(cpsa);
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));
782 //=======================================================================
783 //function : ReduceSegments
785 //=======================================================================
786 void TopOpeBRep_EdgesIntersector::ReduceSegments()
788 Standard_Boolean condredu = (myHasSegment && !mySameDomain);
789 if (!condredu) return;
791 Standard_Integer ip = 1;Standard_Integer np = mynp2d;
793 TopOpeBRep_Point2d& psa = mysp2d(ip);
794 TopOpeBRep_Point2d& psb = mysp2d(ip+1);
795 TopOpeBRep_Point2d pn;
796 Standard_Boolean reduced = ReduceSegment(psa,psb,pn);
798 pn.SetIndex(++mynp2d);
805 myNbSegments = mylseg.Length();
806 myHasSegment = (myNbSegments != 0);
807 myTrueNbPoints = myNbPoints + 2 * myNbSegments;
812 //=======================================================================
815 //=======================================================================
816 Standard_Boolean TopOpeBRep_EdgesIntersector::IsEmpty ()
818 return (mynp2d == 0);
821 //=======================================================================
822 //function : HasSegment
824 //=======================================================================
825 Standard_Boolean TopOpeBRep_EdgesIntersector::HasSegment () const
830 //=======================================================================
831 //function : SameDomain
833 //=======================================================================
834 Standard_Boolean TopOpeBRep_EdgesIntersector::SameDomain() const
839 //=======================================================================
842 //=======================================================================
843 const TopoDS_Shape& TopOpeBRep_EdgesIntersector::Edge(const Standard_Integer Index) const
845 if ( Index == 1 ) return myEdge1;
846 else if ( Index == 2 ) return myEdge2;
847 else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Edge");
852 //=======================================================================
855 //=======================================================================
856 const Geom2dAdaptor_Curve& TopOpeBRep_EdgesIntersector::Curve(const Standard_Integer Index) const
858 if ( Index == 1 ) return myCurve1;
859 else if ( Index == 2 ) return myCurve2;
860 else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Curve");
865 //=======================================================================
868 //=======================================================================
869 const TopoDS_Shape& TopOpeBRep_EdgesIntersector::Face(const Standard_Integer Index) const
871 if ( Index == 1 ) return myFace1;
872 else if ( Index == 2 ) return myFace2;
873 else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Face");
878 //=======================================================================
881 //=======================================================================
882 const BRepAdaptor_Surface& TopOpeBRep_EdgesIntersector::Surface(const Standard_Integer Index) const
884 if ( Index == 1 ) return mySurface1->ChangeSurface();
885 else if ( Index == 2 ) return mySurface2->ChangeSurface();
886 else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Surface");
888 return mySurface1->ChangeSurface();
891 //=======================================================================
892 //function : SurfacesSameOriented
894 //=======================================================================
895 Standard_Boolean TopOpeBRep_EdgesIntersector::SurfacesSameOriented () const
897 return mySurfacesSameOriented;
900 //=======================================================================
901 //function : FacesSameOriented
903 //=======================================================================
904 Standard_Boolean TopOpeBRep_EdgesIntersector::FacesSameOriented () const
906 return myFacesSameOriented;
909 //=======================================================================
910 //function : InitPoint
912 //=======================================================================
913 void TopOpeBRep_EdgesIntersector::InitPoint(const Standard_Boolean selectkeep)
915 myselectkeep = selectkeep;
916 myip2d = 1; mynp2d = mysp2d.Length();
920 //=======================================================================
921 //function : MorePoint
923 //=======================================================================
924 Standard_Boolean TopOpeBRep_EdgesIntersector::MorePoint() const
926 Standard_Boolean b = (myip2d <= mynp2d);
930 //=======================================================================
931 //function : NextPoint
933 //=======================================================================
934 void TopOpeBRep_EdgesIntersector::NextPoint()
940 //=======================================================================
943 //=======================================================================
944 void TopOpeBRep_EdgesIntersector::Find()
946 while (myip2d <= mynp2d) {
948 Standard_Boolean kf = mysp2d(myip2d).Keep();
958 //=======================================================================
961 //=======================================================================
962 const TopOpeBRep_SequenceOfPoint2d& TopOpeBRep_EdgesIntersector::Points() const
967 //=======================================================================
970 //=======================================================================
971 const TopOpeBRep_Point2d& TopOpeBRep_EdgesIntersector::Point() const
973 return mysp2d(myip2d);
976 //=======================================================================
979 //=======================================================================
980 const TopOpeBRep_Point2d& TopOpeBRep_EdgesIntersector::Point(const Standard_Integer I) const
982 if (I<1 || I>mysp2d.Length()) Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Point(I)");
986 //=======================================================================
987 //function : ToleranceMax
989 //=======================================================================
990 Standard_Real TopOpeBRep_EdgesIntersector::ToleranceMax() const
992 Standard_Real tol = Max(myTol1,myTol2);
996 //=======================================================================
997 //function : Tolerances
999 //=======================================================================
1000 void TopOpeBRep_EdgesIntersector::Tolerances(Standard_Real& tol1, Standard_Real& tol2) const
1006 //=======================================================================
1007 //function : NbPoints
1009 //=======================================================================
1010 Standard_Integer TopOpeBRep_EdgesIntersector::NbPoints() const
1015 //=======================================================================
1016 //function : NbSegments
1018 //=======================================================================
1019 Standard_Integer TopOpeBRep_EdgesIntersector::NbSegments() const
1021 return myNbSegments;
1024 //=======================================================================
1027 //=======================================================================
1029 void TopOpeBRep_EdgesIntersector::Dump(const TCollection_AsciiString& ,const Standard_Integer ,const Standard_Integer )
1032 void TopOpeBRep_EdgesIntersector::Dump(const TCollection_AsciiString& str,const Standard_Integer E1index,const Standard_Integer E2index)
1034 InitPoint();if (!MorePoint()) return;
1035 cout<<endl<<"---- "<<str<<" ---- E/E : "<<NbPoints()<<" p , ";
1036 cout<<NbSegments()<<" s : "<<myTrueNbPoints<<" true points"<<endl;
1037 cout<<"E1 = "<<E1index<<" ";TopAbs::Print(Edge(1).Orientation(),cout)<<", ";
1038 cout<<"E2 = "<<E2index<<" ";TopAbs::Print(Edge(2).Orientation(),cout)<<" ";
1039 cout<<"hs="<<HasSegment()<<" hsd="<<SameDomain()<<endl;
1041 for (InitPoint(); MorePoint(); NextPoint()) {
1042 const TopOpeBRep_Point2d P2d = Point();
1043 P2d.Dump(E1index,E2index);
1044 if (P2d.Status() == TopOpeBRep_P2DNEW) {
1045 Standard_Integer ip1,ip2; P2d.SegmentAncestors(ip1,ip2);
1046 Standard_Real d1 = Point(ip1).Value().Distance(Point(ip2).Value());
1047 Standard_Real d2 = d1 + Point(ip1).Tolerance()/2. + Point(ip2).Tolerance()/2.;
1048 cout<<"ancestor segment : d P"<<ip1<<",P"<<ip2<<" = "<<d1<<endl;
1049 cout<<" t1/2 + d + t2/2 P"<<ip1<<",P"<<ip2<<" = "<<d2<<endl;