0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / GeomInt / GeomInt_LineConstructor.cxx
CommitLineData
b311480e 1// Created on: 1995-02-07
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1995-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
17#include <GeomInt_LineConstructor.ixx>
18
19#include <GeomInt_LineTool.hxx>
20#include <GeomInt_SequenceOfParameterAndOrientation.hxx>
21#include <GeomInt_ParameterAndOrientation.hxx>
22
23#include <IntPatch_Point.hxx>
24#include <IntPatch_GLine.hxx>
25#include <IntPatch_WLine.hxx>
26#include <IntPatch_ALine.hxx>
27#include <IntSurf_Transition.hxx>
28#include <TopAbs_Orientation.hxx>
29
30#include <Precision.hxx>
31#include <gp_Pnt2d.hxx>
32#include <Adaptor2d_HCurve2d.hxx>
33
34#include <GeomAdaptor_HSurface.hxx>
35#include <Standard_ConstructionError.hxx>
36#include <IntSurf_Quadric.hxx>
37#include <IntSurf_PntOn2S.hxx>
38#include <ElCLib.hxx>
39#include <GeomAbs_SurfaceType.hxx>
40
41
42//=======================================================================
43//function : Recadre
44//purpose :
45//=======================================================================
46static void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
47 const Handle(GeomAdaptor_HSurface)& myHS2,
48 Standard_Real& u1,
49 Standard_Real& v1,
50 Standard_Real& u2,
51 Standard_Real& v2)
52{
53 Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
54 const GeomAbs_SurfaceType typs1 = myHS1->GetType();
55 switch (typs1)
56 {
57 case GeomAbs_Cylinder:
58 case GeomAbs_Cone:
59 case GeomAbs_Sphere:
60 {
61 myHS1IsUPeriodic = Standard_True;
62 myHS1IsVPeriodic = Standard_False;
63 break;
64 }
65 case GeomAbs_Torus:
66 {
67 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
68 break;
69 }
70 default:
71 {
72 //-- Le cas de biparametrees periodiques est gere en amont
73 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
74 break;
75 }
76 }
77 Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
78 const GeomAbs_SurfaceType typs2 = myHS2->GetType();
79 switch (typs2)
80 {
81 case GeomAbs_Cylinder:
82 case GeomAbs_Cone:
83 case GeomAbs_Sphere:
84 {
85 myHS2IsUPeriodic = Standard_True;
86 myHS2IsVPeriodic = Standard_False;
87 break;
88 }
89 case GeomAbs_Torus:
90 {
91 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
92 break;
93 }
94 default:
95 {
96 //-- Le cas de biparametrees periodiques est gere en amont
97 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
98 break;
99 }
100 }
101 if(myHS1IsUPeriodic) {
c6541a0c 102 const Standard_Real lmf = M_PI+M_PI; //-- myHS1->UPeriod();
7fd59977 103 const Standard_Real f = myHS1->FirstUParameter();
104 const Standard_Real l = myHS1->LastUParameter();
105 while(u1 < f) { u1+=lmf; }
106 while(u1 > l) { u1-=lmf; }
107 }
108 if(myHS1IsVPeriodic) {
c6541a0c 109 const Standard_Real lmf = M_PI+M_PI; //-- myHS1->VPeriod();
7fd59977 110 const Standard_Real f = myHS1->FirstVParameter();
111 const Standard_Real l = myHS1->LastVParameter();
112 while(v1 < f) { v1+=lmf; }
113 while(v1 > l) { v1-=lmf; }
114 }
115 if(myHS2IsUPeriodic) {
c6541a0c 116 const Standard_Real lmf = M_PI+M_PI; //-- myHS2->UPeriod();
7fd59977 117 const Standard_Real f = myHS2->FirstUParameter();
118 const Standard_Real l = myHS2->LastUParameter();
119 while(u2 < f) { u2+=lmf; }
120 while(u2 > l) { u2-=lmf; }
121 }
122 if(myHS2IsVPeriodic) {
c6541a0c 123 const Standard_Real lmf = M_PI+M_PI; //-- myHS2->VPeriod();
7fd59977 124 const Standard_Real f = myHS2->FirstVParameter();
125 const Standard_Real l = myHS2->LastVParameter();
126 while(v2 < f) { v2+=lmf; }
127 while(v2 > l) { v2-=lmf; }
128 }
129}
130
131
132//=======================================================================
133//function : Parameters
134//purpose :
135//=======================================================================
136static void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
137 const Handle(GeomAdaptor_HSurface)& myHS2,
138 const gp_Pnt& Ptref,
139 Standard_Real& U1,
140 Standard_Real& V1,
141 Standard_Real& U2,
142 Standard_Real& V2)
143{
144 IntSurf_Quadric quad1,quad2;
145 switch (myHS1->Surface().GetType())
146 {
147 case GeomAbs_Plane: quad1.SetValue(myHS1->Surface().Plane()); break;
148 case GeomAbs_Cylinder: quad1.SetValue(myHS1->Surface().Cylinder()); break;
149 case GeomAbs_Cone: quad1.SetValue(myHS1->Surface().Cone()); break;
150 case GeomAbs_Sphere: quad1.SetValue(myHS1->Surface().Sphere()); break;
7eed5d29 151 case GeomAbs_Torus: quad1.SetValue(myHS1->Surface().Torus()); break;
7fd59977 152 default: Standard_ConstructionError::Raise("GeomInt_LineConstructor::Parameters");
153 }
154 switch (myHS2->Surface().GetType())
155 {
156 case GeomAbs_Plane: quad2.SetValue(myHS2->Surface().Plane()); break;
157 case GeomAbs_Cylinder: quad2.SetValue(myHS2->Surface().Cylinder()); break;
158 case GeomAbs_Cone: quad2.SetValue(myHS2->Surface().Cone()); break;
159 case GeomAbs_Sphere: quad2.SetValue(myHS2->Surface().Sphere()); break;
7eed5d29 160 case GeomAbs_Torus: quad2.SetValue(myHS2->Surface().Torus()); break;
7fd59977 161 default: Standard_ConstructionError::Raise("GeomInt_LineConstructor::Parameters");
162 }
163 quad1.Parameters(Ptref,U1,V1);
164 quad2.Parameters(Ptref,U2,V2);
165}
166
167
168//=======================================================================
169//function : Perform
170//purpose :
171//=======================================================================
172void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
173{
174 Standard_Integer i,nbvtx;
175 Standard_Real firstp,lastp;
176 const Standard_Real Tol = Precision::PConfusion() * 35.0;
177
178 const IntPatch_IType typl = L->ArcType();
179 if(typl == IntPatch_Analytic)
180 {
181 Standard_Real u1,v1,u2,v2;
182 Handle(IntPatch_ALine)& ALine = *((Handle(IntPatch_ALine) *)&L);
183 seqp.Clear();
184 nbvtx = GeomInt_LineTool::NbVertex(L);
185 for(i=1;i<nbvtx;i++)
186 {
187 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
188 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
00302ba4 189 const Standard_Real pmid = (firstp+lastp)*0.5;
190 const gp_Pnt Pmid = ALine->Value(pmid);
191
192 //Checking, if it is an "micro-curve" (can it be collapsed in one point?).
193 //If "yes" then first-, last- and midpoints are same point.
194 gp_Pnt aP1 = ALine->Value(RealToInt(firstp)),
195 aP2 = ALine->Value(RealToInt(lastp));
196
197 Standard_Real aSQDist = aP1.SquareDistance(aP2);
198 aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid));
199 aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid));
b92f3572 200
00302ba4 201 Standard_Boolean isMicro = aSQDist*100.0 < Tol;
202
203 if((Abs(firstp-lastp)>Precision::PConfusion()) && !isMicro)
204 {
7fd59977 205 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
206 Recadre(myHS1,myHS2,u1,v1,u2,v2);
207 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
208 if(in1 != TopAbs_OUT) {
209 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
210 if(in2 != TopAbs_OUT) {
211 seqp.Append(firstp);
212 seqp.Append(lastp);
213 }
214 }
215 }
216 }
217 done = Standard_True;
218 return;
219 }
220 else if(typl == IntPatch_Walking)
00302ba4 221 {
7fd59977 222 Standard_Real u1,v1,u2,v2;
223 Handle(IntPatch_WLine)& WLine = *((Handle(IntPatch_WLine) *)&L);
224 seqp.Clear();
00302ba4 225
226 i = 1;
227
228 {
229 firstp = GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
230 const IntSurf_PntOn2S& Pf = WLine->Point(RealToInt(firstp));
231
232 Pf.Parameters(u1,v1,u2,v2);
233
234//Inscribe parameters into main period for periodic surfaces
235 Recadre(myHS1,myHS2,u1,v1,u2,v2);
236
237 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
238 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
239 if((in1 == TopAbs_OUT) || (in2 == TopAbs_OUT))
240 {
241 i = 2;
242 }
243 }
244
7fd59977 245 nbvtx = GeomInt_LineTool::NbVertex(L);
00302ba4 246 for(;i<nbvtx;i++)
247 {
7fd59977 248 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
249 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
00302ba4 250 const Standard_Integer pmid = RealToInt((firstp+lastp)*0.5);
251 const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
252
253 //Checking, if it is an "micro-curve" (can it be collapsed in one point?).
254 //If "yes" then first-, last- and midpoints are same point.
255 gp_Pnt aP1 = WLine->Point(RealToInt(firstp)).Value(),
256 aP2 = WLine->Point(RealToInt(lastp)).Value();
257
258 Standard_Real aSQDist = aP1.SquareDistance(aP2);
259 aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid.Value()));
260 aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid.Value()));
261
262 Standard_Boolean isMicro = aSQDist*100.0 < Tol;
263
b92f3572 264 if(isMicro)
265 {//3D-dimension is small. Checking 2D-dimension
266 aSQDist = 0.0;
267 Standard_Real u1f, v1f, u2f, v2f;
268 Standard_Real u1l, v1l, u2l, v2l;
269 Standard_Real u1m, v1m, u2m, v2m;
270
271 WLine->Point(RealToInt(firstp)).Parameters(u1f, v1f, u2f, v2f);
272 WLine->Point(RealToInt(lastp)).Parameters(u1l, v1l, u2l, v2l);
273 WLine->Point(pmid).Parameters(u1m, v1m, u2m, v2m);
274
275 Standard_Real aDelta = u1m - u1f;
276 aSQDist += aDelta*aDelta;
277 aDelta = v1m - v1f;
278 aSQDist += aDelta*aDelta;
279 aDelta = u2m - u2f;
280 aSQDist += aDelta*aDelta;
281 aDelta = v2m - v2f;
282 aSQDist += aDelta*aDelta;
283
284 aDelta = u1m - u1l;
285 aSQDist += aDelta*aDelta;
286 aDelta = v1m - v1l;
287 aSQDist += aDelta*aDelta;
288 aDelta = u2m - u2l;
289 aSQDist += aDelta*aDelta;
290 aDelta = v2m - v2l;
291 aSQDist += aDelta*aDelta;
292
293 isMicro = aSQDist*100.0 < Tol;
294 }
295
00302ba4 296 if((Abs(firstp-lastp)>Precision::PConfusion()) && !isMicro)
297 {
7fd59977 298 Pmid.Parameters(u1,v1,u2,v2);
00302ba4 299//Inscribe parameters into main period for periodic surfaces
7fd59977 300 Recadre(myHS1,myHS2,u1,v1,u2,v2);
00302ba4 301
302 const TopAbs_State in1m = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
303 if(in1m == TopAbs_OUT)
304 {
305 continue;
306 }
307
308 const TopAbs_State in2m = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
309 if(in2m == TopAbs_OUT)
310 {
311 continue;
7fd59977 312 }
00302ba4 313
314 const IntSurf_PntOn2S& Plast = WLine->Point(RealToInt(lastp));
315 Plast.Parameters(u1,v1,u2,v2);
316//Inscribe parameters into main period for periodic surfaces
317 Recadre(myHS1,myHS2,u1,v1,u2,v2);
318
319 const TopAbs_State in1l = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
320 if(in1l == TopAbs_OUT)
321 {
322 continue;
323 }
324
325 const TopAbs_State in2l = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
326 if(in2l == TopAbs_OUT)
327 {
328 continue;
329 }
330
331 seqp.Append(firstp);
332 seqp.Append(lastp);
7fd59977 333 }
334 }
335 done = Standard_True;
336 return;
337 }
338 else if (typl != IntPatch_Restriction)
339 {
340 Standard_Real u1,v1,u2,v2;
341 Handle(IntPatch_GLine)& GLine = *((Handle(IntPatch_GLine) *)&L);
342 seqp.Clear();
343 nbvtx = GeomInt_LineTool::NbVertex(L);
344 Standard_Boolean intrvtested = Standard_False;
345 for(i=1;i<nbvtx;i++)
346 {
347 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
348 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
00302ba4 349
350 if((Abs(firstp-lastp)>Precision::PConfusion()))
7fd59977 351 {
352 intrvtested = Standard_True;
353 const Standard_Real pmid = (firstp+lastp)*0.5;
00302ba4 354 gp_Pnt Pmid, aP1, aP2;
7fd59977 355 switch (typl)
356 {
00302ba4 357 case IntPatch_Lin:
358 Pmid = ElCLib::Value(pmid,GLine->Line());
359 aP1 = ElCLib::Value(firstp,GLine->Line());
360 aP2 = ElCLib::Value(lastp,GLine->Line());
361 break;
362 case IntPatch_Circle:
363 Pmid = ElCLib::Value(pmid,GLine->Circle());
364 aP1 = ElCLib::Value(firstp,GLine->Circle());
365 aP2 = ElCLib::Value(lastp,GLine->Circle());
366 break;
367 case IntPatch_Ellipse:
368 Pmid = ElCLib::Value(pmid,GLine->Ellipse());
369 aP1 = ElCLib::Value(firstp,GLine->Ellipse());
370 aP2 = ElCLib::Value(lastp,GLine->Ellipse());
371 break;
372 case IntPatch_Hyperbola:
373 Pmid = ElCLib::Value(pmid,GLine->Hyperbola());
374 aP1 = ElCLib::Value(firstp,GLine->Hyperbola());
375 aP2 = ElCLib::Value(lastp,GLine->Hyperbola());
376 break;
377 case IntPatch_Parabola:
378 Pmid = ElCLib::Value(pmid,GLine->Parabola());
379 aP1 = ElCLib::Value(firstp,GLine->Parabola());
380 aP2 = ElCLib::Value(lastp,GLine->Parabola());
381 break;
566f8441 382 case IntPatch_Analytic:
383 case IntPatch_Walking:
384 case IntPatch_Restriction: break; // cases Analytic, Walking and Restriction are handled above
7fd59977 385 }
00302ba4 386
387 Standard_Real aSQDist = aP1.SquareDistance(aP2);
388 aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid));
389 aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid));
390
391 if(aSQDist*100.0 > Tol)
392 { //if it is not an "micro-curve" (can it be collapsed in one point?).
393 //If "yes" then first-, last- and midpoints are same point.
394 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
395 Recadre(myHS1,myHS2,u1,v1,u2,v2);
396 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
397 if(in1 != TopAbs_OUT) {
398 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
399 if(in2 != TopAbs_OUT) {
400 seqp.Append(firstp);
401 seqp.Append(lastp);
402 }
7fd59977 403 }
404 }
405 }
406 }
407 if(typl == IntPatch_Circle || typl == IntPatch_Ellipse)
00302ba4 408 {
409 const Standard_Real aT = M_PI + M_PI;
7fd59977 410 firstp = GeomInt_LineTool::Vertex(L,nbvtx).ParameterOnLine();
00302ba4 411 lastp = aT + GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
7fd59977 412 const Standard_Real cadrinf = GeomInt_LineTool::FirstParameter(L);
413 const Standard_Real cadrsup = GeomInt_LineTool::LastParameter(L);
414 Standard_Real acadr = (firstp+lastp)*0.5;
00302ba4 415 while(acadr < cadrinf)
416 {
417 acadr+=aT;
418 }
419
420 while(acadr > cadrsup)
421 {
422 acadr-=aT;
423 }
424
7fd59977 425 if(acadr>=cadrinf && acadr<=cadrsup)
426 {
00302ba4 427 if(Abs(firstp-lastp) > Precision::PConfusion())
7fd59977 428 {
429 intrvtested = Standard_True;
430 const Standard_Real pmid = (firstp+lastp)*0.5;
431 gp_Pnt Pmid;
432 if (typl == IntPatch_Circle)
433 Pmid = ElCLib::Value(pmid,GLine->Circle());
434 else
435 Pmid = ElCLib::Value(pmid,GLine->Ellipse());
436 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
437 Recadre(myHS1,myHS2,u1,v1,u2,v2);
438 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
00302ba4 439 if(in1 != TopAbs_OUT)
440 {
7fd59977 441 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
00302ba4 442 if(in2 != TopAbs_OUT)
443 {
7fd59977 444 seqp.Append(firstp);
445 seqp.Append(lastp);
446 }
447 }
448 }
449 }
00302ba4 450 }
451
7fd59977 452 if (!intrvtested) {
453 // on garde a priori. Il faudrait un point 2d sur chaque
454 // surface pour prendre la decision. Sera fait dans
455 // l`appelant
456 seqp.Append(GeomInt_LineTool::FirstParameter(L));
457 seqp.Append(GeomInt_LineTool::LastParameter(L));
458 }
459 done = Standard_True;
460 return;
461 }
462
463 done = Standard_False;
464 seqp.Clear();
465 nbvtx = GeomInt_LineTool::NbVertex(L);
466 if (nbvtx == 0) { // on garde a priori. Il faudrait un point 2d sur chaque
467 // surface pour prendre la decision. Sera fait dans
468 // l`appelant
469 seqp.Append(GeomInt_LineTool::FirstParameter(L));
470 seqp.Append(GeomInt_LineTool::LastParameter(L));
471 done = Standard_True;
472 return;
473 }
474
475 GeomInt_SequenceOfParameterAndOrientation seqpss;
476 TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD;
477
478 for (i=1; i<=nbvtx; i++)
479 {
480 const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i);
481 const Standard_Real prm = thevtx.ParameterOnLine();
482 if (thevtx.IsOnDomS1())
483 {
484 switch (thevtx.TransitionLineArc1().TransitionType())
485 {
486 case IntSurf_In: or1 = TopAbs_FORWARD; break;
487 case IntSurf_Out: or1 = TopAbs_REVERSED; break;
488 case IntSurf_Touch: or1 = TopAbs_INTERNAL; break;
489 case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break;
490 }
491 }
492 else
493 or1 = TopAbs_INTERNAL;
494
495 if (thevtx.IsOnDomS2())
496 {
497 switch (thevtx.TransitionLineArc2().TransitionType())
498 {
499 case IntSurf_In: or2 = TopAbs_FORWARD; break;
500 case IntSurf_Out: or2 = TopAbs_REVERSED; break;
501 case IntSurf_Touch: or2 = TopAbs_INTERNAL; break;
502 case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break;
503 }
504 }
505 else
506 or2 = TopAbs_INTERNAL;
507
508 const Standard_Integer nbinserted = seqpss.Length();
509 Standard_Boolean inserted = Standard_False;
510 for (Standard_Integer j=1; j<=nbinserted;j++)
511 {
512 if (Abs(prm-seqpss(j).Parameter()) <= Tol)
513 {
514 // on cumule
515 GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
00302ba4 516 if (or1 != TopAbs_INTERNAL)
517 {
518 if (valj.Orientation1() != TopAbs_INTERNAL)
519 {
520 if (or1 != valj.Orientation1())
521 {
7fd59977 522 valj.SetOrientation1(TopAbs_INTERNAL);
523 }
524 }
00302ba4 525 else
526 {
7fd59977 527 valj.SetOrientation1(or1);
528 }
529 }
530
00302ba4 531 if (or2 != TopAbs_INTERNAL)
532 {
533 if (valj.Orientation2() != TopAbs_INTERNAL)
534 {
535 if (or2 != valj.Orientation2())
536 {
7fd59977 537 valj.SetOrientation2(TopAbs_INTERNAL);
538 }
539 }
00302ba4 540 else
541 {
7fd59977 542 valj.SetOrientation2(or2);
543 }
00302ba4 544 }
545
7fd59977 546 inserted = Standard_True;
547 break;
548 }
549
550 if (prm < seqpss(j).Parameter()-Tol ) {
551 // on insere avant la position j
552 seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
553 inserted = Standard_True;
554 break;
555 }
556 }
00302ba4 557
558 if (!inserted)
559 {
7fd59977 560 seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
561 }
562 }
563
564 // on determine l`etat en debut de ligne
565 Standard_Boolean trim = Standard_False;
566 Standard_Boolean dansS1 = Standard_False;
567 Standard_Boolean dansS2 = Standard_False;
568
569 nbvtx = seqpss.Length();
570 for (i=1; i<= nbvtx; i++)
571 {
572 or1 = seqpss(i).Orientation1();
573 if (or1 != TopAbs_INTERNAL)
574 {
575 trim = Standard_True;
576 dansS1 = (or1 != TopAbs_FORWARD);
577 break;
578 }
579 }
580
581 if (i > nbvtx)
582 {
583 Standard_Real U,V;
584 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )
585 {
586 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() )
587 {
588 GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
589 gp_Pnt2d PPCC(U,V);
590 if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
591 done = Standard_True;
592 return;
593 }
594 break;
595 }
596 }
597 dansS1 = Standard_True; // on garde dans le doute
598 }
599
600 for (i=1; i<= nbvtx; i++)
601 {
602 or2 = seqpss(i).Orientation2();
603 if (or2 != TopAbs_INTERNAL)
604 {
605 trim = Standard_True;
606 dansS2 = (or2 != TopAbs_FORWARD);
607 break;
608 }
609 }
610
611 if (i > nbvtx)
612 {
613 Standard_Real U,V;
614 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )
615 {
616 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() )
617 {
618 GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
619 if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
620 done = Standard_True;
621 return;
622 }
623 break;
624 }
625 }
626 dansS2 = Standard_True; // on garde dans le doute
627 }
628
629 if (!trim) { // on a necessairement dansS1 == dansS2 == Standard_True
630 seqp.Append(GeomInt_LineTool::FirstParameter(L));
631 seqp.Append(GeomInt_LineTool::LastParameter(L));
632 done = Standard_True;
633 return;
634 }
635
636 // On epluche la sequence seqpss pour constituer les bouts valides
637 // et les stocker dans seqp(2*i+1) et seqp(2*i+2)
638 Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L);
639 Standard_Real thelast = GeomInt_LineTool::LastParameter(L);
640 firstp = thefirst;
641
642 for (i=1; i<=nbvtx; i++)
643 {
644 or1 = seqpss(i).Orientation1();
645 or2 = seqpss(i).Orientation2();
646 if (dansS1 && dansS2)
647 {
648 if (or1 == TopAbs_REVERSED)
649 dansS1 = Standard_False;
650 /*else if (or1 == TopAbs_FORWARD) {
651 }*/
652 if (or2 == TopAbs_REVERSED)
653 dansS2 = Standard_False;
654 /*else if (or2 == TopAbs_FORWARD) {
655 }*/
656 if (!dansS1 || !dansS2)
657 {
658 lastp = seqpss(i).Parameter();
659 Standard_Real stofirst = Max(firstp, thefirst);
660 Standard_Real stolast = Min(lastp, thelast) ;
00302ba4 661 if (stolast > stofirst)
662 {
7fd59977 663 seqp.Append(stofirst);
664 seqp.Append(stolast);
665 }
00302ba4 666
7fd59977 667 if (lastp > thelast)
668 break;
669 }
670 }
671 else
672 {
673 if (dansS1)
674 {
675 if (or1 == TopAbs_REVERSED)
676 dansS1 = Standard_False;
677 /*else if (or1 == TopAbs_FORWARD) {
678 }*/
679 }
680 else
681 {
682 if (or1 == TopAbs_FORWARD)
683 dansS1 = Standard_True;
684 /*else if (or1 == TopAbs_REVERSED) {
685 }*/
686 }
687 if (dansS2)
688 {
689 if (or2 == TopAbs_REVERSED)
690 dansS2 = Standard_False;
691 /*else if (or2 == TopAbs_FORWARD) {
692 }*/
693 }
694 else
695 {
696 if (or2 == TopAbs_FORWARD)
697 dansS2 = Standard_True;
698 /*else if (or2 == TopAbs_REVERSED) {
699 }*/
700 }
701 if (dansS1 && dansS2)
702 firstp = seqpss(i).Parameter();
703 }
704 }
705
706 // le petit dernier a rajouter
707 if (dansS1 && dansS2)
708 {
709 lastp = thelast;
710 firstp = Max(firstp,thefirst);
711 if (lastp > firstp) {
712 seqp.Append(firstp);
713 seqp.Append(lastp);
714 }
715 }
716 done = Standard_True;
717}
718
719
720//=======================================================================
721//function : PeriodicLine
722//purpose :
723//=======================================================================
724void GeomInt_LineConstructor::PeriodicLine (const Handle(IntPatch_Line)& L) const
725{
726 const IntPatch_IType typl = L->ArcType();
727 if (typl != IntPatch_Circle && typl != IntPatch_Ellipse)
728 return;
729
730 const Standard_Real Tol = Precision::PConfusion();
731 Handle(IntPatch_GLine) glin = Handle(IntPatch_GLine)::DownCast(L);
732 Standard_Integer i,j,nbvtx = glin->NbVertex();
733 for (i=1; i<=nbvtx; i++)
734 {
735 IntPatch_Point thevtx = glin->Vertex(i);
736 const Standard_Real prm = thevtx.ParameterOnLine();
737 Standard_Boolean changevtx = Standard_False;
738 if (thevtx.IsOnDomS1() || thevtx.IsOnDomS2())
739 {
740 for (j=1; j<=nbvtx; j++)
741 {
742 if (j!=i)
743 {
744 const IntPatch_Point& thevtxbis = glin->Vertex(j);
745 const Standard_Real prmbis = thevtxbis.ParameterOnLine();
746 if (Abs(prm-prmbis) <= Tol)
747 {
748 Standard_Real u,v;
749 gp_Pnt2d p2d;
750 if (thevtx.IsOnDomS1() && thevtxbis.IsOnDomS1() &&
751 thevtxbis.TransitionLineArc1().TransitionType()==IntSurf_In)
752 {
753 p2d = thevtx.ArcOnS1()->Value(thevtx.ParameterOnArc1());
754 u = p2d.X(); v = p2d.Y();
755 p2d = thevtxbis.ArcOnS1()->Value(thevtxbis.ParameterOnArc1());
756 if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol)
757 {
758 changevtx = Standard_True;
759 break;
760 }
761 }
762 if (thevtx.IsOnDomS2() && thevtxbis.IsOnDomS2() &&
763 thevtxbis.TransitionLineArc2().TransitionType()==IntSurf_In)
764 {
765 p2d = thevtx.ArcOnS2()->Value(thevtx.ParameterOnArc2());
766 u = p2d.X(); v = p2d.Y();
767 p2d = thevtxbis.ArcOnS2()->Value(thevtxbis.ParameterOnArc2());
768 if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol)
769 {
770 changevtx = Standard_True;
771 break;
772 }
773 }
774 }
775 }
776 }
777 }
778 if (changevtx) {
c6541a0c 779 thevtx.SetParameter(prm + 2.*M_PI);
7fd59977 780 glin->Replace(i,thevtx);
781 }
782 }
783}