0031201: Modeling Algorithms - Result of a section operation is incomplete
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_2.gxx
CommitLineData
b311480e 1// Created on: 1992-05-07
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
d30895f5 17#include <IntPatch_WLine.hxx>
18
7eed5d29 19static
20 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
21 GeomAbs_SurfaceType& theTS,
22 IntSurf_Quadric& theQuad);
23
c5c34473
J
24//=======================================================================
25//function : IntPatch_ImpImpIntersection
26//purpose :
27//=======================================================================
7fd59977 28IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
e146ef9a 29myDone(IntStatus_Fail)
7fd59977 30{
31}
c5c34473
J
32//=======================================================================
33//function : IntPatch_ImpImpIntersection
34//purpose :
35//=======================================================================
7fd59977 36IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
37 (const Handle(Adaptor3d_HSurface)& S1,
7eed5d29 38 const Handle(Adaptor3d_TopolTool)& D1,
7fd59977 39 const Handle(Adaptor3d_HSurface)& S2,
7eed5d29 40 const Handle(Adaptor3d_TopolTool)& D2,
41 const Standard_Real TolArc,
d4b867e6 42 const Standard_Real TolTang,
43 const Standard_Boolean theIsReqToKeepRLine)
7fd59977 44{
d30895f5 45 Perform(S1,D1,S2,D2,TolArc,TolTang, theIsReqToKeepRLine);
7fd59977 46}
c5c34473
J
47//=======================================================================
48//function : Perform
49//purpose :
50//=======================================================================
7fd59977 51void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
7eed5d29 52 const Handle(Adaptor3d_TopolTool)& D1,
53 const Handle(Adaptor3d_HSurface)& S2,
54 const Handle(Adaptor3d_TopolTool)& D2,
55 const Standard_Real TolArc,
ecc4f148 56 const Standard_Real TolTang,
d30895f5 57 const Standard_Boolean theIsReqToKeepRLine)
58{
e146ef9a 59 myDone = IntStatus_Fail;
7fd59977 60 spnt.Clear();
61 slin.Clear();
62
d30895f5 63 Standard_Boolean isPostProcessingRequired = Standard_True;
64
7fd59977 65 empt = Standard_True;
66 tgte = Standard_False;
67 oppo = Standard_False;
68
69 Standard_Boolean all1 = Standard_False;
70 Standard_Boolean all2 = Standard_False;
71 Standard_Boolean SameSurf = Standard_False;
72 Standard_Boolean multpoint = Standard_False;
73
74 Standard_Boolean nosolonS1 = Standard_False;
c5c34473 75 // indique s il y a des points sur restriction du carreau 1
7fd59977 76 Standard_Boolean nosolonS2 = Standard_False;
c5c34473 77 // indique s il y a des points sur restriction du carreau 2
7fd59977 78 Standard_Integer i, nbpt, nbseg;
7fd59977 79 IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
80 IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
c5c34473 81 //
7fd59977 82 // On commence par intersecter les supports des surfaces
7eed5d29 83 IntSurf_Quadric quad1, quad2;
7fd59977 84 IntPatch_ArcFunction AFunc;
788cbaf4 85 const Standard_Real Tolang = 1.e-8;
7eed5d29 86 GeomAbs_SurfaceType typs1, typs2;
87 Standard_Boolean bEmpty = Standard_False;
c5c34473 88 //
7eed5d29 89 const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
90 const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
91 //
92 if (!iT1 || !iT2) {
9775fa61 93 throw Standard_ConstructionError();
7eed5d29 94 return;
95 }
96 //
97 const Standard_Boolean bReverse = iT1 > iT2;
98 const Standard_Integer iTT = iT1*10 + iT2;
99 //
100 switch (iTT) {
101 case 11: { // Plane/Plane
102 if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
103 return;
7fd59977 104 }
7eed5d29 105 break;
7fd59977 106 }
7eed5d29 107 //
108 case 12:
109 case 21: { // Plane/Cylinder
110 Standard_Real VMin, VMax, H;
111 //
34e7ac68 112 const Handle(Adaptor3d_HSurface)& aSCyl = bReverse ? S1 : S2;
7eed5d29 113 VMin = aSCyl->FirstVParameter();
114 VMax = aSCyl->LastVParameter();
115 H = (Precision::IsNegativeInfinite(VMin) ||
116 Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
117 //
118 if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
119 return;
7fd59977 120 }
7eed5d29 121 bEmpty = empt;
122 break;
7fd59977 123 }
7eed5d29 124 //
125 case 13:
126 case 31: { // Plane/Cone
127 if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
128 return;
7fd59977 129 }
7eed5d29 130 bEmpty = empt;
131 break;
7fd59977 132 }
7eed5d29 133 //
134 case 14:
135 case 41: { // Plane/Sphere
136 if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
137 return;
7fd59977 138 }
7eed5d29 139 bEmpty = empt;
140 break;
7fd59977 141 }
7eed5d29 142 //
143 case 15:
144 case 51: { // Plane/Torus
145 if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
146 return;
147 }
148 bEmpty = empt;
149 break;
150 }
151 //
ecc4f148 152 case 22:
153 { // Cylinder/Cylinder
d30895f5 154 Bnd_Box2d aBox1, aBox2;
02effd35 155
d30895f5 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();
02effd35 160
d30895f5 161 const Standard_Real anUperiod = 2.0*M_PI;
02effd35 162
d30895f5 163 if(aU1l - aU1f > anUperiod)
164 aU1l = aU1f + anUperiod;
ecc4f148 165
d30895f5 166 if(aU2l - aU2f > anUperiod)
167 aU2l = aU2f + anUperiod;
ecc4f148 168
d30895f5 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()));
ecc4f148 173
d30895f5 174 // Resolution is too big if the cylinder radius is
261b7d9e 175 // too small. Therefore, we shall bind its value above.
d30895f5 176 // Here, we use simple constant.
177 const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang),
178 S2->UResolution(TolTang)));
ecc4f148 179
261b7d9e 180 myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
181 empt, SameSurf, multpoint, slin, spnt);
ecc4f148 182
e146ef9a 183 if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
ecc4f148 184 {
185 return;
186 }
187
188 bEmpty = empt;
d30895f5 189 if(!slin.IsEmpty())
190 {
191 const Handle(IntPatch_WLine)& aWLine =
192 Handle(IntPatch_WLine)::DownCast(slin.Value(1));
193
194 if(!aWLine.IsNull())
195 {//No geometric solution
196 isPostProcessingRequired = Standard_False;
197 }
198 }
199
ecc4f148 200 break;
7eed5d29 201 }
7eed5d29 202 //
203 case 23:
204 case 32: { // Cylinder/Cone
205 if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
206 return;
207 }
208 bEmpty = empt;
209 break;
210 }
211 //
212 case 24:
213 case 42: { // Cylinder/Sphere
214 if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
215 return;
216 }
217 bEmpty = empt;
218 break;
219 }
220 //
221 case 25:
222 case 52: { // Cylinder/Torus
223 if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
224 return;
225 }
226 bEmpty = empt;
227 break;
228 }
229 //
230 case 33: { // Cone/Cone
231 if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
232 return;
233 }
234 bEmpty = empt;
235 break;
236 }
237 //
238 case 34:
239 case 43: { // Cone/Sphere
240 if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
241 return;
242 }
243 bEmpty = empt;
244 break;
245 }
246 //
247 case 35:
248 case 53: { // Cone/Torus
249 if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
250 return;
251 }
252 break;
253 }
254 //
255 case 44: { // Sphere/Sphere
256 if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
257 return;
258 }
259 bEmpty = empt;
260 break;
261 }
262 //
263 case 45:
264 case 54: { // Sphere/Torus
265 if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
266 return;
267 }
268 bEmpty = empt;
269 break;
270 }
271 //
272 case 55: { // Torus/Torus
273 if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
274 return;
275 }
276 bEmpty = empt;
277 break;
278 }
279 //
280 default: {
9775fa61 281 throw Standard_ConstructionError();
7fd59977 282 break;
283 }
7eed5d29 284 }
285 //
286 if (bEmpty) {
e146ef9a 287 if (myDone == IntStatus_Fail)
288 myDone = IntStatus_OK;
289
7eed5d29 290 return;
291 }
c5c34473 292 //
ecc4f148 293
d30895f5 294 if(isPostProcessingRequired)
ecc4f148 295 {
296 if (!SameSurf) {
297 AFunc.SetQuadric(quad2);
298 AFunc.Set(S1);
7fd59977 299
ecc4f148 300 solrst.Perform(AFunc, D1, TolArc, TolTang);
301 if (!solrst.IsDone()) {
302 return;
303 }
7fd59977 304
ecc4f148 305 if (solrst.AllArcSolution() && typs1 == typs2) {
306 all1 = Standard_True;
307 }
308 nbpt = solrst.NbPoints();
309 nbseg= solrst.NbSegments();
3306fdd9 310 for (i = 1; i <= nbpt; i++)
311 {
312 const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
313 pnt1.Append(aPt);
ecc4f148 314 }
3306fdd9 315 for (i = 1; i <= nbseg; i++)
316 {
317 const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
318 edg1.Append(aSegm);
ecc4f148 319 }
320 nosolonS1 = (nbpt == 0) && (nbseg == 0);
7fd59977 321
ecc4f148 322 if (nosolonS1 && all1) { // cas de face sans restrictions
323 all1 = Standard_False;
324 }
325 }//if (!SameSurf) {
326 else {
327 nosolonS1 = Standard_True;
7fd59977 328 }
7fd59977 329
ecc4f148 330 if (!SameSurf) {
331 AFunc.SetQuadric(quad1);
332 AFunc.Set(S2);
7fd59977 333
ecc4f148 334 solrst.Perform(AFunc, D2, TolArc, TolTang);
335 if (!solrst.IsDone()) {
336 return;
337 }
7fd59977 338
ecc4f148 339 if (solrst.AllArcSolution() && typs1 == typs2) {
340 all2 = Standard_True;
341 }
3306fdd9 342
ecc4f148 343 nbpt = solrst.NbPoints();
344 nbseg= solrst.NbSegments();
345 for (i=1; i<= nbpt; i++) {
3306fdd9 346 const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
347 pnt2.Append(aPt);
ecc4f148 348 }
7fd59977 349
ecc4f148 350 for (i=1; i<= nbseg; i++) {
3306fdd9 351 const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
352 edg2.Append(aSegm);
ecc4f148 353 }
3306fdd9 354
ecc4f148 355 nosolonS2 = (nbpt == 0) && (nbseg == 0);
7fd59977 356
ecc4f148 357 if (nosolonS2 && all2) { // cas de face sans restrictions
358 all2 = Standard_False;
359 }
360 }// if (!SameSurf) {
361 else {
362 nosolonS2 = Standard_True;
7fd59977 363 }
ecc4f148 364 //
365 if (SameSurf || (all1 && all2)) {
366 // faces "paralleles" parfaites
367 empt = Standard_False;
368 tgte = Standard_True;
369 slin.Clear();
370 spnt.Clear();
7fd59977 371
ecc4f148 372 gp_Pnt Ptreference;
7fd59977 373
ecc4f148 374 switch (typs1) {
375 case GeomAbs_Plane: {
376 Ptreference = (S1->Plane()).Location();
377 }
378 break;
379 case GeomAbs_Cylinder: {
380 Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
381 }
382 break;
383 case GeomAbs_Sphere: {
384 Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
385 }
386 break;
387 case GeomAbs_Cone: {
388 Ptreference = ElSLib::Value(0.,10.,S1->Cone());
389 }
390 break;
391 case GeomAbs_Torus: {
392 Ptreference = ElSLib::Value(0.,0.,S1->Torus());
393 }
394 break;
395 default:
396 break;
397 }
398 //
399 oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
e146ef9a 400 myDone = IntStatus_OK;
ecc4f148 401 return;
402 }// if (SameSurf || (all1 && all2)) {
7fd59977 403
ecc4f148 404 if (!nosolonS1 || !nosolonS2) {
405 empt = Standard_False;
406 // C est la qu il faut commencer a bosser...
407 PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
408 multpoint,TolArc);
7fd59977 409
ecc4f148 410 PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
411 multpoint,TolArc);
7fd59977 412
ecc4f148 413 if (edg1.Length() != 0) {
414 ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
415 }
7fd59977 416
ecc4f148 417 if (edg2.Length() != 0) {
418 ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
419 }
7fd59977 420
ecc4f148 421 if (edg1.Length() !=0 || edg2.Length() !=0) {
422 // ProcessRLine(slin,S1,S2,TolArc);
d4b867e6 423 ProcessRLine(slin,quad1,quad2,TolArc, theIsReqToKeepRLine);
ecc4f148 424 }
425 }//if (!nosolonS1 || !nosolonS2) {
426 else {
427 empt = ((slin.Length()==0) && (spnt.Length()==0));
7fd59977 428 }
7fd59977 429 }
ecc4f148 430
431 Standard_Integer nblin = slin.Length(),
432 aNbPnt = spnt.Length();
c5c34473
J
433 //
434 //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
c5c34473
J
435 if (aNbPnt) {
436 IntPatch_SequenceOfPoint aSIP;
437 //
438 for(i=1; i<=aNbPnt; ++i) {
439 Standard_Real aU1, aV1, aU2, aV2;
440 gp_Pnt2d aP2D;
441 TopAbs_State aState1, aState2;
442 //
443 const IntPatch_Point& aIP=spnt(i);
444 aIP.Parameters(aU1, aV1, aU2, aV2);
445 //
446 aP2D.SetCoord(aU1, aV1);
447 aState1=D1->Classify(aP2D, TolArc);
448 //
449 aP2D.SetCoord(aU2, aV2);
450 aState2=D2->Classify(aP2D, TolArc);
451 //
452 if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
7eed5d29 453 aSIP.Append(aIP);
c5c34473
J
454 }
455 }
456 //
457 spnt.Clear();
458 //
459 aNbPnt=aSIP.Length();
460 for(i=1; i<=aNbPnt; ++i) {
461 const IntPatch_Point& aIP=aSIP(i);
462 spnt.Append(aIP);
463 }
464 //
465 }// if (aNbPnt) {
466 //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
467 //
7fd59977 468 for(i=1; i<=nblin; i++) {
469 IntPatch_IType thetype = slin.Value(i)->ArcType();
470 if( (thetype == IntPatch_Ellipse)
471 ||(thetype == IntPatch_Circle)
472 ||(thetype == IntPatch_Lin)
473 ||(thetype == IntPatch_Parabola)
474 ||(thetype == IntPatch_Hyperbola)) {
475 Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
7fd59977 476 glin->ComputeVertexParameters(TolArc);
477 }
478 else if(thetype == IntPatch_Analytic) {
479 Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
480 aligold->ComputeVertexParameters(TolArc);
481 }
482 else if(thetype == IntPatch_Restriction) {
483 Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
484 rlig->ComputeVertexParameters(TolArc);
485 }
486 }
c5c34473 487 //
7fd59977 488 //----------------------------------------------------------------
489 //-- On place 2 vertex sur les courbes de GLine qui n en
490 //-- contiennent pas.
7fd59977 491 for(i=1; i<=nblin; i++) {
492 gp_Pnt P;
493 IntPatch_Point point;
494 Standard_Real u1,v1,u2,v2;
7fd59977 495 if(slin.Value(i)->ArcType() == IntPatch_Circle) {
496 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
7fd59977 497 if(glin->NbVertex() == 0) {
7eed5d29 498 gp_Circ Circ = glin->Circle();
499 P=ElCLib::Value(0.0,Circ);
500 quad1.Parameters(P,u1,v1);
501 quad2.Parameters(P,u2,v2);
502 point.SetValue(P,TolArc,Standard_False);
503 point.SetParameters(u1,v1,u2,v2);
504 point.SetParameter(0.0);
505 glin->AddVertex(point);
506
507 P=ElCLib::Value(0.0,Circ);
508 quad1.Parameters(P,u1,v1);
509 quad2.Parameters(P,u2,v2);
510 point.SetValue(P,TolArc,Standard_False);
511 point.SetParameters(u1,v1,u2,v2);
512 point.SetParameter(M_PI+M_PI);
513 glin->AddVertex(point);
7fd59977 514 }
515 }
516
517 else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) {
518 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
7fd59977 519 if(glin->NbVertex() == 0) {
7eed5d29 520 gp_Elips Elips = glin->Ellipse();
521 P=ElCLib::Value(0.0,Elips);
522 quad1.Parameters(P,u1,v1);
523 quad2.Parameters(P,u2,v2);
524 point.SetValue(P,TolArc,Standard_False);
525 point.SetParameters(u1,v1,u2,v2);
526 point.SetParameter(0.0);
527 glin->AddVertex(point);
528
529 P=ElCLib::Value(0.0,Elips);
530 quad1.Parameters(P,u1,v1);
531 quad2.Parameters(P,u2,v2);
532 point.SetValue(P,TolArc,Standard_False);
533 point.SetParameters(u1,v1,u2,v2);
534 point.SetParameter(M_PI+M_PI);
535 glin->AddVertex(point);
7fd59977 536 }
537 }
538 }
e146ef9a 539 myDone = IntStatus_OK;
7fd59977 540}
7fd59977 541
7eed5d29 542//=======================================================================
543//function : SetQuad
544//purpose :
545//=======================================================================
546Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
547 GeomAbs_SurfaceType& theTS,
548 IntSurf_Quadric& theQuad)
549{
550 theTS = theS->GetType();
551 Standard_Integer iRet = 0;
552 switch (theTS) {
553 case GeomAbs_Plane:
554 theQuad.SetValue(theS->Plane());
555 iRet = 1;
556 break;
557 case GeomAbs_Cylinder:
558 theQuad.SetValue(theS->Cylinder());
559 iRet = 2;
560 break;
561 case GeomAbs_Cone:
562 theQuad.SetValue(theS->Cone());
563 iRet = 3;
564 break;
565 case GeomAbs_Sphere:
566 theQuad.SetValue(theS->Sphere());
567 iRet = 4;
568 break;
569 case GeomAbs_Torus:
570 theQuad.SetValue(theS->Torus());
571 iRet = 5;
572 break;
573 default:
574 break;
575 }
576 //
577 return iRet;
578}
579