7fd59977 |
1 | // File: BRepLib.cxx |
2 | // Created: Wed Dec 15 17:53:58 1993 |
3 | // Author: Remi LEQUETTE |
4 | // <rle@zerox> |
5 | |
6 | // History: pmn 26/09/97 Ajout des parametres d'approx dans BuildCurve3d |
7 | // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 |
8 | |
9 | #include <BRepLib.ixx> |
10 | #include <BRepAdaptor_Surface.hxx> |
11 | #include <BRepAdaptor_HSurface.hxx> |
12 | #include <BRepAdaptor_HCurve2d.hxx> |
13 | #include <BRep_Tool.hxx> |
14 | #include <BRep_Builder.hxx> |
15 | #include <Geom_Surface.hxx> |
16 | #include <Geom_RectangularTrimmedSurface.hxx> |
17 | #include <Geom_Plane.hxx> |
18 | #include <Geom_Curve.hxx> |
19 | #include <Geom_BSplineCurve.hxx> |
20 | #include <Geom_TrimmedCurve.hxx> |
21 | #include <Geom2d_Curve.hxx> |
22 | #include <Geom2d_TrimmedCurve.hxx> |
23 | #include <Geom2d_BSplineCurve.hxx> |
24 | #include <GeomLib.hxx> |
25 | #include <TopExp_Explorer.hxx> |
26 | #include <TopoDS.hxx> |
27 | #include <TopoDS_Edge.hxx> |
28 | #include <TopoDS_Face.hxx> |
29 | #include <TopoDS_Vertex.hxx> |
30 | #include <TopTools_MapOfShape.hxx> |
31 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
32 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
33 | #include <TopExp.hxx> |
34 | #include <gp.hxx> |
35 | #include <gp_Ax2.hxx> |
36 | #include <gp_Pln.hxx> |
37 | #include <Standard_Real.hxx> |
38 | #include <Precision.hxx> |
39 | #include <BRep_GCurve.hxx> |
40 | #include <BRep_TEdge.hxx> |
41 | #include <BRep_TFace.hxx> |
42 | #include <AppParCurves_MultiCurve.hxx> |
43 | #include <AppParCurves_MultiBSpCurve.hxx> |
44 | #include <BRep_ListOfCurveRepresentation.hxx> |
45 | #include <BRep_CurveRepresentation.hxx> |
46 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
47 | #include <BRep_TVertex.hxx> |
48 | #include <Approx_SameParameter.hxx> |
49 | #include <TColgp_Array1OfPnt.hxx> |
50 | #include <TColgp_Array1OfPnt2d.hxx> |
51 | #include <TColStd_Array1OfReal.hxx> |
52 | #include <TColStd_HArray1OfReal.hxx> |
53 | #include <TColStd_MapOfTransient.hxx> |
54 | #include <GeomAdaptor_Curve.hxx> |
55 | #include <GeomAdaptor_HCurve.hxx> |
56 | #include <GeomAdaptor_Surface.hxx> |
57 | #include <GeomAdaptor_HSurface.hxx> |
58 | #include <Geom2dAdaptor_Curve.hxx> |
59 | #include <Geom2dAdaptor_HCurve.hxx> |
60 | #include <Geom2dAdaptor.hxx> |
61 | #include <Geom2dConvert.hxx> |
62 | #include <GCPnts_QuasiUniformDeflection.hxx> |
63 | #include <BSplCLib.hxx> |
64 | #include <ElSLib.hxx> |
65 | #include <Adaptor3d_CurveOnSurface.hxx> |
66 | #include <Extrema_LocateExtPC.hxx> |
67 | #include <ProjLib_ProjectedCurve.hxx> |
68 | #include <BRepClass3d_SolidClassifier.hxx> |
69 | #include <Bnd_Box.hxx> |
70 | #include <BRepBndLib.hxx> |
71 | #include <Approx_CurvilinearParameter.hxx> |
72 | #include <Geom_BSplineSurface.hxx> |
73 | |
74 | // |
75 | // comme on ne pas patcher en cdl GEOMLITE temporairement les GeomLib_ migrent |
76 | // dans BRepLib ... |
77 | // |
78 | |
79 | static Standard_Real thePrecision = Precision::Confusion(); |
80 | static Handle(Geom_Plane) thePlane; |
81 | |
82 | //======================================================================= |
83 | //function : Precision |
84 | //purpose : |
85 | //======================================================================= |
86 | |
87 | void BRepLib::Precision(const Standard_Real P) |
88 | { |
89 | thePrecision = P; |
90 | } |
91 | |
92 | //======================================================================= |
93 | //function : Precision |
94 | //purpose : |
95 | //======================================================================= |
96 | |
97 | Standard_Real BRepLib::Precision() |
98 | { |
99 | return thePrecision; |
100 | } |
101 | |
102 | //======================================================================= |
103 | //function : Plane |
104 | //purpose : |
105 | //======================================================================= |
106 | |
107 | void BRepLib::Plane(const Handle(Geom_Plane)& P) |
108 | { |
109 | thePlane = P; |
110 | } |
111 | |
112 | |
113 | //======================================================================= |
114 | //function : Plane |
115 | //purpose : |
116 | //======================================================================= |
117 | |
118 | const Handle(Geom_Plane)& BRepLib::Plane() |
119 | { |
120 | if (thePlane.IsNull()) thePlane = new Geom_Plane(gp::XOY()); |
121 | return thePlane; |
122 | } |
123 | //======================================================================= |
124 | //function : CheckSameRange |
125 | //purpose : |
126 | //======================================================================= |
127 | |
128 | Standard_Boolean BRepLib::CheckSameRange(const TopoDS_Edge& AnEdge, |
129 | const Standard_Real Tolerance) |
130 | { |
131 | Standard_Boolean IsSameRange = Standard_True, |
132 | first_time_in = Standard_True ; |
133 | |
134 | BRep_ListIteratorOfListOfCurveRepresentation an_Iterator |
135 | ((*((Handle(BRep_TEdge)*)&AnEdge.TShape()))->ChangeCurves()); |
136 | |
137 | Standard_Real first, last; |
138 | #ifndef DEB |
139 | Standard_Real current_first =0., current_last =0. ; |
140 | #else |
141 | Standard_Real current_first,current_last ; |
142 | #endif |
143 | Handle(BRep_GCurve) geometric_representation_ptr ; |
144 | |
145 | while (IsSameRange && an_Iterator.More()) { |
146 | geometric_representation_ptr = |
147 | Handle(BRep_GCurve)::DownCast(an_Iterator.Value()); |
148 | if (!geometric_representation_ptr.IsNull()) { |
149 | |
150 | first = geometric_representation_ptr->First(); |
151 | last = geometric_representation_ptr->Last(); |
152 | if (first_time_in ) { |
153 | current_first = first ; |
154 | current_last = last ; |
155 | first_time_in = Standard_False ; |
156 | } |
157 | else { |
158 | IsSameRange = (Abs(current_first - first) <= Tolerance) |
159 | && (Abs(current_last -last) <= Tolerance ) ; |
160 | } |
161 | } |
162 | an_Iterator.Next() ; |
163 | } |
164 | return IsSameRange ; |
165 | } |
166 | |
167 | //======================================================================= |
168 | //function : SameRange |
169 | //purpose : |
170 | //======================================================================= |
171 | |
172 | void BRepLib::SameRange(const TopoDS_Edge& AnEdge, |
173 | const Standard_Real Tolerance) |
174 | { |
175 | BRep_ListIteratorOfListOfCurveRepresentation an_Iterator |
176 | ((*((Handle(BRep_TEdge)*)&AnEdge.TShape()))->ChangeCurves()); |
177 | |
178 | Handle(Geom2d_Curve) Curve2dPtr, Curve2dPtr2, NewCurve2dPtr, NewCurve2dPtr2; |
179 | TopLoc_Location LocalLoc ; |
180 | |
181 | Standard_Boolean first_time_in = Standard_True, |
182 | has_curve, |
183 | has_closed_curve ; |
184 | Handle(BRep_GCurve) geometric_representation_ptr ; |
185 | Standard_Real first, |
186 | current_first, |
187 | last, |
188 | current_last ; |
189 | |
190 | const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge, |
191 | LocalLoc, |
192 | current_first, |
193 | current_last); |
194 | if (!C.IsNull()) { |
195 | first_time_in = Standard_False ; |
196 | } |
197 | |
198 | while (an_Iterator.More()) { |
199 | geometric_representation_ptr = |
200 | Handle(BRep_GCurve)::DownCast(an_Iterator.Value()); |
201 | if (! geometric_representation_ptr.IsNull()) { |
202 | has_closed_curve = |
203 | has_curve = Standard_False ; |
204 | first = geometric_representation_ptr->First(); |
205 | last = geometric_representation_ptr->Last(); |
206 | if (geometric_representation_ptr->IsCurveOnSurface()) { |
207 | Curve2dPtr = geometric_representation_ptr->PCurve() ; |
208 | has_curve = Standard_True ; |
209 | } |
210 | if (geometric_representation_ptr->IsCurveOnClosedSurface()) { |
211 | Curve2dPtr2 = geometric_representation_ptr->PCurve2() ; |
212 | has_closed_curve = Standard_True ; |
213 | } |
214 | if (has_curve || has_closed_curve) { |
215 | if (first_time_in) { |
216 | current_first = first ; |
217 | current_last = last ; |
218 | first_time_in = Standard_False ; |
219 | } |
220 | |
221 | if (Abs(first - current_first) > Precision::Confusion() || |
222 | Abs(last - current_last) > Precision::Confusion() ) |
223 | { |
224 | if (has_curve) |
225 | { |
226 | GeomLib::SameRange(Tolerance, |
227 | Curve2dPtr, |
228 | geometric_representation_ptr->First(), |
229 | geometric_representation_ptr->Last(), |
230 | current_first, |
231 | current_last, |
232 | NewCurve2dPtr); |
233 | geometric_representation_ptr->PCurve(NewCurve2dPtr) ; |
234 | } |
235 | if (has_closed_curve) |
236 | { |
237 | GeomLib::SameRange(Tolerance, |
238 | Curve2dPtr2, |
239 | geometric_representation_ptr->First(), |
240 | geometric_representation_ptr->Last(), |
241 | current_first, |
242 | current_last, |
243 | NewCurve2dPtr2); |
244 | geometric_representation_ptr->PCurve2(NewCurve2dPtr2) ; |
245 | } |
246 | } |
247 | } |
248 | } |
249 | an_Iterator.Next() ; |
250 | } |
251 | BRep_Builder B; |
252 | B.Range(TopoDS::Edge(AnEdge), |
253 | current_first, |
254 | current_last) ; |
255 | |
256 | B.SameRange(AnEdge, |
257 | Standard_True) ; |
258 | } |
259 | |
260 | //======================================================================= |
261 | //function : EvaluateMaxSegment |
262 | //purpose : return MaxSegment to pass in approximation, if MaxSegment==0 provided |
263 | //======================================================================= |
264 | |
265 | static Standard_Integer evaluateMaxSegment(const Standard_Integer aMaxSegment, |
266 | const Adaptor3d_CurveOnSurface& aCurveOnSurface) |
267 | { |
268 | if (aMaxSegment != 0) return aMaxSegment; |
269 | |
270 | Handle(Adaptor3d_HSurface) aSurf = aCurveOnSurface.GetSurface(); |
271 | Handle(Adaptor2d_HCurve2d) aCurv2d = aCurveOnSurface.GetCurve(); |
272 | |
273 | Standard_Real aNbSKnots = 0, aNbC2dKnots = 0; |
274 | |
275 | if (aSurf->GetType() == GeomAbs_BSplineSurface) { |
276 | Handle(Geom_BSplineSurface) aBSpline = aSurf->BSpline(); |
277 | aNbSKnots = Max(aBSpline->NbUKnots(), aBSpline->NbVKnots()); |
278 | } |
279 | if (aCurv2d->GetType() == GeomAbs_BSplineCurve) { |
280 | aNbC2dKnots = aCurv2d->NbKnots(); |
281 | } |
282 | Standard_Integer aReturn = (Standard_Integer) ( 30 + Max(aNbSKnots, aNbC2dKnots) ) ; |
283 | return aReturn; |
284 | } |
285 | |
286 | //======================================================================= |
287 | //function : BuildCurve3d |
288 | //purpose : |
289 | //======================================================================= |
290 | |
291 | Standard_Boolean BRepLib::BuildCurve3d(const TopoDS_Edge& AnEdge, |
292 | const Standard_Real Tolerance, |
293 | const GeomAbs_Shape Continuity, |
294 | const Standard_Integer MaxDegree, |
295 | const Standard_Integer MaxSegment) |
296 | { |
297 | Standard_Integer //ErrorCode, |
298 | // ReturnCode = 0, |
299 | ii, |
300 | // num_knots, |
301 | jj; |
302 | |
303 | TopLoc_Location LocalLoc,L[2],LC; |
304 | Standard_Real f,l,fc,lc, first[2], last[2], |
305 | tolerance, |
306 | max_deviation, |
307 | average_deviation ; |
308 | Handle(Geom2d_Curve) Curve2dPtr, Curve2dArray[2] ; |
309 | Handle(Geom_Surface) SurfacePtr, SurfaceArray[2] ; |
310 | |
311 | Standard_Integer not_done ; |
312 | // if the edge has a 3d curve returns true |
313 | |
314 | |
315 | const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge,LocalLoc,f,l); |
316 | if (!C.IsNull()) |
317 | return Standard_True; |
318 | // |
319 | // this should not exists but UpdateEdge makes funny things |
320 | // if the edge is not same range |
321 | // |
322 | if (! CheckSameRange(AnEdge, |
323 | Precision::Confusion())) { |
324 | SameRange(AnEdge, |
325 | Tolerance) ; |
326 | } |
327 | |
328 | |
329 | |
330 | // search a curve on a plane |
331 | Handle(Geom_Surface) S; |
332 | Handle(Geom2d_Curve) PC; |
333 | Standard_Integer i = 0; |
334 | Handle(Geom_Plane) P; |
335 | not_done = 1 ; |
336 | |
337 | while (not_done) { |
338 | i++; |
339 | BRep_Tool::CurveOnSurface(AnEdge,PC,S,LocalLoc,f,l,i); |
340 | Handle(Geom_RectangularTrimmedSurface) RT = |
341 | Handle(Geom_RectangularTrimmedSurface)::DownCast(S); |
342 | if ( RT.IsNull()) { |
343 | P = Handle(Geom_Plane)::DownCast(S); |
344 | } |
345 | else { |
346 | P = Handle(Geom_Plane)::DownCast(RT->BasisSurface()); |
347 | } |
348 | not_done = ! (S.IsNull() || !P.IsNull()) ; |
349 | } |
350 | if (! P.IsNull()) { |
351 | // compute the 3d curve |
352 | gp_Ax2 axes = P->Position().Ax2(); |
353 | Handle(Geom_Curve) C3d = GeomLib::To3d(axes,PC); |
354 | |
355 | // update the edge |
356 | Standard_Real First, Last; |
357 | |
358 | BRep_Builder B; |
359 | Standard_Boolean is_closed ; |
360 | is_closed = AnEdge.Closed() ; |
361 | |
362 | B.UpdateEdge(AnEdge,C3d,LocalLoc,0.0e0); |
363 | BRep_Tool::Range(AnEdge, S, LC, First, Last); |
364 | B.Range(AnEdge, First, Last); //Ne pas oublier le range du 3d.(PRO6412) |
365 | TopoDS_Edge E = AnEdge ; |
366 | E.Closed(is_closed) ; |
367 | |
368 | } |
369 | else { |
370 | // |
371 | // compute the 3d curve using existing surface |
372 | // |
373 | fc = f ; |
374 | lc = l ; |
375 | if (!BRep_Tool::Degenerated(AnEdge)) { |
376 | jj = 0 ; |
377 | for (ii = 0 ; ii < 3 ; ii++ ) { |
378 | BRep_Tool::CurveOnSurface(TopoDS::Edge(AnEdge), |
379 | Curve2dPtr, |
380 | SurfacePtr, |
381 | LocalLoc, |
382 | fc, |
383 | lc, |
384 | ii) ; |
385 | |
386 | if (!Curve2dPtr.IsNull() && jj < 2){ |
387 | Curve2dArray[jj] = Curve2dPtr ; |
388 | SurfaceArray[jj] = SurfacePtr ; |
389 | L[jj] = LocalLoc ; |
390 | first[jj] = fc ; |
391 | last[jj] = lc ; |
392 | jj += 1 ; |
393 | } |
394 | } |
395 | f = first[0] ; |
396 | l = last[0] ; |
397 | Curve2dPtr = Curve2dArray[0] ; |
398 | SurfacePtr = SurfaceArray[0] ; |
399 | |
400 | Geom2dAdaptor_Curve AnAdaptor3dCurve2d (Curve2dPtr, f, l) ; |
401 | GeomAdaptor_Surface AnAdaptor3dSurface (SurfacePtr) ; |
402 | Handle(Geom2dAdaptor_HCurve) AnAdaptor3dCurve2dPtr = |
403 | new Geom2dAdaptor_HCurve(AnAdaptor3dCurve2d) ; |
404 | Handle(GeomAdaptor_HSurface) AnAdaptor3dSurfacePtr = |
405 | new GeomAdaptor_HSurface (AnAdaptor3dSurface) ; |
406 | Adaptor3d_CurveOnSurface CurveOnSurface( AnAdaptor3dCurve2dPtr, |
407 | AnAdaptor3dSurfacePtr) ; |
408 | |
409 | Handle(Geom_Curve) NewCurvePtr ; |
410 | |
411 | GeomLib::BuildCurve3d(Tolerance, |
412 | CurveOnSurface, |
413 | f, |
414 | l, |
415 | NewCurvePtr, |
416 | max_deviation, |
417 | average_deviation, |
418 | Continuity, |
419 | MaxDegree, |
420 | evaluateMaxSegment(MaxSegment,CurveOnSurface)) ; |
421 | BRep_Builder B; |
422 | tolerance = BRep_Tool::Tolerance(AnEdge) ; |
423 | //Patch |
424 | //max_deviation = Max(tolerance, max_deviation) ; |
425 | max_deviation = Max( tolerance, Tolerance ); |
426 | |
427 | Standard_Boolean is_closed ; |
428 | is_closed = AnEdge.Closed() ; |
429 | B.UpdateEdge(TopoDS::Edge(AnEdge), |
430 | NewCurvePtr, |
431 | L[0], |
432 | max_deviation) ; |
433 | TopoDS_Edge E = AnEdge ; |
434 | E.Closed(is_closed) ; |
435 | if (jj == 1 ) { |
436 | // |
437 | // if there is only one curve on surface attached to the edge |
438 | // than it can be qualified sameparameter |
439 | // |
440 | B.SameParameter(TopoDS::Edge(AnEdge), |
441 | Standard_True) ; |
442 | } |
443 | } |
444 | else { |
445 | return Standard_False ; |
446 | } |
447 | |
448 | } |
449 | return Standard_True; |
450 | } |
451 | //======================================================================= |
452 | //function : BuildCurves3d |
453 | //purpose : |
454 | //======================================================================= |
455 | |
456 | Standard_Boolean BRepLib::BuildCurves3d(const TopoDS_Shape& S) |
457 | |
458 | { |
459 | return BRepLib::BuildCurves3d(S, |
460 | 1.0e-5) ; |
461 | } |
462 | |
463 | //======================================================================= |
464 | //function : BuildCurves3d |
465 | //purpose : |
466 | //======================================================================= |
467 | |
468 | Standard_Boolean BRepLib::BuildCurves3d(const TopoDS_Shape& S, |
469 | const Standard_Real Tolerance, |
470 | const GeomAbs_Shape Continuity, |
471 | const Standard_Integer MaxDegree, |
472 | const Standard_Integer MaxSegment) |
473 | { |
474 | Standard_Boolean boolean_value, |
475 | ok = Standard_True; |
476 | TopTools_MapOfShape a_counter ; |
477 | TopExp_Explorer ex(S,TopAbs_EDGE); |
478 | |
479 | while (ex.More()) { |
480 | if (a_counter.Add(ex.Current())) { |
481 | boolean_value = |
482 | BuildCurve3d(TopoDS::Edge(ex.Current()), |
483 | Tolerance, Continuity, |
484 | MaxDegree, MaxSegment); |
485 | ok = ok && boolean_value ; |
486 | } |
487 | ex.Next(); |
488 | } |
489 | return ok; |
490 | } |
491 | //======================================================================= |
492 | //function : UpdateEdgeTolerance |
493 | //purpose : |
494 | //======================================================================= |
495 | |
496 | Standard_Boolean BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge, |
497 | const Standard_Real MinToleranceRequested, |
498 | const Standard_Real MaxToleranceToCheck) |
499 | { |
500 | |
501 | Standard_Integer curve_on_surface_index, |
502 | curve_index, |
503 | not_done, |
504 | has_closed_curve, |
505 | has_curve, |
506 | jj, |
507 | ii, |
508 | geom_reference_curve_flag = 0, |
509 | max_sampling_points = 90, |
510 | min_sampling_points = 30 ; |
511 | |
512 | Standard_Real factor = 100.0e0, |
513 | // sampling_array[2], |
514 | safe_factor = 1.4e0, |
515 | current_last, |
516 | current_first, |
517 | max_distance, |
518 | coded_edge_tolerance, |
519 | edge_tolerance = 0.0e0 ; |
520 | Handle(TColStd_HArray1OfReal) parameters_ptr ; |
521 | Handle(BRep_GCurve) geometric_representation_ptr ; |
522 | |
523 | if (BRep_Tool::Degenerated(AnEdge)) return Standard_False ; |
524 | coded_edge_tolerance = BRep_Tool::Tolerance(AnEdge) ; |
525 | if (coded_edge_tolerance > MaxToleranceToCheck) return Standard_False ; |
526 | |
527 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&AnEdge.TShape()); |
528 | BRep_ListOfCurveRepresentation& list_curve_rep = TE->ChangeCurves() ; |
529 | BRep_ListIteratorOfListOfCurveRepresentation an_iterator(list_curve_rep), |
530 | second_iterator(list_curve_rep) ; |
531 | Handle(Geom2d_Curve) curve2d_ptr, new_curve2d_ptr; |
532 | Handle(Geom_Surface) surface_ptr ; |
533 | TopLoc_Location local_location ; |
534 | GCPnts_QuasiUniformDeflection a_sampler ; |
535 | GeomAdaptor_Curve geom_reference_curve ; |
536 | Adaptor3d_CurveOnSurface curve_on_surface_reference ; |
537 | Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge, |
538 | local_location, |
539 | current_first, |
540 | current_last); |
541 | curve_on_surface_index = -1 ; |
542 | if (!C.IsNull()) { |
543 | if (! local_location.IsIdentity()) { |
544 | C = Handle(Geom_Curve):: |
545 | DownCast(C-> Transformed(local_location.Transformation()) ) ; |
546 | } |
547 | geom_reference_curve.Load(C) ; |
548 | geom_reference_curve_flag = 1 ; |
549 | a_sampler.Initialize(geom_reference_curve, |
550 | MinToleranceRequested * factor, |
551 | current_first, |
552 | current_last) ; |
553 | } |
554 | else { |
555 | not_done = 1 ; |
556 | curve_on_surface_index = 0 ; |
557 | |
558 | while (not_done && an_iterator.More()) { |
559 | geometric_representation_ptr = |
560 | Handle(BRep_GCurve)::DownCast(second_iterator.Value()); |
561 | if (!geometric_representation_ptr.IsNull() |
562 | && geometric_representation_ptr->IsCurveOnSurface()) { |
563 | curve2d_ptr = geometric_representation_ptr->PCurve() ; |
564 | local_location = geometric_representation_ptr->Location() ; |
565 | current_first = geometric_representation_ptr->First(); |
566 | //first = geometric_representation_ptr->First(); |
567 | current_last = geometric_representation_ptr->Last(); |
568 | // must be inverted |
569 | // |
570 | if (! local_location.IsIdentity() ) { |
571 | surface_ptr = Handle(Geom_Surface):: |
572 | DownCast( geometric_representation_ptr->Surface()-> |
573 | Transformed(local_location.Transformation()) ) ; |
574 | } |
575 | else { |
576 | surface_ptr = |
577 | geometric_representation_ptr->Surface() ; |
578 | } |
579 | not_done = 0 ; |
580 | } |
581 | curve_on_surface_index += 1 ; |
582 | } |
583 | Geom2dAdaptor_Curve AnAdaptor3dCurve2d (curve2d_ptr) ; |
584 | GeomAdaptor_Surface AnAdaptor3dSurface (surface_ptr) ; |
585 | Handle(Geom2dAdaptor_HCurve) AnAdaptor3dCurve2dPtr = |
586 | new Geom2dAdaptor_HCurve(AnAdaptor3dCurve2d) ; |
587 | Handle(GeomAdaptor_HSurface) AnAdaptor3dSurfacePtr = |
588 | new GeomAdaptor_HSurface (AnAdaptor3dSurface) ; |
589 | curve_on_surface_reference.Load( AnAdaptor3dCurve2dPtr) ; |
590 | curve_on_surface_reference.Load( AnAdaptor3dSurfacePtr) ; |
591 | a_sampler.Initialize(curve_on_surface_reference, |
592 | MinToleranceRequested * factor, |
593 | current_first, |
594 | current_last) ; |
595 | } |
596 | TColStd_Array1OfReal sampling_parameters(1,a_sampler.NbPoints()) ; |
597 | for (ii = 1 ; ii <= a_sampler.NbPoints() ; ii++) { |
598 | sampling_parameters(ii) = a_sampler.Parameter(ii) ; |
599 | } |
600 | if (a_sampler.NbPoints() < min_sampling_points) { |
601 | GeomLib::DensifyArray1OfReal(min_sampling_points, |
602 | sampling_parameters, |
603 | parameters_ptr) ; |
604 | } |
605 | else if (a_sampler.NbPoints() > max_sampling_points) { |
606 | GeomLib::RemovePointsFromArray(max_sampling_points, |
607 | sampling_parameters, |
608 | parameters_ptr) ; |
609 | } |
610 | else { |
611 | jj = 1 ; |
612 | parameters_ptr = |
613 | new TColStd_HArray1OfReal(1,sampling_parameters.Length()) ; |
614 | for (ii = sampling_parameters.Lower() ; ii <= sampling_parameters.Upper() ; ii++) { |
615 | parameters_ptr->ChangeArray1()(jj) = |
616 | sampling_parameters(ii) ; |
617 | jj +=1 ; |
618 | } |
619 | } |
620 | |
621 | curve_index = 0 ; |
622 | |
623 | while (second_iterator.More()) { |
624 | geometric_representation_ptr = |
625 | Handle(BRep_GCurve)::DownCast(second_iterator.Value()); |
626 | if (! geometric_representation_ptr.IsNull() && |
627 | curve_index != curve_on_surface_index) { |
628 | has_closed_curve = |
629 | has_curve = Standard_False ; |
630 | // first = geometric_representation_ptr->First(); |
631 | // last = geometric_representation_ptr->Last(); |
632 | local_location = geometric_representation_ptr->Location() ; |
633 | if (geometric_representation_ptr->IsCurveOnSurface()) { |
634 | curve2d_ptr = geometric_representation_ptr->PCurve() ; |
635 | has_curve = Standard_True ; |
636 | } |
637 | if (geometric_representation_ptr->IsCurveOnClosedSurface()) { |
638 | curve2d_ptr = geometric_representation_ptr->PCurve2() ; |
639 | has_closed_curve = Standard_True ; |
640 | } |
641 | |
642 | if (has_curve || |
643 | has_closed_curve) { |
644 | if (! local_location.IsIdentity() ) { |
645 | surface_ptr = Handle(Geom_Surface):: |
646 | DownCast( geometric_representation_ptr->Surface()-> |
647 | Transformed(local_location.Transformation()) ) ; |
648 | } |
649 | else { |
650 | surface_ptr = |
651 | geometric_representation_ptr->Surface() ; |
652 | } |
653 | Geom2dAdaptor_Curve an_adaptor_curve2d (curve2d_ptr) ; |
654 | GeomAdaptor_Surface an_adaptor_surface(surface_ptr) ; |
655 | Handle(Geom2dAdaptor_HCurve) an_adaptor_curve2d_ptr = |
656 | new Geom2dAdaptor_HCurve(an_adaptor_curve2d) ; |
657 | Handle(GeomAdaptor_HSurface) an_adaptor_surface_ptr = |
658 | new GeomAdaptor_HSurface (an_adaptor_surface) ; |
659 | Adaptor3d_CurveOnSurface a_curve_on_surface(an_adaptor_curve2d_ptr, |
660 | an_adaptor_surface_ptr) ; |
661 | |
662 | if (BRep_Tool::SameParameter(AnEdge)) { |
663 | |
664 | GeomLib::EvalMaxParametricDistance(a_curve_on_surface, |
665 | geom_reference_curve, |
666 | MinToleranceRequested, |
667 | parameters_ptr->Array1(), |
668 | max_distance) ; |
669 | } |
670 | else if (geom_reference_curve_flag) { |
671 | GeomLib::EvalMaxDistanceAlongParameter(a_curve_on_surface, |
672 | geom_reference_curve, |
673 | MinToleranceRequested, |
674 | parameters_ptr->Array1(), |
675 | max_distance) ; |
676 | } |
677 | else { |
678 | |
679 | GeomLib::EvalMaxDistanceAlongParameter(a_curve_on_surface, |
680 | curve_on_surface_reference, |
681 | MinToleranceRequested, |
682 | parameters_ptr->Array1(), |
683 | max_distance) ; |
684 | } |
685 | max_distance *= safe_factor ; |
686 | edge_tolerance = Max(max_distance, edge_tolerance) ; |
687 | } |
688 | |
689 | |
690 | } |
691 | curve_index += 1 ; |
692 | second_iterator.Next() ; |
693 | } |
694 | |
695 | TE->Tolerance(edge_tolerance); |
696 | return Standard_True ; |
697 | |
698 | } |
699 | //======================================================================= |
700 | //function : UpdateEdgeTolerance |
701 | //purpose : |
702 | //======================================================================= |
703 | |
704 | Standard_Boolean BRepLib::UpdateEdgeTolerance(const TopoDS_Shape& S, |
705 | const Standard_Real MinToleranceRequested, |
706 | const Standard_Real MaxToleranceToCheck) |
707 | { |
708 | TopExp_Explorer ex(S,TopAbs_EDGE); |
709 | TopTools_MapOfShape a_counter ; |
710 | |
711 | Standard_Boolean return_status = Standard_False, |
712 | local_flag ; |
713 | |
714 | while (ex.More()) { |
715 | if (a_counter.Add(ex.Current())) { |
716 | local_flag = |
717 | BRepLib::UpdateEdgeTol(TopoDS::Edge(ex.Current()), |
718 | MinToleranceRequested, |
719 | MaxToleranceToCheck) ; |
720 | if (local_flag && ! return_status) { |
721 | return_status = Standard_True ; |
722 | } |
723 | } |
724 | ex.Next(); |
725 | } |
726 | return return_status ; |
727 | } |
728 | |
729 | //======================================================================= |
730 | //function : SetEdgeTol |
731 | //purpose : |
732 | //======================================================================= |
733 | |
734 | static void SetEdgeTol(const TopoDS_Edge& E, |
735 | const TopoDS_Face& F) |
736 | { |
737 | TopLoc_Location L; |
738 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L); |
739 | TopLoc_Location l = L.Predivided(E.Location()); |
740 | |
741 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape()); |
742 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->ChangeCurves()); |
743 | |
744 | while (itcr.More()) { |
745 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
746 | if(cr->IsCurveOnSurface(S,l)) return; |
747 | itcr.Next(); |
748 | } |
749 | |
750 | Handle(Geom_Plane) GP; |
751 | Handle(Geom_RectangularTrimmedSurface) GRTS; |
752 | GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S); |
753 | if(!GRTS.IsNull()) |
754 | GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface()); |
755 | else |
756 | GP = Handle(Geom_Plane)::DownCast(S); |
757 | |
758 | static Handle(GeomAdaptor_HCurve) HC; |
759 | static Handle(GeomAdaptor_HSurface) HS; |
760 | if (HC.IsNull()) { |
761 | HC = new GeomAdaptor_HCurve(); |
762 | HS = new GeomAdaptor_HSurface(); |
763 | } |
764 | |
765 | TopLoc_Location LC; |
766 | Standard_Real First, Last; |
767 | GeomAdaptor_Curve& GAC = HC->ChangeCurve(); |
768 | GAC.Load(BRep_Tool::Curve(E,LC,First,Last)); |
769 | LC = L.Predivided(LC); |
770 | |
771 | if (!LC.IsIdentity()) { |
772 | GP = Handle(Geom_Plane)::DownCast( |
773 | GP->Transformed(LC.Transformation())); |
774 | } |
775 | GeomAdaptor_Surface& GAS = HS->ChangeSurface(); |
776 | GAS.Load(GP); |
777 | |
778 | ProjLib_ProjectedCurve Proj(HS,HC); |
779 | Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj); |
780 | |
781 | gp_Pln pln = GAS.Plane(); |
782 | Standard_Real d2 = 0.; |
783 | Standard_Integer nn = 23; |
784 | Standard_Real unsurnn = 1./nn; |
785 | for(Standard_Integer i = 0; i <= nn; i++){ |
786 | Standard_Real t = unsurnn*i; |
787 | Standard_Real u = First*(1.-t) + Last*t; |
788 | gp_Pnt Pc3d = HC->Value(u); |
789 | gp_Pnt2d p2d = pc->Value(u); |
790 | gp_Pnt Pcons = ElSLib::Value(p2d.X(),p2d.Y(),pln); |
791 | Standard_Real temp = Pc3d.SquareDistance(Pcons); |
792 | if(temp > d2) d2 = temp; |
793 | } |
794 | d2 = 1.5*sqrt(d2); |
795 | TE->UpdateTolerance(d2); |
796 | } |
797 | |
798 | //======================================================================= |
799 | //function : SameParameter |
800 | //purpose : |
801 | //======================================================================= |
802 | void BRepLib::SameParameter(const TopoDS_Shape& S, |
803 | const Standard_Real Tolerance, |
804 | const Standard_Boolean forced) |
805 | { |
806 | TopExp_Explorer ex(S,TopAbs_EDGE); |
807 | TopTools_MapOfShape Done; |
808 | BRep_Builder brB; |
809 | |
810 | while (ex.More()) { |
811 | if (Done.Add(ex.Current())) { |
812 | if (forced) { |
813 | brB.SameRange(TopoDS::Edge(ex.Current()), Standard_False); |
814 | brB.SameParameter(TopoDS::Edge(ex.Current()), Standard_False); |
815 | } |
816 | BRepLib::SameParameter(TopoDS::Edge(ex.Current()),Tolerance); |
817 | } |
818 | ex.Next(); |
819 | } |
820 | |
821 | Done.Clear(); |
822 | BRepAdaptor_Surface BS; |
823 | for(ex.Init(S,TopAbs_FACE); ex.More(); ex.Next()){ |
824 | const TopoDS_Face& curface = TopoDS::Face(ex.Current()); |
825 | if(!Done.Add(curface)) continue; |
826 | BS.Initialize(curface); |
827 | if(BS.GetType() != GeomAbs_Plane) continue; |
828 | TopExp_Explorer ex2; |
829 | for(ex2.Init(curface,TopAbs_EDGE); ex2.More(); ex2.Next()){ |
830 | const TopoDS_Edge& E = TopoDS::Edge(ex2.Current()); |
831 | SetEdgeTol(E,curface); |
832 | } |
833 | } |
834 | BRepLib::UpdateTolerances(S); |
835 | } |
836 | |
837 | //======================================================================= |
838 | //function : SameParameter |
839 | //WARNING : Nouvelle spec DUB LBO 9/9/97. |
840 | // On recode dans l arete la meilleure tolerance trouvee, |
841 | // pour les vertex extremites il faudra trouver autre chose. |
842 | //======================================================================= |
843 | static Standard_Boolean EvalTol(const Handle(Geom2d_Curve)& pc, |
844 | const Handle(Geom_Surface)& s, |
845 | const GeomAdaptor_Curve& gac, |
846 | const Standard_Real tol, |
847 | Standard_Real& tolbail) |
848 | { |
849 | Standard_Integer ok = 0; |
850 | Standard_Real f = gac.FirstParameter(); |
851 | Standard_Real l = gac.LastParameter(); |
852 | Extrema_LocateExtPC Projector; |
853 | Projector.Initialize(gac,f,l,tol); |
854 | Standard_Real u,v; |
855 | gp_Pnt p; |
856 | tolbail = tol; |
857 | for(Standard_Integer i = 1; i <= 5; i++){ |
858 | Standard_Real t = i/6.; |
859 | t = (1.-t) * f + t * l; |
860 | pc->Value(t).Coord(u,v); |
861 | p = s->Value(u,v); |
862 | Projector.Perform(p,t); |
863 | if (Projector.IsDone()) { |
864 | Standard_Real dist2 = Projector.SquareDistance(); |
865 | if(dist2 > tolbail * tolbail) tolbail = sqrt (dist2); |
866 | ok++; |
867 | } |
868 | } |
869 | return (ok > 2); |
870 | } |
871 | |
872 | static Standard_Real ComputeTol(const Handle(Adaptor3d_HCurve)& c3d, |
873 | const Handle(Adaptor2d_HCurve2d)& c2d, |
874 | const Handle(Adaptor3d_HSurface)& surf, |
875 | const Standard_Integer nbp) |
876 | |
877 | { |
878 | |
879 | TColStd_Array1OfReal dist(1,nbp+10); |
880 | dist.Init(-1.); |
881 | |
882 | |
883 | Adaptor3d_CurveOnSurface cons(c2d,surf); |
884 | Standard_Real d2 = 0.; |
885 | Standard_Integer nn = nbp; |
886 | Standard_Real unsurnn = 1./nn; |
887 | Standard_Real first = c3d->FirstParameter(); |
888 | Standard_Real last = c3d->LastParameter(); |
889 | Standard_Integer i = 0; |
890 | for(i = 0; i <= nn; i++){ |
891 | Standard_Real t = unsurnn*i; |
892 | Standard_Real u = first*(1.-t) + last*t; |
893 | gp_Pnt Pc3d = c3d->Value(u); |
894 | gp_Pnt Pcons = cons.Value(u); |
895 | if (Precision::IsInfinite(Pcons.X()) || |
896 | Precision::IsInfinite(Pcons.Y()) || |
897 | Precision::IsInfinite(Pcons.Z())) { |
898 | d2=Precision::Infinite(); |
899 | break; |
900 | } |
901 | Standard_Real temp = Pc3d.SquareDistance(Pcons); |
902 | |
903 | |
904 | dist(i+1) = temp; |
905 | |
906 | |
907 | if(temp > d2) d2 = temp; |
908 | } |
909 | |
910 | |
911 | Standard_Boolean ana = Standard_False; |
912 | Standard_Real D2 = 0; |
913 | Standard_Integer N1 = 0; |
914 | Standard_Integer N2 = 0; |
915 | Standard_Integer N3 = 0; |
916 | |
917 | for( i = 1; i<= nbp+10; i++) |
918 | if( dist(i) > 0 ) { |
919 | if( dist(i) < 1.0 ) N1++; |
920 | else N2++; |
921 | } |
922 | |
923 | if( N1 > N2 && N2 != 0 ) N3 = 100*N2/(N1+N2); |
924 | if( N3 < 10 && N3 != 0 ) { |
925 | ana = Standard_True; |
926 | for( i = 1; i<= nbp+10; i++) |
927 | if( dist(i) > 0 && dist(i) < 1.0 ) |
928 | if( dist(i) > D2 ) D2 = dist(i); |
929 | } |
930 | |
931 | //d2 = 1.5*sqrt(d2); |
932 | d2 = (!ana) ? 1.5*sqrt(d2) : 1.5*sqrt(D2); |
933 | if(d2<1.e-7) d2 = 1.e-7; |
934 | |
935 | return d2; |
936 | } |
937 | |
938 | |
939 | |
940 | void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, |
941 | const Standard_Real Tolerance) |
942 | { |
943 | if (BRep_Tool::SameParameter(AnEdge)) return; |
944 | |
945 | const Standard_Integer NCONTROL = 22; |
946 | |
947 | static Handle(GeomAdaptor_HCurve) HC; |
948 | static Handle(Geom2dAdaptor_HCurve) HC2d; |
949 | static Handle(GeomAdaptor_HSurface) HS; |
950 | if(HC.IsNull()){ |
951 | HC = new GeomAdaptor_HCurve(); |
952 | HC2d = new Geom2dAdaptor_HCurve(); |
953 | HS = new GeomAdaptor_HSurface(); |
954 | } |
955 | GeomAdaptor_Curve& GAC = HC->ChangeCurve(); |
956 | Geom2dAdaptor_Curve& GAC2d = HC2d->ChangeCurve2d(); |
957 | GeomAdaptor_Surface& GAS = HS->ChangeSurface(); |
958 | #ifndef DEB |
959 | Standard_Real f3d =0.,l3d =0.; |
960 | #else |
961 | Standard_Real f3d,l3d; |
962 | #endif |
963 | TopLoc_Location L3d; |
964 | Handle(Geom_Curve) C3d; |
965 | |
966 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &AnEdge.TShape()); |
967 | BRep_ListOfCurveRepresentation& CList = TE->ChangeCurves(); |
968 | BRep_ListIteratorOfListOfCurveRepresentation It(CList); |
969 | |
970 | Standard_Boolean NotDone = Standard_True; |
971 | |
972 | while (NotDone && It.More()) { |
973 | Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(It.Value()); |
974 | if (!GCurve.IsNull() && GCurve->IsCurve3D()) { |
975 | C3d = GCurve->Curve3D() ; |
976 | f3d = GCurve->First(); |
977 | l3d = GCurve->Last(); |
978 | L3d = GCurve->Location() ; |
979 | NotDone = Standard_False; |
980 | } |
981 | It.Next() ; |
982 | } |
983 | |
984 | if(C3d.IsNull()) return; |
985 | |
986 | // modified by NIZHNY-OCC486 Tue Aug 27 17:15:13 2002 : |
987 | Standard_Boolean m_TrimmedPeriodical = Standard_False; |
988 | Handle(Standard_Type) TheType = C3d->DynamicType(); |
989 | if( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) |
990 | { |
991 | const Handle(Geom_Curve)& gtC = (*((Handle(Geom_TrimmedCurve)*)&C3d))->BasisCurve(); |
992 | m_TrimmedPeriodical = gtC->IsPeriodic(); |
993 | } |
994 | // modified by NIZHNY-OCC486 Tue Aug 27 17:15:17 2002 . |
995 | |
996 | BRep_Builder B; |
997 | if(!C3d->IsPeriodic()) { |
998 | Standard_Real Udeb = C3d->FirstParameter(); |
999 | Standard_Real Ufin = C3d->LastParameter(); |
1000 | // modified by NIZHNY-OCC486 Tue Aug 27 17:17:14 2002 : |
1001 | //if (Udeb > f3d) f3d = Udeb; |
1002 | //if (l3d > Ufin) l3d = Ufin; |
1003 | if(!m_TrimmedPeriodical) |
1004 | { |
1005 | if (Udeb > f3d) f3d = Udeb; |
1006 | if (l3d > Ufin) l3d = Ufin; |
1007 | } |
1008 | // modified by NIZHNY-OCC486 Tue Aug 27 17:17:55 2002 . |
1009 | } |
1010 | if(!L3d.IsIdentity()){ |
1011 | C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L3d.Transformation())); |
1012 | } |
1013 | GAC.Load(C3d,f3d,l3d); |
1014 | |
1015 | Standard_Boolean IsSameP = 1; |
1016 | Standard_Real maxdist = 0.; |
1017 | |
1018 | // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin |
1019 | Standard_Real anEdgeTol = BRep_Tool::Tolerance(AnEdge); |
1020 | // Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End |
1021 | Standard_Boolean SameRange = BRep_Tool::SameRange(AnEdge); |
1022 | Standard_Boolean YaPCu = Standard_False; |
1023 | It.Initialize(CList); |
1024 | |
1025 | while (It.More()) { |
1026 | Standard_Boolean isANA = Standard_False; |
1027 | Standard_Boolean isBSP = Standard_False; |
1028 | Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(It.Value()); |
1029 | Handle(Geom2d_Curve) PC[2]; |
1030 | Handle(Geom_Surface) S; |
1031 | if (!GCurve.IsNull() && GCurve->IsCurveOnSurface()) { |
1032 | YaPCu = Standard_True; |
1033 | PC[0] = GCurve->PCurve(); |
1034 | TopLoc_Location PCLoc = GCurve->Location(); |
1035 | S = GCurve->Surface(); |
1036 | if (!PCLoc.IsIdentity() ) { |
1037 | S = Handle(Geom_Surface)::DownCast(S->Transformed(PCLoc.Transformation())); |
1038 | } |
1039 | GAS.Load(S); |
1040 | if (GCurve->IsCurveOnClosedSurface()) { |
1041 | PC[1] = GCurve->PCurve2(); |
1042 | } |
1043 | |
1044 | // Eval tol2d to compute SameRange |
1045 | Standard_Real UResol = GAS.UResolution(Tolerance); |
1046 | Standard_Real VResol = GAS.VResolution(Tolerance); |
1047 | Standard_Real Tol2d = Min(UResol, VResol); |
1048 | for(Standard_Integer i = 0; i < 2; i++){ |
1049 | Handle(Geom2d_Curve) curPC = PC[i]; |
1050 | Standard_Boolean updatepc = 0; |
1051 | if(curPC.IsNull()) break; |
1052 | if(!SameRange){ |
1053 | GeomLib::SameRange(Tol2d, |
1054 | PC[i],GCurve->First(),GCurve->Last(), |
1055 | f3d,l3d,curPC); |
1056 | |
1057 | updatepc = (curPC != PC[i]); |
1058 | |
1059 | } |
1060 | Standard_Boolean goodpc = 1; |
1061 | GAC2d.Load(curPC,f3d,l3d); |
1062 | |
1063 | Standard_Real error = ComputeTol(HC, HC2d, HS, NCONTROL); |
1064 | |
1065 | if(GAC2d.GetType() == GeomAbs_BSplineCurve && |
1066 | GAC2d.Continuity() == GeomAbs_C0) { |
1067 | Handle(Geom2d_BSplineCurve) bs2d = GAC2d.BSpline(); |
1068 | Handle(Geom2d_BSplineCurve) bs2dsov = bs2d; |
1069 | Standard_Real fC0 = bs2d->FirstParameter(), lC0 = bs2d->LastParameter(); |
1070 | Standard_Boolean repar = Standard_True; |
1071 | gp_Pnt2d OriginPoint; |
1072 | bs2d->D0(fC0, OriginPoint); |
1073 | Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d, Tol2d); |
1074 | isBSP = Standard_True; |
1075 | |
1076 | if(bs2d->IsPeriodic()) { // -------- IFV, Jan 2000 |
1077 | gp_Pnt2d NewOriginPoint; |
1078 | bs2d->D0(bs2d->FirstParameter(), NewOriginPoint); |
1079 | if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() || |
1080 | Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion() ) { |
1081 | |
1082 | TColStd_Array1OfReal Knotbs2d (1, bs2d->NbKnots()); |
1083 | bs2d->Knots(Knotbs2d); |
1084 | |
1085 | for(Standard_Integer Index = 1; Index <= bs2d->NbKnots(); Index++) { |
1086 | bs2d->D0(Knotbs2d(Index), NewOriginPoint); |
1087 | if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() || |
1088 | Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion() ) continue; |
1089 | |
1090 | bs2d->SetOrigin(Index); |
1091 | break; |
1092 | } |
1093 | } |
1094 | } |
1095 | |
1096 | if(bs2d->Continuity() == GeomAbs_C0) { |
1097 | Standard_Real tolbail; |
1098 | if(EvalTol(curPC,S,GAC,Tolerance,tolbail)){ |
1099 | bs2d = bs2dsov; |
1100 | Standard_Real UResbail = GAS.UResolution(tolbail); |
1101 | Standard_Real VResbail = GAS.VResolution(tolbail); |
1102 | Standard_Real Tol2dbail = Min(UResbail,VResbail); |
1103 | bs2d->D0(bs2d->FirstParameter(), OriginPoint); |
1104 | |
1105 | Standard_Integer nbp = bs2d->NbPoles(); |
1106 | TColgp_Array1OfPnt2d poles(1,nbp); |
1107 | bs2d->Poles(poles); |
1108 | gp_Pnt2d p = poles(1), p1; |
1109 | Standard_Real d = Precision::Infinite(); |
1110 | for(Standard_Integer ip = 2; ip <= nbp; ip++) { |
1111 | p1 = poles(ip); |
1112 | d = Min(d,p.SquareDistance(p1)); |
1113 | p = p1; |
1114 | } |
1115 | d = sqrt(d)*.1; |
1116 | |
1117 | Tol2dbail = Max(Min(Tol2dbail,d),Tol2d); |
1118 | |
1119 | Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d,Tol2dbail); |
1120 | |
1121 | if(bs2d->IsPeriodic()) { // -------- IFV, Jan 2000 |
1122 | gp_Pnt2d NewOriginPoint; |
1123 | bs2d->D0(bs2d->FirstParameter(), NewOriginPoint); |
1124 | if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() || |
1125 | Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion() ) { |
1126 | |
1127 | TColStd_Array1OfReal Knotbs2d (1, bs2d->NbKnots()); |
1128 | bs2d->Knots(Knotbs2d); |
1129 | |
1130 | for(Standard_Integer Index = 1; Index <= bs2d->NbKnots(); Index++) { |
1131 | bs2d->D0(Knotbs2d(Index), NewOriginPoint); |
1132 | if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() || |
1133 | Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion() ) continue; |
1134 | |
1135 | bs2d->SetOrigin(Index); |
1136 | break; |
1137 | } |
1138 | } |
1139 | } |
1140 | |
1141 | |
1142 | if(bs2d->Continuity() == GeomAbs_C0) { |
1143 | goodpc = 1; |
1144 | bs2d = bs2dsov; |
1145 | repar = Standard_False; |
1146 | } |
1147 | } |
1148 | else goodpc = 0; |
1149 | } |
1150 | |
1151 | if(goodpc){ |
1152 | if(repar) { |
1153 | Standard_Integer NbKnots = bs2d->NbKnots(); |
1154 | TColStd_Array1OfReal Knots(1,NbKnots); |
1155 | bs2d->Knots(Knots); |
1156 | // BSplCLib::Reparametrize(f3d,l3d,Knots); |
1157 | BSplCLib::Reparametrize(fC0,lC0,Knots); |
1158 | bs2d->SetKnots(Knots); |
1159 | GAC2d.Load(bs2d,f3d,l3d); |
1160 | curPC = bs2d; |
1161 | Standard_Boolean updatepcsov = updatepc; |
1162 | updatepc = Standard_True; |
1163 | |
1164 | Standard_Real error1 = ComputeTol(HC, HC2d, HS, NCONTROL); |
1165 | if(error1 > error) { |
1166 | bs2d = bs2dsov; |
1167 | GAC2d.Load(bs2d,f3d,l3d); |
1168 | curPC = bs2d; |
1169 | updatepc = updatepcsov; |
1170 | isANA = Standard_True; |
1171 | } |
1172 | else { |
1173 | error = error1; |
1174 | } |
1175 | } |
1176 | |
1177 | //check, if new BSpline "good" or not --------- IFV, Jan of 2000 |
1178 | GeomAbs_Shape cont = bs2d->Continuity(); |
1179 | Standard_Boolean IsBad = Standard_False; |
1180 | |
1181 | if(cont > GeomAbs_C0 && error > Max(1.e-3,Tolerance)) { |
1182 | Standard_Integer NbKnots = bs2d->NbKnots(); |
1183 | TColStd_Array1OfReal Knots(1,NbKnots); |
1184 | bs2d->Knots(Knots); |
1185 | Standard_Real critratio = 10.; |
1186 | Standard_Real dtprev = Knots(2) - Knots(1), dtratio = 1.; |
1187 | Standard_Real dtmin = dtprev; |
1188 | Standard_Real dtcur; |
1189 | for(Standard_Integer j = 2; j < NbKnots; j++) { |
1190 | dtcur = Knots(j+1) - Knots(j); |
1191 | dtmin = Min(dtmin, dtcur); |
1192 | |
1193 | if(IsBad) continue; |
1194 | |
1195 | if(dtcur > dtprev) dtratio = dtcur/dtprev; |
1196 | else dtratio = dtprev/dtcur; |
1197 | if(dtratio > critratio) {IsBad = Standard_True;} |
1198 | dtprev = dtcur; |
1199 | |
1200 | } |
1201 | if(IsBad) { |
1202 | // To avoid failures in Approx_CurvilinearParameter |
1203 | bs2d->Resolution(Max(1.e-3,Tolerance), dtcur); |
1204 | if(dtmin < dtcur) IsBad = Standard_False; |
1205 | } |
1206 | } |
1207 | |
1208 | |
1209 | if(IsBad ) { //if BSpline "bad", try to reparametrize it |
1210 | // by its curve length |
1211 | |
1212 | // GeomAbs_Shape cont = bs2d->Continuity(); |
1213 | if(cont > GeomAbs_C2) cont = GeomAbs_C2; |
1214 | Standard_Integer maxdeg = bs2d->Degree(); |
1215 | if(maxdeg == 1) maxdeg = 14; |
1216 | Approx_CurvilinearParameter AppCurPar(HC2d, HS, Max(1.e-3,Tolerance), |
1217 | cont, maxdeg, 10); |
1218 | if(AppCurPar.IsDone() || AppCurPar.HasResult()) { |
1219 | bs2d = AppCurPar.Curve2d1(); |
1220 | GAC2d.Load(bs2d,f3d,l3d); |
1221 | curPC = bs2d; |
1222 | |
1223 | if(Abs(bs2d->FirstParameter() - fC0) > Tol2d || |
1224 | Abs(bs2d->LastParameter() - lC0) > Tol2d ) { |
1225 | Standard_Integer NbKnots = bs2d->NbKnots(); |
1226 | TColStd_Array1OfReal Knots(1,NbKnots); |
1227 | bs2d->Knots(Knots); |
1228 | // BSplCLib::Reparametrize(f3d,l3d,Knots); |
1229 | BSplCLib::Reparametrize(fC0,lC0,Knots); |
1230 | bs2d->SetKnots(Knots); |
1231 | GAC2d.Load(bs2d,f3d,l3d); |
1232 | curPC = bs2d; |
1233 | |
1234 | } |
1235 | } |
1236 | } |
1237 | |
1238 | |
1239 | } |
1240 | } |
1241 | |
1242 | |
1243 | if(goodpc){ |
1244 | // Approx_SameParameter SameP(HC,HC2d,HS,Tolerance); |
1245 | Standard_Real aTol = (isANA && isBSP) ? 1.e-7 : Tolerance; |
1246 | Approx_SameParameter SameP(HC,HC2d,HS,aTol); |
1247 | |
1248 | if (SameP.IsSameParameter()) { |
1249 | maxdist = Max(maxdist,SameP.TolReached()); |
1250 | if(updatepc){ |
1251 | if (i == 0) GCurve->PCurve(curPC); |
1252 | else GCurve->PCurve2(curPC); |
1253 | } |
1254 | } |
1255 | else if (SameP.IsDone()) { |
1256 | Standard_Real tolreached = SameP.TolReached(); |
1257 | if(tolreached < error) { |
1258 | curPC = SameP.Curve2d(); |
1259 | updatepc = Standard_True; |
1260 | maxdist = Max(maxdist,tolreached); |
1261 | } |
1262 | else { |
1263 | maxdist = Max(maxdist, error); |
1264 | } |
1265 | if(updatepc){ |
1266 | if (i == 0) GCurve->PCurve(curPC); |
1267 | else GCurve->PCurve2(curPC); |
1268 | } |
1269 | } |
1270 | else IsSameP = 0; |
1271 | |
1272 | } |
1273 | else IsSameP = 0; |
1274 | |
1275 | // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin |
1276 | if (!IsSameP) { |
1277 | if (anEdgeTol > error) { |
1278 | maxdist = Max(maxdist, anEdgeTol); |
1279 | IsSameP = Standard_True; |
1280 | } |
1281 | } |
1282 | // Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End |
1283 | } |
1284 | } |
1285 | It.Next() ; |
1286 | } |
1287 | B.Range(AnEdge,f3d,l3d); |
1288 | B.SameRange(AnEdge,Standard_True); |
1289 | if ( IsSameP) { |
1290 | // On diminue eventuellement la tolerance de l arete, puisque |
1291 | // l on a traite toutes ses representations ( Sauf celles associees |
1292 | // a des plans et non stockees dans l'arete !) |
1293 | // Il n'en va pas de meme des Vertex que l on ne peut que grossir |
1294 | // ou laisser tels quels. |
1295 | if (YaPCu) { |
1296 | // On evite de mettre des tol trop petites. |
1297 | maxdist = Max(maxdist,Precision::Confusion()); |
1298 | TopoDS_Vertex V1,V2; |
1299 | TopExp::Vertices(AnEdge,V1,V2); |
1300 | if (!V1.IsNull()) |
1301 | B.UpdateVertex(V1,maxdist); |
1302 | if (!V2.IsNull()) |
1303 | B.UpdateVertex(V2,maxdist); |
1304 | TE->Modified(Standard_True); |
1305 | TE->Tolerance(maxdist); |
1306 | } |
1307 | B.SameParameter(AnEdge,Standard_True); |
1308 | } |
1309 | } |
1310 | |
1311 | //======================================================================= |
1312 | //function : UpdateTolerances |
1313 | //purpose : |
1314 | //======================================================================= |
1315 | void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape, |
1316 | const Standard_Boolean verifyTolerance) |
1317 | { |
1318 | |
1319 | // On harmonise les tolerance |
1320 | // avec la regle Tolerance(VERTEX)>=Tolerance(EDGE)>=Tolerance(FACE) |
1321 | BRep_Builder B; |
1322 | Standard_Real tol=0; |
1323 | if (verifyTolerance) { |
1324 | // On force la tolerance a sa valeur minimale |
1325 | Handle(Geom_Surface) S; |
1326 | TopLoc_Location l; |
1327 | TopExp_Explorer ex; |
1328 | Bnd_Box aB; |
1329 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dMax; |
1330 | for (ex.Init(aShape, TopAbs_FACE); ex.More(); ex.Next()) { |
1331 | const TopoDS_Face& curf=TopoDS::Face(ex.Current()); |
1332 | S = BRep_Tool::Surface(curf, l); |
1333 | if (!S.IsNull()) { |
1334 | aB.SetVoid(); |
1335 | BRepBndLib::Add(curf,aB); |
1336 | if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
1337 | S = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(); |
1338 | } |
1339 | GeomAdaptor_Surface AS(S); |
1340 | switch (AS.GetType()) { |
1341 | case GeomAbs_Plane: |
1342 | case GeomAbs_Cylinder: |
1343 | case GeomAbs_Cone: |
1344 | { |
1345 | tol=Precision::Confusion(); |
1346 | break; |
1347 | } |
1348 | case GeomAbs_Sphere: |
1349 | case GeomAbs_Torus: |
1350 | { |
1351 | tol=Precision::Confusion()*2; |
1352 | break; |
1353 | } |
1354 | default: |
1355 | tol=Precision::Confusion()*4; |
1356 | } |
1357 | if (!aB.IsWhole()) { |
1358 | aB.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); |
1359 | dMax=1.; |
1360 | if (!aB.IsOpenXmin() && !aB.IsOpenXmax()) dMax=aXmax-aXmin; |
1361 | if (!aB.IsOpenYmin() && !aB.IsOpenYmax()) aYmin=aYmax-aYmin; |
1362 | if (!aB.IsOpenZmin() && !aB.IsOpenZmax()) aZmin=aZmax-aZmin; |
1363 | if (aYmin>dMax) dMax=aYmin; |
1364 | if (aZmin>dMax) dMax=aZmin; |
1365 | tol=tol*dMax; |
1366 | // On ne traite pas les tolerance > 1. |
1367 | if (tol>1.) tol=0.99; |
1368 | } |
1369 | const Handle(BRep_TFace)& Tf = *((Handle(BRep_TFace)*)&curf.TShape()); |
1370 | Tf->Tolerance(tol); |
1371 | } |
1372 | } |
1373 | } |
1374 | |
1375 | //On traite les edges |
1376 | TopTools_IndexedDataMapOfShapeListOfShape parents; |
1377 | TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, parents); |
1378 | TopTools_ListIteratorOfListOfShape lConx; |
1379 | Standard_Integer iCur; |
1380 | for (iCur=1; iCur<=parents.Extent(); iCur++) { |
1381 | tol=0; |
1382 | for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) { |
1383 | tol=Max(tol, BRep_Tool::Tolerance(TopoDS::Face(lConx.Value()))); |
1384 | } |
1385 | // Update ne peut que augmenter la tolerance, donc si l'edge a |
1386 | // une tolerance + grande que ses faces on y touche pas |
1387 | B.UpdateEdge(TopoDS::Edge(parents.FindKey(iCur)), tol); |
1388 | } |
1389 | |
1390 | //On traite les Vertices |
1391 | parents.Clear(); |
1392 | TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, parents); |
1393 | TColStd_MapOfTransient Initialized; |
1394 | TopTools_MapOfShape Done; |
1395 | Standard_Integer nbV = parents.Extent(); |
1396 | for (iCur=1; iCur<=nbV; iCur++) { |
1397 | tol=0; |
1398 | Done.Clear(); |
1399 | const TopoDS_Vertex& V = TopoDS::Vertex(parents.FindKey(iCur)); |
1400 | Bnd_Box box; |
1401 | box.Add(BRep_Tool::Pnt(V)); |
1402 | gp_Pnt p3d; |
1403 | for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) { |
1404 | const TopoDS_Edge& E = TopoDS::Edge(lConx.Value()); |
1405 | if(!Done.Add(E)) continue; |
1406 | tol=Max(tol, BRep_Tool::Tolerance(E)); |
1407 | if(!BRep_Tool::SameRange(E)) continue; |
1408 | Standard_Real par = BRep_Tool::Parameter(V,E); |
1409 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape()); |
1410 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); |
1411 | const TopLoc_Location& Eloc = E.Location(); |
1412 | while (itcr.More()) { |
1413 | // Pour chaque CurveRepresentation, on verifie le parametre fourni |
1414 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
1415 | const TopLoc_Location& loc = cr->Location(); |
1416 | TopLoc_Location L = (Eloc * loc); |
1417 | if (cr->IsCurve3D()) { |
1418 | const Handle(Geom_Curve)& C = cr->Curve3D(); |
1419 | if (!C.IsNull()) { // edge non degenere |
1420 | p3d = C->Value(par); |
1421 | p3d.Transform(L.Transformation()); |
1422 | box.Add(p3d); |
1423 | } |
1424 | } |
1425 | else if (cr->IsCurveOnSurface()) { |
1426 | const Handle(Geom_Surface)& Su = cr->Surface(); |
1427 | const Handle(Geom2d_Curve)& PC = cr->PCurve(); |
1428 | Handle(Geom2d_Curve) PC2; |
1429 | if (cr->IsCurveOnClosedSurface()) { |
1430 | PC2 = cr->PCurve2(); |
1431 | } |
1432 | gp_Pnt2d p2d = PC->Value(par); |
1433 | p3d = Su->Value(p2d.X(),p2d.Y()); |
1434 | p3d.Transform(L.Transformation()); |
1435 | box.Add(p3d); |
1436 | if (!PC2.IsNull()) { |
1437 | p2d = PC2->Value(par); |
1438 | p3d = Su->Value(p2d.X(),p2d.Y()); |
1439 | p3d.Transform(L.Transformation()); |
1440 | box.Add(p3d); |
1441 | } |
1442 | } |
1443 | itcr.Next(); |
1444 | } |
1445 | } |
1446 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; |
1447 | box.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); |
1448 | aXmax -= aXmin; aYmax -= aYmin; aZmax -= aZmin; |
1449 | tol = Max(tol,sqrt(aXmax*aXmax+aYmax*aYmax+aZmax*aZmax)); |
1450 | tol += 2.*Epsilon(tol); |
1451 | if (verifyTolerance) { |
1452 | // On force la tolerance a sa valeur minimale |
1453 | // Attention au partage du vertex par d'autre shapes |
1454 | const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape()); |
1455 | if (Initialized.Add(TV)) |
1456 | TV->Tolerance(tol); |
1457 | else |
1458 | B.UpdateVertex(V, tol); |
1459 | } |
1460 | else { |
1461 | // Update ne peut que augmenter la tolerance, donc si le vertex a |
1462 | // une tolerance + grande que ses edges on y touche pas |
1463 | B.UpdateVertex(V, tol); |
1464 | } |
1465 | } |
1466 | } |
1467 | |
1468 | //======================================================================= |
1469 | //function : OrientClosedSolid |
1470 | //purpose : |
1471 | //======================================================================= |
1472 | Standard_Boolean BRepLib::OrientClosedSolid(TopoDS_Solid& solid) |
1473 | { |
1474 | // On met la matiere a l'interieur du solid |
1475 | BRepClass3d_SolidClassifier where(solid); |
1476 | where.PerformInfinitePoint(Precision::Confusion()); |
1477 | if (where.State()==TopAbs_IN) { |
1478 | solid.Reverse(); |
1479 | } |
1480 | else if (where.State()==TopAbs_ON || where.State()==TopAbs_UNKNOWN) |
1481 | return Standard_False; |
1482 | |
1483 | return Standard_True; |
1484 | } |
1485 | |
1486 | //======================================================================= |
1487 | //function : tgtfaces |
1488 | //purpose : controle de l angle a la frontiere entre 2 carreaux. |
1489 | // Les deux carreaux doivent partager leur edge frontiere. |
1490 | //======================================================================= |
1491 | |
1492 | static Standard_Boolean tgtfaces(const TopoDS_Edge& Ed, |
1493 | const TopoDS_Face& F1, |
1494 | const TopoDS_Face& F2, |
1495 | const Standard_Real ta, |
1496 | const Standard_Boolean couture) |
1497 | { |
1498 | Standard_Real u; |
1499 | TopoDS_Edge E = Ed; |
1500 | BRepAdaptor_Surface aBAS1(F1,Standard_False); |
1501 | BRepAdaptor_Surface aBAS2(F2,Standard_False); |
1502 | Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface(aBAS1); |
1503 | Handle(BRepAdaptor_HSurface) HS2; |
1504 | if(couture) HS2 = HS1; |
1505 | else HS2 = new BRepAdaptor_HSurface(aBAS2); |
1506 | |
1507 | E.Orientation(TopAbs_FORWARD); |
1508 | Handle(BRepAdaptor_HCurve2d) HC2d1 = new BRepAdaptor_HCurve2d(); |
1509 | HC2d1->ChangeCurve2d().Initialize(E,F1); |
1510 | if(couture) E.Orientation(TopAbs_REVERSED); |
1511 | Handle(BRepAdaptor_HCurve2d) HC2d2 = new BRepAdaptor_HCurve2d(); |
1512 | HC2d2->ChangeCurve2d().Initialize(E,F2); |
1513 | Adaptor3d_CurveOnSurface C1(HC2d1,HS1); |
1514 | Adaptor3d_CurveOnSurface C2(HC2d2,HS2); |
1515 | |
1516 | Standard_Boolean rev1 = (F1.Orientation() == TopAbs_REVERSED); |
1517 | Standard_Boolean rev2 = (F2.Orientation() == TopAbs_REVERSED); |
1518 | Standard_Real f,l,eps, angmax = -PI; |
1519 | #ifndef DEB |
1520 | Standard_Real ang =0.; |
1521 | #else |
1522 | Standard_Real ang; |
1523 | #endif |
1524 | BRep_Tool::Range(E,f,l); |
1525 | Extrema_LocateExtPC ext; |
1526 | Standard_Boolean IsInitialized = Standard_False; |
1527 | |
1528 | eps = (l - f)/100.; |
1529 | f += eps; // pour eviter de faire des calculs sur les |
1530 | l -= eps; // pointes des carreaux pointus. |
1531 | gp_Pnt2d p; |
1532 | gp_Pnt pp1,pp2;//,PP; |
1533 | gp_Vec du,dv; |
1534 | gp_Vec d1,d2; |
1535 | Standard_Real uu, vv, norm; |
1536 | |
1537 | Standard_Integer i; |
1538 | Standard_Boolean Nok; |
1539 | for(i = 0; (i<= 20) && (angmax<=ta) ; i++){ |
1540 | // On suppose d'abord que c'est sameParameter |
1541 | Nok = Standard_True; |
1542 | u = f + (l-f)*i/20; |
1543 | HC2d1->D0(u,p); |
1544 | HS1->D1(p.X(),p.Y(),pp1,du,dv); |
1545 | d1 = (du.Crossed(dv)); |
1546 | norm = d1.Magnitude(); |
1547 | if (norm > 1.e-12) d1 /= norm; |
1548 | else Nok=Standard_False; |
1549 | if(rev1) d1.Reverse(); |
1550 | |
1551 | HC2d2->D0(u,p); |
1552 | HS2->D1(p.X(), p.Y(), pp2, du, dv); |
1553 | d2 = (du.Crossed(dv)); |
1554 | norm = d2.Magnitude(); |
1555 | if (norm> 1.e-12) d2 /= norm; |
1556 | else Nok=Standard_False; |
1557 | if(rev2) d2.Reverse(); |
1558 | if (Nok) ang = d1.Angle(d2); |
1559 | |
1560 | if (Nok &&(ang > ta)) { // On raffine par projection |
1561 | if (! IsInitialized ) { |
1562 | ext.Initialize(C2,f,l,Precision::PConfusion()); |
1563 | IsInitialized = Standard_True; |
1564 | } |
1565 | ext.Perform(pp1,u); |
1566 | if(ext.IsDone() && ext.IsMin()){ |
1567 | Extrema_POnCurv poc = ext.Point(); |
1568 | Standard_Real v = poc.Parameter(); |
1569 | |
1570 | HC2d2->D0(v,p); |
1571 | p.Coord(uu,vv); |
1572 | HS2->D1(p.X(), p.Y(), pp2, du, dv); |
1573 | d2 = (du.Crossed(dv)); |
1574 | norm = d2.Magnitude(); |
1575 | if (norm> 1.e-12) d2 /= norm; |
1576 | else Nok = Standard_False; |
1577 | if(rev2) d2.Reverse(); |
1578 | if (Nok) ang = d1.Angle(d2); |
1579 | } |
1580 | } |
1581 | if(ang >= angmax) angmax = ang; |
1582 | } |
1583 | |
1584 | return (angmax<=ta); |
1585 | |
1586 | } |
1587 | |
1588 | |
1589 | //======================================================================= |
1590 | // function : EncodeRegularity |
1591 | // purpose : code les regularites sur tous les edges du shape,frontiere |
1592 | // de deux faces qui n en ont pas. |
1593 | //======================================================================= |
1594 | |
1595 | void BRepLib::EncodeRegularity(const TopoDS_Shape& S, |
1596 | const Standard_Real TolAng) |
1597 | { |
1598 | BRep_Builder B; |
1599 | TopTools_IndexedDataMapOfShapeListOfShape M; |
1600 | TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,M); |
1601 | TopTools_ListIteratorOfListOfShape It; |
1602 | TopExp_Explorer Ex; |
1603 | TopoDS_Face F1,F2; |
1604 | Standard_Boolean found, couture; |
1605 | for(Standard_Integer i = 1; i <= M.Extent(); i++){ |
1606 | TopoDS_Edge E = TopoDS::Edge(M.FindKey(i)); |
1607 | found = Standard_False; couture = Standard_False; |
1608 | F1.Nullify(); |
1609 | for(It.Initialize(M.FindFromIndex(i));It.More() && !found;It.Next()){ |
1610 | if(F1.IsNull()) { F1 = TopoDS::Face(It.Value()); } |
1611 | else { |
1612 | if(!F1.IsSame(TopoDS::Face(It.Value()))){ |
1613 | found = Standard_True; |
1614 | F2 = TopoDS::Face(It.Value()); |
1615 | } |
1616 | } |
1617 | } |
1618 | if (!found && !F1.IsNull()){//est ce un edge de couture? |
1619 | TopAbs_Orientation orE = E.Orientation(); |
1620 | TopoDS_Edge curE; |
1621 | for(Ex.Init(F1,TopAbs_EDGE);Ex.More() && !found;Ex.Next()){ |
1622 | curE= TopoDS::Edge(Ex.Current()); |
1623 | if(E.IsSame(curE) && orE != curE.Orientation()) { |
1624 | found = Standard_True; |
1625 | couture = Standard_True; |
1626 | F2 = F1; |
1627 | } |
1628 | } |
1629 | } |
1630 | if(found){ |
1631 | if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){ |
1632 | if(tgtfaces(E, F1, F2, TolAng, couture)){ |
1633 | B.Continuity(E,F1,F2,GeomAbs_G1); |
1634 | } |
1635 | } |
1636 | } |
1637 | } |
1638 | } |
1639 | |
1640 | //======================================================================= |
1641 | // function : EncodeRegularity |
1642 | // purpose : code la regularite entre 2 face sur une edge |
1643 | //======================================================================= |
1644 | |
1645 | void BRepLib::EncodeRegularity(TopoDS_Edge& E, |
1646 | const TopoDS_Face& F1, |
1647 | const TopoDS_Face& F2, |
1648 | const Standard_Real TolAng) |
1649 | { |
1650 | BRep_Builder B; |
1651 | if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){ |
1652 | if( tgtfaces(E, F1, F2, TolAng, F1.IsEqual(F2))) { |
1653 | B.Continuity(E,F1,F2,GeomAbs_G1); |
1654 | } |
1655 | } |
1656 | } |
1657 | |
1658 | //======================================================================= |
1659 | //function : SortFaces |
1660 | //purpose : |
1661 | //======================================================================= |
1662 | |
1663 | void BRepLib::SortFaces (const TopoDS_Shape& Sh, |
1664 | TopTools_ListOfShape& LF) |
1665 | { |
1666 | LF.Clear(); |
1667 | TopTools_ListOfShape LTri,LPlan,LCyl,LCon,LSphere,LTor,LOther; |
1668 | TopExp_Explorer exp(Sh,TopAbs_FACE); |
1669 | TopLoc_Location l; |
1670 | Handle(Geom_Surface) S; |
1671 | |
1672 | for (; exp.More(); exp.Next()) { |
1673 | const TopoDS_Face& F = TopoDS::Face(exp.Current()); |
1674 | S = BRep_Tool::Surface(F, l); |
1675 | if (!S.IsNull()) { |
1676 | if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
1677 | S = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(); |
1678 | } |
1679 | GeomAdaptor_Surface AS(S); |
1680 | switch (AS.GetType()) { |
1681 | case GeomAbs_Plane: |
1682 | { |
1683 | LPlan.Append(F); |
1684 | break; |
1685 | } |
1686 | case GeomAbs_Cylinder: |
1687 | { |
1688 | LCyl.Append(F); |
1689 | break; |
1690 | } |
1691 | case GeomAbs_Cone: |
1692 | { |
1693 | LCon.Append(F); |
1694 | break; |
1695 | } |
1696 | case GeomAbs_Sphere: |
1697 | { |
1698 | LSphere.Append(F); |
1699 | break; |
1700 | } |
1701 | case GeomAbs_Torus: |
1702 | { |
1703 | LTor.Append(F); |
1704 | break; |
1705 | } |
1706 | default: |
1707 | LOther.Append(F); |
1708 | } |
1709 | } |
1710 | else LTri.Append(F); |
1711 | } |
1712 | LF.Append(LPlan); LF.Append(LCyl ); LF.Append(LCon); LF.Append(LSphere); |
1713 | LF.Append(LTor ); LF.Append(LOther); LF.Append(LTri); |
1714 | } |
1715 | |
1716 | //======================================================================= |
1717 | //function : ReverseSortFaces |
1718 | //purpose : |
1719 | //======================================================================= |
1720 | |
1721 | void BRepLib::ReverseSortFaces (const TopoDS_Shape& Sh, |
1722 | TopTools_ListOfShape& LF) |
1723 | { |
1724 | LF.Clear(); |
1725 | TopTools_ListOfShape LTri,LPlan,LCyl,LCon,LSphere,LTor,LOther; |
1726 | TopExp_Explorer exp(Sh,TopAbs_FACE); |
1727 | TopLoc_Location l; |
1728 | Handle(Geom_Surface) S; |
1729 | |
1730 | for (; exp.More(); exp.Next()) { |
1731 | const TopoDS_Face& F = TopoDS::Face(exp.Current()); |
1732 | S = BRep_Tool::Surface(F, l); |
1733 | if (!S.IsNull()) { |
1734 | if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
1735 | S = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(); |
1736 | } |
1737 | GeomAdaptor_Surface AS(S); |
1738 | switch (AS.GetType()) { |
1739 | case GeomAbs_Plane: |
1740 | { |
1741 | LPlan.Append(F); |
1742 | break; |
1743 | } |
1744 | case GeomAbs_Cylinder: |
1745 | { |
1746 | LCyl.Append(F); |
1747 | break; |
1748 | } |
1749 | case GeomAbs_Cone: |
1750 | { |
1751 | LCon.Append(F); |
1752 | break; |
1753 | } |
1754 | case GeomAbs_Sphere: |
1755 | { |
1756 | LSphere.Append(F); |
1757 | break; |
1758 | } |
1759 | case GeomAbs_Torus: |
1760 | { |
1761 | LTor.Append(F); |
1762 | break; |
1763 | } |
1764 | default: |
1765 | LOther.Append(F); |
1766 | } |
1767 | } |
1768 | else LTri.Append(F); |
1769 | } |
1770 | LF.Append(LTri); LF.Append(LOther); LF.Append(LTor ); LF.Append(LSphere); |
1771 | LF.Append(LCon); LF.Append(LCyl ); LF.Append(LPlan); |
1772 | |
1773 | } |
1774 | |
1775 | |