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