Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-07-15 |
2 | // Created by: Laurent BUCHARD | |
3 | // Copyright (c) 1996-1999 Matra Datavision | |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
5 | // | |
6 | // The content of this file is subject to the Open CASCADE Technology Public | |
7 | // License Version 6.5 (the "License"). You may not use the content of this file | |
8 | // except in compliance with the License. Please obtain a copy of the License | |
9 | // at http://www.opencascade.org and read it completely before using this file. | |
10 | // | |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
13 | // | |
14 | // The Original Code and all software distributed under the License is | |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
16 | // Initial Developer hereby disclaims all such warranties, including without | |
17 | // limitation, any warranties of merchantability, fitness for a particular | |
18 | // purpose or non-infringement. Please see the License for the specific terms | |
19 | // and conditions governing the rights and limitations under the License. | |
20 | ||
7fd59977 | 21 | |
22 | ||
23 | // Modified by skv - Thu Sep 4 11:22:05 2003 OCC578 | |
24 | ||
25 | #include <BRepClass3d_SClassifier.ixx> | |
26 | ||
27 | #include <gp_Pnt.hxx> | |
28 | #include <gp_Lin.hxx> | |
29 | #include <gp_Vec.hxx> | |
30 | #include <BRepClass3d_Intersector3d.hxx> | |
31 | #include <TopoDS.hxx> | |
32 | ||
33 | #include <IntCurvesFace_Intersector.hxx> | |
34 | // modified by NIZHNY-MKK Mon Jun 21 15:13:40 2004 | |
35 | #include <Precision.hxx> | |
36 | #include <ElCLib.hxx> | |
bd05fabf S |
37 | #include <Geom_Surface.hxx> |
38 | #include <BRep_Tool.hxx> | |
7fd59977 | 39 | |
bd05fabf S |
40 | static |
41 | void FaceNormal (const TopoDS_Face& aF, | |
42 | const Standard_Real U, | |
43 | const Standard_Real V, | |
44 | gp_Dir& aDN); | |
7fd59977 | 45 | |
bd05fabf S |
46 | static |
47 | Standard_Real GetAddToParam(const gp_Lin& L,const Standard_Real P,const Bnd_Box& B); | |
7fd59977 | 48 | |
49 | ||
bd05fabf S |
50 | |
51 | //======================================================================= | |
52 | //function : BRepClass3d_SClassifier | |
53 | //purpose : | |
54 | //======================================================================= | |
7fd59977 | 55 | BRepClass3d_SClassifier::BRepClass3d_SClassifier() |
56 | { | |
57 | } | |
58 | ||
59 | ||
bd05fabf S |
60 | //======================================================================= |
61 | //function : BRepClass3d_SClassifier | |
62 | //purpose : | |
63 | //======================================================================= | |
7fd59977 | 64 | BRepClass3d_SClassifier::BRepClass3d_SClassifier(BRepClass3d_SolidExplorer& S, |
65 | const gp_Pnt& P, | |
66 | const Standard_Real Tol) { | |
67 | if(S.Reject(P)) { | |
c898afce | 68 | myState=3; //-- in ds solid case without face |
7fd59977 | 69 | } |
70 | else { | |
71 | Perform(S,P,Tol); | |
72 | } | |
73 | } | |
74 | ||
75 | ||
bd05fabf S |
76 | //======================================================================= |
77 | //function : PerformInfinitePoint | |
78 | //purpose : | |
79 | //======================================================================= | |
80 | void BRepClass3d_SClassifier::PerformInfinitePoint(BRepClass3d_SolidExplorer& aSE, | |
7fd59977 | 81 | const Standard_Real /*Tol*/) { |
c898afce Y |
82 | //-- Idea : Take point A in face1 and point B in face B |
83 | //-- (if there is only one face, take 2 points in the same face.) | |
7fd59977 | 84 | //-- |
c898afce Y |
85 | //-- Intersect straight line AB with the solid and produce transition of the |
86 | //-- first point. If the solid has only one face and the straight line AB does not cut it | |
87 | //-- it is not possible to decide. | |
7fd59977 | 88 | |
bd05fabf | 89 | if(aSE.Reject(gp_Pnt(0,0,0))) { |
c898afce | 90 | myState=3; //-- in ds solid case without face |
7fd59977 | 91 | return; |
92 | } | |
bd05fabf S |
93 | // |
94 | //------------------------------------------------------------ | |
95 | // 1 | |
96 | Standard_Boolean bFound, bFlag; | |
97 | Standard_Integer nump; | |
98 | Standard_Real aParam, aU1, aV1, aU2, aV2; | |
7fd59977 | 99 | gp_Pnt A,B; |
bd05fabf | 100 | gp_Dir aDN1, aDN2; |
e450f818 | 101 | TopoDS_Face aF1, aF2; |
bd05fabf S |
102 | // |
103 | nump = 0; | |
104 | aParam = 0.5; | |
7fd59977 | 105 | myFace.Nullify(); |
106 | myState=2; | |
bd05fabf S |
107 | for(aSE.InitShell(); aSE.MoreShell() && nump<2; aSE.NextShell()) { |
108 | for(aSE.InitFace(); aSE.MoreFace() && nump<2; ) { | |
e450f818 | 109 | TopoDS_Face aF = aSE.CurrentFace(); |
bd05fabf S |
110 | aSE.NextFace(); |
111 | if(!nump) { | |
7fd59977 | 112 | nump++; |
bd05fabf S |
113 | bFound=aSE.FindAPointInTheFace(aF, A, aU1, aV1, aParam); |
114 | if (!bFound) { | |
7fd59977 | 115 | return; |
116 | } | |
bd05fabf S |
117 | aF1=aF; |
118 | if(!aSE.MoreFace()) { | |
7fd59977 | 119 | nump++; |
bd05fabf S |
120 | bFound=aSE.FindAPointInTheFace(aF, B, aU2, aV2, aParam); |
121 | if (!bFound) { | |
122 | return; | |
123 | } | |
124 | aF2=aF; | |
7fd59977 | 125 | } |
bd05fabf S |
126 | }// if(nump==0) { |
127 | else if(nump==1) { | |
128 | bFound=aSE.FindAPointInTheFace(aF, B, aU2, aV2, aParam); | |
129 | if(!bFound) { | |
7fd59977 | 130 | return; |
bd05fabf S |
131 | } |
132 | aF2=aF; | |
133 | nump++; | |
7fd59977 | 134 | } |
bd05fabf S |
135 | }// for(aSE.InitFace(); aSE.MoreFace() && nump<2; ) { |
136 | }// for(aSE.InitShell(); aSE.MoreShell() && nump<2; aSE.NextShell()) { | |
137 | // | |
138 | //------------------------------------------------------------ | |
139 | // 2 | |
140 | Standard_Integer cpasbon; | |
141 | Standard_Real parmin, aD2, aSP; | |
142 | IntCurveSurface_TransitionOnCurve aTC; | |
143 | TopAbs_State aState; | |
144 | // | |
145 | parmin = RealLast(); | |
146 | // | |
147 | bFlag=Standard_False; | |
148 | if (aF1!=aF2) { | |
149 | FaceNormal(aF1, aU1, aV1, aDN1); | |
150 | FaceNormal(aF2, aU2, aV2, aDN2); | |
151 | aSP=1.-aDN1*aDN2; | |
152 | if (aSP < 1.e-5) { | |
153 | bFlag=!bFlag; | |
7fd59977 | 154 | } |
155 | } | |
bd05fabf S |
156 | // |
157 | aD2=A.SquareDistance(B); | |
158 | if(aD2<0.000001 || bFlag) { | |
7fd59977 | 159 | B.SetCoord(A.X()+1,A.Y()+1,A.Z()+1); |
160 | } | |
bd05fabf S |
161 | // |
162 | cpasbon = 0; | |
7fd59977 | 163 | gp_Vec AB(A,B); |
bd05fabf | 164 | // |
7fd59977 | 165 | do { |
166 | switch (cpasbon) | |
167 | { | |
168 | case 1 : AB.SetX(-AB.X());break; | |
169 | case 2 : AB.SetY(-AB.Y());break; | |
170 | case 3 : AB.SetZ(-AB.Z());break; | |
171 | case 4 : AB.SetY(-AB.Y());break; | |
172 | case 5 : AB.SetX(-AB.X());break; | |
173 | } | |
174 | gp_Lin L(A,gp_Dir(AB)); | |
175 | //-- cout<<"\npoint A "<<A.X()<<" "<<A.Y()<<" "<<A.Z()<<endl; | |
176 | //-- cout<<"\npoint B "<<B.X()<<" "<<B.Y()<<" "<<B.Z()<<endl; | |
bd05fabf S |
177 | for(aSE.InitShell();aSE.MoreShell();aSE.NextShell()) { |
178 | if(aSE.RejectShell(L) == Standard_False) { | |
179 | for(aSE.InitFace();aSE.MoreFace(); aSE.NextFace()) { | |
180 | if(aSE.RejectFace(L) == Standard_False) { | |
181 | TopoDS_Shape aLocalShape = aSE.CurrentFace(); | |
7fd59977 | 182 | TopoDS_Face f = TopoDS::Face(aLocalShape); |
bd05fabf S |
183 | IntCurvesFace_Intersector& Intersector3d = aSE.Intersector(f); |
184 | Intersector3d.Perform(L,-RealLast(),parmin); | |
7fd59977 | 185 | |
186 | if(Intersector3d.IsDone()) { | |
187 | if(Intersector3d.NbPnt()) { | |
188 | if(Intersector3d.WParameter(1) < parmin) { | |
bd05fabf | 189 | aState=Intersector3d.State(1); |
7fd59977 | 190 | parmin = Intersector3d.WParameter(1); |
bd05fabf S |
191 | if(aState==TopAbs_IN || aState==TopAbs_ON) { |
192 | aTC=Intersector3d.Transition(1); | |
7fd59977 | 193 | //-- The intersection point between the line and a face F |
194 | // -- of the solid is in the face F | |
bd05fabf | 195 | if(aTC == IntCurveSurface_Out) { |
7fd59977 | 196 | //-- The line is going from inside the solid to outside |
197 | //-- the solid. | |
198 | myState = 3; //-- IN -- | |
199 | } | |
bd05fabf | 200 | else if(aTC == IntCurveSurface_In) { |
7fd59977 | 201 | myState = 4; //-- OUT -- |
202 | } | |
203 | myFace = f; | |
204 | } | |
bd05fabf | 205 | /* |
7fd59977 | 206 | else if(Intersector3d.State(1)==TopAbs_ON) { |
207 | //-- The intersection point between the line and a face F | |
208 | //-- of the solid is in the face F | |
209 | if(Intersector3d.Transition(1) == IntCurveSurface_Out) { | |
210 | //-- The line is going from inside the solid to outside | |
211 | //-- the solid. | |
212 | myState = 3; //-- IN -- | |
213 | } | |
214 | else if(Intersector3d.Transition(1) == IntCurveSurface_In) { | |
215 | myState = 4; //-- OUT -- | |
216 | } | |
217 | //-- myState = 2; | |
218 | myFace = f; | |
219 | } | |
bd05fabf | 220 | */ |
7fd59977 | 221 | } |
bd05fabf | 222 | |
7fd59977 | 223 | else { |
224 | //-- No point has been found by the Intersector3d. | |
225 | //-- Or a Point has been found with a greater parameter. | |
226 | } | |
227 | } | |
228 | } | |
229 | } | |
230 | } //-- Exploration of the faces | |
231 | } //-- Shell has not been rejected | |
232 | else { | |
233 | myState=1; | |
234 | } | |
235 | } //-- Exploration of the shells | |
236 | cpasbon++; | |
237 | } | |
238 | while(cpasbon!=0 && cpasbon<5); | |
239 | } | |
240 | //======================================================================= | |
241 | //function : Perform | |
242 | //purpose : | |
243 | //======================================================================= | |
bd05fabf S |
244 | void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer, |
245 | const gp_Pnt& P, | |
246 | const Standard_Real Tol) | |
7fd59977 | 247 | { |
248 | ||
249 | ||
250 | if(SolidExplorer.Reject(P)) { | |
c898afce | 251 | myState=3; //-- in ds solid case without face |
7fd59977 | 252 | return; |
253 | } | |
254 | ||
255 | ||
256 | myFace.Nullify(); | |
257 | myState = 0; | |
258 | if(SolidExplorer.Reject(P) == Standard_False) { | |
259 | gp_Lin L; | |
260 | Standard_Real Par; | |
261 | //-- We compute the intersection betwwen the line builded in the Solid Explorer | |
262 | //-- and the shape. | |
263 | ||
264 | //-- -------------------------------------------------------------------------------- | |
c898afce Y |
265 | //-- Calculate intersection with the face closest to the direction of bounding boxes |
266 | //-- by priority so that to have the smallest possible parmin. | |
267 | //-- optimization to produce as much as possible rejections with other faces. | |
7fd59977 | 268 | Standard_Integer iFlag; |
269 | // | |
270 | ||
271 | // Modified by skv - Thu Sep 4 11:22:05 2003 OCC578 Begin | |
272 | // If found line passes through a bound of any face, it means that the line | |
273 | // is not found properly and it is necessary to repeat whole procedure. | |
274 | // That's why the main loop while is added. | |
275 | Standard_Boolean isFaultyLine = Standard_True; | |
276 | Standard_Integer anIndFace = 0; | |
277 | Standard_Real parmin; | |
278 | ||
279 | while (isFaultyLine) { | |
280 | if (anIndFace == 0) { | |
281 | iFlag = SolidExplorer.Segment(P,L,Par); | |
282 | } else { | |
283 | iFlag = SolidExplorer.OtherSegment(P,L,Par); | |
284 | } | |
285 | ||
286 | Standard_Integer aCurInd = SolidExplorer.GetFaceSegmentIndex(); | |
287 | ||
288 | if (aCurInd > anIndFace) { | |
289 | anIndFace = aCurInd; | |
290 | } else { | |
291 | myState = 1; | |
292 | ||
293 | return; | |
294 | } | |
295 | // Modified by skv - Thu Sep 4 11:22:10 2003 OCC578 End | |
296 | ||
297 | if (iFlag==1) { | |
298 | // IsOnFace | |
299 | // iFlag==1 i.e face is Infinite | |
300 | myState=2; | |
301 | ||
302 | return; | |
303 | } | |
304 | //SolidExplorer.Segment(P,L,Par); | |
7fd59977 | 305 | // |
306 | //process results from uncorrected shells | |
307 | // | |
7fd59977 | 308 | //if(Par > 1.e+100 && L.Direction().IsParallel(gp_Dir(0.,0.,1.),1.e-8)) { |
309 | if (iFlag==2) { | |
7fd59977 | 310 | myState = 4; |
311 | return; | |
312 | } | |
313 | //-- BRepClass3d_Intersector3d Intersector3d; | |
314 | ||
315 | // Modified by skv - Thu Sep 4 13:48:27 2003 OCC578 Begin | |
316 | // Check if the point is ON surface but OUT of the face. | |
317 | // Just skip this face because it is bad for classification. | |
318 | if (iFlag == 3) | |
319 | continue; | |
320 | ||
321 | isFaultyLine = Standard_False; | |
322 | // Standard_Real parmin = RealLast(); | |
323 | ||
324 | // for(SolidExplorer.InitShell(); | |
325 | // SolidExplorer.MoreShell(); | |
326 | // SolidExplorer.NextShell()) { | |
327 | parmin = RealLast(); | |
328 | ||
329 | for(SolidExplorer.InitShell(); | |
330 | SolidExplorer.MoreShell() && !isFaultyLine; | |
331 | SolidExplorer.NextShell()) { | |
332 | // Modified by skv - Thu Sep 4 13:48:27 2003 OCC578 End | |
333 | ||
334 | if(SolidExplorer.RejectShell(L) == Standard_False) { | |
335 | ||
336 | // Modified by skv - Thu Sep 4 13:48:27 2003 OCC578 Begin | |
337 | // for(SolidExplorer.InitFace(); | |
338 | // SolidExplorer.MoreFace(); | |
339 | // SolidExplorer.NextFace()) { | |
340 | for(SolidExplorer.InitFace(); | |
341 | SolidExplorer.MoreFace() && !isFaultyLine; | |
342 | SolidExplorer.NextFace()) { | |
343 | // Modified by skv - Thu Sep 4 13:48:27 2003 OCC578 End | |
344 | ||
345 | if(SolidExplorer.RejectFace(L) == Standard_False) { | |
346 | ||
347 | //-- Intersector3d.Perform(L,Par,Tol,SolidExplorer.CurrentFace()); | |
348 | TopoDS_Shape aLocalShape = SolidExplorer.CurrentFace(); | |
349 | TopoDS_Face f = TopoDS::Face(aLocalShape); | |
350 | // TopoDS_Face f = TopoDS::Face(SolidExplorer.CurrentFace()); | |
351 | IntCurvesFace_Intersector& Intersector3d = SolidExplorer.Intersector(f); | |
352 | ||
353 | // MSV Oct 25, 2001: prolong segment, since there are cases when | |
354 | // the intersector does not find intersection points with the original | |
355 | // segment due to rough triangulation of a parametrized surface | |
356 | Standard_Real addW = Max(10*Tol, 0.01*Par); | |
357 | Standard_Real AddW = addW; | |
358 | ||
359 | Bnd_Box aBoxF = Intersector3d.Bounding(); | |
360 | ||
361 | // MSV 23.09.2004: the box must be finite in order to | |
362 | // correctly prolong the segment to its bounds | |
363 | if (!aBoxF.IsVoid() && !aBoxF.IsWhole()) { | |
364 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; | |
365 | aBoxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); | |
366 | ||
367 | Standard_Real boxaddW = GetAddToParam(L,Par,aBoxF); | |
368 | addW = Max(addW,boxaddW); | |
369 | } | |
370 | ||
371 | Standard_Real minW = -AddW;//-addW; | |
372 | Standard_Real maxW = Min(Par*10,Par+addW);//Par+addW; | |
373 | //cout << "range [" << minW << "," << maxW << "]" << endl << endl; | |
374 | Intersector3d.Perform(L,minW,maxW); | |
375 | //Intersector3d.Perform(L,-Tol,Par+10.0*Tol); | |
376 | if(Intersector3d.IsDone()) { | |
377 | Standard_Integer i; | |
378 | for (i=1; i <= Intersector3d.NbPnt(); i++) { | |
379 | if(Abs(Intersector3d.WParameter(i)) < Abs(parmin)) { | |
380 | ||
381 | parmin = Intersector3d.WParameter(i); | |
382 | // Modified by skv - Thu Sep 4 12:46:32 2003 OCC578 Begin | |
383 | TopAbs_State aState = Intersector3d.State(i); | |
384 | // Modified by skv - Thu Sep 4 12:46:33 2003 OCC578 End | |
385 | if(Abs(parmin)<=Tol) { | |
386 | myState = 2; | |
387 | myFace = f; | |
388 | } | |
389 | // Modified by skv - Thu Sep 4 12:46:32 2003 OCC578 Begin | |
390 | // Treatment of case TopAbs_ON separately. | |
391 | ||
392 | else if(aState==TopAbs_IN) { | |
393 | // Modified by skv - Thu Sep 4 12:46:32 2003 OCC578 End | |
394 | ||
395 | //-- The intersection point between the line and a face F | |
396 | // -- of the solid is in the face F | |
397 | ||
398 | IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i); | |
399 | if (tran == IntCurveSurface_Tangent) { | |
400 | #ifdef DEB | |
c898afce | 401 | cout<<"*Problem ds BRepClass3d_SClassifier.cxx"<<endl; |
7fd59977 | 402 | #endif |
403 | continue; // ignore this point | |
404 | } | |
405 | // if parmin is negative we should reverse transition | |
406 | if (parmin < 0) | |
407 | tran = (tran == IntCurveSurface_Out | |
408 | ? IntCurveSurface_In : IntCurveSurface_Out); | |
409 | if(tran == IntCurveSurface_Out) { | |
410 | //-- The line is going from inside the solid to outside | |
411 | //-- the solid. | |
412 | myState = 3; //-- IN -- | |
413 | } | |
414 | else /* if(tran == IntCurveSurface_In) */ { | |
415 | myState = 4; //-- OUT -- | |
416 | } | |
417 | myFace = f; | |
418 | } | |
419 | // Modified by skv - Thu Sep 4 12:48:50 2003 OCC578 Begin | |
420 | // If the state is TopAbs_ON, it is necessary to chose | |
421 | // another line and to repeat the whole procedure. | |
422 | else if(aState==TopAbs_ON) { | |
423 | isFaultyLine = Standard_True; | |
424 | ||
425 | break; | |
426 | } | |
427 | // Modified by skv - Thu Sep 4 12:48:50 2003 OCC578 End | |
428 | } | |
429 | else { | |
430 | //-- No point has been found by the Intersector3d. | |
431 | //-- Or a Point has been found with a greater parameter. | |
432 | } | |
433 | } //-- loop by intersection points | |
434 | } //-- Face has not been rejected | |
435 | else { | |
436 | myState = 1; | |
437 | } | |
438 | } | |
439 | } //-- Exploration of the faces | |
440 | } //-- Shell has not been rejected | |
441 | else { | |
442 | myState=1; | |
443 | } | |
444 | } //-- Exploration of the shells | |
445 | ||
446 | // Modified by skv - Thu Sep 4 11:42:03 2003 OCC578 Begin | |
447 | // The end of main loop. | |
448 | } | |
449 | // Modified by skv - Thu Sep 4 11:42:03 2003 OCC578 End | |
450 | ||
451 | #ifdef DEB | |
452 | //################################################# | |
453 | SolidExplorer.DumpSegment(P,L,parmin,State()); | |
454 | //################################################# | |
455 | #endif | |
456 | ||
457 | } //-- Solid has not been rejected | |
458 | else { | |
459 | myState = 1; | |
460 | } | |
461 | } | |
462 | ||
463 | ||
464 | TopAbs_State BRepClass3d_SClassifier::State() const { | |
465 | if(myState==2) return(TopAbs_ON); | |
466 | if(myState==4) return(TopAbs_OUT); //-- | |
467 | else if(myState==3) return(TopAbs_IN); //-- | |
468 | return(TopAbs_OUT); | |
469 | } | |
470 | ||
471 | TopoDS_Face BRepClass3d_SClassifier::Face() const { | |
472 | return(myFace); | |
473 | } | |
474 | ||
475 | Standard_Boolean BRepClass3d_SClassifier::Rejected() const { | |
476 | return(myState==1); | |
477 | } | |
478 | ||
479 | ||
480 | Standard_Boolean BRepClass3d_SClassifier::IsOnAFace() const { | |
481 | return(myState==2); | |
482 | } | |
483 | ||
484 | ||
485 | void BRepClass3d_SClassifier::ForceIn() { | |
486 | myState=3; | |
487 | } | |
488 | ||
489 | void BRepClass3d_SClassifier::ForceOut() { | |
490 | myState=4; | |
491 | } | |
492 | ||
493 | Standard_Real GetAddToParam(const gp_Lin& L, | |
494 | const Standard_Real P, | |
495 | const Bnd_Box& B) | |
496 | { | |
497 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; | |
498 | B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); | |
499 | Standard_Real x[2] = {aXmin,aXmax}, y[2] = {aYmin,aYmax}, z[2] = {aZmin,aZmax}; | |
500 | Standard_Integer i = 0, j = 0, k = 0; | |
501 | Standard_Real Par = P; | |
502 | for(i = 0 ; i < 2; i++) { | |
503 | for(j = 0; j < 2; j++) { | |
504 | for(k = 0; k < 2; k++) { | |
505 | Standard_Real X = fabs(x[i]-L.Location().X()); | |
506 | Standard_Real Y = fabs(y[j]-L.Location().Y()); | |
507 | Standard_Real Z = fabs(z[k]-L.Location().Z()); | |
508 | if(X < 1.e+20 && Y < 1.e+20 && Z < 1.e+20) { | |
509 | gp_Pnt aP(x[i],y[j],z[k]); | |
510 | Standard_Real par = ElCLib::Parameter(L,aP); | |
511 | if(par > Par) | |
512 | Par = par; | |
513 | } | |
514 | else | |
515 | return 1.e+20; | |
516 | } | |
517 | } | |
518 | } | |
519 | return Par - P; | |
520 | } | |
bd05fabf S |
521 | //======================================================================= |
522 | //function : FaceNormal | |
523 | //purpose : | |
524 | //======================================================================= | |
525 | void FaceNormal (const TopoDS_Face& aF, | |
526 | const Standard_Real U, | |
527 | const Standard_Real V, | |
528 | gp_Dir& aDN) | |
529 | { | |
530 | gp_Pnt aPnt ; | |
531 | gp_Vec aD1U, aD1V, aN; | |
532 | Handle(Geom_Surface) aS; | |
533 | ||
534 | aS=BRep_Tool::Surface(aF); | |
535 | aS->D1 (U, V, aPnt, aD1U, aD1V); | |
536 | aN=aD1U.Crossed(aD1V); | |
537 | aN.Normalize(); | |
538 | aDN.SetXYZ(aN.XYZ()); | |
539 | if (aF.Orientation() == TopAbs_REVERSED){ | |
540 | aDN.Reverse(); | |
541 | } | |
542 | return; | |
543 | } |