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