1 // Created on: 1995-03-22
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <IntTools_FClass2d.ixx>
26 #include <Precision.hxx>
30 #include <Geom2dInt_Geom2dCurveTool.hxx>
31 #include <GeomAbs_SurfaceType.hxx>
33 #include <BRep_Tool.hxx>
34 #include <BRepTools_WireExplorer.hxx>
35 #include <BRepClass_FaceClassifier.hxx>
36 #include <CSLib_Class2d.hxx>
37 #include <BRepAdaptor_HSurface.hxx>
38 #include <BRepAdaptor_Curve.hxx>
39 #include <BRepAdaptor_Curve2d.hxx>
42 #include <TopoDS_Edge.hxx>
44 #include <TopAbs_Orientation.hxx>
45 #include <TopExp_Explorer.hxx>
46 #include <TColgp_SequenceOfPnt2d.hxx>
48 #include <TColgp_Array1OfPnt2d.hxx>
49 #include <TopoDS_Wire.hxx>
50 #include <TColStd_DataMapOfIntegerInteger.hxx>
51 #include <TColgp_SequenceOfVec2d.hxx>
53 //=======================================================================
54 //function : IntTools_FClass2d:IntTools:_FClass2d
56 //=======================================================================
57 IntTools_FClass2d::IntTools_FClass2d()
60 //=======================================================================
61 //function : IntTools_FClass2d::IntTools_FClass2d
63 //=======================================================================
64 IntTools_FClass2d::IntTools_FClass2d(const TopoDS_Face& aFace,
65 const Standard_Real TolUV)
66 : Toluv(TolUV), Face(aFace)
70 //=======================================================================
73 //=======================================================================
74 Standard_Boolean IntTools_FClass2d::IsHole() const
78 //=======================================================================
81 //=======================================================================
82 void IntTools_FClass2d::Init(const TopoDS_Face& aFace,
83 const Standard_Real TolUV)
85 Standard_Boolean WireIsNotEmpty, Ancienpnt3dinitialise, degenerated;
86 Standard_Integer nbpnts, firstpoint, NbEdges;
87 Standard_Integer iX, aNbs1, nbs, Avant, BadWire;
88 Standard_Real u, du, Tole, Tol, pfbid, plbid;
89 Standard_Real FlecheU, FlecheV, TolVertex1, TolVertex;
90 Standard_Real uFirst, uLast;
91 Standard_Real aPrCf, aPrCf2;
95 TopAbs_Orientation Or;
96 BRepTools_WireExplorer aWExp;
97 TopExp_Explorer aExpF, aExp;
98 Handle(Geom2d_Curve) aC2D;
100 TColgp_SequenceOfPnt2d SeqPnt2d;
101 TColStd_DataMapOfIntegerInteger anIndexMap;
102 TColgp_SequenceOfVec2d aD1Prev;
103 TColgp_SequenceOfVec2d aD1Next;
105 aPrCf=Precision::Confusion();
107 myIsHole=Standard_True;
111 Face.Orientation(TopAbs_FORWARD);
112 Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
113 surf->ChangeSurface().Initialize(aFace, Standard_False);
117 Umin = Vmin = RealLast();
121 //if face has several wires and one of them is bad,
122 //it is necessary to process all of them for correct
123 //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06
125 aExpF.Init(Face,TopAbs_WIRE);
126 for(; aExpF.More(); aExpF.Next()) {
127 const TopoDS_Wire& aW=*((TopoDS_Wire*)&aExpF.Current());
135 WireIsNotEmpty = Standard_False;
136 Ancienpnt3dinitialise=Standard_False;
137 Ancienpnt3d.SetCoord(0.,0.,0.);
146 aExp.Init(aW, TopAbs_EDGE);
147 for(; aExp.More(); aExp.Next()) {
151 aWExp.Init(aW, Face);
152 for(;aWExp.More(); aWExp.Next()) {
154 edge = aWExp.Current();
155 Or = edge.Orientation();
156 if(!(Or==TopAbs_FORWARD || Or==TopAbs_REVERSED)) {
160 aC2D=BRep_Tool::CurveOnSurface(edge, Face, pfbid, plbid);
165 BRepAdaptor_Curve2d C(edge,Face);
166 BRepAdaptor_Curve C3d;
167 //------------------------------------------
168 degenerated=Standard_False;
169 if(BRep_Tool::Degenerated(edge) ||
170 BRep_Tool::IsClosed(edge, Face)) {
171 degenerated=Standard_True;
174 TopExp::Vertices(edge,Va,Vb);
179 degenerated=Standard_True;
182 TolVertex1=BRep_Tool::Tolerance(Va);
185 degenerated=Standard_True;
188 TolVertex=BRep_Tool::Tolerance(Vb);
191 if(TolVertex<TolVertex1) {
192 TolVertex=TolVertex1;
195 //-- Verification of cases when forgotten to code degenereted
197 // check that whole curve is located in vicinity of its middle point
198 // (within sphere of Precision::Confusion() diameter)
199 C3d.Initialize (edge, Face);
200 gp_Pnt P3da = C3d.Value (0.5 * (pfbid + plbid));
202 const int NBSTEPS = 10;
203 Standard_Real aPrec2 = 0.25 * Precision::Confusion() * Precision::Confusion();
204 degenerated = Standard_True;
205 for (Standard_Integer i=0; i <= NBSTEPS; i++)
207 Standard_Real u = pfbid + i * du / NBSTEPS;
208 gp_Pnt P3db = C3d.Value (u);
209 Standard_Real aR2 = P3da.SquareDistance (P3db);
211 degenerated = Standard_False;
216 //-- ----------------------------------------
217 Tole = BRep_Tool::Tolerance(edge);
223 nbs = Geom2dInt_Geom2dCurveTool::NbSamples(C);
227 du = (plbid-pfbid)/(Standard_Real)(nbs-1);
229 if(Or==TopAbs_FORWARD) {
243 TColStd_Array1OfReal aPrms(1, aNbs1);
246 Standard_Real aCoef=0.0025;
248 aPrms(2)=uFirst+aCoef*(uLast-uFirst);
254 for (iX=2; iX<aNbs1; ++iX) {
255 aPrms(iX)=u+(iX-1)*du;
260 //-- ------------------------------------------------------------
261 //-- Check distance uv between the start point of the edge
262 //-- and the last point saved in SeqPnt2d
263 //-- To to set the first point of the current
264 //-- afar from the last saved point
266 for(iX=firstpoint; iX<=aNbs1; iX++) {
267 Standard_Boolean IsRealCurve3d;
275 if(P2d.X()<Umin) Umin = P2d.X();
276 if(P2d.X()>Umax) Umax = P2d.X();
277 if(P2d.Y()<Vmin) Vmin = P2d.Y();
278 if(P2d.Y()>Vmax) Vmax = P2d.Y();
281 if(degenerated==Standard_False) {
284 if(Ancienpnt3dinitialise) {
285 aDstX=P3d.SquareDistance(Ancienpnt3d);
290 IsRealCurve3d = Standard_True;
291 if (aDstX < aPrCf2) {
293 Standard_Real aDstX1;
296 MidP3d = C3d.Value(0.5*(u+aPrms(iX-1)));
297 aDstX1=P3d.SquareDistance( MidP3d );
298 if (aDstX1 < aPrCf2){
299 IsRealCurve3d = Standard_False;
305 if(degenerated==Standard_False) {
307 Ancienpnt3dinitialise=Standard_True;
310 SeqPnt2d.Append(P2d);
315 Standard_Real ul, dU, dV;
318 gp_Lin2d Lin(SeqPnt2d(ii-2),gp_Dir2d(gp_Vec2d(SeqPnt2d(ii-2),SeqPnt2d(ii))));
319 ul = ElCLib::Parameter(Lin,SeqPnt2d(ii-1));
320 Pp = ElCLib::Value(ul,Lin);
321 dU = Abs(Pp.X()-SeqPnt2d(ii-1).X());
322 dV = Abs(Pp.Y()-SeqPnt2d(ii-1).Y());
330 }// for(iX=firstpoint; iX<=aNbs1; iX++) {
333 continue; //if face has several wires and one of them is bad,
334 //it is necessary to process all of them for correct
335 //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06
338 if(firstpoint==1) firstpoint=2;
339 WireIsNotEmpty = Standard_True;
340 // Append the derivative of the first parameter.
341 Standard_Real aU = aPrms(1);
347 if(Or == TopAbs_REVERSED)
352 // Append the derivative of the last parameter.
356 if(Or == TopAbs_REVERSED)
364 // Fill the map anIndexMap.
366 anIndexMap.Bind(Avant, aD1Next.Length());
368 anIndexMap.Bind(1, aD1Next.Length());
369 } //for(;aWExp.More(); aWExp.Next()) {
370 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
373 //-- count ++ with normal explorer and -- with Wire Explorer
374 TColgp_Array1OfPnt2d PClass(1,2);
375 gp_Pnt2d anInitPnt(0., 0.);
377 PClass.Init(anInitPnt);
378 TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
383 else if(WireIsNotEmpty) {
384 TColgp_Array1OfPnt2d PClass(1,nbpnts);
385 gp_Pnt2d anInitPnt(0., 0.);
387 PClass.Init(anInitPnt);
389 Standard_Integer im2=nbpnts-2;
390 Standard_Integer im1=nbpnts-1;
391 Standard_Integer im0=1;
393 Standard_Real angle = 0.0;
394 Standard_Real aX0, aY0, aX1, aY1, aS;
399 Standard_Integer iFlag=1;
400 PClass(im2)=SeqPnt2d.Value(im2);
401 PClass(im1)=SeqPnt2d.Value(im1);
402 PClass(nbpnts)=SeqPnt2d.Value(nbpnts);
403 for(ii=1; ii<nbpnts; ii++,im0++,im1++,im2++) {
404 if(im2>=nbpnts) im2=1;
405 if(im1>=nbpnts) im1=1;
406 PClass(ii)=SeqPnt2d.Value(ii);
408 const gp_Pnt2d& aP2D1=PClass(im1);
409 const gp_Pnt2d& aP2D0=PClass(im0);
410 //aP2D0 is next to aP2D1
411 aP2D0.Coord(aX0, aY0);
412 aP2D1.Coord(aX1, aY1);
413 aS=aS+(aY0+aY1)*(aX1-aX0);
415 gp_Vec2d A(PClass(im2),PClass(im1));
416 gp_Vec2d B(PClass(im1),PClass(im0));
418 Standard_Real N = A.Magnitude() * B.Magnitude();
420 Standard_Real a=A.Angle(B);
422 if (anIndexMap.IsBound(im1)) {
423 Standard_Integer anInd = anIndexMap.Find(im1);
424 const gp_Vec2d &aVPrev = aD1Prev.Value(anInd);
425 const gp_Vec2d &aVNext = aD1Next.Value(anInd);
427 Standard_Real aN = aVPrev.Magnitude() * aVNext.Magnitude();
429 Standard_Real aDerivAngle = aVPrev.Angle(aVNext);
431 if(Abs(aDerivAngle) <= Precision::Angular()) aDerivAngle = 0.;
432 //ifv 23.08.06 : if edges continuity > G1, |aDerivAngle| ~0,
433 //but can has wrong sign and causes condition aDerivAngle * a < 0.
434 //that is wrong in such situation
435 if (iFlag && aDerivAngle * a < 0.) {
444 }//for(ii=1; ii<nbpnts; ii++,im0++,im1++,im2++) {
449 myIsHole=Standard_False;
458 TabClass.Append((void *)new CSLib_Class2d(PClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
460 if((angle<2 && angle>-2)||(angle>10)||(angle<-10)) {
465 TabOrien.Append((angle>0.0)? 1 : 0);
471 TColgp_Array1OfPnt2d PPClass(1,2);
472 PPClass.Init(anInitPnt);
473 TabClass.Append((void *)new CSLib_Class2d(PPClass,FlecheU,FlecheV,Umin,Vmin,Umax,Vmax));
475 }// else if(WireIsNotEmpty)
476 } // for(; aExpF.More(); aExpF.Next()) {
478 Standard_Integer nbtabclass = TabClass.Length();
481 //-- if an error on a wire was detected : all TabOrien set to -1
486 if( surf->GetType()==GeomAbs_Cone
487 || surf->GetType()==GeomAbs_Cylinder
488 || surf->GetType()==GeomAbs_Torus
489 || surf->GetType()==GeomAbs_Sphere
490 || surf->GetType()==GeomAbs_SurfaceOfRevolution) {
491 Standard_Real uuu=M_PI+M_PI-(Umax-Umin);
500 if(surf->GetType()==GeomAbs_Torus) {
501 Standard_Real uuu=M_PI+M_PI-(Vmax-Vmin);
512 //=======================================================================
513 //function : PerformInfinitePoint
515 //=======================================================================
516 TopAbs_State IntTools_FClass2d::PerformInfinitePoint() const
518 if(Umax==-RealLast() || Vmax==-RealLast() || Umin==RealLast() || Vmin==RealLast()) {
521 gp_Pnt2d P(Umin-(Umax-Umin),Vmin-(Vmax-Vmin));
522 return(Perform(P,Standard_False));
524 //=======================================================================
527 //=======================================================================
528 TopAbs_State IntTools_FClass2d::Perform(const gp_Pnt2d& _Puv,
529 const Standard_Boolean RecadreOnPeriodic) const
531 Standard_Integer dedans, nbtabclass;
533 nbtabclass = TabClass.Length();
539 //-- U1 is the First Param and U2 is in this case U1+Period
540 Standard_Real u, v, uu, vv, uperiod, vperiod;
541 Standard_Boolean IsUPer, IsVPer, urecadre, vrecadre;
542 TopAbs_State Status= TopAbs_UNKNOWN;
548 Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
549 surf->ChangeSurface().Initialize( Face, Standard_False );
551 uperiod=0., vperiod=0.;
552 IsUPer = surf->IsUPeriodic();
553 IsVPer = surf->IsVPeriodic();
556 uperiod = surf->UPeriod();
560 vperiod = surf->VPeriod();
563 urecadre = Standard_False;
564 vrecadre = Standard_False;
566 if (RecadreOnPeriodic) {
599 if(TabOrien(1)!=-1) {
600 Standard_Integer n, cur, TabOrien_n ;
601 for(n=1; n<=nbtabclass; n++) {
602 cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv);
603 TabOrien_n=TabOrien(n);
621 } // for(n=1; n<=nbtabclass; n++)
624 BRepClass_FaceClassifier aClassifier;
625 aClassifier.Perform(Face,Puv,Toluv);
626 Status = aClassifier.State();
634 } // if(TabOrien(1)!=-1) {
636 else { //-- TabOrien(1)=-1 Wrong Wire
637 BRepClass_FaceClassifier aClassifier;
638 aClassifier.Perform(Face,Puv,Toluv);
639 Status = aClassifier.State();
642 if (!RecadreOnPeriodic || !IsUPer && !IsVPer)
645 if (Status == TopAbs_IN || Status == TopAbs_ON)
650 urecadre = Standard_True;
658 if (u > Umax || !IsUPer) {
661 vrecadre = Standard_True;
671 if (v > Vmax || !IsVPer) {
678 //=======================================================================
679 //function : TestOnRestriction
681 //=======================================================================
682 TopAbs_State IntTools_FClass2d::TestOnRestriction(const gp_Pnt2d& _Puv,
683 const Standard_Real Tol,
684 const Standard_Boolean RecadreOnPeriodic) const
687 Standard_Integer dedans, nbtabclass;
689 nbtabclass = TabClass.Length();
695 //-- U1 is the First Param and U2 in this case is U1+Period
696 Standard_Real u=_Puv.X();
697 Standard_Real v=_Puv.Y();
698 Standard_Real uu = u, vv = v;
700 Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
701 surf->ChangeSurface().Initialize( Face, Standard_False );
702 Standard_Boolean IsUPer, IsVPer;
703 Standard_Real uperiod=0, vperiod=0;
704 if ((IsUPer = surf->IsUPeriodic()))
705 uperiod = surf->UPeriod();
706 if ((IsVPer = surf->IsVPeriodic()))
707 vperiod = surf->VPeriod();
708 TopAbs_State Status = TopAbs_UNKNOWN;
709 Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False;
711 if (RecadreOnPeriodic)
743 if(TabOrien(1)!=-1) {
744 for(Standard_Integer n=1; n<=nbtabclass; n++) {
745 Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans_OnMode(Puv,Tol);
773 else { //-- TabOrien(1)=-1 Wrong Wire
774 BRepClass_FaceClassifier aClassifier;
775 aClassifier.Perform(Face,Puv,Tol);
776 Status = aClassifier.State();
779 if (!RecadreOnPeriodic || !IsUPer && !IsVPer)
781 if (Status == TopAbs_IN || Status == TopAbs_ON)
787 urecadre = Standard_True;
792 if (u > Umax || !IsUPer)
797 vrecadre = Standard_True;
805 if (v > Vmax || !IsVPer)
811 //=======================================================================
814 //=======================================================================
815 void IntTools_FClass2d::Destroy()
817 Standard_Integer nbtabclass = TabClass.Length();
818 for(Standard_Integer d=1; d<=nbtabclass;d++) {
820 delete ((CSLib_Class2d *)TabClass(d));