0029859: Coding - GCC compiler warning -Warray-bounds in IntPatch_InterferencePolyhed...
[occt.git] / src / BRepTools / BRepTools.cxx
CommitLineData
b311480e 1// Created on: 1993-01-21
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.
7fd59977 16
7fd59977 17
42cf5bc1 18#include <Bnd_Box2d.hxx>
7fd59977 19#include <BndLib_Add2dCurve.hxx>
42cf5bc1 20#include <BRep_Builder.hxx>
7fd59977 21#include <BRep_CurveRepresentation.hxx>
e50ebf1f 22#include <BRep_GCurve.hxx>
23#include <BRep_ListOfCurveRepresentation.hxx>
7fd59977 24#include <BRep_TEdge.hxx>
42cf5bc1 25#include <BRep_Tool.hxx>
26#include <BRepTools.hxx>
27#include <BRepTools_MapOfVertexPnt2d.hxx>
28#include <BRepTools_ShapeSet.hxx>
11af6cdd 29#include <BRepAdaptor_Surface.hxx>
7fd59977 30#include <ElCLib.hxx>
42cf5bc1 31#include <Geom2d_Curve.hxx>
32#include <Geom2dAdaptor_Curve.hxx>
33#include <Geom_BSplineSurface.hxx>
34#include <Geom_Curve.hxx>
35#include <Geom_RectangularTrimmedSurface.hxx>
36#include <Geom_Surface.hxx>
37#include <gp_Lin2d.hxx>
7fd59977 38#include <gp_Vec2d.hxx>
42cf5bc1 39#include <Message_ProgressIndicator.hxx>
40#include <OSD_OpenFile.hxx>
41#include <Poly_PolygonOnTriangulation.hxx>
42#include <Poly_Triangulation.hxx>
43#include <Precision.hxx>
7fd59977 44#include <Standard_ErrorHandler.hxx>
45#include <Standard_Failure.hxx>
42cf5bc1 46#include <Standard_Stream.hxx>
47#include <TColGeom2d_SequenceOfCurve.hxx>
48#include <TColgp_SequenceOfPnt2d.hxx>
49#include <TColStd_Array1OfReal.hxx>
50#include <TColStd_HArray1OfInteger.hxx>
51#include <TColStd_MapOfTransient.hxx>
52#include <TColStd_SequenceOfReal.hxx>
53#include <TopExp.hxx>
54#include <TopExp_Explorer.hxx>
55#include <TopoDS.hxx>
56#include <TopoDS_Compound.hxx>
57#include <TopoDS_CompSolid.hxx>
58#include <TopoDS_Edge.hxx>
59#include <TopoDS_Face.hxx>
42cf5bc1 60#include <TopoDS_Shape.hxx>
61#include <TopoDS_Shell.hxx>
62#include <TopoDS_Solid.hxx>
63#include <TopoDS_Vertex.hxx>
64#include <TopoDS_Wire.hxx>
65#include <TopTools_SequenceOfShape.hxx>
2651bfde 66#include <GeomLib_CheckCurveOnSurface.hxx>
7fd59977 67#include <errno.h>
11af6cdd 68
69
70//=======================================================================
71//function : IsPCurveUiso
72//purpose :
73//=======================================================================
74
75static Standard_Boolean IsPCurveUiso(const Handle(Geom2d_Curve)& thePCurve,
76 Standard_Real theFirstPar,
77 Standard_Real theLastPar)
78{
79 gp_Pnt2d FirstP2d = thePCurve->Value(theFirstPar);
80 gp_Pnt2d LastP2d = thePCurve->Value(theLastPar);
81
82 Standard_Real DeltaU = Abs(FirstP2d.X() - LastP2d.X());
83 Standard_Real DeltaV = Abs(FirstP2d.Y() - LastP2d.Y());
84
85 return (DeltaU < DeltaV);
86}
87
88
7fd59977 89//=======================================================================
90//function : UVBounds
91//purpose :
92//=======================================================================
7fd59977 93void BRepTools::UVBounds(const TopoDS_Face& F,
94 Standard_Real& UMin, Standard_Real& UMax,
95 Standard_Real& VMin, Standard_Real& VMax)
96{
97 Bnd_Box2d B;
98 AddUVBounds(F,B);
413b1c1a 99 if (!B.IsVoid())
100 {
101 B.Get(UMin,VMin,UMax,VMax);
102 }
103 else
104 {
105 UMin = UMax = VMin = VMax = 0.0;
106 }
7fd59977 107}
108
109//=======================================================================
110//function : UVBounds
111//purpose :
112//=======================================================================
113
114void BRepTools::UVBounds(const TopoDS_Face& F,
115 const TopoDS_Wire& W,
116 Standard_Real& UMin, Standard_Real& UMax,
117 Standard_Real& VMin, Standard_Real& VMax)
118{
119 Bnd_Box2d B;
120 AddUVBounds(F,W,B);
413b1c1a 121 if (!B.IsVoid())
122 {
123 B.Get(UMin,VMin,UMax,VMax);
124 }
125 else
126 {
127 UMin = UMax = VMin = VMax = 0.0;
128 }
7fd59977 129}
130
131
132//=======================================================================
133//function : UVBounds
134//purpose :
135//=======================================================================
136
137void BRepTools::UVBounds(const TopoDS_Face& F,
138 const TopoDS_Edge& E,
139 Standard_Real& UMin, Standard_Real& UMax,
140 Standard_Real& VMin, Standard_Real& VMax)
141{
142 Bnd_Box2d B;
143 AddUVBounds(F,E,B);
413b1c1a 144 if (!B.IsVoid())
145 {
146 B.Get(UMin,VMin,UMax,VMax);
147 }
148 else
149 {
150 UMin = UMax = VMin = VMax = 0.0;
151 }
7fd59977 152}
153
154//=======================================================================
155//function : AddUVBounds
156//purpose :
157//=======================================================================
158
159void BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B)
160{
161 TopoDS_Face F = FF;
162 F.Orientation(TopAbs_FORWARD);
163 TopExp_Explorer ex(F,TopAbs_EDGE);
164
165 // fill box for the given face
166 Bnd_Box2d aBox;
167 for (;ex.More();ex.Next()) {
168 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),aBox);
169 }
170
171 // if the box is empty (face without edges or without pcurves),
172 // get natural bounds
173 if (aBox.IsVoid()) {
174 Standard_Real UMin,UMax,VMin,VMax;
175 TopLoc_Location L;
413b1c1a 176 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(F, L);
177 if (aSurf.IsNull())
178 {
179 return;
180 }
181
182 aSurf->Bounds(UMin,UMax,VMin,VMax);
7fd59977 183 aBox.Update(UMin,VMin,UMax,VMax);
184 }
185
186 // add face box to result
187 B.Add ( aBox );
188}
189
190
191//=======================================================================
192//function : AddUVBounds
193//purpose :
194//=======================================================================
7fd59977 195void BRepTools::AddUVBounds(const TopoDS_Face& F,
196 const TopoDS_Wire& W,
197 Bnd_Box2d& B)
198{
199 TopExp_Explorer ex;
200 for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) {
201 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),B);
202 }
203}
204
205
206//=======================================================================
207//function : AddUVBounds
208//purpose :
209//=======================================================================
59495dbe 210void BRepTools::AddUVBounds(const TopoDS_Face& aF,
6219c44c 211 const TopoDS_Edge& aE,
212 Bnd_Box2d& aB)
7fd59977 213{
413b1c1a 214 Standard_Real aT1, aT2, aXmin = 0.0, aYmin = 0.0, aXmax = 0.0, aYmax = 0.0;
59495dbe 215 Standard_Real aUmin, aUmax, aVmin, aVmax;
216 Bnd_Box2d aBoxC, aBoxS;
217 TopLoc_Location aLoc;
218 //
219 const Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
220 if (aC2D.IsNull()) {
221 return;
222 }
223 //
224 BndLib_Add2dCurve::Add(aC2D, aT1, aT2, 0., aBoxC);
413b1c1a 225 if (!aBoxC.IsVoid())
226 {
227 aBoxC.Get(aXmin, aYmin, aXmax, aYmax);
228 }
59495dbe 229 //
230 Handle(Geom_Surface) aS = BRep_Tool::Surface(aF, aLoc);
231 aS->Bounds(aUmin, aUmax, aVmin, aVmax);
232
233 if(aS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
234 {
235 const Handle(Geom_RectangularTrimmedSurface) aSt =
236 Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
237 aS = aSt->BasisSurface();
7fd59977 238 }
7fd59977 239
59495dbe 240 //
241 if(!aS->IsUPeriodic())
242 {
6219c44c 243 Standard_Boolean isUPeriodic = Standard_False;
244
245 // Additional verification for U-periodicity for B-spline surfaces
246 // 1. Verify that the surface is U-closed (if such flag is false). Verification uses 2 points
247 // 2. Verify periodicity of surface inside UV-bounds of the edge. Verification uses 3 or 6 points.
248 if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) &&
249 (aXmin < aUmin || aXmax > aUmax))
9c06009a 250 {
6219c44c 251 Standard_Real aTol2 = 100 * Precision::Confusion() * Precision::Confusion();
252 isUPeriodic = Standard_True;
253 gp_Pnt P1, P2;
254 // 1. Verify that the surface is U-closed
255 if (!aS->IsUClosed())
256 {
257 Standard_Real aVStep = aVmax - aVmin;
258 for (Standard_Real aV = aVmin; aV <= aVmax; aV += aVStep)
259 {
260 P1 = aS->Value(aUmin, aV);
261 P2 = aS->Value(aUmax, aV);
262 if (P1.SquareDistance(P2) > aTol2)
263 {
264 isUPeriodic = Standard_False;
265 break;
266 }
267 }
268 }
269 // 2. Verify periodicity of surface inside UV-bounds of the edge
270 if (isUPeriodic) // the flag still not changed
271 {
272 Standard_Real aV = (aVmin + aVmax) * 0.5;
273 Standard_Real aU[6]; // values of U lying out of surface boundaries
274 Standard_Real aUpp[6]; // corresponding U-values plus/minus period
275 Standard_Integer aNbPnt = 0;
276 if (aXmin < aUmin)
277 {
278 aU[0] = aXmin;
279 aU[1] = (aXmin + aUmin) * 0.5;
280 aU[2] = aUmin;
281 aUpp[0] = aU[0] + aUmax - aUmin;
282 aUpp[1] = aU[1] + aUmax - aUmin;
283 aUpp[2] = aU[2] + aUmax - aUmin;
284 aNbPnt += 3;
285 }
286 if (aXmax > aUmax)
287 {
288 aU[aNbPnt] = aUmax;
289 aU[aNbPnt + 1] = (aXmax + aUmax) * 0.5;
290 aU[aNbPnt + 2] = aXmax;
291 aUpp[aNbPnt] = aU[aNbPnt] - aUmax + aUmin;
292 aUpp[aNbPnt + 1] = aU[aNbPnt + 1] - aUmax + aUmin;
293 aUpp[aNbPnt + 2] = aU[aNbPnt + 2] - aUmax + aUmin;
294 aNbPnt += 3;
295 }
296 for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++)
297 {
298 P1 = aS->Value(aU[anInd], aV);
299 P2 = aS->Value(aUpp[anInd], aV);
300 if (P1.SquareDistance(P2) > aTol2)
301 {
302 isUPeriodic = Standard_False;
303 break;
304 }
305 }
306 }
9c06009a 307 }
6219c44c 308
309 if (!isUPeriodic)
59495dbe 310 {
6219c44c 311 if((aXmin<aUmin) && (aUmin < aXmax))
312 {
313 aXmin=aUmin;
314 }
315 if((aXmin < aUmax) && (aUmax < aXmax))
316 {
317 aXmax=aUmax;
318 }
7fd59977 319 }
59495dbe 320 }
7fd59977 321
59495dbe 322 if(!aS->IsVPeriodic())
323 {
6219c44c 324 Standard_Boolean isVPeriodic = Standard_False;
325
326 // Additional verification for V-periodicity for B-spline surfaces
327 // 1. Verify that the surface is V-closed (if such flag is false). Verification uses 2 points
328 // 2. Verify periodicity of surface inside UV-bounds of the edge. Verification uses 3 or 6 points.
329 if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) &&
330 (aYmin < aVmin || aYmax > aVmax))
59495dbe 331 {
6219c44c 332 Standard_Real aTol2 = 100 * Precision::Confusion() * Precision::Confusion();
333 isVPeriodic = Standard_True;
334 gp_Pnt P1, P2;
335 // 1. Verify that the surface is V-closed
336 if (!aS->IsVClosed())
337 {
338 Standard_Real aUStep = aUmax - aUmin;
339 for (Standard_Real aU = aUmin; aU <= aUmax; aU += aUStep)
340 {
341 P1 = aS->Value(aU, aVmin);
342 P2 = aS->Value(aU, aVmax);
343 if (P1.SquareDistance(P2) > aTol2)
344 {
345 isVPeriodic = Standard_False;
346 break;
347 }
348 }
349 }
350 // 2. Verify periodicity of surface inside UV-bounds of the edge
351 if (isVPeriodic) // the flag still not changed
352 {
353 Standard_Real aU = (aUmin + aUmax) * 0.5;
354 Standard_Real aV[6]; // values of V lying out of surface boundaries
355 Standard_Real aVpp[6]; // corresponding V-values plus/minus period
356 Standard_Integer aNbPnt = 0;
357 if (aYmin < aVmin)
358 {
359 aV[0] = aYmin;
360 aV[1] = (aYmin + aVmin) * 0.5;
361 aV[2] = aVmin;
362 aVpp[0] = aV[0] + aVmax - aVmin;
363 aVpp[1] = aV[1] + aVmax - aVmin;
364 aVpp[2] = aV[2] + aVmax - aVmin;
365 aNbPnt += 3;
366 }
367 if (aYmax > aVmax)
368 {
369 aV[aNbPnt] = aVmax;
370 aV[aNbPnt + 1] = (aYmax + aVmax) * 0.5;
371 aV[aNbPnt + 2] = aYmax;
372 aVpp[aNbPnt] = aV[aNbPnt] - aVmax + aVmin;
373 aVpp[aNbPnt + 1] = aV[aNbPnt + 1] - aVmax + aVmin;
374 aVpp[aNbPnt + 2] = aV[aNbPnt + 2] - aVmax + aVmin;
375 aNbPnt += 3;
376 }
377 for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++)
378 {
379 P1 = aS->Value(aU, aV[anInd]);
380 P2 = aS->Value(aU, aVpp[anInd]);
381 if (P1.SquareDistance(P2) > aTol2)
382 {
383 isVPeriodic = Standard_False;
384 break;
385 }
386 }
387 }
7fd59977 388 }
6219c44c 389
390 if (!isVPeriodic)
59495dbe 391 {
6219c44c 392 if((aYmin<aVmin) && (aVmin < aYmax))
393 {
394 aYmin=aVmin;
395 }
396 if((aYmin < aVmax) && (aVmax < aYmax))
397 {
398 aYmax=aVmax;
399 }
59495dbe 400 }
7fd59977 401 }
59495dbe 402
403 aBoxS.Update(aXmin, aYmin, aXmax, aYmax);
404
405 aB.Add(aBoxS);
7fd59977 406}
407
408//=======================================================================
409//function : Update
410//purpose :
411//=======================================================================
412
413void BRepTools::Update(const TopoDS_Vertex&)
414{
415}
416
417//=======================================================================
418//function : Update
419//purpose :
420//=======================================================================
421
422void BRepTools::Update(const TopoDS_Edge&)
423{
424}
425
426//=======================================================================
427//function : Update
428//purpose :
429//=======================================================================
430
431void BRepTools::Update(const TopoDS_Wire&)
432{
433}
434
435//=======================================================================
436//function : Update
437//purpose :
438//=======================================================================
439
440void BRepTools::Update(const TopoDS_Face& F)
441{
442 if (!F.Checked()) {
443 UpdateFaceUVPoints(F);
444 F.TShape()->Checked(Standard_True);
445 }
446}
447
448//=======================================================================
449//function : Update
450//purpose :
451//=======================================================================
452
453void BRepTools::Update(const TopoDS_Shell& S)
454{
455 TopExp_Explorer ex(S,TopAbs_FACE);
456 while (ex.More()) {
457 Update(TopoDS::Face(ex.Current()));
458 ex.Next();
459 }
460}
461
462//=======================================================================
463//function : Update
464//purpose :
465//=======================================================================
466
467void BRepTools::Update(const TopoDS_Solid& S)
468{
469 TopExp_Explorer ex(S,TopAbs_FACE);
470 while (ex.More()) {
471 Update(TopoDS::Face(ex.Current()));
472 ex.Next();
473 }
474}
475
476//=======================================================================
477//function : Update
478//purpose :
479//=======================================================================
480
481void BRepTools::Update(const TopoDS_CompSolid& CS)
482{
483 TopExp_Explorer ex(CS,TopAbs_FACE);
484 while (ex.More()) {
485 Update(TopoDS::Face(ex.Current()));
486 ex.Next();
487 }
488}
489
490//=======================================================================
491//function : Update
492//purpose :
493//=======================================================================
494
495void BRepTools::Update(const TopoDS_Compound& C)
496{
497 TopExp_Explorer ex(C,TopAbs_FACE);
498 while (ex.More()) {
499 Update(TopoDS::Face(ex.Current()));
500 ex.Next();
501 }
502}
503
504//=======================================================================
505//function : Update
506//purpose :
507//=======================================================================
508
509void BRepTools::Update(const TopoDS_Shape& S)
510{
511 switch (S.ShapeType()) {
512
513 case TopAbs_VERTEX :
514 Update(TopoDS::Vertex(S));
515 break;
516
517 case TopAbs_EDGE :
518 Update(TopoDS::Edge(S));
519 break;
520
521 case TopAbs_WIRE :
522 Update(TopoDS::Wire(S));
523 break;
524
525 case TopAbs_FACE :
526 Update(TopoDS::Face(S));
527 break;
528
529 case TopAbs_SHELL :
530 Update(TopoDS::Shell(S));
531 break;
532
533 case TopAbs_SOLID :
534 Update(TopoDS::Solid(S));
535 break;
536
537 case TopAbs_COMPSOLID :
538 Update(TopoDS::CompSolid(S));
539 break;
540
541 case TopAbs_COMPOUND :
542 Update(TopoDS::Compound(S));
543 break;
544
545 default:
546 break;
547
548 }
549}
550
7fd59977 551//=======================================================================
552//function : UpdateFaceUVPoints
e50ebf1f 553//purpose : Reset the UV points of edges on the Face
7fd59977 554//=======================================================================
e50ebf1f 555void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& theF)
7fd59977 556{
e50ebf1f 557 // For each edge of the face <F> reset the UV points to the bounding
558 // points of the parametric curve of the edge on the face.
7fd59977 559
e50ebf1f 560 // Get surface of the face
561 TopLoc_Location aLoc;
562 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(theF, aLoc);
563 // Iterate on edges and reset UV points
564 TopExp_Explorer anExpE(theF, TopAbs_EDGE);
565 for (; anExpE.More(); anExpE.Next())
7fd59977 566 {
e50ebf1f 567 const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
568
569 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
570 if (TE->Locked())
571 return;
572
573 const TopLoc_Location aELoc = aLoc.Predivided(aE.Location());
574 // Edge representations
575 BRep_ListOfCurveRepresentation& aLCR = TE->ChangeCurves();
576 BRep_ListIteratorOfListOfCurveRepresentation itLCR(aLCR);
577 for (; itLCR.More(); itLCR.Next())
578 {
579 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itLCR.Value());
580 if (!GC.IsNull() && GC->IsCurveOnSurface(aSurf, aELoc))
581 {
582 // Update UV points
583 GC->Update();
584 break;
7fd59977 585 }
586 }
7fd59977 587 }
588}
589
7fd59977 590//=======================================================================
591//function : Compare
592//purpose :
593//=======================================================================
594
595Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1,
596 const TopoDS_Vertex& V2)
597{
598 if (V1.IsSame(V2)) return Standard_True;
599 gp_Pnt p1 = BRep_Tool::Pnt(V1);
600 gp_Pnt p2 = BRep_Tool::Pnt(V2);
601 Standard_Real l = p1.Distance(p2);
602 if (l <= BRep_Tool::Tolerance(V1)) return Standard_True;
603 if (l <= BRep_Tool::Tolerance(V2)) return Standard_True;
604 return Standard_False;
605}
606
607//=======================================================================
608//function : Compare
609//purpose :
610//=======================================================================
611
612Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1,
613 const TopoDS_Edge& E2)
614{
615 if (E1.IsSame(E2)) return Standard_True;
616 return Standard_False;
617}
618
619//=======================================================================
620//function : OuterWire
621//purpose :
622//=======================================================================
623
624TopoDS_Wire BRepTools::OuterWire(const TopoDS_Face& F)
625{
626 TopoDS_Wire Wres;
627 TopExp_Explorer expw (F,TopAbs_WIRE);
628
629 if (expw.More()) {
630 Wres = TopoDS::Wire(expw.Current());
631 expw.Next();
632 if (expw.More()) {
633 Standard_Real UMin, UMax, VMin, VMax;
634 Standard_Real umin, umax, vmin, vmax;
635 BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax);
636 while (expw.More()) {
637 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
638 BRepTools::UVBounds(F,W,umin, umax, vmin, vmax);
639 if ((umin <= UMin) &&
640 (umax >= UMax) &&
641 (vmin <= VMin) &&
642 (vmax >= VMax)) {
643 Wres = W;
644 UMin = umin;
645 UMax = umax;
646 VMin = vmin;
647 VMax = vmax;
648 }
649 expw.Next();
650 }
651 }
652 }
653 return Wres;
654}
655
7fd59977 656//=======================================================================
657//function : Map3DEdges
658//purpose :
659//=======================================================================
660
661void BRepTools::Map3DEdges(const TopoDS_Shape& S,
662 TopTools_IndexedMapOfShape& M)
663{
664 TopExp_Explorer Ex;
665 for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) {
666 if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current())))
667 M.Add(Ex.Current());
668 }
669}
670
671//=======================================================================
672//function : Dump
673//purpose :
674//=======================================================================
675
676void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
677{
678 BRepTools_ShapeSet SS;
679 SS.Add(Sh);
680 SS.Dump(Sh,S);
681 SS.Dump(S);
682}
683
7fd59977 684//=======================================================================
685//function : Write
686//purpose :
687//=======================================================================
688
689void BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S,
690 const Handle(Message_ProgressIndicator)& PR)
691{
692 BRepTools_ShapeSet SS;
693 SS.SetProgress(PR);
694 SS.Add(Sh);
695 SS.Write(S);
696 SS.Write(Sh,S);
697}
698
699
700//=======================================================================
701//function : Read
702//purpose :
703//=======================================================================
704
705void BRepTools::Read(TopoDS_Shape& Sh,
706 istream& S,
707 const BRep_Builder& B,
708 const Handle(Message_ProgressIndicator)& PR)
709{
710 BRepTools_ShapeSet SS(B);
711 SS.SetProgress(PR);
712 SS.Read(S);
713 SS.Read(Sh,S);
714}
715
716//=======================================================================
717//function : Write
718//purpose :
719//=======================================================================
720
721Standard_Boolean BRepTools::Write(const TopoDS_Shape& Sh,
722 const Standard_CString File,
723 const Handle(Message_ProgressIndicator)& PR)
724{
725 ofstream os;
94708556 726 OSD_OpenStream(os, File, ios::out);
fc8918ad 727 if (!os.is_open() || !os.good())
728 return Standard_False;
7fd59977 729
730 Standard_Boolean isGood = (os.good() && !os.eof());
731 if(!isGood)
732 return isGood;
733
734 BRepTools_ShapeSet SS;
735 SS.SetProgress(PR);
736 SS.Add(Sh);
737
738 os << "DBRep_DrawableShape\n"; // for easy Draw read
739 SS.Write(os);
740 isGood = os.good();
741 if(isGood )
742 SS.Write(Sh,os);
743 os.flush();
744 isGood = os.good();
745
746 errno = 0;
747 os.close();
7fd59977 748 isGood = os.good() && isGood && !errno;
749
750 return isGood;
751}
752
753//=======================================================================
754//function : Read
755//purpose :
756//=======================================================================
757
758Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh,
759 const Standard_CString File,
760 const BRep_Builder& B,
761 const Handle(Message_ProgressIndicator)& PR)
762{
763 filebuf fic;
764 istream in(&fic);
fb0b0531 765 OSD_OpenStream (fic, File, ios::in);
94708556 766 if(!fic.is_open()) return Standard_False;
767
7fd59977 768 BRepTools_ShapeSet SS(B);
769 SS.SetProgress(PR);
770 SS.Read(in);
771 if(!SS.NbShapes()) return Standard_False;
772 SS.Read(Sh,in);
773 return Standard_True;
774}
775
776
777//=======================================================================
778//function : Clean
779//purpose :
780//=======================================================================
781
d0a994c7 782void BRepTools::Clean(const TopoDS_Shape& theShape)
7fd59977 783{
d0a994c7 784 BRep_Builder aBuilder;
785 Handle(Poly_Triangulation) aNullTriangulation;
786 Handle(Poly_PolygonOnTriangulation) aNullPoly;
7fd59977 787
d0a994c7 788 if (theShape.IsNull())
789 return;
790
791 TopExp_Explorer aFaceIt(theShape, TopAbs_FACE);
792 for (; aFaceIt.More(); aFaceIt.Next())
793 {
794 const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
795
796 TopLoc_Location aLoc;
797 const Handle(Poly_Triangulation)& aTriangulation =
798 BRep_Tool::Triangulation(aFace, aLoc);
799
800 if (aTriangulation.IsNull())
801 continue;
802
803 // Nullify edges
804 TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE);
805 for (; aEdgeIt.More(); aEdgeIt.Next())
806 {
807 const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
808 aBuilder.UpdateEdge(aEdge, aNullPoly, aTriangulation, aLoc);
7fd59977 809 }
d0a994c7 810
811 aBuilder.UpdateFace(aFace, aNullTriangulation);
7fd59977 812 }
a4ab454c 813
814 // Iterate over all edges seeking for 3d polygons
815 Handle (Poly_Polygon3D) aNullPoly3d;
816 TopExp_Explorer aEdgeIt (theShape, TopAbs_EDGE);
817 for (; aEdgeIt.More (); aEdgeIt.Next ())
818 {
819 const TopoDS_Edge& aEdge = TopoDS::Edge (aEdgeIt.Current ());
820
821 TopLoc_Location aLoc;
822 Handle (Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (aEdge, aLoc);
823 if (aPoly3d.IsNull ())
824 continue;
825
826 aBuilder.UpdateEdge (aEdge, aNullPoly3d);
827 }
7fd59977 828}
829
01697018
J
830//=======================================================================
831//function : RemoveUnusedPCurves
832//purpose :
833//=======================================================================
834
835void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S)
836{
837 TColStd_MapOfTransient UsedSurfaces;
838
839 TopExp_Explorer Explo(S, TopAbs_FACE);
840 for (; Explo.More(); Explo.Next())
841 {
842 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
843 TopLoc_Location aLoc;
844 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
845 UsedSurfaces.Add(aSurf);
846 }
847
848 TopTools_IndexedMapOfShape Emap;
849 TopExp::MapShapes(S, TopAbs_EDGE, Emap);
7fd59977 850
01697018
J
851 Standard_Integer i;
852 for (i = 1; i <= Emap.Extent(); i++)
853 {
854 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape());
855 BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
856 BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr );
857 while (itrep.More())
858 {
859 Standard_Boolean ToRemove = Standard_False;
860
861 Handle(BRep_CurveRepresentation) CurveRep = itrep.Value();
862 if (CurveRep->IsCurveOnSurface())
863 {
864 Handle(Geom_Surface) aSurface = CurveRep->Surface();
865 if (!UsedSurfaces.Contains(aSurface))
866 ToRemove = Standard_True;
867 }
868 else if (CurveRep->IsRegularity())
869 {
870 Handle(Geom_Surface) Surf1 = CurveRep->Surface();
871 Handle(Geom_Surface) Surf2 = CurveRep->Surface2();
872 ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2));
873 }
874
875 if (ToRemove)
876 lcr.Remove(itrep);
877 else
878 itrep.Next();
879 }
880 }
881}
7fd59977 882
883//=======================================================================
884//function : Triangulation
885//purpose :
886//=======================================================================
887
888Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& S,
889 const Standard_Real deflec)
890{
891 TopExp_Explorer exf, exe;
892 TopLoc_Location l;
893 Handle(Poly_Triangulation) T;
894 Handle(Poly_PolygonOnTriangulation) Poly;
895
896 for (exf.Init(S, TopAbs_FACE); exf.More(); exf.Next()) {
897 const TopoDS_Face& F = TopoDS::Face(exf.Current());
898 T = BRep_Tool::Triangulation(F, l);
899 if (T.IsNull() || (T->Deflection() > deflec))
900 return Standard_False;
901 for (exe.Init(F, TopAbs_EDGE); exe.More(); exe.Next()) {
902 const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
903 Poly = BRep_Tool::PolygonOnTriangulation(E, T, l);
904 if (Poly.IsNull()) return Standard_False;
905 }
906 }
907 return Standard_True;
908}
909
910
911//=======================================================================
912//function : IsReallyClosed
913//purpose :
914//=======================================================================
915
916Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
917 const TopoDS_Face& F)
918{
919 if (!BRep_Tool::IsClosed(E,F)) {
920 return Standard_False;
921 }
922 Standard_Integer nbocc = 0;
923 TopExp_Explorer exp;
924 for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) {
925 if (exp.Current().IsSame(E)) {
926 nbocc++;
927 }
928 }
929 return nbocc == 2;
930}
931
11af6cdd 932//=======================================================================
933//function : DetectClosedness
934//purpose :
935//=======================================================================
936
937void BRepTools::DetectClosedness(const TopoDS_Face& theFace,
938 Standard_Boolean& theUclosed,
939 Standard_Boolean& theVclosed)
940{
941 theUclosed = theVclosed = Standard_False;
942
943 BRepAdaptor_Surface BAsurf(theFace, Standard_False);
944 Standard_Boolean IsSurfUclosed = BAsurf.IsUClosed();
945 Standard_Boolean IsSurfVclosed = BAsurf.IsVClosed();
946 if (!IsSurfUclosed && !IsSurfVclosed)
947 return;
948
949 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
950 for (; Explo.More(); Explo.Next())
951 {
952 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
953 if (BRepTools::IsReallyClosed(anEdge, theFace))
954 {
955 Standard_Real fpar, lpar;
956 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
957 Standard_Boolean IsUiso = IsPCurveUiso(aPCurve, fpar, lpar);
958 if (IsSurfUclosed && IsUiso)
959 theUclosed = Standard_True;
960 if (IsSurfVclosed && !IsUiso)
961 theVclosed = Standard_True;
962
963 if (theUclosed && theVclosed)
964 break;
965 }
966 }
967}
968
2651bfde 969//=======================================================================
970//function : EvalAndUpdateTol
971//purpose :
972//=======================================================================
973
974Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE,
975 const Handle(Geom_Curve)& C3d,
976 const Handle(Geom2d_Curve) C2d,
977 const Handle(Geom_Surface)& S,
978 const Standard_Real f,
979 const Standard_Real l)
980{
981 Standard_Real newtol = 0.;
982 Standard_Real first = f, last = l;
983 //Set first, last to avoid ErrosStatus = 2 because of
984 //too strong checking of limits in class CheckCurveOnSurface
985 //
986 if(!C3d->IsPeriodic())
987 {
988 first = Max(first, C3d->FirstParameter());
989 last = Min(last, C3d->LastParameter());
990 }
991 if(!C2d->IsPeriodic())
992 {
993 first = Max(first, C2d->FirstParameter());
994 last = Min(last, C2d->LastParameter());
995 }
996
997 GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
998 CT.Perform(C2d);
999 if(CT.IsDone())
1000 {
1001 newtol = CT.MaxDistance();
1002 }
1003 else
1004 {
1005 if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
1006 (C3d->IsPeriodic() || C2d->IsPeriodic())))
1007 {
1008 //Try to estimate by sample points
1009 Standard_Integer nbint = 22;
1010 Standard_Real dt = (last - first) / nbint;
1011 dt = Max(dt, Precision::Confusion());
1012 Standard_Real d, dmax = 0.;
1013 gp_Pnt2d aP2d;
1014 gp_Pnt aPC, aPS;
1015 Standard_Integer cnt = 0;
1016 Standard_Real t = first;
1017 for(; t <= last; t += dt)
1018 {
1019 cnt++;
1020 C2d->D0(t, aP2d);
1021 C3d->D0(t, aPC);
1022 S->D0(aP2d.X(), aP2d.Y(), aPS);
1023 d = aPS.SquareDistance(aPC);
1024 if(d > dmax)
1025 {
1026 dmax = d;
1027 }
1028 }
1029 if(cnt < nbint + 1)
1030 {
1031 t = last;
1032 C2d->D0(t, aP2d);
1033 C3d->D0(t, aPC);
1034 S->D0(aP2d.X(), aP2d.Y(), aPS);
1035 d = aPS.SquareDistance(aPC);
1036 if(d > dmax)
1037 {
1038 dmax = d;
1039 }
1040 }
1041
1042 newtol = 1.2 * Sqrt(dmax);
1043 }
1044 }
1045 Standard_Real Tol = BRep_Tool::Tolerance(theE);
1046 if(newtol > Tol)
1047 {
1048 Tol = newtol;
1049 BRep_Builder B;
1050 B.UpdateEdge(theE, Tol);
1051 }
1052
1053 return Tol;
1054
1055}
7fd59977 1056
1057