1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
19 #include <Standard_NotImplemented.hxx>
20 #include <Adaptor3d_TopolTool.ixx>
21 #include <Precision.hxx>
23 #include <gp_Cone.hxx>
25 #include <gp_Trsf.hxx>
27 #define myInfinite 1.e15
29 static void GetConeApexParam(const gp_Cone& C, Standard_Real& U, Standard_Real& V)
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();
37 T.SetTransformation (Pos);
38 gp_Pnt Ploc = P.Transformed (T);
40 if(Ploc.X() ==0.0 && Ploc.Y()==0.0 ) {
43 else if ( -Radius > Ploc.Z()* Tan(SAngle) ) {
44 // the point is at the `wrong` side of the apex
45 U = atan2(-Ploc.Y(), -Ploc.X());
48 U = atan2(Ploc.Y(),Ploc.X());
50 if (U < -1.e-16) U += (M_PI+M_PI);
51 else if (U < 0) U = 0;
53 V = sin(SAngle) * ( Ploc.X() * cos(U) + Ploc.Y() * sin(U) - Radius)
54 + cos(SAngle) * Ploc.Z();
58 Adaptor3d_TopolTool::Adaptor3d_TopolTool () : nbRestr(0),idRestr(0),myNbSamplesU(-1)
63 Adaptor3d_TopolTool::Adaptor3d_TopolTool (const Handle(Adaptor3d_HSurface)& S)
69 void Adaptor3d_TopolTool::Initialize ()
71 Standard_NotImplemented::Raise("Adaptor3d_TopolTool::Initialize ()");
74 void Adaptor3d_TopolTool::Initialize (const Handle(Adaptor3d_HSurface)& S)
76 Standard_Real pinf,psup,deltap;
77 //Adaptor2d_Line2d * Line2dPtr ;
80 Uinf = S->FirstUParameter(); // where UIntervalFirst ??
81 Vinf = S->FirstVParameter();
82 Usup = S->LastUParameter();
83 Vsup = S->LastVParameter();
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);
93 deltap = Min(Usup-Uinf,2.*myInfinite);
94 if (Uinf >= -myInfinite){
98 else if (Usup <= myInfinite) {
100 pinf = psup - deltap;
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));
114 deltap = Min(Vsup-Vinf,2.*myInfinite);
115 if (Vinf >= -myInfinite){
117 psup = pinf + deltap;
119 else if (Vsup <= myInfinite) {
121 pinf = psup - deltap;
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));
137 deltap = Min(Usup-Uinf,2.*myInfinite);
138 if (-Usup >= -myInfinite){
140 psup = pinf + deltap;
142 else if (-Uinf <= myInfinite) {
144 pinf = psup - deltap;
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));
159 deltap = Min(Vsup-Vinf,2.*myInfinite);
160 if (-Vsup >= -myInfinite){
162 psup = pinf + deltap;
164 else if (-Vinf <= myInfinite) {
166 pinf = psup - deltap;
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));
181 if(nbRestr == 2 && S->GetType() == GeomAbs_Cone ) {
182 Standard_Real U = 0., V = 0.;
183 GetConeApexParam(S->Cone(),U,V);
185 deltap = Min(Usup-Uinf,2.*myInfinite);
186 if (Uinf >= -myInfinite){
188 psup = pinf + deltap;
190 else if (Usup <= myInfinite) {
192 pinf = psup - deltap;
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));
207 void Adaptor3d_TopolTool::Init ()
213 Standard_Boolean Adaptor3d_TopolTool::More ()
215 return (idRestr < nbRestr);
218 Handle(Adaptor2d_HCurve2d) Adaptor3d_TopolTool::Value ()
220 if (idRestr >= nbRestr) {Standard_DomainError::Raise();}
221 return myRestr[idRestr];
224 void Adaptor3d_TopolTool::Next ()
230 void Adaptor3d_TopolTool::Initialize(const Handle(Adaptor2d_HCurve2d)& C)
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);
242 // if (!Precision::IsPositiveInfinite(theUsup)) {
243 if (theUsup < myInfinite) {
244 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUsup),TopAbs_REVERSED,1.e-8);
250 void Adaptor3d_TopolTool::InitVertexIterator ()
256 Standard_Boolean Adaptor3d_TopolTool::MoreVertex ()
258 return (idVtx < nbVtx);
262 Handle(Adaptor3d_HVertex) Adaptor3d_TopolTool::Vertex ()
264 if (idVtx >= nbVtx) {Standard_DomainError::Raise();}
268 void Adaptor3d_TopolTool::NextVertex ()
274 TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
275 const Standard_Real Tol,
276 const Standard_Boolean )
277 // const Standard_Boolean RecadreOnPeriodic)
280 Standard_Real U = P.X();
281 Standard_Real V = P.Y();
284 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
285 (V < Vinf - Tol) || (V > Vsup + Tol)) {
288 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
289 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
294 else if (nbRestr == 0) {
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;
304 else if (Precision::IsNegativeInfinite(Uinf)) {
305 surumin = Standard_False;
307 dansu = Standard_False;
308 surumax = Standard_False;
311 dansu = Standard_True;
312 surumax = Standard_False;
313 if (Abs(U-Usup)<=Tol) {
314 surumax = Standard_True;
318 else if (Precision::IsPositiveInfinite(Usup)) {
319 surumax = Standard_False;
321 dansu = Standard_False;
322 surumin = Standard_False;
325 dansu = Standard_True;
326 surumin = Standard_False;
327 if (Abs(U-Uinf)<=Tol) {
328 surumin = Standard_True;
333 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
334 surumin = surumax = dansu = Standard_False;
337 dansu = Standard_True;
338 surumin = surumax = Standard_False;
339 if (Abs(U-Uinf)<=Tol) {
340 surumin = Standard_True;
342 else if (Abs(U-Usup)<=Tol) {
343 surumax = Standard_True;
348 if (Precision::IsNegativeInfinite(Vinf) &&
349 Precision::IsPositiveInfinite(Vsup)) {
350 dansv = Standard_True;
351 survmin = survmax = Standard_False;
353 else if (Precision::IsNegativeInfinite(Vinf)) {
354 survmin = Standard_False;
356 dansv = Standard_False;
357 survmax = Standard_False;
360 dansv = Standard_True;
361 survmax = Standard_False;
362 if (Abs(V-Vsup)<=Tol) {
363 survmax = Standard_True;
367 else if (Precision::IsPositiveInfinite(Vsup)) {
368 survmax = Standard_False;
370 dansv = Standard_False;
371 survmin = Standard_False;
374 dansv = Standard_True;
375 survmin = Standard_False;
376 if (Abs(V-Vinf)<=Tol) {
377 survmin = Standard_True;
382 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
383 survmin = survmax = dansv = Standard_False;
386 dansv = Standard_True;
387 survmin = survmax = Standard_False;
388 if (Abs(V-Vinf)<=Tol) {
389 survmin = Standard_True;
391 else if (Abs(V-Vsup)<=Tol) {
392 survmax = Standard_True;
397 if (!dansu || !dansv) {
400 if (surumin || survmin || surumax || survmax) {
409 Standard_Boolean Adaptor3d_TopolTool::IsThePointOn(const gp_Pnt2d& P,
410 const Standard_Real Tol,
411 const Standard_Boolean )
412 // const Standard_Boolean RecadreOnPeriodic)
415 Standard_Real U = P.X();
416 Standard_Real V = P.Y();
419 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
420 (V < Vinf - Tol) || (V > Vsup + Tol)) {
421 return(Standard_False);
423 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
424 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
425 return(Standard_True);
427 return(Standard_False);
429 else if (nbRestr == 0) {
430 return(Standard_False);
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;
439 else if (Precision::IsNegativeInfinite(Uinf)) {
440 surumin = Standard_False;
442 dansu = Standard_False;
443 surumax = Standard_False;
446 dansu = Standard_True;
447 surumax = Standard_False;
448 if (Abs(U-Usup)<=Tol) {
449 surumax = Standard_True;
453 else if (Precision::IsPositiveInfinite(Usup)) {
454 surumax = Standard_False;
456 dansu = Standard_False;
457 surumin = Standard_False;
460 dansu = Standard_True;
461 surumin = Standard_False;
462 if (Abs(U-Uinf)<=Tol) {
463 surumin = Standard_True;
468 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
469 surumin = surumax = dansu = Standard_False;
472 dansu = Standard_True;
473 surumin = surumax = Standard_False;
474 if (Abs(U-Uinf)<=Tol) {
475 surumin = Standard_True;
477 else if (Abs(U-Usup)<=Tol) {
478 surumax = Standard_True;
483 if (Precision::IsNegativeInfinite(Vinf) &&
484 Precision::IsPositiveInfinite(Vsup)) {
485 dansv = Standard_True;
486 survmin = survmax = Standard_False;
488 else if (Precision::IsNegativeInfinite(Vinf)) {
489 survmin = Standard_False;
491 dansv = Standard_False;
492 survmax = Standard_False;
495 dansv = Standard_True;
496 survmax = Standard_False;
497 if (Abs(V-Vsup)<=Tol) {
498 survmax = Standard_True;
502 else if (Precision::IsPositiveInfinite(Vsup)) {
503 survmax = Standard_False;
505 dansv = Standard_False;
506 survmin = Standard_False;
509 dansv = Standard_True;
510 survmin = Standard_False;
511 if (Abs(V-Vinf)<=Tol) {
512 survmin = Standard_True;
517 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
518 survmin = survmax = dansv = Standard_False;
521 dansv = Standard_True;
522 survmin = survmax = Standard_False;
523 if (Abs(V-Vinf)<=Tol) {
524 survmin = Standard_True;
526 else if (Abs(V-Vsup)<=Tol) {
527 survmax = Standard_True;
532 if (!dansu || !dansv) {
533 return(Standard_False);
535 if (surumin || survmin || surumax || survmax) {
536 return(Standard_True);
538 return(Standard_False);;
543 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
544 (const Handle(Adaptor2d_HCurve2d)&)
546 return TopAbs_FORWARD;
549 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
550 (const Handle(Adaptor3d_HVertex)& V)
552 return V->Orientation();
555 Standard_Boolean Adaptor3d_TopolTool::Identical
556 (const Handle(Adaptor3d_HVertex)& V1,
557 const Handle(Adaptor3d_HVertex)& V2)
559 return V1->IsSame(V2);
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
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>
577 #define myMinPnts 4 //Absolut possible minimum of sample points
578 //Restriction of IntPolyh
581 static void Analyse(const TColgp_Array2OfPnt& array2,
582 const Standard_Integer nbup,
583 const Standard_Integer nbvp,
584 Standard_Integer& myNbSamplesU,
585 Standard_Integer& myNbSamplesV) {
587 Standard_Integer sh,nbch,i,j;
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;
600 for(j=3; j<nbvp;j++) { //-- try
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);
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++; } }
619 myNbSamplesV = nbch+5;
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;
631 for(i=3; i<nbup;i++) { //-- try
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);
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++; } }
645 if(locnbch>nbch) nbch=locnbch;
648 myNbSamplesU = nbch+5;
652 void 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; }
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; }
666 Standard_Integer nbsu,nbsv;
667 GeomAbs_SurfaceType typS = myS->GetType();
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;
676 case GeomAbs_Cylinder:
680 case GeomAbs_SurfaceOfRevolution:
681 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=15; } break;
682 default: { nbsu = 10; nbsv=10; } break;
685 //-- If the number of points is too great... analyze
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);
702 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
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);
710 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
715 Standard_Integer Adaptor3d_TopolTool::NbSamplesU()
717 if(myNbSamplesU <0) {
718 ComputeSamplePoints();
720 return(myNbSamplesU);
723 Standard_Integer Adaptor3d_TopolTool::NbSamplesV()
725 if(myNbSamplesU <0) {
726 ComputeSamplePoints();
728 return(myNbSamplesV);
731 Standard_Integer Adaptor3d_TopolTool::NbSamples()
733 if(myNbSamplesU <0) {
734 ComputeSamplePoints();
736 return(myNbSamplesU*myNbSamplesV);
739 void Adaptor3d_TopolTool::UParameters(TColStd_Array1OfReal& theArray) const
741 theArray = myUPars->Array1();
744 void Adaptor3d_TopolTool::VParameters(TColStd_Array1OfReal& theArray) const
746 theArray = myVPars->Array1();
749 void Adaptor3d_TopolTool::SamplePoint(const Standard_Integer i,
753 Standard_Integer iu, iv;
755 if (myUPars.IsNull())
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;
766 iv = (i-1)/myNbSamplesU + 1;
767 iu = (i-1)%myNbSamplesU + 1;
768 u = myUPars->Value(iu);
769 v = myVPars->Value(iv);
773 P3d = myS->Value(u,v);
778 Standard_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);
785 //=======================================================================
788 //=======================================================================
789 Standard_Address Adaptor3d_TopolTool::Edge() const
793 //=======================================================================
796 //=======================================================================
798 Standard_Boolean Adaptor3d_TopolTool::Has3d() const
800 return Standard_False;
803 //=======================================================================
806 //=======================================================================
808 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)&) const
810 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
814 //=======================================================================
817 //=======================================================================
819 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)&) const
821 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
825 //=======================================================================
828 //=======================================================================
830 gp_Pnt Adaptor3d_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)&) const
832 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
837 //=======================================================================
838 //function : SamplePnts
840 //=======================================================================
842 void Adaptor3d_TopolTool::SamplePnts(const Standard_Real theDefl,
843 const Standard_Integer theNUmin,
844 const Standard_Integer theNVmin)
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; }
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; }
859 // Standard_Integer nbsu,nbsv;
860 GeomAbs_SurfaceType typS = myS->GetType();
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);
878 // case GeomAbs_BSplineSurface: {
879 if(typS == GeomAbs_BSplineSurface) {
880 // Processing BSpline surface
881 BSplSamplePnts(theDefl, theNUmin, theNVmin);
885 ComputeSamplePoints();
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;
897 // if(nbsu<6) nbsu=6;
898 // if(nbsv<6) nbsv=6;
900 // myNbSamplesU = nbsu;
901 // myNbSamplesV = nbsv;
904 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
905 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
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);
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);
925 //=======================================================================
926 //function : BSplSamplePnts
928 //=======================================================================
930 void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
931 const Standard_Integer theNUmin,
932 const Standard_Integer theNVmin)
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();
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();
946 for(i = ui1; i < ui2; ++i) {
947 if(uinf >= aBS->UKnot(i) && uinf < aBS->UKnot(i+1)) {
953 for(i = ui2; i > ui1; --i) {
954 if(usup <= aBS->UKnot(i) && usup > aBS->UKnot(i-1)) {
960 for(i = vi1; i < vi2; ++i) {
961 if(vinf >= aBS->VKnot(i) && vinf < aBS->VKnot(i+1)) {
967 for(i = vi2; i > vi1; --i) {
968 if(vsup <= aBS->VKnot(i) && vsup > aBS->VKnot(i-1)) {
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;
979 //modified by NIZHNY-EMV Mon Jun 10 14:19:04 2013
980 if (nbsu < theNUmin || nbsv < theNVmin) {
981 Standard_Integer aNb;
983 aNb = (Standard_Integer)(nbsv * ((Standard_Real)theNUmin)/((Standard_Real)nbsu));
985 bVuniform = (aNb > nbsv) ? Standard_True : bVuniform;
986 nbsv = bVuniform ? aNb : nbsv;
988 aNb = (Standard_Integer)(nbsu * ((Standard_Real)theNVmin)/((Standard_Real)nbsv));
990 bUuniform = (aNb > nbsu) ? Standard_True : bUuniform;
991 nbsu = bUuniform ? aNb : nbsu;
994 //modified by NIZHNY-EMV Mon Jun 10 14:19:05 2013
996 if(nbsu < theNUmin) {
998 bUuniform = Standard_True;
1001 if(nbsv < theNVmin) {
1003 bVuniform = Standard_True;
1006 TColStd_Array1OfReal anUPars(1, nbsu);
1007 TColStd_Array1OfBoolean anUFlg(1, nbsu);
1008 TColStd_Array1OfReal aVPars(1, nbsv);
1009 TColStd_Array1OfBoolean aVFlg(1, nbsv);
1011 //Filling of sample parameters
1015 dt = (t2 - t1)/(nbsu - 1);
1017 anUFlg(1) = Standard_False;
1019 anUFlg(nbsu) = Standard_False;
1020 for(i = 2, t1 += dt; i < nbsu; ++i, t1 += dt) {
1022 anUFlg(i) = Standard_False;
1026 nbi = aBS->UDegree();
1029 for(i = ui1+1; i <= ui2; ++i) {
1030 if(i == ui2) t2 = usup;
1031 else t2 = aBS->UKnot(i);
1037 anUFlg(k) = Standard_False;
1050 dt = (t2 - t1)/(nbsv - 1);
1052 aVFlg(1) = Standard_False;
1054 aVFlg(nbsv) = Standard_False;
1055 for(i = 2, t1 += dt; i < nbsv; ++i, t1 += dt) {
1057 aVFlg(i) = Standard_False;
1061 nbi = aBS->VDegree();
1064 for(i = vi1+1; i <= vi2; ++i) {
1065 if(i == vi2) t2 = vsup;
1066 else t2 = aBS->VKnot(i);
1072 aVFlg(k) = Standard_False;
1082 //Analysis of deflection
1084 Standard_Real aDefl2 = Max(theDefl*theDefl, 1.e-9);
1085 Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
1088 anUFlg(1) = Standard_True;
1089 anUFlg(nbsu) = Standard_True;
1091 for(i = 1; i <= nbsv; ++i) {
1094 Standard_Boolean bCont = Standard_True;
1095 while (j < nbsu-1 && bCont) {
1103 gp_Pnt p1 = aBS->Value(t2, t1);
1104 for(k = j+2; k <= nbsu; ++k) {
1106 gp_Pnt p2 = aBS->Value(t2, t1);
1107 //gce_MakeLin MkLin(p1, p2);
1108 //const gp_Lin& lin = MkLin.Value();
1110 if(p1.SquareDistance(p2) <= tol) continue;
1112 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1113 Standard_Boolean ok = Standard_True;
1114 for(l = j+1; l < k; ++l) {
1117 ok = Standard_False;
1121 gp_Pnt pp = aBS->Value(anUPars(l), t1);
1122 Standard_Real d = lin.SquareDistance(pp);
1124 if(d <= aDefl2) continue;
1126 ok = Standard_False;
1132 anUFlg(j) = Standard_True;
1145 if(k >= nbsu) bCont = Standard_False;
1151 for (i = 1; i <= nbsu; i++)
1152 if (anUFlg(i) == Standard_True)
1155 if(myNbSamplesU < myMinPnts) {
1156 if(myNbSamplesU == 2) {
1157 //"uniform" distribution;
1158 Standard_Integer nn = nbsu/myMinPnts;
1159 anUFlg(1+nn) = Standard_True;
1160 anUFlg(nbsu-nn) = Standard_True;
1162 else { //myNbSamplesU == 3
1163 //insert in bigger segment
1165 while(!anUFlg(i++));
1166 if(i < nbsu/2) j = Min(i+(nbsu-i)/2, nbsu-1);
1167 else j = Max(i/2, 2);
1169 anUFlg(j) = Standard_True;
1170 myNbSamplesU = myMinPnts;
1173 aVFlg(1) = Standard_True;
1174 aVFlg(nbsv) = Standard_True;
1176 for(i = 1; i <= nbsu; ++i) {
1179 Standard_Boolean bCont = Standard_True;
1180 while (j < nbsv-1 && bCont) {
1188 gp_Pnt p1 = aBS->Value(t1, t2);
1189 for(k = j+2; k <= nbsv; ++k) {
1191 gp_Pnt p2 = aBS->Value(t1, t2);
1193 if(p1.SquareDistance(p2) <= tol) continue;
1194 //gce_MakeLin MkLin(p1, p2);
1195 //const gp_Lin& lin = MkLin.Value();
1196 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1197 Standard_Boolean ok = Standard_True;
1198 for(l = j+1; l < k; ++l) {
1201 ok = Standard_False;
1205 gp_Pnt pp = aBS->Value(t1, aVPars(l));
1206 Standard_Real d = lin.SquareDistance(pp);
1208 if(d <= aDefl2) continue;
1210 ok = Standard_False;
1216 aVFlg(j) = Standard_True;
1229 if(k >= nbsv) bCont = Standard_False;
1235 for (i = 1; i <= nbsv; i++)
1236 if (aVFlg(i) == Standard_True)
1239 if(myNbSamplesV < myMinPnts) {
1240 if(myNbSamplesV == 2) {
1241 //"uniform" distribution;
1242 Standard_Integer nn = nbsv/myMinPnts;
1243 aVFlg(1+nn) = Standard_True;
1244 aVFlg(nbsv-nn) = Standard_True;
1245 myNbSamplesV = myMinPnts;
1247 else { //myNbSamplesU == 3
1248 //insert in bigger segment
1251 if(i < nbsv/2) j = Min(i+(nbsv-i)/2, nbsv-1);
1252 else j = Max(i/2, 2);
1254 myNbSamplesV = myMinPnts;
1255 aVFlg(j) = Standard_True;
1258 //modified by NIZNHY-PKV Fri Dec 16 10:05:01 2011f
1260 Standard_Boolean bFlag;
1263 bFlag=(myNbSamplesU < theNUmin);
1268 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1270 for(j = 0, i = 1; i <= nbsu; ++i) {
1272 myUPars->SetValue(i,anUPars(i));
1277 myUPars->SetValue(j,anUPars(i));
1283 bFlag=(myNbSamplesV < theNVmin);
1288 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1290 for(j = 0, i = 1; i <= nbsv; ++i) {
1292 myVPars->SetValue(i,aVPars(i));
1297 myVPars->SetValue(j,aVPars(i));
1303 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1304 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1307 for(i = 1; i <= nbsu; ++i) {
1310 myUPars->SetValue(j,anUPars(i));
1315 for(i = 1; i <= nbsv; ++i) {
1318 myVPars->SetValue(j,aVPars(i));
1322 //modified by NIZNHY-PKV Mon Dec 26 12:25:35 2011t
1326 //=======================================================================
1327 //function : IsUniformSampling
1329 //=======================================================================
1330 Standard_Boolean Adaptor3d_TopolTool::IsUniformSampling() const
1332 GeomAbs_SurfaceType typS = myS->GetType();
1334 if(typS == GeomAbs_BSplineSurface)
1335 return Standard_False;
1336 return Standard_True;