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)); | |
3922a2ec | 254 | // Check if the point is already in the face |
255 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u_,v_))==TopAbs_IN) { | |
256 | gp_Pnt aPnt; | |
257 | surf->D1(u_, v_, aPnt, theVecD1U, theVecD1V); | |
258 | if (aPnt.SquareDistance(APoint_) < Precision::Confusion() * Precision::Confusion()) | |
259 | return Standard_True; | |
260 | } | |
261 | ||
0d969553 | 262 | //-- Take 4 points in each Quarter of surface |
7fd59977 | 263 | //-- -> Index : 1 -> 16 |
264 | //-- | |
265 | //-- | |
0d969553 | 266 | //-- Then take a matrix of points on a tight grid |
7fd59977 | 267 | //-- |
0d969553 Y |
268 | for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 X u increases |
269 | for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases | |
7fd59977 | 270 | if(++NbPntCalc>=IndexPoint) { |
271 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
272 | u_=u; v_=v; | |
41194117 K |
273 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); |
274 | IndexPoint = NbPntCalc; | |
7fd59977 | 275 | return(Standard_True); |
276 | } | |
277 | } | |
278 | } | |
279 | } | |
aa74e235 | 280 | |
0d969553 | 281 | for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- 0 0 u decreases |
aa74e235 | 282 | for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- X 0 v decreases |
283 | if(++NbPntCalc>=IndexPoint) { | |
284 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
285 | u_=u; v_=v; | |
286 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
287 | IndexPoint = NbPntCalc; | |
288 | return(Standard_True); | |
289 | } | |
290 | } | |
291 | } | |
7fd59977 | 292 | } |
0d969553 | 293 | for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- X 0 u decreases |
aa74e235 | 294 | for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases |
295 | if(++NbPntCalc>=IndexPoint) { | |
296 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
297 | u_=u; v_=v; | |
298 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
299 | IndexPoint = NbPntCalc; | |
300 | return(Standard_True); | |
301 | } | |
302 | } | |
303 | } | |
7fd59977 | 304 | } |
0d969553 | 305 | for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 0 u increases |
aa74e235 | 306 | for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- 0 X v decreases |
307 | if(++NbPntCalc>=IndexPoint) { | |
308 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
309 | u_=u; v_=v; | |
310 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
311 | IndexPoint = NbPntCalc; | |
312 | return(Standard_True); | |
313 | } | |
314 | } | |
315 | } | |
7fd59977 | 316 | } |
0d969553 | 317 | //-- the remainder |
7fd59977 | 318 | du = (U2-U1)/37.0; |
319 | dv = (V2-V1)/37.0; | |
320 | if(du<1e-12) du=1e-12; | |
321 | if(dv<1e-12) dv=1e-12; | |
322 | ||
323 | for(u=du+U1; u<U2; u+=du) { | |
aa74e235 | 324 | for(v=dv+V1; v<V2; v+=dv) { |
325 | if(++NbPntCalc>=IndexPoint) { | |
326 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { | |
327 | u_=u; v_=v; | |
328 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
329 | IndexPoint = NbPntCalc; | |
330 | return(Standard_True); | |
331 | } | |
332 | } | |
333 | } | |
7fd59977 | 334 | } |
335 | u=(U1+U2)*0.5; | |
336 | v=(V1+V2)*0.5; | |
337 | if(++NbPntCalc>=IndexPoint) { | |
aa74e235 | 338 | if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { |
339 | u_=u; v_=v; | |
340 | surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); | |
341 | IndexPoint = NbPntCalc; | |
342 | return(Standard_True); | |
343 | } | |
7fd59977 | 344 | } |
345 | } | |
346 | IndexPoint = NbPntCalc; | |
347 | } | |
348 | else { | |
0d969553 | 349 | //printf("BRepClass3d_SolidExplorer Face not found ds the map \n"); |
7fd59977 | 350 | } |
41194117 K |
351 | |
352 | return BRepClass3d_SolidExplorer | |
353 | ::FindAPointInTheFace (Face,APoint_, u_, v_, param_, theVecD1U, theVecD1V); | |
7fd59977 | 354 | } |
355 | ||
356 | //======================================================================= | |
357 | //function : LimitInfiniteUV | |
358 | //purpose : Limit infinite parameters | |
359 | //======================================================================= | |
7fd59977 | 360 | static void LimitInfiniteUV (Standard_Real& U1, |
aa74e235 | 361 | Standard_Real& V1, |
362 | Standard_Real& U2, | |
363 | Standard_Real& V2) | |
7fd59977 | 364 | { |
365 | Standard_Boolean | |
366 | infU1 = Precision::IsNegativeInfinite(U1), | |
367 | infV1 = Precision::IsNegativeInfinite(V1), | |
368 | infU2 = Precision::IsPositiveInfinite(U2), | |
369 | infV2 = Precision::IsPositiveInfinite(V2); | |
370 | ||
371 | if (infU1) U1 = -1e10; | |
372 | if (infV1) V1 = -1e10; | |
373 | if (infU2) U2 = 1e10; | |
374 | if (infV2) V2 = 1e10; | |
375 | } | |
88cc4cb8 | 376 | //======================================================================= |
377 | //function : IsInfiniteUV | |
378 | //purpose : | |
379 | //======================================================================= | |
380 | static Standard_Integer IsInfiniteUV (Standard_Real& U1, | |
aa74e235 | 381 | Standard_Real& V1, |
382 | Standard_Real& U2, | |
383 | Standard_Real& V2) | |
88cc4cb8 | 384 | { |
7fd59977 | 385 | Standard_Integer aVal = 0; |
386 | ||
387 | if (Precision::IsInfinite(U1)) | |
388 | aVal |= 1; | |
389 | ||
390 | if (Precision::IsInfinite(V1)) | |
391 | aVal |= 2; | |
392 | ||
393 | if (Precision::IsInfinite(U2)) | |
394 | aVal |= 4; | |
395 | ||
396 | if (Precision::IsInfinite(V2)) | |
397 | aVal |= 8; | |
398 | ||
399 | return aVal; | |
400 | } | |
401 | //<-OCC454 | |
402 | // Modified by skv - Tue Sep 16 13:50:39 2003 OCC578 End | |
403 | //======================================================================= | |
404 | //function : OtherSegment | |
405 | //purpose : Returns in <L>, <Par> a segment having at least | |
406 | // one intersection with the shape boundary to | |
407 | // compute intersections. | |
408 | // The First Call to this method returns a line which | |
409 | // point to a point of the first face of the shape. | |
410 | // The Second Call provide a line to the second face | |
411 | // and so on. | |
412 | //======================================================================= | |
88cc4cb8 | 413 | Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P, |
aa74e235 | 414 | gp_Lin& L, |
415 | Standard_Real& _Par) | |
7fd59977 | 416 | { |
41194117 K |
417 | const Standard_Real TolU = Precision::PConfusion(); |
418 | const Standard_Real TolV = TolU; | |
419 | ||
7fd59977 | 420 | TopoDS_Face face; |
421 | TopExp_Explorer faceexplorer; | |
7fd59977 | 422 | gp_Pnt APoint; |
41194117 | 423 | gp_Vec aVecD1U, aVecD1V; |
7fd59977 | 424 | Standard_Real maxscal=0; |
425 | Standard_Boolean ptfound=Standard_False; | |
426 | Standard_Real Par; | |
7fd59977 | 427 | Standard_Real _u,_v; |
428 | Standard_Integer IndexPoint=0; | |
429 | Standard_Integer NbPointsOK=0; | |
430 | Standard_Integer NbFacesInSolid=0; | |
431 | ||
302f96fb | 432 | for(;;) { |
7fd59977 | 433 | myFirstFace++; |
434 | faceexplorer.Init(myShape,TopAbs_FACE); | |
435 | // look for point on face starting from myFirstFace | |
436 | // Modified by skv - Thu Sep 4 14:31:12 2003 OCC578 Begin | |
437 | // while (faceexplorer.More()) { | |
438 | for (; faceexplorer.More(); faceexplorer.Next()) { | |
439 | // Modified by skv - Thu Sep 4 14:31:12 2003 OCC578 End | |
440 | NbFacesInSolid++; | |
441 | if (myFirstFace > NbFacesInSolid) continue; | |
442 | face = TopoDS::Face(faceexplorer.Current()); | |
443 | ||
444 | Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface(); | |
445 | surf->ChangeSurface().Initialize(face); | |
446 | Standard_Real U1,V1,U2,V2; | |
447 | U1 = surf->FirstUParameter(); | |
448 | V1 = surf->FirstVParameter(); | |
449 | U2 = surf->LastUParameter(); | |
450 | V2 = surf->LastVParameter(); | |
451 | face.Orientation(TopAbs_FORWARD); | |
452 | // | |
453 | //avoid process faces from uncorrected shells | |
454 | if( Abs (U2 - U1) < 1.e-12 || Abs(V2 - V1) < 1.e-12) { | |
aa74e235 | 455 | return 2; |
7fd59977 | 456 | } |
457 | // | |
458 | Standard_Real svmyparam=myParamOnEdge; | |
459 | // | |
7fd59977 | 460 | // Check if the point is on the face or the face is infinite. |
461 | Standard_Integer anInfFlag = IsInfiniteUV(U1,V1,U2,V2); | |
3922a2ec | 462 | // default values |
463 | _u = (U1 + U2) * 0.5; | |
464 | _v = (V1 + V2) * 0.5; | |
7fd59977 | 465 | |
7fd59977 | 466 | GeomAdaptor_Surface GA(BRep_Tool::Surface(face)); |
88cc4cb8 | 467 | Extrema_ExtPS Ext(P, GA, TolU, TolV); |
468 | // | |
7fd59977 | 469 | if (Ext.IsDone() && Ext.NbExt() > 0) { |
aa74e235 | 470 | Standard_Integer i, iNear, iEnd; |
471 | Standard_Real aUx, aVx, Dist2, Dist2Min; | |
472 | Extrema_POnSurf aPx; | |
473 | // | |
474 | iNear = 1; | |
475 | Dist2Min = Ext.SquareDistance(1); | |
476 | iEnd = Ext.NbExt(); | |
477 | for (i = 2; i <= iEnd; i++) { | |
478 | aPx=Ext.Point(i); | |
479 | aPx.Parameter(aUx, aVx); | |
480 | if (aUx>=U1 && aUx<=U2 && aVx>=V1 && aVx<=V2) { | |
481 | Dist2 = Ext.SquareDistance(i); | |
482 | if (Dist2 < Dist2Min) { | |
483 | Dist2Min = Dist2; | |
484 | iNear = i; | |
485 | } | |
486 | } | |
487 | } | |
488 | // | |
489 | Standard_Real aDist2Tresh=1.e-24; | |
490 | // | |
491 | if (Dist2Min<aDist2Tresh) { | |
492 | if (anInfFlag) { | |
493 | return 1; | |
494 | } | |
495 | else { | |
496 | BRepClass_FaceClassifier classifier2d; | |
497 | Standard_Real aU; | |
498 | Standard_Real aV; | |
499 | ||
500 | (Ext.Point(iNear)).Parameter(aU, aV); | |
501 | ||
502 | gp_Pnt2d aPuv(aU, aV); | |
503 | ||
504 | classifier2d.Perform(face,aPuv,Precision::PConfusion()); | |
505 | ||
506 | TopAbs_State aState = classifier2d.State(); | |
507 | ||
508 | if (aState == TopAbs_IN || aState == TopAbs_ON) { | |
509 | return 1; | |
510 | } | |
511 | else { | |
512 | return 3; // skv - the point is on surface but outside face. | |
513 | } | |
514 | } | |
515 | } | |
516 | if (anInfFlag) { | |
517 | APoint = (Ext.Point(iNear)).Value(); | |
518 | gp_Vec V(P,APoint); | |
519 | _Par = V.Magnitude(); | |
520 | L = gp_Lin(P,V); | |
521 | ptfound=Standard_True; | |
522 | return 0; | |
523 | } | |
3922a2ec | 524 | |
525 | // set the parameters found by extrema | |
526 | aPx = Ext.Point(iNear); | |
527 | aPx.Parameter(_u, _v); | |
528 | APoint = aPx.Value(); | |
7fd59977 | 529 | } |
530 | //The point is not ON the face or surface. The face is restricted. | |
531 | // find point in a face not too far from a projection of P on face | |
41194117 K |
532 | do { |
533 | if (PointInTheFace (face, APoint, _u, _v, myParamOnEdge, ++IndexPoint, surf, | |
534 | U1, V1, U2, V2, | |
535 | aVecD1U, aVecD1V)) | |
536 | { | |
537 | ++NbPointsOK; | |
538 | gp_Vec V (P, APoint); | |
539 | Par = V.Magnitude(); | |
aa74e235 | 540 | if (Par > gp::Resolution() && |
541 | aVecD1U.Magnitude() > gp::Resolution() && | |
542 | aVecD1V.Magnitude() > gp::Resolution()) | |
41194117 K |
543 | { |
544 | gp_Vec Norm = aVecD1U.Crossed (aVecD1V); | |
545 | Standard_Real tt = Norm.Magnitude(); | |
546 | tt = Abs (Norm.Dot (V)) / (tt * Par); | |
547 | if (tt > maxscal) | |
548 | { | |
549 | maxscal = tt; | |
550 | L = gp_Lin (P, V); | |
551 | _Par = Par; | |
552 | ptfound = Standard_True; | |
553 | if (maxscal>0.2) | |
554 | { | |
555 | myParamOnEdge=svmyparam; | |
556 | return 0; | |
557 | } | |
558 | } | |
559 | } | |
560 | } | |
7fd59977 | 561 | } |
562 | while(IndexPoint<200 && NbPointsOK<16); | |
563 | ||
564 | myParamOnEdge=svmyparam; | |
aa74e235 | 565 | if(maxscal>0.2) { |
566 | return 0; | |
7fd59977 | 567 | } |
568 | ||
569 | ||
570 | // Modified by skv - Thu Sep 4 14:32:14 2003 OCC578 Begin | |
571 | // Next is done in the main for(..) loop. | |
572 | // faceexplorer.Next(); | |
573 | // Modified by skv - Thu Sep 4 14:32:14 2003 OCC578 End | |
574 | IndexPoint = 0; | |
575 | ||
576 | Standard_Boolean encoreuneface = faceexplorer.More(); | |
577 | if(ptfound==Standard_False && encoreuneface==Standard_False) { | |
aa74e235 | 578 | if(myParamOnEdge < 0.0001) { |
579 | //-- This case takes place when the point is on the solid | |
580 | //-- and this solid is reduced to a face | |
581 | gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z()); | |
582 | gp_Vec V(P,PBidon); | |
583 | Par= 1.0; | |
584 | _Par=Par; | |
585 | L = gp_Lin(P,V); | |
586 | return 0; | |
587 | } | |
7fd59977 | 588 | } |
589 | } //-- Exploration of the faces | |
590 | ||
591 | if(NbFacesInSolid==0) { | |
592 | _Par=0.0; | |
593 | myReject=Standard_True; | |
0797d9d3 | 594 | #ifdef OCCT_DEBUG |
0d969553 | 595 | cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx (Solid without face)"<<endl; |
7fd59977 | 596 | #endif |
7fd59977 | 597 | return 0; |
7fd59977 | 598 | } |
599 | ||
600 | if(ptfound) { | |
7fd59977 | 601 | return 0; |
7fd59977 | 602 | } |
603 | myFirstFace = 0; | |
604 | if(myParamOnEdge==0.512345) myParamOnEdge = 0.4; | |
605 | else if(myParamOnEdge==0.4) myParamOnEdge = 0.6; | |
606 | else if(myParamOnEdge==0.6) myParamOnEdge = 0.3; | |
607 | else if(myParamOnEdge==0.3) myParamOnEdge = 0.7; | |
608 | else if(myParamOnEdge==0.7) myParamOnEdge = 0.2; | |
609 | else if(myParamOnEdge==0.2) myParamOnEdge = 0.8; | |
610 | else if(myParamOnEdge==0.8) myParamOnEdge = 0.1; | |
611 | else if(myParamOnEdge==0.1) myParamOnEdge = 0.9; | |
1da5279e | 612 | // |
613 | else { | |
614 | myParamOnEdge*=0.5; | |
615 | if(myParamOnEdge < 0.0001) { | |
aa74e235 | 616 | gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z()); |
617 | gp_Vec V(P,PBidon); | |
618 | Par= 1.0; | |
619 | _Par=Par; | |
620 | L = gp_Lin(P,V); | |
621 | return 0; | |
1da5279e | 622 | } |
623 | } | |
302f96fb | 624 | } //-- for(;;) { ... } |
7fd59977 | 625 | } |
626 | ||
627 | // Modified by skv - Thu Sep 4 12:30:14 2003 OCC578 Begin | |
628 | //======================================================================= | |
629 | //function : GetFaceSegmentIndex | |
630 | //purpose : Returns the index of face for which last segment is calculated. | |
631 | //======================================================================= | |
632 | ||
633 | Standard_Integer BRepClass3d_SolidExplorer::GetFaceSegmentIndex() const | |
634 | { | |
635 | return myFirstFace; | |
636 | } | |
637 | // Modified by skv - Thu Sep 4 12:30:14 2003 OCC578 End | |
638 | ||
639 | //======================================================================= | |
640 | //function : PointInTheFace | |
641 | //purpose : | |
642 | //======================================================================= | |
643 | ||
644 | Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace | |
645 | (const TopoDS_Face& _face, | |
646 | gp_Pnt& APoint_, | |
647 | Standard_Real& u_, Standard_Real& v_, | |
648 | Standard_Real& param_, | |
649 | Standard_Integer& IndexPoint) const | |
650 | { | |
651 | TopoDS_Face Face = _face; | |
652 | Face.Orientation(TopAbs_FORWARD); | |
653 | Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface(); | |
654 | surf->ChangeSurface().Initialize(Face); | |
655 | Standard_Real U1,V1,U2,V2;//,u,v; | |
656 | U1 = surf->FirstUParameter(); | |
657 | V1 = surf->FirstVParameter(); | |
658 | U2 = surf->LastUParameter(); | |
659 | V2 = surf->LastVParameter(); | |
660 | LimitInfiniteUV (U1,V1,U2,V2); | |
661 | return(PointInTheFace(Face,APoint_,u_,v_,param_,IndexPoint,surf,U1,V1,U2,V2)); | |
662 | } | |
663 | ||
664 | //======================================================================= | |
665 | //function : FindAPointInTheFace | |
666 | //purpose : | |
667 | //======================================================================= | |
668 | ||
669 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
670 | (const TopoDS_Face& _face, | |
671 | gp_Pnt& APoint_, | |
672 | Standard_Real& u_,Standard_Real& v_) | |
673 | { | |
674 | Standard_Real param = 0.1; | |
675 | Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u_,v_,param); | |
676 | return r; | |
677 | } | |
678 | ||
679 | //======================================================================= | |
680 | //function : FindAPointInTheFace | |
681 | //purpose : | |
682 | //======================================================================= | |
683 | ||
684 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
685 | (const TopoDS_Face& _face, | |
686 | gp_Pnt& APoint_) | |
687 | { Standard_Real u,v; | |
688 | Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u,v); | |
689 | return r; | |
690 | } | |
691 | ||
692 | //======================================================================= | |
693 | //function : FindAPointInTheFace | |
694 | //purpose : | |
695 | //======================================================================= | |
696 | ||
697 | Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace | |
698 | (const TopoDS_Face& _face, | |
699 | Standard_Real& u_,Standard_Real& v_) | |
700 | { gp_Pnt APoint; | |
701 | Standard_Boolean r = FindAPointInTheFace(_face,APoint,u_,v_); | |
702 | return r; | |
703 | } | |
704 | ||
705 | //======================================================================= | |
706 | //function : BRepClass3d_SolidExplorer | |
707 | //purpose : | |
708 | //======================================================================= | |
709 | ||
710 | BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer() | |
711 | { | |
712 | } | |
713 | #include <Standard_ConstructionError.hxx> | |
714 | ||
715 | //======================================================================= | |
716 | //function : BRepClass3d_SolidExplorer | |
717 | //purpose : Raise if called. | |
718 | //======================================================================= | |
719 | ||
720 | //BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& Oth) | |
721 | BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& ) | |
722 | { | |
723 | Standard_ConstructionError::Raise("Magic constructor not allowed"); | |
724 | } | |
725 | ||
726 | //======================================================================= | |
727 | //function : BRepClass3d_SolidExplorer | |
728 | //purpose : | |
729 | //======================================================================= | |
730 | ||
731 | BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const TopoDS_Shape& S) | |
732 | { | |
733 | InitShape(S); | |
734 | } | |
735 | ||
736 | //======================================================================= | |
737 | //function : Delete | |
738 | //purpose : | |
739 | //======================================================================= | |
740 | ||
741 | void BRepClass3d_SolidExplorer::Delete() | |
742 | { | |
743 | Destroy() ; | |
744 | } | |
745 | ||
746 | //======================================================================= | |
747 | //function : Destroy | |
748 | //purpose : C++: alias ~ | |
749 | //======================================================================= | |
750 | ||
751 | void BRepClass3d_SolidExplorer::Destroy() { | |
752 | BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter); | |
753 | for(;iter.More();iter.Next()) { | |
754 | void *ptr=iter.Value(); | |
755 | if(ptr) { | |
756 | delete (IntCurvesFace_Intersector *)ptr; | |
757 | myMapOfInter.ChangeFind(iter.Key()) = NULL; | |
758 | } | |
759 | } | |
760 | myMapOfInter.Clear(); | |
761 | } | |
762 | ||
763 | //======================================================================= | |
764 | //function : InitShape | |
765 | //purpose : | |
766 | //======================================================================= | |
767 | ||
768 | void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S) | |
769 | { | |
770 | myShape = S; | |
771 | myFirstFace = 0; | |
772 | myParamOnEdge = 0.512345; | |
0d969553 | 773 | //-- Exploring of the Map and removal of allocated objects |
7fd59977 | 774 | |
775 | ||
776 | BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter); | |
777 | for(;iter.More();iter.Next()) { | |
778 | void *ptr=iter.Value(); | |
779 | if(ptr) { | |
780 | delete (IntCurvesFace_Intersector *)ptr; | |
781 | myMapOfInter.ChangeFind(iter.Key()) = NULL; | |
782 | } | |
783 | } | |
784 | ||
785 | myMapOfInter.Clear(); | |
786 | ||
0d969553 | 787 | myReject = Standard_True; //-- case of infinite solid (without any face) |
7fd59977 | 788 | |
789 | TopExp_Explorer Expl; | |
790 | for(Expl.Init(S,TopAbs_FACE); | |
791 | Expl.More(); | |
792 | Expl.Next()) { | |
793 | const TopoDS_Face Face = TopoDS::Face(Expl.Current()); | |
794 | void *ptr = (void *)(new IntCurvesFace_Intersector(Face,Precision::Confusion())); | |
795 | myMapOfInter.Bind(Face,ptr); | |
0d969553 | 796 | myReject=Standard_False; //-- at least one face in the solid |
7fd59977 | 797 | } |
798 | ||
0797d9d3 | 799 | #ifdef OCCT_DEBUG |
7fd59977 | 800 | if(myReject) { |
0d969553 | 801 | cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx (Solid without face)"<<endl; |
7fd59977 | 802 | } |
803 | #endif | |
804 | ||
805 | #if REJECTION | |
806 | BRepBndLib::Add(myShape,myBox); | |
807 | #endif | |
808 | } | |
809 | ||
810 | //======================================================================= | |
811 | //function : Reject | |
812 | //purpose : Should return True if P outside of bounding vol. of the shape | |
813 | //======================================================================= | |
814 | ||
815 | //Standard_Boolean BRepClass3d_SolidExplorer::Reject(const gp_Pnt& P) const | |
816 | Standard_Boolean BRepClass3d_SolidExplorer::Reject(const gp_Pnt& ) const | |
817 | { | |
0d969553 | 818 | return(myReject); // case of solid without face |
7fd59977 | 819 | } |
820 | ||
821 | //======================================================================= | |
822 | //function : InitShell | |
823 | //purpose : Starts an exploration of the shells. | |
824 | //======================================================================= | |
825 | ||
826 | void BRepClass3d_SolidExplorer::InitShell() | |
827 | { | |
828 | myShellExplorer.Init(myShape,TopAbs_SHELL); | |
829 | } | |
830 | ||
831 | //======================================================================= | |
832 | //function : MoreShell | |
833 | //purpose : Returns True if there is a current shell. | |
834 | //======================================================================= | |
835 | ||
836 | Standard_Boolean BRepClass3d_SolidExplorer::MoreShell() const | |
837 | { | |
838 | return(myShellExplorer.More()); | |
839 | } | |
840 | ||
841 | //======================================================================= | |
842 | //function : NextShell | |
843 | //purpose : Sets the explorer to the next shell. | |
844 | //======================================================================= | |
845 | ||
846 | void BRepClass3d_SolidExplorer::NextShell() | |
847 | { | |
848 | myShellExplorer.Next(); | |
849 | } | |
850 | ||
851 | //======================================================================= | |
852 | //function : CurrentShell | |
853 | //purpose : Returns the current shell. | |
854 | //======================================================================= | |
855 | ||
856 | TopoDS_Shell BRepClass3d_SolidExplorer::CurrentShell() const | |
857 | { | |
858 | return(TopoDS::Shell(myShellExplorer.Current())); | |
859 | } | |
860 | ||
861 | //======================================================================= | |
862 | //function : RejectShell | |
863 | //purpose : Returns True if the Shell is rejected. | |
864 | //======================================================================= | |
865 | ||
866 | Standard_Boolean BRepClass3d_SolidExplorer::RejectShell(const gp_Lin& ) const | |
867 | { | |
868 | return(Standard_False); | |
869 | } | |
870 | ||
871 | //======================================================================= | |
872 | //function : InitFace | |
873 | //purpose : Starts an exploration of the faces of the current shell. | |
874 | //======================================================================= | |
875 | ||
876 | void BRepClass3d_SolidExplorer::InitFace() | |
877 | { | |
878 | myFaceExplorer.Init(TopoDS::Shell(myShellExplorer.Current()),TopAbs_FACE); | |
879 | } | |
880 | ||
881 | //======================================================================= | |
882 | //function : MoreFace | |
883 | //purpose : Returns True if current face in current shell. | |
884 | //======================================================================= | |
885 | ||
886 | Standard_Boolean BRepClass3d_SolidExplorer::MoreFace() const | |
887 | { | |
888 | return(myFaceExplorer.More()); | |
889 | } | |
890 | ||
891 | //======================================================================= | |
892 | //function : NextFace | |
893 | //purpose : Sets the explorer to the next Face of the current shell. | |
894 | //======================================================================= | |
895 | ||
896 | void BRepClass3d_SolidExplorer::NextFace() | |
897 | { | |
898 | myFaceExplorer.Next(); | |
899 | } | |
900 | ||
901 | //======================================================================= | |
902 | //function : CurrentFace | |
903 | //purpose : Returns the current face. | |
904 | //======================================================================= | |
905 | ||
906 | TopoDS_Face BRepClass3d_SolidExplorer::CurrentFace() const | |
907 | { | |
908 | return(TopoDS::Face(myFaceExplorer.Current())); | |
909 | } | |
910 | ||
911 | //======================================================================= | |
912 | //function : RejectFace | |
913 | //purpose : returns True if the face is rejected. | |
914 | //======================================================================= | |
915 | ||
916 | Standard_Boolean BRepClass3d_SolidExplorer::RejectFace(const gp_Lin& ) const | |
917 | { | |
918 | return(Standard_False); | |
919 | } | |
920 | ||
0797d9d3 | 921 | #ifdef OCCT_DEBUG |
7fd59977 | 922 | #include <TopAbs_State.hxx> |
923 | #endif | |
924 | ||
925 | //======================================================================= | |
926 | //function : Segment | |
927 | //purpose : Returns in <L>, <Par> a segment having at least | |
928 | // one intersection with the shape boundary to | |
929 | // compute intersections. | |
930 | //======================================================================= | |
88cc4cb8 | 931 | Standard_Integer BRepClass3d_SolidExplorer::Segment(const gp_Pnt& P, |
aa74e235 | 932 | gp_Lin& L, |
933 | Standard_Real& Par) | |
7fd59977 | 934 | { |
935 | Standard_Integer bRetFlag; | |
936 | myFirstFace = 0; | |
937 | bRetFlag=OtherSegment(P,L,Par); | |
938 | return bRetFlag; | |
939 | } | |
7fd59977 | 940 | |
941 | //======================================================================= | |
942 | //function : Intersector | |
943 | //purpose : | |
944 | //======================================================================= | |
945 | ||
946 | IntCurvesFace_Intersector& BRepClass3d_SolidExplorer::Intersector(const TopoDS_Face& F) const { | |
947 | void *ptr = (void*)(myMapOfInter.Find(F)); | |
7fd59977 | 948 | IntCurvesFace_Intersector& curr = (*((IntCurvesFace_Intersector *)ptr)); |
949 | return curr; | |
7fd59977 | 950 | } |
951 | ||
952 | //======================================================================= | |
953 | //function : Box | |
954 | //purpose : | |
955 | //======================================================================= | |
956 | ||
957 | const Bnd_Box& BRepClass3d_SolidExplorer::Box() const { | |
958 | return(myBox); | |
959 | } | |
960 | ||
961 | //======================================================================= | |
962 | //function : DumpSegment | |
963 | //purpose : | |
964 | //======================================================================= | |
965 | ||
966 | void BRepClass3d_SolidExplorer::DumpSegment(const gp_Pnt&, | |
aa74e235 | 967 | const gp_Lin&, |
968 | const Standard_Real, | |
969 | const TopAbs_State) const | |
7fd59977 | 970 | { |
0797d9d3 | 971 | #ifdef OCCT_DEBUG |
0d969553 | 972 | |
7fd59977 | 973 | #endif |
974 | } |