0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / IntPatch / IntPatch_RstInt.cxx
CommitLineData
b311480e 1// Created on: 1993-05-07
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1993-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// ----------------------------------------------------------------------
18//-- lbr: Modifs importantes du 16-17 Nov 95
19//-- - Chercher APointOnRstStillExist et OnDifferentRst
20//-- On veut pouvoir creer un Vtx (A1 sur S1, A2 sur S2)
21//-- et le Vtx (A1 sur S1, A2bis sur S2)
22//-- ce qui revient a distinguer un point deja pose sur une
23//-- restriction de S avec un point pose sur une nouvelle
24//-- restriction de S.
25//-- - Pour rester coherent avec cette facon de faire,
26//-- Chercher(Nbvtx++).
27
42cf5bc1 28#include <Adaptor2d_HCurve2d.hxx>
29#include <Adaptor3d_HSurface.hxx>
30#include <Adaptor3d_TopolTool.hxx>
31#include <gp_Pnt2d.hxx>
7fd59977 32#include <Intf_SectionPoint.hxx>
33#include <Intf_TangentZone.hxx>
7fd59977 34#include <IntPatch_CSFunction.hxx>
35#include <IntPatch_CurvIntSurf.hxx>
42cf5bc1 36#include <IntPatch_HInterTool.hxx>
37#include <IntPatch_Line.hxx>
38#include <IntPatch_PolyArc.hxx>
39#include <IntPatch_PolyLine.hxx>
40#include <IntPatch_RLine.hxx>
41#include <IntPatch_RstInt.hxx>
42#include <IntPatch_SearchPnt.hxx>
43#include <IntPatch_WLine.hxx>
44#include <IntSurf.hxx>
45#include <Precision.hxx>
46#include <Standard_DomainError.hxx>
47#include <TColgp_SequenceOfPnt.hxx>
48#include <TColgp_SequenceOfPnt2d.hxx>
7fd59977 49
f7991731 50#include <ElCLib.hxx>
51
7c4e9501 52#define myInfinite 1.e15 // the same as was in Adaptor3d_TopolTool
7fd59977 53
54static void Recadre(GeomAbs_SurfaceType typeS1,
55 GeomAbs_SurfaceType typeS2,
56 const Handle(IntPatch_WLine)& wlin,
57 Standard_Integer Param,
58 Standard_Real& U1,
59 Standard_Real& V1,
60 Standard_Real& U2,
61 Standard_Real& V2)
62{
63 Standard_Integer nbpnts = wlin->NbPnts();
64 if(Param<1) Param=1; else if(Param>nbpnts) Param=nbpnts;
65 Standard_Real U1p,V1p,U2p,V2p;
66
67 wlin->Point(Param).Parameters(U1p,V1p,U2p,V2p);
68 switch(typeS1) {
69 case GeomAbs_Cylinder:
70 case GeomAbs_Cone:
71 case GeomAbs_Sphere:
72 case GeomAbs_Torus:
c6541a0c
D
73 while(U1<(U1p-1.5*M_PI)) U1+=M_PI+M_PI;
74 while(U1>(U1p+1.5*M_PI)) U1-=M_PI+M_PI;
7fd59977 75 break;
76 default:
77 break;
78 }
79 if(typeS1==GeomAbs_Torus) {
c6541a0c
D
80 while(V1<(V1p-1.5*M_PI)) V1+=M_PI+M_PI;
81 while(V1>(V1p+1.5*M_PI)) V1-=M_PI+M_PI;
7fd59977 82 }
83
84 switch(typeS2) {
85 case GeomAbs_Cylinder:
86 case GeomAbs_Cone:
87 case GeomAbs_Sphere:
88 case GeomAbs_Torus:
c6541a0c
D
89 while(U2<(U2p-1.5*M_PI)) U2+=M_PI+M_PI;
90 while(U2>(U2p+1.5*M_PI)) U2-=M_PI+M_PI;
7fd59977 91 break;
92 default:
93 break;
94 }
95 if(typeS2==GeomAbs_Torus) {
c6541a0c
D
96 while(V2<(V1p-1.5*M_PI)) V2+=M_PI+M_PI;
97 while(V2>(V2p+1.5*M_PI)) V2-=M_PI+M_PI;
7fd59977 98 }
99}
100
101const Standard_Real Confusion = Precision::Confusion();
102
103inline Standard_Real Tol3d (const Handle(Adaptor3d_HVertex)& vtx,
104 const Handle(Adaptor3d_TopolTool)& Domain,
105 const Standard_Real tolDef = 0.)
106{
107 return (Domain->Has3d() ? Domain->Tol3d(vtx)
108 : tolDef < Confusion ? Confusion
109 : tolDef);
110}
111
112inline Standard_Real Tol3d (const Handle(Adaptor2d_HCurve2d)& arc,
113 const Handle(Adaptor3d_TopolTool)& Domain,
114 const Standard_Real tolDef = 0.)
115{
116 return (Domain->Has3d() ? Domain->Tol3d(arc)
117 : tolDef < Confusion ? Confusion
118 : tolDef);
119}
120
121static Standard_Boolean CoincideOnArc(const gp_Pnt& Ptsommet,
122 const Handle(Adaptor2d_HCurve2d)& A,
123 const Handle(Adaptor3d_HSurface)& Surf,
124 const Standard_Real Toler,
125 const Handle(Adaptor3d_TopolTool)& Domain,
126 Handle(Adaptor3d_HVertex)& Vtx)
127{
128 Standard_Real distmin = RealLast();
129 Standard_Real tolarc = Max(Toler,Tol3d(A,Domain));
130
131 Domain->Initialize(A);
132 Domain->InitVertexIterator();
133 while (Domain->MoreVertex()) {
134 Handle(Adaptor3d_HVertex) vtx1 = Domain->Vertex();
135 Standard_Real prm = IntPatch_HInterTool::Parameter(vtx1,A);
136 gp_Pnt2d p2d = A->Value(prm);
137 gp_Pnt point = Surf->Value(p2d.X(),p2d.Y());
138 const Standard_Real dist = point.Distance(Ptsommet);
139 Standard_Real tol = Max (tolarc, Tol3d(vtx1,Domain));
140
141 if (dist <= tol && dist <= distmin) { // the best coincidence
142 distmin = dist;
143 Vtx = vtx1;
144 }
145 Domain->NextVertex();
146 }
147 return distmin < RealLast();
148}
149
150
151static void VerifyTgline(const Handle(IntPatch_WLine)& wlin,
152 const Standard_Integer param,
153 const Standard_Real Tol,
154 gp_Vec& Tgl) {
155
156 if( Abs(Tgl.X())<Tol
157 && Abs(Tgl.Y())<Tol
158 && Abs(Tgl.Z())<Tol) {
159 //-- On construit une tangente plus grande
160 //-- (Eviter des points tres proches ds Walking)
161 Standard_Integer i, n, nbpt=wlin->NbPnts();
162 Standard_Boolean forward = (nbpt-param) >= (param-1);
163 for (n = 2; n > 0; n--, forward = !forward) {
164 if (forward) {
165 for(i=param+1; i<=nbpt; i++) {
166 gp_Vec T(wlin->Point(param).Value(),wlin->Point(i).Value());
167 if( Abs(T.X())>=Tol
168 || Abs(T.Y())>=Tol
169 || Abs(T.Z())>=Tol) {
170 Tgl = T ;
171 return;
172 }
173 }
174 }
175 else {
176 for(i=param-1; i>=1; i--) {
177 gp_Vec T(wlin->Point(i).Value(),wlin->Point(param).Value());
178 if( Abs(T.X())>=Tol
179 || Abs(T.Y())>=Tol
180 || Abs(T.Z())>=Tol) {
181 Tgl = T ;
182 return;
183 }
184 }
185 }
186 }
187 }
188}
189
190static void GetLinePoint2d (const Handle(IntPatch_Line)& L,
191 const Standard_Real param,
192 const Standard_Boolean OnFirst,
193 Standard_Real& U, Standard_Real& V)
194{
c04c30b3 195 Handle(IntPatch_WLine) wlin = Handle(IntPatch_WLine)::DownCast(L);
196 Handle(IntPatch_RLine) rlin = Handle(IntPatch_RLine)::DownCast(L);
7fd59977 197 IntPatch_IType typL = L->ArcType();
7fd59977 198 Standard_Integer Nbptlin = (typL == IntPatch_Walking
199 ? wlin->NbPnts()
200 : rlin->NbPnts());
201
202 Standard_Real par = IntegerPart(param);
203 Standard_Integer Irang = Standard_Integer(par);
204 if (Irang == Nbptlin) {
205 Irang--;
206 par = 1.0;
207 }
208 else
209 par = Abs(param-par);
210
211 Standard_Real us1,vs1,us2,vs2;
212 if (typL == IntPatch_Walking) {
213 if (OnFirst) {
214 wlin->Point(Irang).ParametersOnS1(us1,vs1);
215 wlin->Point(Irang+1).ParametersOnS1(us2,vs2);
216 }
217 else {
218 wlin->Point(Irang).ParametersOnS2(us1,vs1);
219 wlin->Point(Irang+1).ParametersOnS2(us2,vs2);
220 }
221 }
222 else {
223 if (OnFirst) {
224 rlin->Point(Irang).ParametersOnS1(us1,vs1);
225 rlin->Point(Irang+1).ParametersOnS1(us2,vs2);
226 }
227 else {
228 rlin->Point(Irang).ParametersOnS2(us1,vs1);
229 rlin->Point(Irang+1).ParametersOnS2(us2,vs2);
230 }
231 }
232
233 U = (1.-par)*us1+par*us2;
234 V = (1.-par)*vs1+par*vs2;
235}
236
7fd59977 237static Standard_Boolean FindParameter(const Handle(IntPatch_Line)& L,
238 const Handle(Adaptor3d_HSurface)& OtherSurf,
239 const Standard_Real Tol,
240 const gp_Pnt& Ptsom,
241 const gp_Pnt2d& Ptsom2d,
242 Standard_Real& Param,
243 gp_Vec& Tgl,
244 const Standard_Integer ParamApproche,
245 const Standard_Boolean OnFirst)
246
247{
248 // MSV 28.03.2002: find parameter on WLine in 2d space
249
250 //Si la ligne est de type restriction, c est qu on provient necessairement
251 // du cas implicite/parametree, et que la ligne est restriction de
252 // la surface bi-parametree. Cette surface bi-parametree est necessairement
253 // passee en argument a PutVertexOnline dans la variable OtherSurf.
254
255 // Dans le cas d une ligne de cheminement, il faudrait voir la projection
256 // et le calcul de la tangente.
257
c5f3a425 258 Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est
259 Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast.
7fd59977 260 gp_Pnt ptbid;
261 gp_Vec d1u,d1v;
262 gp_Pnt2d p2d;
263 gp_Vec2d d2d;
264 Standard_Real Tol2 = Tol*Tol;
265 IntPatch_IType typL = L->ArcType();
266 Tgl.SetCoord(0.0,0.0,0.0);
267
268 if ( typL == IntPatch_Restriction) {
269 if (!OnFirst && rlin->IsArcOnS1()) {
270 IntPatch_HInterTool::Project(rlin->ArcOnS1(),Ptsom2d,Param,p2d);
271 rlin->ArcOnS1()->D1(Param,p2d,d2d);
272 }
273 else if (OnFirst && rlin->IsArcOnS2()) {
274 IntPatch_HInterTool::Project(rlin->ArcOnS2(),Ptsom2d,Param,p2d);
275 rlin->ArcOnS2()->D1(Param,p2d,d2d);
276 }
277 else {
278 return(Standard_False);
279 }
280 OtherSurf->D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
281 if (ptbid.SquareDistance(Ptsom) > Tol2) {
282 return Standard_False;
283 }
284 Tgl.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
285 return(Standard_True);
286 }
287
288 else if (typL == IntPatch_Walking) {
289 Standard_Integer i, is, nbpt=wlin->NbPnts();
290 Standard_Real norm1,norm2;
291 Standard_Integer ParamSearchInf=1;
292 Standard_Integer ParamSearchSup=nbpt;
293
294 if((ParamApproche-2) > ParamSearchInf) {
295 ParamSearchInf = ParamApproche-2;
296 }
297 if((ParamApproche+2) < ParamSearchSup) {
298 ParamSearchSup = ParamApproche+2;
299 }
300
301 Standard_Integer inf[3],sup[3];
302 // first search inside close bounding around ParamApproche;
303 // then search to the nearest end of line;
304 // and then search to the farest end of line.
305 inf[0] = ParamSearchInf; sup[0] = ParamSearchSup;
306 if (ParamSearchInf-1 < nbpt-ParamSearchSup) {
307 inf[1] = 1; sup[1] = ParamSearchInf;
308 inf[2] = ParamSearchSup; sup[2] = nbpt;
309 }
310 else {
311 inf[1] = ParamSearchSup; sup[1] = nbpt;
312 inf[2] = 1; sup[2] = ParamSearchInf;
313 }
314
315 Standard_Boolean found = Standard_False;
316 for (is=0; is < 3 && !found; is++) {
317 gp_Vec v1,v2;
318 gp_Pnt p1,p2;
319 p1 = wlin->Point(inf[is]).Value();
320 v1 = gp_Vec (Ptsom,p1);
321 norm1 = v1.SquareMagnitude();
322 Standard_Real normmin = Tol2;
323 Standard_Integer ibest = 0;
324 if (norm1 <= normmin) {
325 normmin = norm1;
326 ibest = inf[is];
327 }
328 for (i=inf[is]+1; i <= sup[is] && !found; i++) {
329 p2 = wlin->Point(i).Value();
330 v2 = gp_Vec (Ptsom,p2);
331 norm2 = v2.SquareMagnitude();
332 if (v1.Dot(v2) < 0.) {
333 Param = (Standard_Real)(i-1) + 1./(1.+Sqrt(norm2/norm1));
334 Tgl = gp_Vec (p1,p2);
335 found = Standard_True;
336 }
337 else if (norm2 < normmin) {
338 normmin = norm2;
339 ibest = i;
340 }
341 v1 = v2; p1 = p2; norm1 = norm2;
342 }
343 if (!found && ibest) {
344 Param = (Standard_Real)ibest;
345 found = Standard_True;
346 }
347 }
348 if (found) return Standard_True;
349 }
350 else {
9775fa61 351 throw Standard_DomainError();
7fd59977 352 }
353 return Standard_False;
354}
355
356inline Standard_Boolean ArePnt2dEqual(const gp_Pnt2d& p1, const gp_Pnt2d& p2,
357 const Standard_Real tolU,
358 const Standard_Real tolV)
359{
360 return Abs(p1.X()-p2.X()) < tolU && Abs(p1.Y()-p2.Y()) < tolV;
361}
362
7fd59977 363//=======================================================================
364//function : PutVertexOnLine
365//purpose :
366//=======================================================================
367
7f22979e 368void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
882e1d11 369 const Handle(Adaptor3d_HSurface)& Surf,
370 const Handle(Adaptor3d_TopolTool)& Domain,
371 const Handle(Adaptor3d_HSurface)& OtherSurf,
372 const Standard_Boolean OnFirst,
373 const Standard_Real Tol)
7fd59977 374 {
375
376// Domain est le domaine de restriction de la surface Surf.
377// On intersectera un arc de Surf avec la surface OtherSurf.
378// Si OnFirst = True, c est que la surface Surf correspond a la 1ere
379// surface donnee aux algo d intersection.
380
1ef32e96 381 IntPatch_SearchPnt Commun;
7fd59977 382
383 Standard_Real U,V,W;
1d47d8d0 384 Standard_Real U1,V1,U2 = 0.,V2 = 0.;
7fd59977 385 Standard_Real paramarc=0.,paramline=0.;
386 Standard_Integer i,j,k;
387 TColgp_SequenceOfPnt locpt;
388 TColgp_SequenceOfPnt2d locpt2;
c5f3a425 389 Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est
390 Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast.
7fd59977 391 Standard_Integer Nbvtx =0;
7fd59977 392 Standard_Real tolPLin = Surf->UResolution(Precision::Confusion());
393 tolPLin = Max (tolPLin, Surf->VResolution(Precision::Confusion()));
394 tolPLin = Min (tolPLin, Precision::Confusion());
395 IntPatch_PolyLine PLin(tolPLin);
396
397 Standard_Real PFirst,PLast;
398 Standard_Integer NbEchant;
399 gp_Pnt ptsommet, ptbid;
400 gp_Vec tgline, tgrst, d1u, d1v, normsurf;
401
402 gp_Pnt2d p2d;
403 gp_Vec2d d2d;
404
405 IntPatch_Point Sommet, ptline;
406 Handle(Adaptor3d_HVertex) vtxarc,vtxline;
407 Handle(Adaptor2d_HCurve2d) arc;
408 Standard_Boolean VtxOnArc, duplicate, found;
409 IntSurf_Transition transarc,transline;
410
411 IntPatch_IType typL = L->ArcType();
412 if (typL == IntPatch_Walking) {
413 Nbvtx = wlin->NbVertex();
414 PLin.SetWLine(OnFirst,wlin);
7fd59977 415 }
416 else if ( typL == IntPatch_Restriction) {
417 Nbvtx = rlin->NbVertex();
418 PLin.SetRLine(OnFirst,rlin);
7fd59977 419 }
420 else {
9775fa61 421 throw Standard_DomainError();
7fd59977 422 }
423 if (!Domain->Has3d())
424 // don't use computed deflection in the mode of pure geometric intersection
425 PLin.ResetError();
426
427 const Standard_Boolean SurfaceIsUClosed = Surf->IsUClosed();
428 const Standard_Boolean SurfaceIsVClosed = Surf->IsVClosed();
429 const Standard_Boolean OSurfaceIsUClosed = OtherSurf->IsUClosed();
430 const Standard_Boolean OSurfaceIsVClosed = OtherSurf->IsVClosed();
431 const Standard_Boolean possiblyClosed = (SurfaceIsUClosed || SurfaceIsVClosed ||
432 OSurfaceIsUClosed || OSurfaceIsVClosed);
433 Standard_Real tolUClosed=0., tolVClosed=0., tolOUClosed=0., tolOVClosed=0.;
434 if (possiblyClosed) {
435 if (SurfaceIsUClosed)
436 tolUClosed = (Surf->LastUParameter() - Surf->FirstUParameter()) * 0.01;
437 if (SurfaceIsVClosed)
438 tolVClosed = (Surf->LastVParameter() - Surf->FirstVParameter()) * 0.01;
439 if (OSurfaceIsUClosed)
440 tolOUClosed = (OtherSurf->LastUParameter() - OtherSurf->FirstUParameter()) * 0.01;
441 if (OSurfaceIsVClosed)
442 tolOVClosed = (OtherSurf->LastVParameter() - OtherSurf->FirstVParameter()) * 0.01;
443 }
444
445 //------------------------------------------------------------------------
446 //-- On traite le cas ou la surface est periodique --
447 //-- il faut dans ce cas considerer la restriction --
448 //-- la restriction decalee de +-2PI --
449 //------------------------------------------------------------------------
450 const Handle(Adaptor3d_HSurface)& Surf1 = (OnFirst ? Surf : OtherSurf);
451 const Handle(Adaptor3d_HSurface)& Surf2 = (OnFirst ? OtherSurf : Surf);
452 GeomAbs_SurfaceType TypeS1 = Surf1->GetType();
453 GeomAbs_SurfaceType TypeS2 = Surf2->GetType();
454 Standard_Boolean SurfaceIsPeriodic = Standard_False;
455 Standard_Boolean SurfaceIsBiPeriodic = Standard_False;
456 GeomAbs_SurfaceType surfacetype = (OnFirst ? TypeS1 : TypeS2);
457 if( surfacetype == GeomAbs_Cylinder
458 || surfacetype == GeomAbs_Cone
459 || surfacetype == GeomAbs_Torus
460 || surfacetype == GeomAbs_Sphere) {
461 SurfaceIsPeriodic = Standard_True;
462 if(surfacetype == GeomAbs_Torus) {
463 SurfaceIsBiPeriodic = Standard_True;
464 }
465 }
466
467 Standard_Integer NumeroEdge=0;
468 Domain->Init();
469 while (Domain->More()) {
470 NumeroEdge++;
471 arc = Domain->Value();
472
473 // MSV Oct 15, 2001: use tolerance of this edge if possible
474 Standard_Real edgeTol = Tol3d(arc,Domain,Tol);
7fd59977 475
476 IntPatch_HInterTool::Bounds(arc,PFirst,PLast);
7c4e9501 477 if(Precision::IsNegativeInfinite(PFirst))
478 PFirst = -myInfinite;
479 if(Precision::IsPositiveInfinite(PLast))
480 PLast = myInfinite;
481 //if (Precision::IsNegativeInfinite(PFirst) ||
482 // Precision::IsPositiveInfinite(PLast)) {
04232180 483 // //-- std::cout<<" IntPatch_RstInt::PutVertexOnLine ---> Restrictions Infinies :"<<std::endl;
7c4e9501 484 // return;
485 //}
7fd59977 486
7fd59977 487 gp_Pnt2d p2dFirst,p2dLast;
7fd59977 488 Domain->Initialize(arc);
489 for (Domain->InitVertexIterator(); Domain->MoreVertex(); Domain->NextVertex()) {
490 Handle(Adaptor3d_HVertex) vtx = Domain->Vertex();
491 Standard_Real prm = IntPatch_HInterTool::Parameter(vtx,arc);
492 if (Abs(prm - PFirst) < Precision::PConfusion()) {
493 arc->D0(PFirst,p2dFirst);
7fd59977 494 }
495 else if (Abs(prm - PLast) < Precision::PConfusion()) {
496 arc->D0(PLast,p2dLast);
7fd59977 497 }
498 }
499
9530af27 500 Bnd_Box2d BPLin = PLin.Bounding();
f7991731 501 Standard_Real OffsetV = 0.0;
502 Standard_Real OffsetU = 0.0;
7fd59977 503
504 switch(arc->GetType())
505 {
f7991731 506 case GeomAbs_Line:
507 {
508 NbEchant=10;
509
510 Standard_Real aXmin, aYmin, aXmax, aYmax;
511 BPLin.Get(aXmin, aYmin, aXmax, aYmax);
512 gp_Lin2d aLin = arc->Curve2d().Line();
513 const gp_Pnt2d& aLoc = aLin.Location();
514 const gp_Dir2d& aDir = aLin.Direction();
515
516 //Here, we consider rectangular axis-aligned domain only.
517 const Standard_Boolean isAlongU = (Abs(aDir.X()) > Abs(aDir.Y()));
518
519 if(SurfaceIsPeriodic && !isAlongU)
520 {
521 //Shift along U-direction
522 const Standard_Real aNewLocation =
523 ElCLib::InPeriod(aLoc.X(), aXmin, aXmin + M_PI + M_PI);
524 OffsetU = aNewLocation - aLoc.X();
525 }
526 else if(SurfaceIsBiPeriodic && isAlongU)
527 {
528 //Shift along V-direction
529 const Standard_Real aNewLocation =
530 ElCLib::InPeriod(aLoc.Y(), aYmin, aYmin + M_PI + M_PI);
531 OffsetV = aNewLocation - aLoc.Y();
532 }
533 }
534 break;
7fd59977 535 case GeomAbs_BezierCurve:
536 {
537 NbEchant = (3 + arc->NbPoles());
538 if(NbEchant<10) NbEchant=10;
539 else if(NbEchant>50) NbEchant=50;
540 }
541 break;
542 case GeomAbs_BSplineCurve:
543 {
544 //szv:const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(arc->LastParameter() - arc->FirstParameter())/(PLast-PFirst);
545 const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(PLast-PFirst)/(arc->LastParameter() - arc->FirstParameter());
546 NbEchant = (nbs < 2.0 ? 2 : (Standard_Integer)nbs);
547 if(NbEchant<10) NbEchant=10;
548 else if (NbEchant>50) NbEchant=50;
549 }
550 break;
551 default:
552 {
553 NbEchant = 25;
554 }
555 }
556
f7991731 557 if(SurfaceIsPeriodic) {
558 Standard_Real xmin,ymin,xmax,ymax,g;
559 BPLin.Get(xmin,ymin,xmax,ymax);
560 g = BPLin.GetGap();
561 BPLin.SetVoid();
562 BPLin.Update(xmin-M_PI-M_PI,ymin,
563 xmax+M_PI+M_PI,ymax);
564 BPLin.SetGap(g);
565 }
566 if(SurfaceIsBiPeriodic) {
567 Standard_Real xmin,ymin,xmax,ymax,g;
568 BPLin.Get(xmin,ymin,xmax,ymax);
569 g = BPLin.GetGap();
570 BPLin.SetVoid();
571 BPLin.Update(xmin,ymin-M_PI-M_PI,
572 xmax,ymax+M_PI+M_PI);
573 BPLin.SetGap(g);
574 }
575
7fd59977 576 IntPatch_PolyArc Brise(arc,NbEchant,PFirst,PLast,BPLin);
577
578 Standard_Integer IndiceOffsetBiPeriodic = 0;
f7991731 579 Standard_Integer IndiceOffsetPeriodic = 0;
580 const Standard_Real aRefOU = OffsetU,
581 aRefOV = OffsetV;
582
7fd59977 583 do {
584 if(IndiceOffsetBiPeriodic == 1)
f7991731 585 OffsetV = aRefOV - M_PI - M_PI;
7fd59977 586 else if(IndiceOffsetBiPeriodic == 2)
f7991731 587 OffsetV = aRefOV + M_PI + M_PI;
588
7fd59977 589 do {
f7991731 590 if(IndiceOffsetPeriodic == 1)
591 OffsetU = aRefOU - M_PI - M_PI;
592 else if(IndiceOffsetPeriodic == 2)
593 OffsetU = aRefOU + M_PI + M_PI;
594
595 Brise.SetOffset(OffsetU,OffsetV);
7fd59977 596
597 static int debug_polygon2d =0;
598 if(debug_polygon2d) {
04232180 599 std::cout<<" ***** Numero Restriction : "<<NumeroEdge<<" *****"<<std::endl;
9530af27 600 PLin.Dump();
601 Brise.Dump();
7fd59977 602 }
603
604 Commun.Perform(PLin,Brise);
605 locpt.Clear();
606 locpt2.Clear();
7fd59977 607
8dc56d0f 608 // We do not need in putting vertex into tangent zone(s).
609 // Therefore, only section points are interested by us.
610 // Boundary of WLine (its first/last points) will be
611 // marked by some vertex later. See bug #29494.
612 const Standard_Integer aNbSectionPts = Commun.NbSectionPoints();
613 for (i = 1; i <= aNbSectionPts; i++)
614 {
615 const Standard_Real aW1 = Commun.PntValue(i).ParamOnFirst(),
616 aW2 = Commun.PntValue(i).ParamOnSecond();
617
618 Standard_Integer nbTreated = 0;
619 GetLinePoint2d (L, aW1+1, !OnFirst, U,V);
7fd59977 620
8dc56d0f 621 Standard_Real par = IntegerPart(aW2);
622 Standard_Integer Irang = Standard_Integer(par) + 1;
623 if (Irang == Brise.NbPoints())
624 {
625 Irang--;
626 par = 1.;
627 }
628 else
629 {
630 par = Abs(aW2 - par);
631 }
632
633 W = (1. - par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang + 1);
634
635 //------------------------------------------------------------------------
636 //-- On a trouve un point 2d approche Ua,Va intersection de la ligne
637 //-- de cheminement et de la restriction.
638 //--
639 //-- On injecte ce point ds les intersections Courbe-Surface
640 //--
641 IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
642 // MSV: extend UV bounds to not miss solution near the boundary
643 const Standard_Real margCoef = 0.004;
644 Standard_Boolean refined = Standard_False;
645 IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
646 if (IntCS.IsDone() && !IntCS.IsEmpty())
647 {
648 ptsommet = IntCS.Point();
649 IntCS.ParameterOnSurface(U2,V2);
650 gp_Pnt anOldPnt, aNewPnt;
651 OtherSurf->D0(U,V, anOldPnt);
652 OtherSurf->D0(U2,V2, aNewPnt);
653 if (anOldPnt.SquareDistance(aNewPnt) < Precision::SquareConfusion())
0cbfb9f1 654 {
8dc56d0f 655 U2 = U;
656 V2 = V;
0cbfb9f1 657 }
8dc56d0f 658 paramarc = IntCS.ParameterOnCurve();
659 refined = Standard_True;
660 }
7fd59977 661
8dc56d0f 662 if (refined) {
663 duplicate = Standard_False;
664 for (j=1; j<=locpt.Length();j++) {
665 if (ptsommet.Distance(locpt(j)) <= edgeTol) {
666 if (possiblyClosed) {
667 locpt2(j).Coord(U,V);
668 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
669 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
670 continue;
7fd59977 671 }
8dc56d0f 672 duplicate = Standard_True;
673 break;
7fd59977 674 }
8dc56d0f 675 }
7fd59977 676
8dc56d0f 677 if (!duplicate) {
678 Standard_Integer ParamApproxOnLine = Standard_Integer(aW1)+1;
679
680 arc->D1(paramarc,p2d,d2d);
681 U1 = p2d.X(); V1 = p2d.Y();
682 if (typL == IntPatch_Walking && SurfaceIsPeriodic) {
683 if (OnFirst)
684 Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2);
685 else
686 Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1);
687 }
688 locpt.Append(ptsommet);
689 locpt2.Append(gp_Pnt2d(U2,V2));
690
691 found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2),
692 paramline,tgline,ParamApproxOnLine,OnFirst);
693
694 if (typL == IntPatch_Walking && found && possiblyClosed) {
695 // check in 2d
696 if (SurfaceIsUClosed || SurfaceIsVClosed) {
697 GetLinePoint2d (L, paramline, OnFirst, U,V);
698 if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
699 (SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
700 found = Standard_False;
7fd59977 701 }
8dc56d0f 702 if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) {
703 GetLinePoint2d (L, paramline, !OnFirst, U,V);
704 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
705 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
706 found = Standard_False;
7fd59977 707 }
8dc56d0f 708 }
709 if (!found) {
710 continue;
711 }
7fd59977 712
8dc56d0f 713 VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc);
714 Standard_Real vtxTol;
715 if (VtxOnArc) {
716 vtxTol = Tol3d(vtxarc,Domain);
717 if (edgeTol > vtxTol) vtxTol = edgeTol;
718 }
719 else vtxTol = edgeTol;
720
721 //-- It is necessary to test that the point does not already exist
722 //-- - It can be already a point on arc
723 //-- BUT on a different arc
724 // MSV 27.03.2002: find the nearest point; add check in 2d
725 Standard_Integer ivtx = 0;
726 Standard_Real dmin = RealLast();
727 for (j=1; j<=Nbvtx; j++) {
728 const IntPatch_Point& Rptline = (typL == IntPatch_Walking
729 ? wlin->Vertex(j)
730 : rlin->Vertex(j));
731 Standard_Boolean APointOnRstStillExist =
732 ((OnFirst && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc) ||
733 (!OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc));
734 if(!APointOnRstStillExist) {
735 if (possiblyClosed) {
736 if (SurfaceIsUClosed || SurfaceIsVClosed) {
737 if (OnFirst) Rptline.ParametersOnS1(U,V);
738 else Rptline.ParametersOnS2(U,V);
739 if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
740 (SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
741 continue;
7fd59977 742 }
8dc56d0f 743 if (OSurfaceIsUClosed || OSurfaceIsVClosed) {
744 if (OnFirst) Rptline.ParametersOnS2(U,V);
745 else Rptline.ParametersOnS1(U,V);
746 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
747 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
748 continue;
749 }
750 }
751 Standard_Real dist = ptsommet.Distance(Rptline.Value());
752 Standard_Real dt = Max(vtxTol, Rptline.Tolerance());
753 if (dist < dmin) {
754 if (dist <= dt) {
755 ptline = Rptline;
756 ivtx = j;
757 if( surfacetype == GeomAbs_Cone ) {
7fd59977 758 ivtx = 0;
759 }
8dc56d0f 760 }
761 else {
762 // cancel previous solution because this point is better
763 // but its tolerance is not large enough
764 ivtx = 0;
765 }
766 dmin = dist;
767 }
7fd59977 768 }
8dc56d0f 769 }
770 if (ivtx) {
771 if (ptline.Tolerance() > vtxTol) {
772 vtxTol = ptline.Tolerance();
773 if (!VtxOnArc) {
774 // now we should repeat attempt to coincide on a bound of arc
775 VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc);
776 if (VtxOnArc) {
777 Standard_Real tol = Tol3d(vtxarc,Domain);
778 if (tol > vtxTol) vtxTol = tol;
7fd59977 779 }
780 }
781 }
8dc56d0f 782 }
7fd59977 783
8dc56d0f 784 if (typL == IntPatch_Walking)
785 VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline);
7fd59977 786
8dc56d0f 787 Surf->D1(U1,V1,ptbid,d1u,d1v);
788 tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
7fd59977 789
8dc56d0f 790 normsurf = d1u.Crossed(d1v);
791 if (normsurf.Magnitude() < gp::Resolution()) {
792 transline.SetValue(Standard_True,IntSurf_Undecided);
793 transarc.SetValue(Standard_True,IntSurf_Undecided);
794 }
795 else
796 IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc);
797
798 nbTreated++;
799 if (!ivtx) {
800 Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence
801 if (OnFirst)
802 Sommet.SetParameters(U1,V1,U2,V2);
7fd59977 803 else
8dc56d0f 804 Sommet.SetParameters(U2,V2,U1,V1);
7fd59977 805
8dc56d0f 806 if (VtxOnArc)
807 Sommet.SetVertex(OnFirst,vtxarc);
808
809 //---------------------------------------------------------
810 //-- lbr : On remplace le point d indice paramline sur la -
811 //-- ligne par le vertex . -
812 //---------------------------------------------------------
813 Sommet.SetParameter(paramline); // sur ligne d intersection
814 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
815
816 if (typL == IntPatch_Walking) {
817 wlin->AddVertex(Sommet);
818 Nbvtx++;
7fd59977 819 }
820 else {
8dc56d0f 821 rlin->AddVertex(Sommet);
822 Nbvtx++;
823 }
824 }
825 else {
826 // CAS DE FIGURE : en appelant s1 la surf sur laquelle on
827 // connait les pts sur restriction, et s2 celle sur laquelle
828 // on les cherche. Le point trouve verifie necessairement
829 // IsOnDomS1 = True.
830 // Pas vtxS1, pas vtxS2 :
831 // on recupere le point et on applique SetArcOnS2 et
832 // eventuellement SetVertexOnS2. Si on a deja IsOnDomS2,
833 // on considere que le point est deja traite, mais ne devrait
834 // pas se produire.
835 // vtxS1, pas vtxS2 :
836 // si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2,
837 // et eventuellement SetVertexOnS2.
838 // si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2.
839 // vtxS1,vtxS2 :
840 // on doit avoir VtxOnArc = True. On duplique chaque occurrence
841 // "sur S1" du point en changeant ArcOnS2.
842 // pas vtxS1, vtxS2 :
843 // on doit avoir VtxOnArc = True. On duplique le point sur S1
844 // en changeant ArcOnS2.
845 Standard_Boolean OnDifferentRst =
846 ((OnFirst && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc) ||
847 (!OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc));
848 ptline.SetTolerance(vtxTol);
849 if ( (!ptline.IsVertexOnS1() && OnFirst)
850 || (!ptline.IsVertexOnS2() && !OnFirst)
851 || (OnDifferentRst)) {
852 if ( (!ptline.IsOnDomS2() && !OnFirst)
853 ||(!ptline.IsOnDomS1() && OnFirst)
854 ||(OnDifferentRst)) {
855 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
856 //ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97
857 if (VtxOnArc)
858 ptline.SetVertex(OnFirst,vtxarc);
859 if (typL == IntPatch_Walking) {
860 if(OnDifferentRst) {
861 wlin->AddVertex(ptline);
862 Nbvtx++;
7fd59977 863 }
8dc56d0f 864 else {
865 wlin->Replace(ivtx,ptline);
7fd59977 866 }
867 }
8dc56d0f 868 else {
869 if(OnDifferentRst) {
870 rlin->AddVertex(ptline);
7fd59977 871 Nbvtx++;
872 }
873 else {
8dc56d0f 874 rlin->Replace(ivtx,ptline);
7fd59977 875 }
876 }
8dc56d0f 877 }
878 else if ( ( OnFirst && ptline.IsVertexOnS2())
879 ||(!OnFirst && ptline.IsVertexOnS1())) {
880 Sommet = ptline;
881 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
882 if (VtxOnArc)
883 Sommet.SetVertex(OnFirst,vtxarc);
884 if (typL == IntPatch_Walking) {
885 wlin->AddVertex(Sommet);
886 Nbvtx++;
887 }
7fd59977 888 else {
8dc56d0f 889 rlin->AddVertex(Sommet);
890 Nbvtx++;
7fd59977 891 }
892 }
893 else {
04232180 894 //-- std::cout << "pb dans RstInt Type 1 " << std::endl;
8dc56d0f 895 }
896 }
897 else {
898 Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ;
899 if ( ( OnFirst && !ptline.IsOnDomS2())
900 ||(!OnFirst && !ptline.IsOnDomS1())) {
901 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
902 if (VtxOnArc)
903 ptline.SetVertex(OnFirst,vtxarc);
904 if (typL == IntPatch_Walking) {
905 wlin->Replace(ivtx,ptline);
906 }
907 else {
908 rlin->Replace(ivtx,ptline);
909 }
910
911 for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
7fd59977 912 if (typL == IntPatch_Walking) {
8dc56d0f 913 ptline = wlin->Vertex(k);
7fd59977 914 }
915 else {
8dc56d0f 916 ptline = rlin->Vertex(k);
7fd59977 917 }
8dc56d0f 918 if ( ( OnFirst && ptline.IsVertexOnS1())
919 || (!OnFirst && ptline.IsVertexOnS2())) {
920 if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
921 if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
922 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
923 if (VtxOnArc)
924 ptline.SetVertex(OnFirst,vtxarc);
925 if (typL == IntPatch_Walking) {
926 wlin->Replace(k,ptline);
927 }
928 else {
929 rlin->Replace(k,ptline);
7fd59977 930 }
931 }
932 }
933 }
8dc56d0f 934 }
935 else if( ( OnFirst && ptline.IsVertexOnS2())
936 || (!OnFirst && ptline.IsVertexOnS1())) {
937 // on doit avoir vtxons2 = vtxarc... pas de verif...
938 Sommet = ptline;
939 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
940 if (typL == IntPatch_Walking) {
941 wlin->AddVertex(Sommet);
942 Nbvtx++;
943 }
944 else {
945 rlin->AddVertex(Sommet);
946 Nbvtx++;
947 }
948 for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
7fd59977 949 if (typL == IntPatch_Walking) {
8dc56d0f 950 ptline = wlin->Vertex(k);
7fd59977 951 }
952 else {
8dc56d0f 953 ptline = rlin->Vertex(k);
7fd59977 954 }
8dc56d0f 955 if ( ( OnFirst && ptline.IsVertexOnS1())
956 ||(!OnFirst && ptline.IsVertexOnS2())) {
957 if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
958 if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
959 Sommet = ptline;
960 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
961 if (typL == IntPatch_Walking) {
962 wlin->Replace(k,ptline);
963 wlin->AddVertex(Sommet);
964 Nbvtx++;
965 }
966 else {
967 rlin->Replace(k,ptline);
968 rlin->AddVertex(Sommet);
969 Nbvtx++;
7fd59977 970 }
971 }
972 }
7fd59977 973 }
8dc56d0f 974
975 }
976 else {
04232180 977 //-- std::cout << "pb dans RstInt Type 2 " << std::endl;
7fd59977 978 }
979 }
980 }
981 }
982 }
983 if (nbTreated == 2 && typL == IntPatch_Walking) {
984 // We processed a tangent zone, and both ends have been treated.
985 // So mark WLine as having arc
986 if(OnFirst) wlin->SetArcOnS1(arc);
987 else wlin->SetArcOnS2(arc);
988 }
989 }
990
991 IndiceOffsetPeriodic++;
992 }
993 while(SurfaceIsPeriodic && IndiceOffsetPeriodic<=2);
994
995 IndiceOffsetBiPeriodic++;
996 }
997 while(SurfaceIsBiPeriodic && IndiceOffsetBiPeriodic<=2);
998 Domain->Next();
999 }
1000
1001 //--------------------------------------------------------------------------------
1002 //-- On reprend la ligne et on recale les parametres des vertex.
1003 //--
1004 if (typL == IntPatch_Walking) {
1005 Standard_Real pu1,pv1,pu2,pv2;
1006 pu1=pv1=pu2=pv2=0.0;
1007 switch(TypeS1) {
1008 case GeomAbs_Cylinder:
1009 case GeomAbs_Cone:
1010 case GeomAbs_Sphere:
c6541a0c 1011 pu1=M_PI+M_PI;
7fd59977 1012 break;
1013 case GeomAbs_Torus:
c6541a0c 1014 pu1=pv1=M_PI+M_PI;
7fd59977 1015 break;
1016 default:
1017 {
1018 if( Surf1->IsUPeriodic()) {
1019 pu1=Surf1->UPeriod();
1020 }
1021 else if(Surf1->IsUClosed()) {
1022 pu1=Surf1->LastUParameter() - Surf1->FirstUParameter();
04232180 1023 //std::cout<<" UClosed1 "<<pu1<<std::endl;
7fd59977 1024 }
1025 if( Surf1->IsVPeriodic()) {
1026 pv1=Surf1->VPeriod();
1027 }
1028 else if(Surf1->IsVClosed()) {
1029 pv1=Surf1->LastVParameter() - Surf1->FirstVParameter();
04232180 1030 //std::cout<<" VClosed1 "<<pv1<<std::endl;
7fd59977 1031 }
1032
1033 break;
1034 }
1035 }
1036
1037 switch(TypeS2) {
1038 case GeomAbs_Cylinder:
1039 case GeomAbs_Cone:
1040 case GeomAbs_Sphere:
1041
c6541a0c 1042 pu2=M_PI+M_PI;
7fd59977 1043 break;
1044 case GeomAbs_Torus:
c6541a0c 1045 pu2=pv2=M_PI+M_PI;
7fd59977 1046 break;
1047 default:
1048 {
1049 if( Surf2->IsUPeriodic()) {
1050 pu2=Surf2->UPeriod();
1051 }
1052 else if(Surf2->IsUClosed()) {
1053 pu2=Surf2->LastUParameter() - Surf2->FirstUParameter();
04232180 1054 //std::cout<<" UClosed2 "<<pu2<<std::endl;
7fd59977 1055 }
1056
1057 if( Surf2->IsVPeriodic()) {
1058 pv2=Surf2->VPeriod();
1059 }
1060 else if(Surf2->IsVClosed()) {
1061 pv2=Surf2->LastVParameter() - Surf2->FirstVParameter();
04232180 1062 //std::cout<<" VClosed2 "<<pv2<<std::endl;
7fd59977 1063 }
1064
1065 break;
1066 }
1067 }
1068
1069/*
1070 if(pu1==0) {
1071 pu1=Surf1->LastUParameter() - Surf1->FirstUParameter();
1072 pu1+=pu1;
1073 }
1074 if(pu2==0) {
1075 pu2=Surf2->LastUParameter() - Surf2->FirstUParameter();
1076 pu2+=pu2;
1077 }
1078 if(pv1==0) {
1079 pv1=Surf1->LastVParameter() - Surf1->FirstVParameter();
1080 pv1+=pv1;
1081 }
1082 if(pv2==0) {
1083 pv2=Surf2->LastVParameter() - Surf2->FirstVParameter();
1084 pv2+=pv2;
1085 }
1086*/
1087
1088 wlin->SetPeriod(pu1,pv1,pu2,pv2);
882e1d11 1089 wlin->ComputeVertexParameters(Tol);
7fd59977 1090 }
1091 else {
7fd59977 1092 rlin->ComputeVertexParameters(Tol);
1093 }
1094}