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