1 // Created on: 1992-05-07
2 // Created by: Jacques GOUSSARD
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.
17 #include <IntPatch_WLine.hxx>
20 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
21 GeomAbs_SurfaceType& theTS,
22 IntSurf_Quadric& theQuad);
24 //=======================================================================
25 //function : IntPatch_ImpImpIntersection
27 //=======================================================================
28 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
29 myDone(IntStatus_Fail)
32 //=======================================================================
33 //function : IntPatch_ImpImpIntersection
35 //=======================================================================
36 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
37 (const Handle(Adaptor3d_HSurface)& S1,
38 const Handle(Adaptor3d_TopolTool)& D1,
39 const Handle(Adaptor3d_HSurface)& S2,
40 const Handle(Adaptor3d_TopolTool)& D2,
41 const Standard_Real TolArc,
42 const Standard_Real TolTang,
43 const Standard_Boolean theIsReqToKeepRLine)
45 Perform(S1,D1,S2,D2,TolArc,TolTang, theIsReqToKeepRLine);
47 //=======================================================================
50 //=======================================================================
51 void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
52 const Handle(Adaptor3d_TopolTool)& D1,
53 const Handle(Adaptor3d_HSurface)& S2,
54 const Handle(Adaptor3d_TopolTool)& D2,
55 const Standard_Real TolArc,
56 const Standard_Real TolTang,
57 const Standard_Boolean theIsReqToKeepRLine)
59 myDone = IntStatus_Fail;
63 Standard_Boolean isPostProcessingRequired = Standard_True;
66 tgte = Standard_False;
67 oppo = Standard_False;
69 Standard_Boolean all1 = Standard_False;
70 Standard_Boolean all2 = Standard_False;
71 Standard_Boolean SameSurf = Standard_False;
72 Standard_Boolean multpoint = Standard_False;
74 Standard_Boolean nosolonS1 = Standard_False;
75 // indique s il y a des points sur restriction du carreau 1
76 Standard_Boolean nosolonS2 = Standard_False;
77 // indique s il y a des points sur restriction du carreau 2
78 Standard_Integer i, nbpt, nbseg;
79 IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
80 IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
82 // On commence par intersecter les supports des surfaces
83 IntSurf_Quadric quad1, quad2;
84 IntPatch_ArcFunction AFunc;
85 const Standard_Real Tolang = 1.e-8;
86 GeomAbs_SurfaceType typs1, typs2;
87 Standard_Boolean bEmpty = Standard_False;
89 const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
90 const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
93 Standard_ConstructionError::Raise();
97 const Standard_Boolean bReverse = iT1 > iT2;
98 const Standard_Integer iTT = iT1*10 + iT2;
101 case 11: { // Plane/Plane
102 if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
109 case 21: { // Plane/Cylinder
110 Standard_Real VMin, VMax, H;
112 const Handle(Adaptor3d_HSurface)& aSCyl = bReverse ? S2 : S1;
113 VMin = aSCyl->FirstVParameter();
114 VMax = aSCyl->LastVParameter();
115 H = (Precision::IsNegativeInfinite(VMin) ||
116 Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
118 if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
126 case 31: { // Plane/Cone
127 if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
135 case 41: { // Plane/Sphere
136 if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
144 case 51: { // Plane/Torus
145 if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
153 { // Cylinder/Cylinder
154 Bnd_Box2d aBox1, aBox2;
156 const Standard_Real aU1f = S1->FirstUParameter();
157 Standard_Real aU1l = S1->LastUParameter();
158 const Standard_Real aU2f = S2->FirstUParameter();
159 Standard_Real aU2l = S2->LastUParameter();
161 const Standard_Real anUperiod = 2.0*M_PI;
163 if(aU1l - aU1f > anUperiod)
164 aU1l = aU1f + anUperiod;
166 if(aU2l - aU2f > anUperiod)
167 aU2l = aU2f + anUperiod;
169 aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
170 aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
171 aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
172 aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
174 // Resolution is too big if the cylinder radius is
175 // too small. Therefore, we shall bounde its value above.
176 // Here, we use simple constant.
177 const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang),
178 S2->UResolution(TolTang)));
180 //The bigger range the bigger nunber of points in Walking-line (WLine)
181 //we will be able to add and, consequently, we will obtain more
182 //precise intersection line.
183 //Every point of WLine is determined as function from U1-parameter,
184 //where U1 is U-parameter on 1st quadric.
185 //Therefore, we should use quadric with bigger range as 1st parameter
186 //in IntCyCy() function.
187 //On the other hand, there is no point in reversing in case of
188 //analytical intersection (when result is line, ellipse, point...).
189 //This result is independent of the arguments order.
190 Standard_Boolean isReversed = ((aU2l - aU2f) < (aU1l - aU1f));
194 myDone = IntCyCy(quad2, quad1, TolTang, a2DTol, aBox2, aBox1,
195 Standard_True, empt, SameSurf, multpoint, slin, spnt);
199 myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
200 Standard_False, empt, SameSurf, multpoint, slin, spnt);
203 if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
211 const Handle(IntPatch_WLine)& aWLine =
212 Handle(IntPatch_WLine)::DownCast(slin.Value(1));
215 {//No geometric solution
216 isPostProcessingRequired = Standard_False;
224 case 32: { // Cylinder/Cone
225 if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
233 case 42: { // Cylinder/Sphere
234 if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
242 case 52: { // Cylinder/Torus
243 if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
250 case 33: { // Cone/Cone
251 if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
259 case 43: { // Cone/Sphere
260 if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
268 case 53: { // Cone/Torus
269 if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
275 case 44: { // Sphere/Sphere
276 if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
284 case 54: { // Sphere/Torus
285 if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
292 case 55: { // Torus/Torus
293 if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
301 Standard_ConstructionError::Raise();
307 if (myDone == IntStatus_Fail)
308 myDone = IntStatus_OK;
314 if(isPostProcessingRequired)
317 AFunc.SetQuadric(quad2);
320 solrst.Perform(AFunc, D1, TolArc, TolTang);
321 if (!solrst.IsDone()) {
325 if (solrst.AllArcSolution() && typs1 == typs2) {
326 all1 = Standard_True;
328 nbpt = solrst.NbPoints();
329 nbseg= solrst.NbSegments();
330 for (i=1; i<= nbpt; i++) {
331 pnt1.Append(solrst.Point(i));
333 for (i=1; i<= nbseg; i++) {
334 edg1.Append(solrst.Segment(i));
336 nosolonS1 = (nbpt == 0) && (nbseg == 0);
338 if (nosolonS1 && all1) { // cas de face sans restrictions
339 all1 = Standard_False;
343 nosolonS1 = Standard_True;
347 AFunc.SetQuadric(quad1);
350 solrst.Perform(AFunc, D2, TolArc, TolTang);
351 if (!solrst.IsDone()) {
355 if (solrst.AllArcSolution() && typs1 == typs2) {
356 all2 = Standard_True;
358 nbpt = solrst.NbPoints();
359 nbseg= solrst.NbSegments();
360 for (i=1; i<= nbpt; i++) {
361 pnt2.Append(solrst.Point(i));
364 for (i=1; i<= nbseg; i++) {
365 edg2.Append(solrst.Segment(i));
367 nosolonS2 = (nbpt == 0) && (nbseg == 0);
369 if (nosolonS2 && all2) { // cas de face sans restrictions
370 all2 = Standard_False;
374 nosolonS2 = Standard_True;
377 if (SameSurf || (all1 && all2)) {
378 // faces "paralleles" parfaites
379 empt = Standard_False;
380 tgte = Standard_True;
387 case GeomAbs_Plane: {
388 Ptreference = (S1->Plane()).Location();
391 case GeomAbs_Cylinder: {
392 Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
395 case GeomAbs_Sphere: {
396 Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
400 Ptreference = ElSLib::Value(0.,10.,S1->Cone());
403 case GeomAbs_Torus: {
404 Ptreference = ElSLib::Value(0.,0.,S1->Torus());
411 oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
412 myDone = IntStatus_OK;
414 }// if (SameSurf || (all1 && all2)) {
416 if (!nosolonS1 || !nosolonS2) {
417 empt = Standard_False;
418 // C est la qu il faut commencer a bosser...
419 PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
422 PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
425 if (edg1.Length() != 0) {
426 ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
429 if (edg2.Length() != 0) {
430 ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
433 if (edg1.Length() !=0 || edg2.Length() !=0) {
434 // ProcessRLine(slin,S1,S2,TolArc);
435 ProcessRLine(slin,quad1,quad2,TolArc, theIsReqToKeepRLine);
437 }//if (!nosolonS1 || !nosolonS2) {
439 empt = ((slin.Length()==0) && (spnt.Length()==0));
443 Standard_Integer nblin = slin.Length(),
444 aNbPnt = spnt.Length();
446 //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
448 IntPatch_SequenceOfPoint aSIP;
450 for(i=1; i<=aNbPnt; ++i) {
451 Standard_Real aU1, aV1, aU2, aV2;
453 TopAbs_State aState1, aState2;
455 const IntPatch_Point& aIP=spnt(i);
456 aIP.Parameters(aU1, aV1, aU2, aV2);
458 aP2D.SetCoord(aU1, aV1);
459 aState1=D1->Classify(aP2D, TolArc);
461 aP2D.SetCoord(aU2, aV2);
462 aState2=D2->Classify(aP2D, TolArc);
464 if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
471 aNbPnt=aSIP.Length();
472 for(i=1; i<=aNbPnt; ++i) {
473 const IntPatch_Point& aIP=aSIP(i);
478 //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
480 for(i=1; i<=nblin; i++) {
481 IntPatch_IType thetype = slin.Value(i)->ArcType();
482 if( (thetype == IntPatch_Ellipse)
483 ||(thetype == IntPatch_Circle)
484 ||(thetype == IntPatch_Lin)
485 ||(thetype == IntPatch_Parabola)
486 ||(thetype == IntPatch_Hyperbola)) {
487 Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
488 glin->ComputeVertexParameters(TolArc);
490 else if(thetype == IntPatch_Analytic) {
491 Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
492 aligold->ComputeVertexParameters(TolArc);
494 else if(thetype == IntPatch_Restriction) {
495 Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
496 rlig->ComputeVertexParameters(TolArc);
500 //----------------------------------------------------------------
501 //-- On place 2 vertex sur les courbes de GLine qui n en
502 //-- contiennent pas.
503 for(i=1; i<=nblin; i++) {
505 IntPatch_Point point;
506 Standard_Real u1,v1,u2,v2;
507 if(slin.Value(i)->ArcType() == IntPatch_Circle) {
508 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
509 if(glin->NbVertex() == 0) {
510 gp_Circ Circ = glin->Circle();
511 P=ElCLib::Value(0.0,Circ);
512 quad1.Parameters(P,u1,v1);
513 quad2.Parameters(P,u2,v2);
514 point.SetValue(P,TolArc,Standard_False);
515 point.SetParameters(u1,v1,u2,v2);
516 point.SetParameter(0.0);
517 glin->AddVertex(point);
519 P=ElCLib::Value(0.0,Circ);
520 quad1.Parameters(P,u1,v1);
521 quad2.Parameters(P,u2,v2);
522 point.SetValue(P,TolArc,Standard_False);
523 point.SetParameters(u1,v1,u2,v2);
524 point.SetParameter(M_PI+M_PI);
525 glin->AddVertex(point);
529 else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) {
530 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
531 if(glin->NbVertex() == 0) {
532 gp_Elips Elips = glin->Ellipse();
533 P=ElCLib::Value(0.0,Elips);
534 quad1.Parameters(P,u1,v1);
535 quad2.Parameters(P,u2,v2);
536 point.SetValue(P,TolArc,Standard_False);
537 point.SetParameters(u1,v1,u2,v2);
538 point.SetParameter(0.0);
539 glin->AddVertex(point);
541 P=ElCLib::Value(0.0,Elips);
542 quad1.Parameters(P,u1,v1);
543 quad2.Parameters(P,u2,v2);
544 point.SetValue(P,TolArc,Standard_False);
545 point.SetParameters(u1,v1,u2,v2);
546 point.SetParameter(M_PI+M_PI);
547 glin->AddVertex(point);
551 myDone = IntStatus_OK;
554 //=======================================================================
557 //=======================================================================
558 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
559 GeomAbs_SurfaceType& theTS,
560 IntSurf_Quadric& theQuad)
562 theTS = theS->GetType();
563 Standard_Integer iRet = 0;
566 theQuad.SetValue(theS->Plane());
569 case GeomAbs_Cylinder:
570 theQuad.SetValue(theS->Cylinder());
574 theQuad.SetValue(theS->Cone());
578 theQuad.SetValue(theS->Sphere());
582 theQuad.SetValue(theS->Torus());