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