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