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>
40 void Analyse(const TColgp_Array2OfPnt& array2,
41 const Standard_Integer nbup,
42 const Standard_Integer nbvp,
43 Standard_Integer& myNbSamplesU,
44 Standard_Integer& myNbSamplesV);
45 //=======================================================================
46 //function : BRepTopAdaptor_TopolTool
48 //=======================================================================
49 BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool () : myFClass2d(NULL)
54 //=======================================================================
55 //function : BRepTopAdaptor_TopolTool
57 //=======================================================================
58 BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool(const Handle(Adaptor3d_HSurface)& S)
64 //=======================================================================
65 //function : Initialize
67 //=======================================================================
68 void BRepTopAdaptor_TopolTool::Initialize()
70 Standard_NotImplemented::Raise("BRepTopAdaptor_TopolTool::Initialize()");
72 //=======================================================================
73 //function : Initialize
75 //=======================================================================
76 void BRepTopAdaptor_TopolTool::Initialize(const Handle(Adaptor3d_HSurface)& S)
78 Handle(BRepAdaptor_HSurface) brhs =
79 Handle(BRepAdaptor_HSurface)::DownCast(S);
80 if (brhs.IsNull()) {Standard_ConstructionError::Raise();}
81 TopoDS_Shape s_wnt = ((BRepAdaptor_Surface *)&(brhs->Surface()))->Face();
82 s_wnt.Orientation(TopAbs_FORWARD);
83 myFace = TopoDS::Face(s_wnt);
84 if(myFClass2d != NULL) {
85 delete (BRepTopAdaptor_FClass2d *)myFClass2d;
91 TopExp_Explorer ex(myFace,TopAbs_EDGE);
92 for (; ex.More(); ex.Next()) {
93 Handle(BRepAdaptor_HCurve2d) aCurve = new BRepAdaptor_HCurve2d
94 (BRepAdaptor_Curve2d(TopoDS::Edge(ex.Current()),myFace));
95 myCurves.Append(aCurve);
97 myCIterator = TColStd_ListIteratorOfListOfTransient();
99 //=======================================================================
100 //function : Initialize
102 //=======================================================================
103 void BRepTopAdaptor_TopolTool::Initialize(const Handle(Adaptor2d_HCurve2d)& C)
105 myCurve = Handle(BRepAdaptor_HCurve2d)::DownCast(C);
106 if (myCurve.IsNull()) {Standard_ConstructionError::Raise();}
108 //=======================================================================
111 //=======================================================================
112 void BRepTopAdaptor_TopolTool::Init ()
114 myCIterator.Initialize(myCurves);
116 //=======================================================================
119 //=======================================================================
120 Standard_Boolean BRepTopAdaptor_TopolTool::More ()
122 return myCIterator.More();
124 //=======================================================================
127 //=======================================================================
128 void BRepTopAdaptor_TopolTool::Next()
132 //=======================================================================
135 //=======================================================================
136 Handle(Adaptor2d_HCurve2d) BRepTopAdaptor_TopolTool::Value ()
138 return Handle(Adaptor2d_HCurve2d)::DownCast(myCIterator.Value());
140 //modified by NIZNHY-PKV Tue Mar 27 14:23:40 2001 f
141 //=======================================================================
144 //=======================================================================
145 Standard_Address BRepTopAdaptor_TopolTool::Edge () const
147 Handle(BRepAdaptor_HCurve2d) aHCurve =
148 Handle(BRepAdaptor_HCurve2d)::DownCast(myCIterator.Value());
149 const BRepAdaptor_Curve2d& aCurve = (const BRepAdaptor_Curve2d&)aHCurve->Curve2d();
150 return Standard_Address (& aCurve.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(((BRepAdaptor_Curve2d *)&(myCurve->Curve2d()))->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_HCurve2d)& C)
232 Handle(BRepAdaptor_HCurve2d) brhc =
233 Handle(BRepAdaptor_HCurve2d)::DownCast(C);
234 return ((BRepAdaptor_Curve2d *)&(brhc->Curve2d()))->Edge().Orientation();
236 //=======================================================================
237 //function : Orientation
239 //=======================================================================
240 TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation (const Handle(Adaptor3d_HVertex)& C)
242 return Adaptor3d_TopolTool::Orientation(C);
244 //-- ============================================================
245 //-- methods used for samples
246 //-- ============================================================
248 //=======================================================================
251 //=======================================================================
252 void Analyse(const TColgp_Array2OfPnt& array2,
253 const Standard_Integer nbup,
254 const Standard_Integer nbvp,
255 Standard_Integer& myNbSamplesU,
256 Standard_Integer& myNbSamplesV)
259 Standard_Integer sh,nbch,i,j;
264 for(i=2;i<nbup;i++) {
265 const gp_Pnt& A=array2.Value(i,1);
266 const gp_Pnt& B=array2.Value(i,2);
267 const gp_Pnt& C=array2.Value(i,3);
268 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
269 C.Y()-B.Y()-B.Y()+A.Y(),
270 C.Z()-B.Z()-B.Z()+A.Z());
271 Standard_Integer locnbch=0;
272 for(j=3; j<nbvp;j++) { //-- test
273 const gp_Pnt& Ax=array2.Value(i,j-1);
274 const gp_Pnt& Bx=array2.Value(i,j);
275 const gp_Pnt& Cx=array2.Value(i,j+1);
276 Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
277 Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
278 Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
279 Standard_Real pd = Vi.Dot(Vip1);
281 if(pd>1.0e-7 || pd<-1.0e-7) {
282 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
283 else { if(sh==1) { sh=-1; locnbch++; } }
291 myNbSamplesV = nbch+5;
296 for(j=2;j<nbvp;j++) {
297 const gp_Pnt& A=array2.Value(1,j);
298 const gp_Pnt& B=array2.Value(2,j);
299 const gp_Pnt& C=array2.Value(3,j);
300 Vi.SetCoord(C.X()-B.X()-B.X()+A.X(),
301 C.Y()-B.Y()-B.Y()+A.Y(),
302 C.Z()-B.Z()-B.Z()+A.Z());
303 Standard_Integer locnbch=0;
304 for(i=3; i<nbup;i++) { //-- test
305 const gp_Pnt& Ax=array2.Value(i-1,j);
306 const gp_Pnt& Bx=array2.Value(i,j);
307 const gp_Pnt& Cx=array2.Value(i+1,j);
308 Vip1.SetCoord(Cx.X()-Bx.X()-Bx.X()+Ax.X(),
309 Cx.Y()-Bx.Y()-Bx.Y()+Ax.Y(),
310 Cx.Z()-Bx.Z()-Bx.Z()+Ax.Z());
311 Standard_Real pd = Vi.Dot(Vip1);
313 if(pd>1.0e-7 || pd<-1.0e-7) {
314 if(pd>0) { if(sh==-1) { sh=1; locnbch++; } }
315 else { if(sh==1) { sh=-1; locnbch++; } }
318 if(locnbch>nbch) nbch=locnbch;
321 myNbSamplesU = nbch+5;
327 //=======================================================================
328 //function : ComputeSamplePoints
330 //=======================================================================
331 void BRepTopAdaptor_TopolTool::ComputeSamplePoints()
333 Standard_Real uinf,usup,vinf,vsup;
334 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
335 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
336 if (usup < uinf) { Standard_Real temp=uinf; uinf=usup; usup=temp; }
337 if (vsup < vinf) { Standard_Real temp=vinf; vinf=vsup; vsup=temp; }
338 if (uinf == RealFirst() && usup == RealLast()) { uinf=-1.e5; usup=1.e5; }
339 else if (uinf == RealFirst()) { uinf=usup-2.e5; }
340 else if (usup == RealLast()) { usup=uinf+2.e5; }
342 if (vinf == RealFirst() && vsup == RealLast()) { vinf=-1.e5; vsup=1.e5; }
343 else if (vinf == RealFirst()) { vinf=vsup-2.e5; }
344 else if (vsup == RealLast()) { vsup=vinf+2.e5; }
346 Standard_Integer nbsu,nbsv;
347 GeomAbs_SurfaceType typS = myS->GetType();
349 case GeomAbs_Plane: { nbsv=2; nbsu=2; } break;
350 case GeomAbs_BezierSurface: { nbsv=3+myS->NbVPoles(); nbsu=3+myS->NbUPoles(); } break;
351 case GeomAbs_BSplineSurface: {
352 nbsv = myS->NbVKnots(); nbsv*= myS->VDegree(); if(nbsv < 4) nbsv=4;
353 nbsu = myS->NbUKnots(); nbsu*= myS->UDegree(); if(nbsu < 4) nbsu=4;
356 case GeomAbs_Cylinder:
359 case GeomAbs_Torus: {
361 //-- Not enough ->25 for 2pi
362 nbsu = (Standard_Integer)(8*(usup-uinf));
363 nbsv = (Standard_Integer)(7*(vsup-vinf));
366 if(nbsu>30) nbsu=30; //modif HRT buc60462
368 //-- printf("\n nbsu=%d nbsv=%d\n",nbsu,nbsv);
370 case GeomAbs_SurfaceOfRevolution:
371 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=25; } break;
372 default: { nbsu = 10; nbsv=10; } break;
375 //-- If the number of points is too great, analyze
385 //-- printf("\n BRepTopAdaptor_TopolTool NbSu=%d NbSv=%d ",nbsu,nbsv);
386 if(nbsu>10 || nbsv>10) {
387 if(typS == GeomAbs_BSplineSurface) {
388 const Handle(Geom_BSplineSurface)& Bspl = myS->BSpline();
389 Standard_Integer nbup = Bspl->NbUPoles();
390 Standard_Integer nbvp = Bspl->NbVPoles();
391 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
393 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
396 //-- printf("\n Apres analyse BSPline NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
398 else if(typS == GeomAbs_BezierSurface) {
399 const Handle(Geom_BezierSurface)& Bez = myS->Bezier();
400 Standard_Integer nbup = Bez->NbUPoles();
401 Standard_Integer nbvp = Bez->NbVPoles();
402 TColgp_Array2OfPnt array2(1,nbup,1,nbvp);
404 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
407 //-- printf("\n Apres analyse Bezier NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
420 myDU = (usup-uinf)/(myNbSamplesU+1);
421 myDV = (vsup-vinf)/(myNbSamplesV+1);
423 //=======================================================================
424 //function : NbSamplesU
426 //=======================================================================
427 Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesU()
429 if(myNbSamplesU <0) {
430 ComputeSamplePoints();
432 return(myNbSamplesU);
434 //=======================================================================
435 //function : NbSamplesV
437 //=======================================================================
438 Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesV()
440 if(myNbSamplesU <0) {
441 ComputeSamplePoints();
443 return(myNbSamplesV);
445 //=======================================================================
446 //function : NbSamples
448 //=======================================================================
449 Standard_Integer BRepTopAdaptor_TopolTool::NbSamples()
451 if(myNbSamplesU <0) {
452 ComputeSamplePoints();
454 return(myNbSamplesU*myNbSamplesV);
457 //=======================================================================
458 //function : SamplePoint
460 //=======================================================================
461 void BRepTopAdaptor_TopolTool::SamplePoint(const Standard_Integer i,
465 Standard_Integer iv = 1 + i/myNbSamplesU;
466 Standard_Integer iu = 1+ i-(iv-1)*myNbSamplesU;
467 Standard_Real u=myU0+iu*myDU;
468 Standard_Real v=myV0+iv*myDV;
472 //=======================================================================
473 //function : DomainIsInfinite
475 //=======================================================================
476 Standard_Boolean BRepTopAdaptor_TopolTool::DomainIsInfinite()
478 Standard_Real uinf,usup,vinf,vsup;
479 uinf = myS->FirstUParameter(); usup = myS->LastUParameter();
480 vinf = myS->FirstVParameter(); vsup = myS->LastVParameter();
481 if(Precision::IsNegativeInfinite(uinf)) return(Standard_True);
482 if(Precision::IsPositiveInfinite(usup)) return(Standard_True);
483 if(Precision::IsNegativeInfinite(vinf)) return(Standard_True);
484 if(Precision::IsPositiveInfinite(vsup)) return(Standard_True);
485 return(Standard_False);
488 //=======================================================================
491 //=======================================================================
493 Standard_Boolean BRepTopAdaptor_TopolTool::Has3d() const
495 return Standard_True;
498 //=======================================================================
501 //=======================================================================
503 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)& C) const
505 Handle(BRepAdaptor_HCurve2d) brhc = Handle(BRepAdaptor_HCurve2d)::DownCast(C);
507 Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: arc has no 3d representation");
508 const BRepAdaptor_Curve2d& brc = (const BRepAdaptor_Curve2d &)brhc->Curve2d();
509 const TopoDS_Edge& edge = brc.Edge();
511 Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: arc has no 3d representation");
512 return BRep_Tool::Tolerance(edge);
515 //=======================================================================
518 //=======================================================================
520 Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)& V) const
522 Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
524 Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
525 const TopoDS_Vertex& ver = brhv->Vertex();
527 Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
528 return BRep_Tool::Tolerance(ver);
531 //=======================================================================
534 //=======================================================================
536 gp_Pnt BRepTopAdaptor_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)& V) const
538 Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
540 Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
541 const TopoDS_Vertex& ver = brhv->Vertex();
543 Standard_DomainError::Raise("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
544 return BRep_Tool::Pnt(ver);