Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1994-03-10 |
2 | // Created by: Laurent BUCHARD | |
3 | // Copyright (c) 1994-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. | |
b311480e | 16 | |
0d969553 | 17 | // Modifed: Porting NT 7-5-97 DPF (stdio.h) |
7fd59977 | 18 | // Apr 16 2002 eap, classification against infinite solid (occ299) |
19 | ||
20 | ||
21 | // Modified by skv - Thu Sep 4 12:29:30 2003 OCC578 | |
22 | ||
0d969553 | 23 | //-- Process the case of a hole!! |
7fd59977 | 24 | #define REJECTION 1 |
25 | ||
0d969553 | 26 | //-- To printf on NT |
7fd59977 | 27 | #include <stdio.h> |
28 | ||
29 | #include <BRepClass3d_SolidExplorer.ixx> | |
30 | #include <gp.hxx> | |
31 | #include <TopoDS.hxx> | |
32 | #include <BRepAdaptor_Curve2d.hxx> | |
33 | #include <BRepTools.hxx> | |
34 | #include <Geom2d_Curve.hxx> | |
35 | #include <gp_Vec2d.hxx> | |
36 | #include <GeomAbs_Shape.hxx> | |
37 | #include <BRepAdaptor_Surface.hxx> | |
38 | #include <BRepClass_FacePassiveClassifier.hxx> | |
39 | #include <TopAbs_Orientation.hxx> | |
40 | #include <TopExp_Explorer.hxx> | |
41 | #include <BRepClass_Edge.hxx> | |
42 | ||
43 | #include <Bnd_Box.hxx> | |
44 | #include <BRepBndLib.hxx> | |
45 | ||
46 | #include <BRepAdaptor_HSurface.hxx> | |
47 | ||
48 | #include <ElCLib.hxx> | |
49 | ||
50 | #include <BRepClass3d_DataMapIteratorOfMapOfInter.hxx> | |
51 | #include <Precision.hxx> | |
52 | //OCC454(apo)-> | |
53 | #include <Extrema_ExtPS.hxx> | |
54 | #include <BRep_Tool.hxx> | |
55 | #include <BRepClass_FaceClassifier.hxx> | |
56 | //<-OCC454(apo) | |
be7c077a | 57 | #include <BRepTopAdaptor_FClass2d.hxx> |
58 | ||
7fd59977 | 59 | |
60 | //======================================================================= | |
61 | //function : FindAPointInTheFace | |
0d969553 | 62 | //purpose : Compute a point P in the face F. Param is a Real in |
7fd59977 | 63 | // ]0,1[ and is used to initialise the algorithm. For |
64 | // different values , different points are returned. | |
65 | //======================================================================= | |
66 | ||
67 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
68 | (const TopoDS_Face& _face, | |
69 | gp_Pnt& APoint_, | |
41194117 K |
70 | Standard_Real& param_) |
71 | { | |
7fd59977 | 72 | Standard_Real u,v; |
73 | Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u,v,param_); | |
74 | return r; | |
75 | } | |
76 | ||
77 | //======================================================================= | |
78 | //function : FindAPointInTheFace | |
79 | //purpose : | |
80 | //======================================================================= | |
81 | ||
82 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
83 | (const TopoDS_Face& _face, | |
84 | gp_Pnt& APoint_, | |
85 | Standard_Real& u_, Standard_Real& v_, | |
41194117 K |
86 | Standard_Real& param_) |
87 | { | |
88 | gp_Vec aVecD1U, aVecD1V; | |
89 | return FindAPointInTheFace (_face, APoint_, u_, v_, param_, aVecD1U, aVecD1V); | |
90 | } | |
91 | ||
92 | //======================================================================= | |
93 | //function : FindAPointInTheFace | |
94 | //purpose : | |
95 | //======================================================================= | |
96 | ||
97 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
98 | (const TopoDS_Face& _face, | |
99 | gp_Pnt& APoint_, | |
100 | Standard_Real& u_, Standard_Real& v_, | |
101 | Standard_Real& param_, | |
102 | gp_Vec& theVecD1U, | |
103 | gp_Vec& theVecD1V) | |
104 | { | |
105 | TopoDS_Face face = _face; | |
106 | face.Orientation (TopAbs_FORWARD); | |
107 | ||
108 | TopExp_Explorer faceexplorer; | |
7fd59977 | 109 | BRepAdaptor_Curve2d c; |
110 | gp_Vec2d T; | |
111 | gp_Pnt2d P; | |
41194117 | 112 | |
7fd59977 | 113 | for (faceexplorer.Init(face,TopAbs_EDGE); |
114 | faceexplorer.More(); | |
41194117 K |
115 | faceexplorer.Next()) |
116 | { | |
117 | TopoDS_Edge Edge = TopoDS::Edge (faceexplorer.Current()); | |
118 | c.Initialize (Edge, face); | |
41194117 K |
119 | c.D1((c.LastParameter() - c.FirstParameter()) * param_ + c.FirstParameter(),P,T); |
120 | ||
121 | Standard_Real x = T.X(); | |
122 | Standard_Real y = T.Y(); | |
123 | if (Edge.Orientation() == TopAbs_FORWARD) | |
124 | { | |
125 | T.SetCoord (-y, x); | |
126 | } | |
127 | else | |
128 | { | |
129 | T.SetCoord ( y, -x); | |
130 | } | |
131 | Standard_Real ParamInit = RealLast(); | |
132 | Standard_Real TolInit = 0.00001; | |
133 | Standard_Boolean APointExist = Standard_False; | |
134 | ||
135 | BRepClass_FacePassiveClassifier FClassifier; | |
136 | ||
137 | T.Normalize(); | |
138 | P.SetCoord (P.X() + TolInit * T.X(), P.Y() + TolInit * T.Y()); | |
139 | FClassifier.Reset (gp_Lin2d (P, T), ParamInit, RealEpsilon()); //-- Length and Tolerance ####### | |
140 | ||
141 | TopExp_Explorer otherfaceexplorer; | |
142 | Standard_Integer aNbEdges = 0; | |
143 | for (otherfaceexplorer.Init (face, TopAbs_EDGE); | |
144 | otherfaceexplorer.More(); | |
145 | otherfaceexplorer.Next(), ++aNbEdges) | |
146 | { | |
147 | TopoDS_Edge OtherEdge = TopoDS::Edge (otherfaceexplorer.Current()); | |
148 | if (OtherEdge.Orientation() != TopAbs_EXTERNAL && OtherEdge != Edge) | |
149 | { | |
150 | BRepClass_Edge AEdge (OtherEdge, face); | |
151 | FClassifier.Compare (AEdge, OtherEdge.Orientation()); | |
152 | if (FClassifier.ClosestIntersection()) | |
153 | { | |
154 | if(ParamInit > FClassifier.Parameter()) | |
155 | { | |
156 | ParamInit = FClassifier.Parameter(); | |
157 | APointExist = Standard_True; | |
158 | } | |
159 | } | |
7fd59977 | 160 | } |
41194117 K |
161 | } |
162 | ||
163 | if (aNbEdges == 1) | |
164 | { | |
165 | BRepClass_Edge AEdge (Edge, face); | |
166 | FClassifier.Compare (AEdge, Edge.Orientation()); | |
167 | if (FClassifier.ClosestIntersection()) | |
168 | { | |
169 | if (ParamInit > FClassifier.Parameter()) | |
170 | { | |
171 | ParamInit = FClassifier.Parameter(); | |
172 | APointExist = Standard_True; | |
173 | } | |
7fd59977 | 174 | } |
175 | } | |
41194117 | 176 | |
b9cd9e62 | 177 | while (APointExist) |
41194117 K |
178 | { |
179 | ParamInit *= 0.41234; | |
180 | u_ = P.X() + ParamInit* T.X(); | |
181 | v_ = P.Y() + ParamInit* T.Y(); | |
be7c077a | 182 | |
183 | //Additional check | |
184 | BRepTopAdaptor_FClass2d Classifier(face, Precision::Confusion()); | |
185 | gp_Pnt2d aPnt2d(u_, v_); | |
186 | TopAbs_State StateOfResultingPoint = Classifier.Perform(aPnt2d); | |
187 | if (StateOfResultingPoint != TopAbs_IN) | |
188 | return Standard_False; | |
189 | ||
41194117 K |
190 | BRepAdaptor_Surface s; |
191 | s.Initialize (face, Standard_False); | |
192 | s.D1 (u_, v_, APoint_, theVecD1U, theVecD1V); | |
b9cd9e62 | 193 | |
194 | if(theVecD1U.CrossMagnitude(theVecD1V) > gp::Resolution()) | |
195 | return Standard_True; | |
196 | ||
197 | if(ParamInit < Precision::PConfusion()) | |
198 | return Standard_False; | |
41194117 | 199 | } |
7fd59977 | 200 | } |
41194117 K |
201 | return Standard_False; |
202 | } | |
203 | ||
204 | //======================================================================= | |
205 | //function : PointInTheFace | |
206 | //purpose : | |
207 | //======================================================================= | |
208 | ||
209 | Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace | |
210 | (const TopoDS_Face& Face, | |
211 | gp_Pnt& APoint_, | |
212 | Standard_Real& u_, Standard_Real& v_, | |
213 | Standard_Real& param_, | |
214 | Standard_Integer& IndexPoint, | |
215 | const Handle(BRepAdaptor_HSurface)& surf, | |
216 | const Standard_Real U1, | |
217 | const Standard_Real V1, | |
218 | const Standard_Real U2, | |
219 | const Standard_Real V2) const | |
220 | { | |
221 | gp_Vec aVecD1U, aVecD1V; | |
222 | return PointInTheFace (Face, APoint_, u_, v_, param_, IndexPoint, surf, | |
223 | U1, V1, U2, V2, aVecD1U, aVecD1V); | |
7fd59977 | 224 | } |
225 | ||
226 | //======================================================================= | |
227 | //function : PointInTheFace | |
228 | //purpose : | |
229 | //======================================================================= | |
230 | ||
231 | Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace | |
232 | (const TopoDS_Face& Face, | |
233 | gp_Pnt& APoint_, | |
234 | Standard_Real& u_, Standard_Real& v_, | |
235 | Standard_Real& param_, | |
236 | Standard_Integer& IndexPoint, | |
237 | const Handle(BRepAdaptor_HSurface)& surf, | |
238 | const Standard_Real U1, | |
239 | const Standard_Real V1, | |
240 | const Standard_Real U2, | |
41194117 K |
241 | const Standard_Real V2, |
242 | gp_Vec& theVecD1U, | |
243 | gp_Vec& theVecD1V) const | |
244 | { | |
7fd59977 | 245 | Standard_Real u,du = (U2-U1)/6.0; |
246 | Standard_Real v,dv = (V2-V1)/6.0; | |
247 | if(du<1e-12) du=1e-12; | |
248 | if(dv<1e-12) dv=1e-12; | |
249 | Standard_Integer NbPntCalc=0; | |
250 | if(myMapOfInter.IsBound(Face)) { | |
251 | void *ptr = (void*)(myMapOfInter.Find(Face)); | |
252 | if(ptr) { | |
253 | const IntCurvesFace_Intersector& TheIntersector = (*((IntCurvesFace_Intersector *)ptr)); | |
0d969553 | 254 | //-- Take 4 points in each Quarter of surface |
7fd59977 | 255 | //-- -> Index : 1 -> 16 |
256 | //-- | |
257 | //-- | |
0d969553 | 258 | //-- Then take a matrix of points on a tight grid |
7fd59977 | 259 | //-- |
0d969553 Y |
260 | for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 X u increases |
261 | for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases | |
7fd59977 | 262 | if(++NbPntCalc>=IndexPoint) { |
263 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
264 | u_=u; v_=v; | |
41194117 K |
265 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); |
266 | IndexPoint = NbPntCalc; | |
7fd59977 | 267 | return(Standard_True); |
268 | } | |
269 | } | |
270 | } | |
271 | } | |
aa74e235 | 272 | |
0d969553 | 273 | for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- 0 0 u decreases |
aa74e235 | 274 | for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- X 0 v decreases |
275 | if(++NbPntCalc>=IndexPoint) { | |
276 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
277 | u_=u; v_=v; | |
278 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
279 | IndexPoint = NbPntCalc; | |
280 | return(Standard_True); | |
281 | } | |
282 | } | |
283 | } | |
7fd59977 | 284 | } |
0d969553 | 285 | for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- X 0 u decreases |
aa74e235 | 286 | for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases |
287 | if(++NbPntCalc>=IndexPoint) { | |
288 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
289 | u_=u; v_=v; | |
290 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
291 | IndexPoint = NbPntCalc; | |
292 | return(Standard_True); | |
293 | } | |
294 | } | |
295 | } | |
7fd59977 | 296 | } |
0d969553 | 297 | for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 0 u increases |
aa74e235 | 298 | for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- 0 X v decreases |
299 | if(++NbPntCalc>=IndexPoint) { | |
300 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
301 | u_=u; v_=v; | |
302 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
303 | IndexPoint = NbPntCalc; | |
304 | return(Standard_True); | |
305 | } | |
306 | } | |
307 | } | |
7fd59977 | 308 | } |
0d969553 | 309 | //-- the remainder |
7fd59977 | 310 | du = (U2-U1)/37.0; |
311 | dv = (V2-V1)/37.0; | |
312 | if(du<1e-12) du=1e-12; | |
313 | if(dv<1e-12) dv=1e-12; | |
314 | ||
315 | for(u=du+U1; u<U2; u+=du) { | |
aa74e235 | 316 | for(v=dv+V1; v<V2; v+=dv) { |
317 | if(++NbPntCalc>=IndexPoint) { | |
318 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
319 | u_=u; v_=v; | |
320 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
321 | IndexPoint = NbPntCalc; | |
322 | return(Standard_True); | |
323 | } | |
324 | } | |
325 | } | |
7fd59977 | 326 | } |
327 | u=(U1+U2)*0.5; | |
328 | v=(V1+V2)*0.5; | |
329 | if(++NbPntCalc>=IndexPoint) { | |
aa74e235 | 330 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { |
331 | u_=u; v_=v; | |
332 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
333 | IndexPoint = NbPntCalc; | |
334 | return(Standard_True); | |
335 | } | |
7fd59977 | 336 | } |
337 | } | |
338 | IndexPoint = NbPntCalc; | |
339 | } | |
340 | else { | |
0d969553 | 341 | //printf("BRepClass3d_SolidExplorer Face not found ds the map \n"); |
7fd59977 | 342 | } |
41194117 K |
343 | |
344 | return BRepClass3d_SolidExplorer | |
345 | ::FindAPointInTheFace (Face,APoint_, u_, v_, param_, theVecD1U, theVecD1V); | |
7fd59977 | 346 | } |
347 | ||
348 | //======================================================================= | |
349 | //function : LimitInfiniteUV | |
350 | //purpose : Limit infinite parameters | |
351 | //======================================================================= | |
7fd59977 | 352 | static void LimitInfiniteUV (Standard_Real& U1, |
aa74e235 | 353 | Standard_Real& V1, |
354 | Standard_Real& U2, | |
355 | Standard_Real& V2) | |
7fd59977 | 356 | { |
357 | Standard_Boolean | |
358 | infU1 = Precision::IsNegativeInfinite(U1), | |
359 | infV1 = Precision::IsNegativeInfinite(V1), | |
360 | infU2 = Precision::IsPositiveInfinite(U2), | |
361 | infV2 = Precision::IsPositiveInfinite(V2); | |
362 | ||
363 | if (infU1) U1 = -1e10; | |
364 | if (infV1) V1 = -1e10; | |
365 | if (infU2) U2 = 1e10; | |
366 | if (infV2) V2 = 1e10; | |
367 | } | |
88cc4cb8 | 368 | //======================================================================= |
369 | //function : IsInfiniteUV | |
370 | //purpose : | |
371 | //======================================================================= | |
372 | static Standard_Integer IsInfiniteUV (Standard_Real& U1, | |
aa74e235 | 373 | Standard_Real& V1, |
374 | Standard_Real& U2, | |
375 | Standard_Real& V2) | |
88cc4cb8 | 376 | { |
7fd59977 | 377 | Standard_Integer aVal = 0; |
378 | ||
379 | if (Precision::IsInfinite(U1)) | |
380 | aVal |= 1; | |
381 | ||
382 | if (Precision::IsInfinite(V1)) | |
383 | aVal |= 2; | |
384 | ||
385 | if (Precision::IsInfinite(U2)) | |
386 | aVal |= 4; | |
387 | ||
388 | if (Precision::IsInfinite(V2)) | |
389 | aVal |= 8; | |
390 | ||
391 | return aVal; | |
392 | } | |
393 | //<-OCC454 | |
394 | // Modified by skv - Tue Sep 16 13:50:39 2003 OCC578 End | |
395 | //======================================================================= | |
396 | //function : OtherSegment | |
397 | //purpose : Returns in <L>, <Par> a segment having at least | |
398 | // one intersection with the shape boundary to | |
399 | // compute intersections. | |
400 | // The First Call to this method returns a line which | |
401 | // point to a point of the first face of the shape. | |
402 | // The Second Call provide a line to the second face | |
403 | // and so on. | |
404 | //======================================================================= | |
88cc4cb8 | 405 | Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P, |
aa74e235 | 406 | gp_Lin& L, |
407 | Standard_Real& _Par) | |
7fd59977 | 408 | { |
41194117 K |
409 | const Standard_Real TolU = Precision::PConfusion(); |
410 | const Standard_Real TolV = TolU; | |
411 | ||
7fd59977 | 412 | TopoDS_Face face; |
413 | TopExp_Explorer faceexplorer; | |
7fd59977 | 414 | gp_Pnt APoint; |
41194117 | 415 | gp_Vec aVecD1U, aVecD1V; |
7fd59977 | 416 | Standard_Real maxscal=0; |
417 | Standard_Boolean ptfound=Standard_False; | |
418 | Standard_Real Par; | |
7fd59977 | 419 | Standard_Real _u,_v; |
420 | Standard_Integer IndexPoint=0; | |
421 | Standard_Integer NbPointsOK=0; | |
422 | Standard_Integer NbFacesInSolid=0; | |
423 | ||
302f96fb | 424 | for(;;) { |
7fd59977 | 425 | myFirstFace++; |
426 | faceexplorer.Init(myShape,TopAbs_FACE); | |
427 | // look for point on face starting from myFirstFace | |
428 | // Modified by skv - Thu Sep 4 14:31:12 2003 OCC578 Begin | |
429 | // while (faceexplorer.More()) { | |
430 | for (; faceexplorer.More(); faceexplorer.Next()) { | |
431 | // Modified by skv - Thu Sep 4 14:31:12 2003 OCC578 End | |
432 | NbFacesInSolid++; | |
433 | if (myFirstFace > NbFacesInSolid) continue; | |
434 | face = TopoDS::Face(faceexplorer.Current()); | |
435 | ||
436 | Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface(); | |
437 | surf->ChangeSurface().Initialize(face); | |
438 | Standard_Real U1,V1,U2,V2; | |
439 | U1 = surf->FirstUParameter(); | |
440 | V1 = surf->FirstVParameter(); | |
441 | U2 = surf->LastUParameter(); | |
442 | V2 = surf->LastVParameter(); | |
443 | face.Orientation(TopAbs_FORWARD); | |
444 | // | |
445 | //avoid process faces from uncorrected shells | |
446 | if( Abs (U2 - U1) < 1.e-12 || Abs(V2 - V1) < 1.e-12) { | |
aa74e235 | 447 | return 2; |
7fd59977 | 448 | } |
449 | // | |
450 | Standard_Real svmyparam=myParamOnEdge; | |
451 | // | |
7fd59977 | 452 | // Check if the point is on the face or the face is infinite. |
453 | Standard_Integer anInfFlag = IsInfiniteUV(U1,V1,U2,V2); | |
454 | ||
7fd59977 | 455 | GeomAdaptor_Surface GA(BRep_Tool::Surface(face)); |
88cc4cb8 | 456 | Extrema_ExtPS Ext(P, GA, TolU, TolV); |
457 | // | |
7fd59977 | 458 | if (Ext.IsDone() && Ext.NbExt() > 0) { |
aa74e235 | 459 | Standard_Integer i, iNear, iEnd; |
460 | Standard_Real aUx, aVx, Dist2, Dist2Min; | |
461 | Extrema_POnSurf aPx; | |
462 | // | |
463 | iNear = 1; | |
464 | Dist2Min = Ext.SquareDistance(1); | |
465 | iEnd = Ext.NbExt(); | |
466 | for (i = 2; i <= iEnd; i++) { | |
467 | aPx=Ext.Point(i); | |
468 | aPx.Parameter(aUx, aVx); | |
469 | if (aUx>=U1 && aUx<=U2 && aVx>=V1 && aVx<=V2) { | |
470 | Dist2 = Ext.SquareDistance(i); | |
471 | if (Dist2 < Dist2Min) { | |
472 | Dist2Min = Dist2; | |
473 | iNear = i; | |
474 | } | |
475 | } | |
476 | } | |
477 | // | |
478 | Standard_Real aDist2Tresh=1.e-24; | |
479 | // | |
480 | if (Dist2Min<aDist2Tresh) { | |
481 | if (anInfFlag) { | |
482 | return 1; | |
483 | } | |
484 | else { | |
485 | BRepClass_FaceClassifier classifier2d; | |
486 | Standard_Real aU; | |
487 | Standard_Real aV; | |
488 | ||
489 | (Ext.Point(iNear)).Parameter(aU, aV); | |
490 | ||
491 | gp_Pnt2d aPuv(aU, aV); | |
492 | ||
493 | classifier2d.Perform(face,aPuv,Precision::PConfusion()); | |
494 | ||
495 | TopAbs_State aState = classifier2d.State(); | |
496 | ||
497 | if (aState == TopAbs_IN || aState == TopAbs_ON) { | |
498 | return 1; | |
499 | } | |
500 | else { | |
501 | return 3; // skv - the point is on surface but outside face. | |
502 | } | |
503 | } | |
504 | } | |
505 | if (anInfFlag) { | |
506 | APoint = (Ext.Point(iNear)).Value(); | |
507 | gp_Vec V(P,APoint); | |
508 | _Par = V.Magnitude(); | |
509 | L = gp_Lin(P,V); | |
510 | ptfound=Standard_True; | |
511 | return 0; | |
512 | } | |
7fd59977 | 513 | } |
514 | //The point is not ON the face or surface. The face is restricted. | |
515 | // find point in a face not too far from a projection of P on face | |
41194117 K |
516 | do { |
517 | if (PointInTheFace (face, APoint, _u, _v, myParamOnEdge, ++IndexPoint, surf, | |
518 | U1, V1, U2, V2, | |
519 | aVecD1U, aVecD1V)) | |
520 | { | |
521 | ++NbPointsOK; | |
522 | gp_Vec V (P, APoint); | |
523 | Par = V.Magnitude(); | |
aa74e235 | 524 | if (Par > gp::Resolution() && |
525 | aVecD1U.Magnitude() > gp::Resolution() && | |
526 | aVecD1V.Magnitude() > gp::Resolution()) | |
41194117 K |
527 | { |
528 | gp_Vec Norm = aVecD1U.Crossed (aVecD1V); | |
529 | Standard_Real tt = Norm.Magnitude(); | |
530 | tt = Abs (Norm.Dot (V)) / (tt * Par); | |
531 | if (tt > maxscal) | |
532 | { | |
533 | maxscal = tt; | |
534 | L = gp_Lin (P, V); | |
535 | _Par = Par; | |
536 | ptfound = Standard_True; | |
537 | if (maxscal>0.2) | |
538 | { | |
539 | myParamOnEdge=svmyparam; | |
540 | return 0; | |
541 | } | |
542 | } | |
543 | } | |
544 | } | |
7fd59977 | 545 | } |
546 | while(IndexPoint<200 && NbPointsOK<16); | |
547 | ||
548 | myParamOnEdge=svmyparam; | |
aa74e235 | 549 | if(maxscal>0.2) { |
550 | return 0; | |
7fd59977 | 551 | } |
552 | ||
553 | ||
554 | // Modified by skv - Thu Sep 4 14:32:14 2003 OCC578 Begin | |
555 | // Next is done in the main for(..) loop. | |
556 | // faceexplorer.Next(); | |
557 | // Modified by skv - Thu Sep 4 14:32:14 2003 OCC578 End | |
558 | IndexPoint = 0; | |
559 | ||
560 | Standard_Boolean encoreuneface = faceexplorer.More(); | |
561 | if(ptfound==Standard_False && encoreuneface==Standard_False) { | |
aa74e235 | 562 | if(myParamOnEdge < 0.0001) { |
563 | //-- This case takes place when the point is on the solid | |
564 | //-- and this solid is reduced to a face | |
565 | gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z()); | |
566 | gp_Vec V(P,PBidon); | |
567 | Par= 1.0; | |
568 | _Par=Par; | |
569 | L = gp_Lin(P,V); | |
570 | return 0; | |
571 | } | |
7fd59977 | 572 | } |
573 | } //-- Exploration of the faces | |
574 | ||
575 | if(NbFacesInSolid==0) { | |
576 | _Par=0.0; | |
577 | myReject=Standard_True; | |
578 | #if DEB | |
0d969553 | 579 | cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx (Solid without face)"<<endl; |
7fd59977 | 580 | #endif |
7fd59977 | 581 | return 0; |
7fd59977 | 582 | } |
583 | ||
584 | if(ptfound) { | |
7fd59977 | 585 | return 0; |
7fd59977 | 586 | } |
587 | myFirstFace = 0; | |
588 | if(myParamOnEdge==0.512345) myParamOnEdge = 0.4; | |
589 | else if(myParamOnEdge==0.4) myParamOnEdge = 0.6; | |
590 | else if(myParamOnEdge==0.6) myParamOnEdge = 0.3; | |
591 | else if(myParamOnEdge==0.3) myParamOnEdge = 0.7; | |
592 | else if(myParamOnEdge==0.7) myParamOnEdge = 0.2; | |
593 | else if(myParamOnEdge==0.2) myParamOnEdge = 0.8; | |
594 | else if(myParamOnEdge==0.8) myParamOnEdge = 0.1; | |
595 | else if(myParamOnEdge==0.1) myParamOnEdge = 0.9; | |
1da5279e | 596 | // |
597 | else { | |
598 | myParamOnEdge*=0.5; | |
599 | if(myParamOnEdge < 0.0001) { | |
aa74e235 | 600 | gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z()); |
601 | gp_Vec V(P,PBidon); | |
602 | Par= 1.0; | |
603 | _Par=Par; | |
604 | L = gp_Lin(P,V); | |
605 | return 0; | |
1da5279e | 606 | } |
607 | } | |
302f96fb | 608 | } //-- for(;;) { ... } |
7fd59977 | 609 | } |
610 | ||
611 | // Modified by skv - Thu Sep 4 12:30:14 2003 OCC578 Begin | |
612 | //======================================================================= | |
613 | //function : GetFaceSegmentIndex | |
614 | //purpose : Returns the index of face for which last segment is calculated. | |
615 | //======================================================================= | |
616 | ||
617 | Standard_Integer BRepClass3d_SolidExplorer::GetFaceSegmentIndex() const | |
618 | { | |
619 | return myFirstFace; | |
620 | } | |
621 | // Modified by skv - Thu Sep 4 12:30:14 2003 OCC578 End | |
622 | ||
623 | //======================================================================= | |
624 | //function : PointInTheFace | |
625 | //purpose : | |
626 | //======================================================================= | |
627 | ||
628 | Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace | |
629 | (const TopoDS_Face& _face, | |
630 | gp_Pnt& APoint_, | |
631 | Standard_Real& u_, Standard_Real& v_, | |
632 | Standard_Real& param_, | |
633 | Standard_Integer& IndexPoint) const | |
634 | { | |
635 | TopoDS_Face Face = _face; | |
636 | Face.Orientation(TopAbs_FORWARD); | |
637 | Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface(); | |
638 | surf->ChangeSurface().Initialize(Face); | |
639 | Standard_Real U1,V1,U2,V2;//,u,v; | |
640 | U1 = surf->FirstUParameter(); | |
641 | V1 = surf->FirstVParameter(); | |
642 | U2 = surf->LastUParameter(); | |
643 | V2 = surf->LastVParameter(); | |
644 | LimitInfiniteUV (U1,V1,U2,V2); | |
645 | return(PointInTheFace(Face,APoint_,u_,v_,param_,IndexPoint,surf,U1,V1,U2,V2)); | |
646 | } | |
647 | ||
648 | //======================================================================= | |
649 | //function : FindAPointInTheFace | |
650 | //purpose : | |
651 | //======================================================================= | |
652 | ||
653 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
654 | (const TopoDS_Face& _face, | |
655 | gp_Pnt& APoint_, | |
656 | Standard_Real& u_,Standard_Real& v_) | |
657 | { | |
658 | Standard_Real param = 0.1; | |
659 | Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u_,v_,param); | |
660 | return r; | |
661 | } | |
662 | ||
663 | //======================================================================= | |
664 | //function : FindAPointInTheFace | |
665 | //purpose : | |
666 | //======================================================================= | |
667 | ||
668 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
669 | (const TopoDS_Face& _face, | |
670 | gp_Pnt& APoint_) | |
671 | { Standard_Real u,v; | |
672 | Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u,v); | |
673 | return r; | |
674 | } | |
675 | ||
676 | //======================================================================= | |
677 | //function : FindAPointInTheFace | |
678 | //purpose : | |
679 | //======================================================================= | |
680 | ||
681 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
682 | (const TopoDS_Face& _face, | |
683 | Standard_Real& u_,Standard_Real& v_) | |
684 | { gp_Pnt APoint; | |
685 | Standard_Boolean r = FindAPointInTheFace(_face,APoint,u_,v_); | |
686 | return r; | |
687 | } | |
688 | ||
689 | //======================================================================= | |
690 | //function : BRepClass3d_SolidExplorer | |
691 | //purpose : | |
692 | //======================================================================= | |
693 | ||
694 | BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer() | |
695 | { | |
696 | } | |
697 | #include <Standard_ConstructionError.hxx> | |
698 | ||
699 | //======================================================================= | |
700 | //function : BRepClass3d_SolidExplorer | |
701 | //purpose : Raise if called. | |
702 | //======================================================================= | |
703 | ||
704 | //BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& Oth) | |
705 | BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& ) | |
706 | { | |
707 | Standard_ConstructionError::Raise("Magic constructor not allowed"); | |
708 | } | |
709 | ||
710 | //======================================================================= | |
711 | //function : BRepClass3d_SolidExplorer | |
712 | //purpose : | |
713 | //======================================================================= | |
714 | ||
715 | BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const TopoDS_Shape& S) | |
716 | { | |
717 | InitShape(S); | |
718 | } | |
719 | ||
720 | //======================================================================= | |
721 | //function : Delete | |
722 | //purpose : | |
723 | //======================================================================= | |
724 | ||
725 | void BRepClass3d_SolidExplorer::Delete() | |
726 | { | |
727 | Destroy() ; | |
728 | } | |
729 | ||
730 | //======================================================================= | |
731 | //function : Destroy | |
732 | //purpose : C++: alias ~ | |
733 | //======================================================================= | |
734 | ||
735 | void BRepClass3d_SolidExplorer::Destroy() { | |
736 | BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter); | |
737 | for(;iter.More();iter.Next()) { | |
738 | void *ptr=iter.Value(); | |
739 | if(ptr) { | |
740 | delete (IntCurvesFace_Intersector *)ptr; | |
741 | myMapOfInter.ChangeFind(iter.Key()) = NULL; | |
742 | } | |
743 | } | |
744 | myMapOfInter.Clear(); | |
745 | } | |
746 | ||
747 | //======================================================================= | |
748 | //function : InitShape | |
749 | //purpose : | |
750 | //======================================================================= | |
751 | ||
752 | void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S) | |
753 | { | |
754 | myShape = S; | |
755 | myFirstFace = 0; | |
756 | myParamOnEdge = 0.512345; | |
0d969553 | 757 | //-- Exploring of the Map and removal of allocated objects |
7fd59977 | 758 | |
759 | ||
760 | BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter); | |
761 | for(;iter.More();iter.Next()) { | |
762 | void *ptr=iter.Value(); | |
763 | if(ptr) { | |
764 | delete (IntCurvesFace_Intersector *)ptr; | |
765 | myMapOfInter.ChangeFind(iter.Key()) = NULL; | |
766 | } | |
767 | } | |
768 | ||
769 | myMapOfInter.Clear(); | |
770 | ||
0d969553 | 771 | myReject = Standard_True; //-- case of infinite solid (without any face) |
7fd59977 | 772 | |
773 | TopExp_Explorer Expl; | |
774 | for(Expl.Init(S,TopAbs_FACE); | |
775 | Expl.More(); | |
776 | Expl.Next()) { | |
777 | const TopoDS_Face Face = TopoDS::Face(Expl.Current()); | |
778 | void *ptr = (void *)(new IntCurvesFace_Intersector(Face,Precision::Confusion())); | |
779 | myMapOfInter.Bind(Face,ptr); | |
0d969553 | 780 | myReject=Standard_False; //-- at least one face in the solid |
7fd59977 | 781 | } |
782 | ||
783 | #if DEB | |
784 | if(myReject) { | |
0d969553 | 785 | cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx (Solid without face)"<<endl; |
7fd59977 | 786 | } |
787 | #endif | |
788 | ||
789 | #if REJECTION | |
790 | BRepBndLib::Add(myShape,myBox); | |
791 | #endif | |
792 | } | |
793 | ||
794 | //======================================================================= | |
795 | //function : Reject | |
796 | //purpose : Should return True if P outside of bounding vol. of the shape | |
797 | //======================================================================= | |
798 | ||
799 | //Standard_Boolean BRepClass3d_SolidExplorer::Reject(const gp_Pnt& P) const | |
800 | Standard_Boolean BRepClass3d_SolidExplorer::Reject(const gp_Pnt& ) const | |
801 | { | |
0d969553 | 802 | return(myReject); // case of solid without face |
7fd59977 | 803 | } |
804 | ||
805 | //======================================================================= | |
806 | //function : InitShell | |
807 | //purpose : Starts an exploration of the shells. | |
808 | //======================================================================= | |
809 | ||
810 | void BRepClass3d_SolidExplorer::InitShell() | |
811 | { | |
812 | myShellExplorer.Init(myShape,TopAbs_SHELL); | |
813 | } | |
814 | ||
815 | //======================================================================= | |
816 | //function : MoreShell | |
817 | //purpose : Returns True if there is a current shell. | |
818 | //======================================================================= | |
819 | ||
820 | Standard_Boolean BRepClass3d_SolidExplorer::MoreShell() const | |
821 | { | |
822 | return(myShellExplorer.More()); | |
823 | } | |
824 | ||
825 | //======================================================================= | |
826 | //function : NextShell | |
827 | //purpose : Sets the explorer to the next shell. | |
828 | //======================================================================= | |
829 | ||
830 | void BRepClass3d_SolidExplorer::NextShell() | |
831 | { | |
832 | myShellExplorer.Next(); | |
833 | } | |
834 | ||
835 | //======================================================================= | |
836 | //function : CurrentShell | |
837 | //purpose : Returns the current shell. | |
838 | //======================================================================= | |
839 | ||
840 | TopoDS_Shell BRepClass3d_SolidExplorer::CurrentShell() const | |
841 | { | |
842 | return(TopoDS::Shell(myShellExplorer.Current())); | |
843 | } | |
844 | ||
845 | //======================================================================= | |
846 | //function : RejectShell | |
847 | //purpose : Returns True if the Shell is rejected. | |
848 | //======================================================================= | |
849 | ||
850 | Standard_Boolean BRepClass3d_SolidExplorer::RejectShell(const gp_Lin& ) const | |
851 | { | |
852 | return(Standard_False); | |
853 | } | |
854 | ||
855 | //======================================================================= | |
856 | //function : InitFace | |
857 | //purpose : Starts an exploration of the faces of the current shell. | |
858 | //======================================================================= | |
859 | ||
860 | void BRepClass3d_SolidExplorer::InitFace() | |
861 | { | |
862 | myFaceExplorer.Init(TopoDS::Shell(myShellExplorer.Current()),TopAbs_FACE); | |
863 | } | |
864 | ||
865 | //======================================================================= | |
866 | //function : MoreFace | |
867 | //purpose : Returns True if current face in current shell. | |
868 | //======================================================================= | |
869 | ||
870 | Standard_Boolean BRepClass3d_SolidExplorer::MoreFace() const | |
871 | { | |
872 | return(myFaceExplorer.More()); | |
873 | } | |
874 | ||
875 | //======================================================================= | |
876 | //function : NextFace | |
877 | //purpose : Sets the explorer to the next Face of the current shell. | |
878 | //======================================================================= | |
879 | ||
880 | void BRepClass3d_SolidExplorer::NextFace() | |
881 | { | |
882 | myFaceExplorer.Next(); | |
883 | } | |
884 | ||
885 | //======================================================================= | |
886 | //function : CurrentFace | |
887 | //purpose : Returns the current face. | |
888 | //======================================================================= | |
889 | ||
890 | TopoDS_Face BRepClass3d_SolidExplorer::CurrentFace() const | |
891 | { | |
892 | return(TopoDS::Face(myFaceExplorer.Current())); | |
893 | } | |
894 | ||
895 | //======================================================================= | |
896 | //function : RejectFace | |
897 | //purpose : returns True if the face is rejected. | |
898 | //======================================================================= | |
899 | ||
900 | Standard_Boolean BRepClass3d_SolidExplorer::RejectFace(const gp_Lin& ) const | |
901 | { | |
902 | return(Standard_False); | |
903 | } | |
904 | ||
905 | #ifdef DEB | |
906 | #include <TopAbs_State.hxx> | |
907 | #endif | |
908 | ||
909 | //======================================================================= | |
910 | //function : Segment | |
911 | //purpose : Returns in <L>, <Par> a segment having at least | |
912 | // one intersection with the shape boundary to | |
913 | // compute intersections. | |
914 | //======================================================================= | |
88cc4cb8 | 915 | Standard_Integer BRepClass3d_SolidExplorer::Segment(const gp_Pnt& P, |
aa74e235 | 916 | gp_Lin& L, |
917 | Standard_Real& Par) | |
7fd59977 | 918 | { |
919 | Standard_Integer bRetFlag; | |
920 | myFirstFace = 0; | |
921 | bRetFlag=OtherSegment(P,L,Par); | |
922 | return bRetFlag; | |
923 | } | |
7fd59977 | 924 | |
925 | //======================================================================= | |
926 | //function : Intersector | |
927 | //purpose : | |
928 | //======================================================================= | |
929 | ||
930 | IntCurvesFace_Intersector& BRepClass3d_SolidExplorer::Intersector(const TopoDS_Face& F) const { | |
931 | void *ptr = (void*)(myMapOfInter.Find(F)); | |
7fd59977 | 932 | IntCurvesFace_Intersector& curr = (*((IntCurvesFace_Intersector *)ptr)); |
933 | return curr; | |
7fd59977 | 934 | } |
935 | ||
936 | //======================================================================= | |
937 | //function : Box | |
938 | //purpose : | |
939 | //======================================================================= | |
940 | ||
941 | const Bnd_Box& BRepClass3d_SolidExplorer::Box() const { | |
942 | return(myBox); | |
943 | } | |
944 | ||
945 | //======================================================================= | |
946 | //function : DumpSegment | |
947 | //purpose : | |
948 | //======================================================================= | |
949 | ||
950 | void BRepClass3d_SolidExplorer::DumpSegment(const gp_Pnt&, | |
aa74e235 | 951 | const gp_Lin&, |
952 | const Standard_Real, | |
953 | const TopAbs_State) const | |
7fd59977 | 954 | { |
955 | #ifdef DEB | |
0d969553 | 956 | |
7fd59977 | 957 | #endif |
958 | } |