Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-01-21 |
2 | // Created by: Remi LEQUETTE | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
7fd59977 | 17 | |
42cf5bc1 | 18 | #include <Bnd_Box2d.hxx> |
7fd59977 | 19 | #include <BndLib_Add2dCurve.hxx> |
42cf5bc1 | 20 | #include <BRep_Builder.hxx> |
7fd59977 | 21 | #include <BRep_CurveRepresentation.hxx> |
e50ebf1f | 22 | #include <BRep_GCurve.hxx> |
23 | #include <BRep_ListOfCurveRepresentation.hxx> | |
7fd59977 | 24 | #include <BRep_TEdge.hxx> |
42cf5bc1 | 25 | #include <BRep_Tool.hxx> |
26 | #include <BRepTools.hxx> | |
27 | #include <BRepTools_MapOfVertexPnt2d.hxx> | |
28 | #include <BRepTools_ShapeSet.hxx> | |
11af6cdd | 29 | #include <BRepAdaptor_Surface.hxx> |
7fd59977 | 30 | #include <ElCLib.hxx> |
42cf5bc1 | 31 | #include <Geom2d_Curve.hxx> |
32 | #include <Geom2dAdaptor_Curve.hxx> | |
33 | #include <Geom_BSplineSurface.hxx> | |
34 | #include <Geom_Curve.hxx> | |
35 | #include <Geom_RectangularTrimmedSurface.hxx> | |
36 | #include <Geom_Surface.hxx> | |
37 | #include <gp_Lin2d.hxx> | |
7fd59977 | 38 | #include <gp_Vec2d.hxx> |
42cf5bc1 | 39 | #include <Message_ProgressIndicator.hxx> |
40 | #include <OSD_OpenFile.hxx> | |
41 | #include <Poly_PolygonOnTriangulation.hxx> | |
42 | #include <Poly_Triangulation.hxx> | |
43 | #include <Precision.hxx> | |
7fd59977 | 44 | #include <Standard_ErrorHandler.hxx> |
45 | #include <Standard_Failure.hxx> | |
42cf5bc1 | 46 | #include <Standard_Stream.hxx> |
47 | #include <TColGeom2d_SequenceOfCurve.hxx> | |
48 | #include <TColgp_SequenceOfPnt2d.hxx> | |
49 | #include <TColStd_Array1OfReal.hxx> | |
50 | #include <TColStd_HArray1OfInteger.hxx> | |
51 | #include <TColStd_MapOfTransient.hxx> | |
52 | #include <TColStd_SequenceOfReal.hxx> | |
53 | #include <TopExp.hxx> | |
54 | #include <TopExp_Explorer.hxx> | |
55 | #include <TopoDS.hxx> | |
56 | #include <TopoDS_Compound.hxx> | |
57 | #include <TopoDS_CompSolid.hxx> | |
58 | #include <TopoDS_Edge.hxx> | |
59 | #include <TopoDS_Face.hxx> | |
42cf5bc1 | 60 | #include <TopoDS_Shape.hxx> |
61 | #include <TopoDS_Shell.hxx> | |
62 | #include <TopoDS_Solid.hxx> | |
63 | #include <TopoDS_Vertex.hxx> | |
64 | #include <TopoDS_Wire.hxx> | |
65 | #include <TopTools_SequenceOfShape.hxx> | |
2651bfde | 66 | #include <GeomLib_CheckCurveOnSurface.hxx> |
7fd59977 | 67 | #include <errno.h> |
11af6cdd | 68 | |
69 | ||
70 | //======================================================================= | |
71 | //function : IsPCurveUiso | |
72 | //purpose : | |
73 | //======================================================================= | |
74 | ||
75 | static 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 | 93 | void 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 | ||
114 | void 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 | ||
137 | void 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 | ||
159 | void 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 | 195 | void 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 | 210 | void 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 | ||
413 | void BRepTools::Update(const TopoDS_Vertex&) | |
414 | { | |
415 | } | |
416 | ||
417 | //======================================================================= | |
418 | //function : Update | |
419 | //purpose : | |
420 | //======================================================================= | |
421 | ||
422 | void BRepTools::Update(const TopoDS_Edge&) | |
423 | { | |
424 | } | |
425 | ||
426 | //======================================================================= | |
427 | //function : Update | |
428 | //purpose : | |
429 | //======================================================================= | |
430 | ||
431 | void BRepTools::Update(const TopoDS_Wire&) | |
432 | { | |
433 | } | |
434 | ||
435 | //======================================================================= | |
436 | //function : Update | |
437 | //purpose : | |
438 | //======================================================================= | |
439 | ||
440 | void 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 | ||
453 | void 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 | ||
467 | void 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 | ||
481 | void 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 | ||
495 | void 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 | ||
509 | void 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 | ||
7fd59977 | 551 | //======================================================================= |
552 | //function : UpdateFaceUVPoints | |
e50ebf1f | 553 | //purpose : Reset the UV points of edges on the Face |
7fd59977 | 554 | //======================================================================= |
e50ebf1f | 555 | void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& theF) |
7fd59977 | 556 | { |
e50ebf1f | 557 | // For each edge of the face <F> reset the UV points to the bounding |
558 | // points of the parametric curve of the edge on the face. | |
7fd59977 | 559 | |
e50ebf1f | 560 | // Get surface of the face |
561 | TopLoc_Location aLoc; | |
562 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(theF, aLoc); | |
563 | // Iterate on edges and reset UV points | |
564 | TopExp_Explorer anExpE(theF, TopAbs_EDGE); | |
565 | for (; anExpE.More(); anExpE.Next()) | |
7fd59977 | 566 | { |
e50ebf1f | 567 | const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current()); |
568 | ||
569 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape()); | |
570 | if (TE->Locked()) | |
571 | return; | |
572 | ||
573 | const TopLoc_Location aELoc = aLoc.Predivided(aE.Location()); | |
574 | // Edge representations | |
575 | BRep_ListOfCurveRepresentation& aLCR = TE->ChangeCurves(); | |
576 | BRep_ListIteratorOfListOfCurveRepresentation itLCR(aLCR); | |
577 | for (; itLCR.More(); itLCR.Next()) | |
578 | { | |
579 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itLCR.Value()); | |
580 | if (!GC.IsNull() && GC->IsCurveOnSurface(aSurf, aELoc)) | |
581 | { | |
582 | // Update UV points | |
583 | GC->Update(); | |
584 | break; | |
7fd59977 | 585 | } |
586 | } | |
7fd59977 | 587 | } |
588 | } | |
589 | ||
7fd59977 | 590 | //======================================================================= |
591 | //function : Compare | |
592 | //purpose : | |
593 | //======================================================================= | |
594 | ||
595 | Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1, | |
596 | const TopoDS_Vertex& V2) | |
597 | { | |
598 | if (V1.IsSame(V2)) return Standard_True; | |
599 | gp_Pnt p1 = BRep_Tool::Pnt(V1); | |
600 | gp_Pnt p2 = BRep_Tool::Pnt(V2); | |
601 | Standard_Real l = p1.Distance(p2); | |
602 | if (l <= BRep_Tool::Tolerance(V1)) return Standard_True; | |
603 | if (l <= BRep_Tool::Tolerance(V2)) return Standard_True; | |
604 | return Standard_False; | |
605 | } | |
606 | ||
607 | //======================================================================= | |
608 | //function : Compare | |
609 | //purpose : | |
610 | //======================================================================= | |
611 | ||
612 | Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1, | |
613 | const TopoDS_Edge& E2) | |
614 | { | |
615 | if (E1.IsSame(E2)) return Standard_True; | |
616 | return Standard_False; | |
617 | } | |
618 | ||
619 | //======================================================================= | |
620 | //function : OuterWire | |
621 | //purpose : | |
622 | //======================================================================= | |
623 | ||
624 | TopoDS_Wire BRepTools::OuterWire(const TopoDS_Face& F) | |
625 | { | |
626 | TopoDS_Wire Wres; | |
627 | TopExp_Explorer expw (F,TopAbs_WIRE); | |
628 | ||
629 | if (expw.More()) { | |
630 | Wres = TopoDS::Wire(expw.Current()); | |
631 | expw.Next(); | |
632 | if (expw.More()) { | |
633 | Standard_Real UMin, UMax, VMin, VMax; | |
634 | Standard_Real umin, umax, vmin, vmax; | |
635 | BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax); | |
636 | while (expw.More()) { | |
637 | const TopoDS_Wire& W = TopoDS::Wire(expw.Current()); | |
638 | BRepTools::UVBounds(F,W,umin, umax, vmin, vmax); | |
639 | if ((umin <= UMin) && | |
640 | (umax >= UMax) && | |
641 | (vmin <= VMin) && | |
642 | (vmax >= VMax)) { | |
643 | Wres = W; | |
644 | UMin = umin; | |
645 | UMax = umax; | |
646 | VMin = vmin; | |
647 | VMax = vmax; | |
648 | } | |
649 | expw.Next(); | |
650 | } | |
651 | } | |
652 | } | |
653 | return Wres; | |
654 | } | |
655 | ||
7fd59977 | 656 | //======================================================================= |
657 | //function : Map3DEdges | |
658 | //purpose : | |
659 | //======================================================================= | |
660 | ||
661 | void BRepTools::Map3DEdges(const TopoDS_Shape& S, | |
662 | TopTools_IndexedMapOfShape& M) | |
663 | { | |
664 | TopExp_Explorer Ex; | |
665 | for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) { | |
666 | if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current()))) | |
667 | M.Add(Ex.Current()); | |
668 | } | |
669 | } | |
670 | ||
671 | //======================================================================= | |
672 | //function : Dump | |
673 | //purpose : | |
674 | //======================================================================= | |
675 | ||
676 | void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S) | |
677 | { | |
678 | BRepTools_ShapeSet SS; | |
679 | SS.Add(Sh); | |
680 | SS.Dump(Sh,S); | |
681 | SS.Dump(S); | |
682 | } | |
683 | ||
7fd59977 | 684 | //======================================================================= |
685 | //function : Write | |
686 | //purpose : | |
687 | //======================================================================= | |
688 | ||
689 | void BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S, | |
690 | const Handle(Message_ProgressIndicator)& PR) | |
691 | { | |
692 | BRepTools_ShapeSet SS; | |
693 | SS.SetProgress(PR); | |
694 | SS.Add(Sh); | |
695 | SS.Write(S); | |
696 | SS.Write(Sh,S); | |
697 | } | |
698 | ||
699 | ||
700 | //======================================================================= | |
701 | //function : Read | |
702 | //purpose : | |
703 | //======================================================================= | |
704 | ||
705 | void BRepTools::Read(TopoDS_Shape& Sh, | |
706 | istream& S, | |
707 | const BRep_Builder& B, | |
708 | const Handle(Message_ProgressIndicator)& PR) | |
709 | { | |
710 | BRepTools_ShapeSet SS(B); | |
711 | SS.SetProgress(PR); | |
712 | SS.Read(S); | |
713 | SS.Read(Sh,S); | |
714 | } | |
715 | ||
716 | //======================================================================= | |
717 | //function : Write | |
718 | //purpose : | |
719 | //======================================================================= | |
720 | ||
721 | Standard_Boolean BRepTools::Write(const TopoDS_Shape& Sh, | |
722 | const Standard_CString File, | |
723 | const Handle(Message_ProgressIndicator)& PR) | |
724 | { | |
725 | ofstream os; | |
94708556 | 726 | OSD_OpenStream(os, File, ios::out); |
fc8918ad | 727 | if (!os.is_open() || !os.good()) |
728 | return Standard_False; | |
7fd59977 | 729 | |
730 | Standard_Boolean isGood = (os.good() && !os.eof()); | |
731 | if(!isGood) | |
732 | return isGood; | |
733 | ||
734 | BRepTools_ShapeSet SS; | |
735 | SS.SetProgress(PR); | |
736 | SS.Add(Sh); | |
737 | ||
738 | os << "DBRep_DrawableShape\n"; // for easy Draw read | |
739 | SS.Write(os); | |
740 | isGood = os.good(); | |
741 | if(isGood ) | |
742 | SS.Write(Sh,os); | |
743 | os.flush(); | |
744 | isGood = os.good(); | |
745 | ||
746 | errno = 0; | |
747 | os.close(); | |
7fd59977 | 748 | isGood = os.good() && isGood && !errno; |
749 | ||
750 | return isGood; | |
751 | } | |
752 | ||
753 | //======================================================================= | |
754 | //function : Read | |
755 | //purpose : | |
756 | //======================================================================= | |
757 | ||
758 | Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh, | |
759 | const Standard_CString File, | |
760 | const BRep_Builder& B, | |
761 | const Handle(Message_ProgressIndicator)& PR) | |
762 | { | |
763 | filebuf fic; | |
764 | istream in(&fic); | |
fb0b0531 | 765 | OSD_OpenStream (fic, File, ios::in); |
94708556 | 766 | if(!fic.is_open()) return Standard_False; |
767 | ||
7fd59977 | 768 | BRepTools_ShapeSet SS(B); |
769 | SS.SetProgress(PR); | |
770 | SS.Read(in); | |
771 | if(!SS.NbShapes()) return Standard_False; | |
772 | SS.Read(Sh,in); | |
773 | return Standard_True; | |
774 | } | |
775 | ||
776 | ||
777 | //======================================================================= | |
778 | //function : Clean | |
779 | //purpose : | |
780 | //======================================================================= | |
781 | ||
d0a994c7 | 782 | void BRepTools::Clean(const TopoDS_Shape& theShape) |
7fd59977 | 783 | { |
d0a994c7 | 784 | BRep_Builder aBuilder; |
785 | Handle(Poly_Triangulation) aNullTriangulation; | |
786 | Handle(Poly_PolygonOnTriangulation) aNullPoly; | |
7fd59977 | 787 | |
d0a994c7 | 788 | if (theShape.IsNull()) |
789 | return; | |
790 | ||
791 | TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); | |
792 | for (; aFaceIt.More(); aFaceIt.Next()) | |
793 | { | |
794 | const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current()); | |
795 | ||
796 | TopLoc_Location aLoc; | |
797 | const Handle(Poly_Triangulation)& aTriangulation = | |
798 | BRep_Tool::Triangulation(aFace, aLoc); | |
799 | ||
800 | if (aTriangulation.IsNull()) | |
801 | continue; | |
802 | ||
803 | // Nullify edges | |
804 | TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); | |
805 | for (; aEdgeIt.More(); aEdgeIt.Next()) | |
806 | { | |
807 | const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current()); | |
808 | aBuilder.UpdateEdge(aEdge, aNullPoly, aTriangulation, aLoc); | |
7fd59977 | 809 | } |
d0a994c7 | 810 | |
811 | aBuilder.UpdateFace(aFace, aNullTriangulation); | |
7fd59977 | 812 | } |
a4ab454c | 813 | |
814 | // Iterate over all edges seeking for 3d polygons | |
815 | Handle (Poly_Polygon3D) aNullPoly3d; | |
816 | TopExp_Explorer aEdgeIt (theShape, TopAbs_EDGE); | |
817 | for (; aEdgeIt.More (); aEdgeIt.Next ()) | |
818 | { | |
819 | const TopoDS_Edge& aEdge = TopoDS::Edge (aEdgeIt.Current ()); | |
820 | ||
821 | TopLoc_Location aLoc; | |
822 | Handle (Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (aEdge, aLoc); | |
823 | if (aPoly3d.IsNull ()) | |
824 | continue; | |
825 | ||
826 | aBuilder.UpdateEdge (aEdge, aNullPoly3d); | |
827 | } | |
7fd59977 | 828 | } |
4b114473 | 829 | //======================================================================= |
830 | //function : CleanGeometry | |
831 | //purpose : | |
832 | //======================================================================= | |
833 | ||
834 | void BRepTools::CleanGeometry(const TopoDS_Shape& theShape) | |
835 | { | |
836 | if (theShape.IsNull()) | |
837 | return; | |
838 | ||
839 | BRep_Builder aBuilder; | |
840 | ||
841 | for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next()) | |
842 | { | |
843 | TopLoc_Location aLocation; | |
844 | const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current()); | |
845 | const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(aFace, aLocation); | |
846 | ||
847 | for (TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); aEdgeIt.More(); aEdgeIt.Next()) | |
848 | { | |
849 | const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Current()); | |
850 | aBuilder.UpdateEdge(anEdge, Handle(Geom2d_Curve)(), aSurface, | |
851 | aLocation, BRep_Tool::Tolerance(anEdge)); | |
852 | } | |
853 | ||
854 | aBuilder.UpdateFace(aFace, Handle(Geom_Surface)(), aFace.Location(), BRep_Tool::Tolerance(aFace)); | |
855 | } | |
856 | ||
857 | for (TopExp_Explorer aEdgeIt2(theShape, TopAbs_EDGE); aEdgeIt2.More(); aEdgeIt2.Next()) | |
858 | { | |
859 | const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt2.Current()); | |
860 | ||
861 | aBuilder.UpdateEdge(anEdge, Handle(Geom_Curve)(), | |
862 | TopLoc_Location(), BRep_Tool::Tolerance(anEdge)); | |
863 | } | |
864 | } | |
865 | ||
7fd59977 | 866 | |
01697018 J |
867 | //======================================================================= |
868 | //function : RemoveUnusedPCurves | |
869 | //purpose : | |
870 | //======================================================================= | |
871 | ||
872 | void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S) | |
873 | { | |
874 | TColStd_MapOfTransient UsedSurfaces; | |
875 | ||
876 | TopExp_Explorer Explo(S, TopAbs_FACE); | |
877 | for (; Explo.More(); Explo.Next()) | |
878 | { | |
879 | TopoDS_Face aFace = TopoDS::Face(Explo.Current()); | |
880 | TopLoc_Location aLoc; | |
881 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc); | |
882 | UsedSurfaces.Add(aSurf); | |
883 | } | |
884 | ||
885 | TopTools_IndexedMapOfShape Emap; | |
886 | TopExp::MapShapes(S, TopAbs_EDGE, Emap); | |
7fd59977 | 887 | |
01697018 J |
888 | Standard_Integer i; |
889 | for (i = 1; i <= Emap.Extent(); i++) | |
890 | { | |
891 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape()); | |
892 | BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves(); | |
893 | BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr ); | |
894 | while (itrep.More()) | |
895 | { | |
896 | Standard_Boolean ToRemove = Standard_False; | |
897 | ||
898 | Handle(BRep_CurveRepresentation) CurveRep = itrep.Value(); | |
899 | if (CurveRep->IsCurveOnSurface()) | |
900 | { | |
901 | Handle(Geom_Surface) aSurface = CurveRep->Surface(); | |
902 | if (!UsedSurfaces.Contains(aSurface)) | |
903 | ToRemove = Standard_True; | |
904 | } | |
905 | else if (CurveRep->IsRegularity()) | |
906 | { | |
907 | Handle(Geom_Surface) Surf1 = CurveRep->Surface(); | |
908 | Handle(Geom_Surface) Surf2 = CurveRep->Surface2(); | |
909 | ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2)); | |
910 | } | |
911 | ||
912 | if (ToRemove) | |
913 | lcr.Remove(itrep); | |
914 | else | |
915 | itrep.Next(); | |
916 | } | |
917 | } | |
918 | } | |
7fd59977 | 919 | |
920 | //======================================================================= | |
921 | //function : Triangulation | |
922 | //purpose : | |
923 | //======================================================================= | |
924 | ||
925 | Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& S, | |
926 | const Standard_Real deflec) | |
927 | { | |
928 | TopExp_Explorer exf, exe; | |
929 | TopLoc_Location l; | |
930 | Handle(Poly_Triangulation) T; | |
931 | Handle(Poly_PolygonOnTriangulation) Poly; | |
932 | ||
933 | for (exf.Init(S, TopAbs_FACE); exf.More(); exf.Next()) { | |
934 | const TopoDS_Face& F = TopoDS::Face(exf.Current()); | |
935 | T = BRep_Tool::Triangulation(F, l); | |
936 | if (T.IsNull() || (T->Deflection() > deflec)) | |
937 | return Standard_False; | |
938 | for (exe.Init(F, TopAbs_EDGE); exe.More(); exe.Next()) { | |
939 | const TopoDS_Edge& E = TopoDS::Edge(exe.Current()); | |
940 | Poly = BRep_Tool::PolygonOnTriangulation(E, T, l); | |
941 | if (Poly.IsNull()) return Standard_False; | |
942 | } | |
943 | } | |
944 | return Standard_True; | |
945 | } | |
946 | ||
947 | ||
948 | //======================================================================= | |
949 | //function : IsReallyClosed | |
950 | //purpose : | |
951 | //======================================================================= | |
952 | ||
953 | Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E, | |
954 | const TopoDS_Face& F) | |
955 | { | |
956 | if (!BRep_Tool::IsClosed(E,F)) { | |
957 | return Standard_False; | |
958 | } | |
959 | Standard_Integer nbocc = 0; | |
960 | TopExp_Explorer exp; | |
961 | for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) { | |
962 | if (exp.Current().IsSame(E)) { | |
963 | nbocc++; | |
964 | } | |
965 | } | |
966 | return nbocc == 2; | |
967 | } | |
968 | ||
11af6cdd | 969 | //======================================================================= |
970 | //function : DetectClosedness | |
971 | //purpose : | |
972 | //======================================================================= | |
973 | ||
974 | void BRepTools::DetectClosedness(const TopoDS_Face& theFace, | |
975 | Standard_Boolean& theUclosed, | |
976 | Standard_Boolean& theVclosed) | |
977 | { | |
978 | theUclosed = theVclosed = Standard_False; | |
979 | ||
980 | BRepAdaptor_Surface BAsurf(theFace, Standard_False); | |
981 | Standard_Boolean IsSurfUclosed = BAsurf.IsUClosed(); | |
982 | Standard_Boolean IsSurfVclosed = BAsurf.IsVClosed(); | |
983 | if (!IsSurfUclosed && !IsSurfVclosed) | |
984 | return; | |
985 | ||
986 | TopExp_Explorer Explo(theFace, TopAbs_EDGE); | |
987 | for (; Explo.More(); Explo.Next()) | |
988 | { | |
989 | const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current()); | |
990 | if (BRepTools::IsReallyClosed(anEdge, theFace)) | |
991 | { | |
992 | Standard_Real fpar, lpar; | |
993 | Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar); | |
994 | Standard_Boolean IsUiso = IsPCurveUiso(aPCurve, fpar, lpar); | |
995 | if (IsSurfUclosed && IsUiso) | |
996 | theUclosed = Standard_True; | |
997 | if (IsSurfVclosed && !IsUiso) | |
998 | theVclosed = Standard_True; | |
999 | ||
1000 | if (theUclosed && theVclosed) | |
1001 | break; | |
1002 | } | |
1003 | } | |
1004 | } | |
1005 | ||
2651bfde | 1006 | //======================================================================= |
1007 | //function : EvalAndUpdateTol | |
1008 | //purpose : | |
1009 | //======================================================================= | |
1010 | ||
1011 | Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE, | |
1012 | const Handle(Geom_Curve)& C3d, | |
1013 | const Handle(Geom2d_Curve) C2d, | |
1014 | const Handle(Geom_Surface)& S, | |
1015 | const Standard_Real f, | |
1016 | const Standard_Real l) | |
1017 | { | |
1018 | Standard_Real newtol = 0.; | |
1019 | Standard_Real first = f, last = l; | |
1020 | //Set first, last to avoid ErrosStatus = 2 because of | |
1021 | //too strong checking of limits in class CheckCurveOnSurface | |
1022 | // | |
1023 | if(!C3d->IsPeriodic()) | |
1024 | { | |
1025 | first = Max(first, C3d->FirstParameter()); | |
1026 | last = Min(last, C3d->LastParameter()); | |
1027 | } | |
1028 | if(!C2d->IsPeriodic()) | |
1029 | { | |
1030 | first = Max(first, C2d->FirstParameter()); | |
1031 | last = Min(last, C2d->LastParameter()); | |
1032 | } | |
1033 | ||
1034 | GeomLib_CheckCurveOnSurface CT(C3d, S, first, last); | |
1035 | CT.Perform(C2d); | |
1036 | if(CT.IsDone()) | |
1037 | { | |
1038 | newtol = CT.MaxDistance(); | |
1039 | } | |
1040 | else | |
1041 | { | |
1042 | if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 && | |
1043 | (C3d->IsPeriodic() || C2d->IsPeriodic()))) | |
1044 | { | |
1045 | //Try to estimate by sample points | |
1046 | Standard_Integer nbint = 22; | |
1047 | Standard_Real dt = (last - first) / nbint; | |
1048 | dt = Max(dt, Precision::Confusion()); | |
1049 | Standard_Real d, dmax = 0.; | |
1050 | gp_Pnt2d aP2d; | |
1051 | gp_Pnt aPC, aPS; | |
1052 | Standard_Integer cnt = 0; | |
1053 | Standard_Real t = first; | |
1054 | for(; t <= last; t += dt) | |
1055 | { | |
1056 | cnt++; | |
1057 | C2d->D0(t, aP2d); | |
1058 | C3d->D0(t, aPC); | |
1059 | S->D0(aP2d.X(), aP2d.Y(), aPS); | |
1060 | d = aPS.SquareDistance(aPC); | |
1061 | if(d > dmax) | |
1062 | { | |
1063 | dmax = d; | |
1064 | } | |
1065 | } | |
1066 | if(cnt < nbint + 1) | |
1067 | { | |
1068 | t = last; | |
1069 | C2d->D0(t, aP2d); | |
1070 | C3d->D0(t, aPC); | |
1071 | S->D0(aP2d.X(), aP2d.Y(), aPS); | |
1072 | d = aPS.SquareDistance(aPC); | |
1073 | if(d > dmax) | |
1074 | { | |
1075 | dmax = d; | |
1076 | } | |
1077 | } | |
1078 | ||
1079 | newtol = 1.2 * Sqrt(dmax); | |
1080 | } | |
1081 | } | |
1082 | Standard_Real Tol = BRep_Tool::Tolerance(theE); | |
1083 | if(newtol > Tol) | |
1084 | { | |
1085 | Tol = newtol; | |
1086 | BRep_Builder B; | |
1087 | B.UpdateEdge(theE, Tol); | |
1088 | } | |
1089 | ||
1090 | return Tol; | |
1091 | ||
1092 | } | |
7fd59977 | 1093 | |
1094 |