0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / IntCurvesFace / IntCurvesFace_Intersector.cxx
CommitLineData
b311480e 1// Created on: 1996-06-03
2// Created by: Laurent BUCHARD
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#define OPTIMISATION 1
18
c22b52d6 19#include <IntCurvesFace_Intersector.hxx>
20
21#include <Adaptor3d_Curve.hxx>
42cf5bc1 22#include <Adaptor3d_HSurfaceTool.hxx>
7fd59977 23#include <Bnd_BoundSortBox.hxx>
42cf5bc1 24#include <Bnd_Box.hxx>
c22b52d6 25#include <BRepAdaptor_Surface.hxx>
42cf5bc1 26#include <BRepTopAdaptor_TopolTool.hxx>
27#include <Geom_Line.hxx>
42cf5bc1 28#include <gp_Lin.hxx>
29#include <gp_Pnt.hxx>
30#include <gp_Pnt2d.hxx>
42cf5bc1 31#include <IntCurveSurface_HInter.hxx>
32#include <IntCurveSurface_IntersectionPoint.hxx>
7fd59977 33#include <IntCurveSurface_TheHCurveTool.hxx>
7fd59977 34#include <IntCurveSurface_ThePolygonOfHInter.hxx>
42cf5bc1 35#include <IntCurveSurface_ThePolyhedronToolOfHInter.hxx>
36#include <Intf_Tool.hxx>
42cf5bc1 37#include <TopoDS_Face.hxx>
f85e7ddb 38#include <BRep_Tool.hxx>
39#include <TopoDS.hxx>
3dd193aa 40#include <GeomAPI_ProjectPointOnCurve.hxx>
1f000e59
A
41
42IMPLEMENT_STANDARD_RTTIEXT(IntCurvesFace_Intersector, Standard_Transient)
43
f24f5428 44//
c22b52d6 45static void ComputeSamplePars(const Handle(Adaptor3d_Surface)& Hsurface,
f24f5428 46 const Standard_Integer nbsu,
47 const Standard_Integer nbsv,
48 Handle(TColStd_HArray1OfReal)& UPars,
49 Handle(TColStd_HArray1OfReal)& VPars)
50{
51 Standard_Integer NbUInts = Hsurface->NbUIntervals(GeomAbs_C2);
52 Standard_Integer NbVInts = Hsurface->NbVIntervals(GeomAbs_C2);
53 TColStd_Array1OfReal UInts(1, NbUInts + 1);
54 TColStd_Array1OfReal VInts(1, NbVInts + 1);
55 Hsurface->UIntervals(UInts, GeomAbs_C2);
56 Hsurface->VIntervals(VInts, GeomAbs_C2);
57 //
58 TColStd_Array1OfInteger NbUSubInts(1, NbUInts);
59 TColStd_Array1OfInteger NbVSubInts(1, NbVInts);
60 //
61 Standard_Integer i, j, ind, NbU, NbV;
62 Standard_Real t, dt;
63 t = UInts(NbUInts + 1) - UInts(1);
64 t = 1. / t;
65 NbU = 0;
66 for(i = 1; i <= NbUInts; ++i)
67 {
68 dt = (UInts(i+1) - UInts(i));
69 NbUSubInts(i) = RealToInt(nbsu * dt * t) + 1;
70 NbU += NbUSubInts(i);
71 }
72 t = VInts(NbVInts + 1) - VInts(1);
73 t = 1. / t;
74 NbV = 0;
75 for(i = 1; i <= NbVInts; ++i)
76 {
77 dt = (VInts(i+1) - VInts(i));
78 NbVSubInts(i) = RealToInt(nbsv * dt * t) + 1;
79 NbV += NbVSubInts(i);
80 }
81 UPars = new TColStd_HArray1OfReal(1, NbU + 1);
82 VPars = new TColStd_HArray1OfReal(1, NbV + 1);
83 //
84 ind = 1;
85 for(i = 1; i <= NbUInts; ++i)
86 {
87 UPars->SetValue(ind++, UInts(i));
88 dt = (UInts(i+1) - UInts(i)) / NbUSubInts(i);
89 t = UInts(i);
90 for(j = 1; j < NbUSubInts(i); ++j)
91 {
92 t += dt;
93 UPars->SetValue(ind++, t);
94 }
95 }
96 UPars->SetValue(ind, UInts(NbUInts + 1));
97 //
98 ind = 1;
99 for(i = 1; i <= NbVInts; ++i)
100 {
101 VPars->SetValue(ind++, VInts(i));
102 dt = (VInts(i+1) - VInts(i)) / NbVSubInts(i);
103 t = VInts(i);
104 for(j = 1; j < NbVSubInts(i); ++j)
105 {
106 t += dt;
107 VPars->SetValue(ind++, t);
108 }
109 }
110 VPars->SetValue(ind, VInts(NbVInts + 1));
111}
112//
7d9b843c 113//=======================================================================
114//function : SurfaceType
115//purpose :
116//=======================================================================
117GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
118{
7fd59977 119 return(Adaptor3d_HSurfaceTool::GetType(Hsurface));
120}
7d9b843c 121//=======================================================================
122//function : IntCurvesFace_Intersector
123//purpose :
124//=======================================================================
7fd59977 125IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
a0258acd 126 const Standard_Real aTol,
58e14d59 127 const Standard_Boolean aRestr,
128 const Standard_Boolean UseBToler)
f85e7ddb 129
7fd59977 130:
7d9b843c 131 Tol(aTol),
132 done(Standard_False),
e8dec5e1 133 myReady(Standard_False),
7d9b843c 134 nbpnt(0),
f84edf58 135 myUseBoundTol (UseBToler),
136 myIsParallel(Standard_False)
7fd59977 137{
138 BRepAdaptor_Surface surface;
139 face = Face;
a0258acd 140 surface.Initialize(Face, aRestr);
c22b52d6 141 Hsurface = new BRepAdaptor_Surface(surface);
7fd59977 142 myTopolTool = new BRepTopAdaptor_TopolTool(Hsurface);
143
144 GeomAbs_SurfaceType SurfaceType = Adaptor3d_HSurfaceTool::GetType(Hsurface);
145 if( (SurfaceType != GeomAbs_Plane)
146 && (SurfaceType != GeomAbs_Cylinder)
147 && (SurfaceType != GeomAbs_Cone)
148 && (SurfaceType != GeomAbs_Sphere)
149 && (SurfaceType != GeomAbs_Torus)) {
150 Standard_Integer nbsu,nbsv;
151 Standard_Real U0,V0,U1,V1;
152 U0 = Hsurface->FirstUParameter();
153 U1 = Hsurface->LastUParameter();
154 V0 = Hsurface->FirstVParameter();
155 V1 = Hsurface->LastVParameter();
f24f5428 156 //
157 nbsu = myTopolTool->NbSamplesU();
158 nbsv = myTopolTool->NbSamplesV();
159 //
6fb3418e 160 Standard_Real aURes = Hsurface->UResolution(1.0);
161 Standard_Real aVRes = Hsurface->VResolution(1.0);
162
163 // Checking correlation between number of samples and length of the face along each axis
164 const Standard_Real aTresh = 100.0;
f24f5428 165 Standard_Integer aMinSamples = 20;
6fb3418e 166 const Standard_Integer aMaxSamples = 40;
167 const Standard_Integer aMaxSamples2 = aMaxSamples * aMaxSamples;
168 Standard_Real dU = (U1 - U0) / aURes;
169 Standard_Real dV = (V1 - V0) / aVRes;
f24f5428 170 if (nbsu < aMinSamples) nbsu = aMinSamples;
171 if (nbsv < aMinSamples) nbsv = aMinSamples;
6fb3418e 172 if (nbsu > aMaxSamples) nbsu = aMaxSamples;
173 if (nbsv > aMaxSamples) nbsv = aMaxSamples;
174
e8dec5e1 175 if (dU > Precision::Confusion() && dV > Precision::Confusion()) {
73375359 176 if (Max(dU, dV) > Min(dU, dV) * aTresh)
6fb3418e 177 {
73375359 178 aMinSamples = 10;
179 nbsu = (Standard_Integer)(Sqrt(dU / dV) * aMaxSamples);
180 if (nbsu < aMinSamples) nbsu = aMinSamples;
181 nbsv = aMaxSamples2 / nbsu;
182 if (nbsv < aMinSamples)
183 {
184 nbsv = aMinSamples;
185 nbsu = aMaxSamples2 / aMinSamples;
186 }
187 }
188 }
189 else {
e8dec5e1 190 return; // surface has no extension along one of directions
7d9b843c 191 }
f24f5428 192
193 Standard_Integer NbUOnS = Hsurface->NbUIntervals(GeomAbs_C2);
194 Standard_Integer NbVOnS = Hsurface->NbVIntervals(GeomAbs_C2);
195
196 if(NbUOnS > 1 || NbVOnS > 1)
197 {
198 Handle(TColStd_HArray1OfReal) UPars, VPars;
199 ComputeSamplePars(Hsurface, nbsu, nbsv, UPars, VPars);
1f000e59
A
200 myPolyhedron.reset(new IntCurveSurface_ThePolyhedronOfHInter(Hsurface, UPars->ChangeArray1(),
201 VPars->ChangeArray1()));
f24f5428 202 }
203 else
204 {
1f000e59 205 myPolyhedron.reset(new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1));
f24f5428 206 }
7fd59977 207 }
e8dec5e1 208 myReady = Standard_True;
7fd59977 209}
7d9b843c 210//=======================================================================
211//function : InternalCall
212//purpose :
213//=======================================================================
7fd59977 214void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
1f000e59
A
215 const Standard_Real parinf,
216 const Standard_Real parsup)
7d9b843c 217{
f85e7ddb 218 if(HICS.IsDone() && HICS.NbPoints() > 0) {
219 //Calculate tolerance for 2d classifier
220 Standard_Real mintol3d = BRep_Tool::Tolerance(face);
221 Standard_Real maxtol3d = mintol3d;
222 Standard_Real mintol2d = Tol, maxtol2d = Tol;
223 TopExp_Explorer anExp(face, TopAbs_EDGE);
224 for(; anExp.More(); anExp.Next())
225 {
226 Standard_Real curtol = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Current()));
227 mintol3d = Min(mintol3d, curtol);
228 maxtol3d = Max(maxtol3d, curtol);
229 }
230 Standard_Real minres = Max(Hsurface->UResolution(mintol3d), Hsurface->VResolution(mintol3d));
231 Standard_Real maxres = Max(Hsurface->UResolution(maxtol3d), Hsurface->VResolution(maxtol3d));
232 mintol2d = Max(minres, Tol);
233 maxtol2d = Max(maxres, Tol);
234 //
235 Handle(BRepTopAdaptor_TopolTool) anAdditionalTool;
7fd59977 236 for(Standard_Integer index=HICS.NbPoints(); index>=1; index--) {
237 const IntCurveSurface_IntersectionPoint& HICSPointindex = HICS.Point(index);
238 gp_Pnt2d Puv(HICSPointindex.U(),HICSPointindex.V());
f85e7ddb 239
240 //TopAbs_State currentstate = myTopolTool->Classify(Puv,Tol);
58e14d59 241 TopAbs_State currentstate = myTopolTool->Classify(Puv, !myUseBoundTol ? 0 : mintol2d);
242 if(myUseBoundTol && currentstate == TopAbs_OUT && maxtol2d > mintol2d) {
f85e7ddb 243 if(anAdditionalTool.IsNull())
244 {
245 anAdditionalTool = new BRepTopAdaptor_TopolTool(Hsurface);
246 }
247 currentstate = anAdditionalTool->Classify(Puv,maxtol2d);
248 if(currentstate == TopAbs_ON)
249 {
250 currentstate = TopAbs_OUT;
251 //Find out nearest edge and it's tolerance
252 anExp.Init(face, TopAbs_EDGE);
253 for(; anExp.More(); anExp.Next())
254 {
255 TopoDS_Edge anE = TopoDS::Edge(anExp.Current());
f85e7ddb 256 Standard_Real f, l;
3dd193aa 257 Handle(Geom_Curve) aPC = BRep_Tool::Curve (anE, f, l);
258 GeomAPI_ProjectPointOnCurve aProj (HICSPointindex.Pnt(), aPC, f, l);
259 if (aProj.NbPoints() > 0)
f85e7ddb 260 {
3dd193aa 261 if (aProj.LowerDistance() <= maxtol3d)
f85e7ddb 262 {
263 //Nearest edge is found, state is really ON
264 currentstate = TopAbs_ON;
265 break;
266 }
267 }
268 }
269 }
270 }
7fd59977 271 if(currentstate==TopAbs_IN || currentstate==TopAbs_ON) {
f85e7ddb 272 Standard_Real HICSW = HICSPointindex.W();
273 if(HICSW >= parinf && HICSW <= parsup ) {
274 Standard_Real U = HICSPointindex.U();
275 Standard_Real V = HICSPointindex.V();
276 Standard_Real W = HICSW;
277 IntCurveSurface_TransitionOnCurve transition = HICSPointindex.Transition();
278 gp_Pnt pnt = HICSPointindex.Pnt();
f85e7ddb 279 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
280 Standard_Integer anIntState = (currentstate == TopAbs_IN) ? 0 : 1;
281 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
282
283 if(transition != IntCurveSurface_Tangent && face.Orientation()==TopAbs_REVERSED) {
284 if(transition == IntCurveSurface_In)
285 transition = IntCurveSurface_Out;
286 else
287 transition = IntCurveSurface_In;
288 }
289 //----- Insertion du point
290 if(nbpnt==0) {
291 IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
292 SeqPnt.Append(PPP);
293 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
294 mySeqState.Append(anIntState);
295 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
296 }
297 else {
298 Standard_Integer i = 1;
299 Standard_Integer b = nbpnt+1;
300 while(i<=nbpnt) {
301 const IntCurveSurface_IntersectionPoint& Pnti=SeqPnt.Value(i);
302 Standard_Real wi = Pnti.W();
303 if(wi >= W) { b=i; i=nbpnt; }
304 i++;
305 }
306 IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
307 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
308 // if(b>nbpnt) { SeqPnt.Append(PPP); }
309 // else if(b>0) { SeqPnt.InsertBefore(b,PPP); }
310 if(b>nbpnt) {
311 SeqPnt.Append(PPP);
312 mySeqState.Append(anIntState);
313 } else if(b>0) {
314 SeqPnt.InsertBefore(b,PPP);
315 mySeqState.InsertBefore(b, anIntState);
316 }
317 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
318 }
7fd59977 319
7fd59977 320
f85e7ddb 321 nbpnt++;
322 }
7fd59977 323 } //-- classifier state is IN or ON
324 } //-- Loop on Intersection points.
325 } //-- HICS.IsDone()
f84edf58 326 else if (HICS.IsDone())
327 {
328 myIsParallel = HICS.IsParallel();
329 }
7fd59977 330}
7d9b843c 331//=======================================================================
332//function : Perform
333//purpose :
334//=======================================================================
335void IntCurvesFace_Intersector::Perform(const gp_Lin& L,
1f000e59
A
336 const Standard_Real ParMin,
337 const Standard_Real ParMax)
7d9b843c 338{
e8dec5e1 339 done = Standard_False;
340 if (!myReady)
341 {
342 return;
343 }
7fd59977 344 done = Standard_True;
345 SeqPnt.Clear();
7fd59977 346 mySeqState.Clear();
7fd59977 347 nbpnt = 0;
7fd59977 348
7d9b843c 349 IntCurveSurface_HInter HICS;
7fd59977 350 Handle(Geom_Line) geomline = new Geom_Line(L);
351 GeomAdaptor_Curve LL(geomline);
c22b52d6 352 Handle(GeomAdaptor_Curve) HLL = new GeomAdaptor_Curve(LL);
7fd59977 353 Standard_Real parinf=ParMin;
354 Standard_Real parsup=ParMax;
7d9b843c 355 //
1f000e59 356 if(!myPolyhedron) {
7fd59977 357 HICS.Perform(HLL,Hsurface);
358 }
359 else {
7d9b843c 360 Intf_Tool bndTool;
361 Bnd_Box boxLine;
362 bndTool.LinBox
363 (L,
1f000e59 364 myPolyhedron->Bounding(),
7d9b843c 365 boxLine);
7fd59977 366 if(bndTool.NbSegments() == 0)
367 return;
368 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
369 Standard_Real pinf = bndTool.BeginParam(nbseg);
370 Standard_Real psup = bndTool.EndParam(nbseg);
371 Standard_Real pppp = 0.05*(psup-pinf);
372 pinf-=pppp;
373 psup+=pppp;
374 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; }
375 if(nbseg==1) { parinf=pinf; parsup=psup; }
376 else {
1f000e59
A
377 if(parinf>pinf) parinf = pinf;
378 if(parsup<psup) parsup = psup;
7fd59977 379 }
380 }
381 if(parinf>ParMax) { return; }
382 if(parsup<ParMin) { return; }
383 if(parinf<ParMin) parinf=ParMin;
384 if(parsup>ParMax) parsup=ParMax;
385 if(parinf>(parsup-1e-9)) return;
386 IntCurveSurface_ThePolygonOfHInter polygon(HLL,
1f000e59
A
387 parinf,
388 parsup,
389 2);
7fd59977 390#if OPTIMISATION
1f000e59
A
391 if(!myBndBounding)
392 {
393 myBndBounding.reset(new Bnd_BoundSortBox());
394 myBndBounding->Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*myPolyhedron),
395 IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*myPolyhedron));
7fd59977 396 }
397 HICS.Perform(HLL,
1f000e59
A
398 polygon,
399 Hsurface,
400 *myPolyhedron,
401 *myBndBounding);
7fd59977 402#else
403 HICS.Perform(HLL,
1f000e59
A
404 polygon,
405 Hsurface,
406 *myPolyhedron);
7fd59977 407#endif
408 }
409
410 InternalCall(HICS,parinf,parsup);
7fd59977 411}
7d9b843c 412//=======================================================================
413//function : Perform
414//purpose :
415//=======================================================================
c22b52d6 416void IntCurvesFace_Intersector::Perform(const Handle(Adaptor3d_Curve)& HCu,
1f000e59
A
417 const Standard_Real ParMin,
418 const Standard_Real ParMax)
7d9b843c 419{
e8dec5e1 420 done = Standard_False;
421 if (!myReady)
422 {
423 return;
424 }
7fd59977 425 done = Standard_True;
426 SeqPnt.Clear();
427 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
428 mySeqState.Clear();
429 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
430 nbpnt = 0;
431 IntCurveSurface_HInter HICS;
432
433 //--
434 Standard_Real parinf=ParMin;
435 Standard_Real parsup=ParMax;
436
1f000e59
A
437 if(!myPolyhedron)
438 {
7fd59977 439 HICS.Perform(HCu,Hsurface);
440 }
1f000e59
A
441 else
442 {
7fd59977 443 parinf = IntCurveSurface_TheHCurveTool::FirstParameter(HCu);
444 parsup = IntCurveSurface_TheHCurveTool::LastParameter(HCu);
445 if(parinf<ParMin) parinf = ParMin;
446 if(parsup>ParMax) parsup = ParMax;
447 if(parinf>(parsup-1e-9)) return;
448 Standard_Integer nbs;
449 nbs = IntCurveSurface_TheHCurveTool::NbSamples(HCu,parinf,parsup);
450
451 IntCurveSurface_ThePolygonOfHInter polygon(HCu,
1f000e59
A
452 parinf,
453 parsup,
454 nbs);
7fd59977 455#if OPTIMISATION
1f000e59
A
456 if(!myBndBounding) {
457 myBndBounding.reset(new Bnd_BoundSortBox());
458 myBndBounding->Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*myPolyhedron),
459 IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*myPolyhedron));
7fd59977 460 }
461 HICS.Perform(HCu,
1f000e59
A
462 polygon,
463 Hsurface,
464 *myPolyhedron,
465 *myBndBounding);
7fd59977 466#else
467 HICS.Perform(HCu,
1f000e59
A
468 polygon,
469 Hsurface,
470 *myPolyhedron);
7fd59977 471#endif
472 }
473 InternalCall(HICS,parinf,parsup);
474}
475
476//============================================================================
477Bnd_Box IntCurvesFace_Intersector::Bounding() const {
1f000e59
A
478 if(myPolyhedron)
479 {
480 return myPolyhedron->Bounding();
7fd59977 481 }
1f000e59
A
482 else
483 {
7fd59977 484 Bnd_Box B;
1f000e59 485 return B;
7fd59977 486 }
487}
1f000e59
A
488
489TopAbs_State IntCurvesFace_Intersector::ClassifyUVPoint(const gp_Pnt2d& Puv) const
490{
7fd59977 491 TopAbs_State state = myTopolTool->Classify(Puv,1e-7);
1f000e59 492 return state;
7fd59977 493}
494
1f000e59
A
495void IntCurvesFace_Intersector::SetUseBoundToler(Standard_Boolean UseBToler)
496{
497 myUseBoundTol = UseBToler;
498}
7fd59977 499
1f000e59
A
500Standard_Boolean IntCurvesFace_Intersector::GetUseBoundToler() const
501{
502 return myUseBoundTol;
503}
7fd59977 504
1f000e59
A
505IntCurvesFace_Intersector::~IntCurvesFace_Intersector()
506{
507}