Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-12-15 |
2 | // Created by: Remi LEQUETTE | |
3 | // Copyright (c) 1993-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 | |
17 | //pmn 26/09/97 Add parameters of approximation in BuildCurve3d | |
7fd59977 | 18 | // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 |
19 | ||
42cf5bc1 | 20 | #include <Adaptor3d_CurveOnSurface.hxx> |
21 | #include <AdvApprox_ApproxAFunction.hxx> | |
22 | #include <AppParCurves_MultiBSpCurve.hxx> | |
23 | #include <AppParCurves_MultiCurve.hxx> | |
24 | #include <Approx_CurvilinearParameter.hxx> | |
25 | #include <Approx_SameParameter.hxx> | |
26 | #include <Bnd_Box.hxx> | |
7fd59977 | 27 | #include <BRep_Builder.hxx> |
42cf5bc1 | 28 | #include <BRep_CurveRepresentation.hxx> |
29 | #include <BRep_GCurve.hxx> | |
30 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> | |
31 | #include <BRep_ListOfCurveRepresentation.hxx> | |
32 | #include <BRep_TEdge.hxx> | |
33 | #include <BRep_TFace.hxx> | |
34 | #include <BRep_Tool.hxx> | |
35 | #include <BRep_TVertex.hxx> | |
420f79f8 | 36 | #include <BRepAdaptor_HCurve.hxx> |
42cf5bc1 | 37 | #include <BRepAdaptor_HCurve2d.hxx> |
38 | #include <BRepAdaptor_HSurface.hxx> | |
39 | #include <BRepAdaptor_Surface.hxx> | |
40 | #include <BRepBndLib.hxx> | |
41 | #include <BRepClass3d_SolidClassifier.hxx> | |
42 | #include <BRepLib.hxx> | |
d9ca2e0c | 43 | #include <BRepLib_MakeFace.hxx> |
42cf5bc1 | 44 | #include <BSplCLib.hxx> |
45 | #include <ElSLib.hxx> | |
46 | #include <Extrema_LocateExtPC.hxx> | |
47 | #include <GCPnts_QuasiUniformDeflection.hxx> | |
48 | #include <Geom2d_BSplineCurve.hxx> | |
7fd59977 | 49 | #include <Geom2d_Curve.hxx> |
50 | #include <Geom2d_TrimmedCurve.hxx> | |
42cf5bc1 | 51 | #include <Geom2dAdaptor.hxx> |
52 | #include <Geom2dAdaptor_Curve.hxx> | |
53 | #include <Geom2dAdaptor_HCurve.hxx> | |
54 | #include <Geom2dConvert.hxx> | |
55 | #include <Geom_BSplineCurve.hxx> | |
56 | #include <Geom_BSplineSurface.hxx> | |
57 | #include <Geom_Curve.hxx> | |
58 | #include <Geom_Plane.hxx> | |
59 | #include <Geom_RectangularTrimmedSurface.hxx> | |
60 | #include <Geom_Surface.hxx> | |
61 | #include <Geom_TrimmedCurve.hxx> | |
62 | #include <GeomAdaptor_Curve.hxx> | |
63 | #include <GeomAdaptor_HCurve.hxx> | |
64 | #include <GeomAdaptor_HSurface.hxx> | |
65 | #include <GeomAdaptor_Surface.hxx> | |
7fd59977 | 66 | #include <GeomLib.hxx> |
42cf5bc1 | 67 | #include <GeomLProp_SLProps.hxx> |
7fd59977 | 68 | #include <gp.hxx> |
69 | #include <gp_Ax2.hxx> | |
70 | #include <gp_Pln.hxx> | |
42cf5bc1 | 71 | #include <Poly_PolygonOnTriangulation.hxx> |
72 | #include <Poly_Triangulation.hxx> | |
7fd59977 | 73 | #include <Precision.hxx> |
42cf5bc1 | 74 | #include <ProjLib_ProjectedCurve.hxx> |
712879c8 | 75 | #include <Standard_ErrorHandler.hxx> |
42cf5bc1 | 76 | #include <Standard_Real.hxx> |
7fd59977 | 77 | #include <TColgp_Array1OfPnt.hxx> |
78 | #include <TColgp_Array1OfPnt2d.hxx> | |
79 | #include <TColStd_Array1OfReal.hxx> | |
7fd59977 | 80 | #include <TColStd_MapOfTransient.hxx> |
42cf5bc1 | 81 | #include <TopExp.hxx> |
82 | #include <TopExp_Explorer.hxx> | |
83 | #include <TopoDS.hxx> | |
84 | #include <TopoDS_Edge.hxx> | |
85 | #include <TopoDS_Face.hxx> | |
86 | #include <TopoDS_Shape.hxx> | |
87 | #include <TopoDS_Solid.hxx> | |
88 | #include <TopoDS_Vertex.hxx> | |
89 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
90 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
91 | #include <TopTools_MapOfShape.hxx> | |
7693827d | 92 | #include <TShort_HArray1OfShortReal.hxx> |
a0bb29e7 | 93 | #include <TColgp_Array1OfXY.hxx> |
b60e8432 | 94 | #include <BRepTools_ReShape.hxx> |
95 | #include <TopTools_DataMapOfShapeReal.hxx> | |
96 | #include <TopoDS_LockedShape.hxx> | |
7fd59977 | 97 | |
07ef8bdf | 98 | #include <algorithm> |
99 | ||
41194117 | 100 | // TODO - not thread-safe static variables |
7fd59977 | 101 | static Standard_Real thePrecision = Precision::Confusion(); |
102 | static Handle(Geom_Plane) thePlane; | |
103 | ||
b60e8432 | 104 | static void InternalUpdateTolerances(const TopoDS_Shape& theOldShape, |
105 | const Standard_Boolean IsVerifyTolerance, const Standard_Boolean IsMutableInput, BRepTools_ReShape& theReshaper); | |
106 | ||
07ef8bdf | 107 | //======================================================================= |
108 | // function: BRepLib_ComparePoints | |
109 | // purpose: implementation of IsLess() function for two points | |
110 | //======================================================================= | |
111 | struct BRepLib_ComparePoints { | |
112 | bool operator()(const gp_Pnt& theP1, const gp_Pnt& theP2) | |
113 | { | |
114 | for (Standard_Integer i = 1; i <= 3; ++i) { | |
115 | if (theP1.Coord(i) < theP2.Coord(i)) { | |
116 | return Standard_True; | |
117 | } | |
118 | else if (theP1.Coord(i) > theP2.Coord(i)) { | |
119 | return Standard_False; | |
120 | } | |
121 | } | |
122 | return Standard_False; | |
123 | } | |
124 | }; | |
125 | ||
126 | ||
7fd59977 | 127 | //======================================================================= |
128 | //function : Precision | |
129 | //purpose : | |
130 | //======================================================================= | |
131 | ||
132 | void BRepLib::Precision(const Standard_Real P) | |
133 | { | |
134 | thePrecision = P; | |
135 | } | |
136 | ||
137 | //======================================================================= | |
138 | //function : Precision | |
139 | //purpose : | |
140 | //======================================================================= | |
141 | ||
142 | Standard_Real BRepLib::Precision() | |
143 | { | |
144 | return thePrecision; | |
145 | } | |
146 | ||
147 | //======================================================================= | |
148 | //function : Plane | |
149 | //purpose : | |
150 | //======================================================================= | |
151 | ||
152 | void BRepLib::Plane(const Handle(Geom_Plane)& P) | |
153 | { | |
154 | thePlane = P; | |
155 | } | |
156 | ||
157 | ||
158 | //======================================================================= | |
159 | //function : Plane | |
160 | //purpose : | |
161 | //======================================================================= | |
162 | ||
163 | const Handle(Geom_Plane)& BRepLib::Plane() | |
164 | { | |
165 | if (thePlane.IsNull()) thePlane = new Geom_Plane(gp::XOY()); | |
166 | return thePlane; | |
167 | } | |
168 | //======================================================================= | |
169 | //function : CheckSameRange | |
170 | //purpose : | |
171 | //======================================================================= | |
172 | ||
173 | Standard_Boolean BRepLib::CheckSameRange(const TopoDS_Edge& AnEdge, | |
a86d3ec0 | 174 | const Standard_Real Tolerance) |
7fd59977 | 175 | { |
176 | Standard_Boolean IsSameRange = Standard_True, | |
a86d3ec0 | 177 | first_time_in = Standard_True ; |
7fd59977 | 178 | |
179 | BRep_ListIteratorOfListOfCurveRepresentation an_Iterator | |
180 | ((*((Handle(BRep_TEdge)*)&AnEdge.TShape()))->ChangeCurves()); | |
a86d3ec0 | 181 | |
7fd59977 | 182 | Standard_Real first, last; |
7fd59977 | 183 | Standard_Real current_first =0., current_last =0. ; |
7fd59977 | 184 | Handle(BRep_GCurve) geometric_representation_ptr ; |
185 | ||
186 | while (IsSameRange && an_Iterator.More()) { | |
187 | geometric_representation_ptr = | |
188 | Handle(BRep_GCurve)::DownCast(an_Iterator.Value()); | |
189 | if (!geometric_representation_ptr.IsNull()) { | |
a86d3ec0 | 190 | |
191 | first = geometric_representation_ptr->First(); | |
192 | last = geometric_representation_ptr->Last(); | |
193 | if (first_time_in ) { | |
194 | current_first = first ; | |
195 | current_last = last ; | |
196 | first_time_in = Standard_False ; | |
7fd59977 | 197 | } |
a86d3ec0 | 198 | else { |
199 | IsSameRange = (Abs(current_first - first) <= Tolerance) | |
200 | && (Abs(current_last -last) <= Tolerance ) ; | |
201 | } | |
202 | } | |
7fd59977 | 203 | an_Iterator.Next() ; |
204 | } | |
205 | return IsSameRange ; | |
206 | } | |
a86d3ec0 | 207 | |
7fd59977 | 208 | //======================================================================= |
209 | //function : SameRange | |
210 | //purpose : | |
211 | //======================================================================= | |
212 | ||
213 | void BRepLib::SameRange(const TopoDS_Edge& AnEdge, | |
a86d3ec0 | 214 | const Standard_Real Tolerance) |
7fd59977 | 215 | { |
216 | BRep_ListIteratorOfListOfCurveRepresentation an_Iterator | |
217 | ((*((Handle(BRep_TEdge)*)&AnEdge.TShape()))->ChangeCurves()); | |
a86d3ec0 | 218 | |
7fd59977 | 219 | Handle(Geom2d_Curve) Curve2dPtr, Curve2dPtr2, NewCurve2dPtr, NewCurve2dPtr2; |
220 | TopLoc_Location LocalLoc ; | |
221 | ||
222 | Standard_Boolean first_time_in = Standard_True, | |
a86d3ec0 | 223 | has_curve, |
224 | has_closed_curve ; | |
7fd59977 | 225 | Handle(BRep_GCurve) geometric_representation_ptr ; |
226 | Standard_Real first, | |
a86d3ec0 | 227 | current_first, |
228 | last, | |
229 | current_last ; | |
7fd59977 | 230 | |
231 | const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge, | |
a86d3ec0 | 232 | LocalLoc, |
233 | current_first, | |
234 | current_last); | |
7fd59977 | 235 | if (!C.IsNull()) { |
236 | first_time_in = Standard_False ; | |
237 | } | |
a86d3ec0 | 238 | |
7fd59977 | 239 | while (an_Iterator.More()) { |
240 | geometric_representation_ptr = | |
241 | Handle(BRep_GCurve)::DownCast(an_Iterator.Value()); | |
242 | if (! geometric_representation_ptr.IsNull()) { | |
243 | has_closed_curve = | |
a86d3ec0 | 244 | has_curve = Standard_False ; |
7fd59977 | 245 | first = geometric_representation_ptr->First(); |
246 | last = geometric_representation_ptr->Last(); | |
247 | if (geometric_representation_ptr->IsCurveOnSurface()) { | |
a86d3ec0 | 248 | Curve2dPtr = geometric_representation_ptr->PCurve() ; |
249 | has_curve = Standard_True ; | |
7fd59977 | 250 | } |
251 | if (geometric_representation_ptr->IsCurveOnClosedSurface()) { | |
a86d3ec0 | 252 | Curve2dPtr2 = geometric_representation_ptr->PCurve2() ; |
253 | has_closed_curve = Standard_True ; | |
7fd59977 | 254 | } |
255 | if (has_curve || has_closed_curve) { | |
a86d3ec0 | 256 | if (first_time_in) { |
257 | current_first = first ; | |
258 | current_last = last ; | |
259 | first_time_in = Standard_False ; | |
7fd59977 | 260 | } |
a86d3ec0 | 261 | |
7fd59977 | 262 | if (Abs(first - current_first) > Precision::Confusion() || |
a86d3ec0 | 263 | Abs(last - current_last) > Precision::Confusion() ) |
264 | { | |
265 | if (has_curve) | |
266 | { | |
267 | GeomLib::SameRange(Tolerance, | |
268 | Curve2dPtr, | |
269 | geometric_representation_ptr->First(), | |
270 | geometric_representation_ptr->Last(), | |
271 | current_first, | |
272 | current_last, | |
273 | NewCurve2dPtr); | |
274 | geometric_representation_ptr->PCurve(NewCurve2dPtr) ; | |
275 | } | |
276 | if (has_closed_curve) | |
277 | { | |
278 | GeomLib::SameRange(Tolerance, | |
279 | Curve2dPtr2, | |
280 | geometric_representation_ptr->First(), | |
281 | geometric_representation_ptr->Last(), | |
282 | current_first, | |
283 | current_last, | |
284 | NewCurve2dPtr2); | |
285 | geometric_representation_ptr->PCurve2(NewCurve2dPtr2) ; | |
286 | } | |
287 | } | |
7fd59977 | 288 | } |
289 | } | |
290 | an_Iterator.Next() ; | |
291 | } | |
292 | BRep_Builder B; | |
293 | B.Range(TopoDS::Edge(AnEdge), | |
a86d3ec0 | 294 | current_first, |
295 | current_last) ; | |
7fd59977 | 296 | |
297 | B.SameRange(AnEdge, | |
a86d3ec0 | 298 | Standard_True) ; |
7fd59977 | 299 | } |
300 | ||
301 | //======================================================================= | |
302 | //function : EvaluateMaxSegment | |
303 | //purpose : return MaxSegment to pass in approximation, if MaxSegment==0 provided | |
304 | //======================================================================= | |
305 | ||
306 | static Standard_Integer evaluateMaxSegment(const Standard_Integer aMaxSegment, | |
a86d3ec0 | 307 | const Adaptor3d_CurveOnSurface& aCurveOnSurface) |
7fd59977 | 308 | { |
309 | if (aMaxSegment != 0) return aMaxSegment; | |
310 | ||
311 | Handle(Adaptor3d_HSurface) aSurf = aCurveOnSurface.GetSurface(); | |
312 | Handle(Adaptor2d_HCurve2d) aCurv2d = aCurveOnSurface.GetCurve(); | |
313 | ||
314 | Standard_Real aNbSKnots = 0, aNbC2dKnots = 0; | |
a86d3ec0 | 315 | |
7fd59977 | 316 | if (aSurf->GetType() == GeomAbs_BSplineSurface) { |
317 | Handle(Geom_BSplineSurface) aBSpline = aSurf->BSpline(); | |
318 | aNbSKnots = Max(aBSpline->NbUKnots(), aBSpline->NbVKnots()); | |
319 | } | |
320 | if (aCurv2d->GetType() == GeomAbs_BSplineCurve) { | |
321 | aNbC2dKnots = aCurv2d->NbKnots(); | |
322 | } | |
323 | Standard_Integer aReturn = (Standard_Integer) ( 30 + Max(aNbSKnots, aNbC2dKnots) ) ; | |
324 | return aReturn; | |
325 | } | |
326 | ||
327 | //======================================================================= | |
328 | //function : BuildCurve3d | |
329 | //purpose : | |
330 | //======================================================================= | |
331 | ||
332 | Standard_Boolean BRepLib::BuildCurve3d(const TopoDS_Edge& AnEdge, | |
a86d3ec0 | 333 | const Standard_Real Tolerance, |
334 | const GeomAbs_Shape Continuity, | |
335 | const Standard_Integer MaxDegree, | |
336 | const Standard_Integer MaxSegment) | |
7fd59977 | 337 | { |
338 | Standard_Integer //ErrorCode, | |
a86d3ec0 | 339 | // ReturnCode = 0, |
340 | ii, | |
341 | // num_knots, | |
342 | jj; | |
7fd59977 | 343 | |
344 | TopLoc_Location LocalLoc,L[2],LC; | |
345 | Standard_Real f,l,fc,lc, first[2], last[2], | |
a86d3ec0 | 346 | tolerance, |
347 | max_deviation, | |
348 | average_deviation ; | |
7fd59977 | 349 | Handle(Geom2d_Curve) Curve2dPtr, Curve2dArray[2] ; |
350 | Handle(Geom_Surface) SurfacePtr, SurfaceArray[2] ; | |
351 | ||
352 | Standard_Integer not_done ; | |
353 | // if the edge has a 3d curve returns true | |
354 | ||
355 | ||
356 | const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge,LocalLoc,f,l); | |
357 | if (!C.IsNull()) | |
358 | return Standard_True; | |
a86d3ec0 | 359 | // |
360 | // this should not exists but UpdateEdge makes funny things | |
361 | // if the edge is not same range | |
362 | // | |
7fd59977 | 363 | if (! CheckSameRange(AnEdge, |
a86d3ec0 | 364 | Precision::Confusion())) { |
365 | SameRange(AnEdge, | |
366 | Tolerance) ; | |
7fd59977 | 367 | } |
368 | ||
a86d3ec0 | 369 | |
7fd59977 | 370 | |
371 | // search a curve on a plane | |
372 | Handle(Geom_Surface) S; | |
373 | Handle(Geom2d_Curve) PC; | |
374 | Standard_Integer i = 0; | |
375 | Handle(Geom_Plane) P; | |
376 | not_done = 1 ; | |
377 | ||
378 | while (not_done) { | |
379 | i++; | |
380 | BRep_Tool::CurveOnSurface(AnEdge,PC,S,LocalLoc,f,l,i); | |
381 | Handle(Geom_RectangularTrimmedSurface) RT = | |
382 | Handle(Geom_RectangularTrimmedSurface)::DownCast(S); | |
383 | if ( RT.IsNull()) { | |
384 | P = Handle(Geom_Plane)::DownCast(S); | |
385 | } | |
386 | else { | |
387 | P = Handle(Geom_Plane)::DownCast(RT->BasisSurface()); | |
388 | } | |
389 | not_done = ! (S.IsNull() || !P.IsNull()) ; | |
390 | } | |
391 | if (! P.IsNull()) { | |
392 | // compute the 3d curve | |
393 | gp_Ax2 axes = P->Position().Ax2(); | |
394 | Handle(Geom_Curve) C3d = GeomLib::To3d(axes,PC); | |
dfc06d1f A |
395 | if (C3d.IsNull()) |
396 | return Standard_False; | |
7fd59977 | 397 | // update the edge |
398 | Standard_Real First, Last; | |
399 | ||
400 | BRep_Builder B; | |
7fd59977 | 401 | B.UpdateEdge(AnEdge,C3d,LocalLoc,0.0e0); |
402 | BRep_Tool::Range(AnEdge, S, LC, First, Last); | |
0d969553 | 403 | B.Range(AnEdge, First, Last); //Do not forget 3D range.(PRO6412) |
7fd59977 | 404 | } |
405 | else { | |
406 | // | |
407 | // compute the 3d curve using existing surface | |
408 | // | |
409 | fc = f ; | |
410 | lc = l ; | |
411 | if (!BRep_Tool::Degenerated(AnEdge)) { | |
412 | jj = 0 ; | |
413 | for (ii = 0 ; ii < 3 ; ii++ ) { | |
a86d3ec0 | 414 | BRep_Tool::CurveOnSurface(TopoDS::Edge(AnEdge), |
415 | Curve2dPtr, | |
416 | SurfacePtr, | |
417 | LocalLoc, | |
418 | fc, | |
419 | lc, | |
420 | ii) ; | |
421 | ||
422 | if (!Curve2dPtr.IsNull() && jj < 2){ | |
423 | Curve2dArray[jj] = Curve2dPtr ; | |
424 | SurfaceArray[jj] = SurfacePtr ; | |
425 | L[jj] = LocalLoc ; | |
426 | first[jj] = fc ; | |
427 | last[jj] = lc ; | |
428 | jj += 1 ; | |
429 | } | |
7fd59977 | 430 | } |
431 | f = first[0] ; | |
432 | l = last[0] ; | |
433 | Curve2dPtr = Curve2dArray[0] ; | |
434 | SurfacePtr = SurfaceArray[0] ; | |
a86d3ec0 | 435 | |
7fd59977 | 436 | Geom2dAdaptor_Curve AnAdaptor3dCurve2d (Curve2dPtr, f, l) ; |
437 | GeomAdaptor_Surface AnAdaptor3dSurface (SurfacePtr) ; | |
438 | Handle(Geom2dAdaptor_HCurve) AnAdaptor3dCurve2dPtr = | |
a86d3ec0 | 439 | new Geom2dAdaptor_HCurve(AnAdaptor3dCurve2d) ; |
7fd59977 | 440 | Handle(GeomAdaptor_HSurface) AnAdaptor3dSurfacePtr = |
a86d3ec0 | 441 | new GeomAdaptor_HSurface (AnAdaptor3dSurface) ; |
7fd59977 | 442 | Adaptor3d_CurveOnSurface CurveOnSurface( AnAdaptor3dCurve2dPtr, |
a86d3ec0 | 443 | AnAdaptor3dSurfacePtr) ; |
444 | ||
7fd59977 | 445 | Handle(Geom_Curve) NewCurvePtr ; |
446 | ||
447 | GeomLib::BuildCurve3d(Tolerance, | |
a86d3ec0 | 448 | CurveOnSurface, |
449 | f, | |
450 | l, | |
451 | NewCurvePtr, | |
452 | max_deviation, | |
453 | average_deviation, | |
454 | Continuity, | |
455 | MaxDegree, | |
456 | evaluateMaxSegment(MaxSegment,CurveOnSurface)) ; | |
7fd59977 | 457 | BRep_Builder B; |
458 | tolerance = BRep_Tool::Tolerance(AnEdge) ; | |
459 | //Patch | |
460 | //max_deviation = Max(tolerance, max_deviation) ; | |
461 | max_deviation = Max( tolerance, Tolerance ); | |
dfc06d1f A |
462 | if (NewCurvePtr.IsNull()) |
463 | return Standard_False; | |
7fd59977 | 464 | B.UpdateEdge(TopoDS::Edge(AnEdge), |
a86d3ec0 | 465 | NewCurvePtr, |
466 | L[0], | |
467 | max_deviation) ; | |
7fd59977 | 468 | if (jj == 1 ) { |
a86d3ec0 | 469 | // |
470 | // if there is only one curve on surface attached to the edge | |
471 | // than it can be qualified sameparameter | |
472 | // | |
473 | B.SameParameter(TopoDS::Edge(AnEdge), | |
474 | Standard_True) ; | |
7fd59977 | 475 | } |
476 | } | |
477 | else { | |
478 | return Standard_False ; | |
479 | } | |
a86d3ec0 | 480 | |
7fd59977 | 481 | } |
482 | return Standard_True; | |
483 | } | |
484 | //======================================================================= | |
485 | //function : BuildCurves3d | |
486 | //purpose : | |
487 | //======================================================================= | |
488 | ||
489 | Standard_Boolean BRepLib::BuildCurves3d(const TopoDS_Shape& S) | |
490 | ||
491 | { | |
492 | return BRepLib::BuildCurves3d(S, | |
a86d3ec0 | 493 | 1.0e-5) ; |
7fd59977 | 494 | } |
495 | ||
496 | //======================================================================= | |
497 | //function : BuildCurves3d | |
498 | //purpose : | |
499 | //======================================================================= | |
500 | ||
501 | Standard_Boolean BRepLib::BuildCurves3d(const TopoDS_Shape& S, | |
a86d3ec0 | 502 | const Standard_Real Tolerance, |
503 | const GeomAbs_Shape Continuity, | |
504 | const Standard_Integer MaxDegree, | |
505 | const Standard_Integer MaxSegment) | |
7fd59977 | 506 | { |
507 | Standard_Boolean boolean_value, | |
a86d3ec0 | 508 | ok = Standard_True; |
7fd59977 | 509 | TopTools_MapOfShape a_counter ; |
510 | TopExp_Explorer ex(S,TopAbs_EDGE); | |
511 | ||
512 | while (ex.More()) { | |
513 | if (a_counter.Add(ex.Current())) { | |
514 | boolean_value = | |
a86d3ec0 | 515 | BuildCurve3d(TopoDS::Edge(ex.Current()), |
516 | Tolerance, Continuity, | |
517 | MaxDegree, MaxSegment); | |
7fd59977 | 518 | ok = ok && boolean_value ; |
519 | } | |
520 | ex.Next(); | |
521 | } | |
522 | return ok; | |
523 | } | |
524 | //======================================================================= | |
525 | //function : UpdateEdgeTolerance | |
526 | //purpose : | |
527 | //======================================================================= | |
528 | ||
529 | Standard_Boolean BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge, | |
a86d3ec0 | 530 | const Standard_Real MinToleranceRequested, |
531 | const Standard_Real MaxToleranceToCheck) | |
532 | { | |
533 | ||
534 | Standard_Integer curve_on_surface_index, | |
535 | curve_index, | |
536 | not_done, | |
537 | has_closed_curve, | |
538 | has_curve, | |
539 | jj, | |
540 | ii, | |
541 | geom_reference_curve_flag = 0, | |
542 | max_sampling_points = 90, | |
543 | min_sampling_points = 30 ; | |
544 | ||
545 | Standard_Real factor = 100.0e0, | |
546 | // sampling_array[2], | |
547 | safe_factor = 1.4e0, | |
548 | current_last, | |
549 | current_first, | |
550 | max_distance, | |
551 | coded_edge_tolerance, | |
552 | edge_tolerance = 0.0e0 ; | |
553 | Handle(TColStd_HArray1OfReal) parameters_ptr ; | |
554 | Handle(BRep_GCurve) geometric_representation_ptr ; | |
555 | ||
556 | if (BRep_Tool::Degenerated(AnEdge)) return Standard_False ; | |
557 | coded_edge_tolerance = BRep_Tool::Tolerance(AnEdge) ; | |
558 | if (coded_edge_tolerance > MaxToleranceToCheck) return Standard_False ; | |
559 | ||
560 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&AnEdge.TShape()); | |
561 | BRep_ListOfCurveRepresentation& list_curve_rep = TE->ChangeCurves() ; | |
562 | BRep_ListIteratorOfListOfCurveRepresentation an_iterator(list_curve_rep), | |
563 | second_iterator(list_curve_rep) ; | |
564 | Handle(Geom2d_Curve) curve2d_ptr, new_curve2d_ptr; | |
565 | Handle(Geom_Surface) surface_ptr ; | |
566 | TopLoc_Location local_location ; | |
567 | GCPnts_QuasiUniformDeflection a_sampler ; | |
568 | GeomAdaptor_Curve geom_reference_curve ; | |
569 | Adaptor3d_CurveOnSurface curve_on_surface_reference ; | |
570 | Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge, | |
571 | local_location, | |
572 | current_first, | |
573 | current_last); | |
574 | curve_on_surface_index = -1 ; | |
575 | if (!C.IsNull()) { | |
576 | if (! local_location.IsIdentity()) { | |
577 | C = Handle(Geom_Curve):: | |
578 | DownCast(C-> Transformed(local_location.Transformation()) ) ; | |
7fd59977 | 579 | } |
a86d3ec0 | 580 | geom_reference_curve.Load(C) ; |
581 | geom_reference_curve_flag = 1 ; | |
582 | a_sampler.Initialize(geom_reference_curve, | |
583 | MinToleranceRequested * factor, | |
584 | current_first, | |
585 | current_last) ; | |
586 | } | |
587 | else { | |
588 | not_done = 1 ; | |
589 | curve_on_surface_index = 0 ; | |
590 | ||
591 | while (not_done && an_iterator.More()) { | |
592 | geometric_representation_ptr = | |
593 | Handle(BRep_GCurve)::DownCast(second_iterator.Value()); | |
594 | if (!geometric_representation_ptr.IsNull() | |
595 | && geometric_representation_ptr->IsCurveOnSurface()) { | |
596 | curve2d_ptr = geometric_representation_ptr->PCurve() ; | |
597 | local_location = geometric_representation_ptr->Location() ; | |
598 | current_first = geometric_representation_ptr->First(); | |
599 | //first = geometric_representation_ptr->First(); | |
600 | current_last = geometric_representation_ptr->Last(); | |
601 | // must be inverted | |
602 | // | |
603 | if (! local_location.IsIdentity() ) { | |
604 | surface_ptr = Handle(Geom_Surface):: | |
605 | DownCast( geometric_representation_ptr->Surface()-> | |
606 | Transformed(local_location.Transformation()) ) ; | |
607 | } | |
608 | else { | |
609 | surface_ptr = | |
610 | geometric_representation_ptr->Surface() ; | |
611 | } | |
612 | not_done = 0 ; | |
7fd59977 | 613 | } |
a86d3ec0 | 614 | curve_on_surface_index += 1 ; |
7fd59977 | 615 | } |
a86d3ec0 | 616 | Geom2dAdaptor_Curve AnAdaptor3dCurve2d (curve2d_ptr) ; |
617 | GeomAdaptor_Surface AnAdaptor3dSurface (surface_ptr) ; | |
618 | Handle(Geom2dAdaptor_HCurve) AnAdaptor3dCurve2dPtr = | |
619 | new Geom2dAdaptor_HCurve(AnAdaptor3dCurve2d) ; | |
620 | Handle(GeomAdaptor_HSurface) AnAdaptor3dSurfacePtr = | |
621 | new GeomAdaptor_HSurface (AnAdaptor3dSurface) ; | |
543a9964 | 622 | curve_on_surface_reference.Load (AnAdaptor3dCurve2dPtr, AnAdaptor3dSurfacePtr); |
a86d3ec0 | 623 | a_sampler.Initialize(curve_on_surface_reference, |
624 | MinToleranceRequested * factor, | |
625 | current_first, | |
626 | current_last) ; | |
627 | } | |
628 | TColStd_Array1OfReal sampling_parameters(1,a_sampler.NbPoints()) ; | |
629 | for (ii = 1 ; ii <= a_sampler.NbPoints() ; ii++) { | |
630 | sampling_parameters(ii) = a_sampler.Parameter(ii) ; | |
631 | } | |
632 | if (a_sampler.NbPoints() < min_sampling_points) { | |
633 | GeomLib::DensifyArray1OfReal(min_sampling_points, | |
634 | sampling_parameters, | |
635 | parameters_ptr) ; | |
636 | } | |
637 | else if (a_sampler.NbPoints() > max_sampling_points) { | |
638 | GeomLib::RemovePointsFromArray(max_sampling_points, | |
639 | sampling_parameters, | |
640 | parameters_ptr) ; | |
641 | } | |
642 | else { | |
643 | jj = 1 ; | |
644 | parameters_ptr = | |
645 | new TColStd_HArray1OfReal(1,sampling_parameters.Length()) ; | |
646 | for (ii = sampling_parameters.Lower() ; ii <= sampling_parameters.Upper() ; ii++) { | |
647 | parameters_ptr->ChangeArray1()(jj) = | |
648 | sampling_parameters(ii) ; | |
649 | jj +=1 ; | |
7fd59977 | 650 | } |
a86d3ec0 | 651 | } |
652 | ||
653 | curve_index = 0 ; | |
654 | ||
655 | while (second_iterator.More()) { | |
656 | geometric_representation_ptr = | |
657 | Handle(BRep_GCurve)::DownCast(second_iterator.Value()); | |
658 | if (! geometric_representation_ptr.IsNull() && | |
659 | curve_index != curve_on_surface_index) { | |
660 | has_closed_curve = | |
661 | has_curve = Standard_False ; | |
662 | // first = geometric_representation_ptr->First(); | |
663 | // last = geometric_representation_ptr->Last(); | |
664 | local_location = geometric_representation_ptr->Location() ; | |
665 | if (geometric_representation_ptr->IsCurveOnSurface()) { | |
666 | curve2d_ptr = geometric_representation_ptr->PCurve() ; | |
667 | has_curve = Standard_True ; | |
668 | } | |
669 | if (geometric_representation_ptr->IsCurveOnClosedSurface()) { | |
670 | curve2d_ptr = geometric_representation_ptr->PCurve2() ; | |
671 | has_closed_curve = Standard_True ; | |
672 | } | |
673 | ||
674 | if (has_curve || | |
675 | has_closed_curve) { | |
676 | if (! local_location.IsIdentity() ) { | |
677 | surface_ptr = Handle(Geom_Surface):: | |
678 | DownCast( geometric_representation_ptr->Surface()-> | |
679 | Transformed(local_location.Transformation()) ) ; | |
680 | } | |
681 | else { | |
682 | surface_ptr = | |
683 | geometric_representation_ptr->Surface() ; | |
684 | } | |
685 | Geom2dAdaptor_Curve an_adaptor_curve2d (curve2d_ptr) ; | |
686 | GeomAdaptor_Surface an_adaptor_surface(surface_ptr) ; | |
687 | Handle(Geom2dAdaptor_HCurve) an_adaptor_curve2d_ptr = | |
688 | new Geom2dAdaptor_HCurve(an_adaptor_curve2d) ; | |
689 | Handle(GeomAdaptor_HSurface) an_adaptor_surface_ptr = | |
690 | new GeomAdaptor_HSurface (an_adaptor_surface) ; | |
691 | Adaptor3d_CurveOnSurface a_curve_on_surface(an_adaptor_curve2d_ptr, | |
692 | an_adaptor_surface_ptr) ; | |
693 | ||
694 | if (BRep_Tool::SameParameter(AnEdge)) { | |
695 | ||
696 | GeomLib::EvalMaxParametricDistance(a_curve_on_surface, | |
697 | geom_reference_curve, | |
698 | MinToleranceRequested, | |
699 | parameters_ptr->Array1(), | |
700 | max_distance) ; | |
701 | } | |
702 | else if (geom_reference_curve_flag) { | |
703 | GeomLib::EvalMaxDistanceAlongParameter(a_curve_on_surface, | |
704 | geom_reference_curve, | |
705 | MinToleranceRequested, | |
706 | parameters_ptr->Array1(), | |
707 | max_distance) ; | |
708 | } | |
709 | else { | |
710 | ||
711 | GeomLib::EvalMaxDistanceAlongParameter(a_curve_on_surface, | |
712 | curve_on_surface_reference, | |
713 | MinToleranceRequested, | |
714 | parameters_ptr->Array1(), | |
715 | max_distance) ; | |
716 | } | |
717 | max_distance *= safe_factor ; | |
718 | edge_tolerance = Max(max_distance, edge_tolerance) ; | |
719 | } | |
7fd59977 | 720 | |
7fd59977 | 721 | |
7fd59977 | 722 | } |
a86d3ec0 | 723 | curve_index += 1 ; |
724 | second_iterator.Next() ; | |
7fd59977 | 725 | } |
a86d3ec0 | 726 | |
727 | TE->Tolerance(edge_tolerance); | |
728 | return Standard_True ; | |
729 | ||
730 | } | |
7fd59977 | 731 | //======================================================================= |
732 | //function : UpdateEdgeTolerance | |
733 | //purpose : | |
734 | //======================================================================= | |
7fd59977 | 735 | Standard_Boolean BRepLib::UpdateEdgeTolerance(const TopoDS_Shape& S, |
a86d3ec0 | 736 | const Standard_Real MinToleranceRequested, |
737 | const Standard_Real MaxToleranceToCheck) | |
7fd59977 | 738 | { |
739 | TopExp_Explorer ex(S,TopAbs_EDGE); | |
740 | TopTools_MapOfShape a_counter ; | |
741 | ||
742 | Standard_Boolean return_status = Standard_False, | |
743 | local_flag ; | |
744 | ||
745 | while (ex.More()) { | |
746 | if (a_counter.Add(ex.Current())) { | |
747 | local_flag = | |
a86d3ec0 | 748 | BRepLib::UpdateEdgeTol(TopoDS::Edge(ex.Current()), |
749 | MinToleranceRequested, | |
750 | MaxToleranceToCheck) ; | |
7fd59977 | 751 | if (local_flag && ! return_status) { |
a86d3ec0 | 752 | return_status = Standard_True ; |
7fd59977 | 753 | } |
754 | } | |
755 | ex.Next(); | |
756 | } | |
757 | return return_status ; | |
758 | } | |
759 | ||
760 | //======================================================================= | |
b60e8432 | 761 | //function : GetEdgeTol |
7fd59977 | 762 | //purpose : |
763 | //======================================================================= | |
b60e8432 | 764 | static void GetEdgeTol(const TopoDS_Edge& theEdge, |
765 | const TopoDS_Face& theFace, Standard_Real& theEdTol) | |
7fd59977 | 766 | { |
767 | TopLoc_Location L; | |
b60e8432 | 768 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(theFace,L); |
769 | TopLoc_Location l = L.Predivided(theEdge.Location()); | |
7fd59977 | 770 | |
b60e8432 | 771 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&theEdge.TShape()); |
772 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); | |
7fd59977 | 773 | |
774 | while (itcr.More()) { | |
775 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); | |
776 | if(cr->IsCurveOnSurface(S,l)) return; | |
777 | itcr.Next(); | |
778 | } | |
779 | ||
780 | Handle(Geom_Plane) GP; | |
781 | Handle(Geom_RectangularTrimmedSurface) GRTS; | |
782 | GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S); | |
783 | if(!GRTS.IsNull()) | |
784 | GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface()); | |
785 | else | |
786 | GP = Handle(Geom_Plane)::DownCast(S); | |
787 | ||
41194117 K |
788 | Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(); |
789 | Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(); | |
a86d3ec0 | 790 | |
7fd59977 | 791 | TopLoc_Location LC; |
792 | Standard_Real First, Last; | |
793 | GeomAdaptor_Curve& GAC = HC->ChangeCurve(); | |
b60e8432 | 794 | GAC.Load(BRep_Tool::Curve(theEdge,LC,First,Last)); |
7fd59977 | 795 | LC = L.Predivided(LC); |
796 | ||
797 | if (!LC.IsIdentity()) { | |
798 | GP = Handle(Geom_Plane)::DownCast( | |
a86d3ec0 | 799 | GP->Transformed(LC.Transformation())); |
7fd59977 | 800 | } |
801 | GeomAdaptor_Surface& GAS = HS->ChangeSurface(); | |
802 | GAS.Load(GP); | |
a86d3ec0 | 803 | |
7fd59977 | 804 | ProjLib_ProjectedCurve Proj(HS,HC); |
805 | Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj); | |
806 | ||
807 | gp_Pln pln = GAS.Plane(); | |
808 | Standard_Real d2 = 0.; | |
809 | Standard_Integer nn = 23; | |
810 | Standard_Real unsurnn = 1./nn; | |
811 | for(Standard_Integer i = 0; i <= nn; i++){ | |
812 | Standard_Real t = unsurnn*i; | |
813 | Standard_Real u = First*(1.-t) + Last*t; | |
814 | gp_Pnt Pc3d = HC->Value(u); | |
815 | gp_Pnt2d p2d = pc->Value(u); | |
816 | gp_Pnt Pcons = ElSLib::Value(p2d.X(),p2d.Y(),pln); | |
873c119f | 817 | Standard_Real eps = Max(Pc3d.XYZ().SquareModulus(), Pcons.XYZ().SquareModulus()); |
818 | eps = Epsilon(eps); | |
7fd59977 | 819 | Standard_Real temp = Pc3d.SquareDistance(Pcons); |
873c119f | 820 | if(temp <= eps) |
821 | { | |
822 | temp = 0.; | |
823 | } | |
7fd59977 | 824 | if(temp > d2) d2 = temp; |
825 | } | |
826 | d2 = 1.5*sqrt(d2); | |
b60e8432 | 827 | theEdTol = d2; |
7fd59977 | 828 | } |
829 | ||
830 | //======================================================================= | |
b60e8432 | 831 | //function : UpdTolMap |
832 | //purpose : Update map ShToTol (shape to tolerance) | |
833 | //======================================================================= | |
834 | static void UpdTolMap(const TopoDS_Shape& theSh, Standard_Real theNewTol, | |
835 | TopTools_DataMapOfShapeReal& theShToTol) | |
836 | { | |
837 | TopAbs_ShapeEnum aSt = theSh.ShapeType(); | |
838 | Standard_Real aShTol; | |
839 | if (aSt == TopAbs_VERTEX) | |
840 | aShTol = BRep_Tool::Tolerance(TopoDS::Vertex(theSh)); | |
841 | else if (aSt == TopAbs_EDGE) | |
842 | aShTol = BRep_Tool::Tolerance(TopoDS::Edge(theSh)); | |
843 | else | |
844 | return; | |
845 | // | |
846 | if (theNewTol > aShTol) | |
847 | { | |
848 | const Standard_Real* anOldtol = theShToTol.Seek(theSh); | |
849 | if (!anOldtol) | |
850 | theShToTol.Bind(theSh, theNewTol); | |
851 | else | |
852 | theShToTol(theSh) = Max(*anOldtol, theNewTol); | |
853 | } | |
854 | } | |
855 | ||
856 | //======================================================================= | |
857 | //function : UpdShTol | |
858 | //purpose : Update vertices/edges/faces according to ShToTol map (create copies of necessary) | |
859 | //======================================================================= | |
860 | static void UpdShTol(const TopTools_DataMapOfShapeReal& theShToTol, | |
861 | const Standard_Boolean IsMutableInput, BRepTools_ReShape& theReshaper, | |
862 | Standard_Boolean theVForceUpdate) | |
863 | { | |
864 | BRep_Builder aB; | |
865 | TopTools_DataMapIteratorOfDataMapOfShapeReal SHToTolit(theShToTol); | |
866 | for (;SHToTolit.More();SHToTolit.Next()) | |
867 | { | |
868 | const TopoDS_Shape& aSh = SHToTolit.Key(); | |
869 | Standard_Real aTol = SHToTolit.Value(); | |
870 | // | |
871 | TopoDS_Shape aNsh; | |
872 | const TopoDS_Shape& aVsh = theReshaper.Value(aSh); | |
873 | Standard_Boolean UseOldSh = IsMutableInput || theReshaper.IsNewShape(aSh) || !aVsh.IsSame(aSh); | |
874 | if (UseOldSh) | |
875 | aNsh = aVsh; | |
876 | else | |
877 | { | |
878 | aNsh = aSh.EmptyCopied(); | |
879 | //add subshapes from the original shape | |
880 | TopoDS_Iterator sit(aSh); | |
881 | for (;sit.More();sit.Next()) | |
882 | aB.Add(aNsh, sit.Value()); | |
883 | // | |
884 | aNsh.Free(aSh.Free()); | |
885 | aNsh.Checked(aSh.Checked()); | |
886 | aNsh.Orientable(aSh.Orientable()); | |
887 | aNsh.Closed(aSh.Closed()); | |
888 | aNsh.Infinite(aSh.Infinite()); | |
889 | aNsh.Convex(aSh.Convex()); | |
890 | // | |
891 | } | |
892 | // | |
893 | switch (aSh.ShapeType()) | |
894 | { | |
895 | case TopAbs_FACE: | |
896 | { | |
897 | aB.UpdateFace(TopoDS::Face(aNsh), aTol); | |
898 | break; | |
899 | } | |
900 | case TopAbs_EDGE: | |
901 | { | |
902 | aB.UpdateEdge(TopoDS::Edge(aNsh), aTol); | |
903 | break; | |
904 | } | |
905 | case TopAbs_VERTEX: | |
906 | { | |
907 | const Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&aNsh.TShape()); | |
908 | // | |
909 | if(aTV->Locked()) | |
910 | throw TopoDS_LockedShape("BRep_Builder::UpdateVertex"); | |
911 | // | |
912 | if (theVForceUpdate) | |
913 | aTV->Tolerance(aTol); | |
914 | else | |
915 | aTV->UpdateTolerance(aTol); | |
916 | aTV->Modified(Standard_True); | |
917 | break; | |
918 | } | |
919 | default: | |
920 | break; | |
921 | } | |
922 | // | |
923 | if (!UseOldSh) | |
924 | theReshaper.Replace(aSh, aNsh); | |
925 | } | |
926 | } | |
927 | ||
928 | //======================================================================= | |
929 | //function : InternalSameParameter | |
7fd59977 | 930 | //purpose : |
931 | //======================================================================= | |
b60e8432 | 932 | static void InternalSameParameter(const TopoDS_Shape& theSh, BRepTools_ReShape& theReshaper, |
933 | const Standard_Real theTol, const Standard_Boolean IsForced, const Standard_Boolean IsMutableInput ) | |
7fd59977 | 934 | { |
b60e8432 | 935 | TopExp_Explorer ex(theSh,TopAbs_EDGE); |
7fd59977 | 936 | TopTools_MapOfShape Done; |
b60e8432 | 937 | BRep_Builder aB; |
938 | TopTools_DataMapOfShapeReal aShToTol; | |
939 | ||
940 | while (ex.More()) | |
941 | { | |
942 | const TopoDS_Edge& aCE = TopoDS::Edge(ex.Current()); | |
943 | if (Done.Add(aCE)) | |
944 | { | |
945 | TopoDS_Edge aNE = TopoDS::Edge(theReshaper.Value(aCE)); | |
946 | Standard_Boolean UseOldEdge = IsMutableInput || theReshaper.IsNewShape(aCE) || !aNE.IsSame(aCE); | |
947 | if (IsForced && (BRep_Tool::SameRange(aCE) || BRep_Tool::SameParameter(aCE))) | |
948 | { | |
949 | if (!UseOldEdge) | |
950 | { | |
951 | aNE = TopoDS::Edge(aCE.EmptyCopied()); | |
952 | TopoDS_Iterator sit(aCE); | |
953 | for (;sit.More();sit.Next()) | |
954 | aB.Add(aNE, sit.Value()); | |
955 | theReshaper.Replace(aCE, aNE); | |
956 | UseOldEdge = Standard_True; | |
957 | } | |
958 | aB.SameRange(aNE, Standard_False); | |
959 | aB.SameParameter(aNE, Standard_False); | |
960 | } | |
961 | Standard_Real aNewTol = -1; | |
962 | TopoDS_Edge aResEdge = BRepLib::SameParameter(aNE, theTol, aNewTol, UseOldEdge); | |
963 | if (!UseOldEdge && !aResEdge.IsNull()) | |
964 | //NE have been empty-copied | |
965 | theReshaper.Replace(aNE, aResEdge); | |
966 | if (aNewTol > 0) | |
967 | { | |
968 | TopoDS_Vertex aV1, aV2; | |
969 | TopExp::Vertices(aCE,aV1,aV2); | |
970 | if (!aV1.IsNull()) | |
971 | UpdTolMap(aV1, aNewTol, aShToTol); | |
972 | if (!aV2.IsNull()) | |
973 | UpdTolMap(aV2, aNewTol, aShToTol); | |
7fd59977 | 974 | } |
7fd59977 | 975 | } |
976 | ex.Next(); | |
977 | } | |
b60e8432 | 978 | |
7fd59977 | 979 | Done.Clear(); |
980 | BRepAdaptor_Surface BS; | |
b60e8432 | 981 | for(ex.Init(theSh,TopAbs_FACE); ex.More(); ex.Next()){ |
7fd59977 | 982 | const TopoDS_Face& curface = TopoDS::Face(ex.Current()); |
983 | if(!Done.Add(curface)) continue; | |
984 | BS.Initialize(curface); | |
985 | if(BS.GetType() != GeomAbs_Plane) continue; | |
986 | TopExp_Explorer ex2; | |
987 | for(ex2.Init(curface,TopAbs_EDGE); ex2.More(); ex2.Next()){ | |
988 | const TopoDS_Edge& E = TopoDS::Edge(ex2.Current()); | |
b60e8432 | 989 | TopoDS_Shape aNe = theReshaper.Value(E); |
990 | Standard_Real aNewEtol = -1; | |
991 | GetEdgeTol(TopoDS::Edge(aNe), curface, aNewEtol); | |
992 | if (aNewEtol >= 0) //not equal to -1 | |
993 | UpdTolMap(E, aNewEtol, aShToTol); | |
7fd59977 | 994 | } |
995 | } | |
b60e8432 | 996 | |
997 | // | |
998 | UpdShTol(aShToTol, IsMutableInput, theReshaper, Standard_False ); | |
999 | ||
1000 | InternalUpdateTolerances(theSh, Standard_False, IsMutableInput, theReshaper ); | |
7fd59977 | 1001 | } |
1002 | ||
0d969553 | 1003 | //================================================================ |
7fd59977 | 1004 | //function : SameParameter |
0d969553 Y |
1005 | //WARNING : New spec DUB LBO 9/9/97. |
1006 | // Recode in the edge the best tolerance found, | |
1007 | // for vertex extremities it is required to find something else | |
1008 | //================================================================ | |
b60e8432 | 1009 | void BRepLib::SameParameter(const TopoDS_Shape& S, |
1010 | const Standard_Real Tolerance, | |
1011 | const Standard_Boolean forced) | |
1012 | { | |
1013 | BRepTools_ReShape reshaper; | |
1014 | InternalSameParameter( S, reshaper, Tolerance, forced, Standard_True); | |
1015 | } | |
1016 | ||
1017 | //======================================================================= | |
1018 | //function : SameParameter | |
1019 | //purpose : | |
1020 | //======================================================================= | |
1021 | void BRepLib::SameParameter(const TopoDS_Shape& S, BRepTools_ReShape& theReshaper, | |
1022 | const Standard_Real Tolerance, const Standard_Boolean forced ) | |
1023 | { | |
1024 | InternalSameParameter( S, theReshaper, Tolerance, forced, Standard_False); | |
1025 | } | |
1026 | ||
1027 | //======================================================================= | |
1028 | //function : EvalTol | |
1029 | //purpose : | |
1030 | //======================================================================= | |
7fd59977 | 1031 | static Standard_Boolean EvalTol(const Handle(Geom2d_Curve)& pc, |
a86d3ec0 | 1032 | const Handle(Geom_Surface)& s, |
1033 | const GeomAdaptor_Curve& gac, | |
1034 | const Standard_Real tol, | |
1035 | Standard_Real& tolbail) | |
7fd59977 | 1036 | { |
1037 | Standard_Integer ok = 0; | |
1038 | Standard_Real f = gac.FirstParameter(); | |
1039 | Standard_Real l = gac.LastParameter(); | |
1040 | Extrema_LocateExtPC Projector; | |
1041 | Projector.Initialize(gac,f,l,tol); | |
1042 | Standard_Real u,v; | |
1043 | gp_Pnt p; | |
1044 | tolbail = tol; | |
1045 | for(Standard_Integer i = 1; i <= 5; i++){ | |
1046 | Standard_Real t = i/6.; | |
1047 | t = (1.-t) * f + t * l; | |
1048 | pc->Value(t).Coord(u,v); | |
1049 | p = s->Value(u,v); | |
1050 | Projector.Perform(p,t); | |
1051 | if (Projector.IsDone()) { | |
1052 | Standard_Real dist2 = Projector.SquareDistance(); | |
1053 | if(dist2 > tolbail * tolbail) tolbail = sqrt (dist2); | |
1054 | ok++; | |
1055 | } | |
1056 | } | |
1057 | return (ok > 2); | |
1058 | } | |
1059 | ||
b60e8432 | 1060 | //======================================================================= |
1061 | //function : ComputeTol | |
1062 | //purpose : | |
1063 | //======================================================================= | |
7fd59977 | 1064 | static Standard_Real ComputeTol(const Handle(Adaptor3d_HCurve)& c3d, |
a86d3ec0 | 1065 | const Handle(Adaptor2d_HCurve2d)& c2d, |
1066 | const Handle(Adaptor3d_HSurface)& surf, | |
1067 | const Standard_Integer nbp) | |
7fd59977 | 1068 | |
1069 | { | |
1070 | ||
1071 | TColStd_Array1OfReal dist(1,nbp+10); | |
1072 | dist.Init(-1.); | |
1073 | ||
f4dee9bb | 1074 | //Adaptor3d_CurveOnSurface cons(c2d,surf); |
1075 | Standard_Real uf = surf->FirstUParameter(), ul = surf->LastUParameter(), | |
1076 | vf = surf->FirstVParameter(), vl = surf->LastVParameter(); | |
1077 | Standard_Real du = 0.01 * (ul - uf), dv = 0.01 * (vl - vf); | |
1078 | Standard_Boolean isUPeriodic = surf->IsUPeriodic(), isVPeriodic = surf->IsVPeriodic(); | |
1079 | Standard_Real DSdu = 1./surf->UResolution(1.), DSdv = 1./surf->VResolution(1.); | |
7fd59977 | 1080 | Standard_Real d2 = 0.; |
7fd59977 | 1081 | Standard_Real first = c3d->FirstParameter(); |
1082 | Standard_Real last = c3d->LastParameter(); | |
f4dee9bb | 1083 | Standard_Real dapp = -1.; |
c48e2889 | 1084 | for (Standard_Integer i = 0; i <= nbp; ++i) |
1085 | { | |
a86d3ec0 | 1086 | const Standard_Real t = IntToReal(i)/IntToReal(nbp); |
1087 | const Standard_Real u = first*(1.-t) + last*t; | |
7fd59977 | 1088 | gp_Pnt Pc3d = c3d->Value(u); |
f4dee9bb | 1089 | gp_Pnt2d Puv = c2d->Value(u); |
1090 | if(!isUPeriodic) | |
1091 | { | |
1092 | if(Puv.X() < uf - du) | |
1093 | { | |
1094 | dapp = Max(dapp, DSdu * (uf - Puv.X())); | |
1095 | continue; | |
1096 | } | |
1097 | else if(Puv.X() > ul + du) | |
1098 | { | |
1099 | dapp = Max(dapp, DSdu * (Puv.X() - ul)); | |
1100 | continue; | |
1101 | } | |
1102 | } | |
1103 | if(!isVPeriodic) | |
1104 | { | |
1105 | if(Puv.Y() < vf - dv) | |
1106 | { | |
1107 | dapp = Max(dapp, DSdv * (vf - Puv.Y())); | |
1108 | continue; | |
1109 | } | |
1110 | else if(Puv.Y() > vl + dv) | |
1111 | { | |
1112 | dapp = Max(dapp, DSdv * (Puv.Y() - vl)); | |
1113 | continue; | |
1114 | } | |
1115 | } | |
1116 | gp_Pnt Pcons = surf->Value(Puv.X(), Puv.Y()); | |
7fd59977 | 1117 | if (Precision::IsInfinite(Pcons.X()) || |
f4dee9bb | 1118 | Precision::IsInfinite(Pcons.Y()) || |
1119 | Precision::IsInfinite(Pcons.Z())) | |
1120 | { | |
c48e2889 | 1121 | d2 = Precision::Infinite(); |
1122 | break; | |
7fd59977 | 1123 | } |
1124 | Standard_Real temp = Pc3d.SquareDistance(Pcons); | |
1125 | ||
7fd59977 | 1126 | dist(i+1) = temp; |
1127 | ||
c48e2889 | 1128 | d2 = Max (d2, temp); |
7fd59977 | 1129 | } |
1130 | ||
f4dee9bb | 1131 | if(Precision::IsInfinite(d2)) |
1132 | { | |
1133 | return d2; | |
1134 | } | |
1135 | ||
1136 | d2 = Sqrt(d2); | |
1137 | if(dapp > d2) | |
1138 | { | |
1139 | return dapp; | |
1140 | } | |
7fd59977 | 1141 | |
1142 | Standard_Boolean ana = Standard_False; | |
1143 | Standard_Real D2 = 0; | |
1144 | Standard_Integer N1 = 0; | |
1145 | Standard_Integer N2 = 0; | |
1146 | Standard_Integer N3 = 0; | |
1147 | ||
c48e2889 | 1148 | for (Standard_Integer i = 1; i<= nbp+10; ++i) |
1149 | { | |
1150 | if (dist(i) > 0) | |
1151 | { | |
1152 | if (dist(i) < 1.0) | |
1153 | { | |
1154 | ++N1; | |
1155 | } | |
1156 | else | |
1157 | { | |
1158 | ++N2; | |
1159 | } | |
7fd59977 | 1160 | } |
c48e2889 | 1161 | } |
7fd59977 | 1162 | |
c48e2889 | 1163 | if (N1 > N2 && N2 != 0) |
1164 | { | |
1165 | N3 = 100*N2/(N1+N2); | |
1166 | } | |
1167 | if (N3 < 10 && N3 != 0) | |
1168 | { | |
1169 | ana = Standard_True; | |
1170 | for (Standard_Integer i = 1; i <= nbp+10; ++i) | |
1171 | { | |
1172 | if (dist(i) > 0 && dist(i) < 1.0) | |
1173 | { | |
1174 | D2 = Max (D2, dist(i)); | |
1175 | } | |
a86d3ec0 | 1176 | } |
c48e2889 | 1177 | } |
7fd59977 | 1178 | |
c48e2889 | 1179 | //d2 = 1.5*sqrt(d2); |
1180 | d2 = (!ana) ? 1.5 * d2 : 1.5*sqrt(D2); | |
1181 | d2 = Max (d2, 1.e-7); | |
1182 | return d2; | |
7fd59977 | 1183 | } |
1184 | ||
b60e8432 | 1185 | //======================================================================= |
1186 | //function : GetCurve3d | |
1187 | //purpose : | |
1188 | //======================================================================= | |
1189 | static void GetCurve3d(const TopoDS_Edge& theEdge, Handle(Geom_Curve)& theC3d, Standard_Real& theF3d, | |
1190 | Standard_Real& theL3d, TopLoc_Location& theLoc3d, BRep_ListOfCurveRepresentation& theCList) | |
1191 | { | |
1192 | const Handle(BRep_TEdge)& aTE = *((Handle(BRep_TEdge)*) &theEdge.TShape()); | |
1193 | theCList = aTE->ChangeCurves(); // current function (i.e. GetCurve3d()) will not change any of this curves | |
1194 | BRep_ListIteratorOfListOfCurveRepresentation anIt(theCList); | |
1195 | Standard_Boolean NotDone = Standard_True; | |
1196 | while (NotDone && anIt.More()) { | |
1197 | Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(anIt.Value()); | |
1198 | if (!GCurve.IsNull() && GCurve->IsCurve3D()) { | |
1199 | theC3d = GCurve->Curve3D() ; | |
1200 | theF3d = GCurve->First(); | |
1201 | theL3d = GCurve->Last(); | |
1202 | theLoc3d = GCurve->Location() ; | |
1203 | NotDone = Standard_False; | |
1204 | } | |
1205 | anIt.Next() ; | |
1206 | } | |
1207 | } | |
1208 | ||
1209 | //======================================================================= | |
1210 | //function : UpdateVTol | |
1211 | //purpose : | |
1212 | //======================================================================= | |
1213 | void UpdateVTol(const TopoDS_Vertex theV1, const TopoDS_Vertex& theV2, Standard_Real theTol) | |
7fd59977 | 1214 | { |
b60e8432 | 1215 | BRep_Builder aB; |
1216 | if (!theV1.IsNull()) | |
1217 | aB.UpdateVertex(theV1,theTol); | |
1218 | if (!theV2.IsNull()) | |
1219 | aB.UpdateVertex(theV2,theTol); | |
1220 | } | |
7fd59977 | 1221 | |
b60e8432 | 1222 | //======================================================================= |
1223 | //function : SameParameter | |
1224 | //purpose : | |
1225 | //======================================================================= | |
1226 | void BRepLib::SameParameter(const TopoDS_Edge& theEdge, | |
1227 | const Standard_Real theTolerance) | |
1228 | { | |
1229 | Standard_Real aNewTol = -1; | |
1230 | SameParameter(theEdge, theTolerance, aNewTol, Standard_True); | |
1231 | if (aNewTol > 0) | |
1232 | { | |
1233 | TopoDS_Vertex aV1, aV2; | |
1234 | TopExp::Vertices(theEdge,aV1,aV2); | |
1235 | UpdateVTol(aV1, aV2, aNewTol); | |
1236 | } | |
1237 | } | |
7fd59977 | 1238 | |
b60e8432 | 1239 | //======================================================================= |
1240 | //function : SameParameter | |
1241 | //purpose : | |
1242 | //======================================================================= | |
1243 | TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge, | |
1244 | const Standard_Real theTolerance, Standard_Real& theNewTol, Standard_Boolean IsUseOldEdge) | |
1245 | { | |
1246 | if (BRep_Tool::SameParameter(theEdge)) | |
1247 | return TopoDS_Edge(); | |
7fd59977 | 1248 | Standard_Real f3d =0.,l3d =0.; |
7fd59977 | 1249 | TopLoc_Location L3d; |
1250 | Handle(Geom_Curve) C3d; | |
b60e8432 | 1251 | BRep_ListOfCurveRepresentation CList; |
1252 | GetCurve3d(theEdge, C3d, f3d, l3d, L3d, CList); | |
1253 | if(C3d.IsNull()) | |
1254 | return TopoDS_Edge(); | |
7fd59977 | 1255 | |
b60e8432 | 1256 | BRep_Builder B; |
1257 | TopoDS_Edge aNE; | |
1258 | Handle(BRep_TEdge) aNTE; | |
1259 | if (IsUseOldEdge) | |
1260 | { | |
1261 | aNE = theEdge; | |
1262 | aNTE = *((Handle(BRep_TEdge)*) &theEdge.TShape()); | |
1263 | } | |
1264 | else | |
1265 | { | |
1266 | aNE = TopoDS::Edge(theEdge.EmptyCopied()); //will be modified a little bit later, so copy anyway | |
1267 | GetCurve3d(aNE, C3d, f3d, l3d, L3d, CList); //C3d pointer and CList will be differ after copying | |
1268 | aNTE = *((Handle(BRep_TEdge)*) &aNE.TShape()); | |
1269 | TopoDS_Iterator sit(theEdge); | |
1270 | for (;sit.More();sit.Next()) //add vertices from old edge to the new ones | |
1271 | B.Add(aNE, sit.Value()); | |
1272 | } | |
a86d3ec0 | 1273 | |
b60e8432 | 1274 | BRep_ListIteratorOfListOfCurveRepresentation It(CList); |
7fd59977 | 1275 | |
b60e8432 | 1276 | const Standard_Integer NCONTROL = 22; |
7fd59977 | 1277 | |
b60e8432 | 1278 | Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(); |
1279 | Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve(); | |
1280 | Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(); | |
1281 | GeomAdaptor_Curve& GAC = HC->ChangeCurve(); | |
1282 | Geom2dAdaptor_Curve& GAC2d = HC2d->ChangeCurve2d(); | |
1283 | GeomAdaptor_Surface& GAS = HS->ChangeSurface(); | |
7fd59977 | 1284 | |
1285 | // modified by NIZHNY-OCC486 Tue Aug 27 17:15:13 2002 : | |
1286 | Standard_Boolean m_TrimmedPeriodical = Standard_False; | |
1287 | Handle(Standard_Type) TheType = C3d->DynamicType(); | |
1288 | if( TheType == STANDARD_TYPE(Geom_TrimmedCurve)) | |
a86d3ec0 | 1289 | { |
c5f3a425 | 1290 | Handle(Geom_Curve) gtC (Handle(Geom_TrimmedCurve)::DownCast (C3d)->BasisCurve()); |
a86d3ec0 | 1291 | m_TrimmedPeriodical = gtC->IsPeriodic(); |
1292 | } | |
7fd59977 | 1293 | // modified by NIZHNY-OCC486 Tue Aug 27 17:15:17 2002 . |
1294 | ||
b60e8432 | 1295 | |
7fd59977 | 1296 | if(!C3d->IsPeriodic()) { |
1297 | Standard_Real Udeb = C3d->FirstParameter(); | |
1298 | Standard_Real Ufin = C3d->LastParameter(); | |
1299 | // modified by NIZHNY-OCC486 Tue Aug 27 17:17:14 2002 : | |
1300 | //if (Udeb > f3d) f3d = Udeb; | |
1301 | //if (l3d > Ufin) l3d = Ufin; | |
1302 | if(!m_TrimmedPeriodical) | |
a86d3ec0 | 1303 | { |
1304 | if (Udeb > f3d) f3d = Udeb; | |
1305 | if (l3d > Ufin) l3d = Ufin; | |
1306 | } | |
7fd59977 | 1307 | // modified by NIZHNY-OCC486 Tue Aug 27 17:17:55 2002 . |
1308 | } | |
1309 | if(!L3d.IsIdentity()){ | |
1310 | C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L3d.Transformation())); | |
1311 | } | |
1312 | GAC.Load(C3d,f3d,l3d); | |
1313 | ||
1314 | Standard_Boolean IsSameP = 1; | |
1315 | Standard_Real maxdist = 0.; | |
1316 | ||
a86d3ec0 | 1317 | // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin |
b60e8432 | 1318 | Standard_Real anEdgeTol = BRep_Tool::Tolerance(aNE); |
a86d3ec0 | 1319 | // Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End |
b60e8432 | 1320 | Standard_Boolean SameRange = BRep_Tool::SameRange(aNE); |
7fd59977 | 1321 | Standard_Boolean YaPCu = Standard_False; |
f4dee9bb | 1322 | const Standard_Real BigError = 1.e10; |
7fd59977 | 1323 | It.Initialize(CList); |
1324 | ||
1325 | while (It.More()) { | |
b60e8432 | 1326 | |
7fd59977 | 1327 | Standard_Boolean isANA = Standard_False; |
1328 | Standard_Boolean isBSP = Standard_False; | |
1329 | Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(It.Value()); | |
1330 | Handle(Geom2d_Curve) PC[2]; | |
1331 | Handle(Geom_Surface) S; | |
1332 | if (!GCurve.IsNull() && GCurve->IsCurveOnSurface()) { | |
1333 | YaPCu = Standard_True; | |
1334 | PC[0] = GCurve->PCurve(); | |
1335 | TopLoc_Location PCLoc = GCurve->Location(); | |
1336 | S = GCurve->Surface(); | |
1337 | if (!PCLoc.IsIdentity() ) { | |
a86d3ec0 | 1338 | S = Handle(Geom_Surface)::DownCast(S->Transformed(PCLoc.Transformation())); |
7fd59977 | 1339 | } |
a86d3ec0 | 1340 | |
7fd59977 | 1341 | GAS.Load(S); |
1342 | if (GCurve->IsCurveOnClosedSurface()) { | |
a86d3ec0 | 1343 | PC[1] = GCurve->PCurve2(); |
7fd59977 | 1344 | } |
a86d3ec0 | 1345 | |
7fd59977 | 1346 | // Eval tol2d to compute SameRange |
b60e8432 | 1347 | Standard_Real UResol = Max(GAS.UResolution(theTolerance), Precision::PConfusion()); |
1348 | Standard_Real VResol = Max(GAS.VResolution(theTolerance), Precision::PConfusion()); | |
7fd59977 | 1349 | Standard_Real Tol2d = Min(UResol, VResol); |
1350 | for(Standard_Integer i = 0; i < 2; i++){ | |
a86d3ec0 | 1351 | Handle(Geom2d_Curve) curPC = PC[i]; |
1352 | Standard_Boolean updatepc = 0; | |
1353 | if(curPC.IsNull()) break; | |
1354 | if(!SameRange){ | |
1355 | GeomLib::SameRange(Tol2d, | |
1356 | PC[i],GCurve->First(),GCurve->Last(), | |
1357 | f3d,l3d,curPC); | |
1358 | ||
1359 | updatepc = (curPC != PC[i]); | |
1360 | ||
1361 | } | |
1362 | Standard_Boolean goodpc = 1; | |
1363 | GAC2d.Load(curPC,f3d,l3d); | |
1364 | ||
1365 | Standard_Real error = ComputeTol(HC, HC2d, HS, NCONTROL); | |
1366 | ||
f4dee9bb | 1367 | if(error > BigError) |
1368 | { | |
1369 | maxdist = error; | |
1370 | break; | |
1371 | } | |
1372 | ||
a86d3ec0 | 1373 | if(GAC2d.GetType() == GeomAbs_BSplineCurve && |
1374 | GAC2d.Continuity() == GeomAbs_C0) { | |
1375 | Handle(Geom2d_BSplineCurve) bs2d = GAC2d.BSpline(); | |
1376 | Handle(Geom2d_BSplineCurve) bs2dsov = bs2d; | |
1377 | Standard_Real fC0 = bs2d->FirstParameter(), lC0 = bs2d->LastParameter(); | |
1378 | Standard_Boolean repar = Standard_True; | |
1379 | gp_Pnt2d OriginPoint; | |
1380 | bs2d->D0(fC0, OriginPoint); | |
1381 | Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d, Tol2d); | |
1382 | isBSP = Standard_True; | |
1383 | ||
1384 | if(bs2d->IsPeriodic()) { // -------- IFV, Jan 2000 | |
1385 | gp_Pnt2d NewOriginPoint; | |
1386 | bs2d->D0(bs2d->FirstParameter(), NewOriginPoint); | |
1387 | if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() || | |
1388 | Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion() ) { | |
1389 | ||
1390 | TColStd_Array1OfReal Knotbs2d (1, bs2d->NbKnots()); | |
1391 | bs2d->Knots(Knotbs2d); | |
1392 | ||
1393 | for(Standard_Integer Index = 1; Index <= bs2d->NbKnots(); Index++) { | |
1394 | bs2d->D0(Knotbs2d(Index), NewOriginPoint); | |
1395 | if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() || | |
1396 | Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion() ) continue; | |
1397 | ||
1398 | bs2d->SetOrigin(Index); | |
1399 | break; | |
1400 | } | |
1401 | } | |
1402 | } | |
1403 | ||
1404 | if(bs2d->Continuity() == GeomAbs_C0) { | |
1405 | Standard_Real tolbail; | |
b60e8432 | 1406 | if(EvalTol(curPC,S,GAC,theTolerance,tolbail)){ |
a86d3ec0 | 1407 | bs2d = bs2dsov; |
1408 | Standard_Real UResbail = GAS.UResolution(tolbail); | |
1409 | Standard_Real VResbail = GAS.VResolution(tolbail); | |
1410 | Standard_Real Tol2dbail = Min(UResbail,VResbail); | |
1411 | bs2d->D0(bs2d->FirstParameter(), OriginPoint); | |
1412 | ||
1413 | Standard_Integer nbp = bs2d->NbPoles(); | |
1414 | TColgp_Array1OfPnt2d poles(1,nbp); | |
1415 | bs2d->Poles(poles); | |
1416 | gp_Pnt2d p = poles(1), p1; | |
1417 | Standard_Real d = Precision::Infinite(); | |
1418 | for(Standard_Integer ip = 2; ip <= nbp; ip++) { | |
1419 | p1 = poles(ip); | |
1420 | d = Min(d,p.SquareDistance(p1)); | |
1421 | p = p1; | |
1422 | } | |
1423 | d = sqrt(d)*.1; | |
1424 | ||
1425 | Tol2dbail = Max(Min(Tol2dbail,d),Tol2d); | |
1426 | ||
1427 | Geom2dConvert::C0BSplineToC1BSplineCurve(bs2d,Tol2dbail); | |
1428 | ||
1429 | if(bs2d->IsPeriodic()) { // -------- IFV, Jan 2000 | |
1430 | gp_Pnt2d NewOriginPoint; | |
1431 | bs2d->D0(bs2d->FirstParameter(), NewOriginPoint); | |
1432 | if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() || | |
1433 | Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion() ) { | |
1434 | ||
1435 | TColStd_Array1OfReal Knotbs2d (1, bs2d->NbKnots()); | |
1436 | bs2d->Knots(Knotbs2d); | |
1437 | ||
1438 | for(Standard_Integer Index = 1; Index <= bs2d->NbKnots(); Index++) { | |
1439 | bs2d->D0(Knotbs2d(Index), NewOriginPoint); | |
1440 | if(Abs(OriginPoint.X() - NewOriginPoint.X()) > Precision::PConfusion() || | |
1441 | Abs(OriginPoint.Y() - NewOriginPoint.Y()) > Precision::PConfusion() ) continue; | |
1442 | ||
1443 | bs2d->SetOrigin(Index); | |
1444 | break; | |
1445 | } | |
1446 | } | |
1447 | } | |
1448 | ||
1449 | ||
1450 | if(bs2d->Continuity() == GeomAbs_C0) { | |
1451 | goodpc = 1; | |
1452 | bs2d = bs2dsov; | |
1453 | repar = Standard_False; | |
1454 | } | |
1455 | } | |
1456 | else goodpc = 0; | |
1457 | } | |
1458 | ||
1459 | if(goodpc){ | |
1460 | if(repar) { | |
1461 | Standard_Integer NbKnots = bs2d->NbKnots(); | |
1462 | TColStd_Array1OfReal Knots(1,NbKnots); | |
1463 | bs2d->Knots(Knots); | |
1464 | // BSplCLib::Reparametrize(f3d,l3d,Knots); | |
1465 | BSplCLib::Reparametrize(fC0,lC0,Knots); | |
1466 | bs2d->SetKnots(Knots); | |
1467 | GAC2d.Load(bs2d,f3d,l3d); | |
1468 | curPC = bs2d; | |
1469 | Standard_Boolean updatepcsov = updatepc; | |
1470 | updatepc = Standard_True; | |
1471 | ||
1472 | Standard_Real error1 = ComputeTol(HC, HC2d, HS, NCONTROL); | |
1473 | if(error1 > error) { | |
1474 | bs2d = bs2dsov; | |
1475 | GAC2d.Load(bs2d,f3d,l3d); | |
1476 | curPC = bs2d; | |
1477 | updatepc = updatepcsov; | |
1478 | isANA = Standard_True; | |
1479 | } | |
1480 | else { | |
1481 | error = error1; | |
1482 | } | |
1483 | } | |
1484 | ||
1485 | //check, if new BSpline "good" or not --------- IFV, Jan of 2000 | |
1486 | GeomAbs_Shape cont = bs2d->Continuity(); | |
1487 | Standard_Boolean IsBad = Standard_False; | |
1488 | ||
b60e8432 | 1489 | if(cont > GeomAbs_C0 && error > Max(1.e-3,theTolerance)) { |
a86d3ec0 | 1490 | Standard_Integer NbKnots = bs2d->NbKnots(); |
1491 | TColStd_Array1OfReal Knots(1,NbKnots); | |
1492 | bs2d->Knots(Knots); | |
1493 | Standard_Real critratio = 10.; | |
1494 | Standard_Real dtprev = Knots(2) - Knots(1), dtratio = 1.; | |
1495 | Standard_Real dtmin = dtprev; | |
1496 | Standard_Real dtcur; | |
1497 | for(Standard_Integer j = 2; j < NbKnots; j++) { | |
1498 | dtcur = Knots(j+1) - Knots(j); | |
1499 | dtmin = Min(dtmin, dtcur); | |
1500 | ||
1501 | if(IsBad) continue; | |
1502 | ||
1503 | if(dtcur > dtprev) dtratio = dtcur/dtprev; | |
1504 | else dtratio = dtprev/dtcur; | |
1505 | if(dtratio > critratio) {IsBad = Standard_True;} | |
1506 | dtprev = dtcur; | |
1507 | ||
1508 | } | |
1509 | if(IsBad) { | |
1510 | // To avoid failures in Approx_CurvilinearParameter | |
b60e8432 | 1511 | bs2d->Resolution(Max(1.e-3,theTolerance), dtcur); |
a86d3ec0 | 1512 | if(dtmin < dtcur) IsBad = Standard_False; |
1513 | } | |
1514 | } | |
1515 | ||
1516 | ||
1517 | if(IsBad ) { //if BSpline "bad", try to reparametrize it | |
1518 | // by its curve length | |
1519 | ||
1520 | // GeomAbs_Shape cont = bs2d->Continuity(); | |
1521 | if(cont > GeomAbs_C2) cont = GeomAbs_C2; | |
1522 | Standard_Integer maxdeg = bs2d->Degree(); | |
1523 | if(maxdeg == 1) maxdeg = 14; | |
b60e8432 | 1524 | Approx_CurvilinearParameter AppCurPar(HC2d, HS, Max(1.e-3,theTolerance), |
a86d3ec0 | 1525 | cont, maxdeg, 10); |
1526 | if(AppCurPar.IsDone() || AppCurPar.HasResult()) { | |
1527 | bs2d = AppCurPar.Curve2d1(); | |
1528 | GAC2d.Load(bs2d,f3d,l3d); | |
1529 | curPC = bs2d; | |
1530 | ||
1531 | if(Abs(bs2d->FirstParameter() - fC0) > Tol2d || | |
1532 | Abs(bs2d->LastParameter() - lC0) > Tol2d ) { | |
1533 | Standard_Integer NbKnots = bs2d->NbKnots(); | |
1534 | TColStd_Array1OfReal Knots(1,NbKnots); | |
1535 | bs2d->Knots(Knots); | |
1536 | // BSplCLib::Reparametrize(f3d,l3d,Knots); | |
1537 | BSplCLib::Reparametrize(fC0,lC0,Knots); | |
1538 | bs2d->SetKnots(Knots); | |
1539 | GAC2d.Load(bs2d,f3d,l3d); | |
1540 | curPC = bs2d; | |
1541 | ||
1542 | } | |
1543 | } | |
1544 | } | |
1545 | ||
1546 | ||
1547 | } | |
1548 | } | |
1549 | ||
1550 | ||
1551 | if(goodpc){ | |
1552 | // Approx_SameParameter SameP(HC,HC2d,HS,Tolerance); | |
b60e8432 | 1553 | Standard_Real aTol = (isANA && isBSP) ? 1.e-7 : theTolerance; |
543a9964 | 1554 | const Handle(Adaptor3d_HCurve)& aHCurv = HC; // to avoid ambiguity |
1555 | const Handle(Adaptor2d_HCurve2d)& aHCurv2d = HC2d; // to avoid ambiguity | |
1556 | Approx_SameParameter SameP(aHCurv,aHCurv2d,HS,aTol); | |
a86d3ec0 | 1557 | |
1558 | if (SameP.IsSameParameter()) { | |
1559 | maxdist = Max(maxdist,SameP.TolReached()); | |
1560 | if(updatepc){ | |
1561 | if (i == 0) GCurve->PCurve(curPC); | |
1562 | else GCurve->PCurve2(curPC); | |
1563 | } | |
1564 | } | |
1565 | else if (SameP.IsDone()) { | |
1566 | Standard_Real tolreached = SameP.TolReached(); | |
52db4751 | 1567 | if(tolreached <= error) { |
a86d3ec0 | 1568 | curPC = SameP.Curve2d(); |
1569 | updatepc = Standard_True; | |
1570 | maxdist = Max(maxdist,tolreached); | |
1571 | } | |
1572 | else { | |
1573 | maxdist = Max(maxdist, error); | |
1574 | } | |
1575 | if(updatepc){ | |
1576 | if (i == 0) GCurve->PCurve(curPC); | |
1577 | else GCurve->PCurve2(curPC); | |
1578 | } | |
1579 | } | |
4e14c88f | 1580 | else |
1581 | { | |
1582 | //Approx_SameParameter has failed. | |
1583 | //Consequently, the situation might be, | |
1584 | //when 3D and 2D-curve do not have same-range. | |
1585 | GeomLib::SameRange( Tol2d, PC[i], | |
1586 | GCurve->First(), GCurve->Last(), | |
1587 | f3d,l3d,curPC); | |
1588 | ||
1589 | if (i == 0) GCurve->PCurve(curPC); | |
1590 | else GCurve->PCurve2(curPC); | |
1591 | ||
1592 | IsSameP = 0; | |
1593 | } | |
a86d3ec0 | 1594 | |
1595 | } | |
1596 | else IsSameP = 0; | |
1597 | ||
1598 | // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin | |
1599 | if (!IsSameP) { | |
52db4751 | 1600 | if (anEdgeTol >= error) { |
a86d3ec0 | 1601 | maxdist = Max(maxdist, anEdgeTol); |
1602 | IsSameP = Standard_True; | |
1603 | } | |
1604 | } | |
1605 | // Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End | |
7fd59977 | 1606 | } |
1607 | } | |
1608 | It.Next() ; | |
1609 | } | |
b60e8432 | 1610 | B.Range(aNE,f3d,l3d); |
1611 | B.SameRange(aNE,Standard_True); | |
7fd59977 | 1612 | if ( IsSameP) { |
0d969553 Y |
1613 | // Reduce eventually the tolerance of the edge, as |
1614 | // all its representations are processed (except for some associated | |
1615 | // to planes and not stored in the edge !) | |
1616 | // The same cannot be done with vertices that cannot be enlarged | |
1617 | // or left as is. | |
7fd59977 | 1618 | if (YaPCu) { |
0d969553 | 1619 | // Avoid setting too small tolerances. |
7fd59977 | 1620 | maxdist = Max(maxdist,Precision::Confusion()); |
b60e8432 | 1621 | theNewTol = maxdist; |
1622 | aNTE->Modified(Standard_True); | |
1623 | aNTE->Tolerance(maxdist); | |
7fd59977 | 1624 | } |
b60e8432 | 1625 | B.SameParameter(aNE,Standard_True); |
7fd59977 | 1626 | } |
b60e8432 | 1627 | |
1628 | return aNE; | |
7fd59977 | 1629 | } |
1630 | ||
1631 | //======================================================================= | |
b60e8432 | 1632 | //function : InternalUpdateTolerances |
7fd59977 | 1633 | //purpose : |
1634 | //======================================================================= | |
b60e8432 | 1635 | static void InternalUpdateTolerances(const TopoDS_Shape& theOldShape, |
1636 | const Standard_Boolean IsVerifyTolerance, const Standard_Boolean IsMutableInput, BRepTools_ReShape& theReshaper) | |
7fd59977 | 1637 | { |
b60e8432 | 1638 | TopTools_DataMapOfShapeReal aShToTol; |
a86d3ec0 | 1639 | // Harmonize tolerances |
1640 | // with rule Tolerance(VERTEX)>=Tolerance(EDGE)>=Tolerance(FACE) | |
7fd59977 | 1641 | Standard_Real tol=0; |
b60e8432 | 1642 | if (IsVerifyTolerance) { |
0d969553 | 1643 | // Set tolerance to its minimum value |
7fd59977 | 1644 | Handle(Geom_Surface) S; |
1645 | TopLoc_Location l; | |
1646 | TopExp_Explorer ex; | |
1647 | Bnd_Box aB; | |
1648 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dMax; | |
b60e8432 | 1649 | for (ex.Init(theOldShape, TopAbs_FACE); ex.More(); ex.Next()) { |
7fd59977 | 1650 | const TopoDS_Face& curf=TopoDS::Face(ex.Current()); |
1651 | S = BRep_Tool::Surface(curf, l); | |
1652 | if (!S.IsNull()) { | |
a86d3ec0 | 1653 | aB.SetVoid(); |
1654 | BRepBndLib::Add(curf,aB); | |
1655 | if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { | |
c5f3a425 | 1656 | S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface(); |
a86d3ec0 | 1657 | } |
1658 | GeomAdaptor_Surface AS(S); | |
1659 | switch (AS.GetType()) { | |
1660 | case GeomAbs_Plane: | |
1661 | case GeomAbs_Cylinder: | |
1662 | case GeomAbs_Cone: | |
1663 | { | |
1664 | tol=Precision::Confusion(); | |
1665 | break; | |
1666 | } | |
1667 | case GeomAbs_Sphere: | |
1668 | case GeomAbs_Torus: | |
1669 | { | |
1670 | tol=Precision::Confusion()*2; | |
1671 | break; | |
1672 | } | |
1673 | default: | |
1674 | tol=Precision::Confusion()*4; | |
1675 | } | |
1676 | if (!aB.IsWhole()) { | |
1677 | aB.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); | |
1678 | dMax=1.; | |
1679 | if (!aB.IsOpenXmin() && !aB.IsOpenXmax()) dMax=aXmax-aXmin; | |
1680 | if (!aB.IsOpenYmin() && !aB.IsOpenYmax()) aYmin=aYmax-aYmin; | |
1681 | if (!aB.IsOpenZmin() && !aB.IsOpenZmax()) aZmin=aZmax-aZmin; | |
1682 | if (aYmin>dMax) dMax=aYmin; | |
1683 | if (aZmin>dMax) dMax=aZmin; | |
1684 | tol=tol*dMax; | |
1685 | // Do not process tolerances > 1. | |
1686 | if (tol>1.) tol=0.99; | |
1687 | } | |
b60e8432 | 1688 | aShToTol.Bind(curf, tol); |
7fd59977 | 1689 | } |
1690 | } | |
1691 | } | |
a86d3ec0 | 1692 | |
0d969553 | 1693 | //Process edges |
7fd59977 | 1694 | TopTools_IndexedDataMapOfShapeListOfShape parents; |
b60e8432 | 1695 | TopExp::MapShapesAndAncestors(theOldShape, TopAbs_EDGE, TopAbs_FACE, parents); |
7fd59977 | 1696 | TopTools_ListIteratorOfListOfShape lConx; |
1697 | Standard_Integer iCur; | |
1698 | for (iCur=1; iCur<=parents.Extent(); iCur++) { | |
1699 | tol=0; | |
b60e8432 | 1700 | for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) |
1701 | { | |
1702 | const TopoDS_Face& FF = TopoDS::Face(lConx.Value()); | |
1703 | Standard_Real Ftol; | |
1704 | if (IsVerifyTolerance && aShToTol.IsBound(FF)) //first condition for speed-up | |
1705 | Ftol = aShToTol(FF); | |
1706 | else | |
1707 | Ftol = BRep_Tool::Tolerance(FF); //tolerance have not been updated | |
1708 | tol=Max(tol, Ftol); | |
7fd59977 | 1709 | } |
0d969553 Y |
1710 | // Update can only increase tolerance, so if the edge has a greater |
1711 | // tolerance than its faces it is not concerned | |
b60e8432 | 1712 | const TopoDS_Edge& EK = TopoDS::Edge(parents.FindKey(iCur)); |
1713 | if (tol > BRep_Tool::Tolerance(EK)) | |
1714 | aShToTol.Bind(EK, tol); | |
7fd59977 | 1715 | } |
1716 | ||
0d969553 | 1717 | //Vertices are processed |
f4dee9bb | 1718 | const Standard_Real BigTol = 1.e10; |
7fd59977 | 1719 | parents.Clear(); |
b60e8432 | 1720 | |
1721 | TopExp::MapShapesAndUniqueAncestors(theOldShape, TopAbs_VERTEX, TopAbs_EDGE, parents); | |
7fd59977 | 1722 | TColStd_MapOfTransient Initialized; |
7fd59977 | 1723 | Standard_Integer nbV = parents.Extent(); |
1724 | for (iCur=1; iCur<=nbV; iCur++) { | |
1725 | tol=0; | |
7fd59977 | 1726 | const TopoDS_Vertex& V = TopoDS::Vertex(parents.FindKey(iCur)); |
1727 | Bnd_Box box; | |
1728 | box.Add(BRep_Tool::Pnt(V)); | |
1729 | gp_Pnt p3d; | |
1730 | for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) { | |
1731 | const TopoDS_Edge& E = TopoDS::Edge(lConx.Value()); | |
b60e8432 | 1732 | const Standard_Real* aNtol = aShToTol.Seek(E); |
1733 | tol=Max(tol, aNtol ? *aNtol : BRep_Tool::Tolerance(E)); | |
f4dee9bb | 1734 | if(tol > BigTol) continue; |
7fd59977 | 1735 | if(!BRep_Tool::SameRange(E)) continue; |
1736 | Standard_Real par = BRep_Tool::Parameter(V,E); | |
1737 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape()); | |
1738 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); | |
1739 | const TopLoc_Location& Eloc = E.Location(); | |
1740 | while (itcr.More()) { | |
a86d3ec0 | 1741 | // For each CurveRepresentation, check the provided parameter |
1742 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); | |
1743 | const TopLoc_Location& loc = cr->Location(); | |
1744 | TopLoc_Location L = (Eloc * loc); | |
1745 | if (cr->IsCurve3D()) { | |
1746 | const Handle(Geom_Curve)& C = cr->Curve3D(); | |
1747 | if (!C.IsNull()) { // edge non degenerated | |
1748 | p3d = C->Value(par); | |
1749 | p3d.Transform(L.Transformation()); | |
1750 | box.Add(p3d); | |
1751 | } | |
1752 | } | |
1753 | else if (cr->IsCurveOnSurface()) { | |
1754 | const Handle(Geom_Surface)& Su = cr->Surface(); | |
1755 | const Handle(Geom2d_Curve)& PC = cr->PCurve(); | |
1756 | Handle(Geom2d_Curve) PC2; | |
1757 | if (cr->IsCurveOnClosedSurface()) { | |
1758 | PC2 = cr->PCurve2(); | |
1759 | } | |
1760 | gp_Pnt2d p2d = PC->Value(par); | |
1761 | p3d = Su->Value(p2d.X(),p2d.Y()); | |
1762 | p3d.Transform(L.Transformation()); | |
1763 | box.Add(p3d); | |
1764 | if (!PC2.IsNull()) { | |
1765 | p2d = PC2->Value(par); | |
1766 | p3d = Su->Value(p2d.X(),p2d.Y()); | |
1767 | p3d.Transform(L.Transformation()); | |
1768 | box.Add(p3d); | |
1769 | } | |
1770 | } | |
1771 | itcr.Next(); | |
7fd59977 | 1772 | } |
1773 | } | |
1774 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; | |
1775 | box.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); | |
1776 | aXmax -= aXmin; aYmax -= aYmin; aZmax -= aZmin; | |
1777 | tol = Max(tol,sqrt(aXmax*aXmax+aYmax*aYmax+aZmax*aZmax)); | |
1778 | tol += 2.*Epsilon(tol); | |
b60e8432 | 1779 | // |
1780 | Standard_Real aVTol = BRep_Tool::Tolerance(V); | |
1781 | Standard_Boolean anUpdTol = tol > aVTol; | |
1782 | const Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&V.TShape()); | |
1783 | Standard_Boolean toAdd = Standard_False; | |
1784 | if (IsVerifyTolerance) | |
1785 | { | |
0d969553 | 1786 | // ASet minimum value of the tolerance |
b60e8432 | 1787 | // Attention to sharing of the vertex by other shapes |
1788 | toAdd = Initialized.Add(aTV) && aVTol != tol; //if Vtol == tol => no need to update toler | |
7fd59977 | 1789 | } |
b60e8432 | 1790 | //'Initialized' map is not used anywhere outside this block |
1791 | if (anUpdTol || toAdd) | |
1792 | aShToTol.Bind(V, tol); | |
7fd59977 | 1793 | } |
b60e8432 | 1794 | |
1795 | UpdShTol(aShToTol, IsMutableInput, theReshaper, Standard_True); | |
1796 | } | |
1797 | ||
1798 | //======================================================================= | |
1799 | //function : UpdateTolerances | |
1800 | //purpose : | |
1801 | //======================================================================= | |
1802 | void BRepLib::UpdateTolerances (const TopoDS_Shape& S, const Standard_Boolean verifyFaceTolerance) | |
1803 | { | |
1804 | BRepTools_ReShape aReshaper; | |
1805 | InternalUpdateTolerances(S, verifyFaceTolerance, Standard_True, aReshaper); | |
1806 | } | |
1807 | ||
1808 | //======================================================================= | |
1809 | //function : UpdateTolerances | |
1810 | //purpose : | |
1811 | //======================================================================= | |
1812 | void BRepLib::UpdateTolerances (const TopoDS_Shape& S, BRepTools_ReShape& theReshaper, const Standard_Boolean verifyFaceTolerance ) | |
1813 | { | |
1814 | InternalUpdateTolerances(S, verifyFaceTolerance, Standard_False, theReshaper); | |
7fd59977 | 1815 | } |
1816 | ||
420f79f8 | 1817 | //======================================================================= |
1818 | //function : UpdateInnerTolerances | |
1819 | //purpose : | |
1820 | //======================================================================= | |
1821 | void BRepLib::UpdateInnerTolerances(const TopoDS_Shape& aShape) | |
1822 | { | |
1823 | TopTools_IndexedDataMapOfShapeListOfShape EFmap; | |
1824 | TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, EFmap); | |
1825 | BRep_Builder BB; | |
1826 | for (Standard_Integer i = 1; i <= EFmap.Extent(); i++) | |
1827 | { | |
1828 | TopoDS_Edge anEdge = TopoDS::Edge(EFmap.FindKey(i)); | |
1829 | TopoDS_Vertex V1, V2; | |
1830 | TopExp::Vertices(anEdge, V1, V2); | |
1831 | Standard_Real fpar, lpar; | |
1832 | BRep_Tool::Range(anEdge, fpar, lpar); | |
1833 | Standard_Real TolEdge = BRep_Tool::Tolerance(anEdge); | |
1834 | gp_Pnt Pnt1, Pnt2; | |
1835 | Handle(BRepAdaptor_HCurve) anHCurve = new BRepAdaptor_HCurve(); | |
1836 | anHCurve->ChangeCurve().Initialize(anEdge); | |
1837 | if (!V1.IsNull()) | |
1838 | Pnt1 = BRep_Tool::Pnt(V1); | |
1839 | if (!V2.IsNull()) | |
1840 | Pnt2 = BRep_Tool::Pnt(V2); | |
1841 | ||
1842 | if (!BRep_Tool::Degenerated(anEdge) && | |
1843 | EFmap(i).Extent() > 0) | |
1844 | { | |
1845 | NCollection_Sequence<Handle(Adaptor3d_HCurve)> theRep; | |
1846 | theRep.Append(anHCurve); | |
1847 | TopTools_ListIteratorOfListOfShape itl(EFmap(i)); | |
1848 | for (; itl.More(); itl.Next()) | |
1849 | { | |
1850 | const TopoDS_Face& aFace = TopoDS::Face(itl.Value()); | |
1851 | Handle(BRepAdaptor_HCurve) anHCurvOnSurf = new BRepAdaptor_HCurve(); | |
1852 | anHCurvOnSurf->ChangeCurve().Initialize(anEdge, aFace); | |
1853 | theRep.Append(anHCurvOnSurf); | |
1854 | } | |
1855 | ||
1856 | const Standard_Integer NbSamples = (BRep_Tool::SameParameter(anEdge))? 23 : 2; | |
1857 | Standard_Real delta = (lpar - fpar)/(NbSamples-1); | |
1858 | Standard_Real MaxDist = 0.; | |
1859 | for (Standard_Integer j = 2; j <= theRep.Length(); j++) | |
1860 | { | |
1861 | for (Standard_Integer k = 0; k <= NbSamples; k++) | |
1862 | { | |
1863 | Standard_Real ParamOnCenter = (k == NbSamples)? lpar : | |
1864 | fpar + k*delta; | |
1865 | gp_Pnt Center = theRep(1)->Value(ParamOnCenter); | |
1866 | Standard_Real ParamOnCurve = (BRep_Tool::SameParameter(anEdge))? ParamOnCenter | |
1867 | : ((k == 0)? theRep(j)->FirstParameter() : theRep(j)->LastParameter()); | |
1868 | gp_Pnt aPoint = theRep(j)->Value(ParamOnCurve); | |
1869 | Standard_Real aDist = Center.Distance(aPoint); | |
1870 | //aDist *= 1.1; | |
1871 | aDist += 2.*Epsilon(aDist); | |
1872 | if (aDist > MaxDist) | |
1873 | MaxDist = aDist; | |
1874 | ||
1875 | //Update tolerances of vertices | |
1876 | if (k == 0 && !V1.IsNull()) | |
1877 | { | |
1878 | Standard_Real aDist1 = Pnt1.Distance(aPoint); | |
1879 | aDist1 += 2.*Epsilon(aDist1); | |
1880 | BB.UpdateVertex(V1, aDist1); | |
1881 | } | |
1882 | if (k == NbSamples && !V2.IsNull()) | |
1883 | { | |
1884 | Standard_Real aDist2 = Pnt2.Distance(aPoint); | |
1885 | aDist2 += 2.*Epsilon(aDist2); | |
1886 | BB.UpdateVertex(V2, aDist2); | |
1887 | } | |
1888 | } | |
1889 | } | |
1890 | BB.UpdateEdge(anEdge, MaxDist); | |
1891 | } | |
1892 | TolEdge = BRep_Tool::Tolerance(anEdge); | |
1893 | if (!V1.IsNull()) | |
1894 | { | |
1895 | gp_Pnt End1 = anHCurve->Value(fpar); | |
1896 | Standard_Real dist1 = Pnt1.Distance(End1); | |
1897 | dist1 += 2.*Epsilon(dist1); | |
1898 | BB.UpdateVertex(V1, Max(dist1, TolEdge)); | |
1899 | } | |
1900 | if (!V2.IsNull()) | |
1901 | { | |
1902 | gp_Pnt End2 = anHCurve->Value(lpar); | |
1903 | Standard_Real dist2 = Pnt2.Distance(End2); | |
1904 | dist2 += 2.*Epsilon(dist2); | |
1905 | BB.UpdateVertex(V2, Max(dist2, TolEdge)); | |
1906 | } | |
1907 | } | |
1908 | } | |
1909 | ||
7fd59977 | 1910 | //======================================================================= |
1911 | //function : OrientClosedSolid | |
1912 | //purpose : | |
1913 | //======================================================================= | |
1914 | Standard_Boolean BRepLib::OrientClosedSolid(TopoDS_Solid& solid) | |
1915 | { | |
a86d3ec0 | 1916 | // Set material inside the solid |
7fd59977 | 1917 | BRepClass3d_SolidClassifier where(solid); |
1918 | where.PerformInfinitePoint(Precision::Confusion()); | |
1919 | if (where.State()==TopAbs_IN) { | |
1920 | solid.Reverse(); | |
1921 | } | |
1922 | else if (where.State()==TopAbs_ON || where.State()==TopAbs_UNKNOWN) | |
1923 | return Standard_False; | |
1924 | ||
1925 | return Standard_True; | |
1926 | } | |
712879c8 | 1927 | |
1928 | // Structure for calculation of properties, necessary for decision about continuity | |
1929 | class SurfaceProperties | |
1930 | { | |
1931 | public: | |
1932 | SurfaceProperties(const Handle(Geom_Surface)& theSurface, | |
1933 | const gp_Trsf& theSurfaceTrsf, | |
1934 | const Handle(Geom2d_Curve)& theCurve2D, | |
1935 | const Standard_Boolean theReversed) | |
1936 | : mySurfaceProps(theSurface, 2, Precision::Confusion()), | |
1937 | mySurfaceTrsf(theSurfaceTrsf), | |
1938 | myCurve2d(theCurve2D), | |
1939 | myIsReversed(theReversed) | |
1940 | {} | |
1941 | ||
1942 | // Calculate derivatives on surface related to the point on curve | |
1943 | void Calculate(const Standard_Real theParamOnCurve) | |
1944 | { | |
1945 | gp_Pnt2d aUV; | |
1946 | myCurve2d->D1(theParamOnCurve, aUV, myCurveTangent); | |
1947 | mySurfaceProps.SetParameters(aUV.X(), aUV.Y()); | |
1948 | } | |
1949 | ||
1950 | // Returns point just calculated | |
1951 | gp_Pnt Value() | |
1952 | { return mySurfaceProps.Value().Transformed(mySurfaceTrsf); } | |
1953 | ||
1954 | // Calculate a derivative orthogonal to curve's tangent vector | |
1955 | gp_Vec Derivative() | |
1956 | { | |
1957 | gp_Vec aDeriv; | |
1958 | // direction orthogonal to tangent vector of the curve | |
1959 | gp_Vec2d anOrtho(-myCurveTangent.Y(), myCurveTangent.X()); | |
1960 | Standard_Real aLen = anOrtho.Magnitude(); | |
1961 | if (aLen < Precision::Confusion()) | |
1962 | return aDeriv; | |
1963 | anOrtho /= aLen; | |
1964 | if (myIsReversed) | |
1965 | anOrtho.Reverse(); | |
1966 | ||
1967 | aDeriv.SetLinearForm(anOrtho.X(), mySurfaceProps.D1U(), | |
1968 | anOrtho.Y(), mySurfaceProps.D1V()); | |
1969 | return aDeriv.Transformed(mySurfaceTrsf); | |
1970 | } | |
1971 | ||
1972 | // Calculate principal curvatures, which consist of minimal and maximal normal curvatures and | |
1973 | // the directions on the tangent plane (principal direction) where the extremums are reached | |
1974 | void Curvature(gp_Dir& thePrincipalDir1, Standard_Real& theCurvature1, | |
1975 | gp_Dir& thePrincipalDir2, Standard_Real& theCurvature2) | |
1976 | { | |
1977 | mySurfaceProps.CurvatureDirections(thePrincipalDir1, thePrincipalDir2); | |
1978 | theCurvature1 = mySurfaceProps.MaxCurvature(); | |
1979 | theCurvature2 = mySurfaceProps.MinCurvature(); | |
1980 | if (myIsReversed) | |
1981 | { | |
1982 | theCurvature1 = -theCurvature1; | |
1983 | theCurvature2 = -theCurvature2; | |
1984 | } | |
1985 | thePrincipalDir1.Transform(mySurfaceTrsf); | |
1986 | thePrincipalDir2.Transform(mySurfaceTrsf); | |
1987 | } | |
1988 | ||
1989 | private: | |
1990 | GeomLProp_SLProps mySurfaceProps; // properties calculator | |
1991 | gp_Trsf mySurfaceTrsf; | |
1992 | Handle(Geom2d_Curve) myCurve2d; | |
1993 | Standard_Boolean myIsReversed; // the face based on the surface is reversed | |
1994 | ||
1995 | // tangent vector to Pcurve in UV | |
1996 | gp_Vec2d myCurveTangent; | |
1997 | }; | |
1998 | ||
7fd59977 | 1999 | //======================================================================= |
2000 | //function : tgtfaces | |
0d969553 Y |
2001 | //purpose : check the angle at the border between two squares. |
2002 | // Two shares should have a shared front edge. | |
7fd59977 | 2003 | //======================================================================= |
a0bb29e7 | 2004 | static GeomAbs_Shape tgtfaces(const TopoDS_Edge& Ed, |
712879c8 | 2005 | const TopoDS_Face& F1, |
2006 | const TopoDS_Face& F2, | |
2007 | const Standard_Real theAngleTol) | |
7fd59977 | 2008 | { |
712879c8 | 2009 | Standard_Boolean isSeam = F1.IsEqual(F2); |
2010 | ||
2011 | TopoDS_Edge E = Ed; | |
2012 | ||
4f933493 | 2013 | // Check if pcurves exist on both faces of edge |
2014 | Standard_Real aFirst,aLast; | |
712879c8 | 2015 | E.Orientation(TopAbs_FORWARD); |
2016 | Handle(Geom2d_Curve) aCurve1 = BRep_Tool::CurveOnSurface(E, F1, aFirst, aLast); | |
2017 | if(aCurve1.IsNull()) | |
a0bb29e7 | 2018 | return GeomAbs_C0; |
712879c8 | 2019 | |
2020 | if (isSeam) | |
2021 | E.Orientation(TopAbs_REVERSED); | |
2022 | Handle(Geom2d_Curve) aCurve2 = BRep_Tool::CurveOnSurface(E, F2, aFirst, aLast); | |
2023 | if(aCurve2.IsNull()) | |
a0bb29e7 | 2024 | return GeomAbs_C0; |
712879c8 | 2025 | |
2026 | TopLoc_Location aLoc1, aLoc2; | |
2027 | Handle(Geom_Surface) aSurface1 = BRep_Tool::Surface(F1, aLoc1); | |
2028 | const gp_Trsf& aSurf1Trsf = aLoc1.Transformation(); | |
2029 | Handle(Geom_Surface) aSurface2 = BRep_Tool::Surface(F2, aLoc2); | |
2030 | const gp_Trsf& aSurf2Trsf = aLoc2.Transformation(); | |
2031 | ||
2032 | if (aSurface1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) | |
2033 | aSurface1 = Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface1)->BasisSurface(); | |
2034 | if (aSurface2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) | |
2035 | aSurface2 = Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface2)->BasisSurface(); | |
2036 | ||
a0bb29e7 | 2037 | // seam edge on elementary surface is always CN |
2038 | Standard_Boolean isElementary = | |
712879c8 | 2039 | (aSurface1->IsKind(STANDARD_TYPE(Geom_ElementarySurface)) && |
2040 | aSurface2->IsKind(STANDARD_TYPE(Geom_ElementarySurface))); | |
2041 | if (isSeam && isElementary) | |
a0bb29e7 | 2042 | { |
2043 | return GeomAbs_CN; | |
2044 | } | |
712879c8 | 2045 | |
2046 | SurfaceProperties aSP1(aSurface1, aSurf1Trsf, aCurve1, F1.Orientation() == TopAbs_REVERSED); | |
2047 | SurfaceProperties aSP2(aSurface2, aSurf2Trsf, aCurve2, F2.Orientation() == TopAbs_REVERSED); | |
2048 | ||
2049 | Standard_Real f, l, eps; | |
7fd59977 | 2050 | BRep_Tool::Range(E,f,l); |
2051 | Extrema_LocateExtPC ext; | |
712879c8 | 2052 | Handle(BRepAdaptor_HCurve) aHC2; |
a86d3ec0 | 2053 | |
7fd59977 | 2054 | eps = (l - f)/100.; |
0d969553 Y |
2055 | f += eps; // to avoid calculations on |
2056 | l -= eps; // points of pointed squares. | |
712879c8 | 2057 | |
2058 | const Standard_Real anAngleTol2 = theAngleTol * theAngleTol; | |
2059 | ||
2060 | gp_Vec aDer1, aDer2; | |
2061 | gp_Vec aNorm1; | |
2062 | Standard_Real aSqLen1, aSqLen2; | |
2063 | gp_Dir aCrvDir1[2], aCrvDir2[2]; | |
2064 | Standard_Real aCrvLen1[2], aCrvLen2[2]; | |
2065 | ||
a0bb29e7 | 2066 | GeomAbs_Shape aCont = (isElementary ? GeomAbs_CN : GeomAbs_C2); |
712879c8 | 2067 | GeomAbs_Shape aCurCont; |
2068 | Standard_Real u; | |
2069 | for (Standard_Integer i = 0; i <= 20 && aCont > GeomAbs_C0; i++) | |
a0bb29e7 | 2070 | { |
0d969553 | 2071 | // First suppose that this is sameParameter |
7fd59977 | 2072 | u = f + (l-f)*i/20; |
a0bb29e7 | 2073 | |
712879c8 | 2074 | // Check conditions for G1 and C1 continuity: |
2075 | // * calculate a derivative in tangent plane of each surface | |
2076 | // orthogonal to curve's tangent vector | |
2077 | // * continuity is C1 if the vectors are equal | |
2078 | // * continuity is G1 if the vectors are just parallel | |
2079 | aCurCont = GeomAbs_C0; | |
2080 | ||
2081 | aSP1.Calculate(u); | |
2082 | aSP2.Calculate(u); | |
2083 | ||
2084 | aDer1 = aSP1.Derivative(); | |
2085 | aSqLen1 = aDer1.SquareMagnitude(); | |
2086 | aDer2 = aSP2.Derivative(); | |
2087 | aSqLen2 = aDer2.SquareMagnitude(); | |
2088 | Standard_Boolean isSmoothSuspect = (aDer1.CrossSquareMagnitude(aDer2) <= anAngleTol2 * aSqLen1 * aSqLen2); | |
2089 | if (!isSmoothSuspect) | |
a0bb29e7 | 2090 | { |
712879c8 | 2091 | // Refine by projection |
2092 | if (aHC2.IsNull()) | |
2093 | { | |
2094 | // adaptor for pcurve on the second surface | |
2095 | aHC2 = new BRepAdaptor_HCurve(BRepAdaptor_Curve(E, F2)); | |
2096 | ext.Initialize(aHC2->Curve(), f, l, Precision::PConfusion()); | |
2097 | } | |
2098 | ext.Perform(aSP1.Value(), u); | |
2099 | if (ext.IsDone() && ext.IsMin()) | |
2100 | { | |
2101 | const Extrema_POnCurv& poc = ext.Point(); | |
2102 | aSP2.Calculate(poc.Parameter()); | |
2103 | aDer2 = aSP2.Derivative(); | |
2104 | aSqLen2 = aDer2.SquareMagnitude(); | |
2105 | } | |
2106 | isSmoothSuspect = (aDer1.CrossSquareMagnitude(aDer2) <= anAngleTol2 * aSqLen1 * aSqLen2); | |
a0bb29e7 | 2107 | } |
712879c8 | 2108 | if (isSmoothSuspect) |
2109 | { | |
2110 | aCurCont = GeomAbs_G1; | |
2111 | if (Abs(Sqrt(aSqLen1) - Sqrt(aSqLen2)) < Precision::Confusion() && | |
2112 | aDer1.Dot(aDer2) > Precision::SquareConfusion()) // <= check vectors are codirectional | |
2113 | aCurCont = GeomAbs_C1; | |
2114 | } | |
2115 | else | |
2116 | return GeomAbs_C0; | |
2117 | ||
2118 | if (aCont < GeomAbs_G2) | |
2119 | continue; // no need further processing, because maximal continuity is less than G2 | |
2120 | ||
2121 | // Check conditions for G2 and C2 continuity: | |
2122 | // * calculate principal curvatures on each surface | |
2123 | // * continuity is C2 if directions of principal curvatures are equal on differenct surfaces | |
2124 | // * continuity is G2 if directions of principal curvatures are just parallel | |
2125 | // and values of curvatures are the same | |
2126 | aSP1.Curvature(aCrvDir1[0], aCrvLen1[0], aCrvDir1[1], aCrvLen1[1]); | |
2127 | aSP2.Curvature(aCrvDir2[0], aCrvLen2[0], aCrvDir2[1], aCrvLen2[1]); | |
2128 | for (Standard_Integer aStep = 0; aStep <= 1; ++aStep) | |
a0bb29e7 | 2129 | { |
712879c8 | 2130 | if (aCrvDir1[0].XYZ().CrossSquareMagnitude(aCrvDir2[aStep].XYZ()) <= Precision::SquareConfusion() && |
2131 | Abs(aCrvLen1[0] - aCrvLen2[aStep]) < Precision::Confusion() && | |
2132 | aCrvDir1[1].XYZ().CrossSquareMagnitude(aCrvDir2[1 - aStep].XYZ()) <= Precision::SquareConfusion() && | |
2133 | Abs(aCrvLen1[1] - aCrvLen2[1 - aStep]) < Precision::Confusion()) | |
2134 | { | |
2135 | if (aCurCont == GeomAbs_C1 && | |
2136 | aCrvDir1[0].Dot(aCrvDir2[aStep]) > Precision::Confusion() && | |
2137 | aCrvDir1[1].Dot(aCrvDir2[1 - aStep]) > Precision::Confusion()) | |
2138 | aCurCont = GeomAbs_C2; | |
2139 | else | |
2140 | aCurCont = GeomAbs_G2; | |
2141 | break; | |
7fd59977 | 2142 | } |
2143 | } | |
a86d3ec0 | 2144 | |
712879c8 | 2145 | if (aCurCont < aCont) |
2146 | aCont = aCurCont; | |
2147 | } | |
2148 | ||
2149 | // according to the list of supported elementary surfaces, | |
2150 | // if the continuity is C2, than it is totally CN | |
2151 | if (isElementary && aCont == GeomAbs_C2) | |
2152 | aCont = GeomAbs_CN; | |
a0bb29e7 | 2153 | return aCont; |
7fd59977 | 2154 | } |
2155 | ||
7fd59977 | 2156 | //======================================================================= |
2157 | // function : EncodeRegularity | |
712879c8 | 2158 | // purpose : Code the regularities on all edges of the shape, boundary of |
0d969553 | 2159 | // two faces that do not have it. |
712879c8 | 2160 | // Takes into account that compound may consists of same solid |
2161 | // placed with different transformations | |
7fd59977 | 2162 | //======================================================================= |
712879c8 | 2163 | static void EncodeRegularity(const TopoDS_Shape& theShape, |
2164 | const Standard_Real theTolAng, | |
2165 | TopTools_MapOfShape& theMap, | |
2166 | const TopTools_MapOfShape& theEdgesToEncode = TopTools_MapOfShape()) | |
7fd59977 | 2167 | { |
712879c8 | 2168 | TopoDS_Shape aShape = theShape; |
2169 | TopLoc_Location aNullLoc; | |
2170 | aShape.Location(aNullLoc); // nullify location | |
2171 | if (!theMap.Add(aShape)) | |
2172 | return; // do not need to process shape twice | |
2173 | ||
2174 | if (aShape.ShapeType() == TopAbs_COMPOUND || | |
2175 | aShape.ShapeType() == TopAbs_COMPSOLID) | |
2176 | { | |
2177 | for (TopoDS_Iterator it(aShape); it.More(); it.Next()) | |
2178 | EncodeRegularity(it.Value(), theTolAng, theMap, theEdgesToEncode); | |
2179 | return; | |
2180 | } | |
2181 | ||
2182 | try { | |
2183 | OCC_CATCH_SIGNALS | |
2184 | ||
2185 | TopTools_IndexedDataMapOfShapeListOfShape M; | |
2186 | TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, M); | |
2187 | TopTools_ListIteratorOfListOfShape It; | |
2188 | TopExp_Explorer Ex; | |
2189 | TopoDS_Face F1,F2; | |
2190 | Standard_Boolean found; | |
2191 | for (Standard_Integer i = 1; i <= M.Extent(); i++){ | |
2192 | TopoDS_Edge E = TopoDS::Edge(M.FindKey(i)); | |
2193 | if (!theEdgesToEncode.IsEmpty()) | |
2194 | { | |
2195 | // process only the edges from the list to update their regularity | |
2196 | TopoDS_Shape aPureEdge = E.Located(aNullLoc); | |
2197 | aPureEdge.Orientation(TopAbs_FORWARD); | |
2198 | if (!theEdgesToEncode.Contains(aPureEdge)) | |
2199 | continue; | |
7fd59977 | 2200 | } |
041bfce9 | 2201 | |
712879c8 | 2202 | found = Standard_False; |
2203 | F1.Nullify(); | |
2204 | for (It.Initialize(M.FindFromIndex(i)); It.More() && !found; It.Next()){ | |
2205 | if (F1.IsNull()) { F1 = TopoDS::Face(It.Value()); } | |
2206 | else { | |
2207 | const TopoDS_Face& aTmpF2 = TopoDS::Face(It.Value()); | |
2208 | if (!F1.IsSame(aTmpF2)){ | |
2209 | found = Standard_True; | |
2210 | F2 = aTmpF2; | |
2211 | } | |
041bfce9 | 2212 | } |
712879c8 | 2213 | } |
2214 | if (!found && !F1.IsNull()){//is it a sewing edge? | |
2215 | TopAbs_Orientation orE = E.Orientation(); | |
2216 | TopoDS_Edge curE; | |
2217 | for (Ex.Init(F1, TopAbs_EDGE); Ex.More() && !found; Ex.Next()){ | |
2218 | curE = TopoDS::Edge(Ex.Current()); | |
2219 | if (E.IsSame(curE) && orE != curE.Orientation()) { | |
2220 | found = Standard_True; | |
2221 | F2 = F1; | |
2222 | } | |
041bfce9 | 2223 | } |
7fd59977 | 2224 | } |
712879c8 | 2225 | if (found) |
2226 | BRepLib::EncodeRegularity(E, F1, F2, theTolAng); | |
7fd59977 | 2227 | } |
2228 | } | |
9775fa61 | 2229 | catch (Standard_Failure const& anException) { |
712879c8 | 2230 | #ifdef OCCT_DEBUG |
2231 | cout << "Warning: Exception in BRepLib::EncodeRegularity(): "; | |
9775fa61 | 2232 | anException.Print(cout); |
712879c8 | 2233 | cout << endl; |
2234 | #endif | |
9775fa61 | 2235 | (void)anException; |
712879c8 | 2236 | } |
2237 | } | |
2238 | ||
2239 | //======================================================================= | |
2240 | // function : EncodeRegularity | |
2241 | // purpose : code the regularities on all edges of the shape, boundary of | |
2242 | // two faces that do not have it. | |
2243 | //======================================================================= | |
2244 | ||
2245 | void BRepLib::EncodeRegularity(const TopoDS_Shape& S, | |
2246 | const Standard_Real TolAng) | |
2247 | { | |
2248 | TopTools_MapOfShape aMap; | |
2249 | ::EncodeRegularity(S, TolAng, aMap); | |
2250 | } | |
2251 | ||
2252 | //======================================================================= | |
2253 | // function : EncodeRegularity | |
2254 | // purpose : code the regularities on all edges in the list that do not | |
2255 | // have it, and which are boundary of two faces on the shape. | |
2256 | //======================================================================= | |
2257 | ||
2258 | void BRepLib::EncodeRegularity(const TopoDS_Shape& S, | |
2259 | const TopTools_ListOfShape& LE, | |
2260 | const Standard_Real TolAng) | |
2261 | { | |
2262 | // Collect edges without location and orientation | |
2263 | TopTools_MapOfShape aPureEdges; | |
2264 | TopLoc_Location aNullLoc; | |
2265 | TopTools_ListIteratorOfListOfShape anEdgeIt(LE); | |
2266 | for (; anEdgeIt.More(); anEdgeIt.Next()) | |
2267 | { | |
2268 | TopoDS_Shape anEdge = anEdgeIt.Value(); | |
2269 | anEdge.Location(aNullLoc); | |
2270 | anEdge.Orientation(TopAbs_FORWARD); | |
2271 | aPureEdges.Add(anEdge); | |
2272 | } | |
2273 | ||
2274 | TopTools_MapOfShape aMap; | |
2275 | ::EncodeRegularity(S, TolAng, aMap, aPureEdges); | |
7fd59977 | 2276 | } |
2277 | ||
2278 | //======================================================================= | |
2279 | // function : EncodeRegularity | |
712879c8 | 2280 | // purpose : code the regularity between 2 faces connected by edge |
7fd59977 | 2281 | //======================================================================= |
2282 | ||
2283 | void BRepLib::EncodeRegularity(TopoDS_Edge& E, | |
a86d3ec0 | 2284 | const TopoDS_Face& F1, |
2285 | const TopoDS_Face& F2, | |
2286 | const Standard_Real TolAng) | |
7fd59977 | 2287 | { |
2288 | BRep_Builder B; | |
2289 | if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0){ | |
041bfce9 | 2290 | try { |
712879c8 | 2291 | GeomAbs_Shape aCont = tgtfaces(E, F1, F2, TolAng); |
a0bb29e7 | 2292 | B.Continuity(E,F1,F2,aCont); |
2293 | ||
041bfce9 | 2294 | } |
2295 | catch(Standard_Failure) | |
2296 | { | |
712879c8 | 2297 | #ifdef OCCT_DEBUG |
2298 | cout << "Failure: Exception in BRepLib::EncodeRegularity" << endl; | |
2299 | #endif | |
041bfce9 | 2300 | } |
a86d3ec0 | 2301 | } |
7fd59977 | 2302 | } |
2303 | ||
7693827d | 2304 | //======================================================================= |
2305 | // function : EnsureNormalConsistency | |
2306 | // purpose : Corrects the normals in Poly_Triangulation of faces. | |
2307 | // Returns TRUE if any correction is done. | |
2308 | //======================================================================= | |
2309 | Standard_Boolean BRepLib:: | |
2310 | EnsureNormalConsistency(const TopoDS_Shape& theShape, | |
2311 | const Standard_Real theAngTol, | |
2312 | const Standard_Boolean theForceComputeNormals) | |
2313 | { | |
2314 | const Standard_Real aThresDot = cos(theAngTol); | |
2315 | ||
2316 | Standard_Boolean aRetVal = Standard_False, isNormalsFound = Standard_False; | |
2317 | ||
2318 | // compute normals if they are absent | |
2319 | TopExp_Explorer anExpFace(theShape,TopAbs_FACE); | |
2320 | for (; anExpFace.More(); anExpFace.Next()) | |
2321 | { | |
2322 | const TopoDS_Face& aFace = TopoDS::Face(anExpFace.Current()); | |
2323 | const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); | |
2324 | if(aSurf.IsNull()) | |
2325 | continue; | |
2326 | TopLoc_Location aLoc; | |
2327 | const Handle(Poly_Triangulation)& aPT = BRep_Tool::Triangulation(aFace, aLoc); | |
2328 | if(aPT.IsNull()) | |
2329 | continue; | |
2330 | if (!theForceComputeNormals && aPT->HasNormals()) | |
2331 | { | |
2332 | isNormalsFound = Standard_True; | |
2333 | continue; | |
2334 | } | |
2335 | ||
2336 | GeomLProp_SLProps aSLP(aSurf, 2, Precision::Confusion()); | |
2337 | const Standard_Integer anArrDim = 3*aPT->NbNodes(); | |
2338 | Handle(TShort_HArray1OfShortReal) aNormArr = new TShort_HArray1OfShortReal(1, anArrDim); | |
2339 | Standard_Integer anNormInd = aNormArr->Lower(); | |
2340 | for(Standard_Integer i = aPT->UVNodes().Lower(); i <= aPT->UVNodes().Upper(); i++) | |
2341 | { | |
2342 | const gp_Pnt2d &aP2d = aPT->UVNodes().Value(i); | |
2343 | aSLP.SetParameters(aP2d.X(), aP2d.Y()); | |
2344 | ||
2345 | gp_XYZ aNorm(0.,0.,0.); | |
2346 | if(!aSLP.IsNormalDefined()) | |
2347 | { | |
2348 | #ifdef OCCT_DEBUG | |
2349 | cout << "BRepLib::EnsureNormalConsistency(): Cannot find normal!" << endl; | |
2350 | #endif | |
2351 | } | |
2352 | else | |
2353 | { | |
2354 | aNorm = aSLP.Normal().XYZ(); | |
2355 | if (aFace.Orientation() == TopAbs_REVERSED) | |
2356 | aNorm.Reverse(); | |
2357 | } | |
2358 | aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.X()); | |
2359 | aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.Y()); | |
2360 | aNormArr->ChangeValue(anNormInd++) = static_cast<Standard_ShortReal>(aNorm.Z()); | |
2361 | } | |
2362 | ||
2363 | aRetVal = Standard_True; | |
2364 | isNormalsFound = Standard_True; | |
2365 | aPT->SetNormals(aNormArr); | |
2366 | } | |
2367 | ||
2368 | if(!isNormalsFound) | |
2369 | { | |
2370 | return aRetVal; | |
2371 | } | |
2372 | ||
2373 | // loop by edges | |
2374 | TopTools_IndexedDataMapOfShapeListOfShape aMapEF; | |
2375 | TopExp::MapShapesAndAncestors(theShape,TopAbs_EDGE,TopAbs_FACE,aMapEF); | |
2376 | for(Standard_Integer anInd = 1; anInd <= aMapEF.Extent(); anInd++) | |
2377 | { | |
2378 | const TopoDS_Edge& anEdg = TopoDS::Edge(aMapEF.FindKey(anInd)); | |
2379 | const TopTools_ListOfShape& anEdgList = aMapEF.FindFromIndex(anInd); | |
2380 | if (anEdgList.Extent() != 2) | |
2381 | continue; | |
2382 | TopTools_ListIteratorOfListOfShape anItF(anEdgList); | |
2383 | const TopoDS_Face aFace1 = TopoDS::Face(anItF.Value()); | |
2384 | anItF.Next(); | |
2385 | const TopoDS_Face aFace2 = TopoDS::Face(anItF.Value()); | |
2386 | TopLoc_Location aLoc1, aLoc2; | |
2387 | const Handle(Poly_Triangulation)& aPT1 = BRep_Tool::Triangulation(aFace1, aLoc1); | |
2388 | const Handle(Poly_Triangulation)& aPT2 = BRep_Tool::Triangulation(aFace2, aLoc2); | |
2389 | ||
2390 | if(aPT1.IsNull() || aPT2.IsNull()) | |
2391 | continue; | |
2392 | ||
2393 | if(!aPT1->HasNormals() || !aPT2->HasNormals()) | |
2394 | continue; | |
2395 | ||
2396 | const Handle(Poly_PolygonOnTriangulation)& aPTEF1 = | |
2397 | BRep_Tool::PolygonOnTriangulation(anEdg, aPT1, aLoc1); | |
2398 | const Handle(Poly_PolygonOnTriangulation)& aPTEF2 = | |
2399 | BRep_Tool::PolygonOnTriangulation(anEdg, aPT2, aLoc2); | |
2400 | ||
2401 | TShort_Array1OfShortReal& aNormArr1 = aPT1->ChangeNormals(); | |
2402 | TShort_Array1OfShortReal& aNormArr2 = aPT2->ChangeNormals(); | |
2403 | ||
9d671cd1 | 2404 | if (aPTEF1->Nodes().Lower() != aPTEF2->Nodes().Lower() || |
2405 | aPTEF1->Nodes().Upper() != aPTEF2->Nodes().Upper()) | |
2406 | continue; | |
2407 | ||
7693827d | 2408 | for(Standard_Integer anEdgNode = aPTEF1->Nodes().Lower(); |
2409 | anEdgNode <= aPTEF1->Nodes().Upper(); anEdgNode++) | |
2410 | { | |
2411 | //Number of node | |
2412 | const Standard_Integer aFNodF1 = aPTEF1->Nodes().Value(anEdgNode); | |
2413 | const Standard_Integer aFNodF2 = aPTEF2->Nodes().Value(anEdgNode); | |
2414 | ||
2415 | const Standard_Integer aFNorm1FirstIndex = aNormArr1.Lower() + 3* | |
2416 | (aFNodF1 - aPT1->Nodes().Lower()); | |
2417 | const Standard_Integer aFNorm2FirstIndex = aNormArr2.Lower() + 3* | |
2418 | (aFNodF2 - aPT2->Nodes().Lower()); | |
2419 | ||
2420 | gp_XYZ aNorm1(aNormArr1.Value(aFNorm1FirstIndex), | |
2421 | aNormArr1.Value(aFNorm1FirstIndex+1), | |
2422 | aNormArr1.Value(aFNorm1FirstIndex+2)); | |
2423 | gp_XYZ aNorm2(aNormArr2.Value(aFNorm2FirstIndex), | |
2424 | aNormArr2.Value(aFNorm2FirstIndex+1), | |
2425 | aNormArr2.Value(aFNorm2FirstIndex+2)); | |
2426 | const Standard_Real aDot = aNorm1 * aNorm2; | |
2427 | ||
2428 | if(aDot > aThresDot) | |
2429 | { | |
2430 | gp_XYZ aNewNorm = (aNorm1 + aNorm2).Normalized(); | |
2431 | aNormArr1.ChangeValue(aFNorm1FirstIndex) = | |
2432 | aNormArr2.ChangeValue(aFNorm2FirstIndex) = | |
2433 | static_cast<Standard_ShortReal>(aNewNorm.X()); | |
2434 | aNormArr1.ChangeValue(aFNorm1FirstIndex+1) = | |
2435 | aNormArr2.ChangeValue(aFNorm2FirstIndex+1) = | |
2436 | static_cast<Standard_ShortReal>(aNewNorm.Y()); | |
2437 | aNormArr1.ChangeValue(aFNorm1FirstIndex+2) = | |
2438 | aNormArr2.ChangeValue(aFNorm2FirstIndex+2) = | |
2439 | static_cast<Standard_ShortReal>(aNewNorm.Z()); | |
2440 | aRetVal = Standard_True; | |
2441 | } | |
2442 | } | |
2443 | } | |
2444 | ||
2445 | return aRetVal; | |
2446 | } | |
2447 | ||
7fd59977 | 2448 | //======================================================================= |
2449 | //function : SortFaces | |
2450 | //purpose : | |
2451 | //======================================================================= | |
2452 | ||
2453 | void BRepLib::SortFaces (const TopoDS_Shape& Sh, | |
a86d3ec0 | 2454 | TopTools_ListOfShape& LF) |
7fd59977 | 2455 | { |
2456 | LF.Clear(); | |
2457 | TopTools_ListOfShape LTri,LPlan,LCyl,LCon,LSphere,LTor,LOther; | |
2458 | TopExp_Explorer exp(Sh,TopAbs_FACE); | |
2459 | TopLoc_Location l; | |
2460 | Handle(Geom_Surface) S; | |
2461 | ||
2462 | for (; exp.More(); exp.Next()) { | |
2463 | const TopoDS_Face& F = TopoDS::Face(exp.Current()); | |
2464 | S = BRep_Tool::Surface(F, l); | |
2465 | if (!S.IsNull()) { | |
2466 | if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { | |
c5f3a425 | 2467 | S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface(); |
7fd59977 | 2468 | } |
2469 | GeomAdaptor_Surface AS(S); | |
2470 | switch (AS.GetType()) { | |
2471 | case GeomAbs_Plane: | |
a86d3ec0 | 2472 | { |
2473 | LPlan.Append(F); | |
2474 | break; | |
2475 | } | |
7fd59977 | 2476 | case GeomAbs_Cylinder: |
a86d3ec0 | 2477 | { |
2478 | LCyl.Append(F); | |
2479 | break; | |
2480 | } | |
7fd59977 | 2481 | case GeomAbs_Cone: |
a86d3ec0 | 2482 | { |
2483 | LCon.Append(F); | |
2484 | break; | |
2485 | } | |
7fd59977 | 2486 | case GeomAbs_Sphere: |
a86d3ec0 | 2487 | { |
2488 | LSphere.Append(F); | |
2489 | break; | |
2490 | } | |
7fd59977 | 2491 | case GeomAbs_Torus: |
a86d3ec0 | 2492 | { |
2493 | LTor.Append(F); | |
2494 | break; | |
2495 | } | |
7fd59977 | 2496 | default: |
a86d3ec0 | 2497 | LOther.Append(F); |
7fd59977 | 2498 | } |
2499 | } | |
2500 | else LTri.Append(F); | |
2501 | } | |
2502 | LF.Append(LPlan); LF.Append(LCyl ); LF.Append(LCon); LF.Append(LSphere); | |
2503 | LF.Append(LTor ); LF.Append(LOther); LF.Append(LTri); | |
2504 | } | |
2505 | ||
2506 | //======================================================================= | |
2507 | //function : ReverseSortFaces | |
2508 | //purpose : | |
2509 | //======================================================================= | |
2510 | ||
2511 | void BRepLib::ReverseSortFaces (const TopoDS_Shape& Sh, | |
a86d3ec0 | 2512 | TopTools_ListOfShape& LF) |
7fd59977 | 2513 | { |
2514 | LF.Clear(); | |
e1c1b6b9 | 2515 | // Use the allocator of the result LF for intermediate results |
2516 | TopTools_ListOfShape LTri(LF.Allocator()), LPlan(LF.Allocator()), | |
2517 | LCyl(LF.Allocator()), LCon(LF.Allocator()), LSphere(LF.Allocator()), | |
2518 | LTor(LF.Allocator()), LOther(LF.Allocator()); | |
7fd59977 | 2519 | TopExp_Explorer exp(Sh,TopAbs_FACE); |
2520 | TopLoc_Location l; | |
a86d3ec0 | 2521 | |
7fd59977 | 2522 | for (; exp.More(); exp.Next()) { |
2523 | const TopoDS_Face& F = TopoDS::Face(exp.Current()); | |
e1c1b6b9 | 2524 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(F, l); |
7fd59977 | 2525 | if (!S.IsNull()) { |
7fd59977 | 2526 | GeomAdaptor_Surface AS(S); |
2527 | switch (AS.GetType()) { | |
2528 | case GeomAbs_Plane: | |
a86d3ec0 | 2529 | { |
2530 | LPlan.Append(F); | |
2531 | break; | |
2532 | } | |
7fd59977 | 2533 | case GeomAbs_Cylinder: |
a86d3ec0 | 2534 | { |
2535 | LCyl.Append(F); | |
2536 | break; | |
2537 | } | |
7fd59977 | 2538 | case GeomAbs_Cone: |
a86d3ec0 | 2539 | { |
2540 | LCon.Append(F); | |
2541 | break; | |
2542 | } | |
7fd59977 | 2543 | case GeomAbs_Sphere: |
a86d3ec0 | 2544 | { |
2545 | LSphere.Append(F); | |
2546 | break; | |
2547 | } | |
7fd59977 | 2548 | case GeomAbs_Torus: |
a86d3ec0 | 2549 | { |
2550 | LTor.Append(F); | |
2551 | break; | |
2552 | } | |
7fd59977 | 2553 | default: |
a86d3ec0 | 2554 | LOther.Append(F); |
7fd59977 | 2555 | } |
2556 | } | |
2557 | else LTri.Append(F); | |
2558 | } | |
2559 | LF.Append(LTri); LF.Append(LOther); LF.Append(LTor ); LF.Append(LSphere); | |
2560 | LF.Append(LCon); LF.Append(LCyl ); LF.Append(LPlan); | |
7fd59977 | 2561 | |
a86d3ec0 | 2562 | } |
7fd59977 | 2563 | |
07ef8bdf | 2564 | //======================================================================= |
2565 | // function: BoundingVertex | |
2566 | // purpose : | |
2567 | //======================================================================= | |
2568 | void BRepLib::BoundingVertex(const NCollection_List<TopoDS_Shape>& theLV, | |
2569 | gp_Pnt& theNewCenter, Standard_Real& theNewTol) | |
2570 | { | |
2571 | Standard_Integer aNb; | |
2572 | // | |
2573 | aNb=theLV.Extent(); | |
2574 | if (aNb < 2) { | |
2575 | return; | |
2576 | } | |
2577 | // | |
2578 | else if (aNb==2) { | |
2579 | Standard_Integer m, n; | |
2580 | Standard_Real aR[2], dR, aD, aEps; | |
2581 | TopoDS_Vertex aV[2]; | |
2582 | gp_Pnt aP[2]; | |
2583 | // | |
2584 | aEps=RealEpsilon(); | |
2585 | for (m=0; m<aNb; ++m) { | |
2586 | aV[m]=(!m)? | |
2587 | *((TopoDS_Vertex*)(&theLV.First())): | |
2588 | *((TopoDS_Vertex*)(&theLV.Last())); | |
2589 | aP[m]=BRep_Tool::Pnt(aV[m]); | |
2590 | aR[m]=BRep_Tool::Tolerance(aV[m]); | |
2591 | } | |
2592 | // | |
2593 | m=0; // max R | |
2594 | n=1; // min R | |
2595 | if (aR[0]<aR[1]) { | |
2596 | m=1; | |
2597 | n=0; | |
2598 | } | |
2599 | // | |
2600 | dR=aR[m]-aR[n]; // dR >= 0. | |
2601 | gp_Vec aVD(aP[m], aP[n]); | |
2602 | aD=aVD.Magnitude(); | |
2603 | // | |
2604 | if (aD<=dR || aD<aEps) { | |
2605 | theNewCenter = aP[m]; | |
2606 | theNewTol = aR[m]; | |
2607 | } | |
2608 | else { | |
2609 | Standard_Real aRr; | |
2610 | gp_XYZ aXYZr; | |
2611 | gp_Pnt aPr; | |
2612 | // | |
2613 | aRr=0.5*(aR[m]+aR[n]+aD); | |
2614 | aXYZr=0.5*(aP[m].XYZ()+aP[n].XYZ()-aVD.XYZ()*(dR/aD)); | |
2615 | aPr.SetXYZ(aXYZr); | |
2616 | // | |
2617 | theNewCenter = aPr; | |
2618 | theNewTol = aRr; | |
2619 | //aBB.MakeVertex (aVnew, aPr, aRr); | |
2620 | } | |
2621 | return; | |
2622 | }// else if (aNb==2) { | |
2623 | // | |
2624 | else { // if (aNb>2) | |
2625 | // compute the point | |
2626 | // | |
2627 | // issue 0027540 - sum of doubles may depend on the order | |
2628 | // of addition, thus sort the coordinates for stable result | |
2629 | Standard_Integer i; | |
2630 | NCollection_Array1<gp_Pnt> aPoints(0, aNb-1); | |
2631 | NCollection_List<TopoDS_Edge>::Iterator aIt(theLV); | |
2632 | for (i = 0; aIt.More(); aIt.Next(), ++i) { | |
2633 | const TopoDS_Vertex& aVi = *((TopoDS_Vertex*)(&aIt.Value())); | |
2634 | gp_Pnt aPi = BRep_Tool::Pnt(aVi); | |
2635 | aPoints(i) = aPi; | |
2636 | } | |
2637 | // | |
2638 | std::sort(aPoints.begin(), aPoints.end(), BRepLib_ComparePoints()); | |
2639 | // | |
2640 | gp_XYZ aXYZ(0., 0., 0.); | |
2641 | for (i = 0; i < aNb; ++i) { | |
2642 | aXYZ += aPoints(i).XYZ(); | |
2643 | } | |
2644 | aXYZ.Divide((Standard_Real)aNb); | |
2645 | // | |
2646 | gp_Pnt aP(aXYZ); | |
2647 | // | |
2648 | // compute the tolerance for the new vertex | |
2649 | Standard_Real aTi, aDi, aDmax; | |
2650 | // | |
2651 | aDmax=-1.; | |
2652 | aIt.Initialize(theLV); | |
2653 | for (; aIt.More(); aIt.Next()) { | |
2654 | TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value())); | |
2655 | gp_Pnt aPi=BRep_Tool::Pnt(aVi); | |
2656 | aTi=BRep_Tool::Tolerance(aVi); | |
2657 | aDi=aP.SquareDistance(aPi); | |
2658 | aDi=sqrt(aDi); | |
2659 | aDi=aDi+aTi; | |
2660 | if (aDi > aDmax) { | |
2661 | aDmax=aDi; | |
2662 | } | |
2663 | } | |
2664 | // | |
2665 | theNewCenter = aP; | |
2666 | theNewTol = aDmax; | |
2667 | } | |
2668 | } | |
d9ca2e0c | 2669 | |
2670 | //======================================================================= | |
2671 | //function : ExtendFace | |
2672 | //purpose : | |
2673 | //======================================================================= | |
2674 | void BRepLib::ExtendFace(const TopoDS_Face& theF, | |
2675 | const Standard_Real theExtVal, | |
2676 | const Standard_Boolean theExtUMin, | |
2677 | const Standard_Boolean theExtUMax, | |
2678 | const Standard_Boolean theExtVMin, | |
2679 | const Standard_Boolean theExtVMax, | |
2680 | TopoDS_Face& theFExtended) | |
2681 | { | |
2682 | // Get face bounds | |
2683 | BRepAdaptor_Surface aBAS(theF); | |
2684 | Standard_Real aFUMin = aBAS.FirstUParameter(), | |
2685 | aFUMax = aBAS.LastUParameter(), | |
2686 | aFVMin = aBAS.FirstVParameter(), | |
2687 | aFVMax = aBAS.LastVParameter(); | |
2688 | const Standard_Real aTol = BRep_Tool::Tolerance(theF); | |
2689 | ||
2690 | // Surface to build the face | |
2691 | Handle(Geom_Surface) aS; | |
2692 | ||
2693 | const GeomAbs_SurfaceType aType = aBAS.GetType(); | |
2694 | // treat analytical surfaces first | |
2695 | if (aType == GeomAbs_Plane || | |
2696 | aType == GeomAbs_Sphere || | |
2697 | aType == GeomAbs_Cylinder || | |
2698 | aType == GeomAbs_Torus || | |
2699 | aType == GeomAbs_Cone) | |
2700 | { | |
2701 | // Get basis transformed basis surface | |
2702 | Handle(Geom_Surface) aSurf = Handle(Geom_Surface):: | |
2703 | DownCast(aBAS.Surface().Surface()->Transformed(aBAS.Trsf())); | |
2704 | ||
2705 | // Get bounds of the basis surface | |
2706 | Standard_Real aSUMin, aSUMax, aSVMin, aSVMax; | |
2707 | aSurf->Bounds(aSUMin, aSUMax, aSVMin, aSVMax); | |
2708 | ||
82d3cd0b | 2709 | Standard_Boolean isUPeriodic = aBAS.IsUPeriodic(); |
2710 | Standard_Real anUPeriod = isUPeriodic ? aBAS.UPeriod() : 0.0; | |
2711 | if (isUPeriodic) | |
d9ca2e0c | 2712 | { |
2713 | // Adjust face bounds to first period | |
2714 | Standard_Real aDelta = aFUMax - aFUMin; | |
82d3cd0b | 2715 | aFUMin = Max(aSUMin, aFUMin + anUPeriod*Ceiling((aSUMin - aFUMin) / anUPeriod)); |
d9ca2e0c | 2716 | aFUMax = aFUMin + aDelta; |
2717 | } | |
82d3cd0b | 2718 | |
2719 | Standard_Boolean isVPeriodic = aBAS.IsVPeriodic(); | |
2720 | Standard_Real aVPeriod = isVPeriodic ? aBAS.VPeriod() : 0.0; | |
2721 | if (isVPeriodic) | |
d9ca2e0c | 2722 | { |
2723 | // Adjust face bounds to first period | |
2724 | Standard_Real aDelta = aFVMax - aFVMin; | |
82d3cd0b | 2725 | aFVMin = Max(aSVMin, aFVMin + aVPeriod*Ceiling((aSVMin - aFVMin) / aVPeriod)); |
d9ca2e0c | 2726 | aFVMax = aFVMin + aDelta; |
2727 | } | |
2728 | ||
2729 | // Enlarge the face | |
2730 | Standard_Real anURes = 0., aVRes = 0.; | |
2731 | if (theExtUMin || theExtUMax) | |
2732 | anURes = aBAS.UResolution(theExtVal); | |
2733 | if (theExtVMin || theExtVMax) | |
2734 | aVRes = aBAS.VResolution(theExtVal); | |
2735 | ||
2736 | if (theExtUMin) aFUMin = Max(aSUMin, aFUMin - anURes); | |
82d3cd0b | 2737 | if (theExtUMax) aFUMax = Min(isUPeriodic ? aFUMin + anUPeriod : aSUMax, aFUMax + anURes); |
d9ca2e0c | 2738 | if (theExtVMin) aFVMin = Max(aSVMin, aFVMin - aVRes); |
82d3cd0b | 2739 | if (theExtVMax) aFVMax = Min(isVPeriodic ? aFVMin + aVPeriod : aSVMax, aFVMax + aVRes); |
2740 | ||
2741 | // Check if the periodic surface should become closed. | |
2742 | // In this case, use the basis surface with basis bounds. | |
2743 | const Standard_Real anEps = Precision::PConfusion(); | |
2744 | if (isUPeriodic && Abs(aFUMax - aFUMin - anUPeriod) < anEps) | |
2745 | { | |
2746 | aFUMin = aSUMin; | |
2747 | aFUMax = aSUMax; | |
2748 | } | |
2749 | if (isVPeriodic && Abs(aFVMax - aFVMin - aVPeriod) < anEps) | |
2750 | { | |
2751 | aFVMin = aSVMin; | |
2752 | aFVMax = aSVMax; | |
2753 | } | |
d9ca2e0c | 2754 | |
2755 | aS = aSurf; | |
2756 | } | |
2757 | else | |
2758 | { | |
2759 | // General case | |
2760 | ||
2761 | Handle(Geom_BoundedSurface) aSB = | |
2762 | Handle(Geom_BoundedSurface)::DownCast(BRep_Tool::Surface(theF)); | |
2763 | if (aSB.IsNull()) | |
2764 | { | |
2765 | theFExtended = theF; | |
2766 | return; | |
2767 | } | |
2768 | ||
2769 | // Get surfaces bounds | |
2770 | Standard_Real aSUMin, aSUMax, aSVMin, aSVMax; | |
2771 | aSB->Bounds(aSUMin, aSUMax, aSVMin, aSVMax); | |
2772 | ||
2773 | Standard_Boolean isUClosed = aSB->IsUClosed(); | |
2774 | Standard_Boolean isVClosed = aSB->IsVClosed(); | |
2775 | ||
2776 | // Check if the extension in necessary directions is done | |
2777 | Standard_Boolean isExtUMin = Standard_False, | |
2778 | isExtUMax = Standard_False, | |
2779 | isExtVMin = Standard_False, | |
2780 | isExtVMax = Standard_False; | |
2781 | ||
2782 | // UMin | |
2783 | if (theExtUMin && !isUClosed && !Precision::IsInfinite(aSUMin)) { | |
2784 | GeomLib::ExtendSurfByLength(aSB, theExtVal, 1, Standard_True, Standard_False); | |
2785 | isExtUMin = Standard_True; | |
2786 | } | |
2787 | // UMax | |
2788 | if (theExtUMax && !isUClosed && !Precision::IsInfinite(aSUMax)) { | |
2789 | GeomLib::ExtendSurfByLength(aSB, theExtVal, 1, Standard_True, Standard_True); | |
2790 | isExtUMax = Standard_True; | |
2791 | } | |
2792 | // VMin | |
2793 | if (theExtVMin && !isVClosed && !Precision::IsInfinite(aSVMax)) { | |
2794 | GeomLib::ExtendSurfByLength(aSB, theExtVal, 1, Standard_False, Standard_False); | |
2795 | isExtVMin = Standard_True; | |
2796 | } | |
2797 | // VMax | |
2798 | if (theExtVMax && !isVClosed && !Precision::IsInfinite(aSVMax)) { | |
2799 | GeomLib::ExtendSurfByLength(aSB, theExtVal, 1, Standard_False, Standard_True); | |
2800 | isExtVMax = Standard_True; | |
2801 | } | |
2802 | ||
2803 | aS = aSB; | |
2804 | ||
2805 | // Get new bounds | |
2806 | aS->Bounds(aSUMin, aSUMax, aSVMin, aSVMax); | |
2807 | if (isExtUMin) aFUMin = aSUMin; | |
2808 | if (isExtUMax) aFUMax = aSUMax; | |
2809 | if (isExtVMin) aFVMin = aSVMin; | |
2810 | if (isExtVMax) aFVMax = aSVMax; | |
2811 | } | |
2812 | ||
2813 | BRepLib_MakeFace aMF(aS, aFUMin, aFUMax, aFVMin, aFVMax, aTol); | |
2814 | theFExtended = *(TopoDS_Face*)&aMF.Shape(); | |
2815 | if (theF.Orientation() == TopAbs_REVERSED) | |
2816 | theFExtended.Reverse(); | |
2817 | } |