0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / BRepTopAdaptor / BRepTopAdaptor_TopolTool.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 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
973c2be1 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.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
7fd59977 15
42cf5bc1 16#include <Adaptor2d_HCurve2d.hxx>
17#include <Adaptor3d_HSurface.hxx>
18#include <Adaptor3d_HVertex.hxx>
19#include <BRep_Tool.hxx>
7fd59977 20#include <BRepAdaptor_HCurve2d.hxx>
42cf5bc1 21#include <BRepAdaptor_HSurface.hxx>
7fd59977 22#include <BRepClass_FaceClassifier.hxx>
23#include <BRepClass_FaceExplorer.hxx>
7fd59977 24#include <BRepTopAdaptor_FClass2d.hxx>
42cf5bc1 25#include <BRepTopAdaptor_HVertex.hxx>
26#include <BRepTopAdaptor_TopolTool.hxx>
7fd59977 27#include <Geom_BezierSurface.hxx>
28#include <Geom_BSplineSurface.hxx>
42cf5bc1 29#include <gp_Pnt.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>
37#include <TopoDS.hxx>
7fd59977 38
92efcf78 39IMPLEMENT_STANDARD_RTTIEXT(BRepTopAdaptor_TopolTool,Adaptor3d_TopolTool)
40
7fd59977 41static
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
49//purpose :
50//=======================================================================
51 BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool () : myFClass2d(NULL)
52{
53 myNbSamplesU=-1;
54}
55
56//=======================================================================
57//function : BRepTopAdaptor_TopolTool
58//purpose :
59//=======================================================================
60 BRepTopAdaptor_TopolTool::BRepTopAdaptor_TopolTool(const Handle(Adaptor3d_HSurface)& S)
61: myFClass2d(NULL)
62{
63 Initialize(S);
64 //myS = S;
65}
66//=======================================================================
67//function : Initialize
68//purpose :
69//=======================================================================
70 void BRepTopAdaptor_TopolTool::Initialize()
71{
9775fa61 72 throw Standard_NotImplemented("BRepTopAdaptor_TopolTool::Initialize()");
7fd59977 73}
74//=======================================================================
75//function : Initialize
76//purpose :
77//=======================================================================
78 void BRepTopAdaptor_TopolTool::Initialize(const Handle(Adaptor3d_HSurface)& S)
79{
80 Handle(BRepAdaptor_HSurface) brhs =
81 Handle(BRepAdaptor_HSurface)::DownCast(S);
9775fa61 82 if (brhs.IsNull()) {throw Standard_ConstructionError();}
7fd59977 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;
88 }
89 myFClass2d = NULL;
90 myNbSamplesU=-1;
91 myS = S;
92 myCurves.Clear();
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);
98 }
99 myCIterator = TColStd_ListIteratorOfListOfTransient();
100}
101//=======================================================================
102//function : Initialize
103//purpose :
104//=======================================================================
105 void BRepTopAdaptor_TopolTool::Initialize(const Handle(Adaptor2d_HCurve2d)& C)
106{
107 myCurve = Handle(BRepAdaptor_HCurve2d)::DownCast(C);
9775fa61 108 if (myCurve.IsNull()) {throw Standard_ConstructionError();}
7fd59977 109}
110//=======================================================================
111//function : Init
112//purpose :
113//=======================================================================
114 void BRepTopAdaptor_TopolTool::Init ()
115{
116 myCIterator.Initialize(myCurves);
117}
118//=======================================================================
119//function : More
120//purpose :
121//=======================================================================
122 Standard_Boolean BRepTopAdaptor_TopolTool::More ()
123{
124 return myCIterator.More();
125}
126//=======================================================================
127//function : Next
128//purpose :
129//=======================================================================
130 void BRepTopAdaptor_TopolTool::Next()
131{
132 myCIterator.Next();
133}
134//=======================================================================
135//function : Value
136//purpose :
137//=======================================================================
138 Handle(Adaptor2d_HCurve2d) BRepTopAdaptor_TopolTool::Value ()
139{
140 return Handle(Adaptor2d_HCurve2d)::DownCast(myCIterator.Value());
141}
142//modified by NIZNHY-PKV Tue Mar 27 14:23:40 2001 f
143//=======================================================================
144//function : Edge
145//purpose :
146//=======================================================================
147 Standard_Address BRepTopAdaptor_TopolTool::Edge () const
148{
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());
153}
154
155//modified by NIZNHY-PKV Tue Mar 27 14:23:43 2001 t
156//=======================================================================
157//function : InitVertexIterator
158//purpose :
159//=======================================================================
160 void BRepTopAdaptor_TopolTool::InitVertexIterator ()
161{
162 myVIterator.Init(((BRepAdaptor_Curve2d *)&(myCurve->Curve2d()))->Edge(),TopAbs_VERTEX);
163}
164//=======================================================================
165//function : NextVertex
166//purpose :
167//=======================================================================
168 Standard_Boolean BRepTopAdaptor_TopolTool::MoreVertex ()
169{
170 return myVIterator.More();
171}
172
173 void BRepTopAdaptor_TopolTool::NextVertex ()
174{
175 myVIterator.Next();
176}
177//=======================================================================
178//function : Vertex
179//purpose :
180//=======================================================================
181 Handle(Adaptor3d_HVertex) BRepTopAdaptor_TopolTool::Vertex ()
182{
183 return new
184 BRepTopAdaptor_HVertex(TopoDS::Vertex(myVIterator.Current()),myCurve);
185}
186
187//=======================================================================
188//function : Classify
189//purpose :
190//=======================================================================
191 TopAbs_State BRepTopAdaptor_TopolTool::Classify(const gp_Pnt2d& P,
192 const Standard_Real Tol,
193 const Standard_Boolean RecadreOnPeriodic)
194{
8ba67813 195 if(myFace.IsNull())
196 return TopAbs_UNKNOWN;
7fd59977 197 if(myFClass2d == NULL) {
198 myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
199 }
200 return(((BRepTopAdaptor_FClass2d *)myFClass2d)->Perform(P,RecadreOnPeriodic));
201}
202
203//=======================================================================
204//function : IsThePointOn
205//purpose :
206//=======================================================================
207 Standard_Boolean BRepTopAdaptor_TopolTool::IsThePointOn(const gp_Pnt2d& P,
208 const Standard_Real Tol,
209 const Standard_Boolean RecadreOnPeriodic)
210{
211 if(myFClass2d == NULL) {
212 myFClass2d = (void *) new BRepTopAdaptor_FClass2d(myFace,Tol);
213 }
214 return(TopAbs_ON==((BRepTopAdaptor_FClass2d *)myFClass2d)->TestOnRestriction(P,Tol,RecadreOnPeriodic));
215}
216
217//=======================================================================
218//function : Destroy
219//purpose :
220//=======================================================================
221 void BRepTopAdaptor_TopolTool::Destroy()
222{
223 if(myFClass2d != NULL) {
224 delete (BRepTopAdaptor_FClass2d *)myFClass2d;
225 myFClass2d=NULL;
226 }
227}
228//=======================================================================
229//function : Orientation
230//purpose :
231//=======================================================================
232 TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation (const Handle(Adaptor2d_HCurve2d)& C)
233{
234 Handle(BRepAdaptor_HCurve2d) brhc =
235 Handle(BRepAdaptor_HCurve2d)::DownCast(C);
236 return ((BRepAdaptor_Curve2d *)&(brhc->Curve2d()))->Edge().Orientation();
237}
238//=======================================================================
239//function : Orientation
240//purpose :
241//=======================================================================
242 TopAbs_Orientation BRepTopAdaptor_TopolTool::Orientation (const Handle(Adaptor3d_HVertex)& C)
243{
244 return Adaptor3d_TopolTool::Orientation(C);
245}
246//-- ============================================================
0d969553 247//-- methods used for samples
7fd59977 248//-- ============================================================
249
250//=======================================================================
251//function : Analyse
252//purpose :
253//=======================================================================
254void Analyse(const TColgp_Array2OfPnt& array2,
255 const Standard_Integer nbup,
256 const Standard_Integer nbvp,
257 Standard_Integer& myNbSamplesU,
258 Standard_Integer& myNbSamplesV)
259{
260 gp_Vec Vi,Vip1;
261 Standard_Integer sh,nbch,i,j;
262
263 sh = 1;
264 nbch = 0;
265 if(nbvp>2) {
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;
0d969553 274 for(j=3; j<nbvp;j++) { //-- test
7fd59977 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);
282 Vi=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++; } }
286 }
287 }
288 if(locnbch>nbch) {
289 nbch=locnbch;
290 }
291 }
292 }
293 myNbSamplesV = nbch+5;
294
295
296 nbch=0;
297 if(nbup>2) {
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;
0d969553 306 for(i=3; i<nbup;i++) { //-- test
7fd59977 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);
314 Vi=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++; } }
318 }
319 }
320 if(locnbch>nbch) nbch=locnbch;
321 }
322 }
323 myNbSamplesU = nbch+5;
324}
325
326
327
328
329//=======================================================================
330//function : ComputeSamplePoints
331//purpose :
332//=======================================================================
333 void BRepTopAdaptor_TopolTool::ComputeSamplePoints()
334{
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; }
343
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; }
347
348 Standard_Integer nbsu,nbsv;
349 GeomAbs_SurfaceType typS = myS->GetType();
350 switch(typS) {
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;
356 }
357 break;
358 case GeomAbs_Cylinder:
359 case GeomAbs_Cone:
360 case GeomAbs_Sphere:
361 case GeomAbs_Torus: {
0d969553
Y
362 //-- Set 15 for 2pi
363 //-- Not enough ->25 for 2pi
7fd59977 364 nbsu = (Standard_Integer)(8*(usup-uinf));
365 nbsv = (Standard_Integer)(7*(vsup-vinf));
366 if(nbsu<5) nbsu=5;
367 if(nbsv<5) nbsv=5;
368 if(nbsu>30) nbsu=30; //modif HRT buc60462
369 if(nbsv>15) nbsv=15;
370 //-- printf("\n nbsu=%d nbsv=%d\n",nbsu,nbsv);
371 } break;
372 case GeomAbs_SurfaceOfRevolution:
373 case GeomAbs_SurfaceOfExtrusion: { nbsv = 15; nbsu=25; } break;
374 default: { nbsu = 10; nbsv=10; } break;
375 }
376
0d969553 377 //-- If the number of points is too great, analyze
7fd59977 378 //--
379 //--
380
381 if(nbsu<10) nbsu=10;
382 if(nbsv<10) nbsv=10;
383
384 myNbSamplesU = nbsu;
385 myNbSamplesV = nbsv;
386
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);
394 Bspl->Poles(array2);
395 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
396 nbsu=myNbSamplesU;
397 nbsv=myNbSamplesV;
398 //-- printf("\n Apres analyse BSPline NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
399 }
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);
405 Bez->Poles(array2);
406 Analyse(array2,nbup,nbvp,myNbSamplesU,myNbSamplesV);
407 nbsu=myNbSamplesU;
408 nbsv=myNbSamplesV;
409 //-- printf("\n Apres analyse Bezier NbSu=%d NbSv=%d ",myNbSamplesU,myNbSamplesV);
410 }
411 }
412
413 if(nbsu<10) nbsu=10;
414 if(nbsv<10) nbsv=10;
415
416 myNbSamplesU = nbsu;
417 myNbSamplesV = nbsv;
418
419 myU0 = uinf;
420 myV0 = vinf;
421
422 myDU = (usup-uinf)/(myNbSamplesU+1);
423 myDV = (vsup-vinf)/(myNbSamplesV+1);
424}
425//=======================================================================
426//function : NbSamplesU
427//purpose :
428//=======================================================================
429 Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesU()
430{
431 if(myNbSamplesU <0) {
432 ComputeSamplePoints();
433 }
434 return(myNbSamplesU);
435}
436//=======================================================================
437//function : NbSamplesV
438//purpose :
439//=======================================================================
440 Standard_Integer BRepTopAdaptor_TopolTool::NbSamplesV()
441{
442 if(myNbSamplesU <0) {
443 ComputeSamplePoints();
444 }
445 return(myNbSamplesV);
446}
447//=======================================================================
448//function : NbSamples
449//purpose :
450//=======================================================================
451 Standard_Integer BRepTopAdaptor_TopolTool::NbSamples()
452{
453 if(myNbSamplesU <0) {
454 ComputeSamplePoints();
455 }
456 return(myNbSamplesU*myNbSamplesV);
457}
458
459//=======================================================================
460//function : SamplePoint
461//purpose :
462//=======================================================================
463 void BRepTopAdaptor_TopolTool::SamplePoint(const Standard_Integer i,
464 gp_Pnt2d& P2d,
465 gp_Pnt& P3d)
466{
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;
471 P2d.SetCoord(u,v);
472 P3d=myS->Value(u,v);
473}
474//=======================================================================
475//function : DomainIsInfinite
476//purpose :
477//=======================================================================
478 Standard_Boolean BRepTopAdaptor_TopolTool::DomainIsInfinite()
479{
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);
488}
489
490//=======================================================================
491//function : Has3d
492//purpose :
493//=======================================================================
494
495Standard_Boolean BRepTopAdaptor_TopolTool::Has3d() const
496{
497 return Standard_True;
498}
499
500//=======================================================================
501//function : Tol3d
502//purpose :
503//=======================================================================
504
505Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor2d_HCurve2d)& C) const
506{
507 Handle(BRepAdaptor_HCurve2d) brhc = Handle(BRepAdaptor_HCurve2d)::DownCast(C);
508 if (brhc.IsNull())
9775fa61 509 throw Standard_DomainError("BRepTopAdaptor_TopolTool: arc has no 3d representation");
7fd59977 510 const BRepAdaptor_Curve2d& brc = (const BRepAdaptor_Curve2d &)brhc->Curve2d();
511 const TopoDS_Edge& edge = brc.Edge();
512 if (edge.IsNull())
9775fa61 513 throw Standard_DomainError("BRepTopAdaptor_TopolTool: arc has no 3d representation");
7fd59977 514 return BRep_Tool::Tolerance(edge);
515}
516
517//=======================================================================
518//function : Tol3d
519//purpose :
520//=======================================================================
521
522Standard_Real BRepTopAdaptor_TopolTool::Tol3d(const Handle(Adaptor3d_HVertex)& V) const
523{
524 Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
525 if (brhv.IsNull())
9775fa61 526 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
7fd59977 527 const TopoDS_Vertex& ver = brhv->Vertex();
528 if (ver.IsNull())
9775fa61 529 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
7fd59977 530 return BRep_Tool::Tolerance(ver);
531}
532
533//=======================================================================
534//function : Pnt
535//purpose :
536//=======================================================================
537
538gp_Pnt BRepTopAdaptor_TopolTool::Pnt(const Handle(Adaptor3d_HVertex)& V) const
539{
540 Handle(BRepTopAdaptor_HVertex) brhv = Handle(BRepTopAdaptor_HVertex)::DownCast(V);
541 if (brhv.IsNull())
9775fa61 542 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
7fd59977 543 const TopoDS_Vertex& ver = brhv->Vertex();
544 if (ver.IsNull())
9775fa61 545 throw Standard_DomainError("BRepTopAdaptor_TopolTool: vertex has no 3d representation");
7fd59977 546 return BRep_Tool::Pnt(ver);
547}