0031587: Modeling Data - add BRepTools::RemoveInternals() removing internal sub-shape...
[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//=======================================================================
7fd59977 71//function : UVBounds
72//purpose :
73//=======================================================================
7fd59977 74void BRepTools::UVBounds(const TopoDS_Face& F,
75 Standard_Real& UMin, Standard_Real& UMax,
76 Standard_Real& VMin, Standard_Real& VMax)
77{
78 Bnd_Box2d B;
79 AddUVBounds(F,B);
413b1c1a 80 if (!B.IsVoid())
81 {
82 B.Get(UMin,VMin,UMax,VMax);
83 }
84 else
85 {
86 UMin = UMax = VMin = VMax = 0.0;
87 }
7fd59977 88}
89
90//=======================================================================
91//function : UVBounds
92//purpose :
93//=======================================================================
94
95void BRepTools::UVBounds(const TopoDS_Face& F,
96 const TopoDS_Wire& W,
97 Standard_Real& UMin, Standard_Real& UMax,
98 Standard_Real& VMin, Standard_Real& VMax)
99{
100 Bnd_Box2d B;
101 AddUVBounds(F,W,B);
413b1c1a 102 if (!B.IsVoid())
103 {
104 B.Get(UMin,VMin,UMax,VMax);
105 }
106 else
107 {
108 UMin = UMax = VMin = VMax = 0.0;
109 }
7fd59977 110}
111
112
113//=======================================================================
114//function : UVBounds
115//purpose :
116//=======================================================================
117
118void BRepTools::UVBounds(const TopoDS_Face& F,
119 const TopoDS_Edge& E,
120 Standard_Real& UMin, Standard_Real& UMax,
121 Standard_Real& VMin, Standard_Real& VMax)
122{
123 Bnd_Box2d B;
124 AddUVBounds(F,E,B);
413b1c1a 125 if (!B.IsVoid())
126 {
127 B.Get(UMin,VMin,UMax,VMax);
128 }
129 else
130 {
131 UMin = UMax = VMin = VMax = 0.0;
132 }
7fd59977 133}
134
135//=======================================================================
136//function : AddUVBounds
137//purpose :
138//=======================================================================
139
140void BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B)
141{
142 TopoDS_Face F = FF;
143 F.Orientation(TopAbs_FORWARD);
144 TopExp_Explorer ex(F,TopAbs_EDGE);
145
146 // fill box for the given face
147 Bnd_Box2d aBox;
148 for (;ex.More();ex.Next()) {
149 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),aBox);
150 }
151
152 // if the box is empty (face without edges or without pcurves),
153 // get natural bounds
154 if (aBox.IsVoid()) {
155 Standard_Real UMin,UMax,VMin,VMax;
156 TopLoc_Location L;
413b1c1a 157 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(F, L);
158 if (aSurf.IsNull())
159 {
160 return;
161 }
162
163 aSurf->Bounds(UMin,UMax,VMin,VMax);
7fd59977 164 aBox.Update(UMin,VMin,UMax,VMax);
165 }
166
167 // add face box to result
168 B.Add ( aBox );
169}
170
171
172//=======================================================================
173//function : AddUVBounds
174//purpose :
175//=======================================================================
7fd59977 176void BRepTools::AddUVBounds(const TopoDS_Face& F,
177 const TopoDS_Wire& W,
178 Bnd_Box2d& B)
179{
180 TopExp_Explorer ex;
181 for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) {
182 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),B);
183 }
184}
185
186
187//=======================================================================
188//function : AddUVBounds
189//purpose :
190//=======================================================================
59495dbe 191void BRepTools::AddUVBounds(const TopoDS_Face& aF,
6219c44c 192 const TopoDS_Edge& aE,
193 Bnd_Box2d& aB)
7fd59977 194{
413b1c1a 195 Standard_Real aT1, aT2, aXmin = 0.0, aYmin = 0.0, aXmax = 0.0, aYmax = 0.0;
59495dbe 196 Standard_Real aUmin, aUmax, aVmin, aVmax;
197 Bnd_Box2d aBoxC, aBoxS;
198 TopLoc_Location aLoc;
199 //
200 const Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
201 if (aC2D.IsNull()) {
202 return;
203 }
204 //
205 BndLib_Add2dCurve::Add(aC2D, aT1, aT2, 0., aBoxC);
413b1c1a 206 if (!aBoxC.IsVoid())
207 {
208 aBoxC.Get(aXmin, aYmin, aXmax, aYmax);
209 }
59495dbe 210 //
211 Handle(Geom_Surface) aS = BRep_Tool::Surface(aF, aLoc);
212 aS->Bounds(aUmin, aUmax, aVmin, aVmax);
213
214 if(aS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
215 {
216 const Handle(Geom_RectangularTrimmedSurface) aSt =
217 Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
218 aS = aSt->BasisSurface();
7fd59977 219 }
7fd59977 220
59495dbe 221 //
222 if(!aS->IsUPeriodic())
223 {
6219c44c 224 Standard_Boolean isUPeriodic = Standard_False;
225
226 // Additional verification for U-periodicity for B-spline surfaces
227 // 1. Verify that the surface is U-closed (if such flag is false). Verification uses 2 points
228 // 2. Verify periodicity of surface inside UV-bounds of the edge. Verification uses 3 or 6 points.
229 if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) &&
230 (aXmin < aUmin || aXmax > aUmax))
9c06009a 231 {
6219c44c 232 Standard_Real aTol2 = 100 * Precision::Confusion() * Precision::Confusion();
233 isUPeriodic = Standard_True;
234 gp_Pnt P1, P2;
235 // 1. Verify that the surface is U-closed
236 if (!aS->IsUClosed())
237 {
238 Standard_Real aVStep = aVmax - aVmin;
239 for (Standard_Real aV = aVmin; aV <= aVmax; aV += aVStep)
240 {
241 P1 = aS->Value(aUmin, aV);
242 P2 = aS->Value(aUmax, aV);
243 if (P1.SquareDistance(P2) > aTol2)
244 {
245 isUPeriodic = Standard_False;
246 break;
247 }
248 }
249 }
250 // 2. Verify periodicity of surface inside UV-bounds of the edge
251 if (isUPeriodic) // the flag still not changed
252 {
253 Standard_Real aV = (aVmin + aVmax) * 0.5;
254 Standard_Real aU[6]; // values of U lying out of surface boundaries
255 Standard_Real aUpp[6]; // corresponding U-values plus/minus period
256 Standard_Integer aNbPnt = 0;
257 if (aXmin < aUmin)
258 {
259 aU[0] = aXmin;
260 aU[1] = (aXmin + aUmin) * 0.5;
261 aU[2] = aUmin;
262 aUpp[0] = aU[0] + aUmax - aUmin;
263 aUpp[1] = aU[1] + aUmax - aUmin;
264 aUpp[2] = aU[2] + aUmax - aUmin;
265 aNbPnt += 3;
266 }
267 if (aXmax > aUmax)
268 {
269 aU[aNbPnt] = aUmax;
270 aU[aNbPnt + 1] = (aXmax + aUmax) * 0.5;
271 aU[aNbPnt + 2] = aXmax;
272 aUpp[aNbPnt] = aU[aNbPnt] - aUmax + aUmin;
273 aUpp[aNbPnt + 1] = aU[aNbPnt + 1] - aUmax + aUmin;
274 aUpp[aNbPnt + 2] = aU[aNbPnt + 2] - aUmax + aUmin;
275 aNbPnt += 3;
276 }
277 for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++)
278 {
279 P1 = aS->Value(aU[anInd], aV);
280 P2 = aS->Value(aUpp[anInd], aV);
281 if (P1.SquareDistance(P2) > aTol2)
282 {
283 isUPeriodic = Standard_False;
284 break;
285 }
286 }
287 }
9c06009a 288 }
6219c44c 289
290 if (!isUPeriodic)
59495dbe 291 {
6219c44c 292 if((aXmin<aUmin) && (aUmin < aXmax))
293 {
294 aXmin=aUmin;
295 }
296 if((aXmin < aUmax) && (aUmax < aXmax))
297 {
298 aXmax=aUmax;
299 }
7fd59977 300 }
59495dbe 301 }
7fd59977 302
59495dbe 303 if(!aS->IsVPeriodic())
304 {
6219c44c 305 Standard_Boolean isVPeriodic = Standard_False;
306
307 // Additional verification for V-periodicity for B-spline surfaces
308 // 1. Verify that the surface is V-closed (if such flag is false). Verification uses 2 points
309 // 2. Verify periodicity of surface inside UV-bounds of the edge. Verification uses 3 or 6 points.
310 if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) &&
311 (aYmin < aVmin || aYmax > aVmax))
59495dbe 312 {
6219c44c 313 Standard_Real aTol2 = 100 * Precision::Confusion() * Precision::Confusion();
314 isVPeriodic = Standard_True;
315 gp_Pnt P1, P2;
316 // 1. Verify that the surface is V-closed
317 if (!aS->IsVClosed())
318 {
319 Standard_Real aUStep = aUmax - aUmin;
320 for (Standard_Real aU = aUmin; aU <= aUmax; aU += aUStep)
321 {
322 P1 = aS->Value(aU, aVmin);
323 P2 = aS->Value(aU, aVmax);
324 if (P1.SquareDistance(P2) > aTol2)
325 {
326 isVPeriodic = Standard_False;
327 break;
328 }
329 }
330 }
331 // 2. Verify periodicity of surface inside UV-bounds of the edge
332 if (isVPeriodic) // the flag still not changed
333 {
334 Standard_Real aU = (aUmin + aUmax) * 0.5;
335 Standard_Real aV[6]; // values of V lying out of surface boundaries
336 Standard_Real aVpp[6]; // corresponding V-values plus/minus period
337 Standard_Integer aNbPnt = 0;
338 if (aYmin < aVmin)
339 {
340 aV[0] = aYmin;
341 aV[1] = (aYmin + aVmin) * 0.5;
342 aV[2] = aVmin;
343 aVpp[0] = aV[0] + aVmax - aVmin;
344 aVpp[1] = aV[1] + aVmax - aVmin;
345 aVpp[2] = aV[2] + aVmax - aVmin;
346 aNbPnt += 3;
347 }
348 if (aYmax > aVmax)
349 {
350 aV[aNbPnt] = aVmax;
351 aV[aNbPnt + 1] = (aYmax + aVmax) * 0.5;
352 aV[aNbPnt + 2] = aYmax;
353 aVpp[aNbPnt] = aV[aNbPnt] - aVmax + aVmin;
354 aVpp[aNbPnt + 1] = aV[aNbPnt + 1] - aVmax + aVmin;
355 aVpp[aNbPnt + 2] = aV[aNbPnt + 2] - aVmax + aVmin;
356 aNbPnt += 3;
357 }
358 for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++)
359 {
360 P1 = aS->Value(aU, aV[anInd]);
361 P2 = aS->Value(aU, aVpp[anInd]);
362 if (P1.SquareDistance(P2) > aTol2)
363 {
364 isVPeriodic = Standard_False;
365 break;
366 }
367 }
368 }
7fd59977 369 }
6219c44c 370
371 if (!isVPeriodic)
59495dbe 372 {
6219c44c 373 if((aYmin<aVmin) && (aVmin < aYmax))
374 {
375 aYmin=aVmin;
376 }
377 if((aYmin < aVmax) && (aVmax < aYmax))
378 {
379 aYmax=aVmax;
380 }
59495dbe 381 }
7fd59977 382 }
59495dbe 383
384 aBoxS.Update(aXmin, aYmin, aXmax, aYmax);
385
386 aB.Add(aBoxS);
7fd59977 387}
388
389//=======================================================================
390//function : Update
391//purpose :
392//=======================================================================
393
394void BRepTools::Update(const TopoDS_Vertex&)
395{
396}
397
398//=======================================================================
399//function : Update
400//purpose :
401//=======================================================================
402
403void BRepTools::Update(const TopoDS_Edge&)
404{
405}
406
407//=======================================================================
408//function : Update
409//purpose :
410//=======================================================================
411
412void BRepTools::Update(const TopoDS_Wire&)
413{
414}
415
416//=======================================================================
417//function : Update
418//purpose :
419//=======================================================================
420
421void BRepTools::Update(const TopoDS_Face& F)
422{
423 if (!F.Checked()) {
424 UpdateFaceUVPoints(F);
425 F.TShape()->Checked(Standard_True);
426 }
427}
428
429//=======================================================================
430//function : Update
431//purpose :
432//=======================================================================
433
434void BRepTools::Update(const TopoDS_Shell& S)
435{
436 TopExp_Explorer ex(S,TopAbs_FACE);
437 while (ex.More()) {
438 Update(TopoDS::Face(ex.Current()));
439 ex.Next();
440 }
441}
442
443//=======================================================================
444//function : Update
445//purpose :
446//=======================================================================
447
448void BRepTools::Update(const TopoDS_Solid& S)
449{
450 TopExp_Explorer ex(S,TopAbs_FACE);
451 while (ex.More()) {
452 Update(TopoDS::Face(ex.Current()));
453 ex.Next();
454 }
455}
456
457//=======================================================================
458//function : Update
459//purpose :
460//=======================================================================
461
462void BRepTools::Update(const TopoDS_CompSolid& CS)
463{
464 TopExp_Explorer ex(CS,TopAbs_FACE);
465 while (ex.More()) {
466 Update(TopoDS::Face(ex.Current()));
467 ex.Next();
468 }
469}
470
471//=======================================================================
472//function : Update
473//purpose :
474//=======================================================================
475
476void BRepTools::Update(const TopoDS_Compound& C)
477{
478 TopExp_Explorer ex(C,TopAbs_FACE);
479 while (ex.More()) {
480 Update(TopoDS::Face(ex.Current()));
481 ex.Next();
482 }
483}
484
485//=======================================================================
486//function : Update
487//purpose :
488//=======================================================================
489
490void BRepTools::Update(const TopoDS_Shape& S)
491{
492 switch (S.ShapeType()) {
493
494 case TopAbs_VERTEX :
495 Update(TopoDS::Vertex(S));
496 break;
497
498 case TopAbs_EDGE :
499 Update(TopoDS::Edge(S));
500 break;
501
502 case TopAbs_WIRE :
503 Update(TopoDS::Wire(S));
504 break;
505
506 case TopAbs_FACE :
507 Update(TopoDS::Face(S));
508 break;
509
510 case TopAbs_SHELL :
511 Update(TopoDS::Shell(S));
512 break;
513
514 case TopAbs_SOLID :
515 Update(TopoDS::Solid(S));
516 break;
517
518 case TopAbs_COMPSOLID :
519 Update(TopoDS::CompSolid(S));
520 break;
521
522 case TopAbs_COMPOUND :
523 Update(TopoDS::Compound(S));
524 break;
525
526 default:
527 break;
528
529 }
530}
531
7fd59977 532//=======================================================================
533//function : UpdateFaceUVPoints
e50ebf1f 534//purpose : Reset the UV points of edges on the Face
7fd59977 535//=======================================================================
e50ebf1f 536void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& theF)
7fd59977 537{
e50ebf1f 538 // For each edge of the face <F> reset the UV points to the bounding
539 // points of the parametric curve of the edge on the face.
7fd59977 540
e50ebf1f 541 // Get surface of the face
542 TopLoc_Location aLoc;
543 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(theF, aLoc);
544 // Iterate on edges and reset UV points
545 TopExp_Explorer anExpE(theF, TopAbs_EDGE);
546 for (; anExpE.More(); anExpE.Next())
7fd59977 547 {
e50ebf1f 548 const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
549
550 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
551 if (TE->Locked())
552 return;
553
554 const TopLoc_Location aELoc = aLoc.Predivided(aE.Location());
555 // Edge representations
556 BRep_ListOfCurveRepresentation& aLCR = TE->ChangeCurves();
557 BRep_ListIteratorOfListOfCurveRepresentation itLCR(aLCR);
558 for (; itLCR.More(); itLCR.Next())
559 {
560 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itLCR.Value());
561 if (!GC.IsNull() && GC->IsCurveOnSurface(aSurf, aELoc))
562 {
563 // Update UV points
564 GC->Update();
565 break;
7fd59977 566 }
567 }
7fd59977 568 }
569}
570
7fd59977 571//=======================================================================
572//function : Compare
573//purpose :
574//=======================================================================
575
576Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1,
577 const TopoDS_Vertex& V2)
578{
579 if (V1.IsSame(V2)) return Standard_True;
580 gp_Pnt p1 = BRep_Tool::Pnt(V1);
581 gp_Pnt p2 = BRep_Tool::Pnt(V2);
582 Standard_Real l = p1.Distance(p2);
583 if (l <= BRep_Tool::Tolerance(V1)) return Standard_True;
584 if (l <= BRep_Tool::Tolerance(V2)) return Standard_True;
585 return Standard_False;
586}
587
588//=======================================================================
589//function : Compare
590//purpose :
591//=======================================================================
592
593Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1,
594 const TopoDS_Edge& E2)
595{
596 if (E1.IsSame(E2)) return Standard_True;
597 return Standard_False;
598}
599
600//=======================================================================
601//function : OuterWire
602//purpose :
603//=======================================================================
604
605TopoDS_Wire BRepTools::OuterWire(const TopoDS_Face& F)
606{
607 TopoDS_Wire Wres;
608 TopExp_Explorer expw (F,TopAbs_WIRE);
609
610 if (expw.More()) {
611 Wres = TopoDS::Wire(expw.Current());
612 expw.Next();
613 if (expw.More()) {
614 Standard_Real UMin, UMax, VMin, VMax;
615 Standard_Real umin, umax, vmin, vmax;
616 BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax);
617 while (expw.More()) {
618 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
619 BRepTools::UVBounds(F,W,umin, umax, vmin, vmax);
620 if ((umin <= UMin) &&
621 (umax >= UMax) &&
622 (vmin <= VMin) &&
623 (vmax >= VMax)) {
624 Wres = W;
625 UMin = umin;
626 UMax = umax;
627 VMin = vmin;
628 VMax = vmax;
629 }
630 expw.Next();
631 }
632 }
633 }
634 return Wres;
635}
636
7fd59977 637//=======================================================================
638//function : Map3DEdges
639//purpose :
640//=======================================================================
641
642void BRepTools::Map3DEdges(const TopoDS_Shape& S,
643 TopTools_IndexedMapOfShape& M)
644{
645 TopExp_Explorer Ex;
646 for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) {
647 if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current())))
648 M.Add(Ex.Current());
649 }
650}
651
652//=======================================================================
653//function : Dump
654//purpose :
655//=======================================================================
656
657void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
658{
659 BRepTools_ShapeSet SS;
660 SS.Add(Sh);
661 SS.Dump(Sh,S);
662 SS.Dump(S);
663}
664
7fd59977 665//=======================================================================
666//function : Write
667//purpose :
668//=======================================================================
669
670void BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S,
671 const Handle(Message_ProgressIndicator)& PR)
672{
673 BRepTools_ShapeSet SS;
674 SS.SetProgress(PR);
675 SS.Add(Sh);
676 SS.Write(S);
677 SS.Write(Sh,S);
678}
679
680
681//=======================================================================
682//function : Read
683//purpose :
684//=======================================================================
685
686void BRepTools::Read(TopoDS_Shape& Sh,
04232180 687 std::istream& S,
7fd59977 688 const BRep_Builder& B,
689 const Handle(Message_ProgressIndicator)& PR)
690{
691 BRepTools_ShapeSet SS(B);
692 SS.SetProgress(PR);
693 SS.Read(S);
694 SS.Read(Sh,S);
695}
696
697//=======================================================================
698//function : Write
699//purpose :
700//=======================================================================
701
702Standard_Boolean BRepTools::Write(const TopoDS_Shape& Sh,
703 const Standard_CString File,
704 const Handle(Message_ProgressIndicator)& PR)
705{
04232180 706 std::ofstream os;
707 OSD_OpenStream(os, File, std::ios::out);
fc8918ad 708 if (!os.is_open() || !os.good())
709 return Standard_False;
7fd59977 710
711 Standard_Boolean isGood = (os.good() && !os.eof());
712 if(!isGood)
713 return isGood;
714
715 BRepTools_ShapeSet SS;
716 SS.SetProgress(PR);
717 SS.Add(Sh);
718
719 os << "DBRep_DrawableShape\n"; // for easy Draw read
720 SS.Write(os);
721 isGood = os.good();
722 if(isGood )
723 SS.Write(Sh,os);
724 os.flush();
725 isGood = os.good();
726
727 errno = 0;
728 os.close();
7fd59977 729 isGood = os.good() && isGood && !errno;
730
731 return isGood;
732}
733
734//=======================================================================
735//function : Read
736//purpose :
737//=======================================================================
738
739Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh,
740 const Standard_CString File,
741 const BRep_Builder& B,
742 const Handle(Message_ProgressIndicator)& PR)
743{
04232180 744 std::filebuf fic;
745 std::istream in(&fic);
746 OSD_OpenStream (fic, File, std::ios::in);
94708556 747 if(!fic.is_open()) return Standard_False;
748
7fd59977 749 BRepTools_ShapeSet SS(B);
750 SS.SetProgress(PR);
751 SS.Read(in);
752 if(!SS.NbShapes()) return Standard_False;
753 SS.Read(Sh,in);
754 return Standard_True;
755}
756
757
758//=======================================================================
759//function : Clean
760//purpose :
761//=======================================================================
762
128654b6 763void BRepTools::Clean (const TopoDS_Shape& theShape)
7fd59977 764{
128654b6 765 if (theShape.IsNull())
766 return;
767
d0a994c7 768 BRep_Builder aBuilder;
769 Handle(Poly_Triangulation) aNullTriangulation;
770 Handle(Poly_PolygonOnTriangulation) aNullPoly;
7fd59977 771
128654b6 772 TopTools_MapOfShape aShapeMap;
773 const TopLoc_Location anEmptyLoc;
d0a994c7 774
775 TopExp_Explorer aFaceIt(theShape, TopAbs_FACE);
776 for (; aFaceIt.More(); aFaceIt.Next())
777 {
128654b6 778 TopoDS_Shape aFaceNoLoc = aFaceIt.Value();
779 aFaceNoLoc.Location (anEmptyLoc);
780 if (!aShapeMap.Add (aFaceNoLoc))
781 {
782 // the face has already been processed
783 continue;
784 }
785
786 const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
787 if (!BRep_Tool::IsGeometric (aFace))
788 {
789 // Do not remove triangulation as there is no surface to recompute it.
790 continue;
791 }
792
d0a994c7 793
794 TopLoc_Location aLoc;
795 const Handle(Poly_Triangulation)& aTriangulation =
796 BRep_Tool::Triangulation(aFace, aLoc);
797
798 if (aTriangulation.IsNull())
799 continue;
800
801 // Nullify edges
128654b6 802 // Theoretically, the edges on the face (with surface) may have no geometry
803 // (no curve 3d or 2d or both). Such faces should be considered as invalid and
804 // are not supported by current implementation. So, both triangulation of the face
805 // and polygon on triangulation of the edges are removed unconditionally.
d0a994c7 806 TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE);
807 for (; aEdgeIt.More(); aEdgeIt.Next())
808 {
809 const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
810 aBuilder.UpdateEdge(aEdge, aNullPoly, aTriangulation, aLoc);
7fd59977 811 }
d0a994c7 812
813 aBuilder.UpdateFace(aFace, aNullTriangulation);
7fd59977 814 }
a4ab454c 815
816 // Iterate over all edges seeking for 3d polygons
817 Handle (Poly_Polygon3D) aNullPoly3d;
818 TopExp_Explorer aEdgeIt (theShape, TopAbs_EDGE);
819 for (; aEdgeIt.More (); aEdgeIt.Next ())
820 {
128654b6 821 TopoDS_Edge anEdgeNoLoc = TopoDS::Edge (aEdgeIt.Value());
822 anEdgeNoLoc.Location (anEmptyLoc);
823
824 if (!aShapeMap.Add (anEdgeNoLoc))
825 {
826 // the edge has already been processed
827 continue;
828 }
829
830 if (!BRep_Tool::IsGeometric (TopoDS::Edge (anEdgeNoLoc)))
831 {
832 // Do not remove polygon 3d as there is no curve to recompute it.
833 continue;
834 }
a4ab454c 835
836 TopLoc_Location aLoc;
128654b6 837 Handle (Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (anEdgeNoLoc, aLoc);
838 if (aPoly3d.IsNull())
a4ab454c 839 continue;
840
128654b6 841 aBuilder.UpdateEdge (anEdgeNoLoc, aNullPoly3d);
a4ab454c 842 }
7fd59977 843}
4b114473 844//=======================================================================
845//function : CleanGeometry
846//purpose :
847//=======================================================================
848
849void BRepTools::CleanGeometry(const TopoDS_Shape& theShape)
850{
851 if (theShape.IsNull())
852 return;
853
854 BRep_Builder aBuilder;
855
856 for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
857 {
858 TopLoc_Location aLocation;
859 const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
860 const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(aFace, aLocation);
861
862 for (TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); aEdgeIt.More(); aEdgeIt.Next())
863 {
864 const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Current());
865 aBuilder.UpdateEdge(anEdge, Handle(Geom2d_Curve)(), aSurface,
866 aLocation, BRep_Tool::Tolerance(anEdge));
867 }
868
869 aBuilder.UpdateFace(aFace, Handle(Geom_Surface)(), aFace.Location(), BRep_Tool::Tolerance(aFace));
870 }
871
872 for (TopExp_Explorer aEdgeIt2(theShape, TopAbs_EDGE); aEdgeIt2.More(); aEdgeIt2.Next())
873 {
874 const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt2.Current());
875
876 aBuilder.UpdateEdge(anEdge, Handle(Geom_Curve)(),
877 TopLoc_Location(), BRep_Tool::Tolerance(anEdge));
878 }
879}
880
7fd59977 881
01697018
J
882//=======================================================================
883//function : RemoveUnusedPCurves
884//purpose :
885//=======================================================================
886
887void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S)
888{
889 TColStd_MapOfTransient UsedSurfaces;
890
891 TopExp_Explorer Explo(S, TopAbs_FACE);
892 for (; Explo.More(); Explo.Next())
893 {
894 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
895 TopLoc_Location aLoc;
896 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
897 UsedSurfaces.Add(aSurf);
898 }
899
900 TopTools_IndexedMapOfShape Emap;
901 TopExp::MapShapes(S, TopAbs_EDGE, Emap);
7fd59977 902
01697018
J
903 Standard_Integer i;
904 for (i = 1; i <= Emap.Extent(); i++)
905 {
906 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape());
907 BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
908 BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr );
909 while (itrep.More())
910 {
911 Standard_Boolean ToRemove = Standard_False;
912
913 Handle(BRep_CurveRepresentation) CurveRep = itrep.Value();
914 if (CurveRep->IsCurveOnSurface())
915 {
916 Handle(Geom_Surface) aSurface = CurveRep->Surface();
917 if (!UsedSurfaces.Contains(aSurface))
918 ToRemove = Standard_True;
919 }
920 else if (CurveRep->IsRegularity())
921 {
922 Handle(Geom_Surface) Surf1 = CurveRep->Surface();
923 Handle(Geom_Surface) Surf2 = CurveRep->Surface2();
924 ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2));
925 }
926
927 if (ToRemove)
928 lcr.Remove(itrep);
929 else
930 itrep.Next();
931 }
932 }
933}
7fd59977 934
935//=======================================================================
936//function : Triangulation
937//purpose :
938//=======================================================================
939
29263c94 940Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& theShape,
941 const Standard_Real theLinDefl,
942 const Standard_Boolean theToCheckFreeEdges)
7fd59977 943{
29263c94 944 TopExp_Explorer anEdgeIter;
945 TopLoc_Location aDummyLoc;
946 for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
947 {
948 const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
949 const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation (aFace, aDummyLoc);
950 if (aTri.IsNull()
951 || aTri->Deflection() > theLinDefl)
952 {
7fd59977 953 return Standard_False;
7fd59977 954 }
29263c94 955
956 for (anEdgeIter.Init (aFace, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
957 {
958 const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
959 const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTri, aDummyLoc);
960 if (aPoly.IsNull())
961 {
962 return Standard_False;
963 }
964 }
965 }
966 if (!theToCheckFreeEdges)
967 {
968 return Standard_True;
7fd59977 969 }
29263c94 970
971 Handle(Poly_Triangulation) anEdgeTri;
972 for (anEdgeIter.Init (theShape, TopAbs_EDGE, TopAbs_FACE); anEdgeIter.More(); anEdgeIter.Next())
973 {
974 const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
975 const Handle(Poly_Polygon3D)& aPolygon = BRep_Tool::Polygon3D (anEdge, aDummyLoc);
976 if (!aPolygon.IsNull())
977 {
978 if (aPolygon->Deflection() > theLinDefl)
979 {
980 return Standard_False;
981 }
982 }
983 else
984 {
985 const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeTri, aDummyLoc);
986 if (aPoly.IsNull()
987 || anEdgeTri.IsNull()
988 || anEdgeTri->Deflection() > theLinDefl)
989 {
990 return Standard_False;
991 }
992 }
993 }
994
7fd59977 995 return Standard_True;
996}
997
998
999//=======================================================================
1000//function : IsReallyClosed
1001//purpose :
1002//=======================================================================
1003
1004Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
1005 const TopoDS_Face& F)
1006{
1007 if (!BRep_Tool::IsClosed(E,F)) {
1008 return Standard_False;
1009 }
1010 Standard_Integer nbocc = 0;
1011 TopExp_Explorer exp;
1012 for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) {
1013 if (exp.Current().IsSame(E)) {
1014 nbocc++;
1015 }
1016 }
1017 return nbocc == 2;
1018}
1019
2651bfde 1020//=======================================================================
11af6cdd 1021//function : DetectClosedness
1022//purpose :
1023//=======================================================================
1024
1025void BRepTools::DetectClosedness(const TopoDS_Face& theFace,
1026 Standard_Boolean& theUclosed,
1027 Standard_Boolean& theVclosed)
1028{
1029 theUclosed = theVclosed = Standard_False;
1030
11af6cdd 1031 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1032 for (; Explo.More(); Explo.Next())
1033 {
1034 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
85c103d2 1035 if (BRep_Tool::IsClosed(anEdge, theFace) &&
1036 BRepTools::IsReallyClosed(anEdge, theFace))
11af6cdd 1037 {
1038 Standard_Real fpar, lpar;
85c103d2 1039 Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
1040 Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(anEdge.Reversed()),
1041 theFace, fpar, lpar);
1042 gp_Pnt2d Point1 = PCurve1->Value(fpar);
1043 gp_Pnt2d Point2 = PCurve2->Value(fpar);
1044 Standard_Boolean IsUiso = (Abs(Point1.X() - Point2.X()) > Abs(Point1.Y() - Point2.Y()));
1045 if (IsUiso)
11af6cdd 1046 theUclosed = Standard_True;
85c103d2 1047 else
11af6cdd 1048 theVclosed = Standard_True;
11af6cdd 1049 }
1050 }
1051}
1052
1053//=======================================================================
2651bfde 1054//function : EvalAndUpdateTol
1055//purpose :
1056//=======================================================================
1057
1058Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE,
1059 const Handle(Geom_Curve)& C3d,
1060 const Handle(Geom2d_Curve) C2d,
1061 const Handle(Geom_Surface)& S,
1062 const Standard_Real f,
1063 const Standard_Real l)
1064{
1065 Standard_Real newtol = 0.;
1066 Standard_Real first = f, last = l;
1067 //Set first, last to avoid ErrosStatus = 2 because of
1068 //too strong checking of limits in class CheckCurveOnSurface
1069 //
1070 if(!C3d->IsPeriodic())
1071 {
1072 first = Max(first, C3d->FirstParameter());
1073 last = Min(last, C3d->LastParameter());
1074 }
1075 if(!C2d->IsPeriodic())
1076 {
1077 first = Max(first, C2d->FirstParameter());
1078 last = Min(last, C2d->LastParameter());
1079 }
1080
1081 GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
1082 CT.Perform(C2d);
1083 if(CT.IsDone())
1084 {
1085 newtol = CT.MaxDistance();
1086 }
1087 else
1088 {
1089 if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
1090 (C3d->IsPeriodic() || C2d->IsPeriodic())))
1091 {
1092 //Try to estimate by sample points
1093 Standard_Integer nbint = 22;
1094 Standard_Real dt = (last - first) / nbint;
1095 dt = Max(dt, Precision::Confusion());
1096 Standard_Real d, dmax = 0.;
1097 gp_Pnt2d aP2d;
1098 gp_Pnt aPC, aPS;
1099 Standard_Integer cnt = 0;
1100 Standard_Real t = first;
1101 for(; t <= last; t += dt)
1102 {
1103 cnt++;
1104 C2d->D0(t, aP2d);
1105 C3d->D0(t, aPC);
1106 S->D0(aP2d.X(), aP2d.Y(), aPS);
1107 d = aPS.SquareDistance(aPC);
1108 if(d > dmax)
1109 {
1110 dmax = d;
1111 }
1112 }
1113 if(cnt < nbint + 1)
1114 {
1115 t = last;
1116 C2d->D0(t, aP2d);
1117 C3d->D0(t, aPC);
1118 S->D0(aP2d.X(), aP2d.Y(), aPS);
1119 d = aPS.SquareDistance(aPC);
1120 if(d > dmax)
1121 {
1122 dmax = d;
1123 }
1124 }
1125
1126 newtol = 1.2 * Sqrt(dmax);
1127 }
1128 }
1129 Standard_Real Tol = BRep_Tool::Tolerance(theE);
1130 if(newtol > Tol)
1131 {
1132 Tol = newtol;
1133 BRep_Builder B;
1134 B.UpdateEdge(theE, Tol);
1135 }
1136
1137 return Tol;
1138
1139}
7fd59977 1140
eff3eff9 1141//=======================================================================
1142//function : OriEdgeInFace
1143//purpose :
1144//=======================================================================
7fd59977 1145
eff3eff9 1146TopAbs_Orientation BRepTools::OriEdgeInFace (const TopoDS_Edge& E,
1147 const TopoDS_Face& F )
1148
1149{
1150 TopExp_Explorer Exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1151
1152 for (; Exp.More() ;Exp.Next()) {
1153 if (Exp.Current().IsSame(E)) {
1154 return Exp.Current().Orientation();
1155 }
1156 }
1157 throw Standard_ConstructionError("BRepTools::OriEdgeInFace");
1158}
09543c2d 1159
1160
1161namespace
1162{
1163 //=======================================================================
1164 //function : findInternalsToKeep
1165 //purpose : Looks for internal sub-shapes which has to be kept to preserve
1166 // topological connectivity.
1167 //=======================================================================
1168 static void findInternalsToKeep (const TopoDS_Shape& theS,
1169 TopTools_MapOfShape& theAllNonInternals,
1170 TopTools_MapOfShape& theAllInternals,
1171 TopTools_MapOfShape& theShapesToKeep)
1172 {
1173 for (TopoDS_Iterator it (theS, Standard_True); it.More(); it.Next())
1174 {
1175 const TopoDS_Shape& aSS = it.Value();
1176 findInternalsToKeep (aSS, theAllNonInternals, theAllInternals, theShapesToKeep);
1177
1178 if (aSS.Orientation() == TopAbs_INTERNAL)
1179 theAllInternals.Add (aSS);
1180 else
1181 theAllNonInternals.Add (aSS);
1182
1183 if (theAllNonInternals.Contains(aSS) && theAllInternals.Contains (aSS))
1184 theShapesToKeep.Add (aSS);
1185 }
1186 }
1187
1188 //=======================================================================
1189 //function : removeShapes
1190 //purpose : Removes sub-shapes from the shape
1191 //=======================================================================
1192 static void removeShapes (TopoDS_Shape& theS,
1193 const TopTools_ListOfShape& theLS)
1194 {
1195 BRep_Builder aBB;
1196 Standard_Boolean isFree = theS.Free();
1197 theS.Free (Standard_True);
1198
1199 for (TopTools_ListOfShape::Iterator it (theLS); it.More(); it.Next())
1200 {
1201 aBB.Remove (theS, it.Value());
1202 }
1203 theS.Free (isFree);
1204 }
1205
1206 //=======================================================================
1207 //function : removeInternals
1208 //purpose : Removes recursively all internal sub-shapes from the given shape.
1209 // Returns true if all sub-shapes have been removed from the shape.
1210 //=======================================================================
1211 static Standard_Boolean removeInternals (TopoDS_Shape& theS,
1212 const TopTools_MapOfShape* theShapesToKeep)
1213 {
1214 TopTools_ListOfShape aLRemove;
1215 for (TopoDS_Iterator it (theS, Standard_True); it.More(); it.Next())
1216 {
1217 const TopoDS_Shape& aSS = it.Value();
1218 if (aSS.Orientation() == TopAbs_INTERNAL)
1219 {
1220 if (!theShapesToKeep || !theShapesToKeep->Contains (aSS))
1221 aLRemove.Append (aSS);
1222 }
1223 else
1224 {
1225 if (removeInternals (*(TopoDS_Shape*)&aSS, theShapesToKeep))
1226 aLRemove.Append (aSS);
1227 }
1228 }
1229
1230 Standard_Integer aNbSToRemove = aLRemove.Extent();
1231 if (aNbSToRemove)
1232 {
1233 removeShapes (theS, aLRemove);
1234 return (theS.NbChildren() == 0);
1235 }
1236 return Standard_False;
1237 }
1238
1239}
1240
1241//=======================================================================
1242//function : RemoveInternals
1243//purpose :
1244//=======================================================================
1245void BRepTools::RemoveInternals (TopoDS_Shape& theS,
1246 const Standard_Boolean theForce)
1247{
1248 TopTools_MapOfShape *pMKeep = NULL, aMKeep;
1249 if (!theForce)
1250 {
1251 // Find all internal sub-shapes which has to be kept to preserve topological connectivity.
1252 // Note that if the multi-connected shape is not directly contained in some shape,
1253 // but as a part of bigger sub-shape which will be removed, the multi-connected
1254 // shape is going to be removed also, breaking topological connectivity.
1255 // For instance, <theS> is a compound of the face and edge, which does not
1256 // belong to the face. The face contains internal wire and the edge shares
1257 // the vertex with one of the vertices of that wire. The vertex is not directly
1258 // contained in the face, thus will be removed as part of internal wire, and topological
1259 // connectivity between edge and face will be lost.
1260 TopTools_MapOfShape anAllNonInternals, anAllInternals;
1261 findInternalsToKeep (theS, anAllNonInternals, anAllInternals, aMKeep);
1262 if (aMKeep.Extent())
1263 pMKeep = &aMKeep;
1264 }
1265
1266 removeInternals (theS, pMKeep);
1267}