1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <Standard_NotImplemented.hxx>
15 #include <Adaptor3d_TopolTool.ixx>
16 #include <Precision.hxx>
17 #include <GeomAdaptor_Surface.hxx>
19 #include <gp_Cone.hxx>
21 #include <gp_Trsf.hxx>
23 #define myInfinite Precision::Infinite()
25 static void GetConeApexParam(const gp_Cone& C, Standard_Real& U, Standard_Real& V)
27 const gp_Ax3& Pos = C.Position();
28 Standard_Real Radius = C.RefRadius();
29 Standard_Real SAngle = C.SemiAngle();
30 const gp_Pnt& P = C.Apex();
33 T.SetTransformation (Pos);
34 gp_Pnt Ploc = P.Transformed (T);
36 if(Ploc.X() ==0.0 && Ploc.Y()==0.0 ) {
39 else if ( -Radius > Ploc.Z()* Tan(SAngle) ) {
40 // the point is at the `wrong` side of the apex
41 U = atan2(-Ploc.Y(), -Ploc.X());
44 U = atan2(Ploc.Y(),Ploc.X());
46 if (U < -1.e-16) U += (M_PI+M_PI);
47 else if (U < 0) U = 0;
49 V = sin(SAngle) * ( Ploc.X() * cos(U) + Ploc.Y() * sin(U) - Radius)
50 + cos(SAngle) * Ploc.Z();
54 Adaptor3d_TopolTool::Adaptor3d_TopolTool () : myNbSamplesU(-1),nbRestr(0),idRestr(0)
59 Adaptor3d_TopolTool::Adaptor3d_TopolTool (const Handle(Adaptor3d_HSurface)& S)
65 void Adaptor3d_TopolTool::Initialize ()
67 Standard_NotImplemented::Raise("Adaptor3d_TopolTool::Initialize ()");
70 void Adaptor3d_TopolTool::Initialize (const Handle(Adaptor3d_HSurface)& S)
72 Standard_Real pinf,psup,deltap;
73 //Adaptor2d_Line2d * Line2dPtr ;
76 Uinf = S->FirstUParameter(); // where UIntervalFirst ??
77 Vinf = S->FirstVParameter();
78 Usup = S->LastUParameter();
79 Vsup = S->LastVParameter();
83 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
84 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
85 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
86 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
89 deltap = Min(Usup-Uinf,2.*myInfinite);
90 if (Uinf >= -myInfinite){
94 else if (Usup <= myInfinite) {
103 // Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup);
104 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
105 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup));
110 deltap = Min(Vsup-Vinf,2.*myInfinite);
111 if (Vinf >= -myInfinite){
113 psup = pinf + deltap;
115 else if (Vsup <= myInfinite) {
117 pinf = psup - deltap;
126 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup);
127 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
128 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup));
133 deltap = Min(Usup-Uinf,2.*myInfinite);
134 if (-Usup >= -myInfinite){
136 psup = pinf + deltap;
138 else if (-Uinf <= myInfinite) {
140 pinf = psup - deltap;
148 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup);
149 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
150 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup));
155 deltap = Min(Vsup-Vinf,2.*myInfinite);
156 if (-Vsup >= -myInfinite){
158 psup = pinf + deltap;
160 else if (-Vinf <= myInfinite) {
162 pinf = psup - deltap;
169 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup);
170 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
171 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup));
177 if(nbRestr == 2 && S->GetType() == GeomAbs_Cone ) {
178 Standard_Real U = 0., V = 0.;
179 GetConeApexParam(S->Cone(),U,V);
181 deltap = Min(Usup-Uinf,2.*myInfinite);
182 if (Uinf >= -myInfinite){
184 psup = pinf + deltap;
186 else if (Usup <= myInfinite) {
188 pinf = psup - deltap;
195 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup);
196 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
197 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup));
203 void Adaptor3d_TopolTool::Init ()
209 Standard_Boolean Adaptor3d_TopolTool::More ()
211 return (idRestr < nbRestr);
214 Handle(Adaptor2d_HCurve2d) Adaptor3d_TopolTool::Value ()
216 if (idRestr >= nbRestr) {Standard_DomainError::Raise();}
217 return myRestr[idRestr];
220 void Adaptor3d_TopolTool::Next ()
226 void Adaptor3d_TopolTool::Initialize(const Handle(Adaptor2d_HCurve2d)& C)
230 Standard_Real theUinf,theUsup;
231 theUinf = C->FirstParameter();
232 theUsup = C->LastParameter();
233 // if (!Precision::IsNegativeInfinite(theUinf)) {
234 if (theUinf > -myInfinite) {
235 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUinf),TopAbs_FORWARD,1.e-8);
238 // if (!Precision::IsPositiveInfinite(theUsup)) {
239 if (theUsup < myInfinite) {
240 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUsup),TopAbs_REVERSED,1.e-8);
246 void Adaptor3d_TopolTool::InitVertexIterator ()
252 Standard_Boolean Adaptor3d_TopolTool::MoreVertex ()
254 return (idVtx < nbVtx);
258 Handle(Adaptor3d_HVertex) Adaptor3d_TopolTool::Vertex ()
260 if (idVtx >= nbVtx) {Standard_DomainError::Raise();}
264 void Adaptor3d_TopolTool::NextVertex ()
270 TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
271 const Standard_Real Tol,
272 const Standard_Boolean )
273 // const Standard_Boolean RecadreOnPeriodic)
276 Standard_Real U = P.X();
277 Standard_Real V = P.Y();
280 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
281 (V < Vinf - Tol) || (V > Vsup + Tol)) {
284 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
285 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
290 else if (nbRestr == 0) {
294 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
295 if (Precision::IsNegativeInfinite(Uinf) &&
296 Precision::IsPositiveInfinite(Usup)) {
297 dansu = Standard_True;
298 surumin = surumax = Standard_False;
300 else if (Precision::IsNegativeInfinite(Uinf)) {
301 surumin = Standard_False;
303 dansu = Standard_False;
304 surumax = Standard_False;
307 dansu = Standard_True;
308 surumax = Standard_False;
309 if (Abs(U-Usup)<=Tol) {
310 surumax = Standard_True;
314 else if (Precision::IsPositiveInfinite(Usup)) {
315 surumax = Standard_False;
317 dansu = Standard_False;
318 surumin = Standard_False;
321 dansu = Standard_True;
322 surumin = Standard_False;
323 if (Abs(U-Uinf)<=Tol) {
324 surumin = Standard_True;
329 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
330 surumin = surumax = dansu = Standard_False;
333 dansu = Standard_True;
334 surumin = surumax = Standard_False;
335 if (Abs(U-Uinf)<=Tol) {
336 surumin = Standard_True;
338 else if (Abs(U-Usup)<=Tol) {
339 surumax = Standard_True;
344 if (Precision::IsNegativeInfinite(Vinf) &&
345 Precision::IsPositiveInfinite(Vsup)) {
346 dansv = Standard_True;
347 survmin = survmax = Standard_False;
349 else if (Precision::IsNegativeInfinite(Vinf)) {
350 survmin = Standard_False;
352 dansv = Standard_False;
353 survmax = Standard_False;
356 dansv = Standard_True;
357 survmax = Standard_False;
358 if (Abs(V-Vsup)<=Tol) {
359 survmax = Standard_True;
363 else if (Precision::IsPositiveInfinite(Vsup)) {
364 survmax = Standard_False;
366 dansv = Standard_False;
367 survmin = Standard_False;
370 dansv = Standard_True;
371 survmin = Standard_False;
372 if (Abs(V-Vinf)<=Tol) {
373 survmin = Standard_True;
378 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
379 survmin = survmax = dansv = Standard_False;
382 dansv = Standard_True;
383 survmin = survmax = Standard_False;
384 if (Abs(V-Vinf)<=Tol) {
385 survmin = Standard_True;
387 else if (Abs(V-Vsup)<=Tol) {
388 survmax = Standard_True;
393 if (!dansu || !dansv) {
396 if (surumin || survmin || surumax || survmax) {
405 Standard_Boolean Adaptor3d_TopolTool::IsThePointOn(const gp_Pnt2d& P,
406 const Standard_Real Tol,
407 const Standard_Boolean )
408 // const Standard_Boolean RecadreOnPeriodic)
411 Standard_Real U = P.X();
412 Standard_Real V = P.Y();
415 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
416 (V < Vinf - Tol) || (V > Vsup + Tol)) {
417 return(Standard_False);
419 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
420 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
421 return(Standard_True);
423 return(Standard_False);
425 else if (nbRestr == 0) {
426 return(Standard_False);
429 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
430 if (Precision::IsNegativeInfinite(Uinf) &&
431 Precision::IsPositiveInfinite(Usup)) {
432 dansu = Standard_True;
433 surumin = surumax = Standard_False;
435 else if (Precision::IsNegativeInfinite(Uinf)) {
436 surumin = Standard_False;
438 dansu = Standard_False;
439 surumax = Standard_False;
442 dansu = Standard_True;
443 surumax = Standard_False;
444 if (Abs(U-Usup)<=Tol) {
445 surumax = Standard_True;
449 else if (Precision::IsPositiveInfinite(Usup)) {
450 surumax = Standard_False;
452 dansu = Standard_False;
453 surumin = Standard_False;
456 dansu = Standard_True;
457 surumin = Standard_False;
458 if (Abs(U-Uinf)<=Tol) {
459 surumin = Standard_True;
464 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
465 surumin = surumax = dansu = Standard_False;
468 dansu = Standard_True;
469 surumin = surumax = Standard_False;
470 if (Abs(U-Uinf)<=Tol) {
471 surumin = Standard_True;
473 else if (Abs(U-Usup)<=Tol) {
474 surumax = Standard_True;
479 if (Precision::IsNegativeInfinite(Vinf) &&
480 Precision::IsPositiveInfinite(Vsup)) {
481 dansv = Standard_True;
482 survmin = survmax = Standard_False;
484 else if (Precision::IsNegativeInfinite(Vinf)) {
485 survmin = Standard_False;
487 dansv = Standard_False;
488 survmax = Standard_False;
491 dansv = Standard_True;
492 survmax = Standard_False;
493 if (Abs(V-Vsup)<=Tol) {
494 survmax = Standard_True;
498 else if (Precision::IsPositiveInfinite(Vsup)) {
499 survmax = Standard_False;
501 dansv = Standard_False;
502 survmin = Standard_False;
505 dansv = Standard_True;
506 survmin = Standard_False;
507 if (Abs(V-Vinf)<=Tol) {
508 survmin = Standard_True;
513 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
514 survmin = survmax = dansv = Standard_False;
517 dansv = Standard_True;
518 survmin = survmax = Standard_False;
519 if (Abs(V-Vinf)<=Tol) {
520 survmin = Standard_True;
522 else if (Abs(V-Vsup)<=Tol) {
523 survmax = Standard_True;
528 if (!dansu || !dansv) {
529 return(Standard_False);
531 if (surumin || survmin || surumax || survmax) {
532 return(Standard_True);
534 return(Standard_False);;
539 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
540 (const Handle(Adaptor2d_HCurve2d)&)
542 return TopAbs_FORWARD;
545 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
546 (const Handle(Adaptor3d_HVertex)& V)
548 return V->Orientation();
551 Standard_Boolean Adaptor3d_TopolTool::Identical
552 (const Handle(Adaptor3d_HVertex)& V1,
553 const Handle(Adaptor3d_HVertex)& V2)
555 return V1->IsSame(V2);
559 //-- ============================================================
560 //-- m e t h o d e s u t i l i s e e s p o u r l e s
562 //-- ============================================================
563 #include <TColgp_Array2OfPnt.hxx>
564 #include <Geom_BezierSurface.hxx>
565 #include <Geom_BSplineSurface.hxx>
566 #include <TColStd_Array1OfReal.hxx>
567 #include <TColStd_Array1OfBoolean.hxx>
568 //#include <gce_MakeLin.hxx>
569 #include <gp_Lin.hxx>
570 #include <gp_Dir.hxx>
571 #include <gp_Vec.hxx>
573 #define myMinPnts 4 //Absolut possible minimum of sample points
574 //Restriction of IntPolyh
577 static void Analyse(const TColgp_Array2OfPnt& array2,
578 const Standard_Integer nbup,
579 const Standard_Integer nbvp,
580 Standard_Integer& myNbSamplesU,
581 Standard_Integer& myNbSamplesV) {
583 Standard_Integer sh,nbch,i,j;
588 for(i=2;i<nbup;i++) {
589 const gp_Pnt& A=array2.Value(i,1);
590 const gp_Pnt& B=array2.Value(i,2);
591 const gp_Pnt& C=array2.Value(i,3);
592 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
593 C.Y()-B.Y()-B.Y()+A.Y(),
594 C.Z()-B.Z()-B.Z()+A.Z());
595 Standard_Integer locnbch=0;
596 for(j=3; j<nbvp;j++) { //-- try
597 const gp_Pnt& A1=array2.Value(i,j-1);
598 const gp_Pnt& B1=array2.Value(i,j);
599 const gp_Pnt& C1=array2.Value(i,j+1);
600 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
601 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
602 C1.Z()-B1.Z()-B1.Z()+A1.Z());
603 Standard_Real pd = Vi.Dot(Vip1);
605 if(pd>1.0e-7 || pd<-1.0e-7) {
606 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
607 else { if(sh==1) { sh=-1; locnbch++; } }
615 myNbSamplesV = nbch+5;
619 for(j=2;j<nbvp;j++) {
620 const gp_Pnt& A=array2.Value(1,j);
621 const gp_Pnt& B=array2.Value(2,j);
622 const gp_Pnt& C=array2.Value(3,j);
623 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
624 C.Y()-B.Y()-B.Y()+A.Y(),
625 C.Z()-B.Z()-B.Z()+A.Z());
626 Standard_Integer locnbch=0;
627 for(i=3; i<nbup;i++) { //-- try
628 const gp_Pnt& A1=array2.Value(i-1,j);
629 const gp_Pnt& B1=array2.Value(i,j);
630 const gp_Pnt& C1=array2.Value(i+1,j);
631 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
632 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
633 C1.Z()-B1.Z()-B1.Z()+A1.Z());
634 Standard_Real pd = Vi.Dot(Vip1);
636 if(pd>1.0e-7 || pd<-1.0e-7) {
637 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
638 else { if(sh==1) { sh=-1; locnbch++; } }
641 if(locnbch>nbch) nbch=locnbch;
644 myNbSamplesU = nbch+5;
648 void Adaptor3d_TopolTool::ComputeSamplePoints() {
649 Standard_Real uinf,usup,vinf,vsup;
650 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
651 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
652 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
653 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
654 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
655 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
656 else if (usup == RealLast()) { usup=uinf+2.e5; }
658 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
659 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
660 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
662 Standard_Integer nbsu,nbsv;
663 GeomAbs_SurfaceType typS = myS->GetType();
665 case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
666 case GeomAbs_BezierSurface: { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles(); } break;
667 case GeomAbs_BSplineSurface: {
668 nbsv = myS->NbVKnots(); nbsv*= myS->VDegree(); if(nbsv < 4) nbsv=4;
669 nbsu = myS->NbUKnots(); nbsu*= myS->UDegree(); if(nbsu < 4) nbsu=4;
672 case GeomAbs_Cylinder:
676 case GeomAbs_SurfaceOfRevolution:
677 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=15; } break;
678 default: { nbsu = 10; nbsv=10; } break;
681 //-- If the number of points is too great... analyze
691 if(nbsu>8 || nbsv>8) {
692 if(typS == GeomAbs_BSplineSurface) {
693 const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
694 Standard_Integer nbup = Bspl->NbUPoles();
695 Standard_Integer nbvp = Bspl->NbVPoles();
696 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
698 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
700 else if(typS == GeomAbs_BezierSurface) {
701 const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
702 Standard_Integer nbup = Bez->NbUPoles();
703 Standard_Integer nbvp = Bez->NbVPoles();
704 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
706 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
711 Standard_Integer Adaptor3d_TopolTool::NbSamplesU()
713 if(myNbSamplesU <0) {
714 ComputeSamplePoints();
716 return(myNbSamplesU);
719 Standard_Integer Adaptor3d_TopolTool::NbSamplesV()
721 if(myNbSamplesU <0) {
722 ComputeSamplePoints();
724 return(myNbSamplesV);
727 Standard_Integer Adaptor3d_TopolTool::NbSamples()
729 if(myNbSamplesU <0) {
730 ComputeSamplePoints();
732 return(myNbSamplesU*myNbSamplesV);
735 void Adaptor3d_TopolTool::UParameters(TColStd_Array1OfReal& theArray) const
737 theArray = myUPars->Array1();
740 void Adaptor3d_TopolTool::VParameters(TColStd_Array1OfReal& theArray) const
742 theArray = myVPars->Array1();
745 void Adaptor3d_TopolTool::SamplePoint(const Standard_Integer i,
749 Standard_Integer iu, iv;
751 if (myUPars.IsNull())
753 Standard_Real myDU=(Usup-Uinf)/(myNbSamplesU+1);
754 Standard_Real myDV=(Vsup-Vinf)/(myNbSamplesV+1);
755 iv = 1 + i/myNbSamplesU;
756 iu = 1+ i-(iv-1)*myNbSamplesU;
762 iv = (i-1)/myNbSamplesU + 1;
763 iu = (i-1)%myNbSamplesU + 1;
764 u = myUPars->Value(iu);
765 v = myVPars->Value(iv);
769 P3d = myS->Value(u,v);
774 Standard_Boolean Adaptor3d_TopolTool::DomainIsInfinite() {
775 if(Precision::IsNegativeInfinite(Uinf)) return(Standard_True);
776 if(Precision::IsPositiveInfinite(Usup)) return(Standard_True);
777 if(Precision::IsNegativeInfinite(Vinf)) return(Standard_True);
778 if(Precision::IsPositiveInfinite(Vsup)) return(Standard_True);
779 return(Standard_False);
781 //=======================================================================
784 //=======================================================================
785 Standard_Address Adaptor3d_TopolTool::Edge() const
789 //=======================================================================
792 //=======================================================================
794 Standard_Boolean Adaptor3d_TopolTool::Has3d() const
796 return Standard_False;
799 //=======================================================================
802 //=======================================================================
804 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)&) const
806 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
810 //=======================================================================
813 //=======================================================================
815 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)&) const
817 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
821 //=======================================================================
824 //=======================================================================
826 gp_Pnt Adaptor3d_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)&) const
828 Standard_DomainError::Raise("Adaptor3d_TopolTool: has no 3d representation");
833 //=======================================================================
834 //function : SamplePnts
836 //=======================================================================
838 void Adaptor3d_TopolTool::SamplePnts(const Standard_Real theDefl,
839 const Standard_Integer theNUmin,
840 const Standard_Integer theNVmin)
842 Standard_Real uinf,usup,vinf,vsup;
843 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
844 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
845 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
846 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
847 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
848 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
849 else if (usup == RealLast()) { usup=uinf+2.e5; }
851 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
852 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
853 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
855 // Standard_Integer nbsu,nbsv;
856 GeomAbs_SurfaceType typS = myS->GetType();
858 // case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
859 // case GeomAbs_BezierSurface: {
860 // nbsv=myS->NbVPoles();
861 // nbsu=myS->NbUPoles();
862 // nbsu = Max(nbsu, theNUmin);
863 // nbsv = Max(nbsv, theNVmin);
864 // if(nbsu>8 || nbsv>8) {
865 // const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
866 // Standard_Integer nbup = Bez->NbUPoles();
867 // Standard_Integer nbvp = Bez->NbVPoles();
868 // TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
869 // Bez->Poles(array2);
870 // Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
874 // case GeomAbs_BSplineSurface: {
875 if(typS == GeomAbs_BSplineSurface) {
876 // Processing BSpline surface
877 BSplSamplePnts(theDefl, theNUmin, theNVmin);
881 ComputeSamplePoints();
883 // case GeomAbs_Cylinder:
884 // case GeomAbs_Cone:
885 // case GeomAbs_Sphere:
886 // case GeomAbs_Torus:
887 // case GeomAbs_SurfaceOfRevolution:
888 // case GeomAbs_SurfaceOfExtrusion: { nbsv = Max(15,theNVmin); nbsu=Max(15,theNUmin); } break;
889 // default: { nbsu = Max(10,theNUmin); nbsv=Max(10,theNVmin); } break;
893 // if(nbsu<6) nbsu=6;
894 // if(nbsv<6) nbsv=6;
896 // myNbSamplesU = nbsu;
897 // myNbSamplesV = nbsv;
900 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
901 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
903 Standard_Real t, dt = (usup - uinf)/(myNbSamplesU - 1);
904 myUPars->SetValue(1, uinf);
905 myUPars->SetValue(myNbSamplesU, usup);
906 for(i = 2, t = uinf+dt; i < myNbSamplesU; ++i, t += dt) {
907 myUPars->SetValue(i, t);
910 dt = (vsup - vinf)/(myNbSamplesV - 1);
911 myVPars->SetValue(1, vinf);
912 myVPars->SetValue(myNbSamplesV, vsup);
913 for(i = 2, t = vinf+dt; i < myNbSamplesV; ++i, t += dt) {
914 myVPars->SetValue(i, t);
921 //=======================================================================
922 //function : BSplSamplePnts
924 //=======================================================================
926 void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
927 const Standard_Integer theNUmin,
928 const Standard_Integer theNVmin)
930 const Handle(Geom_BSplineSurface)& aBS = myS->BSpline();
931 Standard_Real uinf,usup,vinf,vsup;
932 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
933 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
935 Standard_Integer i, k, j = 1;
936 Standard_Real t1, t2, dt;
937 Standard_Integer ui1 = aBS->FirstUKnotIndex();
938 Standard_Integer ui2 = aBS->LastUKnotIndex();
939 Standard_Integer vi1 = aBS->FirstVKnotIndex();
940 Standard_Integer vi2 = aBS->LastVKnotIndex();
942 for(i = ui1; i < ui2; ++i) {
943 if(uinf >= aBS->UKnot(i) && uinf < aBS->UKnot(i+1)) {
949 for(i = ui2; i > ui1; --i) {
950 if(usup <= aBS->UKnot(i) && usup > aBS->UKnot(i-1)) {
956 for(i = vi1; i < vi2; ++i) {
957 if(vinf >= aBS->VKnot(i) && vinf < aBS->VKnot(i+1)) {
963 for(i = vi2; i > vi1; --i) {
964 if(vsup <= aBS->VKnot(i) && vsup > aBS->VKnot(i-1)) {
970 Standard_Integer nbsu = ui2-ui1+1; nbsu += (nbsu - 1) * (aBS->UDegree()-1);
971 Standard_Integer nbsv = vi2-vi1+1; nbsv += (nbsv - 1) * (aBS->VDegree()-1);
972 Standard_Boolean bUuniform = Standard_False;
973 Standard_Boolean bVuniform = Standard_False;
975 //modified by NIZHNY-EMV Mon Jun 10 14:19:04 2013
976 if (nbsu < theNUmin || nbsv < theNVmin) {
977 Standard_Integer aNb;
979 aNb = (Standard_Integer)(nbsv * ((Standard_Real)theNUmin)/((Standard_Real)nbsu));
981 bVuniform = (aNb > nbsv) ? Standard_True : bVuniform;
982 nbsv = bVuniform ? aNb : nbsv;
984 aNb = (Standard_Integer)(nbsu * ((Standard_Real)theNVmin)/((Standard_Real)nbsv));
986 bUuniform = (aNb > nbsu) ? Standard_True : bUuniform;
987 nbsu = bUuniform ? aNb : nbsu;
990 //modified by NIZHNY-EMV Mon Jun 10 14:19:05 2013
992 if(nbsu < theNUmin) {
994 bUuniform = Standard_True;
997 if(nbsv < theNVmin) {
999 bVuniform = Standard_True;
1002 TColStd_Array1OfReal anUPars(1, nbsu);
1003 TColStd_Array1OfBoolean anUFlg(1, nbsu);
1004 TColStd_Array1OfReal aVPars(1, nbsv);
1005 TColStd_Array1OfBoolean aVFlg(1, nbsv);
1007 //Filling of sample parameters
1011 dt = (t2 - t1)/(nbsu - 1);
1013 anUFlg(1) = Standard_False;
1015 anUFlg(nbsu) = Standard_False;
1016 for(i = 2, t1 += dt; i < nbsu; ++i, t1 += dt) {
1018 anUFlg(i) = Standard_False;
1022 Standard_Integer nbi = aBS->UDegree();
1025 for(i = ui1+1; i <= ui2; ++i) {
1026 if(i == ui2) t2 = usup;
1027 else t2 = aBS->UKnot(i);
1033 anUFlg(k) = Standard_False;
1046 dt = (t2 - t1)/(nbsv - 1);
1048 aVFlg(1) = Standard_False;
1050 aVFlg(nbsv) = Standard_False;
1051 for(i = 2, t1 += dt; i < nbsv; ++i, t1 += dt) {
1053 aVFlg(i) = Standard_False;
1057 Standard_Integer nbi = aBS->VDegree();
1060 for(i = vi1+1; i <= vi2; ++i) {
1061 if(i == vi2) t2 = vsup;
1062 else t2 = aBS->VKnot(i);
1068 aVFlg(k) = Standard_False;
1078 //Analysis of deflection
1080 Standard_Real aDefl2 = Max(theDefl*theDefl, 1.e-9);
1081 Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
1084 // Calculations of B-spline values will be made using adaptor,
1085 // because it caches the data for performance
1086 GeomAdaptor_Surface aBSplAdaptor(aBS);
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 gp_Pnt p1 = aBSplAdaptor.Value(t2, t1);
1105 for(k = j+2; k <= nbsu; ++k) {
1107 // gp_Pnt p2 = aBS->Value(t2, t1);
1108 gp_Pnt p2 = aBSplAdaptor.Value(t2, t1);
1109 //gce_MakeLin MkLin(p1, p2);
1110 //const gp_Lin& lin = MkLin.Value();
1112 if(p1.SquareDistance(p2) <= tol) continue;
1114 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1115 Standard_Boolean ok = Standard_True;
1116 for(l = j+1; l < k; ++l) {
1119 ok = Standard_False;
1123 // gp_Pnt pp = aBS->Value(anUPars(l), t1);
1124 gp_Pnt pp = aBSplAdaptor.Value(anUPars(l), t1);
1125 Standard_Real d = lin.SquareDistance(pp);
1127 if(d <= aDefl2) continue;
1129 ok = Standard_False;
1135 anUFlg(j) = Standard_True;
1148 if(k >= nbsu) bCont = Standard_False;
1154 for (i = 1; i <= nbsu; i++)
1155 if (anUFlg(i) == Standard_True)
1158 if(myNbSamplesU < myMinPnts) {
1159 if(myNbSamplesU == 2) {
1160 //"uniform" distribution;
1161 Standard_Integer nn = nbsu/myMinPnts;
1162 anUFlg(1+nn) = Standard_True;
1163 anUFlg(nbsu-nn) = Standard_True;
1165 else { //myNbSamplesU == 3
1166 //insert in bigger segment
1168 while(!anUFlg(i++));
1169 if(i < nbsu/2) j = Min(i+(nbsu-i)/2, nbsu-1);
1170 else j = Max(i/2, 2);
1172 anUFlg(j) = Standard_True;
1173 myNbSamplesU = myMinPnts;
1176 aVFlg(1) = Standard_True;
1177 aVFlg(nbsv) = Standard_True;
1179 for(i = 1; i <= nbsu; ++i) {
1182 Standard_Boolean bCont = Standard_True;
1183 while (j < nbsv-1 && bCont) {
1191 // gp_Pnt p1 = aBS->Value(t1, t2);
1192 gp_Pnt p1 = aBSplAdaptor.Value(t1, t2);
1193 for(k = j+2; k <= nbsv; ++k) {
1195 // gp_Pnt p2 = aBS->Value(t1, t2);
1196 gp_Pnt p2 = aBSplAdaptor.Value(t1, t2);
1198 if(p1.SquareDistance(p2) <= tol) continue;
1199 //gce_MakeLin MkLin(p1, p2);
1200 //const gp_Lin& lin = MkLin.Value();
1201 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1202 Standard_Boolean ok = Standard_True;
1203 for(l = j+1; l < k; ++l) {
1206 ok = Standard_False;
1210 // gp_Pnt pp = aBS->Value(t1, aVPars(l));
1211 gp_Pnt pp = aBSplAdaptor.Value(t1, aVPars(l));
1212 Standard_Real d = lin.SquareDistance(pp);
1214 if(d <= aDefl2) continue;
1216 ok = Standard_False;
1222 aVFlg(j) = Standard_True;
1235 if(k >= nbsv) bCont = Standard_False;
1241 for (i = 1; i <= nbsv; i++)
1242 if (aVFlg(i) == Standard_True)
1245 if(myNbSamplesV < myMinPnts) {
1246 if(myNbSamplesV == 2) {
1247 //"uniform" distribution;
1248 Standard_Integer nn = nbsv/myMinPnts;
1249 aVFlg(1+nn) = Standard_True;
1250 aVFlg(nbsv-nn) = Standard_True;
1251 myNbSamplesV = myMinPnts;
1253 else { //myNbSamplesU == 3
1254 //insert in bigger segment
1257 if(i < nbsv/2) j = Min(i+(nbsv-i)/2, nbsv-1);
1258 else j = Max(i/2, 2);
1260 myNbSamplesV = myMinPnts;
1261 aVFlg(j) = Standard_True;
1264 //modified by NIZNHY-PKV Fri Dec 16 10:05:01 2011f
1266 Standard_Boolean bFlag;
1269 bFlag=(myNbSamplesU < theNUmin);
1274 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1276 for(j = 0, i = 1; i <= nbsu; ++i) {
1278 myUPars->SetValue(i,anUPars(i));
1283 myUPars->SetValue(j,anUPars(i));
1289 bFlag=(myNbSamplesV < theNVmin);
1294 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1296 for(j = 0, i = 1; i <= nbsv; ++i) {
1298 myVPars->SetValue(i,aVPars(i));
1303 myVPars->SetValue(j,aVPars(i));
1309 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1310 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1313 for(i = 1; i <= nbsu; ++i) {
1316 myUPars->SetValue(j,anUPars(i));
1321 for(i = 1; i <= nbsv; ++i) {
1324 myVPars->SetValue(j,aVPars(i));
1328 //modified by NIZNHY-PKV Mon Dec 26 12:25:35 2011t
1332 //=======================================================================
1333 //function : IsUniformSampling
1335 //=======================================================================
1336 Standard_Boolean Adaptor3d_TopolTool::IsUniformSampling() const
1338 GeomAbs_SurfaceType typS = myS->GetType();
1340 if(typS == GeomAbs_BSplineSurface)
1341 return Standard_False;
1342 return Standard_True;