Warning, /include/opencascade/IntPatch_ImpImpIntersection_2.gxx is written in an unsupported language. File is not indexed.
0001 // Created on: 1992-05-07
0002 // Created by: Jacques GOUSSARD
0003 // Copyright (c) 1992-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016
0017 #include <IntPatch_WLine.hxx>
0018
0019 static
0020 Standard_Integer SetQuad(const Handle(Adaptor3d_Surface)& theS,
0021 GeomAbs_SurfaceType& theTS,
0022 IntSurf_Quadric& theQuad);
0023
0024 //=======================================================================
0025 //function : IntPatch_ImpImpIntersection
0026 //purpose :
0027 //=======================================================================
0028 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
0029 myDone(IntStatus_Fail),
0030 empt(Standard_True),
0031 tgte(Standard_False),
0032 oppo(Standard_False)
0033 {
0034 }
0035 //=======================================================================
0036 //function : IntPatch_ImpImpIntersection
0037 //purpose :
0038 //=======================================================================
0039 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
0040 (const Handle(Adaptor3d_Surface)& S1,
0041 const Handle(Adaptor3d_TopolTool)& D1,
0042 const Handle(Adaptor3d_Surface)& S2,
0043 const Handle(Adaptor3d_TopolTool)& D2,
0044 const Standard_Real TolArc,
0045 const Standard_Real TolTang,
0046 const Standard_Boolean theIsReqToKeepRLine)
0047 {
0048 Perform(S1,D1,S2,D2,TolArc,TolTang, theIsReqToKeepRLine);
0049 }
0050 //=======================================================================
0051 //function : Perform
0052 //purpose :
0053 //=======================================================================
0054 void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_Surface)& S1,
0055 const Handle(Adaptor3d_TopolTool)& D1,
0056 const Handle(Adaptor3d_Surface)& S2,
0057 const Handle(Adaptor3d_TopolTool)& D2,
0058 const Standard_Real TolArc,
0059 const Standard_Real TolTang,
0060 const Standard_Boolean theIsReqToKeepRLine)
0061 {
0062 myDone = IntStatus_Fail;
0063 spnt.Clear();
0064 slin.Clear();
0065
0066 Standard_Boolean isPostProcessingRequired = Standard_True;
0067
0068 empt = Standard_True;
0069 tgte = Standard_False;
0070 oppo = Standard_False;
0071
0072 Standard_Boolean all1 = Standard_False;
0073 Standard_Boolean all2 = Standard_False;
0074 Standard_Boolean SameSurf = Standard_False;
0075 Standard_Boolean multpoint = Standard_False;
0076
0077 Standard_Boolean nosolonS1 = Standard_False;
0078 // indique s il y a des points sur restriction du carreau 1
0079 Standard_Boolean nosolonS2 = Standard_False;
0080 // indique s il y a des points sur restriction du carreau 2
0081 Standard_Integer i, nbpt, nbseg;
0082 IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
0083 IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
0084 //
0085 // On commence par intersecter les supports des surfaces
0086 IntSurf_Quadric quad1, quad2;
0087 IntPatch_ArcFunction AFunc;
0088 const Standard_Real Tolang = 1.e-8;
0089 GeomAbs_SurfaceType typs1, typs2;
0090 Standard_Boolean bEmpty = Standard_False;
0091 //
0092 const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
0093 const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
0094 //
0095 if (!iT1 || !iT2) {
0096 throw Standard_ConstructionError();
0097 return;
0098 }
0099 //
0100 const Standard_Boolean bReverse = iT1 > iT2;
0101 const Standard_Integer iTT = iT1*10 + iT2;
0102 //
0103 switch (iTT) {
0104 case 11: { // Plane/Plane
0105 if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
0106 return;
0107 }
0108 break;
0109 }
0110 //
0111 case 12:
0112 case 21: { // Plane/Cylinder
0113 Standard_Real VMin, VMax, H;
0114 //
0115 const Handle(Adaptor3d_Surface)& aSCyl = bReverse ? S1 : S2;
0116 VMin = aSCyl->FirstVParameter();
0117 VMax = aSCyl->LastVParameter();
0118 H = (Precision::IsNegativeInfinite(VMin) ||
0119 Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
0120 //
0121 if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
0122 return;
0123 }
0124 bEmpty = empt;
0125 break;
0126 }
0127 //
0128 case 13:
0129 case 31: { // Plane/Cone
0130 if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
0131 return;
0132 }
0133 bEmpty = empt;
0134 break;
0135 }
0136 //
0137 case 14:
0138 case 41: { // Plane/Sphere
0139 if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
0140 return;
0141 }
0142 bEmpty = empt;
0143 break;
0144 }
0145 //
0146 case 15:
0147 case 51: { // Plane/Torus
0148 if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
0149 return;
0150 }
0151 bEmpty = empt;
0152 break;
0153 }
0154 //
0155 case 22:
0156 { // Cylinder/Cylinder
0157 Bnd_Box2d aBox1, aBox2;
0158
0159 const Standard_Real aU1f = S1->FirstUParameter();
0160 Standard_Real aU1l = S1->LastUParameter();
0161 const Standard_Real aU2f = S2->FirstUParameter();
0162 Standard_Real aU2l = S2->LastUParameter();
0163
0164 const Standard_Real anUperiod = 2.0*M_PI;
0165
0166 if(aU1l - aU1f > anUperiod)
0167 aU1l = aU1f + anUperiod;
0168
0169 if(aU2l - aU2f > anUperiod)
0170 aU2l = aU2f + anUperiod;
0171
0172 aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
0173 aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
0174 aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
0175 aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
0176
0177 // Resolution is too big if the cylinder radius is
0178 // too small. Therefore, we shall bind its value above.
0179 // Here, we use simple constant.
0180 const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang),
0181 S2->UResolution(TolTang)));
0182
0183 myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
0184 empt, SameSurf, multpoint, slin, spnt);
0185
0186 if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
0187 {
0188 return;
0189 }
0190
0191 bEmpty = empt;
0192 if(!slin.IsEmpty())
0193 {
0194 const Handle(IntPatch_WLine)& aWLine =
0195 Handle(IntPatch_WLine)::DownCast(slin.Value(1));
0196
0197 if(!aWLine.IsNull())
0198 {//No geometric solution
0199 isPostProcessingRequired = Standard_False;
0200 }
0201 }
0202
0203 break;
0204 }
0205 //
0206 case 23:
0207 case 32: { // Cylinder/Cone
0208 if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
0209 return;
0210 }
0211 bEmpty = empt;
0212 break;
0213 }
0214 //
0215 case 24:
0216 case 42: { // Cylinder/Sphere
0217 if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
0218 return;
0219 }
0220 bEmpty = empt;
0221 break;
0222 }
0223 //
0224 case 25:
0225 case 52: { // Cylinder/Torus
0226 if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
0227 return;
0228 }
0229 bEmpty = empt;
0230 break;
0231 }
0232 //
0233 case 33: { // Cone/Cone
0234 if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
0235 return;
0236 }
0237 bEmpty = empt;
0238 break;
0239 }
0240 //
0241 case 34:
0242 case 43: { // Cone/Sphere
0243 if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
0244 return;
0245 }
0246 bEmpty = empt;
0247 break;
0248 }
0249 //
0250 case 35:
0251 case 53: { // Cone/Torus
0252 if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
0253 return;
0254 }
0255 break;
0256 }
0257 //
0258 case 44: { // Sphere/Sphere
0259 if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
0260 return;
0261 }
0262 bEmpty = empt;
0263 break;
0264 }
0265 //
0266 case 45:
0267 case 54: { // Sphere/Torus
0268 if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
0269 return;
0270 }
0271 bEmpty = empt;
0272 break;
0273 }
0274 //
0275 case 55: { // Torus/Torus
0276 if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
0277 return;
0278 }
0279 bEmpty = empt;
0280 break;
0281 }
0282 //
0283 default: {
0284 throw Standard_ConstructionError();
0285 break;
0286 }
0287 }
0288 //
0289 if (bEmpty) {
0290 if (myDone == IntStatus_Fail)
0291 myDone = IntStatus_OK;
0292
0293 return;
0294 }
0295 //
0296
0297 if(isPostProcessingRequired)
0298 {
0299 if (!SameSurf) {
0300 AFunc.SetQuadric(quad2);
0301 AFunc.Set(S1);
0302
0303 solrst.Perform(AFunc, D1, TolArc, TolTang);
0304 if (!solrst.IsDone()) {
0305 return;
0306 }
0307
0308 if (solrst.AllArcSolution() && typs1 == typs2) {
0309 all1 = Standard_True;
0310 }
0311 nbpt = solrst.NbPoints();
0312 nbseg= solrst.NbSegments();
0313 for (i = 1; i <= nbpt; i++)
0314 {
0315 const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
0316 pnt1.Append(aPt);
0317 }
0318 for (i = 1; i <= nbseg; i++)
0319 {
0320 const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
0321 edg1.Append(aSegm);
0322 }
0323 nosolonS1 = (nbpt == 0) && (nbseg == 0);
0324
0325 if (nosolonS1 && all1) { // cas de face sans restrictions
0326 all1 = Standard_False;
0327 }
0328 }//if (!SameSurf) {
0329 else {
0330 nosolonS1 = Standard_True;
0331 }
0332
0333 if (!SameSurf) {
0334 AFunc.SetQuadric(quad1);
0335 AFunc.Set(S2);
0336
0337 solrst.Perform(AFunc, D2, TolArc, TolTang);
0338 if (!solrst.IsDone()) {
0339 return;
0340 }
0341
0342 if (solrst.AllArcSolution() && typs1 == typs2) {
0343 all2 = Standard_True;
0344 }
0345
0346 nbpt = solrst.NbPoints();
0347 nbseg= solrst.NbSegments();
0348 for (i=1; i<= nbpt; i++) {
0349 const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
0350 pnt2.Append(aPt);
0351 }
0352
0353 for (i=1; i<= nbseg; i++) {
0354 const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
0355 edg2.Append(aSegm);
0356 }
0357
0358 nosolonS2 = (nbpt == 0) && (nbseg == 0);
0359
0360 if (nosolonS2 && all2) { // cas de face sans restrictions
0361 all2 = Standard_False;
0362 }
0363 }// if (!SameSurf) {
0364 else {
0365 nosolonS2 = Standard_True;
0366 }
0367 //
0368 if (SameSurf || (all1 && all2)) {
0369 // faces "paralleles" parfaites
0370 empt = Standard_False;
0371 tgte = Standard_True;
0372 slin.Clear();
0373 spnt.Clear();
0374
0375 gp_Pnt Ptreference;
0376
0377 switch (typs1) {
0378 case GeomAbs_Plane: {
0379 Ptreference = (S1->Plane()).Location();
0380 }
0381 break;
0382 case GeomAbs_Cylinder: {
0383 Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
0384 }
0385 break;
0386 case GeomAbs_Sphere: {
0387 Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
0388 }
0389 break;
0390 case GeomAbs_Cone: {
0391 Ptreference = ElSLib::Value(0.,10.,S1->Cone());
0392 }
0393 break;
0394 case GeomAbs_Torus: {
0395 Ptreference = ElSLib::Value(0.,0.,S1->Torus());
0396 }
0397 break;
0398 default:
0399 break;
0400 }
0401 //
0402 oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
0403 myDone = IntStatus_OK;
0404 return;
0405 }// if (SameSurf || (all1 && all2)) {
0406
0407 if (!nosolonS1 || !nosolonS2) {
0408 empt = Standard_False;
0409 // C est la qu il faut commencer a bosser...
0410 PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
0411 multpoint,TolArc);
0412
0413 PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
0414 multpoint,TolArc);
0415
0416 if (edg1.Length() != 0) {
0417 ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
0418 }
0419
0420 if (edg2.Length() != 0) {
0421 ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
0422 }
0423
0424 if (edg1.Length() !=0 || edg2.Length() !=0) {
0425 // ProcessRLine(slin,S1,S2,TolArc);
0426 ProcessRLine(slin,quad1,quad2,TolArc, theIsReqToKeepRLine);
0427 }
0428 }//if (!nosolonS1 || !nosolonS2) {
0429 else {
0430 empt = ((slin.Length()==0) && (spnt.Length()==0));
0431 }
0432 }
0433
0434 Standard_Integer nblin = slin.Length(),
0435 aNbPnt = spnt.Length();
0436 //
0437 //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
0438 if (aNbPnt) {
0439 IntPatch_SequenceOfPoint aSIP;
0440 //
0441 for(i=1; i<=aNbPnt; ++i) {
0442 Standard_Real aU1, aV1, aU2, aV2;
0443 gp_Pnt2d aP2D;
0444 TopAbs_State aState1, aState2;
0445 //
0446 const IntPatch_Point& aIP=spnt(i);
0447 aIP.Parameters(aU1, aV1, aU2, aV2);
0448 //
0449 aP2D.SetCoord(aU1, aV1);
0450 aState1=D1->Classify(aP2D, TolArc);
0451 //
0452 aP2D.SetCoord(aU2, aV2);
0453 aState2=D2->Classify(aP2D, TolArc);
0454 //
0455 if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
0456 aSIP.Append(aIP);
0457 }
0458 }
0459 //
0460 spnt.Clear();
0461 //
0462 aNbPnt=aSIP.Length();
0463 for(i=1; i<=aNbPnt; ++i) {
0464 const IntPatch_Point& aIP=aSIP(i);
0465 spnt.Append(aIP);
0466 }
0467 //
0468 }// if (aNbPnt) {
0469 //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
0470 //
0471 for(i=1; i<=nblin; i++) {
0472 IntPatch_IType thetype = slin.Value(i)->ArcType();
0473 if( (thetype == IntPatch_Ellipse)
0474 ||(thetype == IntPatch_Circle)
0475 ||(thetype == IntPatch_Lin)
0476 ||(thetype == IntPatch_Parabola)
0477 ||(thetype == IntPatch_Hyperbola)) {
0478 Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
0479 glin->ComputeVertexParameters(TolArc);
0480 }
0481 else if(thetype == IntPatch_Analytic) {
0482 Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
0483 aligold->ComputeVertexParameters(TolArc);
0484 }
0485 else if(thetype == IntPatch_Restriction) {
0486 Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
0487 rlig->ComputeVertexParameters(TolArc);
0488 }
0489 }
0490 //
0491 //----------------------------------------------------------------
0492 //-- On place 2 vertex sur les courbes de GLine qui n en
0493 //-- contiennent pas.
0494 for(i=1; i<=nblin; i++) {
0495 gp_Pnt P;
0496 IntPatch_Point point;
0497 Standard_Real u1,v1,u2,v2;
0498 if(slin.Value(i)->ArcType() == IntPatch_Circle) {
0499 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
0500 if(glin->NbVertex() == 0) {
0501 gp_Circ Circ = glin->Circle();
0502 P=ElCLib::Value(0.0,Circ);
0503 quad1.Parameters(P,u1,v1);
0504 quad2.Parameters(P,u2,v2);
0505 point.SetValue(P,TolArc,Standard_False);
0506 point.SetParameters(u1,v1,u2,v2);
0507 point.SetParameter(0.0);
0508 glin->AddVertex(point);
0509
0510 P=ElCLib::Value(0.0,Circ);
0511 quad1.Parameters(P,u1,v1);
0512 quad2.Parameters(P,u2,v2);
0513 point.SetValue(P,TolArc,Standard_False);
0514 point.SetParameters(u1,v1,u2,v2);
0515 point.SetParameter(M_PI+M_PI);
0516 glin->AddVertex(point);
0517 }
0518 }
0519
0520 else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) {
0521 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
0522 if(glin->NbVertex() == 0) {
0523 gp_Elips Elips = glin->Ellipse();
0524 P=ElCLib::Value(0.0,Elips);
0525 quad1.Parameters(P,u1,v1);
0526 quad2.Parameters(P,u2,v2);
0527 point.SetValue(P,TolArc,Standard_False);
0528 point.SetParameters(u1,v1,u2,v2);
0529 point.SetParameter(0.0);
0530 glin->AddVertex(point);
0531
0532 P=ElCLib::Value(0.0,Elips);
0533 quad1.Parameters(P,u1,v1);
0534 quad2.Parameters(P,u2,v2);
0535 point.SetValue(P,TolArc,Standard_False);
0536 point.SetParameters(u1,v1,u2,v2);
0537 point.SetParameter(M_PI+M_PI);
0538 glin->AddVertex(point);
0539 }
0540 }
0541 }
0542 myDone = IntStatus_OK;
0543 }
0544
0545 //=======================================================================
0546 //function : SetQuad
0547 //purpose :
0548 //=======================================================================
0549 Standard_Integer SetQuad(const Handle(Adaptor3d_Surface)& theS,
0550 GeomAbs_SurfaceType& theTS,
0551 IntSurf_Quadric& theQuad)
0552 {
0553 theTS = theS->GetType();
0554 Standard_Integer iRet = 0;
0555 switch (theTS) {
0556 case GeomAbs_Plane:
0557 theQuad.SetValue(theS->Plane());
0558 iRet = 1;
0559 break;
0560 case GeomAbs_Cylinder:
0561 theQuad.SetValue(theS->Cylinder());
0562 iRet = 2;
0563 break;
0564 case GeomAbs_Cone:
0565 theQuad.SetValue(theS->Cone());
0566 iRet = 3;
0567 break;
0568 case GeomAbs_Sphere:
0569 theQuad.SetValue(theS->Sphere());
0570 iRet = 4;
0571 break;
0572 case GeomAbs_Torus:
0573 theQuad.SetValue(theS->Torus());
0574 iRet = 5;
0575 break;
0576 default:
0577 break;
0578 }
0579 //
0580 return iRet;
0581 }
0582