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