0023089: Wrong result done by solid classifier algorithm
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22
7d9b843c 23
7fd59977 24
25
26#define OPTIMISATION 1
27
28
29#include <IntCurvesFace_Intersector.ixx>
30
31#include <IntCurveSurface_ThePolyhedronToolOfHInter.hxx>
32#include <Bnd_BoundSortBox.hxx>
33
34#include <IntCurveSurface_IntersectionPoint.hxx>
35#include <gp_Lin.hxx>
36#include <TopoDS_Face.hxx>
37#include <TopAbs.hxx>
38
39
40#include <IntCurveSurface_HInter.hxx>
41#include <BRepAdaptor_HSurface.hxx>
42#include <Geom_Line.hxx>
43#include <gp_Pnt2d.hxx>
44#include <BRepClass_FaceClassifier.hxx>
45
46#include <GeomAdaptor_Curve.hxx>
47
48#include <GeomAdaptor_HCurve.hxx>
49#include <BRepAdaptor_HSurface.hxx>
50
51
52
53#include <Adaptor3d_HSurfaceTool.hxx>
54#include <IntCurveSurface_TheHCurveTool.hxx>
55#include <Adaptor3d_HCurve.hxx>
56#include <Bnd_Box.hxx>
57#include <Intf_Tool.hxx>
58#include <IntCurveSurface_ThePolyhedronOfHInter.hxx>
59#include <IntCurveSurface_ThePolygonOfHInter.hxx>
60#include <IntCurveSurface_SequenceOfPnt.hxx>
61
62
63
7d9b843c 64//=======================================================================
65//function : SurfaceType
66//purpose :
67//=======================================================================
68GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
69{
7fd59977 70 return(Adaptor3d_HSurfaceTool::GetType(Hsurface));
71}
7d9b843c 72//=======================================================================
73//function : IntCurvesFace_Intersector
74//purpose :
75//=======================================================================
7fd59977 76IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
77 const Standard_Real aTol)
78:
7d9b843c 79 Tol(aTol),
80 done(Standard_False),
81 nbpnt(0),
82 PtrOnPolyhedron(NULL),
83 PtrOnBndBounding(NULL)
7fd59977 84{
85 BRepAdaptor_Surface surface;
86 face = Face;
87 surface.Initialize(Face,Standard_True);
88 Hsurface = new BRepAdaptor_HSurface(surface);
89 myTopolTool = new BRepTopAdaptor_TopolTool(Hsurface);
90
91 GeomAbs_SurfaceType SurfaceType = Adaptor3d_HSurfaceTool::GetType(Hsurface);
92 if( (SurfaceType != GeomAbs_Plane)
93 && (SurfaceType != GeomAbs_Cylinder)
94 && (SurfaceType != GeomAbs_Cone)
95 && (SurfaceType != GeomAbs_Sphere)
96 && (SurfaceType != GeomAbs_Torus)) {
97 Standard_Integer nbsu,nbsv;
98 Standard_Real U0,V0,U1,V1;
99 U0 = Hsurface->FirstUParameter();
100 U1 = Hsurface->LastUParameter();
101 V0 = Hsurface->FirstVParameter();
102 V1 = Hsurface->LastVParameter();
7d9b843c 103 //modified by NIZNHY-PKV Fri Apr 06 07:30:47 2012f
104 Standard_Boolean bFlag;
105 //
106 {
107 Standard_Real dU, dV, dA, dB, aR, aTresh;
108 bFlag=Standard_True;
109 //
110 aTresh=100.;
111 dU=U1-U0;
112 dV=V1-V0;
113 dA=dU;
114 dB=dV;
115 if (dV>dU) {
116 dA=dV;
117 dB=dU;
118 }
119 //
120 aR=dA/dB;
121 if (dB<Precision::PConfusion()) {
122 bFlag=!bFlag;
123 }
124 else {
125 if (aR>aTresh) {
126 bFlag=!bFlag;
127 }
128 }
129 }
130 //
131 if (bFlag) {
132 nbsu = myTopolTool->NbSamplesU();
133 nbsv = myTopolTool->NbSamplesV();
134 if(nbsu>40) nbsu = 40;
135 if(nbsv>40) nbsv = 40;
136 PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
137 new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
138 }
139 //
140 /*
7fd59977 141 nbsu = myTopolTool->NbSamplesU();
142 nbsv = myTopolTool->NbSamplesV();
143 if(nbsu>40) nbsu = 40;
144 if(nbsv>40) nbsv = 40;
7d9b843c 145 PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
146 new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
147 */
148
149 //modified by NIZNHY-PKV Fri Apr 06 07:30:49 2012t
7fd59977 150 }
151}
7d9b843c 152//=======================================================================
153//function : InternalCall
154//purpose :
155//=======================================================================
7fd59977 156void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
7d9b843c 157 const Standard_Real parinf,
158 const Standard_Real parsup)
159{
7fd59977 160 if(HICS.IsDone()) {
161 for(Standard_Integer index=HICS.NbPoints(); index>=1; index--) {
162 const IntCurveSurface_IntersectionPoint& HICSPointindex = HICS.Point(index);
163 gp_Pnt2d Puv(HICSPointindex.U(),HICSPointindex.V());
164
165 TopAbs_State currentstate = myTopolTool->Classify(Puv,Tol);
166 if(currentstate==TopAbs_IN || currentstate==TopAbs_ON) {
167 Standard_Real HICSW = HICSPointindex.W();
168 if(HICSW >= parinf && HICSW <= parsup ) {
169 Standard_Real U = HICSPointindex.U();
170 Standard_Real V = HICSPointindex.V();
171 Standard_Real W = HICSW;
172 IntCurveSurface_TransitionOnCurve transition = HICSPointindex.Transition();
173 gp_Pnt pnt = HICSPointindex.Pnt();
174 // state = currentstate;
175 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
176 Standard_Integer anIntState = (currentstate == TopAbs_IN) ? 0 : 1;
177 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
178
179 if(transition != IntCurveSurface_Tangent && face.Orientation()==TopAbs_REVERSED) {
180 if(transition == IntCurveSurface_In)
181 transition = IntCurveSurface_Out;
182 else
183 transition = IntCurveSurface_In;
184 }
185 //----- Insertion du point
186 if(nbpnt==0) {
187 IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
188 SeqPnt.Append(PPP);
189 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
190 mySeqState.Append(anIntState);
191 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
192 }
193 else {
194 Standard_Integer i = 1;
195 Standard_Integer b = nbpnt+1;
196 while(i<=nbpnt) {
197 const IntCurveSurface_IntersectionPoint& Pnti=SeqPnt.Value(i);
198 Standard_Real wi = Pnti.W();
199 if(wi >= W) { b=i; i=nbpnt; }
200 i++;
201 }
202 IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
203 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
204// if(b>nbpnt) { SeqPnt.Append(PPP); }
205// else if(b>0) { SeqPnt.InsertBefore(b,PPP); }
206 if(b>nbpnt) {
207 SeqPnt.Append(PPP);
208 mySeqState.Append(anIntState);
209 } else if(b>0) {
210 SeqPnt.InsertBefore(b,PPP);
211 mySeqState.InsertBefore(b, anIntState);
212 }
213 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
214 }
215
216
217 nbpnt++;
218 }
219 } //-- classifier state is IN or ON
220 } //-- Loop on Intersection points.
221 } //-- HICS.IsDone()
222}
7d9b843c 223//=======================================================================
224//function : Perform
225//purpose :
226//=======================================================================
227void IntCurvesFace_Intersector::Perform(const gp_Lin& L,
228 const Standard_Real ParMin,
229 const Standard_Real ParMax)
230{
7fd59977 231 done = Standard_True;
232 SeqPnt.Clear();
7fd59977 233 mySeqState.Clear();
7fd59977 234 nbpnt = 0;
7fd59977 235
7d9b843c 236 IntCurveSurface_HInter HICS;
7fd59977 237 Handle(Geom_Line) geomline = new Geom_Line(L);
238 GeomAdaptor_Curve LL(geomline);
7fd59977 239 Handle(GeomAdaptor_HCurve) HLL = new GeomAdaptor_HCurve(LL);
7fd59977 240 Standard_Real parinf=ParMin;
241 Standard_Real parsup=ParMax;
7d9b843c 242 //
7fd59977 243 if(PtrOnPolyhedron == NULL) {
244 HICS.Perform(HLL,Hsurface);
245 }
246 else {
7d9b843c 247 Intf_Tool bndTool;
248 Bnd_Box boxLine;
249 bndTool.LinBox
250 (L,
251 ((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron)->Bounding(),
252 boxLine);
7fd59977 253 if(bndTool.NbSegments() == 0)
254 return;
255 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
256 Standard_Real pinf = bndTool.BeginParam(nbseg);
257 Standard_Real psup = bndTool.EndParam(nbseg);
258 Standard_Real pppp = 0.05*(psup-pinf);
259 pinf-=pppp;
260 psup+=pppp;
261 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; }
262 if(nbseg==1) { parinf=pinf; parsup=psup; }
263 else {
264 if(parinf>pinf) parinf = pinf;
265 if(parsup<psup) parsup = psup;
266 }
267 }
268 if(parinf>ParMax) { return; }
269 if(parsup<ParMin) { return; }
270 if(parinf<ParMin) parinf=ParMin;
271 if(parsup>ParMax) parsup=ParMax;
272 if(parinf>(parsup-1e-9)) return;
273 IntCurveSurface_ThePolygonOfHInter polygon(HLL,
274 parinf,
275 parsup,
276 2);
277#if OPTIMISATION
278 if(PtrOnBndBounding==NULL) {
279 PtrOnBndBounding = (Bnd_BoundSortBox *) new Bnd_BoundSortBox();
7d9b843c 280 IntCurveSurface_ThePolyhedronOfHInter *thePolyh=
281 (IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
282 ((Bnd_BoundSortBox *)(PtrOnBndBounding))->
283 Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*thePolyh),
284 IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*thePolyh));
7fd59977 285 }
286 HICS.Perform(HLL,
287 polygon,
288 Hsurface,
289 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron),
290 *((Bnd_BoundSortBox *)PtrOnBndBounding));
291#else
292 HICS.Perform(HLL,
293 polygon,
294 Hsurface,
295 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron));
296#endif
297 }
298
299 InternalCall(HICS,parinf,parsup);
7fd59977 300}
7d9b843c 301//=======================================================================
302//function : Perform
303//purpose :
304//=======================================================================
305void IntCurvesFace_Intersector::Perform(const Handle(Adaptor3d_HCurve)& HCu,
306 const Standard_Real ParMin,
307 const Standard_Real ParMax)
308{
7fd59977 309 done = Standard_True;
310 SeqPnt.Clear();
311 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
312 mySeqState.Clear();
313 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
314 nbpnt = 0;
315 IntCurveSurface_HInter HICS;
316
317 //--
318 Standard_Real parinf=ParMin;
319 Standard_Real parsup=ParMax;
320
321 if(PtrOnPolyhedron == NULL) {
322 HICS.Perform(HCu,Hsurface);
323 }
324 else {
325 parinf = IntCurveSurface_TheHCurveTool::FirstParameter(HCu);
326 parsup = IntCurveSurface_TheHCurveTool::LastParameter(HCu);
327 if(parinf<ParMin) parinf = ParMin;
328 if(parsup>ParMax) parsup = ParMax;
329 if(parinf>(parsup-1e-9)) return;
330 Standard_Integer nbs;
331 nbs = IntCurveSurface_TheHCurveTool::NbSamples(HCu,parinf,parsup);
332
333 IntCurveSurface_ThePolygonOfHInter polygon(HCu,
334 parinf,
335 parsup,
336 nbs);
337#if OPTIMISATION
338 if(PtrOnBndBounding==NULL) {
339 PtrOnBndBounding = (Bnd_BoundSortBox *) new Bnd_BoundSortBox();
340 IntCurveSurface_ThePolyhedronOfHInter *thePolyh=(IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
341 ((Bnd_BoundSortBox *)(PtrOnBndBounding))->Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*thePolyh),
342 IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*thePolyh));
343 }
344 HICS.Perform(HCu,
345 polygon,
346 Hsurface,
347 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron),
348 *((Bnd_BoundSortBox *)PtrOnBndBounding));
349#else
350 HICS.Perform(HCu,
351 polygon,
352 Hsurface,
353 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron));
354#endif
355 }
356 InternalCall(HICS,parinf,parsup);
357}
358
359//============================================================================
360Bnd_Box IntCurvesFace_Intersector::Bounding() const {
361 if(PtrOnPolyhedron !=NULL) {
362 return(((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron)->Bounding());
363 }
364 else {
365 Bnd_Box B;
366 return(B);
367 }
368}
369TopAbs_State IntCurvesFace_Intersector::ClassifyUVPoint(const gp_Pnt2d& Puv) const {
370 TopAbs_State state = myTopolTool->Classify(Puv,1e-7);
371 return(state);
372}
373//============================================================================
374void IntCurvesFace_Intersector::Destroy() {
375 if(PtrOnPolyhedron !=NULL) {
376 delete (IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
377 PtrOnPolyhedron = NULL;
378 }
379 if(PtrOnBndBounding !=NULL) {
380 delete (Bnd_BoundSortBox *)PtrOnBndBounding;
381 PtrOnBndBounding=NULL;
382 }
383}
384
385
386