0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / BRepLib / BRepLib.cxx
CommitLineData
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 102static Standard_Real thePrecision = Precision::Confusion();
103static Handle(Geom_Plane) thePlane;
104
b60e8432 105static 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//=======================================================================
112struct 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
133void BRepLib::Precision(const Standard_Real P)
134{
135 thePrecision = P;
136}
137
138//=======================================================================
139//function : Precision
140//purpose :
141//=======================================================================
142
143Standard_Real BRepLib::Precision()
144{
145 return thePrecision;
146}
147
148//=======================================================================
149//function : Plane
150//purpose :
151//=======================================================================
152
153void BRepLib::Plane(const Handle(Geom_Plane)& P)
154{
155 thePlane = P;
156}
157
158
159//=======================================================================
160//function : Plane
161//purpose :
162//=======================================================================
163
164const 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
174Standard_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
214void 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
307static 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
333Standard_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
490Standard_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
502Standard_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
530Standard_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 736Standard_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 765static 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//=======================================================================
835static 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//=======================================================================
861static 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 933static 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 1010void 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//=======================================================================
1022void 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 1032static 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 1065static 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//=======================================================================
1190static 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//=======================================================================
1214void 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//=======================================================================
1227void 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//=======================================================================
1244TopoDS_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 1640static 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//=======================================================================
1807void 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//=======================================================================
1817void 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//=======================================================================
1826void 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//=======================================================================
1919Standard_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
1934class SurfaceProperties
1935{
1936public:
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
1994private:
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 2009static 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 2168static 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
2250void 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
2263void 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
2288void 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//=======================================================================
2314Standard_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
2458void 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
2516void 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//=======================================================================
2573void 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//=======================================================================
2679void 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}