0023024: Update headers of OCCT files
[occt.git] / src / Adaptor3d / Adaptor3d_TopolTool.cxx
CommitLineData
b311480e 1// Copyright (c) 1999-2012 OPEN CASCADE SAS
2//
3// The content of this file is subject to the Open CASCADE Technology Public
4// License Version 6.5 (the "License"). You may not use the content of this file
5// except in compliance with the License. Please obtain a copy of the License
6// at http://www.opencascade.org and read it completely before using this file.
7//
8// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10//
11// The Original Code and all software distributed under the License is
12// distributed on an "AS IS" basis, without warranty of any kind, and the
13// Initial Developer hereby disclaims all such warranties, including without
14// limitation, any warranties of merchantability, fitness for a particular
15// purpose or non-infringement. Please see the License for the specific terms
16// and conditions governing the rights and limitations under the License.
17
7fd59977 18
19#include <Standard_NotImplemented.hxx>
20#include <Adaptor3d_TopolTool.ixx>
21#include <Precision.hxx>
22
23#include <gp_Cone.hxx>
24#include <gp_Pnt.hxx>
25#include <gp_Trsf.hxx>
26
27#define myInfinite 1.e15
28
29static void GetConeApexParam(const gp_Cone& C, Standard_Real& U, Standard_Real& V)
30{
31 const gp_Ax3& Pos = C.Position();
32 Standard_Real Radius = C.RefRadius();
33 Standard_Real SAngle = C.SemiAngle();
34 const gp_Pnt& P = C.Apex();
35
36 gp_Trsf T;
37 T.SetTransformation (Pos);
38 gp_Pnt Ploc = P.Transformed (T);
39
40 if(Ploc.X() ==0.0 && Ploc.Y()==0.0 ) {
41 U = 0.0;
42 }
43 else if ( -Radius > Ploc.Z()* Tan(SAngle) ) {
0d969553 44 // the point is at the `wrong` side of the apex
7fd59977 45 U = atan2(-Ploc.Y(), -Ploc.X());
46 }
47 else {
48 U = atan2(Ploc.Y(),Ploc.X());
49 }
c6541a0c 50 if (U < -1.e-16) U += (M_PI+M_PI);
7fd59977 51 else if (U < 0) U = 0;
52
53 V = sin(SAngle) * ( Ploc.X() * cos(U) + Ploc.Y() * sin(U) - Radius)
54 + cos(SAngle) * Ploc.Z();
55}
56
57
58Adaptor3d_TopolTool::Adaptor3d_TopolTool () : nbRestr(0),idRestr(0),myNbSamplesU(-1)
59
60{
61}
62
63Adaptor3d_TopolTool::Adaptor3d_TopolTool (const Handle(Adaptor3d_HSurface)& S)
64{
65 Initialize(S);
66}
67
68
69void Adaptor3d_TopolTool::Initialize ()
70{
71 Standard_NotImplemented::Raise("Adaptor3d_TopolTool::Initialize ()");
72}
73
74void Adaptor3d_TopolTool::Initialize (const Handle(Adaptor3d_HSurface)& S)
75{
76 Standard_Real pinf,psup,deltap;
77 //Adaptor2d_Line2d * Line2dPtr ;
78
79 myNbSamplesU=-1;
0d969553 80 Uinf = S->FirstUParameter(); // where UIntervalFirst ??
7fd59977 81 Vinf = S->FirstVParameter();
82 Usup = S->LastUParameter();
83 Vsup = S->LastVParameter();
84 nbRestr = 0;
85 idRestr = 0;
86
87 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
88 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
89 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
90 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
91
92 if (! Vinfinfinite) {
93 deltap = Min(Usup-Uinf,2.*myInfinite);
94 if (Uinf >= -myInfinite){
95 pinf = Uinf;
96 psup = pinf + deltap;
97 }
98 else if (Usup <= myInfinite) {
99 psup = Usup;
100 pinf = psup - deltap;
101 }
102 else {
103 pinf = -myInfinite;
104 psup = myInfinite;
105 }
106
107 // Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup);
108 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
109 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup));
110 nbRestr++;
111 }
112
113 if (!Usupinfinite) {
114 deltap = Min(Vsup-Vinf,2.*myInfinite);
115 if (Vinf >= -myInfinite){
116 pinf = Vinf;
117 psup = pinf + deltap;
118 }
119 else if (Vsup <= myInfinite) {
120 psup = Vsup;
121 pinf = psup - deltap;
122 }
123 else {
124 pinf = -myInfinite;
125 psup = myInfinite;
126 }
127
128
129
130 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup);
131 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
132 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup));
133 nbRestr++;
134 }
135
136 if (!Vsupinfinite) {
137 deltap = Min(Usup-Uinf,2.*myInfinite);
138 if (-Usup >= -myInfinite){
139 pinf = -Usup;
140 psup = pinf + deltap;
141 }
142 else if (-Uinf <= myInfinite) {
143 psup = -Uinf;
144 pinf = psup - deltap;
145 }
146 else {
147 pinf = -myInfinite;
148 psup = myInfinite;
149 }
150
151
152 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup);
153 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
154 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup));
155 nbRestr++;
156 }
157
158 if (!Uinfinfinite) {
159 deltap = Min(Vsup-Vinf,2.*myInfinite);
160 if (-Vsup >= -myInfinite){
161 pinf = -Vsup;
162 psup = pinf + deltap;
163 }
164 else if (-Vinf <= myInfinite) {
165 psup = -Vinf;
166 pinf = psup - deltap;
167 }
168 else {
169 pinf = -myInfinite;
170 psup = myInfinite;
171 }
172
173 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup);
174 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
175 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup));
176 nbRestr++;
177 }
178
179 myS = S;
180
181 if(nbRestr == 2 && S->GetType() == GeomAbs_Cone ) {
182 Standard_Real U = 0., V = 0.;
183 GetConeApexParam(S->Cone(),U,V);
184
185 deltap = Min(Usup-Uinf,2.*myInfinite);
186 if (Uinf >= -myInfinite){
187 pinf = Uinf;
188 psup = pinf + deltap;
189 }
190 else if (Usup <= myInfinite) {
191 psup = Usup;
192 pinf = psup - deltap;
193 }
194 else {
195 pinf = -myInfinite;
196 psup = myInfinite;
197 }
198
199 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup);
200 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
201 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup));
202 nbRestr++;
203 }
204}
205
206
207void Adaptor3d_TopolTool::Init ()
208{
209 idRestr = 0;
210}
211
212
213Standard_Boolean Adaptor3d_TopolTool::More ()
214{
215 return (idRestr < nbRestr);
216}
217
218Handle(Adaptor2d_HCurve2d) Adaptor3d_TopolTool::Value ()
219{
220 if (idRestr >= nbRestr) {Standard_DomainError::Raise();}
221 return myRestr[idRestr];
222}
223
224void Adaptor3d_TopolTool::Next ()
225{
226 idRestr++;
227}
228
229
230void Adaptor3d_TopolTool::Initialize(const Handle(Adaptor2d_HCurve2d)& C)
231{
232 nbVtx = 0;
233 idVtx = 0;
234 Standard_Real theUinf,theUsup;
235 theUinf = C->FirstParameter();
236 theUsup = C->LastParameter();
237// if (!Precision::IsNegativeInfinite(theUinf)) {
238 if (theUinf > -myInfinite) {
239 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUinf),TopAbs_FORWARD,1.e-8);
240 nbVtx++;
241 }
242// if (!Precision::IsPositiveInfinite(theUsup)) {
243 if (theUsup < myInfinite) {
244 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUsup),TopAbs_REVERSED,1.e-8);
245 nbVtx++;
246 }
247}
248
249
250void Adaptor3d_TopolTool::InitVertexIterator ()
251{
252 idVtx = 0;
253}
254
255
256Standard_Boolean Adaptor3d_TopolTool::MoreVertex ()
257{
258 return (idVtx < nbVtx);
259}
260
261
262Handle(Adaptor3d_HVertex) Adaptor3d_TopolTool::Vertex ()
263{
264 if (idVtx >= nbVtx) {Standard_DomainError::Raise();}
265 return myVtx[idVtx];
266}
267
268void Adaptor3d_TopolTool::NextVertex ()
269{
270 idVtx++;
271}
272
273
274TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
275 const Standard_Real Tol,
276 const Standard_Boolean )
277// const Standard_Boolean RecadreOnPeriodic)
278{
279
280 Standard_Real U = P.X();
281 Standard_Real V = P.Y();
282
283 if (nbRestr == 4) {
284 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
285 (V < Vinf - Tol) || (V > Vsup + Tol)) {
286 return TopAbs_OUT;
287 }
288 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
289 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
290 return TopAbs_ON;
291 }
292 return TopAbs_IN;
293 }
294 else if (nbRestr == 0) {
295 return TopAbs_IN;
296 }
297 else {
298 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
299 if (Precision::IsNegativeInfinite(Uinf) &&
300 Precision::IsPositiveInfinite(Usup)) {
301 dansu = Standard_True;
302 surumin = surumax = Standard_False;
303 }
304 else if (Precision::IsNegativeInfinite(Uinf)) {
305 surumin = Standard_False;
306 if (U >= Usup+Tol) {
307 dansu = Standard_False;
308 surumax = Standard_False;
309 }
310 else {
311 dansu = Standard_True;
312 surumax = Standard_False;
313 if (Abs(U-Usup)<=Tol) {
314 surumax = Standard_True;
315 }
316 }
317 }
318 else if (Precision::IsPositiveInfinite(Usup)) {
319 surumax = Standard_False;
320 if (U < Uinf-Tol) {
321 dansu = Standard_False;
322 surumin = Standard_False;
323 }
324 else {
325 dansu = Standard_True;
326 surumin = Standard_False;
327 if (Abs(U-Uinf)<=Tol) {
328 surumin = Standard_True;
329 }
330 }
331 }
332 else {
333 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
334 surumin = surumax = dansu = Standard_False;
335 }
336 else {
337 dansu = Standard_True;
338 surumin = surumax = Standard_False;
339 if (Abs(U-Uinf)<=Tol) {
340 surumin = Standard_True;
341 }
342 else if (Abs(U-Usup)<=Tol) {
343 surumax = Standard_True;
344 }
345 }
346 }
347
348 if (Precision::IsNegativeInfinite(Vinf) &&
349 Precision::IsPositiveInfinite(Vsup)) {
350 dansv = Standard_True;
351 survmin = survmax = Standard_False;
352 }
353 else if (Precision::IsNegativeInfinite(Vinf)) {
354 survmin = Standard_False;
355 if (V > Vsup+Tol) {
356 dansv = Standard_False;
357 survmax = Standard_False;
358 }
359 else {
360 dansv = Standard_True;
361 survmax = Standard_False;
362 if (Abs(V-Vsup)<=Tol) {
363 survmax = Standard_True;
364 }
365 }
366 }
367 else if (Precision::IsPositiveInfinite(Vsup)) {
368 survmax = Standard_False;
369 if (V < Vinf-Tol) {
370 dansv = Standard_False;
371 survmin = Standard_False;
372 }
373 else {
374 dansv = Standard_True;
375 survmin = Standard_False;
376 if (Abs(V-Vinf)<=Tol) {
377 survmin = Standard_True;
378 }
379 }
380 }
381 else {
382 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
383 survmin = survmax = dansv = Standard_False;
384 }
385 else {
386 dansv = Standard_True;
387 survmin = survmax = Standard_False;
388 if (Abs(V-Vinf)<=Tol) {
389 survmin = Standard_True;
390 }
391 else if (Abs(V-Vsup)<=Tol) {
392 survmax = Standard_True;
393 }
394 }
395 }
396
397 if (!dansu || !dansv) {
398 return TopAbs_OUT;
399 }
400 if (surumin || survmin || surumax || survmax) {
401 return TopAbs_ON;
402 }
403 return TopAbs_IN;
404 }
405}
406
407
408
409Standard_Boolean Adaptor3d_TopolTool::IsThePointOn(const gp_Pnt2d& P,
410 const Standard_Real Tol,
411 const Standard_Boolean )
412// const Standard_Boolean RecadreOnPeriodic)
413{
414
415 Standard_Real U = P.X();
416 Standard_Real V = P.Y();
417
418 if (nbRestr == 4) {
419 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
420 (V < Vinf - Tol) || (V > Vsup + Tol)) {
421 return(Standard_False);
422 }
423 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
424 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
425 return(Standard_True);
426 }
427 return(Standard_False);
428 }
429 else if (nbRestr == 0) {
430 return(Standard_False);
431 }
432 else {
433 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
434 if (Precision::IsNegativeInfinite(Uinf) &&
435 Precision::IsPositiveInfinite(Usup)) {
436 dansu = Standard_True;
437 surumin = surumax = Standard_False;
438 }
439 else if (Precision::IsNegativeInfinite(Uinf)) {
440 surumin = Standard_False;
441 if (U >= Usup+Tol) {
442 dansu = Standard_False;
443 surumax = Standard_False;
444 }
445 else {
446 dansu = Standard_True;
447 surumax = Standard_False;
448 if (Abs(U-Usup)<=Tol) {
449 surumax = Standard_True;
450 }
451 }
452 }
453 else if (Precision::IsPositiveInfinite(Usup)) {
454 surumax = Standard_False;
455 if (U < Uinf-Tol) {
456 dansu = Standard_False;
457 surumin = Standard_False;
458 }
459 else {
460 dansu = Standard_True;
461 surumin = Standard_False;
462 if (Abs(U-Uinf)<=Tol) {
463 surumin = Standard_True;
464 }
465 }
466 }
467 else {
468 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
469 surumin = surumax = dansu = Standard_False;
470 }
471 else {
472 dansu = Standard_True;
473 surumin = surumax = Standard_False;
474 if (Abs(U-Uinf)<=Tol) {
475 surumin = Standard_True;
476 }
477 else if (Abs(U-Usup)<=Tol) {
478 surumax = Standard_True;
479 }
480 }
481 }
482
483 if (Precision::IsNegativeInfinite(Vinf) &&
484 Precision::IsPositiveInfinite(Vsup)) {
485 dansv = Standard_True;
486 survmin = survmax = Standard_False;
487 }
488 else if (Precision::IsNegativeInfinite(Vinf)) {
489 survmin = Standard_False;
490 if (V > Vsup+Tol) {
491 dansv = Standard_False;
492 survmax = Standard_False;
493 }
494 else {
495 dansv = Standard_True;
496 survmax = Standard_False;
497 if (Abs(V-Vsup)<=Tol) {
498 survmax = Standard_True;
499 }
500 }
501 }
502 else if (Precision::IsPositiveInfinite(Vsup)) {
503 survmax = Standard_False;
504 if (V < Vinf-Tol) {
505 dansv = Standard_False;
506 survmin = Standard_False;
507 }
508 else {
509 dansv = Standard_True;
510 survmin = Standard_False;
511 if (Abs(V-Vinf)<=Tol) {
512 survmin = Standard_True;
513 }
514 }
515 }
516 else {
517 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
518 survmin = survmax = dansv = Standard_False;
519 }
520 else {
521 dansv = Standard_True;
522 survmin = survmax = Standard_False;
523 if (Abs(V-Vinf)<=Tol) {
524 survmin = Standard_True;
525 }
526 else if (Abs(V-Vsup)<=Tol) {
527 survmax = Standard_True;
528 }
529 }
530 }
531
532 if (!dansu || !dansv) {
533 return(Standard_False);
534 }
535 if (surumin || survmin || surumax || survmax) {
536 return(Standard_True);
537 }
538 return(Standard_False);;
539 }
540}
541
542
543TopAbs_Orientation Adaptor3d_TopolTool::Orientation
544 (const Handle(Adaptor2d_HCurve2d)&)
545{
546 return TopAbs_FORWARD;
547}
548
549TopAbs_Orientation Adaptor3d_TopolTool::Orientation
550 (const Handle(Adaptor3d_HVertex)& V)
551{
552 return V->Orientation();
553}
554
555Standard_Boolean Adaptor3d_TopolTool::Identical
556 (const Handle(Adaptor3d_HVertex)& V1,
557 const Handle(Adaptor3d_HVertex)& V2)
558{
559 return V1->IsSame(V2);
560}
561
562
563//-- ============================================================
564//-- m e t h o d e s u t i l i s e e s p o u r l e s
565//-- s a m p l e s
566//-- ============================================================
567#include <TColgp_Array2OfPnt.hxx>
568#include <Geom_BezierSurface.hxx>
569#include <Geom_BSplineSurface.hxx>
570#include <TColStd_Array1OfReal.hxx>
571#include <TColStd_Array1OfBoolean.hxx>
572//#include <gce_MakeLin.hxx>
573#include <gp_Lin.hxx>
574#include <gp_Dir.hxx>
575#include <gp_Vec.hxx>
576
577#define myMinPnts 4 //Absolut possible minimum of sample points
578 //Restriction of IntPolyh
579
580
581static void Analyse(const TColgp_Array2OfPnt& array2,
582 const Standard_Integer nbup,
583 const Standard_Integer nbvp,
584 Standard_Integer& myNbSamplesU,
585 Standard_Integer& myNbSamplesV) {
586 gp_Vec Vi,Vip1;
587 Standard_Integer sh,nbch,i,j;
588
589 sh = 1;
590 nbch = 0;
591 if(nbvp>2) {
592 for(i=2;i<nbup;i++) {
593 const gp_Pnt& A=array2.Value(i,1);
594 const gp_Pnt& B=array2.Value(i,2);
595 const gp_Pnt& C=array2.Value(i,3);
596 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
597 C.Y()-B.Y()-B.Y()+A.Y(),
598 C.Z()-B.Z()-B.Z()+A.Z());
599 Standard_Integer locnbch=0;
0d969553 600 for(j=3; j<nbvp;j++) { //-- try
7fd59977 601 const gp_Pnt& A1=array2.Value(i,j-1);
602 const gp_Pnt& B1=array2.Value(i,j);
603 const gp_Pnt& C1=array2.Value(i,j+1);
604 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
605 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
606 C1.Z()-B1.Z()-B1.Z()+A1.Z());
607 Standard_Real pd = Vi.Dot(Vip1);
608 Vi=Vip1;
609 if(pd>1.0e-7 || pd<-1.0e-7) {
610 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
611 else { if(sh==1) { sh=-1; locnbch++; } }
612 }
613 }
614 if(locnbch>nbch) {
615 nbch=locnbch;
616 }
617 }
618 }
619 myNbSamplesV = nbch+5;
620
621 nbch=0;
622 if(nbup>2) {
623 for(j=2;j<nbvp;j++) {
624 const gp_Pnt& A=array2.Value(1,j);
625 const gp_Pnt& B=array2.Value(2,j);
626 const gp_Pnt& C=array2.Value(3,j);
627 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
628 C.Y()-B.Y()-B.Y()+A.Y(),
629 C.Z()-B.Z()-B.Z()+A.Z());
630 Standard_Integer locnbch=0;
0d969553 631 for(i=3; i<nbup;i++) { //-- try
7fd59977 632 const gp_Pnt& A1=array2.Value(i-1,j);
633 const gp_Pnt& B1=array2.Value(i,j);
634 const gp_Pnt& C1=array2.Value(i+1,j);
635 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
636 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
637 C1.Z()-B1.Z()-B1.Z()+A1.Z());
638 Standard_Real pd = Vi.Dot(Vip1);
639 Vi=Vip1;
640 if(pd>1.0e-7 || pd<-1.0e-7) {
641 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
642 else { if(sh==1) { sh=-1; locnbch++; } }
643 }
644 }
645 if(locnbch>nbch) nbch=locnbch;
646 }
647 }
648 myNbSamplesU = nbch+5;
649}
650
651
652void Adaptor3d_TopolTool::ComputeSamplePoints() {
653 Standard_Real uinf,usup,vinf,vsup;
654 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
655 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
656 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
657 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
658 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
659 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
660 else if (usup == RealLast()) { usup=uinf+2.e5; }
661
662 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
663 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
664 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
665
666 Standard_Integer nbsu,nbsv;
667 GeomAbs_SurfaceType typS = myS->GetType();
668 switch(typS) {
669 case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
670 case GeomAbs_BezierSurface: { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles(); } break;
671 case GeomAbs_BSplineSurface: {
672 nbsv = myS->NbVKnots(); nbsv*= myS->VDegree(); if(nbsv < 4) nbsv=4;
673 nbsu = myS->NbUKnots(); nbsu*= myS->UDegree(); if(nbsu < 4) nbsu=4;
674 }
675 break;
676 case GeomAbs_Cylinder:
677 case GeomAbs_Cone:
678 case GeomAbs_Sphere:
679 case GeomAbs_Torus:
680 case GeomAbs_SurfaceOfRevolution:
681 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=15; } break;
682 default: { nbsu = 10; nbsv=10; } break;
683 }
684
0d969553 685 //-- If the number of points is too great... analyze
7fd59977 686 //--
687 //--
688
689 if(nbsu<6) nbsu=6;
690 if(nbsv<6) nbsv=6;
691
692 myNbSamplesU = nbsu;
693 myNbSamplesV = nbsv;
694
695 if(nbsu>8 || nbsv>8) {
696 if(typS == GeomAbs_BSplineSurface) {
697 const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
698 Standard_Integer nbup = Bspl->NbUPoles();
699 Standard_Integer nbvp = Bspl->NbVPoles();
700 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
701 Bspl->Poles(array2);
702 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
703 }
704 else if(typS == GeomAbs_BezierSurface) {
705 const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
706 Standard_Integer nbup = Bez->NbUPoles();
707 Standard_Integer nbvp = Bez->NbVPoles();
708 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
709 Bez->Poles(array2);
710 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
711 }
712 }
713}
714
715Standard_Integer Adaptor3d_TopolTool::NbSamplesU()
716{
717 if(myNbSamplesU <0) {
718 ComputeSamplePoints();
719 }
720 return(myNbSamplesU);
721}
722
723Standard_Integer Adaptor3d_TopolTool::NbSamplesV()
724{
725 if(myNbSamplesU <0) {
726 ComputeSamplePoints();
727 }
728 return(myNbSamplesV);
729}
730
731Standard_Integer Adaptor3d_TopolTool::NbSamples()
732{
733 if(myNbSamplesU <0) {
734 ComputeSamplePoints();
735 }
736 return(myNbSamplesU*myNbSamplesV);
737}
738
739void Adaptor3d_TopolTool::UParameters(TColStd_Array1OfReal& theArray) const
740{
741 theArray = myUPars->Array1();
742}
743
744void Adaptor3d_TopolTool::VParameters(TColStd_Array1OfReal& theArray) const
745{
746 theArray = myVPars->Array1();
747}
748
749void Adaptor3d_TopolTool::SamplePoint(const Standard_Integer i,
750 gp_Pnt2d& P2d,
751 gp_Pnt& P3d)
752{
753 Standard_Integer iu, iv;
754 Standard_Real u, v;
755 if (myUPars.IsNull())
756 {
757 Standard_Real myDU=(Usup-Uinf)/(myNbSamplesU+1);
758 Standard_Real myDV=(Vsup-Vinf)/(myNbSamplesV+1);
759 iv = 1 + i/myNbSamplesU;
760 iu = 1+ i-(iv-1)*myNbSamplesU;
761 u=Uinf+iu*myDU;
762 v=Vinf+iv*myDV;
763 }
764 else
765 {
766 iv = (i-1)/myNbSamplesU + 1;
767 iu = (i-1)%myNbSamplesU + 1;
768 u = myUPars->Value(iu);
769 v = myVPars->Value(iv);
770 }
771
772 P2d.SetCoord(u,v);
773 P3d = myS->Value(u,v);
774}
775
776
777
778Standard_Boolean Adaptor3d_TopolTool::DomainIsInfinite() {
779 if(Precision::IsNegativeInfinite(Uinf)) return(Standard_True);
780 if(Precision::IsPositiveInfinite(Usup)) return(Standard_True);
781 if(Precision::IsNegativeInfinite(Vinf)) return(Standard_True);
782 if(Precision::IsPositiveInfinite(Vsup)) return(Standard_True);
783 return(Standard_False);
784}
7fd59977 785//=======================================================================
786//function : Edge
787//purpose :
788//=======================================================================
789 Standard_Address Adaptor3d_TopolTool::Edge() const
790{
791 return NULL;
792}
7fd59977 793//=======================================================================
794//function : Has3d
795//purpose :
796//=======================================================================
797
798Standard_Boolean Adaptor3d_TopolTool::Has3d() const
799{
800 return Standard_False;
801}
802
803//=======================================================================
804//function : Tol3d
805//purpose :
806//=======================================================================
807
808Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)&) const
809{
810 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
811 return 0.;
812}
813
814//=======================================================================
815//function : Tol3d
816//purpose :
817//=======================================================================
818
819Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)&) const
820{
821 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
822 return 0.;
823}
824
825//=======================================================================
826//function : Pnt
827//purpose :
828//=======================================================================
829
830gp_Pnt Adaptor3d_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)&) const
831{
832 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
833 return gp::Origin();
834}
835
836
837//=======================================================================
838//function : SamplePnts
839//purpose :
840//=======================================================================
841
842void Adaptor3d_TopolTool::SamplePnts(const Standard_Real theDefl,
843 const Standard_Integer theNUmin,
844 const Standard_Integer theNVmin)
845{
846 Standard_Real uinf,usup,vinf,vsup;
847 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
848 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
849 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
850 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
851 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
852 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
853 else if (usup == RealLast()) { usup=uinf+2.e5; }
854
855 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
856 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
857 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
858
859// Standard_Integer nbsu,nbsv;
860 GeomAbs_SurfaceType typS = myS->GetType();
861// switch(typS) {
862// case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
863// case GeomAbs_BezierSurface: {
864// nbsv=myS->NbVPoles();
865// nbsu=myS->NbUPoles();
866// nbsu = Max(nbsu, theNUmin);
867// nbsv = Max(nbsv, theNVmin);
868// if(nbsu>8 || nbsv>8) {
869// const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
870// Standard_Integer nbup = Bez->NbUPoles();
871// Standard_Integer nbvp = Bez->NbVPoles();
872// TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
873// Bez->Poles(array2);
874// Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
875// }
876// }
877// break;
878// case GeomAbs_BSplineSurface: {
879 if(typS == GeomAbs_BSplineSurface) {
0d969553 880 // Processing BSpline surface
7fd59977 881 BSplSamplePnts(theDefl, theNUmin, theNVmin);
882 return;
883 }
884 else {
885 ComputeSamplePoints();
886 }
887// case GeomAbs_Cylinder:
888// case GeomAbs_Cone:
889// case GeomAbs_Sphere:
890// case GeomAbs_Torus:
891// case GeomAbs_SurfaceOfRevolution:
892// case GeomAbs_SurfaceOfExtrusion: { nbsv = Max(15,theNVmin); nbsu=Max(15,theNUmin); } break;
893// default: { nbsu = Max(10,theNUmin); nbsv=Max(10,theNVmin); } break;
894// }
895
896
897// if(nbsu<6) nbsu=6;
898// if(nbsv<6) nbsv=6;
899
900// myNbSamplesU = nbsu;
901// myNbSamplesV = nbsv;
902
903
904 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
905 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
906 Standard_Integer i;
907 Standard_Real t, dt = (usup - uinf)/(myNbSamplesU - 1);
908 myUPars->SetValue(1, uinf);
909 myUPars->SetValue(myNbSamplesU, usup);
910 for(i = 2, t = uinf+dt; i < myNbSamplesU; ++i, t += dt) {
911 myUPars->SetValue(i, t);
912 }
913
914 dt = (vsup - vinf)/(myNbSamplesV - 1);
915 myVPars->SetValue(1, vinf);
916 myVPars->SetValue(myNbSamplesV, vsup);
917 for(i = 2, t = vinf+dt; i < myNbSamplesV; ++i, t += dt) {
918 myVPars->SetValue(i, t);
919 }
920
921 return;
922
923}
924
925//=======================================================================
926//function : BSplSamplePnts
927//purpose :
928//=======================================================================
929
930void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
931 const Standard_Integer theNUmin,
932 const Standard_Integer theNVmin)
933{
934 const Handle(Geom_BSplineSurface)& aBS = myS->BSpline();
935 Standard_Real uinf,usup,vinf,vsup;
936 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
937 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
938
939 Standard_Integer i, j, k, nbi;
940 Standard_Real t1, t2, dt;
941 Standard_Integer ui1 = aBS->FirstUKnotIndex();
942 Standard_Integer ui2 = aBS->LastUKnotIndex();
943 Standard_Integer vi1 = aBS->FirstVKnotIndex();
944 Standard_Integer vi2 = aBS->LastVKnotIndex();
945
946 for(i = ui1; i < ui2; ++i) {
947 if(uinf >= aBS->UKnot(i) && uinf < aBS->UKnot(i+1)) {
948 ui1 = i;
949 break;
950 }
951 }
952
953 for(i = ui2; i > ui1; --i) {
954 if(usup <= aBS->UKnot(i) && usup > aBS->UKnot(i-1)) {
955 ui2 = i;
956 break;
957 }
958 }
959
960 for(i = vi1; i < vi2; ++i) {
961 if(vinf >= aBS->VKnot(i) && vinf < aBS->VKnot(i+1)) {
962 vi1 = i;
963 break;
964 }
965 }
966
967 for(i = vi2; i > vi1; --i) {
968 if(vsup <= aBS->VKnot(i) && vsup > aBS->VKnot(i-1)) {
969 vi2 = i;
970 break;
971 }
972 }
973
974 Standard_Integer nbsu = ui2-ui1+1; nbsu += (nbsu - 1) * (aBS->UDegree()-1);
975 Standard_Integer nbsv = vi2-vi1+1; nbsv += (nbsv - 1) * (aBS->VDegree()-1);
976 Standard_Boolean bUuniform = Standard_False;
977 Standard_Boolean bVuniform = Standard_False;
978
979 if(nbsu < theNUmin) {
980 nbsu = theNUmin;
981 bUuniform = Standard_True;
982 }
983
984 if(nbsv < theNVmin) {
985 nbsv = theNVmin;
986 bVuniform = Standard_True;
987 }
988
989 TColStd_Array1OfReal anUPars(1, nbsu);
990 TColStd_Array1OfBoolean anUFlg(1, nbsu);
991 TColStd_Array1OfReal aVPars(1, nbsv);
992 TColStd_Array1OfBoolean aVFlg(1, nbsv);
993
994 //Filling of sample parameters
995 if(bUuniform) {
996 t1 = uinf;
997 t2 = usup;
998 dt = (t2 - t1)/(nbsu - 1);
999 anUPars(1) = t1;
1000 anUFlg(1) = Standard_False;
1001 anUPars(nbsu) = t2;
1002 anUFlg(nbsu) = Standard_False;
1003 for(i = 2, t1 += dt; i < nbsu; ++i, t1 += dt) {
1004 anUPars(i) = t1;
1005 anUFlg(i) = Standard_False;
1006 }
1007 }
1008 else {
1009 nbi = aBS->UDegree();
1010 k = 0;
1011 t1 = uinf;
1012 for(i = ui1+1; i <= ui2; ++i) {
1013 if(i == ui2) t2 = usup;
1014 else t2 = aBS->UKnot(i);
1015 dt = (t2 - t1)/nbi;
1016 j = 1;
1017 do {
1018 ++k;
1019 anUPars(k) = t1;
1020 anUFlg(k) = Standard_False;
1021 t1 += dt;
1022 }
1023 while (++j <= nbi);
1024 t1 = t2;
1025 }
1026 ++k;
1027 anUPars(k) = t1;
1028 }
1029
1030 if(bVuniform) {
1031 t1 = vinf;
1032 t2 = vsup;
1033 dt = (t2 - t1)/(nbsv - 1);
1034 aVPars(1) = t1;
1035 aVFlg(1) = Standard_False;
1036 aVPars(nbsv) = t2;
1037 aVFlg(nbsv) = Standard_False;
1038 for(i = 2, t1 += dt; i < nbsv; ++i, t1 += dt) {
1039 aVPars(i) = t1;
1040 aVFlg(i) = Standard_False;
1041 }
1042 }
1043 else {
1044 nbi = aBS->VDegree();
1045 k = 0;
1046 t1 = vinf;
1047 for(i = vi1+1; i <= vi2; ++i) {
1048 if(i == vi2) t2 = vsup;
1049 else t2 = aBS->VKnot(i);
1050 dt = (t2 - t1)/nbi;
1051 j = 1;
1052 do {
1053 ++k;
1054 aVPars(k) = t1;
1055 aVFlg(k) = Standard_False;
1056 t1 += dt;
1057 }
1058 while (++j <= nbi);
1059 t1 = t2;
1060 }
1061 ++k;
1062 aVPars(k) = t1;
1063 }
1064
1065 //Analysis of deflection
1066
1067 Standard_Real aDefl2 = Max(theDefl*theDefl, 1.e-9);
1068 Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
1069 Standard_Integer l;
1070
1071 anUFlg(1) = Standard_True;
1072 anUFlg(nbsu) = Standard_True;
1073 myNbSamplesU = 2;
1074 for(i = 1; i <= nbsv; ++i) {
1075 t1 = aVPars(i);
1076 j = 1;
1077 Standard_Boolean bCont = Standard_True;
1078 while (j < nbsu-1 && bCont) {
1079
1080 if(anUFlg(j+1)) {
1081 ++j;
1082 continue;
1083 }
1084
1085 t2 = anUPars(j);
1086 gp_Pnt p1 = aBS->Value(t2, t1);
1087 for(k = j+2; k <= nbsu; ++k) {
1088 t2 = anUPars(k);
1089 gp_Pnt p2 = aBS->Value(t2, t1);
1090 //gce_MakeLin MkLin(p1, p2);
1091 //const gp_Lin& lin = MkLin.Value();
1092
1093 if(p1.SquareDistance(p2) <= tol) continue;
1094
1095 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1096 Standard_Boolean ok = Standard_True;
1097 for(l = j+1; l < k; ++l) {
1098
1099 if(anUFlg(l)) {
1100 ok = Standard_False;
1101 break;
1102 }
1103
1104 gp_Pnt pp = aBS->Value(anUPars(l), t1);
1105 Standard_Real d = lin.SquareDistance(pp);
1106
1107 if(d <= aDefl2) continue;
1108
1109 ok = Standard_False;
1110 break;
1111 }
1112
1113 if(!ok) {
1114 j = k - 1;
1115 anUFlg(j) = Standard_True;
1116 ++myNbSamplesU;
1117 break;
1118 }
1119
1120 if(anUFlg(k)) {
1121 j = k;
1122 break;
1123 }
1124
1125
1126 }
1127
1128 if(k >= nbsu) bCont = Standard_False;
1129
1130 }
1131 }
1132 if(myNbSamplesU < myMinPnts) {
1133 if(myNbSamplesU == 2) {
1134 //"uniform" distribution;
1135 Standard_Integer nn = nbsu/myMinPnts;
1136 anUFlg(1+nn) = Standard_True;
1137 anUFlg(nbsu-nn) = Standard_True;
1138 }
1139 else { //myNbSamplesU == 3
1140 //insert in bigger segment
1141 i = 2;
1142 while(!anUFlg(i++));
1143 if(i < nbsu/2) j = Min(i+(nbsu-i)/2, nbsu-1);
1144 else j = Max(i/2, 2);
1145 }
1146 anUFlg(j) = Standard_True;
1147 myNbSamplesU = myMinPnts;
1148 }
1149
1150 aVFlg(1) = Standard_True;
1151 aVFlg(nbsv) = Standard_True;
1152 myNbSamplesV = 2;
1153 for(i = 1; i <= nbsu; ++i) {
1154 t1 = anUPars(i);
1155 j = 1;
1156 Standard_Boolean bCont = Standard_True;
1157 while (j < nbsv-1 && bCont) {
1158
1159 if(aVFlg(j+1)) {
1160 ++j;
1161 continue;
1162 }
1163
1164 t2 = aVPars(j);
1165 gp_Pnt p1 = aBS->Value(t1, t2);
1166 for(k = j+2; k <= nbsv; ++k) {
1167 t2 = aVPars(k);
1168 gp_Pnt p2 = aBS->Value(t1, t2);
1169
1170 if(p1.SquareDistance(p2) <= tol) continue;
1171 //gce_MakeLin MkLin(p1, p2);
1172 //const gp_Lin& lin = MkLin.Value();
1173 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1174 Standard_Boolean ok = Standard_True;
1175 for(l = j+1; l < k; ++l) {
1176
1177 if(aVFlg(l)) {
1178 ok = Standard_False;
1179 break;
1180 }
1181
1182 gp_Pnt pp = aBS->Value(t1, aVPars(l));
1183 Standard_Real d = lin.SquareDistance(pp);
1184
1185 if(d <= aDefl2) continue;
1186
1187 ok = Standard_False;
1188 break;
1189 }
1190
1191 if(!ok) {
1192 j = k - 1;
1193 aVFlg(j) = Standard_True;
1194 ++myNbSamplesV;
1195 break;
1196 }
1197
1198 if(aVFlg(k)) {
1199 j = k;
1200 break;
1201 }
1202
1203
1204 }
1205
1206 if(k >= nbsv) bCont = Standard_False;
1207
1208 }
1209 }
1210 if(myNbSamplesV < myMinPnts) {
1211 if(myNbSamplesV == 2) {
1212 //"uniform" distribution;
1213 Standard_Integer nn = nbsv/myMinPnts;
1214 aVFlg(1+nn) = Standard_True;
1215 aVFlg(nbsv-nn) = Standard_True;
1216 myNbSamplesV = myMinPnts;
1217 }
1218 else { //myNbSamplesU == 3
1219 //insert in bigger segment
1220 i = 2;
1221 while(!aVFlg(i++));
1222 if(i < nbsv/2) j = Min(i+(nbsv-i)/2, nbsv-1);
1223 else j = Max(i/2, 2);
1224 }
1225 myNbSamplesV = myMinPnts;
1226 aVFlg(j) = Standard_True;
1227 }
fa9681ca
P
1228 //
1229 //modified by NIZNHY-PKV Fri Dec 16 10:05:01 2011f
1230 //
1231 Standard_Boolean bFlag;
1232 //
1233 // U
1234 bFlag=(myNbSamplesU < theNUmin);
1235 if (bFlag) {
1236 myNbSamplesU=nbsu;
1237 }
1238 //
1239 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1240 //
1241 for(j = 0, i = 1; i <= nbsu; ++i) {
1242 if (bFlag) {
1243 myUPars->SetValue(i,anUPars(i));
1244 }
1245 else {
1246 if(anUFlg(i)) {
1247 ++j;
1248 myUPars->SetValue(j,anUPars(i));
1249 }
1250 }
1251 }
1252 //
1253 // V
1254 bFlag=(myNbSamplesV < theNVmin);
1255 if (bFlag) {
1256 myNbSamplesV=nbsv;
1257 }
1258 //
1259 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1260 //
1261 for(j = 0, i = 1; i <= nbsv; ++i) {
1262 if (bFlag) {
1263 myVPars->SetValue(i,aVPars(i));
1264 }
1265 else {
1266 if(aVFlg(i)) {
1267 ++j;
1268 myVPars->SetValue(j,aVPars(i));
1269 }
1270 }
1271 }
1272 //
1273 /*
7fd59977 1274 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1275 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1276
1277 j = 0;
1278 for(i = 1; i <= nbsu; ++i) {
1279 if(anUFlg(i)) {
1280 ++j;
1281 myUPars->SetValue(j,anUPars(i));
1282 }
1283 }
1284
1285 j = 0;
1286 for(i = 1; i <= nbsv; ++i) {
1287 if(aVFlg(i)) {
1288 ++j;
1289 myVPars->SetValue(j,aVPars(i));
1290 }
1291 }
fa9681ca
P
1292 */
1293 //modified by NIZNHY-PKV Mon Dec 26 12:25:35 2011t
7fd59977 1294
1295}
1296
fa9681ca
P
1297//=======================================================================
1298//function : IsUniformSampling
1299//purpose :
1300//=======================================================================
7fd59977 1301Standard_Boolean Adaptor3d_TopolTool::IsUniformSampling() const
1302{
1303 GeomAbs_SurfaceType typS = myS->GetType();
1304
1305 if(typS == GeomAbs_BSplineSurface)
1306 return Standard_False;
1307 return Standard_True;
1308}