0024023: Revamp the OCCT Handle -- downcast (automatic)
[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
2a78ec6a 41#include <TColStd_IndexedMapOfInteger.hxx>
42#include <GeomInt.hxx>
43
44
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);
71
72//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
73//
7fd59977 74//=======================================================================
2a78ec6a 75//class : GeomInt_RealWithFlag
7fd59977 76//purpose :
77//=======================================================================
2a78ec6a 78class GeomInt_RealWithFlag {
79 public:
80 GeomInt_RealWithFlag() :
81 myValue(-99.), myFlag(1)
7fd59977 82 {
2a78ec6a 83 };
84 //
85 ~GeomInt_RealWithFlag() {
86 };
87 //
88 void SetValue(const Standard_Real aT) {
89 myValue=aT;
90 };
91 //
92 Standard_Real Value() const {
93 return myValue;
7fd59977 94 }
2a78ec6a 95 //
96 void SetFlag(const Standard_Integer aFlag) {
97 myFlag=aFlag;
98 };
99 //
100 Standard_Integer Flag() const {
101 return myFlag;
7fd59977 102 }
2a78ec6a 103 //
104 Standard_Boolean operator < (const GeomInt_RealWithFlag& aOther) {
105 return myValue<aOther.myValue;
7fd59977 106 }
2a78ec6a 107 //
108 protected:
109 Standard_Real myValue;
110 Standard_Integer myFlag;
111};
112//------------
113static
114 void SortShell(const Standard_Integer,
115 GeomInt_RealWithFlag *);
116static
117 void RejectDuplicates(Standard_Integer& aNbVtx,
118 GeomInt_RealWithFlag *pVtx,
119 Standard_Real aTolPrm);
120static
121 void RejectNearBeacons(Standard_Integer& aNbVtx,
122 GeomInt_RealWithFlag *pVtx,
123 Standard_Real aTolPC1,
124 const GeomAbs_SurfaceType aTS1,
125 const GeomAbs_SurfaceType aTS2);
126static
127 Standard_Real AdjustOnPeriod(const Standard_Real aTr,
128 const Standard_Real aPeriod);
129
130static
131 Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
132 const IntPatch_IType aType,
133 const Standard_Real aTol3D);
7fd59977 134
135//=======================================================================
136//function : Perform
137//purpose :
138//=======================================================================
139void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
140{
141 Standard_Integer i,nbvtx;
142 Standard_Real firstp,lastp;
143 const Standard_Real Tol = Precision::PConfusion() * 35.0;
144
145 const IntPatch_IType typl = L->ArcType();
2a78ec6a 146 if(typl == IntPatch_Analytic) {
7fd59977 147 Standard_Real u1,v1,u2,v2;
c5f3a425 148 Handle(IntPatch_ALine)& ALine = Handle(IntPatch_ALine)::DownCast (L);
7fd59977 149 seqp.Clear();
150 nbvtx = GeomInt_LineTool::NbVertex(L);
2a78ec6a 151 for(i=1;i<nbvtx;i++) {
7fd59977 152 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
153 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
2a78ec6a 154 if(firstp!=lastp) {
155 const Standard_Real pmid = (firstp+lastp)*0.5;
156 const gp_Pnt Pmid = ALine->Value(pmid);
7fd59977 157 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
158 Recadre(myHS1,myHS2,u1,v1,u2,v2);
159 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
2a78ec6a 160 if(in1 != TopAbs_OUT) {
7fd59977 161 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
162 if(in2 != TopAbs_OUT) {
163 seqp.Append(firstp);
164 seqp.Append(lastp);
165 }
166 }
167 }
168 }
169 done = Standard_True;
170 return;
2a78ec6a 171 } // if(typl == IntPatch_Analytic) {
172 else if(typl == IntPatch_Walking) {
7fd59977 173 Standard_Real u1,v1,u2,v2;
c5f3a425 174 Handle(IntPatch_WLine)& WLine = Handle(IntPatch_WLine)::DownCast (L);
7fd59977 175 seqp.Clear();
176 nbvtx = GeomInt_LineTool::NbVertex(L);
2a78ec6a 177 for(i=1;i<nbvtx;i++) {
7fd59977 178 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
179 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
2a78ec6a 180 if(firstp!=lastp) {
181 if(lastp != firstp+1) {
182 const Standard_Integer pmid = (Standard_Integer )( (firstp+lastp)/2);
183 const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
184 Pmid.Parameters(u1,v1,u2,v2);
185 Recadre(myHS1,myHS2,u1,v1,u2,v2);
186 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
187 if(in1 != TopAbs_OUT) {
188 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
189 if(in2 != TopAbs_OUT) {
190 seqp.Append(firstp);
191 seqp.Append(lastp);
192 }
193 }
00302ba4 194 }
2a78ec6a 195 else {
196 const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer)(firstp));
197 Pfirst.Parameters(u1,v1,u2,v2);
198 Recadre(myHS1,myHS2,u1,v1,u2,v2);
199 TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
200 if(in1 != TopAbs_OUT) { //-- !=ON donne Pb
201 TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
202 if(in2 != TopAbs_OUT) { //-- !=ON
203 const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer)(lastp));
204 Plast.Parameters(u1,v1,u2,v2);
205 Recadre(myHS1,myHS2,u1,v1,u2,v2);
206 in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
207 if(in1 != TopAbs_OUT) { //-- !=ON donne Pb
208 in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
209 if(in2 != TopAbs_OUT) {
210 seqp.Append(firstp);
211 seqp.Append(lastp);
212 }
213 }
214 }
215 }
7fd59977 216 }
2a78ec6a 217 }
218 }
219 //
220 // The One resulting curve consists of 7 segments that are
221 // connected between each other.
222 // The aim of the block is to reject these segments and have
223 // one segment instead of 7.
224 // The other reason to do that is value of TolReached3D=49.
225 // Why -? It is not known yet.
226 // PKV 22.Apr.2002
227 //
228 Standard_Integer aNbParts;
229 //
230 aNbParts = seqp.Length()/2;
231 if (aNbParts > 1) {
232 Standard_Boolean bCond;
233 GeomAbs_SurfaceType aST1, aST2;
234 aST1 = myHS1->Surface().GetType();
235 aST2 = myHS2->Surface().GetType();
236 //
237 bCond=Standard_False;
238 if (aST1==GeomAbs_Plane) {
239 if (aST2==GeomAbs_SurfaceOfExtrusion ||
240 aST2==GeomAbs_SurfaceOfRevolution) {//+zft
241 bCond=!bCond;
00302ba4 242 }
2a78ec6a 243 }
244 else if (aST2==GeomAbs_Plane) {
245 if (aST1==GeomAbs_SurfaceOfExtrusion ||
246 aST1==GeomAbs_SurfaceOfRevolution) {//+zft
247 bCond=!bCond;
00302ba4 248 }
7fd59977 249 }
2a78ec6a 250 //
251 if (bCond) {
252 Standard_Integer aNb, anIndex, aNbTmp, jx;
253 TColStd_IndexedMapOfInteger aMap;
254 TColStd_SequenceOfReal aSeqTmp;
255 //
256 aNb=seqp.Length();
257 for(i=1; i<=aNb; ++i) {
258 lastp =seqp(i);
259 anIndex=(Standard_Integer)lastp;
260 if (!aMap.Contains(anIndex)){
261 aMap.Add(anIndex);
262 aSeqTmp.Append(lastp);
263 }
264 else {
265 aNbTmp=aSeqTmp.Length();
266 aSeqTmp.Remove(aNbTmp);
267 }
268 }
269 //
270 seqp.Clear();
271 //
272 aNb=aSeqTmp.Length()/2;
273 for(i=1; i<=aNb;++i) {
274 jx=2*i;
275 firstp=aSeqTmp(jx-1);
276 lastp =aSeqTmp(jx);
277 seqp.Append(firstp);
278 seqp.Append(lastp);
279 }
280 }//if (bCond) {
7fd59977 281 }
282 done = Standard_True;
283 return;
2a78ec6a 284 }// else if(typl == IntPatch_Walking) {
285 //
286 //-----------------------------------------------------------
287 else if (typl != IntPatch_Restriction) {
7fd59977 288 seqp.Clear();
2a78ec6a 289 //
c5f3a425 290 Handle(IntPatch_GLine)& GLine = Handle(IntPatch_GLine)::DownCast (L);
2a78ec6a 291 //
292 if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
293 TreatCircle(L, Tol);
294 done=Standard_True;
295 return;
296 }
297 //----------------------------
298 Standard_Boolean intrvtested;
299 Standard_Real u1,v1,u2,v2;
300 //
7fd59977 301 nbvtx = GeomInt_LineTool::NbVertex(L);
2a78ec6a 302 intrvtested = Standard_False;
303 for(i=1; i<nbvtx; ++i) {
7fd59977 304 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
305 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
2a78ec6a 306 if(Abs(firstp-lastp)>Precision::PConfusion()) {
7fd59977 307 intrvtested = Standard_True;
308 const Standard_Real pmid = (firstp+lastp)*0.5;
2a78ec6a 309 gp_Pnt Pmid;
310 GLinePoint(typl, GLine, pmid, Pmid);
311 //
312 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
313 Recadre(myHS1,myHS2,u1,v1,u2,v2);
314 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
315 if(in1 != TopAbs_OUT) {
316 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
317 if(in2 != TopAbs_OUT) {
318 seqp.Append(firstp);
319 seqp.Append(lastp);
7fd59977 320 }
321 }
322 }
00302ba4 323 }
2a78ec6a 324 //
7fd59977 325 if (!intrvtested) {
2a78ec6a 326 // Keep a priori. A point 2d on each
327 // surface is required to make the decision. Will be done in the caller
7fd59977 328 seqp.Append(GeomInt_LineTool::FirstParameter(L));
329 seqp.Append(GeomInt_LineTool::LastParameter(L));
330 }
2a78ec6a 331 //
332 done =Standard_True;
7fd59977 333 return;
2a78ec6a 334 } // else if (typl != IntPatch_Restriction) {
7fd59977 335
336 done = Standard_False;
337 seqp.Clear();
338 nbvtx = GeomInt_LineTool::NbVertex(L);
2a78ec6a 339 if (nbvtx == 0) { // Keep a priori. Point 2d is required on each
340 // surface to make the decision. Will be done in the caller
7fd59977 341 seqp.Append(GeomInt_LineTool::FirstParameter(L));
342 seqp.Append(GeomInt_LineTool::LastParameter(L));
343 done = Standard_True;
344 return;
345 }
346
347 GeomInt_SequenceOfParameterAndOrientation seqpss;
348 TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD;
349
2a78ec6a 350 for (i=1; i<=nbvtx; i++) {
7fd59977 351 const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i);
352 const Standard_Real prm = thevtx.ParameterOnLine();
2a78ec6a 353 if (thevtx.IsOnDomS1()) {
354 switch (thevtx.TransitionLineArc1().TransitionType()) {
355 case IntSurf_In: or1 = TopAbs_FORWARD; break;
356 case IntSurf_Out: or1 = TopAbs_REVERSED; break;
357 case IntSurf_Touch: or1 = TopAbs_INTERNAL; break;
7fd59977 358 case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break;
359 }
360 }
2a78ec6a 361 else {
7fd59977 362 or1 = TopAbs_INTERNAL;
2a78ec6a 363 }
364
365 if (thevtx.IsOnDomS2()) {
366 switch (thevtx.TransitionLineArc2().TransitionType()) {
367 case IntSurf_In: or2 = TopAbs_FORWARD; break;
368 case IntSurf_Out: or2 = TopAbs_REVERSED; break;
369 case IntSurf_Touch: or2 = TopAbs_INTERNAL; break;
370 case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break;
7fd59977 371 }
372 }
2a78ec6a 373 else {
7fd59977 374 or2 = TopAbs_INTERNAL;
2a78ec6a 375 }
376 //
7fd59977 377 const Standard_Integer nbinserted = seqpss.Length();
378 Standard_Boolean inserted = Standard_False;
2a78ec6a 379 for (Standard_Integer j=1; j<=nbinserted;j++) {
380 if (Abs(prm-seqpss(j).Parameter()) <= Tol) {
381 // accumulate
7fd59977 382 GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
2a78ec6a 383 if (or1 != TopAbs_INTERNAL) {
384 if (valj.Orientation1() != TopAbs_INTERNAL) {
385 if (or1 != valj.Orientation1()) {
7fd59977 386 valj.SetOrientation1(TopAbs_INTERNAL);
387 }
388 }
2a78ec6a 389 else {
7fd59977 390 valj.SetOrientation1(or1);
391 }
392 }
2a78ec6a 393
394 if (or2 != TopAbs_INTERNAL) {
395 if (valj.Orientation2() != TopAbs_INTERNAL) {
396 if (or2 != valj.Orientation2()) {
7fd59977 397 valj.SetOrientation2(TopAbs_INTERNAL);
398 }
399 }
2a78ec6a 400 else {
7fd59977 401 valj.SetOrientation2(or2);
402 }
2a78ec6a 403 }
7fd59977 404 inserted = Standard_True;
405 break;
406 }
407
408 if (prm < seqpss(j).Parameter()-Tol ) {
2a78ec6a 409 // insert before position j
7fd59977 410 seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
411 inserted = Standard_True;
412 break;
413 }
2a78ec6a 414
7fd59977 415 }
2a78ec6a 416 if (!inserted) {
7fd59977 417 seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
418 }
419 }
420
2a78ec6a 421 // determine the state at the beginning of line
7fd59977 422 Standard_Boolean trim = Standard_False;
423 Standard_Boolean dansS1 = Standard_False;
424 Standard_Boolean dansS2 = Standard_False;
425
426 nbvtx = seqpss.Length();
2a78ec6a 427 for (i=1; i<= nbvtx; i++) {
7fd59977 428 or1 = seqpss(i).Orientation1();
2a78ec6a 429 if (or1 != TopAbs_INTERNAL) {
7fd59977 430 trim = Standard_True;
431 dansS1 = (or1 != TopAbs_FORWARD);
432 break;
433 }
434 }
2a78ec6a 435
436 if (i > nbvtx) {
7fd59977 437 Standard_Real U,V;
2a78ec6a 438 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) {
439 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() ) {
7fd59977 440 GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
441 gp_Pnt2d PPCC(U,V);
442 if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
443 done = Standard_True;
444 return;
445 }
446 break;
447 }
448 }
2a78ec6a 449 dansS1 = Standard_True; // Keep in doubt
7fd59977 450 }
2a78ec6a 451 //
452 for (i=1; i<= nbvtx; i++) {
7fd59977 453 or2 = seqpss(i).Orientation2();
2a78ec6a 454 if (or2 != TopAbs_INTERNAL) {
7fd59977 455 trim = Standard_True;
456 dansS2 = (or2 != TopAbs_FORWARD);
457 break;
458 }
459 }
460
2a78ec6a 461 if (i > nbvtx) {
7fd59977 462 Standard_Real U,V;
2a78ec6a 463 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) {
464 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() ) {
7fd59977 465 GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
466 if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
467 done = Standard_True;
468 return;
469 }
470 break;
471 }
472 }
2a78ec6a 473 dansS2 = Standard_True; // Keep in doubt
7fd59977 474 }
475
2a78ec6a 476 if (!trim) { // necessarily dansS1 == dansS2 == Standard_True
7fd59977 477 seqp.Append(GeomInt_LineTool::FirstParameter(L));
478 seqp.Append(GeomInt_LineTool::LastParameter(L));
479 done = Standard_True;
480 return;
481 }
482
2a78ec6a 483 // sequence seqpss is peeled to create valid ends
484 // and store them in seqp(2*i+1) and seqp(2*i+2)
7fd59977 485 Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L);
486 Standard_Real thelast = GeomInt_LineTool::LastParameter(L);
487 firstp = thefirst;
488
2a78ec6a 489 for (i=1; i<=nbvtx; i++) {
7fd59977 490 or1 = seqpss(i).Orientation1();
491 or2 = seqpss(i).Orientation2();
2a78ec6a 492 if (dansS1 && dansS2) {
493 if (or1 == TopAbs_REVERSED){
7fd59977 494 dansS1 = Standard_False;
2a78ec6a 495 }
496
497 if (or2 == TopAbs_REVERSED){
7fd59977 498 dansS2 = Standard_False;
2a78ec6a 499 }
500 if (!dansS1 || !dansS2) {
7fd59977 501 lastp = seqpss(i).Parameter();
502 Standard_Real stofirst = Max(firstp, thefirst);
503 Standard_Real stolast = Min(lastp, thelast) ;
2a78ec6a 504
505 if (stolast > stofirst) {
7fd59977 506 seqp.Append(stofirst);
507 seqp.Append(stolast);
508 }
2a78ec6a 509 if (lastp > thelast) {
7fd59977 510 break;
2a78ec6a 511 }
7fd59977 512 }
513 }
2a78ec6a 514 else {
515 if (dansS1) {
516 if (or1 == TopAbs_REVERSED) {
7fd59977 517 dansS1 = Standard_False;
2a78ec6a 518 }
7fd59977 519 }
2a78ec6a 520 else {
521 if (or1 == TopAbs_FORWARD){
7fd59977 522 dansS1 = Standard_True;
2a78ec6a 523 }
7fd59977 524 }
2a78ec6a 525 if (dansS2) {
526 if (or2 == TopAbs_REVERSED) {
7fd59977 527 dansS2 = Standard_False;
2a78ec6a 528 }
7fd59977 529 }
2a78ec6a 530 else {
531 if (or2 == TopAbs_FORWARD){
7fd59977 532 dansS2 = Standard_True;
2a78ec6a 533 }
7fd59977 534 }
2a78ec6a 535 if (dansS1 && dansS2){
7fd59977 536 firstp = seqpss(i).Parameter();
2a78ec6a 537 }
7fd59977 538 }
539 }
2a78ec6a 540 //
541 // finally to add
542 if (dansS1 && dansS2) {
7fd59977 543 lastp = thelast;
544 firstp = Max(firstp,thefirst);
545 if (lastp > firstp) {
546 seqp.Append(firstp);
547 seqp.Append(lastp);
548 }
549 }
550 done = Standard_True;
551}
552
553
554//=======================================================================
2a78ec6a 555//function : Recadre
556//purpose :
557//=======================================================================
558void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
559 const Handle(GeomAdaptor_HSurface)& myHS2,
560 Standard_Real& u1,
561 Standard_Real& v1,
562 Standard_Real& u2,
563 Standard_Real& v2)
564{
565 Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
566 const GeomAbs_SurfaceType typs1 = myHS1->GetType();
567 switch (typs1)
568 {
569 case GeomAbs_Cylinder:
570 case GeomAbs_Cone:
571 case GeomAbs_Sphere:
572 {
573 myHS1IsUPeriodic = Standard_True;
574 myHS1IsVPeriodic = Standard_False;
575 break;
576 }
577 case GeomAbs_Torus:
578 {
579 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
580 break;
581 }
582 default:
583 {
584 //-- Case of periodic biparameters is processed upstream
585 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
586 break;
587 }
588 }
589 Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
590 const GeomAbs_SurfaceType typs2 = myHS2->GetType();
591 switch (typs2)
592 {
593 case GeomAbs_Cylinder:
594 case GeomAbs_Cone:
595 case GeomAbs_Sphere:
596 {
597 myHS2IsUPeriodic = Standard_True;
598 myHS2IsVPeriodic = Standard_False;
599 break;
600 }
601 case GeomAbs_Torus:
602 {
603 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
604 break;
605 }
606 default:
607 {
608 //-- Case of periodic biparameters is processed upstream
609 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
610 break;
611 }
612 }
613 Standard_Real du, dv;
614 //
615 if(myHS1IsUPeriodic) {
616 const Standard_Real lmf = M_PI+M_PI; //-- myHS1->UPeriod();
617 const Standard_Real f = myHS1->FirstUParameter();
618 const Standard_Real l = myHS1->LastUParameter();
619 GeomInt::AdjustPeriodic(u1, f, l, lmf, u1, du);
620 }
621 if(myHS1IsVPeriodic) {
622 const Standard_Real lmf = M_PI+M_PI; //-- myHS1->VPeriod();
623 const Standard_Real f = myHS1->FirstVParameter();
624 const Standard_Real l = myHS1->LastVParameter();
625 GeomInt::AdjustPeriodic(v1, f, l, lmf, v1, dv);
626 }
627 if(myHS2IsUPeriodic) {
628 const Standard_Real lmf = M_PI+M_PI; //-- myHS2->UPeriod();
629 const Standard_Real f = myHS2->FirstUParameter();
630 const Standard_Real l = myHS2->LastUParameter();
631 GeomInt::AdjustPeriodic(u2, f, l, lmf, u2, du);
632 }
633 if(myHS2IsVPeriodic) {
634 const Standard_Real lmf = M_PI+M_PI; //-- myHS2->VPeriod();
635 const Standard_Real f = myHS2->FirstVParameter();
636 const Standard_Real l = myHS2->LastVParameter();
637 GeomInt::AdjustPeriodic(v2, f, l, lmf, v2, dv);
638 }
639}
640//=======================================================================
641//function : Parameters
642//purpose :
643//=======================================================================
644void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
645 const Handle(GeomAdaptor_HSurface)& myHS2,
646 const gp_Pnt& Ptref,
647 Standard_Real& U1,
648 Standard_Real& V1,
649 Standard_Real& U2,
650 Standard_Real& V2)
651{
652 Parameters(myHS1, Ptref, U1, V1);
653 Parameters(myHS2, Ptref, U2, V2);
654}
655//=======================================================================
656//function : Parameter
657//purpose :
658//=======================================================================
659void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
660 const gp_Pnt& Ptref,
661 Standard_Real& U1,
662 Standard_Real& V1)
663{
664 IntSurf_Quadric quad1;
665 //
666 switch (myHS1->Surface().GetType()) {
667 case GeomAbs_Plane:
668 quad1.SetValue(myHS1->Surface().Plane());
669 break;
670 case GeomAbs_Cylinder:
671 quad1.SetValue(myHS1->Surface().Cylinder());
672 break;
673 case GeomAbs_Cone:
674 quad1.SetValue(myHS1->Surface().Cone());
675 break;
676 case GeomAbs_Sphere:
677 quad1.SetValue(myHS1->Surface().Sphere());
678 break;
679 case GeomAbs_Torus:
680 quad1.SetValue(myHS1->Surface().Torus());
681 break;
682 default:
683 Standard_ConstructionError::Raise("GeomInt_LineConstructor::Parameters");
684 }
685 quad1.Parameters(Ptref,U1,V1);
686}
687
688//=======================================================================
689//function : GLinePoint
7fd59977 690//purpose :
691//=======================================================================
2a78ec6a 692void GLinePoint(const IntPatch_IType typl,
693 const Handle(IntPatch_GLine)& GLine,
694 const Standard_Real aT,
695 gp_Pnt& aP)
7fd59977 696{
2a78ec6a 697 switch (typl) {
698 case IntPatch_Lin:
699 aP = ElCLib::Value(aT, GLine->Line());
700 break;
701 case IntPatch_Circle:
702 aP = ElCLib::Value(aT, GLine->Circle());
703 break;
704 case IntPatch_Ellipse:
705 aP = ElCLib::Value(aT, GLine->Ellipse());
706 break;
707 case IntPatch_Hyperbola:
708 aP = ElCLib::Value(aT, GLine->Hyperbola());
709 break;
710 case IntPatch_Parabola:
711 aP = ElCLib::Value(aT, GLine->Parabola());
712 break;
713 default:
714 Standard_ConstructionError::Raise("GeomInt_LineConstructor::Parameters");
715 }
716}
7fd59977 717
2a78ec6a 718//=======================================================================
719//function : TreatCircle
720//purpose :
721//=======================================================================
722void GeomInt_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();
c5f3a425 729 Handle(IntPatch_GLine)& aGLine=Handle(IntPatch_GLine)::DownCast (aLine);
2a78ec6a 730 //
731 bRejected=RejectMicroCircle(aGLine, aType, aTol);
732 if (bRejected) {
733 return;
734 }
735 //----------------------------------------
736 Standard_Boolean bFound;
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 GeomInt_RealWithFlag *pVtx;
745 //-------------------------------------1
746 aTwoPI=M_PI+M_PI;
747 aTolPC=Precision::PConfusion();
748 aNbVtxWas=GeomInt_LineTool::NbVertex(aLine);
749
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 GeomInt_RealWithFlag [aNbVtx];
762 //
763 pVtx[0].SetValue(0.);
764 pVtx[1].SetValue(aTwoPI);
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 //
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 //
31e0b8e8 791 for(i=0; i<aNbVtx - 1; ++i) {
2a78ec6a 792 aT=pVtx[i+1].Value();
793 pVtx[i].SetValue(aT);
794 }
795 --aNbVtx;
796 }
797 }
798 //
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 GeomInt_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);
7fd59977 861 }
862 }
863 }
2a78ec6a 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 GeomInt_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);
7fd59977 894 }
2a78ec6a 895 }
896 //
897 j=0;
898 for(i=0; i<aNbVtx; ++i) {
899 if (pVtx[i].Flag()) {
900 pVtx[j]=pVtx[i];
901 ++j;
7fd59977 902 }
903 }
2a78ec6a 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 GeomInt_RealWithFlag *a)
958{
959 Standard_Integer nd, i, j, l, d=1;
960 GeomInt_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)
7fd59977 983}