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