0022771: An extra vertex produced in result of Boolean section for the cases of close...
[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
3928aec6
P
35static
36 void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
37 const gp_Pnt& Ptref,
38 Standard_Real& U1,
39 Standard_Real& V1);
40static
41 void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
42 const Handle(GeomAdaptor_HSurface)& myHS2,
43 const gp_Pnt& Ptref,
44 Standard_Real& U1,
45 Standard_Real& V1,
46 Standard_Real& U2,
47 Standard_Real& V2);
48
49static
50 void GLinePoint(const IntPatch_IType typl,
51 const Handle(IntPatch_GLine)& GLine,
52 const Standard_Real aT,
53 gp_Pnt& aP);
54static
55 void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
56 const Handle(GeomAdaptor_HSurface)& myHS2,
57 Standard_Real& u1,
58 Standard_Real& v1,
59 Standard_Real& u2,
60 Standard_Real& v2);
7fd59977 61
62//=======================================================================
63//function : Perform
64//purpose :
65//=======================================================================
66void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
67{
68 Standard_Integer i,nbvtx;
69 Standard_Real firstp,lastp;
70 const Standard_Real Tol = Precision::PConfusion() * 35.0;
71
72 const IntPatch_IType typl = L->ArcType();
3928aec6 73 if(typl == IntPatch_Analytic) {
7fd59977 74 Standard_Real u1,v1,u2,v2;
75 Handle(IntPatch_ALine)& ALine = *((Handle(IntPatch_ALine) *)&L);
76 seqp.Clear();
77 nbvtx = GeomInt_LineTool::NbVertex(L);
3928aec6 78 for(i=1;i<nbvtx;i++) {
7fd59977 79 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
80 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
3928aec6 81 if(firstp!=lastp) {
7fd59977 82 const Standard_Real pmid = (firstp+lastp)*0.5;
83 const gp_Pnt Pmid = ALine->Value(pmid);
84 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
85 Recadre(myHS1,myHS2,u1,v1,u2,v2);
86 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
87 if(in1 != TopAbs_OUT) {
88 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
89 if(in2 != TopAbs_OUT) {
90 seqp.Append(firstp);
91 seqp.Append(lastp);
92 }
93 }
94 }
95 }
96 done = Standard_True;
97 return;
3928aec6
P
98 } // if(typl == IntPatch_Analytic) {
99 else if(typl == IntPatch_Walking) {
7fd59977 100 Standard_Real u1,v1,u2,v2;
101 Handle(IntPatch_WLine)& WLine = *((Handle(IntPatch_WLine) *)&L);
102 seqp.Clear();
103 nbvtx = GeomInt_LineTool::NbVertex(L);
3928aec6 104 for(i=1;i<nbvtx;i++) {
7fd59977 105 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
106 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
3928aec6
P
107 if(firstp!=lastp) {
108 if(lastp != firstp+1) {
7fd59977 109 const Standard_Integer pmid = (Standard_Integer )( (firstp+lastp)/2);
110 const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
111 Pmid.Parameters(u1,v1,u2,v2);
112 Recadre(myHS1,myHS2,u1,v1,u2,v2);
113 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
81bba717 114 if(in1 != TopAbs_OUT) {
7fd59977 115 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
81bba717 116 if(in2 != TopAbs_OUT) {
7fd59977 117 seqp.Append(firstp);
118 seqp.Append(lastp);
119 }
120 }
121 }
3928aec6 122 else {
7fd59977 123 const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer)(firstp));
124 Pfirst.Parameters(u1,v1,u2,v2);
125 Recadre(myHS1,myHS2,u1,v1,u2,v2);
126 TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
127 if(in1 != TopAbs_OUT) { //-- !=ON donne Pb
128 TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
129 if(in2 != TopAbs_OUT) { //-- !=ON
130 const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer)(lastp));
131 Plast.Parameters(u1,v1,u2,v2);
132 Recadre(myHS1,myHS2,u1,v1,u2,v2);
133 in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
134 if(in1 != TopAbs_OUT) { //-- !=ON donne Pb
135 in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
136 if(in2 != TopAbs_OUT) {
137 seqp.Append(firstp);
138 seqp.Append(lastp);
139 }
140 }
141 }
142 }
7fd59977 143 }
144 }
145 }
7fd59977 146 //
3928aec6 147 // The One resulting curve consists of 7 segments that are
7fd59977 148 // connected between each other.
3928aec6 149 // The aim of the block is to reject these segments and have
7fd59977 150 // one segment instead of 7.
151 // The other reason to do that is value of TolReached3D=49.
152 // Why -? It is not known yet.
153 // PKV 22.Apr.2002
154 //
3928aec6
P
155 Standard_Integer aNbParts;
156 //
157 aNbParts = seqp.Length()/2;
158 if (aNbParts > 1) {
159 Standard_Boolean bCond;
160 GeomAbs_SurfaceType aST1, aST2;
161 aST1 = myHS1->Surface().GetType();
162 aST2 = myHS2->Surface().GetType();
163 //
164 bCond=Standard_False;
165 if (aST1==GeomAbs_Plane) {
166 if (aST2==GeomAbs_SurfaceOfExtrusion ||
167 aST2==GeomAbs_SurfaceOfRevolution) {//+zft
168 bCond=!bCond;
7fd59977 169 }
3928aec6
P
170 }
171 else if (aST2==GeomAbs_Plane) {
172 if (aST1==GeomAbs_SurfaceOfExtrusion ||
173 aST1==GeomAbs_SurfaceOfRevolution) {//+zft
174 bCond=!bCond;
7fd59977 175 }
176 }
177 //
3928aec6
P
178 if (bCond) {
179 Standard_Integer aNb, anIndex, aNbTmp, jx;
180 TColStd_IndexedMapOfInteger aMap;
181 TColStd_SequenceOfReal aSeqTmp;
182 //
183 aNb=seqp.Length();
184 for(i=1; i<=aNb; ++i) {
185 lastp =seqp(i);
186 anIndex=(Standard_Integer)lastp;
187 if (!aMap.Contains(anIndex)){
188 aMap.Add(anIndex);
189 aSeqTmp.Append(lastp);
190 }
191 else {
192 aNbTmp=aSeqTmp.Length();
193 aSeqTmp.Remove(aNbTmp);
194 }
195 }
196 //
197 seqp.Clear();
198 //
199 aNb=aSeqTmp.Length()/2;
200 for(i=1; i<=aNb;++i) {
201 jx=2*i;
202 firstp=aSeqTmp(jx-1);
203 lastp =aSeqTmp(jx);
204 seqp.Append(firstp);
205 seqp.Append(lastp);
206 }
207 }//if (bCond) {
7fd59977 208 }
7fd59977 209 done = Standard_True;
210 return;
3928aec6
P
211 }// else if(typl == IntPatch_Walking) {
212 //
213 else if (typl != IntPatch_Restriction) {
214 Standard_Boolean intrvtested;
7fd59977 215 Standard_Real u1,v1,u2,v2;
3928aec6 216 //
7fd59977 217 seqp.Clear();
3928aec6
P
218 //
219 Handle(IntPatch_GLine)& GLine = *((Handle(IntPatch_GLine) *)&L);
220 // reject micro circles, ellipses
221 switch (typl) {
222 case IntPatch_Circle: {
223 Standard_Real aR;
224 gp_Circ aCirc;
225 //
226 aCirc=GLine->Circle();
227 aR=aCirc.Radius();
228 if (aR<Tol) {
229 done = Standard_True;
230 return;
231 }
232 break;
233 }
234 case IntPatch_Ellipse: {
235 Standard_Real aR;
236 gp_Elips aEllipse;
237 //
238 aEllipse=GLine->Ellipse();
239 aR=aEllipse.MajorRadius();
240 if (aR<Tol) {
241 done = Standard_True;
242 return;
243 }
244 break;
245 }
246 default:
247 break;
248 }
249 //modified by NIZNHY-PKV Wed Nov 02 11:50:23 2011t
250 //
7fd59977 251 nbvtx = GeomInt_LineTool::NbVertex(L);
3928aec6
P
252 intrvtested = Standard_False;
253 for(i=1; i<nbvtx; ++i) {
7fd59977 254 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
255 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
3928aec6 256 if(Abs(firstp-lastp)>Precision::PConfusion()) {
7fd59977 257 intrvtested = Standard_True;
258 const Standard_Real pmid = (firstp+lastp)*0.5;
259 gp_Pnt Pmid;
3928aec6
P
260 //modified by NIZNHY-PKV Fri Nov 11 10:27:01 2011f
261 GLinePoint(typl, GLine, pmid, Pmid);
262 /*
263 switch (typl) {
264 case IntPatch_Lin:
265 Pmid = ElCLib::Value(pmid,GLine->Line());
266 break;
267 case IntPatch_Circle:
268 Pmid = ElCLib::Value(pmid,GLine->Circle());
269 break;
270 case IntPatch_Ellipse:
271 Pmid = ElCLib::Value(pmid,GLine->Ellipse());
272 break;
273 case IntPatch_Hyperbola:
274 Pmid = ElCLib::Value(pmid,GLine->Hyperbola());
275 break;
276 case IntPatch_Parabola:
277 Pmid = ElCLib::Value(pmid,GLine->Parabola());
278 break;
279 default:
280 break;
7fd59977 281 }
3928aec6
P
282 */
283 //modified by NIZNHY-PKV Fri Nov 11 12:25:40 2011t
284 //
7fd59977 285 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
286 Recadre(myHS1,myHS2,u1,v1,u2,v2);
287 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
288 if(in1 != TopAbs_OUT) {
289 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
290 if(in2 != TopAbs_OUT) {
291 seqp.Append(firstp);
292 seqp.Append(lastp);
293 }
294 }
295 }
296 }
3928aec6
P
297 //
298 if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
7fd59977 299 firstp = GeomInt_LineTool::Vertex(L,nbvtx).ParameterOnLine();
c6541a0c 300 lastp = M_PI + M_PI + GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
7fd59977 301 const Standard_Real cadrinf = GeomInt_LineTool::FirstParameter(L);
302 const Standard_Real cadrsup = GeomInt_LineTool::LastParameter(L);
303 Standard_Real acadr = (firstp+lastp)*0.5;
3928aec6
P
304 while(acadr < cadrinf) {
305 acadr+=M_PI+M_PI;
306 }
307 while(acadr > cadrsup) {
308 acadr-=M_PI+M_PI;
309 }
310 if(acadr>=cadrinf && acadr<=cadrsup) {
311 if(Abs(firstp-lastp)>Precision::PConfusion()) {
7fd59977 312 intrvtested = Standard_True;
313 const Standard_Real pmid = (firstp+lastp)*0.5;
314 gp_Pnt Pmid;
3928aec6 315 if (typl == IntPatch_Circle) {
7fd59977 316 Pmid = ElCLib::Value(pmid,GLine->Circle());
3928aec6
P
317 }
318 else {
7fd59977 319 Pmid = ElCLib::Value(pmid,GLine->Ellipse());
3928aec6 320 }
7fd59977 321 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
322 Recadre(myHS1,myHS2,u1,v1,u2,v2);
323 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
324 if(in1 != TopAbs_OUT) {
325 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
326 if(in2 != TopAbs_OUT) {
327 seqp.Append(firstp);
328 seqp.Append(lastp);
329 }
330 }
331 }
332 }
333 }
334 if (!intrvtested) {
81bba717 335 // Keep a priori. A point 2d on each
336 // surface is required to make the decision. Will be done in the caller
7fd59977 337 seqp.Append(GeomInt_LineTool::FirstParameter(L));
338 seqp.Append(GeomInt_LineTool::LastParameter(L));
339 }
340 //
3928aec6
P
341 // Treatment Circles/Ellipses that are the results of intersection
342 // between Plane / (Cylinder, Sphere).
343 // In these cases the intersection curves can contain
344 // a lot of 'vertices' on the curve that leads to a lot of parts
345 // of the curve. Some adjacent parts can be united to the one part.
346 //
347 Standard_Integer aNbParts;
7fd59977 348 //
3928aec6
P
349 aNbParts = seqp.Length()/2;
350 if (aNbParts > 1 && (typl == IntPatch_Circle || typl == IntPatch_Ellipse)) {
351 Standard_Boolean bCond, bPCS, bPCS1, bPCS2, bCC;
352 GeomAbs_SurfaceType aST1, aST2;
353 //
354 aST1 = myHS1->Surface().GetType();
355 aST2 = myHS2->Surface().GetType();
356 //
357 bPCS1=((aST1==GeomAbs_Plane) && (aST2==GeomAbs_Cylinder || aST2==GeomAbs_Sphere));
358 bPCS2=((aST2==GeomAbs_Plane) && (aST1==GeomAbs_Cylinder || aST1==GeomAbs_Sphere));
359 bPCS=(bPCS1 || bPCS2);
360 bCC=(aST1==GeomAbs_Cylinder && aST2==GeomAbs_Cylinder);
361 //
362 // ZZ
363 //modified by NIZNHY-PKV Fri Nov 11 10:13:58 2011f
364 Standard_Integer j, i1, i2;
365 Standard_Real aT, aU, aV;
366 Handle(GeomAdaptor_HSurface) aHS;
367 //
368 bCond=Standard_False;
369 //
370 if (bCC) {
371 bCond=Standard_True;
372 }
373 else if (bPCS) {
374 if ((aST1==GeomAbs_Sphere) || (aST2==GeomAbs_Sphere)) {
375 if (aST1==GeomAbs_Sphere) {
376 aHS=myHS1;
377 }
378 else if (aST2==GeomAbs_Sphere){
379 aHS=myHS2;
380 }
381 //
382 Standard_Integer aNbP;
383 Standard_Real aHalfPI, aPPC;
384 //
385 bCond=Standard_True;
386 //
387 aNbP=seqp.Length();
388 aPPC=Precision::PConfusion();
389 aHalfPI=0.5*PI;
390 i1=0;
391 i2=0;
392 //
393 for (i=1; i<=aNbP; ++i) {
394 gp_Pnt aP;
395 //
396 aT=seqp(i);
397 GLinePoint(typl, GLine, aT, aP);
398 Parameters(aHS, aP, aU, aV);
399 if (aV<0.) {
400 if (fabs(aV+aHalfPI) < aPPC) {
401 ++i2;
402 }
7fd59977 403 }
3928aec6
P
404 else {
405 if (fabs(aV-aHalfPI) < aPPC) {
406 ++i1;
407 }
7fd59977 408 }
409 }
3928aec6
P
410 if (i1==2 || i2==2) {
411 bCond=Standard_False;
412 }
413 }
414 }// else if (bPCS1 || bPCS2) {
415 //modified by NIZNHY-PKV Fri Nov 11 10:14:00 2011t
416 //
417 if (bCond){
418 Standard_Integer i2, j2;
419 Standard_Real aFi, aLi, aFj, aLj, aF, aL;
420 TColStd_SequenceOfReal aSeq;
421 //
422 aFi=seqp(1);
423 aSeq.Append(aFi);
424 for (i=1; i<aNbParts; ++i) {
425 j=i+1;
426 i2=2*i;
427 j2=2*j;
7fd59977 428 //
3928aec6
P
429 aFi=seqp(i2-1);
430 aLi=seqp(i2);
431 //
432 aFj=seqp(j2-1);
433 aLj=seqp(j2);
434 //
435 if (fabs (aFj-aLi) < Tol) {
436 aL=aLj;
437 }
438 else {
439 aL=aLi;
440 aSeq.Append(aL);
441 aF=aFj;
442 aSeq.Append(aF);
7fd59977 443 }
444 }
3928aec6
P
445 aSeq.Append(aLj);
446 //
447 seqp.Clear();
448 aNbParts=aSeq.Length();
449 for (i=1; i<=aNbParts; ++i) {
450 aF=aSeq(i);
451 seqp.Append(aF);
452 }
7fd59977 453 }
454 }
7fd59977 455 //
456 done =Standard_True;
457 return;
3928aec6 458 }// else if (typl != IntPatch_Restriction) {
7fd59977 459
460 done = Standard_False;
461 seqp.Clear();
462 nbvtx = GeomInt_LineTool::NbVertex(L);
81bba717 463 if (nbvtx == 0) { // Keep a priori. Point 2d is required on each
464 // surface to make the decision. Will be done in the caller
7fd59977 465 seqp.Append(GeomInt_LineTool::FirstParameter(L));
466 seqp.Append(GeomInt_LineTool::LastParameter(L));
467 done = Standard_True;
468 return;
469 }
470
471 GeomInt_SequenceOfParameterAndOrientation seqpss;
472 TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD;
473
3928aec6 474 for (i=1; i<=nbvtx; i++) {
7fd59977 475 const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i);
476 const Standard_Real prm = thevtx.ParameterOnLine();
3928aec6
P
477 if (thevtx.IsOnDomS1()) {
478 switch (thevtx.TransitionLineArc1().TransitionType()) {
7fd59977 479 case IntSurf_In: or1 = TopAbs_FORWARD; break;
480 case IntSurf_Out: or1 = TopAbs_REVERSED; break;
481 case IntSurf_Touch: or1 = TopAbs_INTERNAL; break;
482 case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break;
483 }
484 }
3928aec6 485 else {
7fd59977 486 or1 = TopAbs_INTERNAL;
3928aec6 487 }
7fd59977 488
3928aec6
P
489 if (thevtx.IsOnDomS2()) {
490 switch (thevtx.TransitionLineArc2().TransitionType()) {
7fd59977 491 case IntSurf_In: or2 = TopAbs_FORWARD; break;
492 case IntSurf_Out: or2 = TopAbs_REVERSED; break;
493 case IntSurf_Touch: or2 = TopAbs_INTERNAL; break;
494 case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break;
495 }
496 }
3928aec6 497 else {
7fd59977 498 or2 = TopAbs_INTERNAL;
3928aec6
P
499 }
500 //
7fd59977 501 const Standard_Integer nbinserted = seqpss.Length();
502 Standard_Boolean inserted = Standard_False;
3928aec6
P
503 for (Standard_Integer j=1; j<=nbinserted;j++) {
504 if (Abs(prm-seqpss(j).Parameter()) <= Tol) {
81bba717 505 // accumulate
7fd59977 506 GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
507 if (or1 != TopAbs_INTERNAL) {
508 if (valj.Orientation1() != TopAbs_INTERNAL) {
509 if (or1 != valj.Orientation1()) {
510 valj.SetOrientation1(TopAbs_INTERNAL);
511 }
512 }
513 else {
514 valj.SetOrientation1(or1);
515 }
516 }
517
518 if (or2 != TopAbs_INTERNAL) {
519 if (valj.Orientation2() != TopAbs_INTERNAL) {
520 if (or2 != valj.Orientation2()) {
521 valj.SetOrientation2(TopAbs_INTERNAL);
522 }
523 }
524 else {
525 valj.SetOrientation2(or2);
526 }
527 }
528 inserted = Standard_True;
529 break;
530 }
531
532 if (prm < seqpss(j).Parameter()-Tol ) {
81bba717 533 // insert before position j
7fd59977 534 seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
535 inserted = Standard_True;
536 break;
537 }
538
539 }
540 if (!inserted) {
541 seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
542 }
543 }
544
81bba717 545 // determine the state at the beginning of line
7fd59977 546 Standard_Boolean trim = Standard_False;
547 Standard_Boolean dansS1 = Standard_False;
548 Standard_Boolean dansS2 = Standard_False;
549
550 nbvtx = seqpss.Length();
3928aec6 551 for (i=1; i<= nbvtx; i++) {
7fd59977 552 or1 = seqpss(i).Orientation1();
3928aec6 553 if (or1 != TopAbs_INTERNAL) {
7fd59977 554 trim = Standard_True;
555 dansS1 = (or1 != TopAbs_FORWARD);
556 break;
557 }
558 }
559
3928aec6 560 if (i > nbvtx) {
7fd59977 561 Standard_Real U,V;
3928aec6
P
562 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) {
563 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() ) {
7fd59977 564 GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
565 gp_Pnt2d PPCC(U,V);
566 if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
567 done = Standard_True;
568 return;
569 }
570 break;
571 }
572 }
81bba717 573 dansS1 = Standard_True; // Keep in doubt
7fd59977 574 }
3928aec6
P
575 //
576 for (i=1; i<= nbvtx; i++) {
7fd59977 577 or2 = seqpss(i).Orientation2();
3928aec6 578 if (or2 != TopAbs_INTERNAL) {
7fd59977 579 trim = Standard_True;
580 dansS2 = (or2 != TopAbs_FORWARD);
581 break;
582 }
583 }
584
3928aec6 585 if (i > nbvtx) {
7fd59977 586 Standard_Real U,V;
3928aec6
P
587 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) {
588 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() ) {
7fd59977 589 GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
590 if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
591 done = Standard_True;
592 return;
593 }
594 break;
595 }
596 }
81bba717 597 dansS2 = Standard_True; // Keep in doubt
7fd59977 598 }
599
81bba717 600 if (!trim) { // necessarily dansS1 == dansS2 == Standard_True
7fd59977 601 seqp.Append(GeomInt_LineTool::FirstParameter(L));
602 seqp.Append(GeomInt_LineTool::LastParameter(L));
603 done = Standard_True;
604 return;
605 }
606
81bba717 607 // sequence seqpss is peeled to create valid ends
608 // and store them in seqp(2*i+1) and seqp(2*i+2)
7fd59977 609 Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L);
610 Standard_Real thelast = GeomInt_LineTool::LastParameter(L);
611 firstp = thefirst;
612
3928aec6 613 for (i=1; i<=nbvtx; i++) {
7fd59977 614 or1 = seqpss(i).Orientation1();
615 or2 = seqpss(i).Orientation2();
3928aec6
P
616 if (dansS1 && dansS2) {
617 if (or1 == TopAbs_REVERSED){
7fd59977 618 dansS1 = Standard_False;
3928aec6
P
619 }
620
621 if (or2 == TopAbs_REVERSED){
7fd59977 622 dansS2 = Standard_False;
3928aec6
P
623 }
624 if (!dansS1 || !dansS2) {
7fd59977 625 lastp = seqpss(i).Parameter();
626 Standard_Real stofirst = Max(firstp, thefirst);
627 Standard_Real stolast = Min(lastp, thelast) ;
628
629 if (stolast > stofirst) {
630 seqp.Append(stofirst);
631 seqp.Append(stolast);
632 }
3928aec6 633 if (lastp > thelast) {
7fd59977 634 break;
3928aec6 635 }
7fd59977 636 }
637 }
3928aec6
P
638 else {
639 if (dansS1) {
640 if (or1 == TopAbs_REVERSED) {
7fd59977 641 dansS1 = Standard_False;
3928aec6 642 }
7fd59977 643 }
3928aec6
P
644 else {
645 if (or1 == TopAbs_FORWARD){
7fd59977 646 dansS1 = Standard_True;
3928aec6 647 }
7fd59977 648 }
3928aec6
P
649 if (dansS2) {
650 if (or2 == TopAbs_REVERSED) {
7fd59977 651 dansS2 = Standard_False;
3928aec6 652 }
7fd59977 653 }
3928aec6
P
654 else {
655 if (or2 == TopAbs_FORWARD){
7fd59977 656 dansS2 = Standard_True;
3928aec6 657 }
7fd59977 658 }
3928aec6 659 if (dansS1 && dansS2){
7fd59977 660 firstp = seqpss(i).Parameter();
3928aec6 661 }
7fd59977 662 }
663 }
3928aec6 664 //
81bba717 665 // finally to add
3928aec6 666 if (dansS1 && dansS2) {
7fd59977 667 lastp = thelast;
668 firstp = Max(firstp,thefirst);
669 if (lastp > firstp) {
670 seqp.Append(firstp);
671 seqp.Append(lastp);
672 }
673 }
674 done = Standard_True;
675}
676
677
678//=======================================================================
679//function : PeriodicLine
680//purpose :
681//=======================================================================
682void IntTools_LineConstructor::PeriodicLine (const Handle(IntPatch_Line)& L) const
683{
684 const IntPatch_IType typl = L->ArcType();
685 if (typl != IntPatch_Circle && typl != IntPatch_Ellipse)
686 return;
687
688 const Standard_Real Tol = Precision::PConfusion();
689 Handle(IntPatch_GLine) glin = Handle(IntPatch_GLine)::DownCast(L);
690 Standard_Integer i,j,nbvtx = glin->NbVertex();
691 for (i=1; i<=nbvtx; i++)
692 {
693 IntPatch_Point thevtx = glin->Vertex(i);
694 const Standard_Real prm = thevtx.ParameterOnLine();
695 Standard_Boolean changevtx = Standard_False;
696 if (thevtx.IsOnDomS1() || thevtx.IsOnDomS2())
697 {
698 for (j=1; j<=nbvtx; j++)
699 {
700 if (j!=i)
701 {
702 const IntPatch_Point& thevtxbis = glin->Vertex(j);
703 const Standard_Real prmbis = thevtxbis.ParameterOnLine();
704 if (Abs(prm-prmbis) <= Tol)
705 {
706 Standard_Real u,v;
707 gp_Pnt2d p2d;
708 if (thevtx.IsOnDomS1() && thevtxbis.IsOnDomS1() &&
709 thevtxbis.TransitionLineArc1().TransitionType()==IntSurf_In)
710 {
711 p2d = thevtx.ArcOnS1()->Value(thevtx.ParameterOnArc1());
712 u = p2d.X(); v = p2d.Y();
713 p2d = thevtxbis.ArcOnS1()->Value(thevtxbis.ParameterOnArc1());
714 if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol)
715 {
716 changevtx = Standard_True;
717 break;
718 }
719 }
720 if (thevtx.IsOnDomS2() && thevtxbis.IsOnDomS2() &&
721 thevtxbis.TransitionLineArc2().TransitionType()==IntSurf_In)
722 {
723 p2d = thevtx.ArcOnS2()->Value(thevtx.ParameterOnArc2());
724 u = p2d.X(); v = p2d.Y();
725 p2d = thevtxbis.ArcOnS2()->Value(thevtxbis.ParameterOnArc2());
726 if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol)
727 {
728 changevtx = Standard_True;
729 break;
730 }
731 }
732 }
733 }
734 }
735 }
736 if (changevtx) {
c6541a0c 737 thevtx.SetParameter(prm + 2.*M_PI);
7fd59977 738 glin->Replace(i,thevtx);
739 }
740 }
741}
3928aec6
P
742//modified by NIZNHY-PKV Fri Nov 11 10:30:34 2011f
743//=======================================================================
744//function : Recadre
745//purpose :
746//=======================================================================
747void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
748 const Handle(GeomAdaptor_HSurface)& myHS2,
749 Standard_Real& u1,
750 Standard_Real& v1,
751 Standard_Real& u2,
752 Standard_Real& v2)
753{
754 Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
755 const GeomAbs_SurfaceType typs1 = myHS1->GetType();
756 switch (typs1)
757 {
758 case GeomAbs_Cylinder:
759 case GeomAbs_Cone:
760 case GeomAbs_Sphere:
761 {
762 myHS1IsUPeriodic = Standard_True;
763 myHS1IsVPeriodic = Standard_False;
764 break;
765 }
766 case GeomAbs_Torus:
767 {
768 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
769 break;
770 }
771 default:
772 {
773 //-- Case of periodic biparameters is processed upstream
774 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
775 break;
776 }
777 }
778 Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
779 const GeomAbs_SurfaceType typs2 = myHS2->GetType();
780 switch (typs2)
781 {
782 case GeomAbs_Cylinder:
783 case GeomAbs_Cone:
784 case GeomAbs_Sphere:
785 {
786 myHS2IsUPeriodic = Standard_True;
787 myHS2IsVPeriodic = Standard_False;
788 break;
789 }
790 case GeomAbs_Torus:
791 {
792 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
793 break;
794 }
795 default:
796 {
797 //-- Case of periodic biparameters is processed upstream
798 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
799 break;
800 }
801 }
802 if(myHS1IsUPeriodic) {
803 const Standard_Real lmf = PI+PI; //-- myHS1->UPeriod();
804 const Standard_Real f = myHS1->FirstUParameter();
805 const Standard_Real l = myHS1->LastUParameter();
806 while(u1 < f) { u1+=lmf; }
807 while(u1 > l) { u1-=lmf; }
808 }
809 if(myHS1IsVPeriodic) {
810 const Standard_Real lmf = PI+PI; //-- myHS1->VPeriod();
811 const Standard_Real f = myHS1->FirstVParameter();
812 const Standard_Real l = myHS1->LastVParameter();
813 while(v1 < f) { v1+=lmf; }
814 while(v1 > l) { v1-=lmf; }
815 }
816 if(myHS2IsUPeriodic) {
817 const Standard_Real lmf = PI+PI; //-- myHS2->UPeriod();
818 const Standard_Real f = myHS2->FirstUParameter();
819 const Standard_Real l = myHS2->LastUParameter();
820 while(u2 < f) { u2+=lmf; }
821 while(u2 > l) { u2-=lmf; }
822 }
823 if(myHS2IsVPeriodic) {
824 const Standard_Real lmf = PI+PI; //-- myHS2->VPeriod();
825 const Standard_Real f = myHS2->FirstVParameter();
826 const Standard_Real l = myHS2->LastVParameter();
827 while(v2 < f) { v2+=lmf; }
828 while(v2 > l) { v2-=lmf; }
829 }
830}
831//=======================================================================
832//function : Parameters
833//purpose :
834//=======================================================================
835void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
836 const Handle(GeomAdaptor_HSurface)& myHS2,
837 const gp_Pnt& Ptref,
838 Standard_Real& U1,
839 Standard_Real& V1,
840 Standard_Real& U2,
841 Standard_Real& V2)
842{
843 //modified by NIZNHY-PKV Fri Nov 11 10:07:55 2011f
844 Parameters(myHS1, Ptref, U1, V1);
845 Parameters(myHS2, Ptref, U2, V2);
846 /*
847 IntSurf_Quadric quad1,quad2;
848 switch (myHS1->Surface().GetType())
849 {
850 case GeomAbs_Plane: quad1.SetValue(myHS1->Surface().Plane()); break;
851 case GeomAbs_Cylinder: quad1.SetValue(myHS1->Surface().Cylinder()); break;
852 case GeomAbs_Cone: quad1.SetValue(myHS1->Surface().Cone()); break;
853 case GeomAbs_Sphere: quad1.SetValue(myHS1->Surface().Sphere()); break;
854 default: Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
855 }
856 switch (myHS2->Surface().GetType())
857 {
858 case GeomAbs_Plane: quad2.SetValue(myHS2->Surface().Plane()); break;
859 case GeomAbs_Cylinder: quad2.SetValue(myHS2->Surface().Cylinder()); break;
860 case GeomAbs_Cone: quad2.SetValue(myHS2->Surface().Cone()); break;
861 case GeomAbs_Sphere: quad2.SetValue(myHS2->Surface().Sphere()); break;
862 default: Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
863 }
864 quad1.Parameters(Ptref,U1,V1);
865 quad2.Parameters(Ptref,U2,V2);
866 */
867 //modified by NIZNHY-PKV Fri Nov 11 10:08:38 2011t
868}
869//modified by NIZNHY-PKV Fri Nov 11 10:06:02 2011f
870//=======================================================================
871//function : Parameter
872//purpose :
873//=======================================================================
874void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
875 const gp_Pnt& Ptref,
876 Standard_Real& U1,
877 Standard_Real& V1)
878{
879 IntSurf_Quadric quad1;
880 //
881 switch (myHS1->Surface().GetType()) {
882 case GeomAbs_Plane:
883 quad1.SetValue(myHS1->Surface().Plane());
884 break;
885 case GeomAbs_Cylinder:
886 quad1.SetValue(myHS1->Surface().Cylinder());
887 break;
888 case GeomAbs_Cone:
889 quad1.SetValue(myHS1->Surface().Cone());
890 break;
891 case GeomAbs_Sphere:
892 quad1.SetValue(myHS1->Surface().Sphere());
893 break;
894 default:
895 Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
896 }
897 quad1.Parameters(Ptref,U1,V1);
898}
899
900//=======================================================================
901//function : GLinePoint
902//purpose :
903//=======================================================================
904void GLinePoint(const IntPatch_IType typl,
905 const Handle(IntPatch_GLine)& GLine,
906 const Standard_Real aT,
907 gp_Pnt& aP)
908{
909 switch (typl) {
910 case IntPatch_Lin:
911 aP = ElCLib::Value(aT, GLine->Line());
912 break;
913 case IntPatch_Circle:
914 aP = ElCLib::Value(aT, GLine->Circle());
915 break;
916 case IntPatch_Ellipse:
917 aP = ElCLib::Value(aT, GLine->Ellipse());
918 break;
919 case IntPatch_Hyperbola:
920 aP = ElCLib::Value(aT, GLine->Hyperbola());
921 break;
922 case IntPatch_Parabola:
923 aP = ElCLib::Value(aT, GLine->Parabola());
924 break;
925 default:
926 Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
927 }
928}
929//modified by NIZNHY-PKV Fri Nov 11 10:06:04 2011t