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