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.
15 #include <Adaptor2d_HCurve2d.hxx>
16 #include <Adaptor2d_HLine2d.hxx>
17 #include <Adaptor3d_HSurface.hxx>
18 #include <Adaptor3d_HVertex.hxx>
19 #include <Adaptor3d_TopolTool.hxx>
20 #include <GeomAdaptor_Surface.hxx>
21 #include <gp_Cone.hxx>
23 #include <gp_Pnt2d.hxx>
24 #include <gp_Trsf.hxx>
25 #include <Precision.hxx>
26 #include <Standard_DomainError.hxx>
27 #include <Standard_NotImplemented.hxx>
28 #include <Standard_Type.hxx>
30 IMPLEMENT_STANDARD_RTTIEXT(Adaptor3d_TopolTool,Standard_Transient)
32 #define myInfinite Precision::Infinite()
34 static void GetConeApexParam(const gp_Cone& C, Standard_Real& U, Standard_Real& V)
36 const gp_Ax3& Pos = C.Position();
37 Standard_Real Radius = C.RefRadius();
38 Standard_Real SAngle = C.SemiAngle();
39 const gp_Pnt& P = C.Apex();
42 T.SetTransformation (Pos);
43 gp_Pnt Ploc = P.Transformed (T);
45 if(Ploc.X() ==0.0 && Ploc.Y()==0.0 ) {
48 else if ( -Radius > Ploc.Z()* Tan(SAngle) ) {
49 // the point is at the `wrong` side of the apex
50 U = atan2(-Ploc.Y(), -Ploc.X());
53 U = atan2(Ploc.Y(),Ploc.X());
55 if (U < -1.e-16) U += (M_PI+M_PI);
56 else if (U < 0) U = 0;
58 V = sin(SAngle) * ( Ploc.X() * cos(U) + Ploc.Y() * sin(U) - Radius)
59 + cos(SAngle) * Ploc.Z();
63 Adaptor3d_TopolTool::Adaptor3d_TopolTool () : myNbSamplesU(-1),nbRestr(0),idRestr(0)
68 Adaptor3d_TopolTool::Adaptor3d_TopolTool (const Handle(Adaptor3d_HSurface)& S)
74 void Adaptor3d_TopolTool::Initialize ()
76 throw Standard_NotImplemented("Adaptor3d_TopolTool::Initialize ()");
79 void Adaptor3d_TopolTool::Initialize (const Handle(Adaptor3d_HSurface)& S)
81 Standard_Real pinf,psup,deltap;
82 //Adaptor2d_Line2d * Line2dPtr ;
85 Uinf = S->FirstUParameter(); // where UIntervalFirst ??
86 Vinf = S->FirstVParameter();
87 Usup = S->LastUParameter();
88 Vsup = S->LastVParameter();
92 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
93 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
94 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
95 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
98 deltap = Min(Usup-Uinf,2.*myInfinite);
99 if (Uinf >= -myInfinite){
101 psup = pinf + deltap;
103 else if (Usup <= myInfinite) {
105 pinf = psup - deltap;
112 // Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup);
113 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
114 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vinf),gp_Dir2d(1.,0.),pinf,psup));
119 deltap = Min(Vsup-Vinf,2.*myInfinite);
120 if (Vinf >= -myInfinite){
122 psup = pinf + deltap;
124 else if (Vsup <= myInfinite) {
126 pinf = psup - deltap;
135 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup);
136 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
137 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(Usup,0.),gp_Dir2d(0.,1.),pinf,psup));
142 deltap = Min(Usup-Uinf,2.*myInfinite);
143 if (-Usup >= -myInfinite){
145 psup = pinf + deltap;
147 else if (-Uinf <= myInfinite) {
149 pinf = psup - deltap;
157 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup);
158 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
159 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(0.,Vsup),gp_Dir2d(-1.,0.),pinf,psup));
164 deltap = Min(Vsup-Vinf,2.*myInfinite);
165 if (-Vsup >= -myInfinite){
167 psup = pinf + deltap;
169 else if (-Vinf <= myInfinite) {
171 pinf = psup - deltap;
178 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup);
179 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
180 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(Uinf,0.),gp_Dir2d(0.,-1),pinf,psup));
186 if(nbRestr == 2 && S->GetType() == GeomAbs_Cone ) {
187 Standard_Real U = 0., V = 0.;
188 GetConeApexParam(S->Cone(),U,V);
190 deltap = Min(Usup-Uinf,2.*myInfinite);
191 if (Uinf >= -myInfinite){
193 psup = pinf + deltap;
195 else if (Usup <= myInfinite) {
197 pinf = psup - deltap;
204 //Line2dPtr = new Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup);
205 //myRestr[nbRestr] = new Adaptor2d_HLine2d(*Line2dPtr);
206 myRestr[nbRestr] = new Adaptor2d_HLine2d(Adaptor2d_Line2d(gp_Pnt2d(U,V),gp_Dir2d(1.,0.),pinf,psup));
212 void Adaptor3d_TopolTool::Init ()
218 Standard_Boolean Adaptor3d_TopolTool::More ()
220 return (idRestr < nbRestr);
223 Handle(Adaptor2d_HCurve2d) Adaptor3d_TopolTool::Value ()
225 if (idRestr >= nbRestr) {throw Standard_DomainError();}
226 return myRestr[idRestr];
229 void Adaptor3d_TopolTool::Next ()
235 void Adaptor3d_TopolTool::Initialize(const Handle(Adaptor2d_HCurve2d)& C)
239 Standard_Real theUinf,theUsup;
240 theUinf = C->FirstParameter();
241 theUsup = C->LastParameter();
242 // if (!Precision::IsNegativeInfinite(theUinf)) {
243 if (theUinf > -myInfinite) {
244 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUinf),TopAbs_FORWARD,1.e-8);
247 // if (!Precision::IsPositiveInfinite(theUsup)) {
248 if (theUsup < myInfinite) {
249 myVtx[nbVtx] = new Adaptor3d_HVertex(C->Value(theUsup),TopAbs_REVERSED,1.e-8);
255 void Adaptor3d_TopolTool::InitVertexIterator ()
261 Standard_Boolean Adaptor3d_TopolTool::MoreVertex ()
263 return (idVtx < nbVtx);
267 Handle(Adaptor3d_HVertex) Adaptor3d_TopolTool::Vertex ()
269 if (idVtx >= nbVtx) {throw Standard_DomainError();}
273 void Adaptor3d_TopolTool::NextVertex ()
279 TopAbs_State Adaptor3d_TopolTool::Classify(const gp_Pnt2d& P,
280 const Standard_Real Tol,
281 const Standard_Boolean )
282 // const Standard_Boolean RecadreOnPeriodic)
285 Standard_Real U = P.X();
286 Standard_Real V = P.Y();
289 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
290 (V < Vinf - Tol) || (V > Vsup + Tol)) {
293 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
294 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
299 else if (nbRestr == 0) {
303 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
304 if (Precision::IsNegativeInfinite(Uinf) &&
305 Precision::IsPositiveInfinite(Usup)) {
306 dansu = Standard_True;
307 surumin = surumax = Standard_False;
309 else if (Precision::IsNegativeInfinite(Uinf)) {
310 surumin = Standard_False;
312 dansu = Standard_False;
313 surumax = Standard_False;
316 dansu = Standard_True;
317 surumax = Standard_False;
318 if (Abs(U-Usup)<=Tol) {
319 surumax = Standard_True;
323 else if (Precision::IsPositiveInfinite(Usup)) {
324 surumax = Standard_False;
326 dansu = Standard_False;
327 surumin = Standard_False;
330 dansu = Standard_True;
331 surumin = Standard_False;
332 if (Abs(U-Uinf)<=Tol) {
333 surumin = Standard_True;
338 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
339 surumin = surumax = dansu = Standard_False;
342 dansu = Standard_True;
343 surumin = surumax = Standard_False;
344 if (Abs(U-Uinf)<=Tol) {
345 surumin = Standard_True;
347 else if (Abs(U-Usup)<=Tol) {
348 surumax = Standard_True;
353 if (Precision::IsNegativeInfinite(Vinf) &&
354 Precision::IsPositiveInfinite(Vsup)) {
355 dansv = Standard_True;
356 survmin = survmax = Standard_False;
358 else if (Precision::IsNegativeInfinite(Vinf)) {
359 survmin = Standard_False;
361 dansv = Standard_False;
362 survmax = Standard_False;
365 dansv = Standard_True;
366 survmax = Standard_False;
367 if (Abs(V-Vsup)<=Tol) {
368 survmax = Standard_True;
372 else if (Precision::IsPositiveInfinite(Vsup)) {
373 survmax = Standard_False;
375 dansv = Standard_False;
376 survmin = Standard_False;
379 dansv = Standard_True;
380 survmin = Standard_False;
381 if (Abs(V-Vinf)<=Tol) {
382 survmin = Standard_True;
387 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
388 survmin = survmax = dansv = Standard_False;
391 dansv = Standard_True;
392 survmin = survmax = Standard_False;
393 if (Abs(V-Vinf)<=Tol) {
394 survmin = Standard_True;
396 else if (Abs(V-Vsup)<=Tol) {
397 survmax = Standard_True;
402 if (!dansu || !dansv) {
405 if (surumin || survmin || surumax || survmax) {
414 Standard_Boolean Adaptor3d_TopolTool::IsThePointOn(const gp_Pnt2d& P,
415 const Standard_Real Tol,
416 const Standard_Boolean )
417 // const Standard_Boolean RecadreOnPeriodic)
420 Standard_Real U = P.X();
421 Standard_Real V = P.Y();
424 if ((U < Uinf - Tol) || (U > Usup + Tol) ||
425 (V < Vinf - Tol) || (V > Vsup + Tol)) {
426 return(Standard_False);
428 if ((Abs(U - Uinf) <= Tol) || (Abs(U - Usup) <= Tol) ||
429 (Abs(V - Vinf) <= Tol) || (Abs(V - Vsup) <= Tol)) {
430 return(Standard_True);
432 return(Standard_False);
434 else if (nbRestr == 0) {
435 return(Standard_False);
438 Standard_Boolean dansu,dansv,surumin,surumax,survmin,survmax;
439 if (Precision::IsNegativeInfinite(Uinf) &&
440 Precision::IsPositiveInfinite(Usup)) {
441 dansu = Standard_True;
442 surumin = surumax = Standard_False;
444 else if (Precision::IsNegativeInfinite(Uinf)) {
445 surumin = Standard_False;
447 dansu = Standard_False;
448 surumax = Standard_False;
451 dansu = Standard_True;
452 surumax = Standard_False;
453 if (Abs(U-Usup)<=Tol) {
454 surumax = Standard_True;
458 else if (Precision::IsPositiveInfinite(Usup)) {
459 surumax = Standard_False;
461 dansu = Standard_False;
462 surumin = Standard_False;
465 dansu = Standard_True;
466 surumin = Standard_False;
467 if (Abs(U-Uinf)<=Tol) {
468 surumin = Standard_True;
473 if ((U < Uinf - Tol) || (U > Usup + Tol)) {
474 surumin = surumax = dansu = Standard_False;
477 dansu = Standard_True;
478 surumin = surumax = Standard_False;
479 if (Abs(U-Uinf)<=Tol) {
480 surumin = Standard_True;
482 else if (Abs(U-Usup)<=Tol) {
483 surumax = Standard_True;
488 if (Precision::IsNegativeInfinite(Vinf) &&
489 Precision::IsPositiveInfinite(Vsup)) {
490 dansv = Standard_True;
491 survmin = survmax = Standard_False;
493 else if (Precision::IsNegativeInfinite(Vinf)) {
494 survmin = Standard_False;
496 dansv = Standard_False;
497 survmax = Standard_False;
500 dansv = Standard_True;
501 survmax = Standard_False;
502 if (Abs(V-Vsup)<=Tol) {
503 survmax = Standard_True;
507 else if (Precision::IsPositiveInfinite(Vsup)) {
508 survmax = Standard_False;
510 dansv = Standard_False;
511 survmin = Standard_False;
514 dansv = Standard_True;
515 survmin = Standard_False;
516 if (Abs(V-Vinf)<=Tol) {
517 survmin = Standard_True;
522 if ((V < Vinf - Tol) || (V > Vsup + Tol)) {
523 survmin = survmax = dansv = Standard_False;
526 dansv = Standard_True;
527 survmin = survmax = Standard_False;
528 if (Abs(V-Vinf)<=Tol) {
529 survmin = Standard_True;
531 else if (Abs(V-Vsup)<=Tol) {
532 survmax = Standard_True;
537 if (!dansu || !dansv) {
538 return(Standard_False);
540 if (surumin || survmin || surumax || survmax) {
541 return(Standard_True);
543 return(Standard_False);;
548 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
549 (const Handle(Adaptor2d_HCurve2d)&)
551 return TopAbs_FORWARD;
554 TopAbs_Orientation Adaptor3d_TopolTool::Orientation
555 (const Handle(Adaptor3d_HVertex)& V)
557 return V->Orientation();
560 Standard_Boolean Adaptor3d_TopolTool::Identical
561 (const Handle(Adaptor3d_HVertex)& V1,
562 const Handle(Adaptor3d_HVertex)& V2)
564 return V1->IsSame(V2);
568 //-- ============================================================
569 //-- m e t h o d e s u t i l i s e e s p o u r l e s
571 //-- ============================================================
572 #include <TColgp_Array2OfPnt.hxx>
573 #include <Geom_BezierSurface.hxx>
574 #include <Geom_BSplineSurface.hxx>
575 #include <TColStd_Array1OfReal.hxx>
576 #include <TColStd_Array1OfBoolean.hxx>
577 //#include <gce_MakeLin.hxx>
578 #include <gp_Lin.hxx>
579 #include <gp_Dir.hxx>
580 #include <gp_Vec.hxx>
582 #define myMinPnts 4 //Absolut possible minimum of sample points
583 //Restriction of IntPolyh
586 static void Analyse(const TColgp_Array2OfPnt& array2,
587 const Standard_Integer nbup,
588 const Standard_Integer nbvp,
589 Standard_Integer& myNbSamplesU,
590 Standard_Integer& myNbSamplesV) {
592 Standard_Integer sh,nbch,i,j;
597 for(i=2;i<nbup;i++) {
598 const gp_Pnt& A=array2.Value(i,1);
599 const gp_Pnt& B=array2.Value(i,2);
600 const gp_Pnt& C=array2.Value(i,3);
601 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
602 C.Y()-B.Y()-B.Y()+A.Y(),
603 C.Z()-B.Z()-B.Z()+A.Z());
604 Standard_Integer locnbch=0;
605 for(j=3; j<nbvp;j++) { //-- try
606 const gp_Pnt& A1=array2.Value(i,j-1);
607 const gp_Pnt& B1=array2.Value(i,j);
608 const gp_Pnt& C1=array2.Value(i,j+1);
609 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
610 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
611 C1.Z()-B1.Z()-B1.Z()+A1.Z());
612 Standard_Real pd = Vi.Dot(Vip1);
614 if(pd>1.0e-7 || pd<-1.0e-7) {
615 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
616 else { if(sh==1) { sh=-1; locnbch++; } }
624 myNbSamplesV = nbch+5;
628 for(j=2;j<nbvp;j++) {
629 const gp_Pnt& A=array2.Value(1,j);
630 const gp_Pnt& B=array2.Value(2,j);
631 const gp_Pnt& C=array2.Value(3,j);
632 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
633 C.Y()-B.Y()-B.Y()+A.Y(),
634 C.Z()-B.Z()-B.Z()+A.Z());
635 Standard_Integer locnbch=0;
636 for(i=3; i<nbup;i++) { //-- try
637 const gp_Pnt& A1=array2.Value(i-1,j);
638 const gp_Pnt& B1=array2.Value(i,j);
639 const gp_Pnt& C1=array2.Value(i+1,j);
640 Vip1.SetCoord(C1.X()-B1.X()-B1.X()+A1.X(),
641 C1.Y()-B1.Y()-B1.Y()+A1.Y(),
642 C1.Z()-B1.Z()-B1.Z()+A1.Z());
643 Standard_Real pd = Vi.Dot(Vip1);
645 if(pd>1.0e-7 || pd<-1.0e-7) {
646 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
647 else { if(sh==1) { sh=-1; locnbch++; } }
650 if(locnbch>nbch) nbch=locnbch;
653 myNbSamplesU = nbch+5;
657 void Adaptor3d_TopolTool::ComputeSamplePoints() {
658 Standard_Real uinf,usup,vinf,vsup;
659 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
660 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
661 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
662 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
663 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
664 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
665 else if (usup == RealLast()) { usup=uinf+2.e5; }
667 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
668 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
669 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
671 Standard_Integer nbsu,nbsv;
672 GeomAbs_SurfaceType typS = myS->GetType();
674 case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
675 case GeomAbs_BezierSurface: { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles(); } break;
676 case GeomAbs_BSplineSurface: {
677 nbsv = myS->NbVKnots(); nbsv*= myS->VDegree(); if(nbsv < 4) nbsv=4;
678 nbsu = myS->NbUKnots(); nbsu*= myS->UDegree(); if(nbsu < 4) nbsu=4;
681 case GeomAbs_Cylinder:
685 case GeomAbs_SurfaceOfRevolution:
686 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=15; } break;
687 default: { nbsu = 10; nbsv=10; } break;
690 //-- If the number of points is too great... analyze
700 if(nbsu>8 || nbsv>8) {
701 if(typS == GeomAbs_BSplineSurface) {
702 const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
703 Standard_Integer nbup = Bspl->NbUPoles();
704 Standard_Integer nbvp = Bspl->NbVPoles();
705 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
707 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
709 else if(typS == GeomAbs_BezierSurface) {
710 const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
711 Standard_Integer nbup = Bez->NbUPoles();
712 Standard_Integer nbvp = Bez->NbVPoles();
713 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
715 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
720 Standard_Integer Adaptor3d_TopolTool::NbSamplesU()
722 if(myNbSamplesU <0) {
723 ComputeSamplePoints();
725 return(myNbSamplesU);
728 Standard_Integer Adaptor3d_TopolTool::NbSamplesV()
730 if(myNbSamplesU <0) {
731 ComputeSamplePoints();
733 return(myNbSamplesV);
736 Standard_Integer Adaptor3d_TopolTool::NbSamples()
738 if(myNbSamplesU <0) {
739 ComputeSamplePoints();
741 return(myNbSamplesU*myNbSamplesV);
744 void Adaptor3d_TopolTool::UParameters(TColStd_Array1OfReal& theArray) const
746 theArray = myUPars->Array1();
749 void Adaptor3d_TopolTool::VParameters(TColStd_Array1OfReal& theArray) const
751 theArray = myVPars->Array1();
754 void Adaptor3d_TopolTool::SamplePoint(const Standard_Integer i,
758 Standard_Integer iu, iv;
760 if (myUPars.IsNull())
762 Standard_Real myDU=(Usup-Uinf)/(myNbSamplesU+1);
763 Standard_Real myDV=(Vsup-Vinf)/(myNbSamplesV+1);
764 iv = 1 + i/myNbSamplesU;
765 iu = 1+ i-(iv-1)*myNbSamplesU;
771 iv = (i-1)/myNbSamplesU + 1;
772 iu = (i-1)%myNbSamplesU + 1;
773 u = myUPars->Value(iu);
774 v = myVPars->Value(iv);
778 P3d = myS->Value(u,v);
783 Standard_Boolean Adaptor3d_TopolTool::DomainIsInfinite() {
784 if(Precision::IsNegativeInfinite(Uinf)) return(Standard_True);
785 if(Precision::IsPositiveInfinite(Usup)) return(Standard_True);
786 if(Precision::IsNegativeInfinite(Vinf)) return(Standard_True);
787 if(Precision::IsPositiveInfinite(Vsup)) return(Standard_True);
788 return(Standard_False);
790 //=======================================================================
793 //=======================================================================
794 Standard_Address Adaptor3d_TopolTool::Edge() const
798 //=======================================================================
801 //=======================================================================
803 Standard_Boolean Adaptor3d_TopolTool::Has3d() const
805 return Standard_False;
808 //=======================================================================
811 //=======================================================================
813 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)&) const
815 throw Standard_DomainError("Adaptor3d_TopolTool: has no 3d representation");
818 //=======================================================================
821 //=======================================================================
823 Standard_Real Adaptor3d_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)&) const
825 throw Standard_DomainError("Adaptor3d_TopolTool: has no 3d representation");
828 //=======================================================================
831 //=======================================================================
833 gp_Pnt Adaptor3d_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)&) const
835 throw Standard_DomainError("Adaptor3d_TopolTool: has no 3d representation");
839 //=======================================================================
840 //function : SamplePnts
842 //=======================================================================
844 void Adaptor3d_TopolTool::SamplePnts(const Standard_Real theDefl,
845 const Standard_Integer theNUmin,
846 const Standard_Integer theNVmin)
848 Standard_Real uinf,usup,vinf,vsup;
849 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
850 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
851 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
852 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
853 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
854 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
855 else if (usup == RealLast()) { usup=uinf+2.e5; }
857 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
858 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
859 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
861 // Standard_Integer nbsu,nbsv;
862 GeomAbs_SurfaceType typS = myS->GetType();
864 // case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
865 // case GeomAbs_BezierSurface: {
866 // nbsv=myS->NbVPoles();
867 // nbsu=myS->NbUPoles();
868 // nbsu = Max(nbsu, theNUmin);
869 // nbsv = Max(nbsv, theNVmin);
870 // if(nbsu>8 || nbsv>8) {
871 // const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
872 // Standard_Integer nbup = Bez->NbUPoles();
873 // Standard_Integer nbvp = Bez->NbVPoles();
874 // TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
875 // Bez->Poles(array2);
876 // Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
880 // case GeomAbs_BSplineSurface: {
881 if(typS == GeomAbs_BSplineSurface) {
882 // Processing BSpline surface
883 BSplSamplePnts(theDefl, theNUmin, theNVmin);
887 ComputeSamplePoints();
889 // case GeomAbs_Cylinder:
890 // case GeomAbs_Cone:
891 // case GeomAbs_Sphere:
892 // case GeomAbs_Torus:
893 // case GeomAbs_SurfaceOfRevolution:
894 // case GeomAbs_SurfaceOfExtrusion: { nbsv = Max(15,theNVmin); nbsu=Max(15,theNUmin); } break;
895 // default: { nbsu = Max(10,theNUmin); nbsv=Max(10,theNVmin); } break;
899 // if(nbsu<6) nbsu=6;
900 // if(nbsv<6) nbsv=6;
902 // myNbSamplesU = nbsu;
903 // myNbSamplesV = nbsv;
906 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
907 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
909 Standard_Real t, dt = (usup - uinf)/(myNbSamplesU - 1);
910 myUPars->SetValue(1, uinf);
911 myUPars->SetValue(myNbSamplesU, usup);
912 for(i = 2, t = uinf+dt; i < myNbSamplesU; ++i, t += dt) {
913 myUPars->SetValue(i, t);
916 dt = (vsup - vinf)/(myNbSamplesV - 1);
917 myVPars->SetValue(1, vinf);
918 myVPars->SetValue(myNbSamplesV, vsup);
919 for(i = 2, t = vinf+dt; i < myNbSamplesV; ++i, t += dt) {
920 myVPars->SetValue(i, t);
927 //=======================================================================
928 //function : BSplSamplePnts
930 //=======================================================================
932 void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
933 const Standard_Integer theNUmin,
934 const Standard_Integer theNVmin)
936 const Handle(Geom_BSplineSurface)& aBS = myS->BSpline();
937 Standard_Real uinf,usup,vinf,vsup;
938 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
939 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
941 Standard_Integer i, k, j = 1;
942 Standard_Real t1, t2, dt;
943 Standard_Integer ui1 = aBS->FirstUKnotIndex();
944 Standard_Integer ui2 = aBS->LastUKnotIndex();
945 Standard_Integer vi1 = aBS->FirstVKnotIndex();
946 Standard_Integer vi2 = aBS->LastVKnotIndex();
948 for(i = ui1; i < ui2; ++i) {
949 if(uinf >= aBS->UKnot(i) && uinf < aBS->UKnot(i+1)) {
955 for(i = ui2; i > ui1; --i) {
956 if(usup <= aBS->UKnot(i) && usup > aBS->UKnot(i-1)) {
962 for(i = vi1; i < vi2; ++i) {
963 if(vinf >= aBS->VKnot(i) && vinf < aBS->VKnot(i+1)) {
969 for(i = vi2; i > vi1; --i) {
970 if(vsup <= aBS->VKnot(i) && vsup > aBS->VKnot(i-1)) {
976 Standard_Integer nbsu = ui2-ui1+1; nbsu += (nbsu - 1) * (aBS->UDegree()-1);
977 Standard_Integer nbsv = vi2-vi1+1; nbsv += (nbsv - 1) * (aBS->VDegree()-1);
978 Standard_Boolean bUuniform = Standard_False;
979 Standard_Boolean bVuniform = Standard_False;
981 //modified by NIZHNY-EMV Mon Jun 10 14:19:04 2013
982 if (nbsu < theNUmin || nbsv < theNVmin) {
983 Standard_Integer aNb;
985 aNb = (Standard_Integer)(nbsv * ((Standard_Real)theNUmin)/((Standard_Real)nbsu));
987 bVuniform = (aNb > nbsv) ? Standard_True : bVuniform;
988 nbsv = bVuniform ? aNb : nbsv;
990 aNb = (Standard_Integer)(nbsu * ((Standard_Real)theNVmin)/((Standard_Real)nbsv));
992 bUuniform = (aNb > nbsu) ? Standard_True : bUuniform;
993 nbsu = bUuniform ? aNb : nbsu;
996 //modified by NIZHNY-EMV Mon Jun 10 14:19:05 2013
998 if(nbsu < theNUmin) {
1000 bUuniform = Standard_True;
1003 if(nbsv < theNVmin) {
1005 bVuniform = Standard_True;
1008 TColStd_Array1OfReal anUPars(1, nbsu);
1009 TColStd_Array1OfBoolean anUFlg(1, nbsu);
1010 TColStd_Array1OfReal aVPars(1, nbsv);
1011 TColStd_Array1OfBoolean aVFlg(1, nbsv);
1013 //Filling of sample parameters
1017 dt = (t2 - t1)/(nbsu - 1);
1019 anUFlg(1) = Standard_False;
1021 anUFlg(nbsu) = Standard_False;
1022 for(i = 2, t1 += dt; i < nbsu; ++i, t1 += dt) {
1024 anUFlg(i) = Standard_False;
1028 Standard_Integer nbi = aBS->UDegree();
1031 for(i = ui1+1; i <= ui2; ++i) {
1032 if(i == ui2) t2 = usup;
1033 else t2 = aBS->UKnot(i);
1039 anUFlg(k) = Standard_False;
1052 dt = (t2 - t1)/(nbsv - 1);
1054 aVFlg(1) = Standard_False;
1056 aVFlg(nbsv) = Standard_False;
1057 for(i = 2, t1 += dt; i < nbsv; ++i, t1 += dt) {
1059 aVFlg(i) = Standard_False;
1063 Standard_Integer nbi = aBS->VDegree();
1066 for(i = vi1+1; i <= vi2; ++i) {
1067 if(i == vi2) t2 = vsup;
1068 else t2 = aBS->VKnot(i);
1074 aVFlg(k) = Standard_False;
1084 //Analysis of deflection
1086 Standard_Real aDefl2 = Max(theDefl*theDefl, 1.e-9);
1087 Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
1090 anUFlg(1) = Standard_True;
1091 anUFlg(nbsu) = Standard_True;
1093 for(i = 1; i <= nbsv; ++i) {
1096 Standard_Boolean bCont = Standard_True;
1097 while (j < nbsu-1 && bCont) {
1105 gp_Pnt p1 = myS->Value(t2, t1);
1106 for(k = j+2; k <= nbsu; ++k) {
1108 gp_Pnt p2 = myS->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 = myS->Value(anUPars(l), t1);
1124 Standard_Real d = lin.SquareDistance(pp);
1126 if(d <= aDefl2) continue;
1128 ok = Standard_False;
1134 anUFlg(j) = Standard_True;
1147 if(k >= nbsu) bCont = Standard_False;
1153 for (i = 1; i <= nbsu; i++)
1154 if (anUFlg(i) == Standard_True)
1157 if(myNbSamplesU < myMinPnts) {
1158 if(myNbSamplesU == 2) {
1159 //"uniform" distribution;
1160 Standard_Integer nn = nbsu/myMinPnts;
1161 anUFlg(1+nn) = Standard_True;
1162 anUFlg(nbsu-nn) = Standard_True;
1164 else { //myNbSamplesU == 3
1165 //insert in bigger segment
1167 while(!anUFlg(i++));
1168 if(i < nbsu/2) j = Min(i+(nbsu-i)/2, nbsu-1);
1169 else j = Max(i/2, 2);
1171 anUFlg(j) = Standard_True;
1172 myNbSamplesU = myMinPnts;
1175 aVFlg(1) = Standard_True;
1176 aVFlg(nbsv) = Standard_True;
1178 for(i = 1; i <= nbsu; ++i) {
1181 Standard_Boolean bCont = Standard_True;
1182 while (j < nbsv-1 && bCont) {
1190 gp_Pnt p1 = myS->Value(t1, t2);
1191 for(k = j+2; k <= nbsv; ++k) {
1193 gp_Pnt p2 = myS->Value(t1, t2);
1195 if(p1.SquareDistance(p2) <= tol) continue;
1196 //gce_MakeLin MkLin(p1, p2);
1197 //const gp_Lin& lin = MkLin.Value();
1198 gp_Lin lin(p1, gp_Dir(gp_Vec(p1, p2)));
1199 Standard_Boolean ok = Standard_True;
1200 for(l = j+1; l < k; ++l) {
1203 ok = Standard_False;
1207 gp_Pnt pp = myS->Value(t1, aVPars(l));
1208 Standard_Real d = lin.SquareDistance(pp);
1210 if(d <= aDefl2) continue;
1212 ok = Standard_False;
1218 aVFlg(j) = Standard_True;
1231 if(k >= nbsv) bCont = Standard_False;
1237 for (i = 1; i <= nbsv; i++)
1238 if (aVFlg(i) == Standard_True)
1241 if(myNbSamplesV < myMinPnts) {
1242 if(myNbSamplesV == 2) {
1243 //"uniform" distribution;
1244 Standard_Integer nn = nbsv/myMinPnts;
1245 aVFlg(1+nn) = Standard_True;
1246 aVFlg(nbsv-nn) = Standard_True;
1247 myNbSamplesV = myMinPnts;
1249 else { //myNbSamplesU == 3
1250 //insert in bigger segment
1253 if(i < nbsv/2) j = Min(i+(nbsv-i)/2, nbsv-1);
1254 else j = Max(i/2, 2);
1256 myNbSamplesV = myMinPnts;
1257 aVFlg(j) = Standard_True;
1260 //modified by NIZNHY-PKV Fri Dec 16 10:05:01 2011f
1262 Standard_Boolean bFlag;
1265 bFlag=(myNbSamplesU < theNUmin);
1270 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1272 for(j = 0, i = 1; i <= nbsu; ++i) {
1274 myUPars->SetValue(i,anUPars(i));
1279 myUPars->SetValue(j,anUPars(i));
1285 bFlag=(myNbSamplesV < theNVmin);
1290 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1292 for(j = 0, i = 1; i <= nbsv; ++i) {
1294 myVPars->SetValue(i,aVPars(i));
1299 myVPars->SetValue(j,aVPars(i));
1305 myUPars = new TColStd_HArray1OfReal(1, myNbSamplesU);
1306 myVPars = new TColStd_HArray1OfReal(1, myNbSamplesV);
1309 for(i = 1; i <= nbsu; ++i) {
1312 myUPars->SetValue(j,anUPars(i));
1317 for(i = 1; i <= nbsv; ++i) {
1320 myVPars->SetValue(j,aVPars(i));
1324 //modified by NIZNHY-PKV Mon Dec 26 12:25:35 2011t
1328 //=======================================================================
1329 //function : IsUniformSampling
1331 //=======================================================================
1332 Standard_Boolean Adaptor3d_TopolTool::IsUniformSampling() const
1334 GeomAbs_SurfaceType typS = myS->GetType();
1336 if(typS == GeomAbs_BSplineSurface)
1337 return Standard_False;
1338 return Standard_True;