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_HCurve2d.hxx>
17 #include <Adaptor3d_HSurface.hxx>
18 #include <Adaptor3d_HVertex.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_HCurve2d.hxx>
21 #include <BRepAdaptor_HSurface.hxx>
22 #include <BRepClass_FaceClassifier.hxx>
23 #include <BRepClass_FaceExplorer.hxx>
24 #include <BRepTopAdaptor_FClass2d.hxx>
25 #include <BRepTopAdaptor_HVertex.hxx>
26 #include <BRepTopAdaptor_TopolTool.hxx>
27 #include <Geom_BezierSurface.hxx>
28 #include <Geom_BSplineSurface.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <Precision.hxx>
32 #include <Standard_ConstructionError.hxx>
33 #include <Standard_DomainError.hxx>
34 #include <Standard_NotImplemented.hxx>
35 #include <Standard_Type.hxx>
36 #include <TColgp_Array2OfPnt.hxx>
39 IMPLEMENT_STANDARD_RTTIEXT(BRepTopAdaptor_TopolTool,Adaptor3d_TopolTool)
42 void Analyse(const TColgp_Array2OfPnt& array2,
43 const Standard_Integer nbup,
44 const Standard_Integer nbvp,
45 Standard_Integer& myNbSamplesU,
46 Standard_Integer& myNbSamplesV);
47 //=======================================================================
48 //function : BRepTopAdaptor_TopolTool
50 //=======================================================================
51 BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool () : myFClass2d(NULL)
56 //=======================================================================
57 //function : BRepTopAdaptor_TopolTool
59 //=======================================================================
60 BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool(const Handle(Adaptor3d_HSurface)& 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_HSurface)& S)
80 Handle(BRepAdaptor_HSurface) brhs =
81 Handle(BRepAdaptor_HSurface)::DownCast(S);
82 if (brhs.IsNull()) {throw Standard_ConstructionError();}
83 TopoDS_Shape s_wnt = ((BRepAdaptor_Surface *)&(brhs->Surface()))->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_HCurve2d) aCurve = new BRepAdaptor_HCurve2d
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_HCurve2d)& C)
107 myCurve = Handle(BRepAdaptor_HCurve2d)::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_HCurve2d) BRepTopAdaptor_TopolTool::Value ()
140 return Handle(Adaptor2d_HCurve2d)::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_HCurve2d) aHCurve =
150 Handle(BRepAdaptor_HCurve2d)::DownCast(myCIterator.Value());
151 const BRepAdaptor_Curve2d& aCurve = (const BRepAdaptor_Curve2d&)aHCurve->Curve2d();
152 return Standard_Address (& aCurve.Edge());
155 //modified by NIZNHY-PKV Tue Mar 27 14:23:43 2001 t
156 //=======================================================================
157 //function : InitVertexIterator
159 //=======================================================================
160 void BRepTopAdaptor_TopolTool::InitVertexIterator ()
162 myVIterator.Init(((BRepAdaptor_Curve2d *)&(myCurve->Curve2d()))->Edge(),TopAbs_VERTEX);
164 //=======================================================================
165 //function : NextVertex
167 //=======================================================================
168 Standard_Boolean BRepTopAdaptor_TopolTool::MoreVertex ()
170 return myVIterator.More();
173 void BRepTopAdaptor_TopolTool::NextVertex ()
177 //=======================================================================
180 //=======================================================================
181 Handle(Adaptor3d_HVertex) BRepTopAdaptor_TopolTool::Vertex ()
184 BRepTopAdaptor_HVertex(TopoDS::Vertex(myVIterator.Current()),myCurve);
187 //=======================================================================
188 //function : Classify
190 //=======================================================================
191 TopAbs_State BRepTopAdaptor_TopolTool::Classify(const gp_Pnt2d& P,
192 const Standard_Real Tol,
193 const Standard_Boolean RecadreOnPeriodic)
196 return TopAbs_UNKNOWN;
197 if(myFClass2d == NULL) {
198 myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
200 return(((BRepTopAdaptor_FClass2d *)myFClass2d)->Perform(P,RecadreOnPeriodic));
203 //=======================================================================
204 //function : IsThePointOn
206 //=======================================================================
207 Standard_Boolean BRepTopAdaptor_TopolTool::IsThePointOn(const gp_Pnt2d& P,
208 const Standard_Real Tol,
209 const Standard_Boolean RecadreOnPeriodic)
211 if(myFClass2d == NULL) {
212 myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
214 return(TopAbs_ON==((BRepTopAdaptor_FClass2d *)myFClass2d)->TestOnRestriction(P,Tol,RecadreOnPeriodic));
217 //=======================================================================
220 //=======================================================================
221 void BRepTopAdaptor_TopolTool::Destroy()
223 if(myFClass2d != NULL) {
224 delete (BRepTopAdaptor_FClass2d *)myFClass2d;
228 //=======================================================================
229 //function : Orientation
231 //=======================================================================
232 TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation (const Handle(Adaptor2d_HCurve2d)& C)
234 Handle(BRepAdaptor_HCurve2d) brhc =
235 Handle(BRepAdaptor_HCurve2d)::DownCast(C);
236 return ((BRepAdaptor_Curve2d *)&(brhc->Curve2d()))->Edge().Orientation();
238 //=======================================================================
239 //function : Orientation
241 //=======================================================================
242 TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation (const Handle(Adaptor3d_HVertex)& C)
244 return Adaptor3d_TopolTool::Orientation(C);
246 //-- ============================================================
247 //-- methods used for samples
248 //-- ============================================================
250 //=======================================================================
253 //=======================================================================
254 void Analyse(const TColgp_Array2OfPnt& array2,
255 const Standard_Integer nbup,
256 const Standard_Integer nbvp,
257 Standard_Integer& myNbSamplesU,
258 Standard_Integer& myNbSamplesV)
261 Standard_Integer sh,nbch,i,j;
266 for(i=2;i<nbup;i++) {
267 const gp_Pnt& A=array2.Value(i,1);
268 const gp_Pnt& B=array2.Value(i,2);
269 const gp_Pnt& C=array2.Value(i,3);
270 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
271 C.Y()-B.Y()-B.Y()+A.Y(),
272 C.Z()-B.Z()-B.Z()+A.Z());
273 Standard_Integer locnbch=0;
274 for(j=3; j<nbvp;j++) { //-- test
275 const gp_Pnt& Ax=array2.Value(i,j-1);
276 const gp_Pnt& Bx=array2.Value(i,j);
277 const gp_Pnt& Cx=array2.Value(i,j+1);
278 Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
279 Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
280 Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
281 Standard_Real pd = Vi.Dot(Vip1);
283 if(pd>1.0e-7 || pd<-1.0e-7) {
284 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
285 else { if(sh==1) { sh=-1; locnbch++; } }
293 myNbSamplesV = nbch+5;
298 for(j=2;j<nbvp;j++) {
299 const gp_Pnt& A=array2.Value(1,j);
300 const gp_Pnt& B=array2.Value(2,j);
301 const gp_Pnt& C=array2.Value(3,j);
302 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
303 C.Y()-B.Y()-B.Y()+A.Y(),
304 C.Z()-B.Z()-B.Z()+A.Z());
305 Standard_Integer locnbch=0;
306 for(i=3; i<nbup;i++) { //-- test
307 const gp_Pnt& Ax=array2.Value(i-1,j);
308 const gp_Pnt& Bx=array2.Value(i,j);
309 const gp_Pnt& Cx=array2.Value(i+1,j);
310 Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
311 Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
312 Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
313 Standard_Real pd = Vi.Dot(Vip1);
315 if(pd>1.0e-7 || pd<-1.0e-7) {
316 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
317 else { if(sh==1) { sh=-1; locnbch++; } }
320 if(locnbch>nbch) nbch=locnbch;
323 myNbSamplesU = nbch+5;
329 //=======================================================================
330 //function : ComputeSamplePoints
332 //=======================================================================
333 void BRepTopAdaptor_TopolTool::ComputeSamplePoints()
335 Standard_Real uinf,usup,vinf,vsup;
336 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
337 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
338 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
339 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
340 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
341 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
342 else if (usup == RealLast()) { usup=uinf+2.e5; }
344 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
345 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
346 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
348 Standard_Integer nbsu,nbsv;
349 GeomAbs_SurfaceType typS = myS->GetType();
351 case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
352 case GeomAbs_BezierSurface: { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles(); } break;
353 case GeomAbs_BSplineSurface: {
354 nbsv = myS->NbVKnots(); nbsv*= myS->VDegree(); if(nbsv < 4) nbsv=4;
355 nbsu = myS->NbUKnots(); nbsu*= myS->UDegree(); if(nbsu < 4) nbsu=4;
358 case GeomAbs_Cylinder:
361 case GeomAbs_Torus: {
363 //-- Not enough ->25 for 2pi
364 nbsu = (Standard_Integer)(8*(usup-uinf));
365 nbsv = (Standard_Integer)(7*(vsup-vinf));
368 if(nbsu>30) nbsu=30; //modif HRT buc60462
370 //-- printf("\n nbsu=%d nbsv=%d\n",nbsu,nbsv);
372 case GeomAbs_SurfaceOfRevolution:
373 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=25; } break;
374 default: { nbsu = 10; nbsv=10; } break;
377 //-- If the number of points is too great, analyze
387 //-- printf("\n BRepTopAdaptor_TopolTool NbSu=%d NbSv=%d ",nbsu,nbsv);
388 if(nbsu>10 || nbsv>10) {
389 if(typS == GeomAbs_BSplineSurface) {
390 const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
391 Standard_Integer nbup = Bspl->NbUPoles();
392 Standard_Integer nbvp = Bspl->NbVPoles();
393 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
395 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
398 //-- printf("\n Apres analyse BSPline NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
400 else if(typS == GeomAbs_BezierSurface) {
401 const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
402 Standard_Integer nbup = Bez->NbUPoles();
403 Standard_Integer nbvp = Bez->NbVPoles();
404 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
406 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
409 //-- printf("\n Apres analyse Bezier NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
422 myDU = (usup-uinf)/(myNbSamplesU+1);
423 myDV = (vsup-vinf)/(myNbSamplesV+1);
425 //=======================================================================
426 //function : NbSamplesU
428 //=======================================================================
429 Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesU()
431 if(myNbSamplesU <0) {
432 ComputeSamplePoints();
434 return(myNbSamplesU);
436 //=======================================================================
437 //function : NbSamplesV
439 //=======================================================================
440 Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesV()
442 if(myNbSamplesU <0) {
443 ComputeSamplePoints();
445 return(myNbSamplesV);
447 //=======================================================================
448 //function : NbSamples
450 //=======================================================================
451 Standard_Integer BRepTopAdaptor_TopolTool::NbSamples()
453 if(myNbSamplesU <0) {
454 ComputeSamplePoints();
456 return(myNbSamplesU*myNbSamplesV);
459 //=======================================================================
460 //function : SamplePoint
462 //=======================================================================
463 void BRepTopAdaptor_TopolTool::SamplePoint(const Standard_Integer i,
467 Standard_Integer iv = 1 + i/myNbSamplesU;
468 Standard_Integer iu = 1+ i-(iv-1)*myNbSamplesU;
469 Standard_Real u=myU0+iu*myDU;
470 Standard_Real v=myV0+iv*myDV;
474 //=======================================================================
475 //function : DomainIsInfinite
477 //=======================================================================
478 Standard_Boolean BRepTopAdaptor_TopolTool::DomainIsInfinite()
480 Standard_Real uinf,usup,vinf,vsup;
481 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
482 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
483 if(Precision::IsNegativeInfinite(uinf)) return(Standard_True);
484 if(Precision::IsPositiveInfinite(usup)) return(Standard_True);
485 if(Precision::IsNegativeInfinite(vinf)) return(Standard_True);
486 if(Precision::IsPositiveInfinite(vsup)) return(Standard_True);
487 return(Standard_False);
490 //=======================================================================
493 //=======================================================================
495 Standard_Boolean BRepTopAdaptor_TopolTool::Has3d() const
497 return Standard_True;
500 //=======================================================================
503 //=======================================================================
505 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)& C) const
507 Handle(BRepAdaptor_HCurve2d) brhc = Handle(BRepAdaptor_HCurve2d)::DownCast(C);
509 throw Standard_DomainError("BRepTopAdaptor_TopolTool: arc has no 3d representation");
510 const BRepAdaptor_Curve2d& brc = (const BRepAdaptor_Curve2d &)brhc->Curve2d();
511 const TopoDS_Edge& edge = brc.Edge();
513 throw Standard_DomainError("BRepTopAdaptor_TopolTool: arc has no 3d representation");
514 return BRep_Tool::Tolerance(edge);
517 //=======================================================================
520 //=======================================================================
522 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)& V) const
524 Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
526 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
527 const TopoDS_Vertex& ver = brhv->Vertex();
529 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
530 return BRep_Tool::Tolerance(ver);
533 //=======================================================================
536 //=======================================================================
538 gp_Pnt BRepTopAdaptor_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)& V) const
540 Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
542 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
543 const TopoDS_Vertex& ver = brhv->Vertex();
545 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
546 return BRep_Tool::Pnt(ver);