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