1 // Created on: 1992-10-22
2 // Created by: Christophe MARION
3 // Copyright (c) 1992-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.
22 #include <Bnd_Box.hxx>
26 #include <HLRBRep_Curve.hxx>
27 #include <HLRBRep_CurveTool.hxx>
28 #include <HLRBRep_EdgeData.hxx>
29 #include <HLRBRep_Intersector.hxx>
30 #include <HLRBRep_SurfaceTool.hxx>
31 #include <HLRBRep_ThePolygonOfInterCSurf.hxx>
32 #include <HLRBRep_ThePolyhedronOfInterCSurf.hxx>
33 #include <IntCurveSurface_IntersectionPoint.hxx>
34 #include <IntCurveSurface_IntersectionSegment.hxx>
35 #include <IntImpParGen.hxx>
36 #include <IntRes2d_IntersectionPoint.hxx>
37 #include <IntRes2d_IntersectionSegment.hxx>
38 #include <IntRes2d_Position.hxx>
39 #include <IntRes2d_Transition.hxx>
40 #include <StdFail_UndefinedDerivative.hxx>
46 static Standard_Integer NbIntersCS=0;
47 static Standard_Integer NbIntersCSVides=0;
48 static Standard_Integer NbIntersAuto=0;
49 static Standard_Integer NbIntersSimulate=0;
50 static Standard_Integer NbInters=0;
51 static Standard_Integer NbIntersVides=0;
52 static Standard_Integer NbInters1Segment=0;
53 static Standard_Integer NbInters1Point=0;
54 static Standard_Integer NbIntersNPoints=0;
55 static Standard_Integer NbIntersNSegments=0;
56 static Standard_Integer NbIntersPointEtSegment=0;
59 //=======================================================================
60 //function : HLRBRep_Intersector
62 //=======================================================================
64 HLRBRep_Intersector::HLRBRep_Intersector () :
69 printf("\n--------------------------------------");
70 printf("\nNbIntersSimulate : %6d",NbIntersSimulate);
71 printf("\nNbIntersCrvSurf : %6d",NbIntersCS);
72 printf("\n -> vide : %6d",NbIntersCSVides);
73 printf("\nNbAutoInters : %6d\n",NbIntersAuto);
74 printf("\nNbInters : %6d",NbInters);
75 printf("\n Vides : %6d",NbIntersVides);
76 printf("\n 1 Segment : %6d",NbInters1Segment);
77 printf("\n 1 Point : %6d",NbInters1Point);
78 printf("\n >1 Point : %6d",NbIntersNPoints);
79 printf("\n >1 Segment : %6d",NbIntersNSegments);
80 printf("\n >1 Pt et Seg : %6d",NbIntersPointEtSegment);
81 printf("\n--------------------------------------\n");
83 NbIntersSimulate=NbIntersAuto=NbIntersCS
84 =NbInters=NbIntersVides=NbInters1Segment=NbInters1Point=NbIntersNPoints
85 = NbIntersNSegments=NbIntersPointEtSegment=NbIntersCSVides=0;
89 //=======================================================================
92 //=======================================================================
94 void HLRBRep_Intersector::Perform (const Standard_Address A1,
95 const Standard_Real da1,
96 const Standard_Real db1)
103 Standard_Address myC1 = ((HLRBRep_EdgeData*) A1)->Curve();
107 gp_Pnt2d pa,pb;//,pa1,pb1;
108 Standard_Real a,b,d,tol;
109 Standard_ShortReal ta,tb;
111 ((HLRBRep_EdgeData*) A1)->Status().Bounds(a,ta,b,tb);
113 if (da1 != 0) a = a + d * da1;
114 if (db1 != 0) b = b - d * db1;
115 ((HLRBRep_Curve*)myC1)->D0(a,pa);
116 ((HLRBRep_Curve*)myC1)->D0(b,pb);
117 a = ((HLRBRep_Curve*)myC1)->Parameter2d(a);
118 b = ((HLRBRep_Curve*)myC1)->Parameter2d(b);
119 IntRes2d_Domain D1(pa,a,(Standard_Real)ta,pb,b,(Standard_Real)tb);
121 //modified by jgv, 18.04.2016 for OCC27341
122 //tol = (Standard_Real)(((HLRBRep_EdgeData*) A1)->Tolerance());
123 tol = Precision::Confusion();
124 //////////////////////////////////////////
126 myIntersector.Perform(myC1,D1,tol,tol);
129 //=======================================================================
132 //=======================================================================
134 void HLRBRep_Intersector::Perform (const Standard_Integer /*nA*/,
135 const Standard_Address A1,
136 const Standard_Real da1,
137 const Standard_Real db1,
138 const Standard_Integer /*nB*/,
139 const Standard_Address A2,
140 const Standard_Real da2,
141 const Standard_Real db2,
142 const Standard_Boolean EnBout)
151 Standard_Address myC1 = ((HLRBRep_EdgeData*) A1)->Curve();
152 Standard_Address myC2 = ((HLRBRep_EdgeData*) A2)->Curve();
156 gp_Pnt2d pa1,pb1,pa2,pb2;
157 gp_Vec2d va1,vb1,va2,vb2;
158 Standard_Real a1,b1,a2,b2,d,dd,tol,tol1,tol2;
159 Standard_ShortReal ta,tb;
161 //modified by jgv, 18.04.2016 for OCC27341
162 //tol1 = (Standard_Real)(((HLRBRep_EdgeData*) A1)->Tolerance());
163 //tol2 = (Standard_Real)(((HLRBRep_EdgeData*) A2)->Tolerance());
164 tol1 = Precision::Confusion();
165 tol2 = Precision::Confusion();
166 //////////////////////////////////////////
167 if (tol1 > tol2) tol = tol1;
171 Standard_Boolean PasBon;
172 Standard_Real decalagea1=100.0;
173 Standard_Real decalagea2=100.0;
174 Standard_Real decalageb1=100.0;
175 Standard_Real decalageb2=100.0;
177 PasBon=Standard_False;
178 ((HLRBRep_EdgeData*) A1)->Status().Bounds(a1,ta,b1,tb); //-- -> Parametres 3d
179 Standard_Real mtol = tol;
184 Standard_Real pdist = tol;
185 if(pdist<0.0000001) pdist = 0.0000001;
189 //-- a = a + d * da1;
190 ((HLRBRep_Curve*)myC1)->D1(a1,pa1,va1);
191 Standard_Real qwe=va1.Magnitude();
193 dd=pdist*decalagea1/qwe;
198 a1+= d * da1; decalagea1=-1;
202 a1+=d * da1; decalagea1=-1;
207 //-- b = b - d * db1;
208 ((HLRBRep_Curve*)myC1)->D1(b1,pb1,vb1);
209 Standard_Real qwe=vb1.Magnitude();
211 dd=pdist*decalageb1/qwe;
216 b1-= d * db1; decalageb1=-1;
220 b1-=d * db1; decalageb1=-1;
225 // if(EnBout) { //-- ************************************************************
226 // Standard_Real d=b1-a1;
233 ((HLRBRep_Curve*)myC1)->D0(a1,pa1);
234 ((HLRBRep_Curve*)myC1)->D0(b1,pb1);
236 a1 = ((HLRBRep_Curve*)myC1)->Parameter2d(a1);
237 b1 = ((HLRBRep_Curve*)myC1)->Parameter2d(b1);
243 if(ta>tol) ta=(Standard_ShortReal) tol;
244 if(tb>tol) tb=(Standard_ShortReal) tol;
246 IntRes2d_Domain D1(pa1,a1,(Standard_Real)ta,pb1,b1,(Standard_Real)tb);
248 ((HLRBRep_EdgeData*) A2)->Status().Bounds(a2,ta,b2,tb);
256 //-- a = a + d * da2;
257 ((HLRBRep_Curve*)myC2)->D1(a2,pa2,va2);
258 Standard_Real qwe=va2.Magnitude();
260 dd=pdist*decalagea2/qwe;
265 a2+= d * da2; decalagea2=-1;
269 a2+=d * da2; decalagea2=-1;
274 //-- b = b - d * db2;
275 ((HLRBRep_Curve*)myC2)->D1(b2,pb2,vb2);
276 Standard_Real qwe=vb2.Magnitude();
278 dd=pdist*decalageb2/qwe;
283 b2-= d * db2; decalageb2=-1;
287 b2-=d * db2; decalageb2=-1;
293 // if(EnBout) { //-- ************************************************************
294 // Standard_Real d=b2-a2;
304 ((HLRBRep_Curve*)myC2)->D0(a2,pa2);
305 ((HLRBRep_Curve*)myC2)->D0(b2,pb2);
307 a2 = ((HLRBRep_Curve*)myC2)->Parameter2d(a2);
308 b2 = ((HLRBRep_Curve*)myC2)->Parameter2d(b2);
314 if(ta>tol) ta=(Standard_ShortReal) tol;
315 if(tb>tol) tb=(Standard_ShortReal) tol;
317 IntRes2d_Domain D2(pa2,a2,(Standard_Real)ta,pb2,b2,(Standard_Real)tb);
321 Standard_Real a1a2 = (da1 || da2)? pa1.Distance(pa2) : RealLast();
322 Standard_Real a1b2 = (da1 || db2)? pa1.Distance(pb2) : RealLast();
323 Standard_Real b1a2 = (db1 || da2)? pb1.Distance(pa2) : RealLast();
324 Standard_Real b1b2 = (db1 || db2)? pb1.Distance(pb2) : RealLast();
326 Standard_Integer cote=1;
327 Standard_Real mindist = a1a2; //-- cas 1
328 if(mindist>a1b2) { mindist = a1b2; cote=2; }
329 if(mindist>b1a2) { mindist = b1a2; cote=3; }
330 if(mindist>b1b2) { mindist = b1b2; cote=4; }
334 //--printf("\n----- Edge %3d %3d [%7.5g %7.5g] [%7.5g %7.5g] Mindist:%8.5g 1000*Tol:%8.5g\n",
335 //-- nA,nB,decalagea1,decalageb1,decalagea2,decalageb2,mindist,1000.0*tol);
338 if(mindist < tol*1000) {
339 PasBon=Standard_True;
341 case 1: { decalagea1*=2; decalagea2*=2; break; }
342 case 2: { decalagea1*=2; decalageb2*=2; break; }
343 case 3: { decalageb1*=2; decalagea2*=2; break; }
344 default: { decalageb1*=2; decalageb2*=2; break; }
346 if(decalagea1<0.0 || decalagea2<0.0 || decalageb1<0.0 || decalageb2<=0.0) {
347 PasBon=Standard_False;
351 if(PasBon==Standard_False) {
352 myIntersector.Perform(myC1,D1,myC2,D2,tol,tol);
362 if(myIntersector.NbPoints()==1) {
363 if(myIntersector.NbSegments()==0) {
367 NbIntersPointEtSegment++;
370 else if(myIntersector.NbPoints()==0) {
371 if(myIntersector.NbSegments()==0) {
374 else if(myIntersector.NbSegments()==1) {
382 if(myIntersector.NbSegments()==0) {
386 NbIntersPointEtSegment++;
392 //=======================================================================
393 //function : SimulateOnePoint
395 //=======================================================================
397 void HLRBRep_Intersector::SimulateOnePoint(const Standard_Address A1,
398 const Standard_Real u,
399 const Standard_Address A2,
400 const Standard_Real v) {
404 Standard_Address myC1 = ((HLRBRep_EdgeData*) A1)->Curve();
405 Standard_Address myC2 = ((HLRBRep_EdgeData*) A2)->Curve();
407 Standard_Real u3= ((HLRBRep_Curve*)myC1)->Parameter3d(u);
408 Standard_Real v3= ((HLRBRep_Curve*)myC2)->Parameter3d(v);
411 ((HLRBRep_Curve*)myC1)->D1(u3,P13,T13);
412 ((HLRBRep_Curve*)myC2)->D1(v3,P23,T23);
414 IntRes2d_Transition Tr1,Tr2;
415 IntRes2d_Position Pos1,Pos2;
416 Pos1=Pos2=IntRes2d_Middle;
418 IntImpParGen::DetermineTransition(Pos1,T13,Tr1,Pos2,T23,Tr2,0.0);
420 mySinglePoint.SetValues(P13,u,v,Tr1,Tr2,Standard_False);
425 //=======================================================================
428 //=======================================================================
430 void HLRBRep_Intersector::Load (Standard_Address& A)
433 if (myPolyhedron != NULL) {
434 delete (HLRBRep_ThePolyhedronOfInterCSurf*)myPolyhedron;
439 //=======================================================================
442 //=======================================================================
444 void HLRBRep_Intersector::Perform (const gp_Lin& L,
445 const Standard_Real P)
448 GeomAbs_SurfaceType typ = HLRBRep_SurfaceTool::GetType(mySurface);
451 case GeomAbs_Cylinder :
453 case GeomAbs_Sphere :
455 myCSIntersector.Perform(L,mySurface);
459 if (myPolyhedron == NULL) {
460 Standard_Integer nbsu,nbsv;
461 Standard_Real u1,v1,u2,v2;
462 u1 = HLRBRep_SurfaceTool::FirstUParameter(mySurface);
463 v1 = HLRBRep_SurfaceTool::FirstVParameter(mySurface);
464 u2 = HLRBRep_SurfaceTool::LastUParameter(mySurface);
465 v2 = HLRBRep_SurfaceTool::LastVParameter(mySurface);
466 nbsu = HLRBRep_SurfaceTool::NbSamplesU(mySurface,u1,u2);
467 nbsv = HLRBRep_SurfaceTool::NbSamplesV(mySurface,v1,v2);
468 myPolyhedron = (Standard_Address)
469 (new HLRBRep_ThePolyhedronOfInterCSurf
470 (mySurface,nbsu,nbsv,u1,v1,u2,v2));
472 Standard_Real x0,y0,z0,x1,y1,z1,pmin,pmax;//,pp;
473 ((HLRBRep_ThePolyhedronOfInterCSurf*)myPolyhedron)
474 ->Bounding().Get(x0,y0,z0,x1,y1,z1);
476 pmax = pmin = ElCLib::Parameter(L, gp_Pnt((x1+x0)*0.5,
479 Standard_Real d = (x1-x0) + (y1-y0) + (z1-z0);
482 if (pmin > P) pmin = P - d;
483 if (pmax > P) pmax = P;
484 HLRBRep_ThePolygonOfInterCSurf Polygon(L,pmin,pmax,3);
485 myCSIntersector.Perform(L,Polygon,mySurface,
486 *((HLRBRep_ThePolyhedronOfInterCSurf*)
490 //-- On va rejeter tous les points de parametres > P
492 p = ElCLib::Parameter(L, gp_Pnt(x0,y0,z0)); pmin=pmax=p;
493 p = ElCLib::Parameter(L, gp_Pnt(x0,y0,z1)); if(pmin>p) pmin=p; if(pmax<p) pmax=p;
495 p = ElCLib::Parameter(L, gp_Pnt(x1,y0,z0)); if(pmin>p) pmin=p; if(pmax<p) pmax=p;
496 p = ElCLib::Parameter(L, gp_Pnt(x1,y0,z1)); if(pmin>p) pmin=p; if(pmax<p) pmax=p;
498 p = ElCLib::Parameter(L, gp_Pnt(x0,y1,z0)); if(pmin>p) pmin=p; if(pmax<p) pmax=p;
499 p = ElCLib::Parameter(L, gp_Pnt(x0,y1,z1)); if(pmin>p) pmin=p; if(pmax<p) pmax=p;
501 p = ElCLib::Parameter(L, gp_Pnt(x1,y1,z0)); if(pmin>p) pmin=p; if(pmax<p) pmax=p;
502 p = ElCLib::Parameter(L, gp_Pnt(x1,y1,z1)); if(pmin>p) pmin=p; if(pmax<p) pmax=p;
503 pmin-=0.000001; pmax+=0.000001;
505 if(pmin>P) { pmin=pmax+1; pmax=pmax+2; } //-- on va rejeter avec les boites
507 if(pmax>P) pmax=P+0.0000001;
509 HLRBRep_ThePolygonOfInterCSurf Polygon(L,pmin,pmax,3);
510 myCSIntersector.Perform(L,Polygon,mySurface,
511 *((HLRBRep_ThePolyhedronOfInterCSurf*)
521 if(myCSIntersector.NbPoints()==0) {
528 //=======================================================================
531 //=======================================================================
533 Standard_Boolean HLRBRep_Intersector::IsDone () const
535 if(myTypePerform == 1)
536 return myIntersector .IsDone();
537 else if(myTypePerform ==2)
538 return myCSIntersector.IsDone();
540 return(Standard_True);
543 //=======================================================================
544 //function : NbPoints
546 //=======================================================================
548 Standard_Integer HLRBRep_Intersector::NbPoints() const
550 if(myTypePerform==43) return(0);
552 if (myTypePerform == 1)
553 return myIntersector .NbPoints();
554 else if(myTypePerform == 2)
555 return myCSIntersector.NbPoints();
560 //=======================================================================
563 //=======================================================================
565 const IntRes2d_IntersectionPoint &
566 HLRBRep_Intersector::Point (const Standard_Integer N) const
569 return(mySinglePoint);
571 return myIntersector.Point(N);
574 //=======================================================================
577 //=======================================================================
579 const IntCurveSurface_IntersectionPoint &
580 HLRBRep_Intersector::CSPoint (const Standard_Integer N) const
582 return myCSIntersector.Point(N);
585 //=======================================================================
586 //function : NbSegments
588 //=======================================================================
590 Standard_Integer HLRBRep_Intersector::NbSegments () const
592 if(myTypePerform == 1)
593 return myIntersector .NbSegments();
594 else if(myTypePerform==2)
595 return myCSIntersector.NbSegments();
600 //=======================================================================
603 //=======================================================================
605 const IntRes2d_IntersectionSegment &
606 HLRBRep_Intersector::Segment (const Standard_Integer N) const
608 return myIntersector .Segment(N);
611 //=======================================================================
612 //function : CSSegment
614 //=======================================================================
616 const IntCurveSurface_IntersectionSegment &
617 HLRBRep_Intersector::CSSegment (const Standard_Integer N) const
619 return myCSIntersector.Segment(N);
622 //=======================================================================
625 //=======================================================================
627 void HLRBRep_Intersector::Destroy ()
629 if (myPolyhedron != NULL)
630 delete (HLRBRep_ThePolyhedronOfInterCSurf *)myPolyhedron;
642 /* ********************************************************************************
644 sauvegarde de l etat du 23 janvier 98
647 void HLRBRep_Intersector::Perform (const Standard_Integer nA,
648 const Standard_Address A1,
649 const Standard_Real da1,
650 const Standard_Real db1,
651 const Standard_Integer nB,
652 const Standard_Address A2,
653 const Standard_Real da2,
654 const Standard_Real db2,
655 const Standard_Boolean EnBout)
657 Standard_Address myC1 = ((HLRBRep_EdgeData*) A1)->Curve();
658 Standard_Address myC2 = ((HLRBRep_EdgeData*) A2)->Curve();
663 Standard_Real a,b,d,tol,tol1,tol2;
664 Standard_ShortReal ta,tb;
666 tol1 = (Standard_Real)(((HLRBRep_EdgeData*) A1)->Tolerance());
667 tol2 = (Standard_Real)(((HLRBRep_EdgeData*) A2)->Tolerance());
668 if (tol1 > tol2) tol = tol1;
671 ((HLRBRep_EdgeData*) A1)->Status().Bounds(a,ta,b,tb); //-- -> Parametres 3d
672 Standard_Real mtol = tol;
676 if (da1 != 0) a = a + d * da1;
677 if (db1 != 0) b = b - d * db1;
678 ((HLRBRep_Curve*)myC1)->D0(a,pa);
679 ((HLRBRep_Curve*)myC1)->D0(b,pb);
681 a = ((HLRBRep_Curve*)myC1)->Parameter2d(a);
682 b = ((HLRBRep_Curve*)myC1)->Parameter2d(b);
692 IntRes2d_Domain D1(pa,a,(Standard_Real)ta,pb,b,(Standard_Real)tb);
694 ((HLRBRep_EdgeData*) A2)->Status().Bounds(a,ta,b,tb);
700 if (da2 != 0) a = a + d * da2;
701 if (db2 != 0) b = b - d * db2;
702 ((HLRBRep_Curve*)myC2)->D0(a,pa);
703 ((HLRBRep_Curve*)myC2)->D0(b,pb);
705 a = ((HLRBRep_Curve*)myC2)->Parameter2d(a);
706 b = ((HLRBRep_Curve*)myC2)->Parameter2d(b);
716 IntRes2d_Domain D2(pa,a,(Standard_Real)ta,pb,b,(Standard_Real)tb);
718 myIntersector.Perform(myC1,D1,myC2,D2,tol,tol);
726 if(myIntersector.NbPoints()==1) {
727 if(myIntersector.NbSegments()==0) {
731 NbIntersPointEtSegment++;
734 else if(myIntersector.NbPoints()==0) {
735 if(myIntersector.NbSegments()==0) {
738 else if(myIntersector.NbSegments()==1) {
746 if(myIntersector.NbSegments()==0) {
750 NbIntersPointEtSegment++;
755 ******************************************************************************** */