0022627: Change OCCT memory management defaults
[occt.git] / src / IntPatch / IntPatch_ALineToWLine.cxx
CommitLineData
7fd59977 1// File: IntPatch_ALineToWLine.cxx
2// Created: Fri Nov 26 10:26:11 1993
3// Author: Modelistation
4// Copyright: Matra Datavision 1993
5
6#include <IntPatch_ALineToWLine.ixx>
7
8#include <IntSurf_LineOn2S.hxx>
9#include <IntSurf_PntOn2S.hxx>
10#include <IntSurf_TypeTrans.hxx>
11#include <IntSurf_Situation.hxx>
12
13#include <TColStd_Array1OfReal.hxx>
14#include <TColStd_Array1OfInteger.hxx>
15
16#include <Precision.hxx>
17
18#include <gp_Pnt.hxx>
19#include <gp_Vec.hxx>
20
21#include <Adaptor2d_HCurve2d.hxx>
22#include <GeomAbs_SurfaceType.hxx>
23#include <gp_Pnt2d.hxx>
24#include <gp_Vec2d.hxx>
25#include <IntAna2d_AnaIntersection.hxx>
26#include <gp_Lin2d.hxx>
27#include <IntAna2d_IntPoint.hxx>
28#include <gp_Cone.hxx>
29
30
31static
32 gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline,
33 const Standard_Real U,
34 Standard_Real& DU,
35 const Standard_Real CurvDef,
36 const Standard_Real AngDef);
37
38static
39 Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,
40 const Handle_Adaptor2d_HCurve2d& C2);
41
42static
43 void RecadreMemePeriode(const IntSurf_Quadric aQuad1,
44 const IntSurf_Quadric aQuad2,
45 Standard_Real& u1,
46 Standard_Real& u2,
47 const Standard_Real anu1,
48 const Standard_Real anu2);
49
50static
51 void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
52 const IntSurf_Quadric aQuad1,
53 const IntSurf_Quadric aQuad2,
54 const Standard_Real ref_u1,
55 const Standard_Real ref_u2,
56 Standard_Real& new_u1,
57 Standard_Real& new_u2);
58
59//
60static
61 void RefineParameters(const Handle(IntPatch_ALine)& aALine,
62 const Standard_Real aTb,
63 const Standard_Real aTe,
64 const Standard_Real aTx,
65 const Standard_Integer iDir,
66 const IntSurf_Quadric& aQuadric,
67 const Standard_Real aTol3D,
68 Standard_Real& aUx,
69 Standard_Real& aVx);
70static
71 Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
72 const Standard_Real aTx,
73 const Standard_Integer iDir,
74 const Standard_Real aTol3D,
75 Standard_Real& aT1);
76static
77 Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
78 const Standard_Real aVx,
79 const Standard_Real aTol3D);
80//
81
82//-- Je ne sais pas faire mieux et ca m'ennerve. lbr.
83//=======================================================================
84//function : IntPatch_ALineToWLine
85//purpose :
86//=======================================================================
87 IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
88 const IntSurf_Quadric& Quad2)
89:
90 quad1(Quad1),
91 quad2(Quad2),
92 deflectionmax(0.01),
93 pasuvmax(0.05),
94 nbpointsmax(200),
95 type(0),
96 myTolParam(1.e-12),
97 myTolOpenDomain(1.e-9),
98 myTolTransition(1.e-8)
99{
100 myTol3D=Precision::Confusion();
101}
102//=======================================================================
103//function : IntPatch_ALineToWLine
104//purpose :
105//=======================================================================
106 IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
107 const IntSurf_Quadric& Quad2,
108 const Standard_Real Deflection,
109 const Standard_Real PasUVMax,
110 const Standard_Integer NbMaxPoints)
111:
112 quad1(Quad1),
113 quad2(Quad2),
114 deflectionmax(Deflection),
115 pasuvmax(PasUVMax),
116 nbpointsmax(NbMaxPoints),
117 myTolParam(1.e-12),
118 myTolOpenDomain(1.e-9),
119 myTolTransition(1.e-8)
120{
121 myTol3D=Precision::Confusion();
122 type = 0;
123}
124//=======================================================================
125//function : SetTol3D
126//purpose :
127//=======================================================================
128 void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
129{
130 myTol3D = aTol;
131}
132//=======================================================================
133//function : Tol3D
134//purpose :
135//=======================================================================
136 Standard_Real IntPatch_ALineToWLine::Tol3D()const
137{
138 return myTol3D;
139}
140//=======================================================================
141//function : SetTolTransition
142//purpose :
143//=======================================================================
144 void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
145{
146 myTolTransition = aTol;
147}
148//=======================================================================
149//function : TolTransition
150//purpose :
151//=======================================================================
152 Standard_Real IntPatch_ALineToWLine::TolTransition()const
153{
154 return myTolTransition;
155}
156//=======================================================================
157//function : SetTolParam
158//purpose :
159//=======================================================================
160 void IntPatch_ALineToWLine::SetTolParam(const Standard_Real aTolParam)
161{
162 myTolParam = aTolParam;
163}
164//=======================================================================
165//function : TolParam
166//purpose :
167//=======================================================================
168 Standard_Real IntPatch_ALineToWLine::TolParam()const
169{
170 return myTolParam;
171}
172//=======================================================================
173//function : SetTolOpenDomain
174//purpose :
175//=======================================================================
176 void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
177{
178 myTolOpenDomain = aTol;
179}
180//=======================================================================
181//function : TolOpenDomain
182//purpose :
183//=======================================================================
184 Standard_Real IntPatch_ALineToWLine::TolOpenDomain()const
185{
186 return myTolOpenDomain;
187}
188//=======================================================================
189//function : SetConstantParameter
190//purpose :
191//=======================================================================
192 void IntPatch_ALineToWLine::SetConstantParameter() const
193{
194}
195//=======================================================================
196//function : SetUniformAbscissa
197//purpose :
198//=======================================================================
199 void IntPatch_ALineToWLine::SetUniformAbscissa() const
200{
201}
202//=======================================================================
203//function : SetUniformDeflection
204//purpose :
205//=======================================================================
206 void IntPatch_ALineToWLine::SetUniformDeflection() const
207{
208}
209//=======================================================================
210//function : MakeWLine
211//purpose :
212//=======================================================================
213 Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline) const
214{
215 Standard_Boolean included;
216 Standard_Real f = aline->FirstParameter(included);
217 if(!included) {
218 f+=myTolOpenDomain;
219 }
220 Standard_Real l = aline->LastParameter(included);
221 if(!included) {
222 l-=myTolOpenDomain;
223 }
224 return(MakeWLine(aline,f,l));
225}
226
227//=======================================================================
228//function : MakeWLine
229//purpose :
230//=======================================================================
231 Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline,
232 const Standard_Real _firstparam,
233 const Standard_Real _lastparam) const
234{
235 //
236 Standard_Real dl, dumin, dumax, U, pv, pu1, pv1, pu2, pv2;
237 Standard_Real firstparam, lastparam;
238 Standard_Integer v, nbvtx;
239 Standard_Boolean TriOk;
240 //
241 firstparam = _firstparam;
242 lastparam = _lastparam;
243 // Pas Bon ...
244 // nbpointsmax It is the field. ( =200. by default)
245 dl = (lastparam - firstparam)/(Standard_Real)(nbpointsmax-1);
246 dumin = 0.1*dl;
247 dumax = 10 * dl;
248 //
249 nbvtx = aline->NbVertex();
250 //
251 TColStd_Array1OfReal paramvertex(1,Max(nbvtx,1)), newparamvertex(1,Max(nbvtx,1));
252 //
253 for(v = 1; v<=nbvtx; v++) {
254 const IntPatch_Point& aVtx = aline->Vertex(v);
255 pv=aVtx.ParameterOnLine();
256 paramvertex(v)=pv;
257 newparamvertex(v)=-1.;
258 }
259 //
260 //-- Tri et Confusion des vertex proches
261 do {
262 TriOk = Standard_True;
263 for(v=2; v<=nbvtx;v++) {
264 if(paramvertex(v) < paramvertex(v-1)) {
265 pv=paramvertex(v);
266 paramvertex(v-1)=paramvertex(v);
267 paramvertex(v)=pv;
268 TriOk = Standard_False;
269 }
270 }
271 }
272 while(!TriOk);
273 //
274 for(v=2; v<=nbvtx;v++) {
275 pv=paramvertex(v);
276 pv1=paramvertex(v-1);
277 if(pv-pv1 < myTolParam) {
278 paramvertex(v)=pv1;
279 }
280 }
281 //
282 Standard_Integer t, nbpwline;
283 Standard_Real u1,v1,u2,v2, anu1, anv1, anu2, anv2;
284 Standard_Real aL, dl_sur_2;
285 gp_Pnt Pnt3d, aPnt3d1;
286 IntSurf_PntOn2S POn2S;
287 Handle(IntSurf_LineOn2S) LinOn2S;
288 //
289 LinOn2S = new IntSurf_LineOn2S;
290
291 //// Modified by jgv, 17.09.09 for OCC21255 ////
292 Standard_Real refpar = RealLast(), ref_u1, ref_u2;
293 if (nbvtx)
294 {
295 const IntPatch_Point& FirstVertex = aline->Vertex(1);
296 refpar = FirstVertex.ParameterOnLine();
297 FirstVertex.Parameters(ref_u1, v1, ref_u2, v2);
298 }
299 ////////////////////////////////////////////////
300
301 //-----------------------------------------------------
302 //-- Estimation Grossiere de la longueur de la courbe
303 //--
304 aL=0.;
305 dl_sur_2=0.5*dl;
306 Pnt3d = aline->Value(firstparam);
307 for(t=0, U=firstparam+dumin; U<lastparam; t++,U+=dl_sur_2) {
308 aPnt3d1 = aline->Value(U);
309 aL+=Pnt3d.Distance(aPnt3d1);
310 Pnt3d=aPnt3d1;
311 }
312 //------------------------------------------------------
313 aL/=t;
314 aL*=2;
315 //------------------------------------------------------
316 //-- Calcul du premier point
317 //--
318 //------------------------------------------------------
319 //-- On reajuste firstparam et lastparam au cas ou ces
320 //-- valeurs sont tres proches des parametres de vertex
321 if(nbvtx) {
322 Standard_Real pvtxmin, pvtxmax;
323 //
324 pvtxmin = aline->Vertex(1).ParameterOnLine();
325 pvtxmax = pvtxmin;
326 //
327 for(v=2; v<=nbvtx; v++) {
328 pv=aline->Vertex(v).ParameterOnLine();
329 if(pvtxmin>pv){
330 pvtxmin = pv;
331 }
332 if(pvtxmax<pv){
333 pvtxmax =pv;
334 }
335 }
336 if(Abs(pvtxmin-firstparam)<myTolOpenDomain) {
337 firstparam=pvtxmin;
338 }
339 if(Abs(pvtxmax-lastparam)<myTolOpenDomain) {
340 lastparam=pvtxmax;
341 }
342 }
343 //
344 // First Point
345 Pnt3d = aline->Value(firstparam);
346 quad1.Parameters(Pnt3d,u1,v1);
347 //
348 RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad1, 10.*myTol3D, u1,v1);
349 //
350 //
351 quad2.Parameters(Pnt3d,u2,v2);
352 //
353 RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad2, 10.*myTol3D, u2,v2);
354 //
355
356 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
357 anu1 = u1;
358 anu2 = u2;
359 LinOn2S->Add(POn2S);
360 nbpwline = 1;
361 U = firstparam;
362 //-------------------------------------------------------
363 //-- On detecte le cas : Point de debut == vertex
364 //-- On affecte un parametre bidon qui sera recadre
365 //-- dans l insertion des vertex dans la ligne
366 //--
367 for(v=1;v<=nbvtx;v++) {
368 if(newparamvertex(v)<0.) {
369 pv=paramvertex(v);
370 if((pv>=U-2.0*myTolOpenDomain) && (pv<=U+2.0*myTolOpenDomain)) {
371 if(pv-U > myTolParam) {
372 newparamvertex(v) = 1.000001;
373 }
374 else if(U-pv>myTolParam) {
375 newparamvertex(v) = 0.999999;
376 }
377 }
378 }
379 }
380 //
381 Standard_Real DeltaU;
382 //
383 // the loop
384 DeltaU=0.;
385 //// Modified by jgv, 17.09.09 for OCC21255 ////
386 Standard_Boolean Corrected = Standard_False;
387 ////////////////////////////////////////////////
388 while(U<lastparam) {
389 Standard_Integer NbCalculD1;
390 Standard_Real UPourCalculD1, pvavant, pvapres;
391 gp_Vec VPourCalculD1;
392 gp_Pnt PPourCalculD1;
393 //
394 DeltaU=0.;
395 NbCalculD1=0;
396 UPourCalculD1=U;
397 do {
398 if(aline->D1(UPourCalculD1,PPourCalculD1,VPourCalculD1)) {
399 Standard_Real NormV = VPourCalculD1.Magnitude();
400 if(NormV > 1.0e-16) {
401 DeltaU = aL/NormV;
402 }
403 }
404 if(DeltaU < dumin)
405 DeltaU = dumin;
406 else if (DeltaU > dumax)
407 DeltaU = dumax;
408 UPourCalculD1+=dumin;
409 }
410 while((++NbCalculD1<10)&&(DeltaU==0.));
411 //
412 //OCC541(apo)->
413 // static //xft
414 Standard_Real CurvDef = deflectionmax, AngDef = CurvDef;
415 if(U+DeltaU < lastparam) {
416 DefineDU(aline,U,DeltaU,CurvDef,AngDef);
417 }
418 //<-OCC451(apo)
419 //
420 if(DeltaU==0.){
421 DeltaU = (dumin+dumax)*0.5;
422 }
423 //--------------------------------------------------------
424 //-- On cherche a placer un minimum de ??? Points entre
425 //-- 2 vertex
426 //--------------------------------------------------------
427 pvavant = firstparam;
428 pvapres = lastparam;
429 for(v=1;v<=nbvtx;v++) {
430 pv=paramvertex(v);
431 if(pv-U > myTolParam) {
432 if(pvapres>pv) {
433 pvapres = pv;
434 }
435 }
436 else {
437 if(U-pv > myTolParam) {
438 if(pvavant<pv) {
439 pvavant = pv;
440 }
441 }
442 }
443 }
444 pvapres-=pvavant;
445 if(pvapres < (10.*DeltaU)) {
446 if(pvapres > (10.*dumin)) {
447 DeltaU = pvapres*0.1;
448 }
449 else {
450 DeltaU = dumin;
451 }
452 }
453 //xf
454 if (nbpwline==1 && nbvtx) {
455 Standard_Real aUnext;
456 //
457 aUnext=U+DeltaU;
458 pv=paramvertex(1);
459 if (aUnext>pv){
460 DeltaU=0.5*(pv-firstparam);
461 }
462 }
463 //xt
464 //--------------------------------------------------------
465 //-- Calcul des nouveaux parametres sur les vertex
466 //--
467 for(v=1;v<=nbvtx;v++) {
468 if(newparamvertex(v)<0.) {
469 pv=paramvertex(v);
470 if(pv>=U && pv<(U+DeltaU) && (U+DeltaU<lastparam) ) {
471 newparamvertex(v) = (Standard_Real)nbpwline + (pv-U)/DeltaU;
472 }
473 }
474 }
475
476 //// Modified by jgv, 17.09.09 for OCC21255 ////
477 if (!Corrected && U >= refpar)
478 {
479 CorrectFirstPartOfLine(LinOn2S, quad1, quad2, ref_u1, ref_u2, anu1, anu2);
480 Corrected = Standard_True;
481 }
482 ////////////////////////////////////////////////
483 U+=DeltaU;
484 if(U < lastparam) {
485 nbpwline++;
486 Pnt3d = aline->Value(U);
487 quad1.Parameters(Pnt3d,u1,v1);
488 quad2.Parameters(Pnt3d,u2,v2);
489 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
490 anu1 = u1;
491 anu2 = u2;
492 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
493 LinOn2S->Add(POn2S);
494 }
495 }//while(U<lastparam)
496
497 U-=DeltaU;
498 for(v=1;v<=nbvtx;v++) {
499 if(newparamvertex(v)<0.) {
500 pv=paramvertex(v);
501 if(pv <= lastparam+myTolOpenDomain) {
502 if(lastparam-U) {
503 newparamvertex(v) = (Standard_Real)nbpwline+(pv-U)/(lastparam-U);
504 }
505 else {
506 newparamvertex(v) = nbpwline+1;
507 }
508 }
509 }
510 }
511 //
512 Pnt3d = aline->Value(lastparam);
513 quad1.Parameters(Pnt3d,u1,v1);
514 //
515 RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad1, 10.*myTol3D, u1,v1);
516 //
517 quad2.Parameters(Pnt3d,u2,v2);
518 //
519 RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad2, 10.*myTol3D, u2,v2);
520 //
521 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
522 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
523 LinOn2S->Add(POn2S);
524 nbpwline++;
525
526 //// Modified by jgv, 17.09.09 for OCC21255 ////
527 if (!Corrected &&
528 (lastparam >= refpar || refpar-lastparam < Precision::Confusion()))
529 CorrectFirstPartOfLine(LinOn2S, quad1, quad2, ref_u1, ref_u2, anu1, anu2);
530 ////////////////////////////////////////////////
531
532 //
533 //-----------------------------------------------------------------
534 //-- Calcul de la transition de la ligne sur les surfaces ---
535 //-----------------------------------------------------------------
536 IntSurf_TypeTrans trans1,trans2;
537 Standard_Integer indice1;
538 Standard_Real dotcross;
539 gp_Pnt aPP0, aPP1;
540 //
541 trans1=IntSurf_Undecided;
542 trans2=IntSurf_Undecided;
543 //
544 indice1 = nbpwline/3;
545 if(indice1<=2) {
546 indice1 = 2;
547 }
548 //
549 aPP1=LinOn2S->Value(indice1).Value();
550 aPP0=LinOn2S->Value(indice1-1).Value();
551 //
552 gp_Vec tgvalid(aPP0, aPP1);
553 gp_Vec aNQ1=quad1.Normale(aPP0);
554 gp_Vec aNQ2=quad2.Normale(aPP0);
555 //
556 dotcross = tgvalid.DotCross(aNQ2, aNQ1);
557 if (dotcross > myTolTransition) {
558 trans1 = IntSurf_Out;
559 trans2 = IntSurf_In;
560 }
561 else if(dotcross < -myTolTransition) {
562 trans1 = IntSurf_In;
563 trans2 = IntSurf_Out;
564 }
565 //-----------------------------------------------------------------
566 //-- C r e a t i o n d e la W L i n e ---
567 //-----------------------------------------------------------------
568 Handle(IntPatch_WLine) wline;
569 //
570 if(aline->TransitionOnS1() == IntSurf_Touch) {
571 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
572 aline->IsTangent(),
573 aline->SituationS1(),
574 aline->SituationS2());
575 wline = wlinetemp;
576 }
577 if(aline->TransitionOnS1() == IntSurf_Undecided) {
578 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
579 aline->IsTangent());
580 wline = wlinetemp;
581 }
582 else {
583 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
584 aline->IsTangent(),
585 trans1, // aline->TransitionOnS1(),
586 trans2); //aline->TransitionOnS2());
587 wline = wlinetemp;
588 }
589
590 //-----------------------------------------------------------------
591 //-- I n s e r t i o n d e s v e r t e x ---
592 //-----------------------------------------------------------------
593 TColStd_Array1OfInteger Redir(1,Max(nbvtx,1));
594 //
595 for(v=1;v<=nbvtx;v++) {
596 Redir(v) = v;
597 }
598 //
599 TriOk=Standard_True;
600 Standard_Integer tamp;
601 do {
602 TriOk = Standard_True;
603 for(v=2; v<=nbvtx;v++) {
604 if(newparamvertex(Redir(v))<newparamvertex(Redir(v-1))) {
605 tamp = Redir(v-1);
606 Redir(v-1) = Redir(v);
607 Redir(v) = tamp;
608 TriOk = Standard_False;
609 }
610 }
611 }
612 while(!TriOk);
613
614 //-----------------------------------------------------------------
615 //-- On detecte le cas ou un Vtx de param 1 ou nbpwline OnArc est double
616 //-- Dans ce cas on supprime le vertex qui reference un arc deja reference
617 //-- par un autre vertex
618 //nbvtx = aline->NbVertex();
619 Standard_Boolean APointHasBeenRemoved;
620 //
621 do {
622 Standard_Boolean RemoveVtxo, RemoveVtx;
623 Standard_Integer vo, voo;
624 Standard_Real ponl, ponlo, ponloo, aDist13, aDist23;
625 //
626 APointHasBeenRemoved = Standard_False;
627 RemoveVtxo = Standard_False;
628 RemoveVtx = Standard_False;
629 //
630 for(v=1; v<=nbvtx && !APointHasBeenRemoved; v++) {
631 //
632 if(newparamvertex(v)>=0.) {
633 const IntPatch_Point& Vtx = aline->Vertex(v);
634 ponl = Vtx.ParameterOnLine();
635 const gp_Pnt& aP=Vtx.Value();
636 //
637 for(vo=1; vo<=nbvtx && !APointHasBeenRemoved; vo++) {
638 if(v!=vo) {
639 if(newparamvertex(vo)>=0.) {
640 const IntPatch_Point& Vtxo = aline->Vertex(vo);
641 ponlo = Vtxo.ParameterOnLine();
642 const gp_Pnt& aPo=Vtxo.Value();
643 //
644 if(ponl-ponlo<myTolParam && ponlo-ponl<myTolParam) {
645 //
646 for(voo=1; voo<=nbvtx && !APointHasBeenRemoved; voo++) {
647 if(voo!=v && voo!=vo) {
648 if(newparamvertex(voo)>=0.) {
649 const IntPatch_Point& Vtxoo = aline->Vertex(voo);
650 ponloo = Vtxoo.ParameterOnLine();
651 const gp_Pnt& aPoo=Vtxoo.Value();
652 //
653 aDist13=aP.Distance(aPoo);
654 //
655 if(aDist13<=myTol3D) {
656 //-- 2 vertex de meme param + un confondu geometriquement
657 if((Vtx.IsOnDomS1() == Vtxoo.IsOnDomS1()) &&
658 (Vtx.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) {
659
660 if(Vtx.IsOnDomS1()) {
661 if(Vtx.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) {
662 if(SameCurve(Vtxoo.ArcOnS1(),Vtx.ArcOnS1())) { //-- param on s1 ?
663 RemoveVtx = Standard_True;
664 }
665 }
666 }
667 if(Vtx.IsOnDomS2()) {
668 if(Vtx.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) {
669 if(SameCurve(Vtxoo.ArcOnS2(),Vtx.ArcOnS2())) {
670 RemoveVtx = Standard_True;
671 }
672 }
673 else {
674 RemoveVtx = Standard_False;
675 }
676 }
677 }
678 //
679 if(RemoveVtx==Standard_False) {
680 //
681 aDist23=aPo.Distance(aPoo);
682 //
683 if(aDist23<=myTol3D) {
684 //-- 2 vertex de meme param + un confondu geometriquement
685 if((Vtxo.IsOnDomS1() == Vtxoo.IsOnDomS1())&&
686 (Vtxo.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) {
687 if(Vtxo.IsOnDomS1()) {
688 if(Vtxo.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) {
689 if(SameCurve(Vtxoo.ArcOnS1(),Vtxo.ArcOnS1())) { //-- param on s1 ?
690 RemoveVtxo = Standard_True;
691 }
692 }
693 }
694 if(Vtxo.IsOnDomS2()) {
695 if(Vtxo.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) {
696 if(SameCurve(Vtxoo.ArcOnS2(),Vtxo.ArcOnS2())) {
697 RemoveVtxo = Standard_True;
698 }
699 }
700 else {
701 RemoveVtxo = Standard_False;
702 }
703 }
704 }
705 }
706 } //--
707 if(RemoveVtx) {
708 newparamvertex(v) = -1.;
709 APointHasBeenRemoved = Standard_True;
710 }
711 else if(RemoveVtxo) {
712 newparamvertex(vo) = -1.;
713 APointHasBeenRemoved = Standard_True;
714 }
715 } //-- Pnt = Pntoo
716 } //-- voo!=v && voo!=vo
717 } //-- Fin boucle sur voo
718 }
719 }
720 }
721 }
722 }
723 }
724 }//for(v=1; v<=nbvtx && !APointHasBeenRemoved; v++)
725 }
726 while(APointHasBeenRemoved);
727 //
728 Standard_Integer ParamVtxPrecedent, refpointonwline, aIndV;
729 Standard_Real pvtx, approxparamonwline, aDst;
730 Standard_Boolean bIsApex1, bIsApex2;
731 //
732 ParamVtxPrecedent = 0;
733 //
734 for(v=1; v<=nbvtx; v++) {
735 aIndV=Redir(v);
736 pv=paramvertex(v);// parameter from ALine
737 pvtx = newparamvertex(aIndV);
738 if(pvtx>=0. && (pvtx <= nbpwline+1)) {
739 approxparamonwline=newparamvertex(aIndV);
740 refpointonwline=1;
741 //
742 IntPatch_Point NewPoint = aline->Vertex(aIndV);
743 //
744 Pnt3d = NewPoint.Value();
745 quad1.Parameters(Pnt3d, u1, v1);
746 quad2.Parameters(Pnt3d, u2, v2);
747 //-------------------------------------------------------
748 //-- On recadre les parametres des vertex dans la bonne -
749 //-- periode en recadrant avec le point le plus proche -
750 //-------------------------------------------------------
751 if(approxparamonwline > nbpwline) {
752 refpointonwline = nbpwline-1;
753 }
754 else if(approxparamonwline < 1) {
755 refpointonwline = 1;
756 }
757 else {
758 refpointonwline = (Standard_Integer)approxparamonwline;
759 }
760 //
761 //
762 const IntSurf_PntOn2S& aP2Sx=LinOn2S->Value(refpointonwline);
763 aP2Sx.ParametersOnS1(anu1, anv1);
764 aP2Sx.ParametersOnS2(anu2, anv2);
765 //
766 bIsApex1=IsApex(quad1, v1, myTol3D);
767 bIsApex2=IsApex(quad2, v2, myTol3D);
768 //
769 //if (refpointonwline==1 || refpointonwline==nbpwline) {
770 if (bIsApex1 || bIsApex2) {
771 if (fabs(pv-firstparam)<myTolParam || fabs(pv-lastparam)<myTolParam) {
772 // aline starts(ends) on vertex
773 const gp_Pnt& aP1x=aP2Sx.Value();
774 //
775 aDst=aP1x.Distance(Pnt3d);
776 if (aDst<10.*myTol3D) {
777 u1=anu1;
778 v1=anv1;
779 u2=anu2;
780 v2=anv2;
781 }
782 }
783 //
784 else {
785 // aline goes through vertex
786 if (bIsApex1) {
787 u1=0.;
788 }
789 if (bIsApex2) {
790 u2=0.;
791 }
792 }
793 }
794 //
795 //
796 if(v==1) {
797 ParamVtxPrecedent=refpointonwline;
798 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
799 NewPoint.SetParameter(refpointonwline);
800 //
801 NewPoint.SetParameters(u1,v1,u2,v2);
802 wline->AddVertex(NewPoint);
803 }
804 //
805 else {
806 if(ParamVtxPrecedent==refpointonwline) {
807 //-- 2 vertex renseignent le meme point de la LineOn2S
808 //-- On insere un nv point = vtx
809 //-- On decale tous les vtx apres de 1
810 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
811 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
812 LinOn2S->InsertBefore(refpointonwline+1, POn2S);
813 nbpwline++;
814 NewPoint.SetParameter(refpointonwline+1);
815 NewPoint.SetParameters(u1,v1,u2,v2);
816 wline->AddVertex(NewPoint);
817 ParamVtxPrecedent = refpointonwline+1;
818 //
819 Standard_Integer vv=v+1;
820 for(; vv<=nbvtx; vv++) {
821 if(newparamvertex(Redir(vv))!=-1.) {
822 newparamvertex(Redir(vv))=newparamvertex(Redir(vv))+1.;
823 }
824 }
825 }
826 //
827 else {
828 RecadreMemePeriode(quad1, quad2, u1,u2, anu1, anu2);
829 NewPoint.SetParameter(refpointonwline);
830 //
831 NewPoint.SetParameters(u1, v1, u2, v2);
832 wline->AddVertex(NewPoint);
833 ParamVtxPrecedent = refpointonwline;
834 }
835 }
836 }
837 }
838 //
839 pu1=0.;
840 pv1=0.;
841 pu2=0.;
842 pv2=0.;
843 //
844 switch(quad1.TypeQuadric()) {
845 case GeomAbs_Cylinder:
846 case GeomAbs_Cone:
847 case GeomAbs_Sphere:
c6541a0c 848 pu1=M_PI+M_PI;
7fd59977 849 break;
850 default:
851 break;
852 }
853 switch(quad2.TypeQuadric()) {
854 case GeomAbs_Cylinder:
855 case GeomAbs_Cone:
856 case GeomAbs_Sphere:
c6541a0c 857 pu2=M_PI+M_PI;
7fd59977 858 break;
859 default:
860 break;
861 }
862 wline->SetPeriod(pu1,pv1,pu2,pv2);
863
864 wline->ComputeVertexParameters(myTol3D);
865 return(wline);
866}
867//=======================================================================
868//function : DefineDU
869//purpose :
870//=======================================================================
871gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline,
872 const Standard_Real U,
873 Standard_Real& DU,
874 const Standard_Real CurvDef,
875 const Standard_Real AngDef)
876{
877 gp_Pnt P1 = aline->Value(U), P2, P3;
878 gp_Vec V13, V12, V23;
879 Standard_Real dU = DU/2.0, curvDef, angDef, m1, m2, m3;
880 do{ //According to class TangentialDeflection from GCPnts
881 P2=aline->Value(U+dU); P3=aline->Value(U+DU);
882 V13 = P3.XYZ().Subtracted(P1.XYZ()); m1 = V13.Magnitude();
883 V12 = P2.XYZ().Subtracted(P1.XYZ()); m2 = V12.Magnitude();
884 V23 = P3.XYZ().Subtracted(P2.XYZ()); m3 = V23.Magnitude();
885 if(m1 < CurvDef || m2 < CurvDef || m3 < CurvDef) break;
886 curvDef = Abs(V13.Angle(V12));
887 angDef = Abs(V13.Angle(V23));
888 if(curvDef < CurvDef && angDef < AngDef) break;
889 DU = dU; dU /= 2.0;
890 }while(1);
891 return P3;
892}
893//=======================================================================
894//function : SameCurve
895//purpose :
896//=======================================================================
897Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,const Handle_Adaptor2d_HCurve2d& C2)
898{
899 Standard_Real C1f = C1->FirstParameter();
900 Standard_Real C2f = C2->FirstParameter();
901 if(C1f!=C2f) return(Standard_False);
902 Standard_Real C1l = C1->LastParameter();
903 Standard_Real C2l = C2->LastParameter();
904 if(C1l!=C2l) return(Standard_False);
905 Standard_Real u=0.3*C1f+0.7*C1l;
906 gp_Pnt2d P1 = C1->Value(u);
907 gp_Pnt2d P2 = C2->Value(u);
908 if(P1.X()!=P2.X()) return(Standard_False);
909 if(P1.Y()!=P2.Y()) return(Standard_False);
910 return(Standard_True);
911}
912//=======================================================================
913//function : RecadreMemePeriode
914//purpose :
915//=======================================================================
916void RecadreMemePeriode(const IntSurf_Quadric aQuad1,
917 const IntSurf_Quadric aQuad2,
918 Standard_Real& u1,
919 Standard_Real& u2,
920 const Standard_Real anu1,
921 const Standard_Real anu2)
922{
923 Standard_Boolean bBothCylinders;
924 GeomAbs_SurfaceType aType1, aType2;
925 //
926 aType1=aQuad1.TypeQuadric();
927 aType2=aQuad2.TypeQuadric();
928 bBothCylinders=(aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder);
929 //
930 while(anu1-u1 > 5.0) {
c6541a0c 931 u1+=M_PI+M_PI;
7fd59977 932 }
933 while(u1-anu1 > 5.0) {
934 //
935 /*
936 if (!bBothCylinders) {//cfe900/H6
937 // this check on Cylinder/Cylinder intersection is probably
938 // because of pbs with ALine on it.
939 // For other Quadrics there was no pbs found during
940 // grid tests.
941 // (it is necessary to see ...IntCyCy(...) for details).
942 //
943 // In any case the pb does not deal with apex problem.
944 //
c6541a0c 945 if (u1-M_PI-M_PI<0.) {
7fd59977 946 break;
947 }
948 }
949 */
950 //
c6541a0c 951 u1-=M_PI+M_PI;
7fd59977 952 }
953 while(anu2-u2 > 5.0) {
c6541a0c 954 u2+=M_PI+M_PI;
7fd59977 955 }
956 while(u2-anu2 > 5.0) {
957 //
958 /*
959 if (!bBothCylinders) {//cfe900/H6
c6541a0c 960 if (u2-M_PI-M_PI<0.) {
7fd59977 961 break;
962 }
963 }
964 */
965 //
c6541a0c 966 u2-=M_PI+M_PI;
7fd59977 967 }
968}
969
970//=======================================================================
971//function : CorrectFirstPartOfLine
972//purpose :
973//=======================================================================
974void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
975 const IntSurf_Quadric aQuad1,
976 const IntSurf_Quadric aQuad2,
977 const Standard_Real ref_u1,
978 const Standard_Real ref_u2,
979 Standard_Real& new_u1,
980 Standard_Real& new_u2)
981{
982 Standard_Integer nbp = LinOn2S->NbPoints();
983 Standard_Real u1, v1, u2, v2, OffsetOnS1, OffsetOnS2;
984
985 IntSurf_PntOn2S aPoint = LinOn2S->Value(nbp);
986 aPoint.Parameters(u1, v1, u2, v2);
987
988 new_u1 = u1;
989 new_u2 = u2;
990 RecadreMemePeriode(aQuad1, aQuad2, new_u1, new_u2, ref_u1, ref_u2);
991 OffsetOnS1 = new_u1 - u1;
992 OffsetOnS2 = new_u2 - u2;
993 if (Abs(OffsetOnS1) > 1. || Abs(OffsetOnS2) > 1.) //recadre on n*2*PI is done
994 {
995 Standard_Integer i;
996 for (i = 1; i <= nbp; i++)
997 {
998 aPoint = LinOn2S->Value(i);
999 aPoint.Parameters(u1, v1, u2, v2);
1000 LinOn2S->SetUV( i, Standard_True, u1 + OffsetOnS1, v1 );
1001 LinOn2S->SetUV( i, Standard_False, u2 + OffsetOnS2, v2 );
1002 }
1003 }
1004}
1005
1006//
1007//=======================================================================
1008//function : IsApex
1009//purpose :
1010//=======================================================================
1011Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
1012 const Standard_Real aVx,
1013 const Standard_Real aTol3D)
1014
1015{
1016 Standard_Boolean bFlag;
1017 Standard_Real aHalfPi, aEpsilon;
1018 GeomAbs_SurfaceType aType;
1019 //
1020 bFlag=Standard_False;
1021 //
1022 aType=aQuadric.TypeQuadric();
1023 if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
1024 return bFlag;
1025 }
1026 //
1027 aEpsilon=Epsilon(10.);//1.77e-15
1028 //
1029 // apex on the Sphere
1030 if(aType==GeomAbs_Sphere) {
c6541a0c 1031 aHalfPi=0.5*M_PI;
7fd59977 1032 if (fabs(aVx-aHalfPi)<aEpsilon) {
1033 bFlag=!bFlag;
1034 }
1035 else if (fabs(aVx+aHalfPi)<aEpsilon){
1036 bFlag=!bFlag;
1037 }
1038 }
1039 //
1040 // apex on the Cone
1041 else if(aType==GeomAbs_Cone) {
1042 Standard_Real aDst;
1043 gp_Pnt aPap, aPx;
1044 gp_Cone aCone;
1045 //
1046 aCone=aQuadric.Cone();
1047 aPap=aCone.Apex();
1048 aPx=aQuadric.Value(0.,aVx);
1049 //
1050 aDst=aPx.Distance(aPap);
1051 if(aDst<aTol3D) {
1052 bFlag=!bFlag;
1053 }
1054 }
1055 return bFlag;
1056}
1057//=======================================================================
1058//function : RefineParameters
1059//purpose :
1060//=======================================================================
1061void RefineParameters(const Handle(IntPatch_ALine)& aALine,
1062 const Standard_Real aTb,
1063 const Standard_Real aTe,
1064 const Standard_Real aTx,
1065 const Standard_Integer iDir,
1066 const IntSurf_Quadric& aQuadric,
1067 const Standard_Real aTol3D,
1068 Standard_Real& aUx,
1069 Standard_Real& aVx)
1070{
1071 GeomAbs_SurfaceType aType;
1072 //
1073 aType=aQuadric.TypeQuadric();
1074 if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
1075 return;
1076 }
1077 //
1078 Standard_Boolean bIsDone, bIsEmpty, bParallel, bFound;
1079 Standard_Integer aNbPoints;
1080 Standard_Real aHalfPi, aEpsilon, aLimV, dT, aT1, aT2, aEpsT;
1081 Standard_Real aU1, aV1, aU2, aV2;
1082 gp_Pnt aP1, aP2, aPx;
1083 gp_Pnt2d aP2D1, aP2D2, aPLim(0., 0.);
1084 gp_Vec2d aVLim(1., 0.);
1085 gp_Lin2d aLLim;
1086 IntAna2d_AnaIntersection aAI;
1087 //
1088 aEpsilon=Epsilon(10.);//1.77e-15
1089 aEpsT=0.0001;
1090 aLLim.SetDirection(aVLim);
1091 //
1092 // apex on the Cone
1093 if(aType==GeomAbs_Cone) {
1094 Standard_Real aDst;
1095 gp_Pnt aPap;
1096 gp_Cone aCone;
1097 //
1098 aCone=aQuadric.Cone();
1099 aPap=aCone.Apex();
1100 //aPx=aQuadric.Value(0.,aVx);
1101 aPx=aALine->Value(aTx);
1102 //
1103 aDst=aPx.Distance(aPap);
1104 if(aDst>aTol3D) {// nothing to do
1105 return;
1106 }
1107 //
1108 aPLim.SetY(aVx);
1109 aLLim.SetLocation(aPLim);
1110 //
1111 }
1112 //
1113 // apex on the Sphere
1114 if(aType==GeomAbs_Sphere) {
c6541a0c 1115 aHalfPi=0.5*M_PI;
7fd59977 1116 //
1117 if (fabs(aVx-aHalfPi)<aEpsilon) {
1118 aLimV=aHalfPi;
1119 }
1120 else if (fabs(aVx+aHalfPi)<aEpsilon){
1121 aLimV=-aHalfPi;
1122 }
1123 else {
1124 //Check: aUx must be 0 or 2*pi
c6541a0c 1125 if(fabs(aUx) < aEpsilon || fabs(aUx - 2.*M_PI) < aEpsilon) {
7fd59977 1126 //aUx = 0 or 2*pi, but may be it must be 2*pi or 0?
1127 bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
1128 if(!bFound) {
1129 dT=aEpsT*(aTe-aTb);
1130 if (iDir<0) {
1131 dT=-dT;
1132 }
1133 aT1=aTx+dT;
1134 }
1135
1136 aP1=aALine->Value(aT1);
1137 aQuadric.Parameters(aP1, aU1, aV1);
1138
c6541a0c
D
1139 if(fabs(aU1) > fabs(aU1 - 2.*M_PI)) {
1140 aUx = 2.*M_PI;
7fd59977 1141 }
1142 else {
1143 aUx = 0.;
1144 }
1145 }
1146
1147 return;
1148 }
1149 //
1150 aPLim.SetY(aLimV);
1151 aLLim.SetLocation(aPLim);
1152 }
1153 //
1154 // aT1, aT2
1155 //
1156 // Try to find aT1, aT2 taking into acc 3D Tolerance
1157 bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
1158 if (bFound) {
1159 bFound=FindNearParameter(aALine, aT1, iDir, aTol3D, aT2);
1160 }
1161 if (!bFound) {
1162 // Assign aT1, aT2 by some values
1163 dT=aEpsT*(aTe-aTb);
1164 if (iDir<0) {
1165 dT=-dT;
1166 }
1167 aT1=aTx+dT;
1168 aT2=aT1+dT;
1169 }
1170 //
1171 aP1=aALine->Value(aT1);
1172 aQuadric.Parameters(aP1, aU1, aV1);
1173 aP2D1.SetCoord(aU1, aV1);
1174 //
1175 aP2=aALine->Value(aT2);
1176 aQuadric.Parameters(aP2, aU2, aV2);
1177 aP2D2.SetCoord(aU2, aV2);
1178 //
1179 gp_Vec2d aV12(aP2D1, aP2D2);
1180
1181 if(aV12.SquareMagnitude() <= aEpsilon) {
1182 return;
1183 }
1184 gp_Lin2d aL12(aP2D1, aV12);
1185 //
1186 aAI.Perform(aLLim, aL12);
1187 bIsDone=aAI.IsDone();
1188 if (!bIsDone) {
1189 return;
1190 }
1191 bIsEmpty=aAI.IsEmpty();
1192 if (bIsEmpty) {
1193 return;
1194 }
1195 aNbPoints=aAI.NbPoints();
1196 if (!aNbPoints) {
1197 return;
1198 }
1199 bParallel=aAI.ParallelElements();
1200 if (bParallel) {
1201 return;
1202 }
1203 const IntAna2d_IntPoint& aIAPnt=aAI.Point(1);
1204 const gp_Pnt2d& aP2D=aIAPnt.Value();
1205 aUx=aP2D.X();
1206}
1207//=======================================================================
1208//function : FindNearParameter
1209//purpose :
1210//=======================================================================
1211Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
1212 const Standard_Real aTx,
1213 const Standard_Integer iDir,
1214 const Standard_Real aTol3D,
1215 Standard_Real& aT1)
1216{
1217 Standard_Boolean bFound;
1218 Standard_Real aX, aY, aZ;
1219 gp_Pnt aPx, aP1;
1220 gp_Vec aVx;
1221 //
1222 aT1=0.;
1223 //
1224 bFound=aALine->D1(aTx, aPx, aVx);
1225 if(!bFound){
1226 return bFound;
1227 }
1228 gp_Dir aDx(aVx);
1229 if (iDir<0) {
1230 aDx.Reverse();
1231 }
1232 aX=aPx.X()+aDx.X()*aTol3D;
1233 aY=aPx.Y()+aDx.Y()*aTol3D;
1234 aZ=aPx.Z()+aDx.Z()*aTol3D;
1235 aP1.SetCoord(aX, aY, aZ);
1236 //
1237 bFound=aALine->FindParameter(aP1, aT1);
1238 //
1239 return bFound;
1240}
1241