1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <Adaptor2d_Curve2d.hxx>
17 #include <BRep_Tool.hxx>
18 #include <BRepAdaptor_Surface.hxx>
19 #include <BRepTopAdaptor_FClass2d.hxx>
20 #include <BRepTopAdaptor_HVertex.hxx>
21 #include <BRepTopAdaptor_TopolTool.hxx>
22 #include <Geom_BezierSurface.hxx>
23 #include <Geom_BSplineSurface.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <Precision.hxx>
27 #include <Standard_ConstructionError.hxx>
28 #include <Standard_DomainError.hxx>
29 #include <Standard_NotImplemented.hxx>
30 #include <Standard_Type.hxx>
31 #include <TColgp_Array2OfPnt.hxx>
34 IMPLEMENT_STANDARD_RTTIEXT(BRepTopAdaptor_TopolTool,Adaptor3d_TopolTool)
37 void Analyse(const TColgp_Array2OfPnt& array2,
38 const Standard_Integer nbup,
39 const Standard_Integer nbvp,
40 Standard_Integer& myNbSamplesU,
41 Standard_Integer& myNbSamplesV);
42 //=======================================================================
43 //function : BRepTopAdaptor_TopolTool
45 //=======================================================================
46 BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool ()
56 //=======================================================================
57 //function : BRepTopAdaptor_TopolTool
59 //=======================================================================
60 BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool(const Handle(Adaptor3d_Surface)& S)
66 //=======================================================================
67 //function : Initialize
69 //=======================================================================
70 void BRepTopAdaptor_TopolTool::Initialize()
72 throw Standard_NotImplemented("BRepTopAdaptor_TopolTool::Initialize()");
74 //=======================================================================
75 //function : Initialize
77 //=======================================================================
78 void BRepTopAdaptor_TopolTool::Initialize(const Handle(Adaptor3d_Surface)& S)
80 Handle(BRepAdaptor_Surface) brhs =
81 Handle(BRepAdaptor_Surface)::DownCast(S);
82 if (brhs.IsNull()) {throw Standard_ConstructionError();}
83 TopoDS_Shape s_wnt = brhs->Face();
84 s_wnt.Orientation(TopAbs_FORWARD);
85 myFace = TopoDS::Face(s_wnt);
86 if(myFClass2d != NULL) {
87 delete (BRepTopAdaptor_FClass2d *)myFClass2d;
93 TopExp_Explorer ex(myFace,TopAbs_EDGE);
94 for (; ex.More(); ex.Next()) {
95 Handle(BRepAdaptor_Curve2d) aCurve = new BRepAdaptor_Curve2d
96 (BRepAdaptor_Curve2d(TopoDS::Edge(ex.Current()),myFace));
97 myCurves.Append(aCurve);
99 myCIterator = TColStd_ListIteratorOfListOfTransient();
101 //=======================================================================
102 //function : Initialize
104 //=======================================================================
105 void BRepTopAdaptor_TopolTool::Initialize(const Handle(Adaptor2d_Curve2d)& C)
107 myCurve = Handle(BRepAdaptor_Curve2d)::DownCast(C);
108 if (myCurve.IsNull()) {throw Standard_ConstructionError();}
110 //=======================================================================
113 //=======================================================================
114 void BRepTopAdaptor_TopolTool::Init ()
116 myCIterator.Initialize(myCurves);
118 //=======================================================================
121 //=======================================================================
122 Standard_Boolean BRepTopAdaptor_TopolTool::More ()
124 return myCIterator.More();
126 //=======================================================================
129 //=======================================================================
130 void BRepTopAdaptor_TopolTool::Next()
134 //=======================================================================
137 //=======================================================================
138 Handle(Adaptor2d_Curve2d) BRepTopAdaptor_TopolTool::Value ()
140 return Handle(Adaptor2d_Curve2d)::DownCast(myCIterator.Value());
142 //modified by NIZNHY-PKV Tue Mar 27 14:23:40 2001 f
143 //=======================================================================
146 //=======================================================================
147 Standard_Address BRepTopAdaptor_TopolTool::Edge () const
149 Handle(BRepAdaptor_Curve2d) aHCurve = Handle(BRepAdaptor_Curve2d)::DownCast(myCIterator.Value());
150 return Standard_Address (&aHCurve->Edge());
153 //modified by NIZNHY-PKV Tue Mar 27 14:23:43 2001 t
154 //=======================================================================
155 //function : InitVertexIterator
157 //=======================================================================
158 void BRepTopAdaptor_TopolTool::InitVertexIterator ()
160 myVIterator.Init (myCurve->Edge(), TopAbs_VERTEX);
162 //=======================================================================
163 //function : NextVertex
165 //=======================================================================
166 Standard_Boolean BRepTopAdaptor_TopolTool::MoreVertex ()
168 return myVIterator.More();
171 void BRepTopAdaptor_TopolTool::NextVertex ()
175 //=======================================================================
178 //=======================================================================
179 Handle(Adaptor3d_HVertex) BRepTopAdaptor_TopolTool::Vertex ()
182 BRepTopAdaptor_HVertex(TopoDS::Vertex(myVIterator.Current()),myCurve);
185 //=======================================================================
186 //function : Classify
188 //=======================================================================
189 TopAbs_State BRepTopAdaptor_TopolTool::Classify(const gp_Pnt2d& P,
190 const Standard_Real Tol,
191 const Standard_Boolean RecadreOnPeriodic)
194 return TopAbs_UNKNOWN;
195 if(myFClass2d == NULL) {
196 myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
198 return(((BRepTopAdaptor_FClass2d *)myFClass2d)->Perform(P,RecadreOnPeriodic));
201 //=======================================================================
202 //function : IsThePointOn
204 //=======================================================================
205 Standard_Boolean BRepTopAdaptor_TopolTool::IsThePointOn(const gp_Pnt2d& P,
206 const Standard_Real Tol,
207 const Standard_Boolean RecadreOnPeriodic)
209 if(myFClass2d == NULL) {
210 myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
212 return(TopAbs_ON==((BRepTopAdaptor_FClass2d *)myFClass2d)->TestOnRestriction(P,Tol,RecadreOnPeriodic));
215 //=======================================================================
218 //=======================================================================
219 void BRepTopAdaptor_TopolTool::Destroy()
221 if(myFClass2d != NULL) {
222 delete (BRepTopAdaptor_FClass2d *)myFClass2d;
226 //=======================================================================
227 //function : Orientation
229 //=======================================================================
230 TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation (const Handle(Adaptor2d_Curve2d)& C)
232 Handle(BRepAdaptor_Curve2d) brhc = Handle(BRepAdaptor_Curve2d)::DownCast(C);
233 return brhc->Edge().Orientation();
235 //=======================================================================
236 //function : Orientation
238 //=======================================================================
239 TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation (const Handle(Adaptor3d_HVertex)& C)
241 return Adaptor3d_TopolTool::Orientation(C);
243 //-- ============================================================
244 //-- methods used for samples
245 //-- ============================================================
247 //=======================================================================
250 //=======================================================================
251 void Analyse(const TColgp_Array2OfPnt& array2,
252 const Standard_Integer nbup,
253 const Standard_Integer nbvp,
254 Standard_Integer& myNbSamplesU,
255 Standard_Integer& myNbSamplesV)
258 Standard_Integer sh,nbch,i,j;
263 for(i=2;i<nbup;i++) {
264 const gp_Pnt& A=array2.Value(i,1);
265 const gp_Pnt& B=array2.Value(i,2);
266 const gp_Pnt& C=array2.Value(i,3);
267 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
268 C.Y()-B.Y()-B.Y()+A.Y(),
269 C.Z()-B.Z()-B.Z()+A.Z());
270 Standard_Integer locnbch=0;
271 for(j=3; j<nbvp;j++) { //-- test
272 const gp_Pnt& Ax=array2.Value(i,j-1);
273 const gp_Pnt& Bx=array2.Value(i,j);
274 const gp_Pnt& Cx=array2.Value(i,j+1);
275 Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
276 Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
277 Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
278 Standard_Real pd = Vi.Dot(Vip1);
280 if(pd>1.0e-7 || pd<-1.0e-7) {
281 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
282 else { if(sh==1) { sh=-1; locnbch++; } }
290 myNbSamplesV = nbch+5;
295 for(j=2;j<nbvp;j++) {
296 const gp_Pnt& A=array2.Value(1,j);
297 const gp_Pnt& B=array2.Value(2,j);
298 const gp_Pnt& C=array2.Value(3,j);
299 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
300 C.Y()-B.Y()-B.Y()+A.Y(),
301 C.Z()-B.Z()-B.Z()+A.Z());
302 Standard_Integer locnbch=0;
303 for(i=3; i<nbup;i++) { //-- test
304 const gp_Pnt& Ax=array2.Value(i-1,j);
305 const gp_Pnt& Bx=array2.Value(i,j);
306 const gp_Pnt& Cx=array2.Value(i+1,j);
307 Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
308 Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
309 Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
310 Standard_Real pd = Vi.Dot(Vip1);
312 if(pd>1.0e-7 || pd<-1.0e-7) {
313 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
314 else { if(sh==1) { sh=-1; locnbch++; } }
317 if(locnbch>nbch) nbch=locnbch;
320 myNbSamplesU = nbch+5;
326 //=======================================================================
327 //function : ComputeSamplePoints
329 //=======================================================================
330 void BRepTopAdaptor_TopolTool::ComputeSamplePoints()
332 Standard_Real uinf,usup,vinf,vsup;
333 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
334 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
335 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
336 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
337 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
338 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
339 else if (usup == RealLast()) { usup=uinf+2.e5; }
341 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
342 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
343 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
345 Standard_Integer nbsu,nbsv;
346 GeomAbs_SurfaceType typS = myS->GetType();
348 case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
349 case GeomAbs_BezierSurface: { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles(); } break;
350 case GeomAbs_BSplineSurface: {
351 nbsv = myS->NbVKnots(); nbsv*= myS->VDegree(); if(nbsv < 4) nbsv=4;
352 nbsu = myS->NbUKnots(); nbsu*= myS->UDegree(); if(nbsu < 4) nbsu=4;
355 case GeomAbs_Cylinder:
358 case GeomAbs_Torus: {
360 //-- Not enough ->25 for 2pi
361 nbsu = (Standard_Integer)(8*(usup-uinf));
362 nbsv = (Standard_Integer)(7*(vsup-vinf));
365 if(nbsu>30) nbsu=30; //modif HRT buc60462
367 //-- printf("\n nbsu=%d nbsv=%d\n",nbsu,nbsv);
369 case GeomAbs_SurfaceOfRevolution:
370 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=25; } break;
371 default: { nbsu = 10; nbsv=10; } break;
374 //-- If the number of points is too great, analyze
384 //-- printf("\n BRepTopAdaptor_TopolTool NbSu=%d NbSv=%d ",nbsu,nbsv);
385 if(nbsu>10 || nbsv>10) {
386 if(typS == GeomAbs_BSplineSurface) {
387 const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
388 Standard_Integer nbup = Bspl->NbUPoles();
389 Standard_Integer nbvp = Bspl->NbVPoles();
390 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
392 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
395 //-- printf("\n Apres analyse BSPline NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
397 else if(typS == GeomAbs_BezierSurface) {
398 const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
399 Standard_Integer nbup = Bez->NbUPoles();
400 Standard_Integer nbvp = Bez->NbVPoles();
401 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
403 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
406 //-- printf("\n Apres analyse Bezier NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
419 myDU = (usup-uinf)/(myNbSamplesU+1);
420 myDV = (vsup-vinf)/(myNbSamplesV+1);
422 //=======================================================================
423 //function : NbSamplesU
425 //=======================================================================
426 Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesU()
428 if(myNbSamplesU <0) {
429 ComputeSamplePoints();
431 return(myNbSamplesU);
433 //=======================================================================
434 //function : NbSamplesV
436 //=======================================================================
437 Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesV()
439 if(myNbSamplesU <0) {
440 ComputeSamplePoints();
442 return(myNbSamplesV);
444 //=======================================================================
445 //function : NbSamples
447 //=======================================================================
448 Standard_Integer BRepTopAdaptor_TopolTool::NbSamples()
450 if(myNbSamplesU <0) {
451 ComputeSamplePoints();
453 return(myNbSamplesU*myNbSamplesV);
456 //=======================================================================
457 //function : SamplePoint
459 //=======================================================================
460 void BRepTopAdaptor_TopolTool::SamplePoint(const Standard_Integer i,
464 Standard_Integer iv = 1 + i/myNbSamplesU;
465 Standard_Integer iu = 1+ i-(iv-1)*myNbSamplesU;
466 Standard_Real u=myU0+iu*myDU;
467 Standard_Real v=myV0+iv*myDV;
471 //=======================================================================
472 //function : DomainIsInfinite
474 //=======================================================================
475 Standard_Boolean BRepTopAdaptor_TopolTool::DomainIsInfinite()
477 Standard_Real uinf,usup,vinf,vsup;
478 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
479 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
480 if(Precision::IsNegativeInfinite(uinf)) return(Standard_True);
481 if(Precision::IsPositiveInfinite(usup)) return(Standard_True);
482 if(Precision::IsNegativeInfinite(vinf)) return(Standard_True);
483 if(Precision::IsPositiveInfinite(vsup)) return(Standard_True);
484 return(Standard_False);
487 //=======================================================================
490 //=======================================================================
492 Standard_Boolean BRepTopAdaptor_TopolTool::Has3d() const
494 return Standard_True;
497 //=======================================================================
500 //=======================================================================
502 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor2d_Curve2d)& C) const
504 Handle(BRepAdaptor_Curve2d) brhc = Handle(BRepAdaptor_Curve2d)::DownCast(C);
507 throw Standard_DomainError("BRepTopAdaptor_TopolTool: arc has no 3d representation");
510 const TopoDS_Edge& edge = brhc->Edge();
512 throw Standard_DomainError("BRepTopAdaptor_TopolTool: arc has no 3d representation");
513 return BRep_Tool::Tolerance(edge);
516 //=======================================================================
519 //=======================================================================
521 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)& V) const
523 Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
525 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
526 const TopoDS_Vertex& ver = brhv->Vertex();
528 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
529 return BRep_Tool::Tolerance(ver);
532 //=======================================================================
535 //=======================================================================
537 gp_Pnt BRepTopAdaptor_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)& V) const
539 Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
541 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
542 const TopoDS_Vertex& ver = brhv->Vertex();
544 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
545 return BRep_Tool::Pnt(ver);