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),
35 //=======================================================================
36 //function : IntPatch_ImpImpIntersection
38 //=======================================================================
39 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
40 (const Handle(Adaptor3d_HSurface)& S1,
41 const Handle(Adaptor3d_TopolTool)& D1,
42 const Handle(Adaptor3d_HSurface)& S2,
43 const Handle(Adaptor3d_TopolTool)& D2,
44 const Standard_Real TolArc,
45 const Standard_Real TolTang,
46 const Standard_Boolean theIsReqToKeepRLine)
48 Perform(S1,D1,S2,D2,TolArc,TolTang, theIsReqToKeepRLine);
50 //=======================================================================
53 //=======================================================================
54 void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
55 const Handle(Adaptor3d_TopolTool)& D1,
56 const Handle(Adaptor3d_HSurface)& S2,
57 const Handle(Adaptor3d_TopolTool)& D2,
58 const Standard_Real TolArc,
59 const Standard_Real TolTang,
60 const Standard_Boolean theIsReqToKeepRLine)
62 myDone = IntStatus_Fail;
66 Standard_Boolean isPostProcessingRequired = Standard_True;
69 tgte = Standard_False;
70 oppo = Standard_False;
72 Standard_Boolean all1 = Standard_False;
73 Standard_Boolean all2 = Standard_False;
74 Standard_Boolean SameSurf = Standard_False;
75 Standard_Boolean multpoint = Standard_False;
77 Standard_Boolean nosolonS1 = Standard_False;
78 // indique s il y a des points sur restriction du carreau 1
79 Standard_Boolean nosolonS2 = Standard_False;
80 // indique s il y a des points sur restriction du carreau 2
81 Standard_Integer i, nbpt, nbseg;
82 IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
83 IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
85 // On commence par intersecter les supports des surfaces
86 IntSurf_Quadric quad1, quad2;
87 IntPatch_ArcFunction AFunc;
88 const Standard_Real Tolang = 1.e-8;
89 GeomAbs_SurfaceType typs1, typs2;
90 Standard_Boolean bEmpty = Standard_False;
92 const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
93 const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
96 throw Standard_ConstructionError();
100 const Standard_Boolean bReverse = iT1 > iT2;
101 const Standard_Integer iTT = iT1*10 + iT2;
104 case 11: { // Plane/Plane
105 if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
112 case 21: { // Plane/Cylinder
113 Standard_Real VMin, VMax, H;
115 const Handle(Adaptor3d_HSurface)& aSCyl = bReverse ? S1 : S2;
116 VMin = aSCyl->FirstVParameter();
117 VMax = aSCyl->LastVParameter();
118 H = (Precision::IsNegativeInfinite(VMin) ||
119 Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
121 if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
129 case 31: { // Plane/Cone
130 if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
138 case 41: { // Plane/Sphere
139 if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
147 case 51: { // Plane/Torus
148 if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
156 { // Cylinder/Cylinder
157 Bnd_Box2d aBox1, aBox2;
159 const Standard_Real aU1f = S1->FirstUParameter();
160 Standard_Real aU1l = S1->LastUParameter();
161 const Standard_Real aU2f = S2->FirstUParameter();
162 Standard_Real aU2l = S2->LastUParameter();
164 const Standard_Real anUperiod = 2.0*M_PI;
166 if(aU1l - aU1f > anUperiod)
167 aU1l = aU1f + anUperiod;
169 if(aU2l - aU2f > anUperiod)
170 aU2l = aU2f + anUperiod;
172 aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
173 aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
174 aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
175 aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
177 // Resolution is too big if the cylinder radius is
178 // too small. Therefore, we shall bind its value above.
179 // Here, we use simple constant.
180 const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang),
181 S2->UResolution(TolTang)));
183 myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
184 empt, SameSurf, multpoint, slin, spnt);
186 if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
194 const Handle(IntPatch_WLine)& aWLine =
195 Handle(IntPatch_WLine)::DownCast(slin.Value(1));
198 {//No geometric solution
199 isPostProcessingRequired = Standard_False;
207 case 32: { // Cylinder/Cone
208 if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
216 case 42: { // Cylinder/Sphere
217 if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
225 case 52: { // Cylinder/Torus
226 if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
233 case 33: { // Cone/Cone
234 if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
242 case 43: { // Cone/Sphere
243 if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
251 case 53: { // Cone/Torus
252 if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
258 case 44: { // Sphere/Sphere
259 if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
267 case 54: { // Sphere/Torus
268 if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
275 case 55: { // Torus/Torus
276 if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
284 throw Standard_ConstructionError();
290 if (myDone == IntStatus_Fail)
291 myDone = IntStatus_OK;
297 if(isPostProcessingRequired)
300 AFunc.SetQuadric(quad2);
303 solrst.Perform(AFunc, D1, TolArc, TolTang);
304 if (!solrst.IsDone()) {
308 if (solrst.AllArcSolution() && typs1 == typs2) {
309 all1 = Standard_True;
311 nbpt = solrst.NbPoints();
312 nbseg= solrst.NbSegments();
313 for (i = 1; i <= nbpt; i++)
315 const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
318 for (i = 1; i <= nbseg; i++)
320 const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
323 nosolonS1 = (nbpt == 0) && (nbseg == 0);
325 if (nosolonS1 && all1) { // cas de face sans restrictions
326 all1 = Standard_False;
330 nosolonS1 = Standard_True;
334 AFunc.SetQuadric(quad1);
337 solrst.Perform(AFunc, D2, TolArc, TolTang);
338 if (!solrst.IsDone()) {
342 if (solrst.AllArcSolution() && typs1 == typs2) {
343 all2 = Standard_True;
346 nbpt = solrst.NbPoints();
347 nbseg= solrst.NbSegments();
348 for (i=1; i<= nbpt; i++) {
349 const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
353 for (i=1; i<= nbseg; i++) {
354 const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
358 nosolonS2 = (nbpt == 0) && (nbseg == 0);
360 if (nosolonS2 && all2) { // cas de face sans restrictions
361 all2 = Standard_False;
365 nosolonS2 = Standard_True;
368 if (SameSurf || (all1 && all2)) {
369 // faces "paralleles" parfaites
370 empt = Standard_False;
371 tgte = Standard_True;
378 case GeomAbs_Plane: {
379 Ptreference = (S1->Plane()).Location();
382 case GeomAbs_Cylinder: {
383 Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
386 case GeomAbs_Sphere: {
387 Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
391 Ptreference = ElSLib::Value(0.,10.,S1->Cone());
394 case GeomAbs_Torus: {
395 Ptreference = ElSLib::Value(0.,0.,S1->Torus());
402 oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
403 myDone = IntStatus_OK;
405 }// if (SameSurf || (all1 && all2)) {
407 if (!nosolonS1 || !nosolonS2) {
408 empt = Standard_False;
409 // C est la qu il faut commencer a bosser...
410 PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
413 PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
416 if (edg1.Length() != 0) {
417 ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
420 if (edg2.Length() != 0) {
421 ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
424 if (edg1.Length() !=0 || edg2.Length() !=0) {
425 // ProcessRLine(slin,S1,S2,TolArc);
426 ProcessRLine(slin,quad1,quad2,TolArc, theIsReqToKeepRLine);
428 }//if (!nosolonS1 || !nosolonS2) {
430 empt = ((slin.Length()==0) && (spnt.Length()==0));
434 Standard_Integer nblin = slin.Length(),
435 aNbPnt = spnt.Length();
437 //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
439 IntPatch_SequenceOfPoint aSIP;
441 for(i=1; i<=aNbPnt; ++i) {
442 Standard_Real aU1, aV1, aU2, aV2;
444 TopAbs_State aState1, aState2;
446 const IntPatch_Point& aIP=spnt(i);
447 aIP.Parameters(aU1, aV1, aU2, aV2);
449 aP2D.SetCoord(aU1, aV1);
450 aState1=D1->Classify(aP2D, TolArc);
452 aP2D.SetCoord(aU2, aV2);
453 aState2=D2->Classify(aP2D, TolArc);
455 if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
462 aNbPnt=aSIP.Length();
463 for(i=1; i<=aNbPnt; ++i) {
464 const IntPatch_Point& aIP=aSIP(i);
469 //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
471 for(i=1; i<=nblin; i++) {
472 IntPatch_IType thetype = slin.Value(i)->ArcType();
473 if( (thetype == IntPatch_Ellipse)
474 ||(thetype == IntPatch_Circle)
475 ||(thetype == IntPatch_Lin)
476 ||(thetype == IntPatch_Parabola)
477 ||(thetype == IntPatch_Hyperbola)) {
478 Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
479 glin->ComputeVertexParameters(TolArc);
481 else if(thetype == IntPatch_Analytic) {
482 Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
483 aligold->ComputeVertexParameters(TolArc);
485 else if(thetype == IntPatch_Restriction) {
486 Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
487 rlig->ComputeVertexParameters(TolArc);
491 //----------------------------------------------------------------
492 //-- On place 2 vertex sur les courbes de GLine qui n en
493 //-- contiennent pas.
494 for(i=1; i<=nblin; i++) {
496 IntPatch_Point point;
497 Standard_Real u1,v1,u2,v2;
498 if(slin.Value(i)->ArcType() == IntPatch_Circle) {
499 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
500 if(glin->NbVertex() == 0) {
501 gp_Circ Circ = glin->Circle();
502 P=ElCLib::Value(0.0,Circ);
503 quad1.Parameters(P,u1,v1);
504 quad2.Parameters(P,u2,v2);
505 point.SetValue(P,TolArc,Standard_False);
506 point.SetParameters(u1,v1,u2,v2);
507 point.SetParameter(0.0);
508 glin->AddVertex(point);
510 P=ElCLib::Value(0.0,Circ);
511 quad1.Parameters(P,u1,v1);
512 quad2.Parameters(P,u2,v2);
513 point.SetValue(P,TolArc,Standard_False);
514 point.SetParameters(u1,v1,u2,v2);
515 point.SetParameter(M_PI+M_PI);
516 glin->AddVertex(point);
520 else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) {
521 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
522 if(glin->NbVertex() == 0) {
523 gp_Elips Elips = glin->Ellipse();
524 P=ElCLib::Value(0.0,Elips);
525 quad1.Parameters(P,u1,v1);
526 quad2.Parameters(P,u2,v2);
527 point.SetValue(P,TolArc,Standard_False);
528 point.SetParameters(u1,v1,u2,v2);
529 point.SetParameter(0.0);
530 glin->AddVertex(point);
532 P=ElCLib::Value(0.0,Elips);
533 quad1.Parameters(P,u1,v1);
534 quad2.Parameters(P,u2,v2);
535 point.SetValue(P,TolArc,Standard_False);
536 point.SetParameters(u1,v1,u2,v2);
537 point.SetParameter(M_PI+M_PI);
538 glin->AddVertex(point);
542 myDone = IntStatus_OK;
545 //=======================================================================
548 //=======================================================================
549 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
550 GeomAbs_SurfaceType& theTS,
551 IntSurf_Quadric& theQuad)
553 theTS = theS->GetType();
554 Standard_Integer iRet = 0;
557 theQuad.SetValue(theS->Plane());
560 case GeomAbs_Cylinder:
561 theQuad.SetValue(theS->Cylinder());
565 theQuad.SetValue(theS->Cone());
569 theQuad.SetValue(theS->Sphere());
573 theQuad.SetValue(theS->Torus());