2 #include <Standard_NotImplemented.hxx>
3 #include <Adaptor3d_TopolTool.ixx>
4 #include <Precision.hxx>
10 #define myInfinite 1.e15
12 static void GetConeApexParam(const gp_Cone& C, Standard_Real& U, Standard_Real& V)
14 const gp_Ax3& Pos = C.Position();
15 Standard_Real Radius = C.RefRadius();
16 Standard_Real SAngle = C.SemiAngle();
17 const gp_Pnt& P = C.Apex();
20 T.SetTransformation (Pos);
21 gp_Pnt Ploc = P.Transformed (T);
23 if(Ploc.X() ==0.0 && Ploc.Y()==0.0 ) {
26 else if ( -Radius > Ploc.Z()* Tan(SAngle) ) {
27 // the point is at the `wrong` side of the apex
28 U = atan2(-Ploc.Y(), -Ploc.X());
31 U = atan2(Ploc.Y(),Ploc.X());
33 if (U < -1.e-16) U += (PI+PI);
34 else if (U < 0) U = 0;
36 V = sin(SAngle) * ( Ploc.X() * cos(U) + Ploc.Y() * sin(U) - Radius)
37 + cos(SAngle) * Ploc.Z();
41 Adaptor3d_TopolTool::Adaptor3d_TopolTool () : nbRestr(0),idRestr(0),myNbSamplesU(-1)
46 Adaptor3d_TopolTool::Adaptor3d_TopolTool (const Handle(Adaptor3d_HSurface)& S)
52 void Adaptor3d_TopolTool::Initialize ()
54 Standard_NotImplemented::Raise("Adaptor3d_TopolTool::Initialize ()");
57 void Adaptor3d_TopolTool::Initialize (const Handle(Adaptor3d_HSurface)& S)
59 Standard_Real pinf,psup,deltap;
60 //Adaptor2d_Line2d * Line2dPtr ;
63 Uinf = S->FirstUParameter(); // where UIntervalFirst ??
64 Vinf = S->FirstVParameter();
65 Usup = S->LastUParameter();
66 Vsup = S->LastVParameter();
70 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
71 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
72 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
73 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
76 deltap = Min(Usup-Uinf,2.*myInfinite);
77 if (Uinf >= -myInfinite){
81 else if (Usup <= myInfinite) {
90 // Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup);
91 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
92 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup));
97 deltap = Min(Vsup-Vinf,2.*myInfinite);
98 if (Vinf >= -myInfinite){
100 psup = pinf + deltap;
102 else if (Vsup <= myInfinite) {
104 pinf = psup - deltap;
113 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup);
114 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
115 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup));
120 deltap = Min(Usup-Uinf,2.*myInfinite);
121 if (-Usup >= -myInfinite){
123 psup = pinf + deltap;
125 else if (-Uinf <= myInfinite) {
127 pinf = psup - deltap;
135 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup);
136 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
137 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup));
142 deltap = Min(Vsup-Vinf,2.*myInfinite);
143 if (-Vsup >= -myInfinite){
145 psup = pinf + deltap;
147 else if (-Vinf <= myInfinite) {
149 pinf = psup - deltap;
156 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup);
157 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
158 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup));
164 if(nbRestr == 2 && S->GetType() == GeomAbs_Cone ) {
165 Standard_Real U = 0., V = 0.;
166 GetConeApexParam(S->Cone(),U,V);
168 deltap = Min(Usup-Uinf,2.*myInfinite);
169 if (Uinf >= -myInfinite){
171 psup = pinf + deltap;
173 else if (Usup <= myInfinite) {
175 pinf = psup - deltap;
182 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup);
183 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
184 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup));
190 void Adaptor3d_TopolTool::Init ()
196 Standard_Boolean Adaptor3d_TopolTool::More ()
198 return (idRestr < nbRestr);
201 Handle(Adaptor2d_HCurve2d) Adaptor3d_TopolTool::Value ()
203 if (idRestr >= nbRestr) {Standard_DomainError::Raise();}
204 return myRestr[idRestr];
207 void Adaptor3d_TopolTool::Next ()
213 void Adaptor3d_TopolTool::Initialize(const Handle(Adaptor2d_HCurve2d)& C)
217 Standard_Real theUinf,theUsup;
218 theUinf = C->FirstParameter();
219 theUsup = C->LastParameter();
220 // if (!Precision::IsNegativeInfinite(theUinf)) {
221 if (theUinf > -myInfinite) {
222 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUinf),TopAbs_FORWARD,1.e-8);
225 // if (!Precision::IsPositiveInfinite(theUsup)) {
226 if (theUsup < myInfinite) {
227 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUsup),TopAbs_REVERSED,1.e-8);
233 void Adaptor3d_TopolTool::InitVertexIterator ()
239 Standard_Boolean Adaptor3d_TopolTool::MoreVertex ()
241 return (idVtx < nbVtx);
245 Handle(Adaptor3d_HVertex) Adaptor3d_TopolTool::Vertex ()
247 if (idVtx >= nbVtx) {Standard_DomainError::Raise();}
251 void Adaptor3d_TopolTool::NextVertex ()
257 TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
258 const Standard_Real Tol,
259 const Standard_Boolean )
260 // const Standard_Boolean RecadreOnPeriodic)
263 Standard_Real U = P.X();
264 Standard_Real V = P.Y();
267 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
268 (V < Vinf - Tol) || (V > Vsup + Tol)) {
271 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
272 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
277 else if (nbRestr == 0) {
281 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
282 if (Precision::IsNegativeInfinite(Uinf) &&
283 Precision::IsPositiveInfinite(Usup)) {
284 dansu = Standard_True;
285 surumin = surumax = Standard_False;
287 else if (Precision::IsNegativeInfinite(Uinf)) {
288 surumin = Standard_False;
290 dansu = Standard_False;
291 surumax = Standard_False;
294 dansu = Standard_True;
295 surumax = Standard_False;
296 if (Abs(U-Usup)<=Tol) {
297 surumax = Standard_True;
301 else if (Precision::IsPositiveInfinite(Usup)) {
302 surumax = Standard_False;
304 dansu = Standard_False;
305 surumin = Standard_False;
308 dansu = Standard_True;
309 surumin = Standard_False;
310 if (Abs(U-Uinf)<=Tol) {
311 surumin = Standard_True;
316 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
317 surumin = surumax = dansu = Standard_False;
320 dansu = Standard_True;
321 surumin = surumax = Standard_False;
322 if (Abs(U-Uinf)<=Tol) {
323 surumin = Standard_True;
325 else if (Abs(U-Usup)<=Tol) {
326 surumax = Standard_True;
331 if (Precision::IsNegativeInfinite(Vinf) &&
332 Precision::IsPositiveInfinite(Vsup)) {
333 dansv = Standard_True;
334 survmin = survmax = Standard_False;
336 else if (Precision::IsNegativeInfinite(Vinf)) {
337 survmin = Standard_False;
339 dansv = Standard_False;
340 survmax = Standard_False;
343 dansv = Standard_True;
344 survmax = Standard_False;
345 if (Abs(V-Vsup)<=Tol) {
346 survmax = Standard_True;
350 else if (Precision::IsPositiveInfinite(Vsup)) {
351 survmax = Standard_False;
353 dansv = Standard_False;
354 survmin = Standard_False;
357 dansv = Standard_True;
358 survmin = Standard_False;
359 if (Abs(V-Vinf)<=Tol) {
360 survmin = Standard_True;
365 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
366 survmin = survmax = dansv = Standard_False;
369 dansv = Standard_True;
370 survmin = survmax = Standard_False;
371 if (Abs(V-Vinf)<=Tol) {
372 survmin = Standard_True;
374 else if (Abs(V-Vsup)<=Tol) {
375 survmax = Standard_True;
380 if (!dansu || !dansv) {
383 if (surumin || survmin || surumax || survmax) {
392 Standard_Boolean Adaptor3d_TopolTool::IsThePointOn(const gp_Pnt2d& P,
393 const Standard_Real Tol,
394 const Standard_Boolean )
395 // const Standard_Boolean RecadreOnPeriodic)
398 Standard_Real U = P.X();
399 Standard_Real V = P.Y();
402 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
403 (V < Vinf - Tol) || (V > Vsup + Tol)) {
404 return(Standard_False);
406 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
407 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
408 return(Standard_True);
410 return(Standard_False);
412 else if (nbRestr == 0) {
413 return(Standard_False);
416 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
417 if (Precision::IsNegativeInfinite(Uinf) &&
418 Precision::IsPositiveInfinite(Usup)) {
419 dansu = Standard_True;
420 surumin = surumax = Standard_False;
422 else if (Precision::IsNegativeInfinite(Uinf)) {
423 surumin = Standard_False;
425 dansu = Standard_False;
426 surumax = Standard_False;
429 dansu = Standard_True;
430 surumax = Standard_False;
431 if (Abs(U-Usup)<=Tol) {
432 surumax = Standard_True;
436 else if (Precision::IsPositiveInfinite(Usup)) {
437 surumax = Standard_False;
439 dansu = Standard_False;
440 surumin = Standard_False;
443 dansu = Standard_True;
444 surumin = Standard_False;
445 if (Abs(U-Uinf)<=Tol) {
446 surumin = Standard_True;
451 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
452 surumin = surumax = dansu = Standard_False;
455 dansu = Standard_True;
456 surumin = surumax = Standard_False;
457 if (Abs(U-Uinf)<=Tol) {
458 surumin = Standard_True;
460 else if (Abs(U-Usup)<=Tol) {
461 surumax = Standard_True;
466 if (Precision::IsNegativeInfinite(Vinf) &&
467 Precision::IsPositiveInfinite(Vsup)) {
468 dansv = Standard_True;
469 survmin = survmax = Standard_False;
471 else if (Precision::IsNegativeInfinite(Vinf)) {
472 survmin = Standard_False;
474 dansv = Standard_False;
475 survmax = Standard_False;
478 dansv = Standard_True;
479 survmax = Standard_False;
480 if (Abs(V-Vsup)<=Tol) {
481 survmax = Standard_True;
485 else if (Precision::IsPositiveInfinite(Vsup)) {
486 survmax = Standard_False;
488 dansv = Standard_False;
489 survmin = Standard_False;
492 dansv = Standard_True;
493 survmin = Standard_False;
494 if (Abs(V-Vinf)<=Tol) {
495 survmin = Standard_True;
500 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
501 survmin = survmax = dansv = Standard_False;
504 dansv = Standard_True;
505 survmin = survmax = Standard_False;
506 if (Abs(V-Vinf)<=Tol) {
507 survmin = Standard_True;
509 else if (Abs(V-Vsup)<=Tol) {
510 survmax = Standard_True;
515 if (!dansu || !dansv) {
516 return(Standard_False);
518 if (surumin || survmin || surumax || survmax) {
519 return(Standard_True);
521 return(Standard_False);;
526 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
527 (const Handle(Adaptor2d_HCurve2d)&)
529 return TopAbs_FORWARD;
532 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
533 (const Handle(Adaptor3d_HVertex)& V)
535 return V->Orientation();
538 Standard_Boolean Adaptor3d_TopolTool::Identical
539 (const Handle(Adaptor3d_HVertex)& V1,
540 const Handle(Adaptor3d_HVertex)& V2)
542 return V1->IsSame(V2);
546 //-- ============================================================
547 //-- m e t h o d e s u t i l i s e e s p o u r l e s
549 //-- ============================================================
550 #include <TColgp_Array2OfPnt.hxx>
551 #include <Geom_BezierSurface.hxx>
552 #include <Geom_BSplineSurface.hxx>
553 #include <TColStd_Array1OfReal.hxx>
554 #include <TColStd_Array1OfBoolean.hxx>
555 //#include <gce_MakeLin.hxx>
556 #include <gp_Lin.hxx>
557 #include <gp_Dir.hxx>
558 #include <gp_Vec.hxx>
560 #define myMinPnts 4 //Absolut possible minimum of sample points
561 //Restriction of IntPolyh
564 static void Analyse(const TColgp_Array2OfPnt& array2,
565 const Standard_Integer nbup,
566 const Standard_Integer nbvp,
567 Standard_Integer& myNbSamplesU,
568 Standard_Integer& myNbSamplesV) {
570 Standard_Integer sh,nbch,i,j;
575 for(i=2;i<nbup;i++) {
576 const gp_Pnt& A=array2.Value(i,1);
577 const gp_Pnt& B=array2.Value(i,2);
578 const gp_Pnt& C=array2.Value(i,3);
579 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
580 C.Y()-B.Y()-B.Y()+A.Y(),
581 C.Z()-B.Z()-B.Z()+A.Z());
582 Standard_Integer locnbch=0;
583 for(j=3; j<nbvp;j++) { //-- try
584 const gp_Pnt& A1=array2.Value(i,j-1);
585 const gp_Pnt& B1=array2.Value(i,j);
586 const gp_Pnt& C1=array2.Value(i,j+1);
587 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
588 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
589 C1.Z()-B1.Z()-B1.Z()+A1.Z());
590 Standard_Real pd = Vi.Dot(Vip1);
592 if(pd>1.0e-7 || pd<-1.0e-7) {
593 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
594 else { if(sh==1) { sh=-1; locnbch++; } }
602 myNbSamplesV = nbch+5;
606 for(j=2;j<nbvp;j++) {
607 const gp_Pnt& A=array2.Value(1,j);
608 const gp_Pnt& B=array2.Value(2,j);
609 const gp_Pnt& C=array2.Value(3,j);
610 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
611 C.Y()-B.Y()-B.Y()+A.Y(),
612 C.Z()-B.Z()-B.Z()+A.Z());
613 Standard_Integer locnbch=0;
614 for(i=3; i<nbup;i++) { //-- try
615 const gp_Pnt& A1=array2.Value(i-1,j);
616 const gp_Pnt& B1=array2.Value(i,j);
617 const gp_Pnt& C1=array2.Value(i+1,j);
618 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
619 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
620 C1.Z()-B1.Z()-B1.Z()+A1.Z());
621 Standard_Real pd = Vi.Dot(Vip1);
623 if(pd>1.0e-7 || pd<-1.0e-7) {
624 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
625 else { if(sh==1) { sh=-1; locnbch++; } }
628 if(locnbch>nbch) nbch=locnbch;
631 myNbSamplesU = nbch+5;
635 void Adaptor3d_TopolTool::ComputeSamplePoints() {
636 Standard_Real uinf,usup,vinf,vsup;
637 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
638 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
639 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
640 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
641 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
642 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
643 else if (usup == RealLast()) { usup=uinf+2.e5; }
645 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
646 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
647 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
649 Standard_Integer nbsu,nbsv;
650 GeomAbs_SurfaceType typS = myS->GetType();
652 case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
653 case GeomAbs_BezierSurface: { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles(); } break;
654 case GeomAbs_BSplineSurface: {
655 nbsv = myS->NbVKnots(); nbsv*= myS->VDegree(); if(nbsv < 4) nbsv=4;
656 nbsu = myS->NbUKnots(); nbsu*= myS->UDegree(); if(nbsu < 4) nbsu=4;
659 case GeomAbs_Cylinder:
663 case GeomAbs_SurfaceOfRevolution:
664 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=15; } break;
665 default: { nbsu = 10; nbsv=10; } break;
668 //-- If the number of points is too great... analyze
678 if(nbsu>8 || nbsv>8) {
679 if(typS == GeomAbs_BSplineSurface) {
680 const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
681 Standard_Integer nbup = Bspl->NbUPoles();
682 Standard_Integer nbvp = Bspl->NbVPoles();
683 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
685 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
687 else if(typS == GeomAbs_BezierSurface) {
688 const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
689 Standard_Integer nbup = Bez->NbUPoles();
690 Standard_Integer nbvp = Bez->NbVPoles();
691 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
693 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
698 Standard_Integer Adaptor3d_TopolTool::NbSamplesU()
700 if(myNbSamplesU <0) {
701 ComputeSamplePoints();
703 return(myNbSamplesU);
706 Standard_Integer Adaptor3d_TopolTool::NbSamplesV()
708 if(myNbSamplesU <0) {
709 ComputeSamplePoints();
711 return(myNbSamplesV);
714 Standard_Integer Adaptor3d_TopolTool::NbSamples()
716 if(myNbSamplesU <0) {
717 ComputeSamplePoints();
719 return(myNbSamplesU*myNbSamplesV);
722 void Adaptor3d_TopolTool::UParameters(TColStd_Array1OfReal& theArray) const
724 theArray = myUPars->Array1();
727 void Adaptor3d_TopolTool::VParameters(TColStd_Array1OfReal& theArray) const
729 theArray = myVPars->Array1();
732 void Adaptor3d_TopolTool::SamplePoint(const Standard_Integer i,
736 Standard_Integer iu, iv;
738 if (myUPars.IsNull())
740 Standard_Real myDU=(Usup-Uinf)/(myNbSamplesU+1);
741 Standard_Real myDV=(Vsup-Vinf)/(myNbSamplesV+1);
742 iv = 1 + i/myNbSamplesU;
743 iu = 1+ i-(iv-1)*myNbSamplesU;
749 iv = (i-1)/myNbSamplesU + 1;
750 iu = (i-1)%myNbSamplesU + 1;
751 u = myUPars->Value(iu);
752 v = myVPars->Value(iv);
756 P3d = myS->Value(u,v);
761 Standard_Boolean Adaptor3d_TopolTool::DomainIsInfinite() {
762 if(Precision::IsNegativeInfinite(Uinf)) return(Standard_True);
763 if(Precision::IsPositiveInfinite(Usup)) return(Standard_True);
764 if(Precision::IsNegativeInfinite(Vinf)) return(Standard_True);
765 if(Precision::IsPositiveInfinite(Vsup)) return(Standard_True);
766 return(Standard_False);
768 //modified by NIZNHY-PKV Mon Apr 23 16:00:31 2001 f
769 //=======================================================================
772 //=======================================================================
773 Standard_Address Adaptor3d_TopolTool::Edge() const
777 //modified by NIZNHY-PKV Mon Apr 23 16:00:35 2001 t
779 //=======================================================================
782 //=======================================================================
784 Standard_Boolean Adaptor3d_TopolTool::Has3d() const
786 return Standard_False;
789 //=======================================================================
792 //=======================================================================
794 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)&) const
796 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
800 //=======================================================================
803 //=======================================================================
805 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)&) const
807 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
811 //=======================================================================
814 //=======================================================================
816 gp_Pnt Adaptor3d_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)&) const
818 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
823 //=======================================================================
824 //function : SamplePnts
826 //=======================================================================
828 void Adaptor3d_TopolTool::SamplePnts(const Standard_Real theDefl,
829 const Standard_Integer theNUmin,
830 const Standard_Integer theNVmin)
832 Standard_Real uinf,usup,vinf,vsup;
833 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
834 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
835 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
836 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
837 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
838 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
839 else if (usup == RealLast()) { usup=uinf+2.e5; }
841 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
842 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
843 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
845 // Standard_Integer nbsu,nbsv;
846 GeomAbs_SurfaceType typS = myS->GetType();
848 // case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
849 // case GeomAbs_BezierSurface: {
850 // nbsv=myS->NbVPoles();
851 // nbsu=myS->NbUPoles();
852 // nbsu = Max(nbsu, theNUmin);
853 // nbsv = Max(nbsv, theNVmin);
854 // if(nbsu>8 || nbsv>8) {
855 // const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
856 // Standard_Integer nbup = Bez->NbUPoles();
857 // Standard_Integer nbvp = Bez->NbVPoles();
858 // TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
859 // Bez->Poles(array2);
860 // Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
864 // case GeomAbs_BSplineSurface: {
865 if(typS == GeomAbs_BSplineSurface) {
866 // Processing BSpline surface
867 BSplSamplePnts(theDefl, theNUmin, theNVmin);
871 ComputeSamplePoints();
873 // case GeomAbs_Cylinder:
874 // case GeomAbs_Cone:
875 // case GeomAbs_Sphere:
876 // case GeomAbs_Torus:
877 // case GeomAbs_SurfaceOfRevolution:
878 // case GeomAbs_SurfaceOfExtrusion: { nbsv = Max(15,theNVmin); nbsu=Max(15,theNUmin); } break;
879 // default: { nbsu = Max(10,theNUmin); nbsv=Max(10,theNVmin); } break;
883 // if(nbsu<6) nbsu=6;
884 // if(nbsv<6) nbsv=6;
886 // myNbSamplesU = nbsu;
887 // myNbSamplesV = nbsv;
890 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
891 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
893 Standard_Real t, dt = (usup - uinf)/(myNbSamplesU - 1);
894 myUPars->SetValue(1, uinf);
895 myUPars->SetValue(myNbSamplesU, usup);
896 for(i = 2, t = uinf+dt; i < myNbSamplesU; ++i, t += dt) {
897 myUPars->SetValue(i, t);
900 dt = (vsup - vinf)/(myNbSamplesV - 1);
901 myVPars->SetValue(1, vinf);
902 myVPars->SetValue(myNbSamplesV, vsup);
903 for(i = 2, t = vinf+dt; i < myNbSamplesV; ++i, t += dt) {
904 myVPars->SetValue(i, t);
911 //=======================================================================
912 //function : BSplSamplePnts
914 //=======================================================================
916 void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
917 const Standard_Integer theNUmin,
918 const Standard_Integer theNVmin)
920 const Handle(Geom_BSplineSurface)& aBS = myS->BSpline();
921 Standard_Real uinf,usup,vinf,vsup;
922 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
923 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
925 Standard_Integer i, j, k, nbi;
926 Standard_Real t1, t2, dt;
927 Standard_Integer ui1 = aBS->FirstUKnotIndex();
928 Standard_Integer ui2 = aBS->LastUKnotIndex();
929 Standard_Integer vi1 = aBS->FirstVKnotIndex();
930 Standard_Integer vi2 = aBS->LastVKnotIndex();
932 for(i = ui1; i < ui2; ++i) {
933 if(uinf >= aBS->UKnot(i) && uinf < aBS->UKnot(i+1)) {
939 for(i = ui2; i > ui1; --i) {
940 if(usup <= aBS->UKnot(i) && usup > aBS->UKnot(i-1)) {
946 for(i = vi1; i < vi2; ++i) {
947 if(vinf >= aBS->VKnot(i) && vinf < aBS->VKnot(i+1)) {
953 for(i = vi2; i > vi1; --i) {
954 if(vsup <= aBS->VKnot(i) && vsup > aBS->VKnot(i-1)) {
960 Standard_Integer nbsu = ui2-ui1+1; nbsu += (nbsu - 1) * (aBS->UDegree()-1);
961 Standard_Integer nbsv = vi2-vi1+1; nbsv += (nbsv - 1) * (aBS->VDegree()-1);
962 Standard_Boolean bUuniform = Standard_False;
963 Standard_Boolean bVuniform = Standard_False;
965 if(nbsu < theNUmin) {
967 bUuniform = Standard_True;
970 if(nbsv < theNVmin) {
972 bVuniform = Standard_True;
975 TColStd_Array1OfReal anUPars(1, nbsu);
976 TColStd_Array1OfBoolean anUFlg(1, nbsu);
977 TColStd_Array1OfReal aVPars(1, nbsv);
978 TColStd_Array1OfBoolean aVFlg(1, nbsv);
980 //Filling of sample parameters
984 dt = (t2 - t1)/(nbsu - 1);
986 anUFlg(1) = Standard_False;
988 anUFlg(nbsu) = Standard_False;
989 for(i = 2, t1 += dt; i < nbsu; ++i, t1 += dt) {
991 anUFlg(i) = Standard_False;
995 nbi = aBS->UDegree();
998 for(i = ui1+1; i <= ui2; ++i) {
999 if(i == ui2) t2 = usup;
1000 else t2 = aBS->UKnot(i);
1006 anUFlg(k) = Standard_False;
1019 dt = (t2 - t1)/(nbsv - 1);
1021 aVFlg(1) = Standard_False;
1023 aVFlg(nbsv) = Standard_False;
1024 for(i = 2, t1 += dt; i < nbsv; ++i, t1 += dt) {
1026 aVFlg(i) = Standard_False;
1030 nbi = aBS->VDegree();
1033 for(i = vi1+1; i <= vi2; ++i) {
1034 if(i == vi2) t2 = vsup;
1035 else t2 = aBS->VKnot(i);
1041 aVFlg(k) = Standard_False;
1051 //Analysis of deflection
1053 Standard_Real aDefl2 = Max(theDefl*theDefl, 1.e-9);
1054 Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
1057 anUFlg(1) = Standard_True;
1058 anUFlg(nbsu) = Standard_True;
1060 for(i = 1; i <= nbsv; ++i) {
1063 Standard_Boolean bCont = Standard_True;
1064 while (j < nbsu-1 && bCont) {
1072 gp_Pnt p1 = aBS->Value(t2, t1);
1073 for(k = j+2; k <= nbsu; ++k) {
1075 gp_Pnt p2 = aBS->Value(t2, t1);
1076 //gce_MakeLin MkLin(p1, p2);
1077 //const gp_Lin& lin = MkLin.Value();
1079 if(p1.SquareDistance(p2) <= tol) continue;
1081 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1082 Standard_Boolean ok = Standard_True;
1083 for(l = j+1; l < k; ++l) {
1086 ok = Standard_False;
1090 gp_Pnt pp = aBS->Value(anUPars(l), t1);
1091 Standard_Real d = lin.SquareDistance(pp);
1093 if(d <= aDefl2) continue;
1095 ok = Standard_False;
1101 anUFlg(j) = Standard_True;
1114 if(k >= nbsu) bCont = Standard_False;
1118 if(myNbSamplesU < myMinPnts) {
1119 if(myNbSamplesU == 2) {
1120 //"uniform" distribution;
1121 Standard_Integer nn = nbsu/myMinPnts;
1122 anUFlg(1+nn) = Standard_True;
1123 anUFlg(nbsu-nn) = Standard_True;
1125 else { //myNbSamplesU == 3
1126 //insert in bigger segment
1128 while(!anUFlg(i++));
1129 if(i < nbsu/2) j = Min(i+(nbsu-i)/2, nbsu-1);
1130 else j = Max(i/2, 2);
1132 anUFlg(j) = Standard_True;
1133 myNbSamplesU = myMinPnts;
1136 aVFlg(1) = Standard_True;
1137 aVFlg(nbsv) = Standard_True;
1139 for(i = 1; i <= nbsu; ++i) {
1142 Standard_Boolean bCont = Standard_True;
1143 while (j < nbsv-1 && bCont) {
1151 gp_Pnt p1 = aBS->Value(t1, t2);
1152 for(k = j+2; k <= nbsv; ++k) {
1154 gp_Pnt p2 = aBS->Value(t1, t2);
1156 if(p1.SquareDistance(p2) <= tol) continue;
1157 //gce_MakeLin MkLin(p1, p2);
1158 //const gp_Lin& lin = MkLin.Value();
1159 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1160 Standard_Boolean ok = Standard_True;
1161 for(l = j+1; l < k; ++l) {
1164 ok = Standard_False;
1168 gp_Pnt pp = aBS->Value(t1, aVPars(l));
1169 Standard_Real d = lin.SquareDistance(pp);
1171 if(d <= aDefl2) continue;
1173 ok = Standard_False;
1179 aVFlg(j) = Standard_True;
1192 if(k >= nbsv) bCont = Standard_False;
1196 if(myNbSamplesV < myMinPnts) {
1197 if(myNbSamplesV == 2) {
1198 //"uniform" distribution;
1199 Standard_Integer nn = nbsv/myMinPnts;
1200 aVFlg(1+nn) = Standard_True;
1201 aVFlg(nbsv-nn) = Standard_True;
1202 myNbSamplesV = myMinPnts;
1204 else { //myNbSamplesU == 3
1205 //insert in bigger segment
1208 if(i < nbsv/2) j = Min(i+(nbsv-i)/2, nbsv-1);
1209 else j = Max(i/2, 2);
1211 myNbSamplesV = myMinPnts;
1212 aVFlg(j) = Standard_True;
1216 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1217 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1220 for(i = 1; i <= nbsu; ++i) {
1223 myUPars->SetValue(j,anUPars(i));
1228 for(i = 1; i <= nbsv; ++i) {
1231 myVPars->SetValue(j,aVPars(i));
1238 Standard_Boolean Adaptor3d_TopolTool::IsUniformSampling() const
1240 GeomAbs_SurfaceType typS = myS->GetType();
1242 if(typS == GeomAbs_BSplineSurface)
1243 return Standard_False;
1244 return Standard_True;