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 <Adaptor3d_TopolTool.hxx>
16 #include <Adaptor2d_Line2d.hxx>
17 #include <Adaptor3d_Surface.hxx>
18 #include <Adaptor3d_HVertex.hxx>
19 #include <GeomAdaptor_Surface.hxx>
20 #include <gp_Cone.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <gp_Trsf.hxx>
24 #include <Precision.hxx>
25 #include <Standard_DomainError.hxx>
26 #include <Standard_NotImplemented.hxx>
27 #include <Standard_Type.hxx>
29 IMPLEMENT_STANDARD_RTTIEXT(Adaptor3d_TopolTool,Standard_Transient)
31 #define myInfinite Precision::Infinite()
33 static void GetConeApexParam(const gp_Cone& C, Standard_Real& U, Standard_Real& V)
35 const gp_Ax3& Pos = C.Position();
36 Standard_Real Radius = C.RefRadius();
37 Standard_Real SAngle = C.SemiAngle();
38 const gp_Pnt& P = C.Apex();
41 T.SetTransformation (Pos);
42 gp_Pnt Ploc = P.Transformed (T);
44 if(Ploc.X() ==0.0 && Ploc.Y()==0.0 ) {
47 else if ( -Radius > Ploc.Z()* Tan(SAngle) ) {
48 // the point is at the `wrong` side of the apex
49 U = atan2(-Ploc.Y(), -Ploc.X());
52 U = atan2(Ploc.Y(),Ploc.X());
54 if (U < -1.e-16) U += (M_PI+M_PI);
55 else if (U < 0) U = 0;
57 V = sin(SAngle) * ( Ploc.X() * cos(U) + Ploc.Y() * sin(U) - Radius)
58 + cos(SAngle) * Ploc.Z();
62 Adaptor3d_TopolTool::Adaptor3d_TopolTool ()
76 Adaptor3d_TopolTool::Adaptor3d_TopolTool (const Handle(Adaptor3d_Surface)& S)
82 void Adaptor3d_TopolTool::Initialize ()
84 throw Standard_NotImplemented("Adaptor3d_TopolTool::Initialize ()");
87 void Adaptor3d_TopolTool::Initialize (const Handle(Adaptor3d_Surface)& S)
89 Standard_Real pinf,psup,deltap;
90 //Adaptor2d_Line2d * Line2dPtr ;
93 Uinf = S->FirstUParameter(); // where UIntervalFirst ??
94 Vinf = S->FirstVParameter();
95 Usup = S->LastUParameter();
96 Vsup = S->LastVParameter();
100 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
101 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
102 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
103 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
105 if (! Vinfinfinite) {
106 deltap = Min(Usup-Uinf,2.*myInfinite);
107 if (Uinf >= -myInfinite){
109 psup = pinf + deltap;
111 else if (Usup <= myInfinite) {
113 pinf = psup - deltap;
120 // Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup);
121 //myRestr[nbRestr] = new Adaptor2d_Line2d(*Line2dPtr);
122 myRestr[nbRestr] = new Adaptor2d_Line2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup));
127 deltap = Min(Vsup-Vinf,2.*myInfinite);
128 if (Vinf >= -myInfinite){
130 psup = pinf + deltap;
132 else if (Vsup <= myInfinite) {
134 pinf = psup - deltap;
143 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup);
144 //myRestr[nbRestr] = new Adaptor2d_Line2d(*Line2dPtr);
145 myRestr[nbRestr] = new Adaptor2d_Line2d(Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup));
150 deltap = Min(Usup-Uinf,2.*myInfinite);
151 if (-Usup >= -myInfinite){
153 psup = pinf + deltap;
155 else if (-Uinf <= myInfinite) {
157 pinf = psup - deltap;
165 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup);
166 //myRestr[nbRestr] = new Adaptor2d_Line2d(*Line2dPtr);
167 myRestr[nbRestr] = new Adaptor2d_Line2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup));
172 deltap = Min(Vsup-Vinf,2.*myInfinite);
173 if (-Vsup >= -myInfinite){
175 psup = pinf + deltap;
177 else if (-Vinf <= myInfinite) {
179 pinf = psup - deltap;
186 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup);
187 //myRestr[nbRestr] = new Adaptor2d_Line2d(*Line2dPtr);
188 myRestr[nbRestr] = new Adaptor2d_Line2d(Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup));
194 if(nbRestr == 2 && S->GetType() == GeomAbs_Cone ) {
195 Standard_Real U = 0., V = 0.;
196 GetConeApexParam(S->Cone(),U,V);
198 deltap = Min(Usup-Uinf,2.*myInfinite);
199 if (Uinf >= -myInfinite){
201 psup = pinf + deltap;
203 else if (Usup <= myInfinite) {
205 pinf = psup - deltap;
212 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup);
213 //myRestr[nbRestr] = new Adaptor2d_Line2d(*Line2dPtr);
214 myRestr[nbRestr] = new Adaptor2d_Line2d(Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup));
220 void Adaptor3d_TopolTool::Init ()
226 Standard_Boolean Adaptor3d_TopolTool::More ()
228 return (idRestr < nbRestr);
231 Handle(Adaptor2d_Curve2d) Adaptor3d_TopolTool::Value ()
233 if (idRestr >= nbRestr) {throw Standard_DomainError();}
234 return myRestr[idRestr];
237 void Adaptor3d_TopolTool::Next ()
243 void Adaptor3d_TopolTool::Initialize(const Handle(Adaptor2d_Curve2d)& C)
247 Standard_Real theUinf,theUsup;
248 theUinf = C->FirstParameter();
249 theUsup = C->LastParameter();
250 // if (!Precision::IsNegativeInfinite(theUinf)) {
251 if (theUinf > -myInfinite) {
252 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUinf),TopAbs_FORWARD,1.e-8);
255 // if (!Precision::IsPositiveInfinite(theUsup)) {
256 if (theUsup < myInfinite) {
257 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUsup),TopAbs_REVERSED,1.e-8);
263 void Adaptor3d_TopolTool::InitVertexIterator ()
269 Standard_Boolean Adaptor3d_TopolTool::MoreVertex ()
271 return (idVtx < nbVtx);
275 Handle(Adaptor3d_HVertex) Adaptor3d_TopolTool::Vertex ()
277 if (idVtx >= nbVtx) {throw Standard_DomainError();}
281 void Adaptor3d_TopolTool::NextVertex ()
287 TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
288 const Standard_Real Tol,
289 const Standard_Boolean )
290 // const Standard_Boolean RecadreOnPeriodic)
293 Standard_Real U = P.X();
294 Standard_Real V = P.Y();
297 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
298 (V < Vinf - Tol) || (V > Vsup + Tol)) {
301 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
302 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
307 else if (nbRestr == 0) {
311 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
312 if (Precision::IsNegativeInfinite(Uinf) &&
313 Precision::IsPositiveInfinite(Usup)) {
314 dansu = Standard_True;
315 surumin = surumax = Standard_False;
317 else if (Precision::IsNegativeInfinite(Uinf)) {
318 surumin = Standard_False;
320 dansu = Standard_False;
321 surumax = Standard_False;
324 dansu = Standard_True;
325 surumax = Standard_False;
326 if (Abs(U-Usup)<=Tol) {
327 surumax = Standard_True;
331 else if (Precision::IsPositiveInfinite(Usup)) {
332 surumax = Standard_False;
334 dansu = Standard_False;
335 surumin = Standard_False;
338 dansu = Standard_True;
339 surumin = Standard_False;
340 if (Abs(U-Uinf)<=Tol) {
341 surumin = Standard_True;
346 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
347 surumin = surumax = dansu = Standard_False;
350 dansu = Standard_True;
351 surumin = surumax = Standard_False;
352 if (Abs(U-Uinf)<=Tol) {
353 surumin = Standard_True;
355 else if (Abs(U-Usup)<=Tol) {
356 surumax = Standard_True;
361 if (Precision::IsNegativeInfinite(Vinf) &&
362 Precision::IsPositiveInfinite(Vsup)) {
363 dansv = Standard_True;
364 survmin = survmax = Standard_False;
366 else if (Precision::IsNegativeInfinite(Vinf)) {
367 survmin = Standard_False;
369 dansv = Standard_False;
370 survmax = Standard_False;
373 dansv = Standard_True;
374 survmax = Standard_False;
375 if (Abs(V-Vsup)<=Tol) {
376 survmax = Standard_True;
380 else if (Precision::IsPositiveInfinite(Vsup)) {
381 survmax = Standard_False;
383 dansv = Standard_False;
384 survmin = Standard_False;
387 dansv = Standard_True;
388 survmin = Standard_False;
389 if (Abs(V-Vinf)<=Tol) {
390 survmin = Standard_True;
395 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
396 survmin = survmax = dansv = Standard_False;
399 dansv = Standard_True;
400 survmin = survmax = Standard_False;
401 if (Abs(V-Vinf)<=Tol) {
402 survmin = Standard_True;
404 else if (Abs(V-Vsup)<=Tol) {
405 survmax = Standard_True;
410 if (!dansu || !dansv) {
413 if (surumin || survmin || surumax || survmax) {
422 Standard_Boolean Adaptor3d_TopolTool::IsThePointOn(const gp_Pnt2d& P,
423 const Standard_Real Tol,
424 const Standard_Boolean )
425 // const Standard_Boolean RecadreOnPeriodic)
428 Standard_Real U = P.X();
429 Standard_Real V = P.Y();
432 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
433 (V < Vinf - Tol) || (V > Vsup + Tol)) {
434 return(Standard_False);
436 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
437 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
438 return(Standard_True);
440 return(Standard_False);
442 else if (nbRestr == 0) {
443 return(Standard_False);
446 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
447 if (Precision::IsNegativeInfinite(Uinf) &&
448 Precision::IsPositiveInfinite(Usup)) {
449 dansu = Standard_True;
450 surumin = surumax = Standard_False;
452 else if (Precision::IsNegativeInfinite(Uinf)) {
453 surumin = Standard_False;
455 dansu = Standard_False;
456 surumax = Standard_False;
459 dansu = Standard_True;
460 surumax = Standard_False;
461 if (Abs(U-Usup)<=Tol) {
462 surumax = Standard_True;
466 else if (Precision::IsPositiveInfinite(Usup)) {
467 surumax = Standard_False;
469 dansu = Standard_False;
470 surumin = Standard_False;
473 dansu = Standard_True;
474 surumin = Standard_False;
475 if (Abs(U-Uinf)<=Tol) {
476 surumin = Standard_True;
481 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
482 surumin = surumax = dansu = Standard_False;
485 dansu = Standard_True;
486 surumin = surumax = Standard_False;
487 if (Abs(U-Uinf)<=Tol) {
488 surumin = Standard_True;
490 else if (Abs(U-Usup)<=Tol) {
491 surumax = Standard_True;
496 if (Precision::IsNegativeInfinite(Vinf) &&
497 Precision::IsPositiveInfinite(Vsup)) {
498 dansv = Standard_True;
499 survmin = survmax = Standard_False;
501 else if (Precision::IsNegativeInfinite(Vinf)) {
502 survmin = Standard_False;
504 dansv = Standard_False;
505 survmax = Standard_False;
508 dansv = Standard_True;
509 survmax = Standard_False;
510 if (Abs(V-Vsup)<=Tol) {
511 survmax = Standard_True;
515 else if (Precision::IsPositiveInfinite(Vsup)) {
516 survmax = Standard_False;
518 dansv = Standard_False;
519 survmin = Standard_False;
522 dansv = Standard_True;
523 survmin = Standard_False;
524 if (Abs(V-Vinf)<=Tol) {
525 survmin = Standard_True;
530 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
531 survmin = survmax = dansv = Standard_False;
534 dansv = Standard_True;
535 survmin = survmax = Standard_False;
536 if (Abs(V-Vinf)<=Tol) {
537 survmin = Standard_True;
539 else if (Abs(V-Vsup)<=Tol) {
540 survmax = Standard_True;
545 if (!dansu || !dansv) {
546 return(Standard_False);
548 if (surumin || survmin || surumax || survmax) {
549 return(Standard_True);
551 return Standard_False;
556 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
557 (const Handle(Adaptor2d_Curve2d)&)
559 return TopAbs_FORWARD;
562 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
563 (const Handle(Adaptor3d_HVertex)& V)
565 return V->Orientation();
568 Standard_Boolean Adaptor3d_TopolTool::Identical
569 (const Handle(Adaptor3d_HVertex)& V1,
570 const Handle(Adaptor3d_HVertex)& V2)
572 return V1->IsSame(V2);
576 //-- ============================================================
577 //-- m e t h o d e s u t i l i s e e s p o u r l e s
579 //-- ============================================================
580 #include <TColgp_Array2OfPnt.hxx>
581 #include <Geom_BezierSurface.hxx>
582 #include <Geom_BSplineSurface.hxx>
583 #include <TColStd_Array1OfReal.hxx>
584 #include <TColStd_Array1OfBoolean.hxx>
585 //#include <gce_MakeLin.hxx>
586 #include <gp_Lin.hxx>
587 #include <gp_Dir.hxx>
588 #include <gp_Vec.hxx>
590 #define myMinPnts 4 //Absolut possible minimum of sample points
591 //Restriction of IntPolyh
594 static void Analyse(const TColgp_Array2OfPnt& array2,
595 const Standard_Integer nbup,
596 const Standard_Integer nbvp,
597 Standard_Integer& myNbSamplesU,
598 Standard_Integer& myNbSamplesV) {
600 Standard_Integer sh,nbch,i,j;
605 for(i=2;i<nbup;i++) {
606 const gp_Pnt& A=array2.Value(i,1);
607 const gp_Pnt& B=array2.Value(i,2);
608 const gp_Pnt& C=array2.Value(i,3);
609 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
610 C.Y()-B.Y()-B.Y()+A.Y(),
611 C.Z()-B.Z()-B.Z()+A.Z());
612 Standard_Integer locnbch=0;
613 for(j=3; j<nbvp;j++) { //-- try
614 const gp_Pnt& A1=array2.Value(i,j-1);
615 const gp_Pnt& B1=array2.Value(i,j);
616 const gp_Pnt& C1=array2.Value(i,j+1);
617 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
618 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
619 C1.Z()-B1.Z()-B1.Z()+A1.Z());
620 Standard_Real pd = Vi.Dot(Vip1);
622 if(pd>1.0e-7 || pd<-1.0e-7) {
623 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
624 else { if(sh==1) { sh=-1; locnbch++; } }
632 myNbSamplesV = nbch+5;
636 for(j=2;j<nbvp;j++) {
637 const gp_Pnt& A=array2.Value(1,j);
638 const gp_Pnt& B=array2.Value(2,j);
639 const gp_Pnt& C=array2.Value(3,j);
640 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
641 C.Y()-B.Y()-B.Y()+A.Y(),
642 C.Z()-B.Z()-B.Z()+A.Z());
643 Standard_Integer locnbch=0;
644 for(i=3; i<nbup;i++) { //-- try
645 const gp_Pnt& A1=array2.Value(i-1,j);
646 const gp_Pnt& B1=array2.Value(i,j);
647 const gp_Pnt& C1=array2.Value(i+1,j);
648 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
649 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
650 C1.Z()-B1.Z()-B1.Z()+A1.Z());
651 Standard_Real pd = Vi.Dot(Vip1);
653 if(pd>1.0e-7 || pd<-1.0e-7) {
654 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
655 else { if(sh==1) { sh=-1; locnbch++; } }
658 if(locnbch>nbch) nbch=locnbch;
661 myNbSamplesU = nbch+5;
665 void Adaptor3d_TopolTool::ComputeSamplePoints()
667 const Standard_Integer aMaxNbSample = 50;
669 Standard_Real uinf,usup,vinf,vsup;
670 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
671 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
672 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
673 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
674 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
675 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
676 else if (usup == RealLast()) { usup=uinf+2.e5; }
678 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
679 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
680 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
682 Standard_Integer nbsu,nbsv;
683 GeomAbs_SurfaceType typS = myS->GetType();
685 case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
686 case GeomAbs_BezierSurface: { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles(); } break;
687 case GeomAbs_BSplineSurface: {
688 nbsv = myS->NbVKnots(); nbsv*= myS->VDegree(); if(nbsv < 4) nbsv=4;
689 nbsu = myS->NbUKnots(); nbsu*= myS->UDegree(); if(nbsu < 4) nbsu=4;
692 case GeomAbs_Cylinder:
696 case GeomAbs_SurfaceOfRevolution:
697 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=15; } break;
698 default: { nbsu = 10; nbsv=10; } break;
701 //-- If the number of points is too great... analyze
708 if (typS == GeomAbs_BSplineSurface) {
709 if (nbsu > 8 || nbsv>8) {
710 const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
711 Standard_Integer nbup = Bspl->NbUPoles();
712 Standard_Integer nbvp = Bspl->NbVPoles();
713 TColgp_Array2OfPnt array2(1, nbup, 1, nbvp);
715 Analyse(array2, nbup, nbvp, nbsu, nbsv);
718 Standard_Real anULen = (usup - uinf) / myS->UResolution(1.);
719 Standard_Real anVLen = (vsup - vinf) / myS->VResolution(1.);
720 Standard_Real aRatio = anULen / anVLen;
724 nbsu = Min(nbsu, aMaxNbSample);
726 else if (aRatio <= 0.1)
729 nbsv = Min(nbsv, aMaxNbSample);
732 else if (typS == GeomAbs_BezierSurface) {
733 if (nbsu > 8 || nbsv > 8) {
734 const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
735 Standard_Integer nbup = Bez->NbUPoles();
736 Standard_Integer nbvp = Bez->NbVPoles();
737 TColgp_Array2OfPnt array2(1, nbup, 1, nbvp);
739 Analyse(array2, nbup, nbvp, nbsu, nbsv);
749 Standard_Integer Adaptor3d_TopolTool::NbSamplesU()
751 if(myNbSamplesU <0) {
752 ComputeSamplePoints();
754 return(myNbSamplesU);
757 Standard_Integer Adaptor3d_TopolTool::NbSamplesV()
759 if(myNbSamplesU <0) {
760 ComputeSamplePoints();
762 return(myNbSamplesV);
765 Standard_Integer Adaptor3d_TopolTool::NbSamples()
767 if(myNbSamplesU <0) {
768 ComputeSamplePoints();
770 return(myNbSamplesU*myNbSamplesV);
773 void Adaptor3d_TopolTool::UParameters(TColStd_Array1OfReal& theArray) const
775 theArray = myUPars->Array1();
778 void Adaptor3d_TopolTool::VParameters(TColStd_Array1OfReal& theArray) const
780 theArray = myVPars->Array1();
783 void Adaptor3d_TopolTool::SamplePoint(const Standard_Integer i,
787 Standard_Integer iu, iv;
789 if (myUPars.IsNull())
791 Standard_Real myDU=(Usup-Uinf)/(myNbSamplesU+1);
792 Standard_Real myDV=(Vsup-Vinf)/(myNbSamplesV+1);
793 iv = 1 + i/myNbSamplesU;
794 iu = 1+ i-(iv-1)*myNbSamplesU;
800 iv = (i-1)/myNbSamplesU + 1;
801 iu = (i-1)%myNbSamplesU + 1;
802 u = myUPars->Value(iu);
803 v = myVPars->Value(iv);
807 P3d = myS->Value(u,v);
812 Standard_Boolean Adaptor3d_TopolTool::DomainIsInfinite() {
813 if(Precision::IsNegativeInfinite(Uinf)) return(Standard_True);
814 if(Precision::IsPositiveInfinite(Usup)) return(Standard_True);
815 if(Precision::IsNegativeInfinite(Vinf)) return(Standard_True);
816 if(Precision::IsPositiveInfinite(Vsup)) return(Standard_True);
817 return(Standard_False);
819 //=======================================================================
822 //=======================================================================
823 Standard_Address Adaptor3d_TopolTool::Edge() const
827 //=======================================================================
830 //=======================================================================
832 Standard_Boolean Adaptor3d_TopolTool::Has3d() const
834 return Standard_False;
837 //=======================================================================
840 //=======================================================================
842 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor2d_Curve2d)&) const
844 throw Standard_DomainError("Adaptor3d_TopolTool: has no 3d representation");
847 //=======================================================================
850 //=======================================================================
852 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)&) const
854 throw Standard_DomainError("Adaptor3d_TopolTool: has no 3d representation");
857 //=======================================================================
860 //=======================================================================
862 gp_Pnt Adaptor3d_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)&) const
864 throw Standard_DomainError("Adaptor3d_TopolTool: has no 3d representation");
868 //=======================================================================
869 //function : SamplePnts
871 //=======================================================================
873 void Adaptor3d_TopolTool::SamplePnts(const Standard_Real theDefl,
874 const Standard_Integer theNUmin,
875 const Standard_Integer theNVmin)
877 Standard_Real uinf,usup,vinf,vsup;
878 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
879 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
880 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
881 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
882 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
883 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
884 else if (usup == RealLast()) { usup=uinf+2.e5; }
886 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
887 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
888 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
890 // Standard_Integer nbsu,nbsv;
891 GeomAbs_SurfaceType typS = myS->GetType();
893 // case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
894 // case GeomAbs_BezierSurface: {
895 // nbsv=myS->NbVPoles();
896 // nbsu=myS->NbUPoles();
897 // nbsu = Max(nbsu, theNUmin);
898 // nbsv = Max(nbsv, theNVmin);
899 // if(nbsu>8 || nbsv>8) {
900 // const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
901 // Standard_Integer nbup = Bez->NbUPoles();
902 // Standard_Integer nbvp = Bez->NbVPoles();
903 // TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
904 // Bez->Poles(array2);
905 // Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
909 // case GeomAbs_BSplineSurface: {
910 if(typS == GeomAbs_BSplineSurface) {
911 // Processing BSpline surface
912 BSplSamplePnts(theDefl, theNUmin, theNVmin);
916 ComputeSamplePoints();
918 // case GeomAbs_Cylinder:
919 // case GeomAbs_Cone:
920 // case GeomAbs_Sphere:
921 // case GeomAbs_Torus:
922 // case GeomAbs_SurfaceOfRevolution:
923 // case GeomAbs_SurfaceOfExtrusion: { nbsv = Max(15,theNVmin); nbsu=Max(15,theNUmin); } break;
924 // default: { nbsu = Max(10,theNUmin); nbsv=Max(10,theNVmin); } break;
928 // if(nbsu<6) nbsu=6;
929 // if(nbsv<6) nbsv=6;
931 // myNbSamplesU = nbsu;
932 // myNbSamplesV = nbsv;
935 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
936 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
938 Standard_Real t, dt = (usup - uinf)/(myNbSamplesU - 1);
939 myUPars->SetValue(1, uinf);
940 myUPars->SetValue(myNbSamplesU, usup);
941 for(i = 2, t = uinf+dt; i < myNbSamplesU; ++i, t += dt) {
942 myUPars->SetValue(i, t);
945 dt = (vsup - vinf)/(myNbSamplesV - 1);
946 myVPars->SetValue(1, vinf);
947 myVPars->SetValue(myNbSamplesV, vsup);
948 for(i = 2, t = vinf+dt; i < myNbSamplesV; ++i, t += dt) {
949 myVPars->SetValue(i, t);
956 //=======================================================================
957 //function : BSplSamplePnts
959 //=======================================================================
961 void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
962 const Standard_Integer theNUmin,
963 const Standard_Integer theNVmin)
965 const Standard_Integer aMaxPnts = 1001;
966 const Handle(Geom_BSplineSurface)& aBS = myS->BSpline();
967 Standard_Real uinf,usup,vinf,vsup;
968 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
969 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
971 Standard_Integer i, k, j = 1;
972 Standard_Real t1, t2, dt;
973 Standard_Integer ui1 = aBS->FirstUKnotIndex();
974 Standard_Integer ui2 = aBS->LastUKnotIndex();
975 Standard_Integer vi1 = aBS->FirstVKnotIndex();
976 Standard_Integer vi2 = aBS->LastVKnotIndex();
978 for(i = ui1; i < ui2; ++i) {
979 if(uinf >= aBS->UKnot(i) && uinf < aBS->UKnot(i+1)) {
985 for(i = ui2; i > ui1; --i) {
986 if(usup <= aBS->UKnot(i) && usup > aBS->UKnot(i-1)) {
992 for(i = vi1; i < vi2; ++i) {
993 if(vinf >= aBS->VKnot(i) && vinf < aBS->VKnot(i+1)) {
999 for(i = vi2; i > vi1; --i) {
1000 if(vsup <= aBS->VKnot(i) && vsup > aBS->VKnot(i-1)) {
1006 Standard_Integer nbsu = ui2-ui1+1; nbsu += (nbsu - 1) * (aBS->UDegree()-1);
1007 Standard_Integer nbsv = vi2-vi1+1; nbsv += (nbsv - 1) * (aBS->VDegree()-1);
1008 Standard_Boolean bUuniform = Standard_False;
1009 Standard_Boolean bVuniform = Standard_False;
1011 //modified by NIZHNY-EMV Mon Jun 10 14:19:04 2013
1012 if (nbsu < theNUmin || nbsv < theNVmin) {
1013 Standard_Integer aNb;
1015 aNb = (Standard_Integer)(nbsv * ((Standard_Real)theNUmin)/((Standard_Real)nbsu));
1017 bVuniform = (aNb > nbsv) ? Standard_True : bVuniform;
1018 nbsv = bVuniform ? aNb : nbsv;
1020 aNb = (Standard_Integer)(nbsu * ((Standard_Real)theNVmin)/((Standard_Real)nbsv));
1022 bUuniform = (aNb > nbsu) ? Standard_True : bUuniform;
1023 nbsu = bUuniform ? aNb : nbsu;
1026 //modified by NIZHNY-EMV Mon Jun 10 14:19:05 2013
1028 if(nbsu < theNUmin) {
1030 bUuniform = Standard_True;
1032 else if (nbsu > aMaxPnts)
1035 bUuniform = Standard_True;
1037 if(nbsv < theNVmin) {
1039 bVuniform = Standard_True;
1041 else if (nbsv > aMaxPnts)
1044 bVuniform = Standard_True;
1047 TColStd_Array1OfReal anUPars(1, nbsu);
1048 TColStd_Array1OfBoolean anUFlg(1, nbsu);
1049 TColStd_Array1OfReal aVPars(1, nbsv);
1050 TColStd_Array1OfBoolean aVFlg(1, nbsv);
1052 //Filling of sample parameters
1056 dt = (t2 - t1)/(nbsu - 1);
1058 anUFlg(1) = Standard_False;
1060 anUFlg(nbsu) = Standard_False;
1061 for(i = 2, t1 += dt; i < nbsu; ++i, t1 += dt) {
1063 anUFlg(i) = Standard_False;
1067 Standard_Integer nbi = aBS->UDegree();
1070 for(i = ui1+1; i <= ui2; ++i) {
1071 if(i == ui2) t2 = usup;
1072 else t2 = aBS->UKnot(i);
1078 anUFlg(k) = Standard_False;
1091 dt = (t2 - t1)/(nbsv - 1);
1093 aVFlg(1) = Standard_False;
1095 aVFlg(nbsv) = Standard_False;
1096 for(i = 2, t1 += dt; i < nbsv; ++i, t1 += dt) {
1098 aVFlg(i) = Standard_False;
1102 Standard_Integer nbi = aBS->VDegree();
1105 for(i = vi1+1; i <= vi2; ++i) {
1106 if(i == vi2) t2 = vsup;
1107 else t2 = aBS->VKnot(i);
1113 aVFlg(k) = Standard_False;
1123 //Analysis of deflection
1125 Standard_Real aDefl2 = Max(theDefl*theDefl, 1.e-9);
1126 Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
1129 anUFlg(1) = Standard_True;
1130 anUFlg(nbsu) = Standard_True;
1132 for(i = 1; i <= nbsv; ++i) {
1135 Standard_Boolean bCont = Standard_True;
1136 while (j < nbsu-1 && bCont) {
1144 gp_Pnt p1 = myS->Value(t2, t1);
1145 for(k = j+2; k <= nbsu; ++k) {
1147 gp_Pnt p2 = myS->Value(t2, t1);
1148 //gce_MakeLin MkLin(p1, p2);
1149 //const gp_Lin& lin = MkLin.Value();
1151 if(p1.SquareDistance(p2) <= tol) continue;
1153 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1154 Standard_Boolean ok = Standard_True;
1155 for(l = j+1; l < k; ++l) {
1158 ok = Standard_False;
1162 gp_Pnt pp = myS->Value(anUPars(l), t1);
1163 Standard_Real d = lin.SquareDistance(pp);
1165 if(d <= aDefl2) continue;
1167 ok = Standard_False;
1173 anUFlg(j) = Standard_True;
1186 if(k >= nbsu) bCont = Standard_False;
1192 for (i = 1; i <= nbsu; i++)
1193 if (anUFlg(i) == Standard_True)
1196 if(myNbSamplesU < myMinPnts) {
1197 if(myNbSamplesU == 2) {
1198 //"uniform" distribution;
1199 Standard_Integer nn = nbsu/myMinPnts;
1200 anUFlg(1+nn) = Standard_True;
1201 anUFlg(nbsu-nn) = Standard_True;
1203 else { //myNbSamplesU == 3
1204 //insert in bigger segment
1206 while(!anUFlg(i++));
1207 if(i < nbsu/2) j = Min(i+(nbsu-i)/2, nbsu-1);
1208 else j = Max(i/2, 2);
1210 anUFlg(j) = Standard_True;
1211 myNbSamplesU = myMinPnts;
1214 aVFlg(1) = Standard_True;
1215 aVFlg(nbsv) = Standard_True;
1217 for(i = 1; i <= nbsu; ++i) {
1220 Standard_Boolean bCont = Standard_True;
1221 while (j < nbsv-1 && bCont) {
1229 gp_Pnt p1 = myS->Value(t1, t2);
1230 for(k = j+2; k <= nbsv; ++k) {
1232 gp_Pnt p2 = myS->Value(t1, t2);
1234 if(p1.SquareDistance(p2) <= tol) continue;
1235 //gce_MakeLin MkLin(p1, p2);
1236 //const gp_Lin& lin = MkLin.Value();
1237 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1238 Standard_Boolean ok = Standard_True;
1239 for(l = j+1; l < k; ++l) {
1242 ok = Standard_False;
1246 gp_Pnt pp = myS->Value(t1, aVPars(l));
1247 Standard_Real d = lin.SquareDistance(pp);
1249 if(d <= aDefl2) continue;
1251 ok = Standard_False;
1257 aVFlg(j) = Standard_True;
1270 if(k >= nbsv) bCont = Standard_False;
1276 for (i = 1; i <= nbsv; i++)
1277 if (aVFlg(i) == Standard_True)
1280 if(myNbSamplesV < myMinPnts) {
1281 if(myNbSamplesV == 2) {
1282 //"uniform" distribution;
1283 Standard_Integer nn = nbsv/myMinPnts;
1284 aVFlg(1+nn) = Standard_True;
1285 aVFlg(nbsv-nn) = Standard_True;
1286 myNbSamplesV = myMinPnts;
1288 else { //myNbSamplesU == 3
1289 //insert in bigger segment
1292 if(i < nbsv/2) j = Min(i+(nbsv-i)/2, nbsv-1);
1293 else j = Max(i/2, 2);
1295 myNbSamplesV = myMinPnts;
1296 aVFlg(j) = Standard_True;
1299 //modified by NIZNHY-PKV Fri Dec 16 10:05:01 2011f
1301 Standard_Boolean bFlag;
1304 bFlag=(myNbSamplesU < theNUmin);
1309 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1311 for(j = 0, i = 1; i <= nbsu; ++i) {
1313 myUPars->SetValue(i,anUPars(i));
1318 myUPars->SetValue(j,anUPars(i));
1324 bFlag=(myNbSamplesV < theNVmin);
1329 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1331 for(j = 0, i = 1; i <= nbsv; ++i) {
1333 myVPars->SetValue(i,aVPars(i));
1338 myVPars->SetValue(j,aVPars(i));
1344 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1345 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1348 for(i = 1; i <= nbsu; ++i) {
1351 myUPars->SetValue(j,anUPars(i));
1356 for(i = 1; i <= nbsv; ++i) {
1359 myVPars->SetValue(j,aVPars(i));
1363 //modified by NIZNHY-PKV Mon Dec 26 12:25:35 2011t
1367 //=======================================================================
1368 //function : IsUniformSampling
1370 //=======================================================================
1371 Standard_Boolean Adaptor3d_TopolTool::IsUniformSampling() const
1373 GeomAbs_SurfaceType typS = myS->GetType();
1375 if(typS == GeomAbs_BSplineSurface)
1376 return Standard_False;
1377 return Standard_True;