0027117: BRepClass3d_SolidClassifier doesn't take into account vertex/edge/face toler...
[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
42cf5bc1 19#include <Adaptor3d_HCurve.hxx>
20#include <Adaptor3d_HSurfaceTool.hxx>
7fd59977 21#include <Bnd_BoundSortBox.hxx>
42cf5bc1 22#include <Bnd_Box.hxx>
7fd59977 23#include <BRepAdaptor_HSurface.hxx>
7fd59977 24#include <BRepClass_FaceClassifier.hxx>
42cf5bc1 25#include <BRepTopAdaptor_TopolTool.hxx>
26#include <Geom_Line.hxx>
7fd59977 27#include <GeomAdaptor_Curve.hxx>
7fd59977 28#include <GeomAdaptor_HCurve.hxx>
42cf5bc1 29#include <gp_Lin.hxx>
30#include <gp_Pnt.hxx>
31#include <gp_Pnt2d.hxx>
32#include <IntCurvesFace_Intersector.hxx>
33#include <IntCurveSurface_HInter.hxx>
34#include <IntCurveSurface_IntersectionPoint.hxx>
35#include <IntCurveSurface_SequenceOfPnt.hxx>
7fd59977 36#include <IntCurveSurface_TheHCurveTool.hxx>
7fd59977 37#include <IntCurveSurface_ThePolygonOfHInter.hxx>
42cf5bc1 38#include <IntCurveSurface_ThePolyhedronOfHInter.hxx>
39#include <IntCurveSurface_ThePolyhedronToolOfHInter.hxx>
40#include <Intf_Tool.hxx>
41#include <TopAbs.hxx>
42#include <TopoDS_Face.hxx>
f85e7ddb 43#include <BRep_Tool.hxx>
44#include <TopoDS.hxx>
45#include <Geom2dAPI_ProjectPointOnCurve.hxx>
7d9b843c 46//=======================================================================
47//function : SurfaceType
48//purpose :
49//=======================================================================
50GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
51{
7fd59977 52 return(Adaptor3d_HSurfaceTool::GetType(Hsurface));
53}
7d9b843c 54//=======================================================================
55//function : IntCurvesFace_Intersector
56//purpose :
57//=======================================================================
7fd59977 58IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
a0258acd 59 const Standard_Real aTol,
58e14d59 60 const Standard_Boolean aRestr,
61 const Standard_Boolean UseBToler)
f85e7ddb 62
7fd59977 63:
7d9b843c 64 Tol(aTol),
65 done(Standard_False),
66 nbpnt(0),
67 PtrOnPolyhedron(NULL),
58e14d59 68 PtrOnBndBounding(NULL),
69 myUseBoundTol (UseBToler)
7fd59977 70{
71 BRepAdaptor_Surface surface;
72 face = Face;
a0258acd 73 surface.Initialize(Face, aRestr);
7fd59977 74 Hsurface = new BRepAdaptor_HSurface(surface);
75 myTopolTool = new BRepTopAdaptor_TopolTool(Hsurface);
76
77 GeomAbs_SurfaceType SurfaceType = Adaptor3d_HSurfaceTool::GetType(Hsurface);
78 if( (SurfaceType != GeomAbs_Plane)
79 && (SurfaceType != GeomAbs_Cylinder)
80 && (SurfaceType != GeomAbs_Cone)
81 && (SurfaceType != GeomAbs_Sphere)
82 && (SurfaceType != GeomAbs_Torus)) {
83 Standard_Integer nbsu,nbsv;
84 Standard_Real U0,V0,U1,V1;
85 U0 = Hsurface->FirstUParameter();
86 U1 = Hsurface->LastUParameter();
87 V0 = Hsurface->FirstVParameter();
88 V1 = Hsurface->LastVParameter();
6fb3418e 89
90 Standard_Real aURes = Hsurface->UResolution(1.0);
91 Standard_Real aVRes = Hsurface->VResolution(1.0);
92
93 // Checking correlation between number of samples and length of the face along each axis
94 const Standard_Real aTresh = 100.0;
95 const Standard_Integer aMinSamples = 10;
96 const Standard_Integer aMaxSamples = 40;
97 const Standard_Integer aMaxSamples2 = aMaxSamples * aMaxSamples;
98 Standard_Real dU = (U1 - U0) / aURes;
99 Standard_Real dV = (V1 - V0) / aVRes;
100 nbsu = myTopolTool->NbSamplesU();
101 nbsv = myTopolTool->NbSamplesV();
102 if (nbsu > aMaxSamples) nbsu = aMaxSamples;
103 if (nbsv > aMaxSamples) nbsv = aMaxSamples;
104
105 if (Max(dU, dV) > Min(dU, dV) * aTresh)
7d9b843c 106 {
6fb3418e 107 nbsu = (Standard_Integer)(Sqrt(dU / dV) * aMaxSamples);
108 if (nbsu < aMinSamples) nbsu = aMinSamples;
109 nbsv = aMaxSamples2 / nbsu;
110 if (nbsv < aMinSamples)
111 {
112 nbsv = aMinSamples;
113 nbsu = aMaxSamples2 / aMinSamples;
7d9b843c 114 }
7d9b843c 115 }
6fb3418e 116 PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
117 new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
7fd59977 118 }
119}
7d9b843c 120//=======================================================================
121//function : InternalCall
122//purpose :
123//=======================================================================
7fd59977 124void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
7d9b843c 125 const Standard_Real parinf,
126 const Standard_Real parsup)
127{
f85e7ddb 128 if(HICS.IsDone() && HICS.NbPoints() > 0) {
129 //Calculate tolerance for 2d classifier
130 Standard_Real mintol3d = BRep_Tool::Tolerance(face);
131 Standard_Real maxtol3d = mintol3d;
132 Standard_Real mintol2d = Tol, maxtol2d = Tol;
133 TopExp_Explorer anExp(face, TopAbs_EDGE);
134 for(; anExp.More(); anExp.Next())
135 {
136 Standard_Real curtol = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Current()));
137 mintol3d = Min(mintol3d, curtol);
138 maxtol3d = Max(maxtol3d, curtol);
139 }
140 Standard_Real minres = Max(Hsurface->UResolution(mintol3d), Hsurface->VResolution(mintol3d));
141 Standard_Real maxres = Max(Hsurface->UResolution(maxtol3d), Hsurface->VResolution(maxtol3d));
142 mintol2d = Max(minres, Tol);
143 maxtol2d = Max(maxres, Tol);
144 //
145 Handle(BRepTopAdaptor_TopolTool) anAdditionalTool;
7fd59977 146 for(Standard_Integer index=HICS.NbPoints(); index>=1; index--) {
147 const IntCurveSurface_IntersectionPoint& HICSPointindex = HICS.Point(index);
148 gp_Pnt2d Puv(HICSPointindex.U(),HICSPointindex.V());
f85e7ddb 149
150 //TopAbs_State currentstate = myTopolTool->Classify(Puv,Tol);
58e14d59 151 TopAbs_State currentstate = myTopolTool->Classify(Puv, !myUseBoundTol ? 0 : mintol2d);
152 if(myUseBoundTol && currentstate == TopAbs_OUT && maxtol2d > mintol2d) {
f85e7ddb 153 if(anAdditionalTool.IsNull())
154 {
155 anAdditionalTool = new BRepTopAdaptor_TopolTool(Hsurface);
156 }
157 currentstate = anAdditionalTool->Classify(Puv,maxtol2d);
158 if(currentstate == TopAbs_ON)
159 {
160 currentstate = TopAbs_OUT;
161 //Find out nearest edge and it's tolerance
162 anExp.Init(face, TopAbs_EDGE);
163 for(; anExp.More(); anExp.Next())
164 {
165 TopoDS_Edge anE = TopoDS::Edge(anExp.Current());
166 Standard_Real curtol = BRep_Tool::Tolerance(anE);
167 Standard_Real tol2d = Max(Hsurface->UResolution(curtol), Hsurface->VResolution(curtol));
168 tol2d = Max(tol2d, Tol);
169 Standard_Real f, l;
170 Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(anE, face, f, l);
171 Geom2dAPI_ProjectPointOnCurve aProj(Puv, aPC, f, l);
172 if(aProj.NbPoints() > 0)
173 {
174 Standard_Real d = aProj.LowerDistance();
175 if(d <= tol2d)
176 {
177 //Nearest edge is found, state is really ON
178 currentstate = TopAbs_ON;
179 break;
180 }
181 }
182 }
183 }
184 }
7fd59977 185 if(currentstate==TopAbs_IN || currentstate==TopAbs_ON) {
f85e7ddb 186 Standard_Real HICSW = HICSPointindex.W();
187 if(HICSW >= parinf && HICSW <= parsup ) {
188 Standard_Real U = HICSPointindex.U();
189 Standard_Real V = HICSPointindex.V();
190 Standard_Real W = HICSW;
191 IntCurveSurface_TransitionOnCurve transition = HICSPointindex.Transition();
192 gp_Pnt pnt = HICSPointindex.Pnt();
193 // state = currentstate;
194 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
195 Standard_Integer anIntState = (currentstate == TopAbs_IN) ? 0 : 1;
196 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
197
198 if(transition != IntCurveSurface_Tangent && face.Orientation()==TopAbs_REVERSED) {
199 if(transition == IntCurveSurface_In)
200 transition = IntCurveSurface_Out;
201 else
202 transition = IntCurveSurface_In;
203 }
204 //----- Insertion du point
205 if(nbpnt==0) {
206 IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
207 SeqPnt.Append(PPP);
208 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
209 mySeqState.Append(anIntState);
210 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
211 }
212 else {
213 Standard_Integer i = 1;
214 Standard_Integer b = nbpnt+1;
215 while(i<=nbpnt) {
216 const IntCurveSurface_IntersectionPoint& Pnti=SeqPnt.Value(i);
217 Standard_Real wi = Pnti.W();
218 if(wi >= W) { b=i; i=nbpnt; }
219 i++;
220 }
221 IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
222 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
223 // if(b>nbpnt) { SeqPnt.Append(PPP); }
224 // else if(b>0) { SeqPnt.InsertBefore(b,PPP); }
225 if(b>nbpnt) {
226 SeqPnt.Append(PPP);
227 mySeqState.Append(anIntState);
228 } else if(b>0) {
229 SeqPnt.InsertBefore(b,PPP);
230 mySeqState.InsertBefore(b, anIntState);
231 }
232 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
233 }
7fd59977 234
7fd59977 235
f85e7ddb 236 nbpnt++;
237 }
7fd59977 238 } //-- classifier state is IN or ON
239 } //-- Loop on Intersection points.
240 } //-- HICS.IsDone()
241}
7d9b843c 242//=======================================================================
243//function : Perform
244//purpose :
245//=======================================================================
246void IntCurvesFace_Intersector::Perform(const gp_Lin& L,
247 const Standard_Real ParMin,
248 const Standard_Real ParMax)
249{
7fd59977 250 done = Standard_True;
251 SeqPnt.Clear();
7fd59977 252 mySeqState.Clear();
7fd59977 253 nbpnt = 0;
7fd59977 254
7d9b843c 255 IntCurveSurface_HInter HICS;
7fd59977 256 Handle(Geom_Line) geomline = new Geom_Line(L);
257 GeomAdaptor_Curve LL(geomline);
7fd59977 258 Handle(GeomAdaptor_HCurve) HLL = new GeomAdaptor_HCurve(LL);
7fd59977 259 Standard_Real parinf=ParMin;
260 Standard_Real parsup=ParMax;
7d9b843c 261 //
7fd59977 262 if(PtrOnPolyhedron == NULL) {
263 HICS.Perform(HLL,Hsurface);
264 }
265 else {
7d9b843c 266 Intf_Tool bndTool;
267 Bnd_Box boxLine;
268 bndTool.LinBox
269 (L,
270 ((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron)->Bounding(),
271 boxLine);
7fd59977 272 if(bndTool.NbSegments() == 0)
273 return;
274 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
275 Standard_Real pinf = bndTool.BeginParam(nbseg);
276 Standard_Real psup = bndTool.EndParam(nbseg);
277 Standard_Real pppp = 0.05*(psup-pinf);
278 pinf-=pppp;
279 psup+=pppp;
280 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; }
281 if(nbseg==1) { parinf=pinf; parsup=psup; }
282 else {
283 if(parinf>pinf) parinf = pinf;
284 if(parsup<psup) parsup = psup;
285 }
286 }
287 if(parinf>ParMax) { return; }
288 if(parsup<ParMin) { return; }
289 if(parinf<ParMin) parinf=ParMin;
290 if(parsup>ParMax) parsup=ParMax;
291 if(parinf>(parsup-1e-9)) return;
292 IntCurveSurface_ThePolygonOfHInter polygon(HLL,
293 parinf,
294 parsup,
295 2);
296#if OPTIMISATION
297 if(PtrOnBndBounding==NULL) {
298 PtrOnBndBounding = (Bnd_BoundSortBox *) new Bnd_BoundSortBox();
7d9b843c 299 IntCurveSurface_ThePolyhedronOfHInter *thePolyh=
300 (IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
301 ((Bnd_BoundSortBox *)(PtrOnBndBounding))->
302 Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*thePolyh),
303 IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*thePolyh));
7fd59977 304 }
305 HICS.Perform(HLL,
306 polygon,
307 Hsurface,
308 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron),
309 *((Bnd_BoundSortBox *)PtrOnBndBounding));
310#else
311 HICS.Perform(HLL,
312 polygon,
313 Hsurface,
314 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron));
315#endif
316 }
317
318 InternalCall(HICS,parinf,parsup);
7fd59977 319}
7d9b843c 320//=======================================================================
321//function : Perform
322//purpose :
323//=======================================================================
324void IntCurvesFace_Intersector::Perform(const Handle(Adaptor3d_HCurve)& HCu,
325 const Standard_Real ParMin,
326 const Standard_Real ParMax)
327{
7fd59977 328 done = Standard_True;
329 SeqPnt.Clear();
330 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
331 mySeqState.Clear();
332 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
333 nbpnt = 0;
334 IntCurveSurface_HInter HICS;
335
336 //--
337 Standard_Real parinf=ParMin;
338 Standard_Real parsup=ParMax;
339
340 if(PtrOnPolyhedron == NULL) {
341 HICS.Perform(HCu,Hsurface);
342 }
343 else {
344 parinf = IntCurveSurface_TheHCurveTool::FirstParameter(HCu);
345 parsup = IntCurveSurface_TheHCurveTool::LastParameter(HCu);
346 if(parinf<ParMin) parinf = ParMin;
347 if(parsup>ParMax) parsup = ParMax;
348 if(parinf>(parsup-1e-9)) return;
349 Standard_Integer nbs;
350 nbs = IntCurveSurface_TheHCurveTool::NbSamples(HCu,parinf,parsup);
351
352 IntCurveSurface_ThePolygonOfHInter polygon(HCu,
353 parinf,
354 parsup,
355 nbs);
356#if OPTIMISATION
357 if(PtrOnBndBounding==NULL) {
358 PtrOnBndBounding = (Bnd_BoundSortBox *) new Bnd_BoundSortBox();
359 IntCurveSurface_ThePolyhedronOfHInter *thePolyh=(IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
360 ((Bnd_BoundSortBox *)(PtrOnBndBounding))->Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*thePolyh),
361 IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*thePolyh));
362 }
363 HICS.Perform(HCu,
364 polygon,
365 Hsurface,
366 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron),
367 *((Bnd_BoundSortBox *)PtrOnBndBounding));
368#else
369 HICS.Perform(HCu,
370 polygon,
371 Hsurface,
372 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron));
373#endif
374 }
375 InternalCall(HICS,parinf,parsup);
376}
377
378//============================================================================
379Bnd_Box IntCurvesFace_Intersector::Bounding() const {
380 if(PtrOnPolyhedron !=NULL) {
381 return(((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron)->Bounding());
382 }
383 else {
384 Bnd_Box B;
385 return(B);
386 }
387}
388TopAbs_State IntCurvesFace_Intersector::ClassifyUVPoint(const gp_Pnt2d& Puv) const {
389 TopAbs_State state = myTopolTool->Classify(Puv,1e-7);
390 return(state);
391}
392//============================================================================
393void IntCurvesFace_Intersector::Destroy() {
394 if(PtrOnPolyhedron !=NULL) {
395 delete (IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
396 PtrOnPolyhedron = NULL;
397 }
398 if(PtrOnBndBounding !=NULL) {
399 delete (Bnd_BoundSortBox *)PtrOnBndBounding;
400 PtrOnBndBounding=NULL;
401 }
402}
403
58e14d59 404 void IntCurvesFace_Intersector::SetUseBoundToler(Standard_Boolean UseBToler)
405 {
406 myUseBoundTol = UseBToler;
407 }
7fd59977 408
58e14d59 409 Standard_Boolean IntCurvesFace_Intersector::GetUseBoundToler() const
410 {
411 return myUseBoundTol;
412 }
7fd59977 413