0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_0.gxx
CommitLineData
b311480e 1// Created on: 1992-05-07
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1992-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// Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455
18
9b0fb8cd 19#include <IntPatch_ThePathPointOfTheSOnBounds.hxx>
20#include <IntPatch_TheSegmentOfTheSOnBounds.hxx>
21#include <IntPatch_RLine.hxx>
22#include <IntSurf.hxx>
23#include <TColStd_Array1OfInteger.hxx>
24#include <TColStd_SequenceOfReal.hxx>
d4b867e6 25#include <IntPatch_GLine.hxx>
7a91ad6e 26#include <Extrema_ExtPC.hxx>
27#include <GeomAdaptor_Curve.hxx>
d4b867e6 28#include <Geom_Ellipse.hxx>
29#include <Geom_Parabola.hxx>
30#include <Geom_Hyperbola.hxx>
92efcf78 31#include <IntPatch_ALine.hxx>
d4b867e6 32
9b0fb8cd 33
7fd59977 34static void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
35 const Handle(Adaptor3d_HSurface)& S2,
36 const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
37 const IntPatch_SequenceOfLine&,
38 const Standard_Boolean,
39 const Handle(Adaptor3d_TopolTool)&,
40 const IntSurf_Quadric&,
41 const IntSurf_Quadric&,
42 const Standard_Boolean,
43 const Standard_Real);
44
3306fdd9 45static Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
46 const Handle(Adaptor3d_TopolTool)& Domain,
47 const IntSurf_Quadric& QuadSurf,
48 const gp_Vec& Normale,
49 const IntPatch_SequenceOfLine& slin,
50 TColStd_Array1OfInteger& Done,
51 TColStd_Array1OfInteger& UsedLine,
52 const Standard_Integer Index,
53 const Standard_Boolean OnFirst,
54 const Standard_Real theToler);
55
56static Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
57 const Handle(Adaptor3d_TopolTool)& Domain,
58 const IntSurf_Quadric& QuadSurf,
59 const gp_Vec& Normale,
60 const gp_Vec& Vtgint,
61 const Handle(IntPatch_Line)& lin,
62 TColStd_Array1OfInteger& Done,
63 const Standard_Integer Index,
64 const Standard_Real theToler);
7fd59977 65
66static Standard_Boolean SingleLine (const gp_Pnt&,
67 const Handle(IntPatch_Line)&,
68 const Standard_Real,
69 Standard_Real&,
70 gp_Vec&);
71
72
3306fdd9 73static Standard_Boolean FindLine(gp_Pnt& Psurf,
74 const IntPatch_SequenceOfLine& slin,
75 const Standard_Real Tol,
76 TColStd_ListOfReal& theLParams,
77 gp_Vec& Vtgtint,
78 Standard_Integer& theLineIdx,
79 Standard_Integer OnlyThisLine,
80 const Handle(Adaptor2d_HCurve2d)& thearc,
81 Standard_Real& theparameteronarc,
82 gp_Pnt& thepointonarc,
83 const IntSurf_Quadric& QuadSurf1,
84 const IntSurf_Quadric& QuadSurf2,
85 Standard_Real& theOutputToler);
7fd59977 86
87static void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds&,
88 IntPatch_SequenceOfLine&,
89 const IntSurf_Quadric&,
90 const IntSurf_Quadric&,
91 const Standard_Boolean,
92 const Standard_Real);
93
94static void ProcessRLine (IntPatch_SequenceOfLine&,
7fd59977 95 const IntSurf_Quadric&,
96 const IntSurf_Quadric&,
d4b867e6 97 const Standard_Real,
98 const Standard_Boolean theIsReqToKeepRLine);
7fd59977 99
7fd59977 100//-- le calcul de dist est completement faux ds la routine ci dessous a revoir (lbr le 18 nov 97)
101Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
102 const Handle(IntPatch_ALine)& alin,
103 Standard_Real& para,
104 const Handle(Adaptor2d_HCurve2d)& thearc,
105 Standard_Real& _theparameteronarc,
106 gp_Pnt& thepointonarc,
107 const IntSurf_Quadric& QuadSurf,
108 const Standard_Real u0alin,
3306fdd9 109 const Standard_Real u1alin) {
7fd59977 110 Standard_Real dtheta,theta;
0797d9d3 111#ifdef OCCT_DEBUG
7fd59977 112 //Standard_Real u,v,A,B,C,cost,sint,sign;
113#endif
114 //-- recherche bete du point le plus proche de thearc->Value(...)
115 dtheta = (u1alin-u0alin)*0.01;
116 Standard_Real du=0.000000001;
1406e955 117 if (du >= dtheta)
118 du = dtheta/2;
7fd59977 119 Standard_Real distmin = RealLast();
1d47d8d0 120
7fd59977 121 Standard_Real thetamin = 0.;
1d47d8d0 122
7fd59977 123 Standard_Real theparameteronarc = _theparameteronarc;
124 for(Standard_Real _theta=u0alin+dtheta; _theta<=u1alin-dtheta; _theta+=dtheta) {
125 gp_Pnt P=alin->Value(_theta);
126 Standard_Real d=P.Distance(PSurf);
127 if(d<distmin) {
128 thetamin=_theta;
129 distmin=d;
130 }
131 }
1d47d8d0 132
7fd59977 133 Standard_Real bestpara =0., besttheta =0., bestdist =0., distinit =0. ;
1d47d8d0 134
7fd59977 135 //-- Distance initiale
136 {
137 gp_Pnt pp0 = alin->Value(thetamin);
138 Standard_Real ua0,va0;
139 QuadSurf.Parameters(pp0,ua0,va0);
140 gp_Pnt2d p2d;
141 gp_Vec2d d2d;
142 thearc->D1(theparameteronarc,p2d,d2d);
143 gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
144 distinit=PaPr.Magnitude();
145 }
146 theta = thetamin;
147 //-- recherche a partir de theta et theparameteronarc
148 Standard_Boolean cpasok=Standard_True;
149 Standard_Integer nbiter=0;
150 Standard_Real drmax = (thearc->LastParameter() - thearc->FirstParameter())*0.05;
151 Standard_Real damax = (u1alin-u0alin)*0.05;
152
153
154
155 bestdist = RealLast();
156
157 do {
158 Standard_Real ua0,va0,ua1,va1;
159 //-- alin->Curve().InternalUVValue(theta,ua0,va0,A,B,C,cost,sint,sign);
160 //-- alin->Curve().InternalUVValue(theta+du,ua1,va1,A,B,C,cost,sint,sign);
161 gp_Pnt pp0 = alin->Value(theta);
162 gp_Pnt pp1 = alin->Value(theta+du);
163 QuadSurf.Parameters(pp0,ua0,va0);
164 QuadSurf.Parameters(pp1,ua1,va1);
165
166
167 gp_Vec2d D1a((ua1-ua0)/du,(va1-va0)/du);
168 gp_Pnt2d p2d;
169 gp_Vec2d d2d;
170 thearc->D1(theparameteronarc,p2d,d2d);
171 gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
172
173 Standard_Real pbd=PaPr.Magnitude();
174 if(bestdist>pbd) {
175 bestdist = pbd;
176 bestpara = theparameteronarc;
177 besttheta = theta;
178 }
179
180 D1a.SetCoord(-D1a.X(),-D1a.Y());
181
182 Standard_Real d = D1a.X() * d2d.Y() - D1a.Y() * d2d.X();
183
184 Standard_Real da = (-PaPr.X())* d2d.Y() - (-PaPr.Y()) * d2d.X();
185 Standard_Real dr = D1a.X() * (-PaPr.Y()) - D1a.Y() * (-PaPr.X());
186 if(Abs(d)>1e-15) {
187 da/=d;
188 dr/=d;
189 }
190 else {
191 if(Abs(PaPr.X())>Abs(PaPr.Y())) {
192 Standard_Real xx=PaPr.X();
193 xx*=0.5;
194 if(D1a.X()) {
195 da = -xx/D1a.X();
196 }
197 if(d2d.X()) {
198 dr = -xx/d2d.X();
199 }
200 }
201 else {
202 Standard_Real yy=PaPr.Y();
203 yy*=0.5;
204 if(D1a.Y()) {
205 da = -yy/D1a.Y();
206 }
207 if(d2d.Y()) {
208 dr = -yy/d2d.Y();
209 }
210 }
211 }
212//-- Standard_Real da = -PaPr.Dot(D1a);
213//-- Standard_Real dr = -PaPr.Dot(d2d);
214
215 if(da<-damax) da=-damax;
216 else if(da>damax) da=damax;
217 if(dr<-drmax) dr=-drmax;
218 else if(dr>drmax) dr=drmax;
219
220 if(Abs(da)<1e-10 && Abs(dr)<1e-10) {
221 para = theta;
222 PSurf = alin->Value(para);
223 _theparameteronarc=theparameteronarc;
224 thepointonarc = alin->Value(para);
225 cpasok=Standard_False;
226//-- printf("\nt:%d",nbiter);
7fd59977 227 return(Standard_True);
228 }
229 else {
230 theta+=da;
231 theparameteronarc+=dr;
232 if( theparameteronarc>thearc->LastParameter() ) {
233 theparameteronarc = thearc->LastParameter();
234 }
235 if( theparameteronarc<thearc->FirstParameter() ) {
236 theparameteronarc = thearc->FirstParameter();
237 }
238 if( theta < u0alin) {
239 theta = u0alin;
240 }
241 if( theta > u1alin-du) {
242 theta = u1alin-du-du;
243 }
244 }
245 nbiter++;
246 }
247 while(cpasok && nbiter<20);
248 if(bestdist < distinit) {
249 para = besttheta;
250 PSurf = alin->Value(para);
251 _theparameteronarc=bestpara;
252 thepointonarc = alin->Value(para);
253//-- printf("\nT:%d",nbiter);
7fd59977 254 return(Standard_True);
255 }
256//-- printf("\nF:%d",nbiter);
257 return(Standard_False);
258}
259
260
261
262
263
264//-- ======================================================================
265static void Recadre(const Handle(Adaptor3d_HSurface)& myHS1,
266 const Handle(Adaptor3d_HSurface)& myHS2,
267 Standard_Real& u1,
268 Standard_Real& v1,
269 Standard_Real& u2,
270 Standard_Real& v2) {
271 Standard_Real f,l,lmf,fpls2;
272 GeomAbs_SurfaceType typs1 = myHS1->GetType();
273 GeomAbs_SurfaceType typs2 = myHS2->GetType();
274
275 Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
276 switch (typs1) {
277 case GeomAbs_Cylinder:
278 case GeomAbs_Cone:
279 case GeomAbs_Sphere:
280 {
281 myHS1IsUPeriodic = Standard_True;
282 myHS1IsVPeriodic = Standard_False;
283 break;
284 }
285 case GeomAbs_Torus:
286 {
287 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
288 break;
289 }
290 default:
291 {
292 //-- Le cas de biparametrees periodiques est gere en amont
293 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
294 break;
295 }
296 }
297
298 Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
299 switch (typs2) {
300 case GeomAbs_Cylinder:
301 case GeomAbs_Cone:
302 case GeomAbs_Sphere:
303 {
304 myHS2IsUPeriodic = Standard_True;
305 myHS2IsVPeriodic = Standard_False;
306 break;
307 }
308 case GeomAbs_Torus:
309 {
310 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
311 break;
312 }
313 default:
314 {
315 //-- Le cas de biparametrees periodiques est gere en amont
316 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
317 break;
318 }
319 }
320 if(myHS1IsUPeriodic) {
c6541a0c 321 lmf = M_PI+M_PI; //-- myHS1->UPeriod();
7fd59977 322 f = myHS1->FirstUParameter();
323 l = myHS1->LastUParameter();
324 fpls2=0.5*(f+l);
325 while((u1 < f)&&((fpls2-u1) > (u1+lmf-fpls2) )) { u1+=lmf; }
326 while((u1 > l)&&((u1-fpls2) > (fpls2-(u1-lmf)) )) { u1-=lmf; }
327
328 }
329 if(myHS1IsVPeriodic) {
c6541a0c 330 lmf = M_PI+M_PI; //-- myHS1->VPeriod();
7fd59977 331 f = myHS1->FirstVParameter();
332 l = myHS1->LastVParameter();
333 fpls2=0.5*(f+l);
334 while((v1 < f)&&((fpls2-v1) > (v1+lmf-fpls2) )) { v1+=lmf; }
335 while((v1 > l)&&((v1-fpls2) > (fpls2-(v1-lmf)) )) { v1-=lmf; }
336 //-- while(v1 < f) { v1+=lmf; }
337 //-- while(v1 > l) { v1-=lmf; }
338 }
339 if(myHS2IsUPeriodic) {
c6541a0c 340 lmf = M_PI+M_PI; //-- myHS2->UPeriod();
7fd59977 341 f = myHS2->FirstUParameter();
342 l = myHS2->LastUParameter();
343 fpls2=0.5*(f+l);
344 while((u2 < f)&&((fpls2-u2) > (u2+lmf-fpls2) )) { u2+=lmf; }
345 while((u2 > l)&&((u2-fpls2) > (fpls2-(u2-lmf)) )) { u2-=lmf; }
346 //-- while(u2 < f) { u2+=lmf; }
347 //-- while(u2 > l) { u2-=lmf; }
348 }
349 if(myHS2IsVPeriodic) {
c6541a0c 350 lmf = M_PI+M_PI; //-- myHS2->VPeriod();
7fd59977 351 f = myHS2->FirstVParameter();
352 l = myHS2->LastVParameter();
353 fpls2=0.5*(f+l);
354 while((v2 < f)&&((fpls2-v2) > (v2+lmf-fpls2) )) { v2+=lmf; }
355 while((v2 > l)&&((v2-fpls2) > (fpls2-(v2-lmf)) )) { v2-=lmf; }
356 //-- while(v2 < f) { v2+=lmf; }
357 //-- while(v2 > l) { v2-=lmf; }
358 }
359}
360//=======================================================================
361//function : PutPointsOnLine
362//purpose :
363//=======================================================================
364void PutPointsOnLine(const Handle(Adaptor3d_HSurface)& S1,
365 const Handle(Adaptor3d_HSurface)& S2,
366 const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
367 const IntPatch_SequenceOfLine& slin,
368 const Standard_Boolean OnFirst,
369 const Handle(Adaptor3d_TopolTool)& Domain,
370 const IntSurf_Quadric& QuadSurf,
371 const IntSurf_Quadric& OtherQuad,
372 const Standard_Boolean multpoint,
373 const Standard_Real Tolarc) {
374
375 // Traitement des point (de listpnt) de depart. On les replace sur
376 // la ligne d intersection, en leur affectant la transition correcte sur
377 // cette ligne.
378 Standard_Integer nbpnt = listpnt.Length();
379 Standard_Integer nblin=slin.Length();
380
381 if (!slin.Length() || !nbpnt) {
382 return;
383 }
384 //
385 Standard_Integer i,k;
386 Standard_Integer linenumber;
3306fdd9 387 Standard_Real currentparameter,tolerance;
7fd59977 388 Standard_Real U1,V1,U2,V2;
389 Standard_Boolean goon;
390
391
392 gp_Pnt Psurf, ptbid;
393 gp_Vec Normale, Vtgint, Vtgrst;
394
395 gp_Vec d1u,d1v;
396 gp_Pnt2d p2d;
397 gp_Vec2d d2d;
398
399 IntSurf_Transition Transline,Transarc;
400
401 Handle(Adaptor2d_HCurve2d) currentarc;
402 Handle(Adaptor3d_HVertex) vtx,vtxbis;
403
404 IntPatch_Point solpnt;
405 IntPatch_ThePathPointOfTheSOnBounds currentpointonrst;
406 IntPatch_IType TheType;
407
408 TColStd_Array1OfInteger UsedLine(1,nblin);
409 TColStd_Array1OfInteger Done(1,nbpnt);
410 for(i=1;i<=nbpnt;i++) Done(i) = 0; //-- Initialisation a la main
411
412 for (i=1; i<=nbpnt; i++) {
413
414 if (Done(i) != 1) {
415 currentpointonrst = listpnt.Value(i);
416 Psurf = currentpointonrst.Value(); // Point dans l espace
417 tolerance = currentpointonrst.Tolerance();
418
419 // On recherche d abord si on a correspondance avec un "point multiple"
420 UsedLine.Init(0);
421
422 goon = Standard_True;
423 if (multpoint) {
424#if 1
425 Normale = QuadSurf.Normale(Psurf); // Normale a la surface au point
426 currentarc = currentpointonrst.Arc();
427 currentparameter = currentpointonrst.Parameter();
428 currentarc->D1(currentparameter,p2d,d2d);
429 QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
430 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
431#endif
432 goon = MultiplePoint(listpnt,Domain,QuadSurf,Normale,slin,Done, UsedLine,
3306fdd9 433 i, OnFirst, Tolarc);
7fd59977 434 }
435 if (goon) {
3306fdd9 436 Standard_Boolean linefound = Standard_False;
7fd59977 437
438 for(Standard_Integer indiceline = 1; indiceline <=slin.Length(); indiceline++) {
439 if( UsedLine(indiceline) != 0 )
440 continue;
441 linenumber = indiceline;
442
443 //-- Attention , les points peuvent etre deplaces
444 //-- il faut reprendre le point original
445 currentpointonrst = listpnt.Value(i);
446 currentarc = currentpointonrst.Arc();
447 currentparameter = currentpointonrst.Parameter();
448 Psurf = currentpointonrst.Value(); // Point dans l espace
449 tolerance = currentpointonrst.Tolerance();
450 //--
451
452
453 // Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 Begin
454 if (! currentpointonrst.IsNew()) {
455 Handle(Adaptor3d_HVertex) aVtx = currentpointonrst.Vertex();
456 Standard_Real aVtxTol = aVtx->Resolution(currentarc);
457 Standard_Real aTolAng = 0.01*tolerance;
458
459 tolerance = Max(tolerance, aVtxTol);
460
461 gp_Vec aNorm1 = QuadSurf.Normale(Psurf);
462 gp_Vec aNorm2 = OtherQuad.Normale(Psurf);
463 //
464 if (aNorm1.Magnitude()>gp::Resolution() &&
465 aNorm2.Magnitude()>gp::Resolution()) {
466
467 if (aNorm1.IsParallel(aNorm2, aTolAng))
468 tolerance = Sqrt(tolerance);
469 }//
470 }
471 // Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 End
472 gp_Pnt pointonarc;
473 Vtgint.SetCoord(0,0,0);
3306fdd9 474 Standard_Real aVertTol = Tolarc;
475 TColStd_ListOfReal aLParams;
476 linefound = FindLine(Psurf, slin, tolerance, aLParams, Vtgint, linenumber,
477 indiceline, currentarc, currentparameter,
478 pointonarc, QuadSurf, OtherQuad, aVertTol);
7fd59977 479 if (linefound) {
480
481#if 1
482 Normale = QuadSurf.Normale(Psurf); // Normale a la surface au point
483 currentarc = currentpointonrst.Arc();
484 //-- currentparameter = currentpointonrst.Parameter();
485 currentarc->D1(currentparameter,p2d,d2d);
486 QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
487 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
488#endif
489
490
491
492 const Handle(IntPatch_Line)& lin = slin.Value(linenumber);
493 TheType = lin->ArcType();
494
495 if (!OnFirst) { // on cherche la correspondance entre point sur domaine
496 // de la premiere surface et point sur domaine de la
497 // deuxieme surface
498
499 goon = PointOnSecondDom (listpnt, Domain, QuadSurf, Normale,
3306fdd9 500 Vtgint, lin, Done, i, aVertTol);
7fd59977 501 }
502
503 if (goon) {
504 //-- Modification du 4 avril 97 tolerance->Tolarc
505 //-- on replace sur le vertex la tolerance d entree et
506 //-- non la tolerance qui a servi au FindLine
3306fdd9 507 solpnt.SetValue(Psurf, aVertTol, Standard_False);
7fd59977 508
509 U1 = p2d.X(); V1 = p2d.Y();
510 OtherQuad.Parameters(Psurf,U2,V2);
511
512 if (OnFirst) {
513 Recadre(S1,S2,U1,V1,U2,V2);
514 solpnt.SetParameters(U1,V1,U2,V2);
515 }
516 else {
517 Recadre(S1,S2,U2,V2,U1,V1);
518 solpnt.SetParameters(U2,V2,U1,V1);
519 }
7fd59977 520
521 if (! currentpointonrst.IsNew()) {
522 vtx = currentpointonrst.Vertex();
523 solpnt.SetVertex(OnFirst,vtx);
524 }
525 else {
526 //-- goon = Standard_False; ????
527 }
528
529 if(Normale.SquareMagnitude()<1e-16) {
530 Transline.SetValue(Standard_True,IntSurf_Undecided);
531 Transarc.SetValue(Standard_True,IntSurf_Undecided);
532 }
533 else {
534 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
535 }
536 solpnt.SetArc(OnFirst,currentarc, currentparameter,
537 Transline,Transarc);
3306fdd9 538
539 for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
540 anItr.More(); anItr.Next())
541 {
542 solpnt.SetParameter(anItr.Value());
543 if (TheType == IntPatch_Analytic)
544 {
545 Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
546 }
547 else
548 {
549 Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
550 }
551 }
552
7fd59977 553 Done(i) = 1;
554
555 if (goon) {
556 for (k=i+1; k<= nbpnt; k++) {
557 if (Done(k) != 1) {
558 currentpointonrst = listpnt.Value(k);
559 if (!currentpointonrst.IsNew()) {
560 vtxbis = currentpointonrst.Vertex();
561 if(vtx.IsNull()) {
562 }
563 else if (Domain->Identical(vtx, vtxbis)) {
564 solpnt.SetVertex(OnFirst,vtxbis);
3306fdd9 565 solpnt.SetTolerance(Tolarc);
7fd59977 566 currentarc = currentpointonrst.Arc();
567 currentparameter = currentpointonrst.Parameter();
568
569 // currentarc->D1(currentparameter,ptbid,Vtgrst);
570 currentarc->D1(currentparameter,p2d,d2d);
571 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
572 if(Normale.SquareMagnitude()<1e-16) {
573 Transline.SetValue(Standard_True,IntSurf_Undecided);
574 Transarc.SetValue(Standard_True,IntSurf_Undecided);
575 }
576 else {
577 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
578 Transline,Transarc);
579 }
580 solpnt.SetArc(OnFirst,currentarc,currentparameter,
581 Transline,Transarc);
582 if (TheType == IntPatch_Analytic) {
c5f3a425 583 Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(solpnt);
7fd59977 584 }
585 else {
c5f3a425 586 Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(solpnt);
7fd59977 587 }
588 Done(k) = 1;
589 }
590 }
591 }
592 }
593 }
594 }
595 }
596 else {
597 Done(i) = 1; // il faudra tester si IsNew ou pas
598 // et traiter en consequence
599 }
600 }
601 }
602 }
603 }
604}
605
606
607Standard_Boolean MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
608 const Handle(Adaptor3d_TopolTool)& Domain,
609 const IntSurf_Quadric& QuadSurf,
610 const gp_Vec& Normale,
611 const IntPatch_SequenceOfLine& slin,
612 TColStd_Array1OfInteger& Done,
613 TColStd_Array1OfInteger& UsedLine,
614 const Standard_Integer Index,
3306fdd9 615 const Standard_Boolean OnFirst,
616 const Standard_Real theToler) {
7fd59977 617
618// Traitement des points "multiples".
619
620
621 Standard_Integer k,ii,jj,nbvtx;
622 Standard_Integer nblin = slin.Length();
623 IntPatch_IType TheType;
624
625
626 IntSurf_Transition Transline,Transarc;
627
628
629 IntPatch_Point intpt;
630 Handle(Adaptor2d_HCurve2d) currentarc;
631 Handle(Adaptor3d_HVertex) vtx,vtxbis;
632
633 Standard_Integer nbpnt = listpnt.Length();
634 IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
635 IntPatch_ThePathPointOfTheSOnBounds otherpt;
636 gp_Pnt Point = currentpointonrst.Value();
637 TColStd_Array1OfInteger localdone(1,nbpnt); localdone.Init(0);
638 for (ii=1; ii<=nbpnt; ii++) {
639 localdone(ii)=Done(ii);
640 }
641
642 Standard_Real currentparameter;
643 Standard_Real Paraint;
644 gp_Vec Vtgint,Vtgrst;
645 gp_Pnt ptbid;
646
647 gp_Vec d1u,d1v;
648 gp_Pnt2d p2d;
649 gp_Vec2d d2d;
650
651 Standard_Boolean goon;
652
653 Standard_Boolean Retvalue = Standard_True;
654
655 for (ii = 1; ii <= nblin; ii++) {
656 const Handle(IntPatch_Line)& slinValueii = slin.Value(ii);
657 TheType = slinValueii->ArcType();
658 if (TheType == IntPatch_Analytic) {
c5f3a425 659 nbvtx = Handle(IntPatch_ALine)::DownCast (slinValueii)->NbVertex();
7fd59977 660 }
661 else {
c5f3a425 662 nbvtx = Handle(IntPatch_GLine)::DownCast (slinValueii)->NbVertex();
7fd59977 663 }
664 jj = 1;
665 while (jj <= nbvtx) {
666 if (TheType == IntPatch_Analytic) {
c5f3a425 667 intpt = Handle(IntPatch_ALine)::DownCast (slinValueii)->Vertex(jj);
7fd59977 668 }
669 else {
c5f3a425 670 intpt = Handle(IntPatch_GLine)::DownCast (slinValueii)->Vertex(jj);
7fd59977 671 }
672 if (intpt.IsMultiple() &&
673 (( OnFirst && !intpt.IsOnDomS1()) ||
674 (!OnFirst && !intpt.IsOnDomS2()))) {
675 if (Point.Distance(intpt.Value()) <= intpt.Tolerance()) {
676 Retvalue = Standard_False;
677 Standard_Boolean foo = SingleLine(Point,slinValueii,
678 intpt.Tolerance(),Paraint,Vtgint);
679 if (!foo) {
680 return Standard_False; // ne doit pas se produire
681 }
682
683 if (!currentpointonrst.IsNew()) {
684 goon = Standard_True;
685 vtx = currentpointonrst.Vertex();
686 intpt.SetVertex(OnFirst,vtx);
687 }
688 else {
689 goon = Standard_False;
690 }
691 currentarc = currentpointonrst.Arc();
692 currentparameter = currentpointonrst.Parameter();
693 currentarc->D1(currentparameter,p2d,d2d);
694 QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
695 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
696
697 //-- Si la normale est nulle (apex d un cone) On simule une transition UNKNOWN
698 if(Normale.SquareMagnitude()<1e-16) {
699 Transline.SetValue(Standard_True,IntSurf_Undecided);
700 Transarc.SetValue(Standard_True,IntSurf_Undecided);
701 }
702 else {
703 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
704 }
705
706 //-- Avant, on ne mettait pas ce point (17 nov 97)
707 //--printf("\n ImpImp_0 : Point(%g,%g,%g) intpt(%g,%g,%g) \n",
708 //-- Point.X(),Point.Y(),Point.Z(),intpt.Value().X(),intpt.Value().Y(),intpt.Value().Z());
709 intpt.SetValue(Point);
710
711 intpt.SetArc(OnFirst,currentarc,currentparameter,
712 Transline,Transarc);
3306fdd9 713 intpt.SetTolerance(theToler);
7fd59977 714
715 if (TheType == IntPatch_Analytic) {
c5f3a425 716 Handle(IntPatch_ALine)::DownCast (slinValueii)->Replace(jj,intpt);
7fd59977 717 }
718 else {
c5f3a425 719 Handle(IntPatch_GLine)::DownCast (slinValueii)->Replace(jj,intpt);
7fd59977 720 }
721 localdone(Index) = 1;
722 if (goon) {
723 for (k=Index+1; k<= nbpnt; k++) {
724 if (Done(k) != 1) {
725 otherpt= listpnt.Value(k);
726 if (!otherpt.IsNew()) {
727 vtxbis = otherpt.Vertex();
728 if (Domain->Identical(vtx, vtxbis)) {
729 intpt.SetVertex(OnFirst,vtxbis);
730 currentarc = otherpt.Arc();
731 currentparameter = otherpt.Parameter();
732
733 currentarc->D1(currentparameter,p2d,d2d);
734 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
735 if(Normale.SquareMagnitude()<1e-16) {
736 Transline.SetValue(Standard_True,IntSurf_Undecided);
737 Transarc.SetValue(Standard_True,IntSurf_Undecided);
738 }
739 else {
740 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
741 Transline,Transarc);
742 }
743 intpt.SetArc(OnFirst,currentarc,currentparameter,
744 Transline,Transarc);
3306fdd9 745 intpt.SetTolerance(theToler);
7fd59977 746 if (TheType == IntPatch_Analytic) {
c5f3a425 747 Handle(IntPatch_ALine)::DownCast (slinValueii)->AddVertex(intpt);
7fd59977 748 }
749 else {
c5f3a425 750 Handle(IntPatch_GLine)::DownCast (slinValueii)->AddVertex(intpt);
7fd59977 751 }
752 UsedLine(ii) = 1;
753 Retvalue = Standard_True;
754 localdone(k) = 1;
755 }
756 }
757 }
758 }
759 }
760//-- jj = nbvtx +1;
761 }
762//-- else {
763 jj = jj+1;
764//-- }
765 }
766 else {
767 jj = jj+1;
768 }
769 }
770 }
771
772 for (ii=1; ii<=nbpnt;ii++) {
773 Done(ii) = localdone(ii);
774 }
775
776 return Retvalue;
777}
778
779
780
781Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
782 const Handle(Adaptor3d_TopolTool)& Domain,
783 const IntSurf_Quadric& QuadSurf,
784 const gp_Vec& Normale,
785 const gp_Vec& Vtgint,
786 const Handle(IntPatch_Line)& lin,
787 TColStd_Array1OfInteger& Done,
3306fdd9 788 const Standard_Integer Index,
789 const Standard_Real theToler)
7fd59977 790
791
792// Duplication des points sur domaine de l autre surface.
793// On sait que le vertex sous-jacent est PntRef
794
795
796{
797
798 Standard_Integer k,jj,nbvtx;
799 IntPatch_IType TheType;
800
801 IntSurf_Transition Transline,Transarc;
802 IntPatch_Point intpt;
803 Handle(Adaptor2d_HCurve2d) currentarc;
804 Handle(Adaptor3d_HVertex) vtx,vtxbis;
805 gp_Pnt ptbid;
806 gp_Vec Vtgrst;
807
808 gp_Vec d1u,d1v;
809 gp_Pnt2d p2d;
810 gp_Vec2d d2d;
811
812 Standard_Integer nbpnt = listpnt.Length();
813 IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
814 Standard_Real currentparameter;
815
816 Standard_Boolean goon;
817 Standard_Boolean Retvalue = Standard_True;
818
819 TheType = lin->ArcType();
820 if (TheType == IntPatch_Analytic) {
c5f3a425 821 nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
7fd59977 822 }
823 else {
c5f3a425 824 nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
7fd59977 825 }
826 jj = 1;
827 while (jj <= nbvtx) {
828 if (TheType == IntPatch_Analytic) {
c5f3a425 829 intpt = Handle(IntPatch_ALine)::DownCast (lin)->Vertex(jj);
7fd59977 830 }
831 else {
c5f3a425 832 intpt = Handle(IntPatch_GLine)::DownCast (lin)->Vertex(jj);
7fd59977 833 }
834 if (!intpt.IsOnDomS2()) {
835 if (currentpointonrst.Value().Distance(intpt.Value()) <=
836 intpt.Tolerance()) {
837 Retvalue = Standard_False;
838 if (!currentpointonrst.IsNew()) {
839 goon = Standard_True;
840 vtx = currentpointonrst.Vertex();
841 intpt.SetVertex(Standard_False,vtx);
842 }
843 else {
844 goon = Standard_False;
845 }
846 currentarc = currentpointonrst.Arc();
847 currentparameter = currentpointonrst.Parameter();
848 currentarc->D1(currentparameter,p2d,d2d);
849 QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
850 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
851 if(Normale.SquareMagnitude()<1e-16) {
852 Transline.SetValue(Standard_True,IntSurf_Undecided);
853 Transarc.SetValue(Standard_True,IntSurf_Undecided);
854 }
855 else {
856 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
857 }
858 intpt.SetArc(Standard_False,currentarc,currentparameter,
859 Transline,Transarc);
3306fdd9 860 intpt.SetTolerance(theToler);
861
7fd59977 862 if (TheType == IntPatch_Analytic) {
c5f3a425 863 Handle(IntPatch_ALine)::DownCast (lin)->Replace(jj,intpt);
7fd59977 864 }
865 else {
c5f3a425 866 Handle(IntPatch_GLine)::DownCast (lin)->Replace(jj,intpt);
7fd59977 867 }
868 Done(Index) = 1;
869
870 if (goon) {
871 for (k=Index+1; k<= nbpnt; k++) {
872 if (Done(k) != 1) {
873 currentpointonrst = listpnt.Value(k);
874 if (!currentpointonrst.IsNew()) {
875 vtxbis = currentpointonrst.Vertex();
876 if (Domain->Identical(vtx, vtxbis)) {
877 intpt.SetVertex(Standard_False,vtxbis);
878 currentarc = currentpointonrst.Arc();
879 currentparameter = currentpointonrst.Parameter();
880 currentarc->D1(currentparameter,p2d,d2d);
881 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
882 if(Normale.SquareMagnitude()<1e-16) {
883 Transline.SetValue(Standard_True,IntSurf_Undecided);
884 Transarc.SetValue(Standard_True,IntSurf_Undecided);
885 }
886 else {
887 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
888 Transline,Transarc);
889 }
890 intpt.SetArc(Standard_False,currentarc,currentparameter,
891 Transline,Transarc);
3306fdd9 892 intpt.SetTolerance(theToler);
7fd59977 893 if (TheType == IntPatch_Analytic) {
c5f3a425 894 Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(intpt);
7fd59977 895 }
896 else {
c5f3a425 897 Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(intpt);
7fd59977 898 }
899 Done(k) = 1;
900 }
901 }
902 }
903 }
904 }
905 //-- jj = nbvtx + 1;
906 jj++;
907 }
908 else {
909 jj = jj+1;
910 }
911 }
912 else {
913 jj = jj+1;
914 }
915 if (TheType == IntPatch_Analytic) {
c5f3a425 916 nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
7fd59977 917 }
918 else {
c5f3a425 919 nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
7fd59977 920 }
921 }
922 return Retvalue;
923}
924
925
926
3306fdd9 927Standard_Boolean FindLine(gp_Pnt& Psurf,
928 const IntPatch_SequenceOfLine& slin,
929 const Standard_Real Tol,
930 TColStd_ListOfReal& theLParams,
931 gp_Vec& Vtgtint,
932 Standard_Integer& theLineIdx,
933 Standard_Integer OnlyThisLine,
934 const Handle(Adaptor2d_HCurve2d)& thearc,
935 Standard_Real& theparameteronarc,
936 gp_Pnt& thepointonarc,
937 const IntSurf_Quadric& QuadSurf1,
938 const IntSurf_Quadric& QuadSurf2,
939 Standard_Real& theOutputToler)
940{
941 if ((QuadSurf1.Distance(Psurf) > Tol) || (QuadSurf2.Distance(Psurf) > Tol))
942 return Standard_False;
7fd59977 943
944// Traitement du point de depart ayant pour representation Psurf
945// dans l espace. On recherche la ligne d intersection contenant ce point.
946// On a en sortie la ligne, et le parametre et sa tangente du point sur
947// la ligne d intersection.
3306fdd9 948 const Standard_Real aSqTol = Tol*Tol;
949 Standard_Real aSqDistMin = RealLast();
950 Standard_Real aSqDist, para;
7fd59977 951 Standard_Real lower,upper;
952 gp_Pnt pt;
953 Standard_Integer i;
954 IntPatch_IType typarc;
955
3306fdd9 956 Standard_Real aParaInt = RealLast();
7fd59977 957 Standard_Integer nblin = slin.Length();
958 for (i=1; i<=nblin; i++) {
959 if(OnlyThisLine) { i=OnlyThisLine; nblin=0; }
960 const Handle(IntPatch_Line)& lin = slin.Value(i);
961 typarc = lin->ArcType();
962 if (typarc == IntPatch_Analytic) {
963 Standard_Boolean foo;
c5f3a425 964 lower = Handle(IntPatch_ALine)::DownCast (lin)->FirstParameter(foo);
965 upper = Handle(IntPatch_ALine)::DownCast (lin)->LastParameter(foo);
7fd59977 966 }
967 else {
c5f3a425 968 if (Handle(IntPatch_GLine)::DownCast (lin)->HasFirstPoint()) {
969 lower = Handle(IntPatch_GLine)::DownCast (lin)->FirstPoint().ParameterOnLine();
7fd59977 970 }
971 else {
972 lower = RealFirst();
973 }
c5f3a425 974 if (Handle(IntPatch_GLine)::DownCast (lin)->HasLastPoint()) {
975 upper = Handle(IntPatch_GLine)::DownCast (lin)->LastPoint().ParameterOnLine();
7fd59977 976 }
977 else {
978 upper = RealLast();
979 }
980 }
981
982 switch (typarc) {
983 case IntPatch_Lin :
984 {
c5f3a425 985 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
7fd59977 986 if (para <= upper && para >= lower) {
c5f3a425 987 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Line());
3306fdd9 988 aSqDist = Psurf.SquareDistance(pt);
989 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
990 {
991 aSqDistMin = aSqDist;
992 aParaInt = para;
993 theLineIdx = i;
7fd59977 994 }
995 }
996 }
997 break;
998 case IntPatch_Circle :
999 {
c5f3a425 1000 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
7fd59977 1001 if ((para <= upper && para >= lower) ||
c6541a0c
D
1002 (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
1003 (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
c5f3a425 1004 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Circle());
3306fdd9 1005 aSqDist = Psurf.SquareDistance(pt);
1006 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1007 {
1008 aSqDistMin = aSqDist;
1009 aParaInt = para;
1010 theLineIdx = i;
7fd59977 1011 }
1012 }
1013 }
1014 break;
1015 case IntPatch_Ellipse :
1016 {
c5f3a425 1017 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
7fd59977 1018 if ((para <= upper && para >= lower) ||
c6541a0c
D
1019 (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
1020 (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
c5f3a425 1021 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse());
3306fdd9 1022 aSqDist = Psurf.SquareDistance(pt);
1023 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1024 {
1025 aSqDistMin = aSqDist;
1026 aParaInt = para;
1027 theLineIdx = i;
7fd59977 1028 }
1029 }
1030 }
1031 break;
1032 case IntPatch_Parabola :
1033 {
1034
1035#if 0
c5f3a425 1036 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
7fd59977 1037 if (para <= upper && para >= lower) {
c5f3a425 1038 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Parabola());
7fd59977 1039 dist = Psurf.Distance(pt);
1040 if (dist< distmin) {
1041 distmin = dist;
1042 Paraint = para;
1043 Range = i;
1044 }
1045 }
1046#else
1047 //-- Le calcul du parametre sur une parabole est mal fait ds ElCLib. Il ne tient pas compte
1048 //-- de la meilleure facon de calculer (axe X ou axe Y). Bilan : Si la parabole est tres
1049 //-- pointue (focal de l'ordre de 1e-2 et si le point est a un parametre grand, ca foire. )
1050 //-- On ne peut pas modifier faciolement ds ElCLib car on ne passe pas la focale. ...
c5f3a425 1051 const gp_Parab& Parab=Handle(IntPatch_GLine)::DownCast (lin)->Parabola();
7fd59977 1052 para = ElCLib::Parameter(Parab,Psurf);
1053 if (para <= upper && para >= lower) {
1054 Standard_Integer amelioration=0;
1055 //-- cout<<"\n ****** \n";
1056 do {
1057 Standard_Real parabis = para+0.0000001;
1058
1059 pt = ElCLib::Value(para,Parab);
3306fdd9 1060 aSqDist = Psurf.SquareDistance(pt);
7fd59977 1061
3306fdd9 1062 const gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
1063 const Standard_Real distbis = Psurf.Distance(ptbis);
1064 const Standard_Real aDist = Sqrt(aSqDist);
1065 const Standard_Real ddist = distbis - aDist;
7fd59977 1066
1067 //--cout<<" para: "<<para<<" dist:"<<dist<<" ddist:"<<ddist<<endl;
1068
3306fdd9 1069 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1070 {
1071 aSqDistMin = aSqDist;
1072 aParaInt = para;
1073 theLineIdx = i;
7fd59977 1074 }
3306fdd9 1075 if (aSqDist < Precision::SquarePConfusion())
1076 {
1077 amelioration = 100;
1078 }
7fd59977 1079
1080 if(ddist>1.0e-9 || ddist<-1.0e-9 ) {
3306fdd9 1081 para = para - aDist*(parabis - para) / ddist;
7fd59977 1082 }
1083 else {
1084 amelioration=100;
1085 }
1086 }
1087 while(++amelioration < 5);
1088 }
1089
1090
1091#endif
1092 }
1093 break;
1094 case IntPatch_Hyperbola :
1095 {
c5f3a425 1096 para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
7fd59977 1097 if (para <= upper && para >= lower) {
c5f3a425 1098 pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola());
3306fdd9 1099 aSqDist = Psurf.SquareDistance(pt);
1100 if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1101 {
1102 aSqDistMin = aSqDist;
1103 aParaInt = para;
1104 theLineIdx = i;
7fd59977 1105 }
1106 }
1107 }
1108 break;
1109
1110 case IntPatch_Analytic :
1111 {
3306fdd9 1112 Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
1113 TColStd_ListOfReal aLParams;
1114 alin->FindParameter(Psurf, aLParams);
1115 if (!aLParams.IsEmpty())
1116 {
1117 // All found distances are already in some internal tolerance
1118 // set in alin->FindParameter(...) method.
1119
1120 aSqDist = RealLast();
1121 for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
1122 anItr.More(); anItr.Next())
1123 {
1124 pt = alin->Value(anItr.Value());
1125 const Standard_Real aSqD = Psurf.SquareDistance(pt);
1126 if (aSqD < aSqDist)
1127 {
1128 aSqDist = aSqD;
1129 }
1130 }
1131
1132 if (aSqDist < aSqDistMin)
1133 {
1134 aSqDistMin = aSqDist;
1135 theLParams = aLParams;
1136 theLineIdx = i;
1137 }
1138 }
7fd59977 1139 else {
1140 //-- le point n a pas ete trouve par bete projection.
1141 //-- on essaie l intersection avec la restriction en 2d
1142 Standard_Real theparamonarc = theparameteronarc;
0797d9d3 1143//#ifdef OCCT_DEBUG
6e6cd5d9 1144// Standard_Real anpara=para;
1145//#endif
7fd59977 1146 gp_Pnt CopiePsurf=Psurf;
3306fdd9 1147 Standard_Boolean IntersectIsOk = IntersectionWithAnArc(CopiePsurf, alin, para,
1148 thearc, theparamonarc,
1149 thepointonarc,
1150 QuadSurf1,
1151 lower, upper);
1152 aSqDist = CopiePsurf.SquareDistance(Psurf);
51740958 1153 if(IntersectIsOk) {
3306fdd9 1154 if (aSqDist < aSqTol)
1155 {
7fd59977 1156 theparameteronarc = theparamonarc;
1157 Psurf = thepointonarc;
3306fdd9 1158 aSqDistMin = aSqDist;
1159 theLParams.Append(para);
1160 theLineIdx = i;
7fd59977 1161 }
1162 }
1163 }
1164 }
1165 break;
1166
1167 case IntPatch_Walking: // impossible . c est pour eviter les warnings
1168 {
1169 }
1170 case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1171 {
1172 }
1173 }
1174 }
1175
3306fdd9 1176 if (aSqDistMin == RealLast())
7fd59977 1177 return Standard_False;
7fd59977 1178
3306fdd9 1179 theOutputToler = Max(theOutputToler, Sqrt(aSqDistMin));
1180
1181 typarc = slin.Value(theLineIdx)->ArcType();
7fd59977 1182
3306fdd9 1183 // Computation of tangent vector
7fd59977 1184 switch (typarc) {
1185 case IntPatch_Lin :
3306fdd9 1186 theLParams.Append(aParaInt);
1187 Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Line().Direction();
7fd59977 1188 break;
1189 case IntPatch_Circle :
3306fdd9 1190 theLParams.Append(aParaInt);
1191 Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Circle(), 1);
7fd59977 1192 break;
1193 case IntPatch_Ellipse :
3306fdd9 1194 theLParams.Append(aParaInt);
1195 Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Ellipse(), 1);
7fd59977 1196 break;
1197 case IntPatch_Parabola :
3306fdd9 1198 theLParams.Append(aParaInt);
1199 Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Parabola(), 1);
7fd59977 1200 break;
1201 case IntPatch_Hyperbola :
3306fdd9 1202 theLParams.Append(aParaInt);
1203 Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Hyperbola(), 1);
7fd59977 1204 break;
1205
1206 case IntPatch_Analytic:
1207 {
3306fdd9 1208 if (!Handle(IntPatch_ALine)::DownCast(slin(theLineIdx))->D1(theLParams.Last(), pt, Vtgtint))
1209 {
1210 //Previously (before the fix #29807) this code tried to process case
1211 //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
1212 //computed Vtgtint input argument value. Currently, any singularities
1213 //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
1214 //Therefore this code has been deleted as deprecated.
1215
1216 Vtgtint.SetCoord(0.0, 0.0, 0.0);
7fd59977 1217 }
1218 }
1219 break;
1220 case IntPatch_Walking: // impossible . c est pour eviter les warnings
1221 {
1222 }
1223 case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1224 {
1225 }
1226
1227 }
1228 return Standard_True;
1229}
1230
3306fdd9 1231//=======================================================================
1232//function : SingleLine
1233//purpose : Traitement du point de depart ayant pour representation Psurf
1234// dans l espace. On le replace sur la ligne d intersection; On a en sortie
1235// son parametre et sa tangente sur la ligne d intersection.
1236// La fonction renvoie False si le point projete est a une distance
1237// superieure a Tol du point a projeter.
1238//=======================================================================
1239Standard_Boolean SingleLine(const gp_Pnt& Psurf,
1240 const Handle(IntPatch_Line)& lin,
1241 const Standard_Real Tol,
1242 Standard_Real& Paraint,
1243 gp_Vec& Vtgtint)
1244{
7fd59977 1245 IntPatch_IType typarc = lin->ArcType();
1246
1d47d8d0 1247 Standard_Real parproj = 0.;
7fd59977 1248 gp_Vec tgint;
1249 gp_Pnt ptproj;
1250 Standard_Boolean retvalue;
1251
7fd59977 1252 switch (typarc) {
1253 case IntPatch_Lin :
c5f3a425 1254 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
1255 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Line(),ptproj,tgint);
7fd59977 1256 break;
1257 case IntPatch_Circle :
c5f3a425 1258 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
1259 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Circle(),ptproj,tgint);
7fd59977 1260 break;
1261 case IntPatch_Ellipse :
c5f3a425 1262 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
1263 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),ptproj,tgint);
7fd59977 1264 break;
1265 case IntPatch_Parabola :
c5f3a425 1266 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
1267 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),ptproj,tgint);
7fd59977 1268 break;
1269 case IntPatch_Hyperbola :
c5f3a425 1270 parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
1271 ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),ptproj,tgint);
7fd59977 1272 break;
1273 case IntPatch_Analytic :
1274 {
3306fdd9 1275 Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
1276 TColStd_ListOfReal aLParams;
1277 alin->FindParameter(Psurf, aLParams);
1278 if (!aLParams.IsEmpty())
1279 {
1280 ptproj = Psurf;
1281 parproj = aLParams.Last();
1282 gp_Pnt aPtemp;
1283 if (!alin->D1(parproj, aPtemp, tgint))
1284 {
1285 //Previously (before the fix #29807) this code tried to process case
1286 //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
1287 //computed Vtgtint input argument value. Currently, any singularities
1288 //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
1289 //Therefore this code has been deleted as deprecated.
1290
1291 tgint.SetCoord(0.0, 0.0, 0.0);
1292 }
7fd59977 1293 }
3306fdd9 1294 else
1295 {
1296 //-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
1297 //-- cout << " Find Parameter"<<endl;
1298 return Standard_False;
7fd59977 1299 }
1300 }
1301 break;
1302 case IntPatch_Walking: // impossible . c est pour eviter les warnings
1303 {
1304 }
1305 case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1306 {
1307 }
1308 }
1309
1310 if (Psurf.Distance(ptproj) <= Tol) {
1311 Paraint = parproj;
1312 Vtgtint = tgint;
1313 retvalue = Standard_True;
1314 }
1315 else {
1316 retvalue = Standard_False;
1317 }
1318 return retvalue;
1319}
1320
1321
1322void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
1323 IntPatch_SequenceOfLine& slin,
1324 const IntSurf_Quadric& Quad1,
1325 const IntSurf_Quadric& Quad2,
1326 const Standard_Boolean OnFirst,
1327 const Standard_Real TolArc) {
1328
1329 Standard_Integer i,j,k;
1330 Standard_Integer nbedg = listedg.Length();
1331 Standard_Integer Nblines,Nbpts;
1332
1333 Handle(Adaptor2d_HCurve2d) arcRef;
1334 IntPatch_Point ptvtx, newptvtx;
1335
1336 Handle(IntPatch_RLine) rline; //-- On fait rline = new ... par la suite
1337
1338 IntPatch_TheSegmentOfTheSOnBounds thesegsol;
1339 IntPatch_ThePathPointOfTheSOnBounds PStartf,PStartl;
1340 Standard_Boolean dofirst,dolast,procf,procl;
1d47d8d0 1341
7fd59977 1342 Standard_Real paramf =0.,paraml =0.,U1 =0.,V1 =0.,U2 =0.,V2 =0.;
1d47d8d0 1343
7fd59977 1344 IntPatch_IType typ;
1345 IntSurf_TypeTrans trans1,trans2;
1346 IntSurf_Transition TRest,TArc;
1347 gp_Vec tgline,norm1,norm2,tgarc;
1348 gp_Pnt valpt;
1349
1350 gp_Vec d1u,d1v;
1351 gp_Pnt2d p2d;
1352 gp_Vec2d d2d;
1353
1354
1355 for (i = 1; i <= nbedg; i++) {
1356 Standard_Boolean EdgeDegenere=Standard_False;
1357 thesegsol = listedg.Value(i);
1358 arcRef = thesegsol.Curve();
1359
1360
1361 rline = new IntPatch_RLine(Standard_False);
1362 if(OnFirst) {
1363 rline->SetArcOnS1(arcRef);
1364 }
1365 else {
1366 rline->SetArcOnS2(arcRef);
1367 }
1368
1369// Traitement des points debut/fin du segment solution.
1370
1371 dofirst = Standard_False;
1372 dolast = Standard_False;
1373 procf = Standard_False;
1374 procl = Standard_False;
1375
1376 if (thesegsol.HasFirstPoint()) {
1377 dofirst = Standard_True;
1378 PStartf = thesegsol.FirstPoint();
1379 paramf = PStartf.Parameter();
1380 }
1381 if (thesegsol.HasLastPoint()) {
1382 dolast = Standard_True;
1383 PStartl = thesegsol.LastPoint();
1384 paraml = PStartl.Parameter();
1385 }
1386
1387 if (dofirst && dolast) { // determination de la transition de la ligne
1388 arcRef->D1(0.5*(paramf+paraml),p2d,d2d);
1389 if (OnFirst) {
1390 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1391 }
1392 else {
1393 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1394 }
1395 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1396
1397 if(d1u.Magnitude()<1e-7) { //-- edge degenere ?
1398 EdgeDegenere=Standard_True;
1399 for(Standard_Integer edg=0;edg<=10;edg++) {
1400 arcRef->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
1401 if (OnFirst) {
1402 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1403 }
1404 else {
1405 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1406 }
1407
1408 if(d1u.Magnitude()>1e-7) {
1409 EdgeDegenere=Standard_False;
1410 }
1411 }
1412 rline = new IntPatch_RLine(Standard_False);
1413 if(OnFirst) {
1414 rline->SetArcOnS1(arcRef);
1415 }
1416 else {
1417 rline->SetArcOnS2(arcRef);
1418 }
1419 }
1420 else {
1421 norm2 = Quad2.Normale(valpt);
1422 norm1 = Quad1.Normale(valpt);
1423
1424 if (tgline.DotCross(norm2,norm1) > 0.000000001) {
1425 trans1 = IntSurf_Out;
1426 trans2 = IntSurf_In;
1427 }
1428 else if (tgline.DotCross(norm2,norm1) < -0.000000001){
1429 trans1 = IntSurf_In;
1430 trans2 = IntSurf_Out;
1431 }
1432 else {
1433 trans1 = trans2 = IntSurf_Undecided;
1434 }
1435 rline = new IntPatch_RLine(Standard_False,trans1,trans2);
1436 if(OnFirst) {
1437 rline->SetArcOnS1(arcRef);
1438 }
1439 else {
1440 rline->SetArcOnS2(arcRef);
1441 }
1442 }
1443 }
1444 else {
1445 rline = new IntPatch_RLine(Standard_False);
1446 if(OnFirst) {
1447 rline->SetArcOnS1(arcRef);
1448 }
1449 else {
1450 rline->SetArcOnS2(arcRef);
1451 }
1452 }
1453
1454 if (dofirst || dolast) {
1455 Nblines = slin.Length();
1456 for (j=1; j<=Nblines; j++) {
1457 const Handle(IntPatch_Line)& slinj = slin(j);
1458 typ = slinj->ArcType();
1459 if (typ == IntPatch_Analytic) {
c5f3a425 1460 Nbpts = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
7fd59977 1461 }
1462 else if (typ == IntPatch_Restriction) {
c5f3a425 1463 Nbpts = Handle(IntPatch_RLine)::DownCast (slinj)->NbVertex();
7fd59977 1464 }
1465 else {
c5f3a425 1466 Nbpts = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
7fd59977 1467 }
1468 for (k=1; k<=Nbpts;k++) {
1469 if (typ == IntPatch_Analytic) {
c5f3a425 1470 ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
7fd59977 1471 }
1472 else if (typ == IntPatch_Restriction) {
c5f3a425 1473 ptvtx = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
7fd59977 1474 }
1475 else {
c5f3a425 1476 ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
7fd59977 1477 }
1478
1479 if (EdgeDegenere==Standard_False && dofirst) {
1480 if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
1481 ptvtx.SetMultiple(Standard_True);
3306fdd9 1482 ptvtx.SetTolerance(TolArc);
7fd59977 1483 if (typ == IntPatch_Analytic) {
c5f3a425 1484 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
7fd59977 1485 }
1486 else if (typ == IntPatch_Restriction) {
c5f3a425 1487 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
7fd59977 1488 }
1489 else {
c5f3a425 1490 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
7fd59977 1491 }
1492 newptvtx = ptvtx;
1493 newptvtx.SetParameter(paramf);
1494 //Recalcul des transitions si point sur restriction
1495
1496 arcRef->D1(paramf,p2d,d2d);
1497 if (OnFirst) {
1498 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1499 }
1500 else {
1501 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1502 }
1503 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1504 if (ptvtx.IsOnDomS1()) {
1505 const Handle(Adaptor2d_HCurve2d)& thearc = ptvtx.ArcOnS1();
1506 thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
1507 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1508 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1509 norm1 = d1u.Crossed(d1v);
1510 if(norm1.SquareMagnitude()<1e-16) {
1511 TRest.SetValue(Standard_True,IntSurf_Undecided);
1512 TArc.SetValue(Standard_True,IntSurf_Undecided);
1513 }
1514 else {
1515 IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
1516 }
1517 newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
1518 TRest,TArc);
1519 }
1520 if (ptvtx.IsOnDomS2()) {
1521 const Handle(Adaptor2d_HCurve2d)& thearc = ptvtx.ArcOnS2();
1522 thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
1523 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1524 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1525 norm2 = d1u.Crossed(d1v);
1526 if(norm2.SquareMagnitude()<1e-16) {
1527 TRest.SetValue(Standard_True,IntSurf_Undecided);
1528 TArc.SetValue(Standard_True,IntSurf_Undecided);
1529 }
1530 else {
1531 IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
1532 }
1533 newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
1534 TRest,TArc);
1535 }
1536
1537 rline->AddVertex(newptvtx);
1538 if (!procf){
1539 procf=Standard_True;
1540 rline->SetFirstPoint(rline->NbVertex());
1541 }
1542 }
1543 }
1544 if (EdgeDegenere==Standard_False && dolast) {
1545 if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
1546 ptvtx.SetMultiple(Standard_True);
3306fdd9 1547 ptvtx.SetTolerance(TolArc);
7fd59977 1548 if (typ == IntPatch_Analytic) {
c5f3a425 1549 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
7fd59977 1550 }
1551 else if (typ == IntPatch_Restriction) {
c5f3a425 1552 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
7fd59977 1553 }
1554 else {
c5f3a425 1555 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
7fd59977 1556 }
1557
1558 newptvtx = ptvtx;
1559 newptvtx.SetParameter(paraml);
1560 //Recalcul des transitions si point sur restriction
1561
1562 arcRef->D1(paraml,p2d,d2d);
1563 if (OnFirst) {
1564 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1565 }
1566 else {
1567 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1568 }
1569 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1570 if (ptvtx.IsOnDomS1()) {
1571 const Handle(Adaptor2d_HCurve2d)& thearc = ptvtx.ArcOnS1();
1572 thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
1573 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1574 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1575 norm1 = d1u.Crossed(d1v);
1576 if(norm1.SquareMagnitude()<1e-16) {
1577 TRest.SetValue(Standard_True,IntSurf_Undecided);
1578 TArc.SetValue(Standard_True,IntSurf_Undecided);
1579 }
1580 else {
1581 IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
1582 }
1583 newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
1584 TRest,TArc);
1585 }
1586 if (ptvtx.IsOnDomS2()) {
1587 const Handle(Adaptor2d_HCurve2d)& thearc = ptvtx.ArcOnS2();
1588 thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
1589 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1590 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1591 norm2 = d1u.Crossed(d1v);
1592 if(norm2.SquareMagnitude()<1e-16) {
1593 TRest.SetValue(Standard_True,IntSurf_Undecided);
1594 TArc.SetValue(Standard_True,IntSurf_Undecided);
1595 }
1596 else {
1597 IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
1598 }
1599 newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
1600 TRest,TArc);
1601 }
1602
1603 rline->AddVertex(newptvtx);
1604 if (!procl){
1605 procl=Standard_True;
1606 rline->SetLastPoint(rline->NbVertex());
1607 }
1608 }
1609 }
1610 }
1611// Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
1612// il (ils) correspond(ent) a un point multiple.
1613
1614 if (procf) {
1615 dofirst = Standard_False;
1616 }
1617 if (procl) {
1618 dolast = Standard_False;
1619 }
1620 }
1621 }
1622// Si on n a pas trouve le point debut et./ou fin sur une des lignes
1623// d intersection, il faut quand-meme le placer sur la restriction solution
1624
1625 if (dofirst) {
1626 ptvtx.SetValue(PStartf.Value(),PStartf.Tolerance(),Standard_False);
1627 Quad1.Parameters(PStartf.Value(),U1,V1);
1628 Quad2.Parameters(PStartf.Value(),U2,V2);
1629 ptvtx.SetParameters(U1,V1,U2,V2);
1630 ptvtx.SetParameter(paramf);
1631 if (! PStartf.IsNew()) {
1632 IntSurf_Transition Transline;
1633 IntSurf_Transition Transarc;
1634 ptvtx.SetVertex(OnFirst,PStartf.Vertex());
1635 ptvtx.SetArc(OnFirst,PStartf.Arc(),PStartf.Parameter(),
1636 Transline,Transarc);
1637 }
1638
1639 rline->AddVertex(ptvtx);
1640 rline->SetFirstPoint(rline->NbVertex());
1641 }
1642 if (dolast) {
1643 ptvtx.SetValue(PStartl.Value(),PStartl.Tolerance(),Standard_False);
1644 Quad1.Parameters(PStartl.Value(),U1,V1);
1645 Quad2.Parameters(PStartl.Value(),U2,V2);
1646 ptvtx.SetParameters(U1,V1,U2,V2);
1647 ptvtx.SetParameter(paraml);
1648 if (! PStartl.IsNew()) {
1649 IntSurf_Transition Transline;
1650 IntSurf_Transition Transarc;
1651
1652 ptvtx.SetVertex(OnFirst,PStartl.Vertex());
1653 ptvtx.SetArc(OnFirst,PStartl.Arc(),PStartl.Parameter(),
1654 Transline,Transarc);
1655 }
1656
1657 rline->AddVertex(ptvtx);
1658 rline->SetLastPoint(rline->NbVertex());
1659 }
1660 slin.Append(rline);
1661 }
1662}
1663
d4b867e6 1664inline const gp_Pnt& PointValue(const Handle(IntPatch_RLine) theRLine,
1665 const Standard_Integer theIndex)
1666{
1667 return theRLine->Point(theIndex).Value();
1668}
1669
1670inline const gp_Pnt& VertexValue( const Handle(IntPatch_RLine) theRLine,
1671 const Standard_Integer theIndex)
1672{
1673 return theRLine->Vertex(theIndex).Value();
1674}
1675
7a91ad6e 1676static Standard_Real SquareDistance(const Handle(IntPatch_GLine)& theGLine,
d4b867e6 1677 const gp_Pnt& theP,
7a91ad6e 1678 Extrema_ExtPC& theExtr)
d4b867e6 1679{
1680 Standard_Real aSQDist = RealLast();
1681 switch(theGLine->ArcType())
1682 {
1683 case IntPatch_Lin:
1684 aSQDist = theGLine->Line().SquareDistance(theP);
1685 break;
1686 case IntPatch_Circle:
1687 aSQDist = theGLine->Circle().SquareDistance(theP);
1688 break;
1689 default:
7a91ad6e 1690 theExtr.Perform(theP);
1691 if(!theExtr.IsDone() || !theExtr.NbExt())
d4b867e6 1692 {
1693 //Lines are not overlapped
1694 return aSQDist;
1695 }
1696
7a91ad6e 1697 aSQDist = theExtr.SquareDistance(1);
1698 const Standard_Integer aNbExtr = theExtr.NbExt();
1699 for ( Standard_Integer i = 2; i <= aNbExtr; i++)
1700 {
1701 const Standard_Real aSQD = theExtr.SquareDistance(i);
1702 if (aSQD < aSQDist)
1703 {
1704 aSQDist = aSQD;
1705 }
1706 }
d4b867e6 1707 }
1708
1709 return aSQDist;
1710}
1711
1712static Standard_Boolean IsRLineGood(const IntSurf_Quadric& Quad1,
1713 const IntSurf_Quadric& Quad2,
1714 const Handle(IntPatch_GLine) theGLine,
1715 const Handle(IntPatch_RLine) theRLine,
1716 const Standard_Real theTol)
1717{
1718 const Standard_Real aSQTol = theTol*theTol;
1719 const IntPatch_IType aGType = theGLine->ArcType();
1720 Standard_Integer aNbPntsM1 = 0;
1721
1722 const gp_Pnt& (*Value) (const Handle(IntPatch_RLine), const Standard_Integer);
1723
1724 if(theRLine->HasPolygon())
1725 {
1726 aNbPntsM1 = theRLine->NbPnts()-1;
1727 Value = PointValue;
1728 }
1729 else
1730 {
1731 aNbPntsM1 = theRLine->NbVertex()-1;
1732 Value = VertexValue;
1733 }
1734
1735 if(aNbPntsM1 < 1)
1736 return Standard_False;
1737
7a91ad6e 1738 Extrema_ExtPC anExtr;
1739 GeomAdaptor_Curve anAC;
d4b867e6 1740 Handle(Geom_Curve) aCurv;
7a91ad6e 1741
d4b867e6 1742 if(aGType == IntPatch_Ellipse)
1743 aCurv = new Geom_Ellipse(theGLine->Ellipse());
1744 else if(aGType == IntPatch_Parabola)
1745 aCurv = new Geom_Parabola(theGLine->Parabola());
1746 else if(aGType == IntPatch_Hyperbola)
1747 aCurv = new Geom_Hyperbola(theGLine->Hyperbola());
1748
1749 if(!aCurv.IsNull())
7a91ad6e 1750 {
1751 const Standard_Real anUinf = aCurv->FirstParameter(),
1752 anUsup = aCurv->LastParameter();
1753 anAC.Load(aCurv, anUinf, anUsup);
1754 anExtr.Initialize(anAC, anUinf, anUsup);
1755 }
d4b867e6 1756
1757 if(aNbPntsM1 == 1)
1758 {
1759 gp_Pnt aP1(Value(theRLine, 1)), aP2(Value(theRLine, 2));
1760
1761 if(aP1.SquareDistance(aP2) < aSQTol)
1762 {
1763 //RLine is degenerated
1764 return Standard_False;
1765 }
1766
1767 gp_Pnt aPMid;
1768 if(theRLine->IsArcOnS1())
1769 {
1770 const Handle(Adaptor2d_HCurve2d)& anAC2d = theRLine->ArcOnS1();
1771 const Standard_Real aParF = anAC2d->FirstParameter(),
1772 aParL = anAC2d->LastParameter();
1773 gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
1774 aPMid = Quad1.Value(aP2d.X(), aP2d.Y());
1775 }
1776 else
1777 {
1778 const Handle(Adaptor2d_HCurve2d)& anAC2d = theRLine->ArcOnS2();
1779 const Standard_Real aParF = anAC2d->FirstParameter(),
1780 aParL = anAC2d->LastParameter();
1781 gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
1782 aPMid = Quad2.Value(aP2d.X(), aP2d.Y());
1783 }
1784
7a91ad6e 1785 const Standard_Real aSQDist = SquareDistance(theGLine, aPMid, anExtr);
d4b867e6 1786 return (aSQDist > aSQTol);
1787 }
1788
1789 for(Standard_Integer i = 2; i <= aNbPntsM1; i++)
1790 {
1791 const gp_Pnt aP(Value(theRLine, i));
7a91ad6e 1792 const Standard_Real aSQDist = SquareDistance(theGLine, aP, anExtr);
d4b867e6 1793
1794 if(aSQDist > aSQTol)
1795 return Standard_True;
1796 }
1797
1798 return Standard_False;
1799}
1800
7fd59977 1801
1802void ProcessRLine (IntPatch_SequenceOfLine& slin,
1803// const Handle(Adaptor3d_HSurface)& Surf1,
1804// const Handle(Adaptor3d_HSurface)& Surf2,
1805 const IntSurf_Quadric& Quad1,
1806 const IntSurf_Quadric& Quad2,
d4b867e6 1807 const Standard_Real _TolArc,
1808 const Standard_Boolean theIsReqToKeepRLine) {
7fd59977 1809
1810// On cherche a placer sur les restrictions solutions les points "multiples"
1811// des autres lignes d intersection
1812// Pas forcemment le plus efficace : on rique de projeter plusieurs fois
1813// le meme point sur la meme restriction...
1814
1815 Standard_Real TolArc=100.0*_TolArc;
1816 if(TolArc>0.1) TolArc=0.1;
1817
1818 Standard_Integer i,j,k;
1819 Standard_Integer Nblin,Nbvtx, Nbpt;
1d47d8d0 1820
7fd59977 1821 Standard_Boolean OnFirst = Standard_False,project = Standard_False,keeppoint = Standard_False;
1d47d8d0 1822
7fd59977 1823 Handle(Adaptor2d_HCurve2d) arcref;
1824 Standard_Real paramproj,paramf,paraml;
1825
1826 TColgp_SequenceOfPnt seq_Pnt3d;
1827 TColStd_SequenceOfReal seq_Real;
1828
1829 gp_Pnt ptproj,toproj,valpt;
1830
1831 gp_Pnt2d p2d;
1832 gp_Vec2d d2d;
1833 gp_Vec d1u,d1v,tgrest,tgarc,norm;
1834 IntSurf_Transition TRest,TArc;
0797d9d3 1835#ifndef OCCT_DEBUG
7fd59977 1836 Standard_Real U =0.,V =0.;
1837#else
1838 Standard_Real U,V;
1839#endif
1840 IntPatch_Point Ptvtx,newptvtx;
1841
1842 IntPatch_IType typ1,typ2;
1843
1844
1845 Nblin = slin.Length();
1846 for (i=1; i<=Nblin; i++) {
1847 const Handle(IntPatch_Line)& slini = slin(i);
1848 typ1 = slini->ArcType();
d4b867e6 1849
1850 Standard_Boolean HasToDeleteRLine = Standard_False;
7fd59977 1851 if (typ1 == IntPatch_Restriction) {
1852 seq_Pnt3d.Clear();
1853 seq_Real.Clear();
d4b867e6 1854
7fd59977 1855 for (j=1; j<=Nblin; j++) {
1856 const Handle(IntPatch_Line)& slinj = slin(j);
1857 Nbpt = seq_Pnt3d.Length(); // important que ce soit ici
1858 typ2 = slinj->ArcType();
1859 if (typ2 != IntPatch_Restriction) {
c5f3a425 1860 //-- arcref = Handle(IntPatch_RLine)::DownCast (slini)->Arc();
1861 //-- OnFirst = Handle(IntPatch_RLine)::DownCast (slini)->IsOnFirstSurface();
7fd59977 1862
1863 //-- DES CHOSES A FAIRE ICI
c5f3a425 1864 if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS1()) {
7fd59977 1865 OnFirst=Standard_True;
c5f3a425 1866 arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS1();
7fd59977 1867 }
c5f3a425 1868 else if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS2()) {
1869 arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS2();
7fd59977 1870 OnFirst=Standard_False;
1871 }
c5f3a425 1872 if (Handle(IntPatch_RLine)::DownCast (slini)->HasFirstPoint()) {
1873 paramf = Handle(IntPatch_RLine)::DownCast (slini)->FirstPoint().ParameterOnLine();
7fd59977 1874 }
1875 else {
1876 // cout << "Pas de param debut sur rst solution" << endl;
1877 paramf = RealFirst();
1878 }
c5f3a425 1879 if (Handle(IntPatch_RLine)::DownCast (slini)->HasLastPoint()) {
1880 paraml = Handle(IntPatch_RLine)::DownCast (slini)->LastPoint().ParameterOnLine();
7fd59977 1881 }
1882 else {
1883 // cout << "Pas de param debut sur rst solution" << endl;
1884 paraml = RealLast();
1885 }
1886
1887 if (typ2 == IntPatch_Analytic) {
c5f3a425 1888 Nbvtx = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
7fd59977 1889 }
1890 else {
c5f3a425 1891 Nbvtx = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
7fd59977 1892 }
1893
1894
1895 Standard_Boolean EdgeDegenere=Standard_True;
1896 for(Standard_Integer edg=0;EdgeDegenere && edg<=10;edg++) {
1897 arcref->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
1898 if (OnFirst) {
1899 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1900 }
1901 else {
1902 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1903 }
1904 if(d1u.Magnitude()>1e-7) {
1905 EdgeDegenere=Standard_False;
1906 }
1907 }
1908
1909 for (k=1; EdgeDegenere==Standard_False && k<=Nbvtx; k++) {
1910 if (typ2 == IntPatch_Analytic) {
c5f3a425 1911 Ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
7fd59977 1912 }
1913 else {
c5f3a425 1914 Ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
7fd59977 1915 }
1916 if ((OnFirst && !Ptvtx.IsOnDomS1()) ||
1917 (!OnFirst && !Ptvtx.IsOnDomS2())) {
1918 // Si OnFirst && OnDomS1, c est qu on est a une extremite
1919 // ca doit etre traite par Process Segment...
1920 project = Standard_True;
1921 keeppoint = Standard_False;
1922 toproj = Ptvtx.Value();
1923
1924 Standard_Integer jj;
1925 for (jj = 1; jj <= Nbpt; jj++) {
1926 //for (Standard_Integer jj = 1; jj <= Nbpt; jj++) {
1927 if (toproj.Distance(seq_Pnt3d(jj)) < _TolArc) {
1928 project = Standard_False;
1929 break;
1930 }
1931 }
1932 if (project) { //-- il faut projeter pour trouver le point sur la rline.
1933 if (OnFirst) {
1934 Ptvtx.ParametersOnS1(U,V);
1935 }
1936 else {
1937 Ptvtx.ParametersOnS2(U,V);
1938 }
1939
1940 project = IntPatch_HInterTool::Project(arcref,gp_Pnt2d(U,V),
1941 paramproj,p2d);
1942
1943 if (project) {
1944 if (OnFirst) {
1945 ptproj = Quad1.Value(p2d.X(),p2d.Y());
1946 }
1947 else {
1948 ptproj = Quad2.Value(p2d.X(),p2d.Y());
1949 }
1950 if ((toproj.Distance(ptproj) <=100*TolArc) &&
1951 (paramproj >= paramf) && (paramproj <= paraml)){
1952 newptvtx = Ptvtx;
1953 newptvtx.SetParameter(paramproj);
1954 keeppoint = Standard_True;
1955 seq_Pnt3d.Append(toproj);
1956 seq_Real.Append(paramproj);
1957
1958 //-- verifier que si la restriction arcref est trouvee, elle porte ce vertex
1959 for (int ri=1; ri<=Nblin; ri++) {
1960 const Handle(IntPatch_Line)& slinri = slin(ri);
1961 if (slinri->ArcType() == IntPatch_Restriction) {
c5f3a425 1962 if(OnFirst && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS1()) {
1963 if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS1()) {
1964 Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
7fd59977 1965 //printf("\n ImpImpIntersection_0.gxx CAS1 \n");
1966 }
1967 }
c5f3a425 1968 else if(OnFirst==Standard_False && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS2()) {
1969 if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS2()) {
1970 Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
7fd59977 1971 //printf("\n ImpImpIntersection_0.gxx CAS2 \n");
1972 }
1973 }
1974 }
1975 }
1976 // -- --------------------------------------------------
1977 }
1978 }
1979 }
1980 else {
1981 keeppoint = Standard_True;
1982 newptvtx = Ptvtx;
1983 newptvtx.SetParameter(seq_Real(jj));
1984 }
1985 if (keeppoint) {
1986 Ptvtx.SetMultiple(Standard_True);
3306fdd9 1987 Ptvtx.SetTolerance(_TolArc);
7fd59977 1988 newptvtx.SetMultiple(Standard_True);
1989
1990 if (typ2 == IntPatch_Analytic) {
c5f3a425 1991 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,Ptvtx);
7fd59977 1992 }
1993 else {
c5f3a425 1994 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,Ptvtx);
7fd59977 1995 }
1996
1997 if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2()) {
1998
1999 arcref->D1(newptvtx.ParameterOnLine(),p2d,d2d);
2000
2001 if (OnFirst) { // donc OnDomS2
2002 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2003 tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2004
2005 const Handle(Adaptor2d_HCurve2d)& thearc = Ptvtx.ArcOnS2();
2006 thearc->D1(Ptvtx.ParameterOnArc2(),p2d,d2d);
2007 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2008 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2009 norm = d1u.Crossed(d1v); //Quad2.Normale(valpt);
2010 if(norm.SquareMagnitude()<1e-16) {
2011 TRest.SetValue(Standard_True,IntSurf_Undecided);
2012 TArc.SetValue(Standard_True,IntSurf_Undecided);
2013 }
2014 else {
2015 IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
2016 }
2017 newptvtx.SetArc(Standard_False,thearc,
2018 Ptvtx.ParameterOnArc2(),TRest,TArc);
2019
2020 }
2021 else { // donc OnDomS1
2022 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2023 tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2024
2025 const Handle(Adaptor2d_HCurve2d)& thearc = Ptvtx.ArcOnS1();
2026 thearc->D1(Ptvtx.ParameterOnArc1(),p2d,d2d);
2027 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2028 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2029 norm = d1u.Crossed(d1v); //Quad1.Normale(valpt);
2030 if(norm.SquareMagnitude()<1e-16) {
2031 TRest.SetValue(Standard_True,IntSurf_Undecided);
2032 TArc.SetValue(Standard_True,IntSurf_Undecided);
2033 }
2034 else {
2035 IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
2036 }
2037 newptvtx.SetArc(Standard_True,thearc,
2038 Ptvtx.ParameterOnArc1(),TRest,TArc);
2039 }
2040 } //-- if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2())
2041
c5f3a425 2042 Handle(IntPatch_RLine)::DownCast (slini)->AddVertex(newptvtx);
7fd59977 2043
2044 } //-- if (keeppoint)
2045 } //-- if ((OnFirst && !Ptvtx.IsOnDomS1())||(!OnFirst && !Ptvtx.IsOnDomS2()))
2046 } //-- boucle sur les vertex
d4b867e6 2047
2048 if(!theIsReqToKeepRLine)
2049 {
2050 Handle(IntPatch_GLine) aGL = Handle(IntPatch_GLine)::DownCast(slinj);
2051
2052 if(!aGL.IsNull())
2053 {
2054 HasToDeleteRLine = !IsRLineGood(Quad1, Quad2, aGL,
2055 Handle(IntPatch_RLine)::DownCast(slini), TolArc);
2056 }
2057
2058 if(HasToDeleteRLine)
2059 {
2060 break;
2061 }
2062 }
7fd59977 2063 } //-- if (typ2 != IntPatch_Restriction)
2064 } //-- for (j=1; j<=Nblin; j++)
2065 } //-- if (typ1 == IntPatch_Restriction)
d4b867e6 2066
2067 if(HasToDeleteRLine)
2068 {
2069 slin.Remove(i);
2070 i--;
2071 Nblin = slin.Length();
2072 continue;
2073 }
7fd59977 2074 } //-- for (i=1; i<=Nblin; i++)
2075}