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