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