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.
18 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
19 GeomAbs_SurfaceType& theTS,
20 IntSurf_Quadric& theQuad);
22 //=======================================================================
23 //function : IntPatch_ImpImpIntersection
25 //=======================================================================
26 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
30 //=======================================================================
31 //function : IntPatch_ImpImpIntersection
33 //=======================================================================
34 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
35 (const Handle(Adaptor3d_HSurface)& S1,
36 const Handle(Adaptor3d_TopolTool)& D1,
37 const Handle(Adaptor3d_HSurface)& S2,
38 const Handle(Adaptor3d_TopolTool)& D2,
39 const Standard_Real TolArc,
40 const Standard_Real TolTang)
42 Perform(S1,D1,S2,D2,TolArc,TolTang);
44 //=======================================================================
47 //=======================================================================
48 void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
49 const Handle(Adaptor3d_TopolTool)& D1,
50 const Handle(Adaptor3d_HSurface)& S2,
51 const Handle(Adaptor3d_TopolTool)& D2,
52 const Standard_Real TolArc,
53 const Standard_Real TolTang,
54 const Standard_Boolean isTheTrimmed) {
55 done = Standard_False;
56 Standard_Boolean isTrimmed = isTheTrimmed;
61 tgte = Standard_False;
62 oppo = Standard_False;
64 Standard_Boolean all1 = Standard_False;
65 Standard_Boolean all2 = Standard_False;
66 Standard_Boolean SameSurf = Standard_False;
67 Standard_Boolean multpoint = Standard_False;
69 Standard_Boolean nosolonS1 = Standard_False;
70 // indique s il y a des points sur restriction du carreau 1
71 Standard_Boolean nosolonS2 = Standard_False;
72 // indique s il y a des points sur restriction du carreau 2
73 Standard_Integer i, nbpt, nbseg;
74 IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
75 IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
77 // On commence par intersecter les supports des surfaces
78 IntSurf_Quadric quad1, quad2;
79 IntPatch_ArcFunction AFunc;
80 const Standard_Real Tolang = 1.e-8;
81 GeomAbs_SurfaceType typs1, typs2;
82 Standard_Boolean bEmpty = Standard_False;
84 const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
85 const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
88 Standard_ConstructionError::Raise();
92 const Standard_Boolean bReverse = iT1 > iT2;
93 const Standard_Integer iTT = iT1*10 + iT2;
96 case 11: { // Plane/Plane
97 if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
104 case 21: { // Plane/Cylinder
105 Standard_Real VMin, VMax, H;
107 const Handle(Adaptor3d_HSurface)& aSCyl = bReverse ? S2 : S1;
108 VMin = aSCyl->FirstVParameter();
109 VMax = aSCyl->LastVParameter();
110 H = (Precision::IsNegativeInfinite(VMin) ||
111 Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
113 if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
121 case 31: { // Plane/Cone
122 if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
130 case 41: { // Plane/Sphere
131 if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
139 case 51: { // Plane/Torus
140 if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
148 { // Cylinder/Cylinder
149 Standard_Boolean isDONE = Standard_False;
153 isDONE = IntCyCy(quad1, quad2, TolTang, empt,
154 SameSurf, multpoint, slin, spnt);
158 Bnd_Box2d aBox1, aBox2;
160 const Standard_Real aU1f = S1->FirstUParameter();
161 Standard_Real aU1l = S1->LastUParameter();
162 const Standard_Real aU2f = S2->FirstUParameter();
163 Standard_Real aU2l = S2->LastUParameter();
165 const Standard_Real anUperiod = 2.0*M_PI;
167 if(aU1l - aU1f > anUperiod)
168 aU1l = aU1f + anUperiod;
170 if(aU2l - aU2f > anUperiod)
171 aU2l = aU2f + anUperiod;
173 aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
174 aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
175 aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
176 aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
178 const Standard_Real a2DTol = Min( S1->UResolution(TolTang),
179 S2->UResolution(TolTang));
181 Standard_Boolean isReversed = ((aU2l - aU2f) < (aU1l - aU1f));
185 isDONE = IntCyCyTrim(quad2, quad1, TolTang, a2DTol, aBox2, aBox1,
186 isReversed, empt, slin, spnt);
190 isDONE = IntCyCyTrim(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
191 isReversed, empt, slin, spnt);
196 isDONE = IntCyCy(quad1, quad2, TolTang, empt,
197 SameSurf, multpoint, slin, spnt);
198 isTrimmed = Standard_False;
212 case 32: { // Cylinder/Cone
213 if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
221 case 42: { // Cylinder/Sphere
222 if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
230 case 52: { // Cylinder/Torus
231 if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
238 case 33: { // Cone/Cone
239 if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
247 case 43: { // Cone/Sphere
248 if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
256 case 53: { // Cone/Torus
257 if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
263 case 44: { // Sphere/Sphere
264 if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
272 case 54: { // Sphere/Torus
273 if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
280 case 55: { // Torus/Torus
281 if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
289 Standard_ConstructionError::Raise();
295 done = Standard_True;
303 AFunc.SetQuadric(quad2);
306 solrst.Perform(AFunc, D1, TolArc, TolTang);
307 if (!solrst.IsDone()) {
311 if (solrst.AllArcSolution() && typs1 == typs2) {
312 all1 = Standard_True;
314 nbpt = solrst.NbPoints();
315 nbseg= solrst.NbSegments();
316 for (i=1; i<= nbpt; i++) {
317 pnt1.Append(solrst.Point(i));
319 for (i=1; i<= nbseg; i++) {
320 edg1.Append(solrst.Segment(i));
322 nosolonS1 = (nbpt == 0) && (nbseg == 0);
324 if (nosolonS1 && all1) { // cas de face sans restrictions
325 all1 = Standard_False;
329 nosolonS1 = Standard_True;
333 AFunc.SetQuadric(quad1);
336 solrst.Perform(AFunc, D2, TolArc, TolTang);
337 if (!solrst.IsDone()) {
341 if (solrst.AllArcSolution() && typs1 == typs2) {
342 all2 = Standard_True;
344 nbpt = solrst.NbPoints();
345 nbseg= solrst.NbSegments();
346 for (i=1; i<= nbpt; i++) {
347 pnt2.Append(solrst.Point(i));
350 for (i=1; i<= nbseg; i++) {
351 edg2.Append(solrst.Segment(i));
353 nosolonS2 = (nbpt == 0) && (nbseg == 0);
355 if (nosolonS2 && all2) { // cas de face sans restrictions
356 all2 = Standard_False;
360 nosolonS2 = Standard_True;
363 if (SameSurf || (all1 && all2)) {
364 // faces "paralleles" parfaites
365 empt = Standard_False;
366 tgte = Standard_True;
373 case GeomAbs_Plane: {
374 Ptreference = (S1->Plane()).Location();
377 case GeomAbs_Cylinder: {
378 Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
381 case GeomAbs_Sphere: {
382 Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
386 Ptreference = ElSLib::Value(0.,10.,S1->Cone());
389 case GeomAbs_Torus: {
390 Ptreference = ElSLib::Value(0.,0.,S1->Torus());
397 oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
398 done = Standard_True;
400 }// if (SameSurf || (all1 && all2)) {
402 if (!nosolonS1 || !nosolonS2) {
403 empt = Standard_False;
404 // C est la qu il faut commencer a bosser...
405 PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
408 PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
411 if (edg1.Length() != 0) {
412 ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
415 if (edg2.Length() != 0) {
416 ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
419 if (edg1.Length() !=0 || edg2.Length() !=0) {
420 // ProcessRLine(slin,S1,S2,TolArc);
421 ProcessRLine(slin,quad1,quad2,TolArc);
423 }//if (!nosolonS1 || !nosolonS2) {
425 empt = ((slin.Length()==0) && (spnt.Length()==0));
429 Standard_Integer nblin = slin.Length(),
430 aNbPnt = spnt.Length();
432 //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
434 IntPatch_SequenceOfPoint aSIP;
436 for(i=1; i<=aNbPnt; ++i) {
437 Standard_Real aU1, aV1, aU2, aV2;
439 TopAbs_State aState1, aState2;
441 const IntPatch_Point& aIP=spnt(i);
442 aIP.Parameters(aU1, aV1, aU2, aV2);
444 aP2D.SetCoord(aU1, aV1);
445 aState1=D1->Classify(aP2D, TolArc);
447 aP2D.SetCoord(aU2, aV2);
448 aState2=D2->Classify(aP2D, TolArc);
450 if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
457 aNbPnt=aSIP.Length();
458 for(i=1; i<=aNbPnt; ++i) {
459 const IntPatch_Point& aIP=aSIP(i);
464 //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
466 for(i=1; i<=nblin; i++) {
467 IntPatch_IType thetype = slin.Value(i)->ArcType();
468 if( (thetype == IntPatch_Ellipse)
469 ||(thetype == IntPatch_Circle)
470 ||(thetype == IntPatch_Lin)
471 ||(thetype == IntPatch_Parabola)
472 ||(thetype == IntPatch_Hyperbola)) {
473 Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
474 glin->ComputeVertexParameters(TolArc);
476 else if(thetype == IntPatch_Analytic) {
477 Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
478 aligold->ComputeVertexParameters(TolArc);
480 else if(thetype == IntPatch_Restriction) {
481 Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
482 rlig->ComputeVertexParameters(TolArc);
486 //----------------------------------------------------------------
487 //-- On place 2 vertex sur les courbes de GLine qui n en
488 //-- contiennent pas.
489 for(i=1; i<=nblin; i++) {
491 IntPatch_Point point;
492 Standard_Real u1,v1,u2,v2;
493 if(slin.Value(i)->ArcType() == IntPatch_Circle) {
494 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
495 if(glin->NbVertex() == 0) {
496 gp_Circ Circ = glin->Circle();
497 P=ElCLib::Value(0.0,Circ);
498 quad1.Parameters(P,u1,v1);
499 quad2.Parameters(P,u2,v2);
500 point.SetValue(P,TolArc,Standard_False);
501 point.SetParameters(u1,v1,u2,v2);
502 point.SetParameter(0.0);
503 glin->AddVertex(point);
505 P=ElCLib::Value(0.0,Circ);
506 quad1.Parameters(P,u1,v1);
507 quad2.Parameters(P,u2,v2);
508 point.SetValue(P,TolArc,Standard_False);
509 point.SetParameters(u1,v1,u2,v2);
510 point.SetParameter(M_PI+M_PI);
511 glin->AddVertex(point);
515 else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) {
516 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
517 if(glin->NbVertex() == 0) {
518 gp_Elips Elips = glin->Ellipse();
519 P=ElCLib::Value(0.0,Elips);
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(0.0);
525 glin->AddVertex(point);
527 P=ElCLib::Value(0.0,Elips);
528 quad1.Parameters(P,u1,v1);
529 quad2.Parameters(P,u2,v2);
530 point.SetValue(P,TolArc,Standard_False);
531 point.SetParameters(u1,v1,u2,v2);
532 point.SetParameter(M_PI+M_PI);
533 glin->AddVertex(point);
537 done = Standard_True;
540 //=======================================================================
543 //=======================================================================
544 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
545 GeomAbs_SurfaceType& theTS,
546 IntSurf_Quadric& theQuad)
548 theTS = theS->GetType();
549 Standard_Integer iRet = 0;
552 theQuad.SetValue(theS->Plane());
555 case GeomAbs_Cylinder:
556 theQuad.SetValue(theS->Cylinder());
560 theQuad.SetValue(theS->Cone());
564 theQuad.SetValue(theS->Sphere());
568 theQuad.SetValue(theS->Torus());