b311480e |
1 | // Created on: 1995-03-22 |
2 | // Created by: Laurent BUCHARD |
3 | // Copyright (c) 1995-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 | |
7fd59977 |
17 | |
18 | #include <BRep_Tool.hxx> |
7fd59977 |
19 | #include <BRepAdaptor_Curve.hxx> |
20 | #include <BRepAdaptor_Curve2d.hxx> |
c22b52d6 |
21 | #include <BRepAdaptor_Surface.hxx> |
42cf5bc1 |
22 | #include <BRepClass_FaceClassifier.hxx> |
23 | #include <BRepTools_WireExplorer.hxx> |
24 | #include <CSLib_Class2d.hxx> |
25 | #include <ElCLib.hxx> |
26 | #include <Geom2dInt_Geom2dCurveTool.hxx> |
27 | #include <GeomAbs_SurfaceType.hxx> |
28 | #include <GeomInt.hxx> |
2651bb32 |
29 | #include <GCPnts_QuasiUniformDeflection.hxx> |
42cf5bc1 |
30 | #include <gp_Pnt.hxx> |
31 | #include <gp_Pnt2d.hxx> |
32 | #include <IntTools_FClass2d.hxx> |
33 | #include <IntTools_Tools.hxx> |
34 | #include <Precision.hxx> |
35 | #include <TColgp_Array1OfPnt2d.hxx> |
36 | #include <TColgp_SequenceOfPnt2d.hxx> |
37 | #include <TColgp_SequenceOfVec2d.hxx> |
38 | #include <TColStd_DataMapOfIntegerInteger.hxx> |
7fd59977 |
39 | #include <TopAbs_Orientation.hxx> |
42cf5bc1 |
40 | #include <TopExp.hxx> |
7fd59977 |
41 | #include <TopExp_Explorer.hxx> |
42cf5bc1 |
42 | #include <TopoDS.hxx> |
43 | #include <TopoDS_Edge.hxx> |
44 | #include <TopoDS_Face.hxx> |
7fd59977 |
45 | #include <TopoDS_Wire.hxx> |
5fe14d0f |
46 | #include <GeomLib.hxx> |
47 | #include <Poly.hxx> |
7fd59977 |
48 | |
42cf5bc1 |
49 | #include <stdio.h> |
2651bb32 |
50 | |
51 | //#define DEBUG_PCLASS_POLYGON |
52 | #ifdef DEBUG_PCLASS_POLYGON |
53 | #include <DrawTrSurf.hxx> |
54 | #include <Geom2d_BSplineCurve.hxx> |
55 | #endif |
56 | |
7fd59977 |
57 | //======================================================================= |
58 | //function : IntTools_FClass2d:IntTools:_FClass2d |
59 | //purpose : |
60 | //======================================================================= |
b311480e |
61 | IntTools_FClass2d::IntTools_FClass2d() |
7fd59977 |
62 | { |
63 | } |
64 | //======================================================================= |
65 | //function : IntTools_FClass2d::IntTools_FClass2d |
66 | //purpose : |
67 | //======================================================================= |
0a512187 |
68 | IntTools_FClass2d::IntTools_FClass2d(const TopoDS_Face& aFace, |
69 | const Standard_Real TolUV) |
47cd8af2 |
70 | : Toluv(TolUV), Face(aFace) |
7fd59977 |
71 | { |
72 | Init(Face, Toluv); |
73 | } |
74 | //======================================================================= |
75 | //function : IsHole |
76 | //purpose : |
77 | //======================================================================= |
0a512187 |
78 | Standard_Boolean IntTools_FClass2d::IsHole() const |
7fd59977 |
79 | { |
80 | return myIsHole; |
81 | } |
82 | //======================================================================= |
83 | //function : Init |
84 | //purpose : |
85 | //======================================================================= |
0a512187 |
86 | void IntTools_FClass2d::Init(const TopoDS_Face& aFace, |
87 | const Standard_Real TolUV) |
7fd59977 |
88 | { |
89 | Standard_Boolean WireIsNotEmpty, Ancienpnt3dinitialise, degenerated; |
5fe14d0f |
90 | Standard_Integer firstpoint, NbEdges; |
7fd59977 |
91 | Standard_Integer iX, aNbs1, nbs, Avant, BadWire; |
92 | Standard_Real u, du, Tole, Tol, pfbid, plbid; |
93 | Standard_Real FlecheU, FlecheV, TolVertex1, TolVertex; |
94 | Standard_Real uFirst, uLast; |
95 | Standard_Real aPrCf, aPrCf2; |
96 | // |
97 | TopoDS_Edge edge; |
98 | TopoDS_Vertex Va,Vb; |
99 | TopAbs_Orientation Or; |
100 | BRepTools_WireExplorer aWExp; |
101 | TopExp_Explorer aExpF, aExp; |
102 | Handle(Geom2d_Curve) aC2D; |
103 | gp_Pnt Ancienpnt3d; |
104 | TColgp_SequenceOfPnt2d SeqPnt2d; |
105 | TColStd_DataMapOfIntegerInteger anIndexMap; |
106 | TColgp_SequenceOfVec2d aD1Prev; |
107 | TColgp_SequenceOfVec2d aD1Next; |
108 | // |
109 | aPrCf=Precision::Confusion(); |
110 | aPrCf2=aPrCf*aPrCf; |
111 | myIsHole=Standard_True; |
112 | // |
113 | Toluv=TolUV; |
114 | Face=aFace; |
115 | Face.Orientation(TopAbs_FORWARD); |
c22b52d6 |
116 | Handle(BRepAdaptor_Surface) surf = new BRepAdaptor_Surface(); |
117 | surf->Initialize(aFace, Standard_False); |
7fd59977 |
118 | // |
119 | Tole = 0.; |
120 | Tol=0.; |
121 | Umin = Vmin = RealLast(); |
122 | Umax = Vmax = -Umin; |
123 | BadWire=0; |
124 | // |
125 | //if face has several wires and one of them is bad, |
126 | //it is necessary to process all of them for correct |
127 | //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06 |
128 | // |
129 | aExpF.Init(Face,TopAbs_WIRE); |
130 | for(; aExpF.More(); aExpF.Next()) { |
131 | const TopoDS_Wire& aW=*((TopoDS_Wire*)&aExpF.Current()); |
132 | // |
7fd59977 |
133 | firstpoint =1; |
134 | FlecheU = 0.; |
135 | FlecheV = 0.; |
136 | TolVertex1=0.; |
137 | TolVertex=0.; |
138 | WireIsNotEmpty = Standard_False; |
139 | Ancienpnt3dinitialise=Standard_False; |
140 | Ancienpnt3d.SetCoord(0.,0.,0.); |
141 | // |
142 | SeqPnt2d.Clear(); |
143 | anIndexMap.Clear(); |
144 | aD1Prev.Clear(); |
145 | aD1Next.Clear(); |
146 | // |
147 | // NbEdges |
148 | NbEdges=0; |
149 | aExp.Init(aW, TopAbs_EDGE); |
150 | for(; aExp.More(); aExp.Next()) { |
151 | NbEdges++; |
152 | } |
153 | // |
154 | aWExp.Init(aW, Face); |
155 | for(;aWExp.More(); aWExp.Next()) { |
156 | NbEdges--; |
157 | edge = aWExp.Current(); |
158 | Or = edge.Orientation(); |
159 | if(!(Or==TopAbs_FORWARD || Or==TopAbs_REVERSED)) { |
655fddc8 |
160 | continue; |
7fd59977 |
161 | } |
162 | // |
163 | aC2D=BRep_Tool::CurveOnSurface(edge, Face, pfbid, plbid); |
164 | if (aC2D.IsNull()) { |
655fddc8 |
165 | return; |
7fd59977 |
166 | } |
167 | // |
168 | BRepAdaptor_Curve2d C(edge,Face); |
169 | BRepAdaptor_Curve C3d; |
170 | //------------------------------------------ |
171 | degenerated=Standard_False; |
172 | if(BRep_Tool::Degenerated(edge) || |
655fddc8 |
173 | BRep_Tool::IsClosed(edge, Face)) { |
174 | degenerated=Standard_True; |
7fd59977 |
175 | } |
176 | // |
177 | TopExp::Vertices(edge,Va,Vb); |
178 | // |
179 | TolVertex1=0.; |
180 | TolVertex=0.; |
181 | if (Va.IsNull()) { |
655fddc8 |
182 | degenerated=Standard_True; |
183 | } |
7fd59977 |
184 | else { |
655fddc8 |
185 | TolVertex1=BRep_Tool::Tolerance(Va); |
7fd59977 |
186 | } |
187 | if (Vb.IsNull()){ |
655fddc8 |
188 | degenerated=Standard_True; |
189 | } |
7fd59977 |
190 | else { |
655fddc8 |
191 | TolVertex=BRep_Tool::Tolerance(Vb); |
7fd59977 |
192 | } |
655fddc8 |
193 | // |
7fd59977 |
194 | if(TolVertex<TolVertex1) { |
655fddc8 |
195 | TolVertex=TolVertex1; |
196 | } |
7fd59977 |
197 | // |
81bba717 |
198 | //-- Verification of cases when forgotten to code degenereted |
7fd59977 |
199 | if(!degenerated) { |
2478cd9d |
200 | // check that whole curve is located in vicinity of its middle point |
201 | // (within sphere of Precision::Confusion() diameter) |
202 | C3d.Initialize (edge, Face); |
203 | gp_Pnt P3da = C3d.Value (0.5 * (pfbid + plbid)); |
204 | du = plbid - pfbid; |
205 | const int NBSTEPS = 10; |
206 | Standard_Real aPrec2 = 0.25 * Precision::Confusion() * Precision::Confusion(); |
207 | degenerated = Standard_True; |
208 | for (Standard_Integer i=0; i <= NBSTEPS; i++) |
209 | { |
51740958 |
210 | Standard_Real U = pfbid + i * du / NBSTEPS; |
211 | gp_Pnt P3db = C3d.Value (U); |
2478cd9d |
212 | Standard_Real aR2 = P3da.SquareDistance (P3db); |
213 | if (aR2 > aPrec2) { |
214 | degenerated = Standard_False; |
215 | break; |
216 | } |
217 | } |
7fd59977 |
218 | }//if(!degenerated) |
219 | //-- ---------------------------------------- |
220 | Tole = BRep_Tool::Tolerance(edge); |
221 | if(Tole>Tol) { |
655fddc8 |
222 | Tol=Tole; |
7fd59977 |
223 | } |
224 | // |
225 | // NbSamples +> nbs |
226 | nbs = Geom2dInt_Geom2dCurveTool::NbSamples(C); |
227 | if (nbs > 2) { |
655fddc8 |
228 | nbs*=4; |
7fd59977 |
229 | } |
230 | du = (plbid-pfbid)/(Standard_Real)(nbs-1); |
231 | // |
232 | if(Or==TopAbs_FORWARD) { |
655fddc8 |
233 | u = pfbid; |
234 | uFirst=pfbid; |
235 | uLast=plbid; |
7fd59977 |
236 | } |
237 | else { |
655fddc8 |
238 | u = plbid; |
239 | uFirst=plbid; |
240 | uLast=pfbid; |
241 | du=-du; |
7fd59977 |
242 | } |
243 | // |
244 | // aPrms |
245 | aNbs1=nbs+1; |
246 | TColStd_Array1OfReal aPrms(1, aNbs1); |
247 | // |
248 | if (nbs==2) { |
655fddc8 |
249 | Standard_Real aCoef=0.0025; |
250 | aPrms(1)=uFirst; |
251 | aPrms(2)=uFirst+aCoef*(uLast-uFirst); |
252 | aPrms(3)=uLast; |
7fd59977 |
253 | } |
254 | else if (nbs>2) { |
655fddc8 |
255 | aNbs1=nbs; |
256 | aPrms(1)=uFirst; |
257 | for (iX=2; iX<aNbs1; ++iX) { |
258 | aPrms(iX)=u+(iX-1)*du; |
259 | } |
260 | aPrms(aNbs1)=uLast; |
7fd59977 |
261 | } |
262 | // |
263 | //-- ------------------------------------------------------------ |
81bba717 |
264 | //-- Check distance uv between the start point of the edge |
265 | //-- and the last point saved in SeqPnt2d |
266 | //-- To to set the first point of the current |
267 | //-- afar from the last saved point |
5fe14d0f |
268 | Avant = SeqPnt2d.Length(); |
7fd59977 |
269 | for(iX=firstpoint; iX<=aNbs1; iX++) { |
655fddc8 |
270 | Standard_Boolean IsRealCurve3d; |
271 | Standard_Integer ii; |
272 | Standard_Real aDstX; |
273 | gp_Pnt2d P2d; |
274 | gp_Pnt P3d; |
275 | // |
276 | u=aPrms(iX); |
277 | P2d = C.Value(u); |
278 | if(P2d.X()<Umin) Umin = P2d.X(); |
279 | if(P2d.X()>Umax) Umax = P2d.X(); |
280 | if(P2d.Y()<Vmin) Vmin = P2d.Y(); |
281 | if(P2d.Y()>Vmax) Vmax = P2d.Y(); |
282 | // |
283 | aDstX=RealLast(); |
284 | if(degenerated==Standard_False) { |
285 | P3d=C3d.Value(u); |
5fe14d0f |
286 | if(!SeqPnt2d.IsEmpty()) { |
655fddc8 |
287 | if(Ancienpnt3dinitialise) { |
288 | aDstX=P3d.SquareDistance(Ancienpnt3d); |
289 | } |
290 | } |
291 | } |
292 | // |
293 | IsRealCurve3d = Standard_True; |
294 | if (aDstX < aPrCf2) { |
295 | if(iX>1) { |
296 | Standard_Real aDstX1; |
297 | gp_Pnt MidP3d; |
298 | // |
299 | MidP3d = C3d.Value(0.5*(u+aPrms(iX-1))); |
300 | aDstX1=P3d.SquareDistance( MidP3d ); |
301 | if (aDstX1 < aPrCf2){ |
302 | IsRealCurve3d = Standard_False; |
303 | } |
304 | } |
305 | } |
306 | // |
307 | if (IsRealCurve3d) { |
308 | if(degenerated==Standard_False) { |
309 | Ancienpnt3d=P3d; |
310 | Ancienpnt3dinitialise=Standard_True; |
311 | } |
655fddc8 |
312 | SeqPnt2d.Append(P2d); |
313 | } |
314 | // |
5fe14d0f |
315 | ii= SeqPnt2d.Length(); |
655fddc8 |
316 | if(ii>(Avant+4)) { |
317 | Standard_Real ul, dU, dV; |
318 | gp_Pnt2d Pp; |
319 | // |
320 | gp_Lin2d Lin(SeqPnt2d(ii-2),gp_Dir2d(gp_Vec2d(SeqPnt2d(ii-2),SeqPnt2d(ii)))); |
321 | ul = ElCLib::Parameter(Lin,SeqPnt2d(ii-1)); |
322 | Pp = ElCLib::Value(ul,Lin); |
323 | dU = Abs(Pp.X()-SeqPnt2d(ii-1).X()); |
324 | dV = Abs(Pp.Y()-SeqPnt2d(ii-1).Y()); |
325 | if(dU>FlecheU) { |
326 | FlecheU = dU; |
327 | } |
328 | if(dV>FlecheV) { |
329 | FlecheV = dV; |
330 | } |
331 | } |
7fd59977 |
332 | }// for(iX=firstpoint; iX<=aNbs1; iX++) { |
333 | // |
334 | if(BadWire) { |
655fddc8 |
335 | continue; //if face has several wires and one of them is bad, |
336 | //it is necessary to process all of them for correct |
337 | //calculation of Umin, Umax, Vmin, Vmax - ifv, 23.08.06 |
7fd59977 |
338 | } |
339 | // |
340 | if(firstpoint==1) firstpoint=2; |
341 | WireIsNotEmpty = Standard_True; |
342 | // Append the derivative of the first parameter. |
343 | Standard_Real aU = aPrms(1); |
344 | gp_Pnt2d aP; |
345 | gp_Vec2d aV; |
346 | |
347 | C.D1(aU, aP, aV); |
348 | |
349 | if(Or == TopAbs_REVERSED) |
655fddc8 |
350 | aV.Reverse(); |
7fd59977 |
351 | |
352 | aD1Next.Append(aV); |
353 | |
354 | // Append the derivative of the last parameter. |
355 | aU = aPrms(aNbs1); |
356 | C.D1(aU, aP, aV); |
357 | |
358 | if(Or == TopAbs_REVERSED) |
655fddc8 |
359 | aV.Reverse(); |
7fd59977 |
360 | |
361 | if (NbEdges > 0) |
655fddc8 |
362 | aD1Prev.Append(aV); |
7fd59977 |
363 | else |
655fddc8 |
364 | aD1Prev.Prepend(aV); |
7fd59977 |
365 | |
366 | // Fill the map anIndexMap. |
367 | if (Avant > 0) |
655fddc8 |
368 | anIndexMap.Bind(Avant, aD1Next.Length()); |
7fd59977 |
369 | else |
655fddc8 |
370 | anIndexMap.Bind(1, aD1Next.Length()); |
7fd59977 |
371 | } //for(;aWExp.More(); aWExp.Next()) { |
372 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
373 | // |
374 | if(NbEdges) { |
81bba717 |
375 | //-- count ++ with normal explorer and -- with Wire Explorer |
7fd59977 |
376 | TColgp_Array1OfPnt2d PClass(1,2); |
377 | gp_Pnt2d anInitPnt(0., 0.); |
378 | // |
379 | PClass.Init(anInitPnt); |
0a512187 |
380 | TabClass.Append((void *)new CSLib_Class2d(PClass, |
381 | FlecheU, |
382 | FlecheV, |
383 | Umin,Vmin,Umax,Vmax)); |
7fd59977 |
384 | BadWire=1; |
385 | TabOrien.Append(-1); |
386 | } |
387 | // |
388 | else if(WireIsNotEmpty) { |
5fe14d0f |
389 | if (SeqPnt2d.Length() > 3) |
390 | { |
2651bb32 |
391 | #ifdef DEBUG_PCLASS_POLYGON |
5fe14d0f |
392 | TColgp_Array1OfPnt2d PClass(1, nbpnts); |
2651bb32 |
393 | TColStd_Array1OfReal aKnots(1, nbpnts); |
394 | TColStd_Array1OfInteger aMults(1, nbpnts); |
395 | for (int i = 1; i <= nbpnts; i++) |
396 | { |
397 | aKnots(i) = i; |
398 | aMults(i) = 1; |
5fe14d0f |
399 | PClass(ii) = SeqPnt2d.Value(ii); |
2651bb32 |
400 | } |
401 | aMults(1) = aMults(nbpnts) = 2; |
402 | Handle(Geom2d_BSplineCurve) aPol = new Geom2d_BSplineCurve(PClass, aKnots, aMults, 1); |
403 | DrawTrSurf::Set("pol", aPol); |
404 | #endif |
405 | |
5fe14d0f |
406 | Standard_Real aS = 0.; |
407 | Standard_Real aPer = 0.; |
408 | Poly::PolygonProperties(SeqPnt2d, aS, aPer); |
409 | |
2651bb32 |
410 | Standard_Real anExpThick = Max(2. * Abs(aS) / aPer, 1e-7); |
411 | Standard_Real aDefl = Max(FlecheU, FlecheV); |
412 | Standard_Real aDiscrDefl = Min(aDefl*0.1, anExpThick * 10.); |
5fe14d0f |
413 | Standard_Boolean isChanged = Standard_False; |
2651bb32 |
414 | while (aDefl > anExpThick && aDiscrDefl > 1e-7) |
415 | { |
416 | // Deflection of the polygon is too much for this ratio of area and perimeter, |
417 | // and this might lead to self-intersections. |
418 | // Discretize the wire more tightly to eliminate the error. |
419 | firstpoint = 1; |
5fe14d0f |
420 | isChanged = Standard_True; |
2651bb32 |
421 | SeqPnt2d.Clear(); |
422 | FlecheU = 0.0; |
423 | FlecheV = 0.0; |
424 | for (aWExp.Init(TopoDS::Wire(aExpF.Current()), Face); |
425 | aWExp.More(); aWExp.Next()) |
426 | { |
427 | edge = aWExp.Current(); |
428 | Or = edge.Orientation(); |
429 | if (Or == TopAbs_FORWARD || Or == TopAbs_REVERSED) |
430 | { |
431 | BRep_Tool::Range(edge, Face, pfbid, plbid); |
432 | if (Abs(plbid - pfbid) < 1.e-9) continue; |
433 | BRepAdaptor_Curve2d C(edge, Face); |
434 | GCPnts_QuasiUniformDeflection aDiscr(C, aDiscrDefl); |
435 | if (!aDiscr.IsDone()) |
436 | break; |
437 | Standard_Integer nbp = aDiscr.NbPoints(); |
438 | Standard_Integer iStep = 1, i = 1, iEnd = nbp + 1; |
439 | if (Or == TopAbs_REVERSED) |
440 | { |
441 | iStep = -1; |
442 | i = nbp; |
443 | iEnd = 0; |
444 | } |
445 | if (firstpoint == 2) |
446 | i += iStep; |
447 | for (; i != iEnd; i += iStep) |
448 | { |
449 | gp_Pnt2d aP2d = C.Value(aDiscr.Parameter(i)); |
450 | SeqPnt2d.Append(aP2d); |
451 | } |
452 | if (nbp > 2) |
453 | { |
454 | Standard_Integer ii = SeqPnt2d.Length(); |
455 | gp_Lin2d Lin(SeqPnt2d(ii - 2), gp_Dir2d(gp_Vec2d(SeqPnt2d(ii - 2), SeqPnt2d(ii)))); |
456 | Standard_Real ul = ElCLib::Parameter(Lin, SeqPnt2d(ii - 1)); |
457 | gp_Pnt2d Pp = ElCLib::Value(ul, Lin); |
458 | Standard_Real dU = Abs(Pp.X() - SeqPnt2d(ii - 1).X()); |
459 | Standard_Real dV = Abs(Pp.Y() - SeqPnt2d(ii - 1).Y()); |
460 | if (dU > FlecheU) FlecheU = dU; |
461 | if (dV > FlecheV) FlecheV = dV; |
462 | } |
463 | firstpoint = 2; |
464 | } |
465 | } |
2651bb32 |
466 | anExpThick = Max(2. * Abs(aS) / aPer, 1e-7); |
467 | aDefl = Max(FlecheU, FlecheV); |
468 | aDiscrDefl = Min(aDiscrDefl * 0.1, anExpThick * 10.); |
469 | } |
470 | |
5fe14d0f |
471 | if (isChanged) |
472 | { |
473 | Poly::PolygonProperties(SeqPnt2d, aS, aPer); |
655fddc8 |
474 | } |
475 | // |
476 | if(FlecheU<Toluv) |
477 | FlecheU = Toluv; |
478 | |
479 | if(FlecheV<Toluv) |
480 | FlecheV = Toluv; |
481 | |
5fe14d0f |
482 | TabClass.Append((void *)new CSLib_Class2d(SeqPnt2d, |
0a512187 |
483 | FlecheU, |
484 | FlecheV, |
485 | Umin,Vmin,Umax,Vmax)); |
655fddc8 |
486 | // |
5fe14d0f |
487 | if(Abs(aS) < Precision::SquareConfusion()) { |
655fddc8 |
488 | BadWire=1; |
489 | TabOrien.Append(-1); |
490 | } |
5fe14d0f |
491 | else |
492 | { |
493 | if (aS > 0.0) |
494 | { |
495 | myIsHole = Standard_False; |
496 | TabOrien.Append(1); |
497 | } |
498 | else |
499 | { |
500 | myIsHole = Standard_True; |
501 | TabOrien.Append(0); |
502 | } |
655fddc8 |
503 | } |
7fd59977 |
504 | } |
505 | else { |
655fddc8 |
506 | BadWire=1; |
507 | TabOrien.Append(-1); |
508 | TColgp_Array1OfPnt2d PPClass(1,2); |
5fe14d0f |
509 | SeqPnt2d.Clear(); |
510 | TabClass.Append((void *)new CSLib_Class2d(SeqPnt2d, |
0a512187 |
511 | FlecheU, |
512 | FlecheV, |
513 | Umin,Vmin,Umax,Vmax)); |
7fd59977 |
514 | } |
515 | }// else if(WireIsNotEmpty) |
516 | } // for(; aExpF.More(); aExpF.Next()) { |
517 | // |
518 | Standard_Integer nbtabclass = TabClass.Length(); |
519 | // |
520 | if(nbtabclass>0) { |
81bba717 |
521 | //-- if an error on a wire was detected : all TabOrien set to -1 |
7fd59977 |
522 | if(BadWire) { |
523 | TabOrien(1)=-1; |
524 | } |
525 | |
526 | if( surf->GetType()==GeomAbs_Cone |
527 | || surf->GetType()==GeomAbs_Cylinder |
528 | || surf->GetType()==GeomAbs_Torus |
529 | || surf->GetType()==GeomAbs_Sphere |
530 | || surf->GetType()==GeomAbs_SurfaceOfRevolution) { |
c6541a0c |
531 | Standard_Real uuu=M_PI+M_PI-(Umax-Umin); |
7fd59977 |
532 | if(uuu<0) uuu=0; |
533 | U1 = Umin-uuu*0.5; |
c6541a0c |
534 | U2 = U1+M_PI+M_PI; |
7fd59977 |
535 | } |
536 | else { |
537 | U1=U2=0.0; |
538 | } |
539 | |
540 | if(surf->GetType()==GeomAbs_Torus) { |
c6541a0c |
541 | Standard_Real uuu=M_PI+M_PI-(Vmax-Vmin); |
7fd59977 |
542 | if(uuu<0) uuu=0; |
543 | |
544 | V1 = Vmin-uuu*0.5; |
c6541a0c |
545 | V2 = V1+M_PI+M_PI; |
7fd59977 |
546 | } |
547 | else { |
548 | V1=V2=0.0; |
549 | } |
550 | } |
551 | } |
552 | //======================================================================= |
553 | //function : PerformInfinitePoint |
554 | //purpose : |
555 | //======================================================================= |
0a512187 |
556 | TopAbs_State IntTools_FClass2d::PerformInfinitePoint() const |
7fd59977 |
557 | { |
0a512187 |
558 | if(Umax==-RealLast() || Vmax==-RealLast() || |
559 | Umin==RealLast() || Vmin==RealLast()) { |
7fd59977 |
560 | return(TopAbs_IN); |
561 | } |
562 | gp_Pnt2d P(Umin-(Umax-Umin),Vmin-(Vmax-Vmin)); |
563 | return(Perform(P,Standard_False)); |
564 | } |
565 | //======================================================================= |
566 | //function : Perform |
567 | //purpose : |
568 | //======================================================================= |
0a512187 |
569 | TopAbs_State IntTools_FClass2d::Perform |
570 | (const gp_Pnt2d& _Puv, |
571 | const Standard_Boolean RecadreOnPeriodic) const |
7fd59977 |
572 | { |
773f53f1 |
573 | Standard_Integer nbtabclass = TabClass.Length(); |
574 | if (nbtabclass == 0) |
575 | { |
576 | return TopAbs_IN; |
7fd59977 |
577 | } |
7fd59977 |
578 | |
773f53f1 |
579 | //-- U1 is the First Param and U2 is in this case U1+Period |
580 | Standard_Real u = _Puv.X(); |
581 | Standard_Real v = _Puv.Y(); |
582 | Standard_Real uu = u; |
583 | Standard_Real vv = v; |
9fd2d2c3 |
584 | TopAbs_State aStatus = TopAbs_UNKNOWN; |
7fd59977 |
585 | |
c22b52d6 |
586 | Handle(BRepAdaptor_Surface) surf = new BRepAdaptor_Surface(); |
587 | surf->Initialize( Face, Standard_False ); |
7fd59977 |
588 | |
773f53f1 |
589 | const Standard_Boolean IsUPer = surf->IsUPeriodic(); |
590 | const Standard_Boolean IsVPer = surf->IsVPeriodic(); |
591 | const Standard_Real uperiod = IsUPer ? surf->UPeriod() : 0.0; |
592 | const Standard_Real vperiod = IsVPer ? surf->VPeriod() : 0.0; |
7fd59977 |
593 | |
78c66ef1 |
594 | Standard_Boolean urecadre, vrecadre, bUseClassifier; |
773f53f1 |
595 | Standard_Integer dedans = 1; |
78c66ef1 |
596 | // |
597 | urecadre = Standard_False; |
598 | vrecadre = Standard_False; |
599 | // |
7fd59977 |
600 | if (RecadreOnPeriodic) { |
655fddc8 |
601 | Standard_Real du, dv; |
7fd59977 |
602 | if (IsUPer) { |
2a78ec6a |
603 | GeomInt::AdjustPeriodic(uu, Umin, Umax, uperiod, uu, du); |
7fd59977 |
604 | }// if (IsUPer) { |
655fddc8 |
605 | // |
7fd59977 |
606 | if (IsVPer) { |
2a78ec6a |
607 | GeomInt::AdjustPeriodic(vv, Vmin, Vmax, vperiod, vv, dv); |
7fd59977 |
608 | }//if (IsVPer) { |
609 | } |
78c66ef1 |
610 | // |
302f96fb |
611 | for(;;) { |
7fd59977 |
612 | dedans = 1; |
613 | gp_Pnt2d Puv(u,v); |
78c66ef1 |
614 | bUseClassifier = (TabOrien(1) == -1); |
615 | if(!bUseClassifier) { |
7fd59977 |
616 | Standard_Integer n, cur, TabOrien_n ; |
617 | for(n=1; n<=nbtabclass; n++) { |
78c66ef1 |
618 | cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv); |
619 | TabOrien_n=TabOrien(n); |
620 | |
621 | if(cur==1) { |
622 | if(TabOrien_n==0) { |
623 | dedans = -1; |
624 | break; |
625 | } |
626 | } |
627 | else if(cur==-1) { |
628 | if(TabOrien_n==1) { |
629 | dedans = -1; |
630 | break; |
631 | } |
632 | } |
633 | else { |
634 | dedans = 0; |
635 | break; |
636 | } |
7fd59977 |
637 | } // for(n=1; n<=nbtabclass; n++) |
78c66ef1 |
638 | |
7fd59977 |
639 | if(dedans==0) { |
78c66ef1 |
640 | bUseClassifier = Standard_True; |
641 | } |
642 | else { |
9fd2d2c3 |
643 | aStatus = (dedans == 1) ? TopAbs_IN : TopAbs_OUT; |
7fd59977 |
644 | } |
645 | } // if(TabOrien(1)!=-1) { |
78c66ef1 |
646 | //compute state of the point using face classifier |
647 | if (bUseClassifier) { |
648 | //compute tolerance to use in face classifier |
649 | Standard_Real aURes, aVRes, aFCTol; |
650 | Standard_Boolean bUIn, bVIn; |
651 | // |
652 | aURes = surf->UResolution(Toluv); |
653 | aVRes = surf->VResolution(Toluv); |
654 | // |
655 | bUIn = (u >= Umin) && (u <= Umax); |
656 | bVIn = (v >= Vmin) && (v <= Vmax); |
657 | // |
b85b0b07 |
658 | if (bUIn==bVIn) { |
659 | aFCTol = Min(aURes, aVRes); |
660 | } |
661 | else { |
662 | aFCTol = (!bUIn) ? aURes : aVRes; |
663 | } |
78c66ef1 |
664 | // |
47cd8af2 |
665 | |
666 | if (myFExplorer.get() == NULL) |
667 | myFExplorer.reset (new BRepClass_FaceExplorer (Face)); |
668 | |
669 | BRepClass_FClassifier aClassifier; |
670 | aClassifier.Perform(*myFExplorer, Puv, aFCTol); |
9fd2d2c3 |
671 | aStatus = aClassifier.State(); |
7fd59977 |
672 | } |
673 | |
0ebaa4db |
674 | if (!RecadreOnPeriodic || (!IsUPer && !IsVPer)) |
9fd2d2c3 |
675 | return aStatus; |
7fd59977 |
676 | |
9fd2d2c3 |
677 | if (aStatus == TopAbs_IN || aStatus == TopAbs_ON) |
678 | return aStatus; |
7fd59977 |
679 | |
680 | if (!urecadre){ |
681 | u = uu; |
682 | urecadre = Standard_True; |
683 | } |
684 | else { |
685 | if (IsUPer){ |
78c66ef1 |
686 | u += uperiod; |
7fd59977 |
687 | } |
688 | } |
689 | |
690 | if (u > Umax || !IsUPer) { |
691 | if (!vrecadre){ |
78c66ef1 |
692 | v = vv; |
693 | vrecadre = Standard_True; |
7fd59977 |
694 | } |
695 | else { |
78c66ef1 |
696 | if (IsVPer){ |
697 | v += vperiod; |
698 | } |
7fd59977 |
699 | } |
700 | |
701 | u = uu; |
702 | |
703 | if (v > Vmax || !IsVPer) { |
9fd2d2c3 |
704 | return aStatus; |
7fd59977 |
705 | } |
706 | } |
707 | } //while (1) |
708 | } |
709 | |
710 | //======================================================================= |
711 | //function : TestOnRestriction |
712 | //purpose : |
713 | //======================================================================= |
0a512187 |
714 | TopAbs_State IntTools_FClass2d::TestOnRestriction |
715 | (const gp_Pnt2d& _Puv, |
716 | const Standard_Real Tol, |
717 | const Standard_Boolean RecadreOnPeriodic) const |
7fd59977 |
718 | { |
773f53f1 |
719 | Standard_Integer nbtabclass = TabClass.Length(); |
720 | if (nbtabclass == 0) |
721 | { |
722 | return TopAbs_IN; |
7fd59977 |
723 | } |
773f53f1 |
724 | |
81bba717 |
725 | //-- U1 is the First Param and U2 in this case is U1+Period |
7fd59977 |
726 | Standard_Real u=_Puv.X(); |
727 | Standard_Real v=_Puv.Y(); |
728 | Standard_Real uu = u, vv = v; |
773f53f1 |
729 | |
c22b52d6 |
730 | Handle(BRepAdaptor_Surface) surf = new BRepAdaptor_Surface(); |
731 | surf->Initialize( Face, Standard_False ); |
773f53f1 |
732 | const Standard_Boolean IsUPer = surf->IsUPeriodic(); |
733 | const Standard_Boolean IsVPer = surf->IsVPeriodic(); |
734 | const Standard_Real uperiod = IsUPer ? surf->UPeriod() : 0.0; |
735 | const Standard_Real vperiod = IsVPer ? surf->VPeriod() : 0.0; |
9fd2d2c3 |
736 | TopAbs_State aStatus = TopAbs_UNKNOWN; |
7fd59977 |
737 | Standard_Boolean urecadre = Standard_False, vrecadre = Standard_False; |
773f53f1 |
738 | Standard_Integer dedans = 1; |
739 | |
655fddc8 |
740 | if (RecadreOnPeriodic) { |
741 | Standard_Real du, dv; |
742 | if (IsUPer) { |
2a78ec6a |
743 | GeomInt::AdjustPeriodic(uu, Umin, Umax, uperiod, uu, du); |
655fddc8 |
744 | }// if (IsUPer) { |
745 | // |
746 | if (IsVPer) { |
2a78ec6a |
747 | GeomInt::AdjustPeriodic(vv, Vmin, Vmax, vperiod, vv, dv); |
655fddc8 |
748 | }//if (IsVPer) { |
749 | } |
750 | // |
7fd59977 |
751 | for (;;) { |
752 | dedans = 1; |
753 | gp_Pnt2d Puv(u,v); |
754 | |
755 | if(TabOrien(1)!=-1) { |
756 | for(Standard_Integer n=1; n<=nbtabclass; n++) { |
655fddc8 |
757 | Standard_Integer cur = ((CSLib_Class2d *)TabClass(n))->SiDans_OnMode(Puv,Tol); |
758 | if(cur==1) { |
759 | if(TabOrien(n)==0) { |
760 | dedans = -1; |
761 | break; |
762 | } |
763 | } |
764 | else if(cur==-1) { |
765 | if(TabOrien(n)==1) { |
766 | dedans = -1; |
767 | break; |
768 | } |
769 | } |
770 | else { |
771 | dedans = 0; |
772 | break; |
773 | } |
7fd59977 |
774 | } |
775 | if(dedans==0) { |
9fd2d2c3 |
776 | aStatus = TopAbs_ON; |
7fd59977 |
777 | } |
778 | if(dedans == 1) { |
9fd2d2c3 |
779 | aStatus = TopAbs_IN; |
7fd59977 |
780 | } |
781 | if(dedans == -1) { |
9fd2d2c3 |
782 | aStatus = TopAbs_OUT; |
7fd59977 |
783 | } |
784 | } |
81bba717 |
785 | else { //-- TabOrien(1)=-1 Wrong Wire |
47cd8af2 |
786 | |
787 | if (myFExplorer.get() == NULL) |
788 | myFExplorer.reset (new BRepClass_FaceExplorer (Face)); |
789 | |
790 | BRepClass_FClassifier aClassifier; |
791 | aClassifier.Perform(*myFExplorer, Puv, Tol); |
9fd2d2c3 |
792 | aStatus = aClassifier.State(); |
7fd59977 |
793 | } |
794 | |
0ebaa4db |
795 | if (!RecadreOnPeriodic || (!IsUPer && !IsVPer)) |
9fd2d2c3 |
796 | return aStatus; |
797 | if (aStatus == TopAbs_IN || aStatus == TopAbs_ON) |
798 | return aStatus; |
7fd59977 |
799 | |
800 | if (!urecadre) |
801 | { |
655fddc8 |
802 | u = uu; |
803 | urecadre = Standard_True; |
7fd59977 |
804 | } |
805 | else |
806 | if (IsUPer) |
655fddc8 |
807 | u += uperiod; |
7fd59977 |
808 | if (u > Umax || !IsUPer) |
809 | { |
655fddc8 |
810 | if (!vrecadre) |
811 | { |
812 | v = vv; |
813 | vrecadre = Standard_True; |
814 | } |
815 | else |
816 | if (IsVPer) |
817 | v += vperiod; |
818 | |
819 | u = uu; |
820 | |
821 | if (v > Vmax || !IsVPer) |
9fd2d2c3 |
822 | return aStatus; |
7fd59977 |
823 | } |
824 | } //for (;;) |
825 | } |
7fd59977 |
826 | //======================================================================= |
827 | //function : Destroy |
828 | //purpose : |
829 | //======================================================================= |
0a512187 |
830 | void IntTools_FClass2d::Destroy() |
7fd59977 |
831 | { |
832 | Standard_Integer nbtabclass = TabClass.Length(); |
833 | for(Standard_Integer d=1; d<=nbtabclass;d++) { |
834 | if(TabClass(d)) { |
835 | delete ((CSLib_Class2d *)TabClass(d)); |
836 | TabClass(d)=NULL; |
837 | } |
838 | } |
839 | } |
840 | |
841 | |