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 <OSD_OpenFile.hxx> |
40 | #include <Poly_PolygonOnTriangulation.hxx> | |
41 | #include <Poly_Triangulation.hxx> | |
42 | #include <Precision.hxx> | |
7fd59977 | 43 | #include <Standard_ErrorHandler.hxx> |
44 | #include <Standard_Failure.hxx> | |
42cf5bc1 | 45 | #include <Standard_Stream.hxx> |
46 | #include <TColGeom2d_SequenceOfCurve.hxx> | |
47 | #include <TColgp_SequenceOfPnt2d.hxx> | |
48 | #include <TColStd_Array1OfReal.hxx> | |
49 | #include <TColStd_HArray1OfInteger.hxx> | |
50 | #include <TColStd_MapOfTransient.hxx> | |
51 | #include <TColStd_SequenceOfReal.hxx> | |
52 | #include <TopExp.hxx> | |
53 | #include <TopExp_Explorer.hxx> | |
54 | #include <TopoDS.hxx> | |
55 | #include <TopoDS_Compound.hxx> | |
56 | #include <TopoDS_CompSolid.hxx> | |
57 | #include <TopoDS_Edge.hxx> | |
58 | #include <TopoDS_Face.hxx> | |
42cf5bc1 | 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> |
11af6cdd | 67 | |
68 | ||
7fd59977 | 69 | //======================================================================= |
70 | //function : UVBounds | |
71 | //purpose : | |
72 | //======================================================================= | |
7fd59977 | 73 | void BRepTools::UVBounds(const TopoDS_Face& F, |
74 | Standard_Real& UMin, Standard_Real& UMax, | |
75 | Standard_Real& VMin, Standard_Real& VMax) | |
76 | { | |
77 | Bnd_Box2d B; | |
78 | AddUVBounds(F,B); | |
413b1c1a | 79 | if (!B.IsVoid()) |
80 | { | |
81 | B.Get(UMin,VMin,UMax,VMax); | |
82 | } | |
83 | else | |
84 | { | |
85 | UMin = UMax = VMin = VMax = 0.0; | |
86 | } | |
7fd59977 | 87 | } |
88 | ||
89 | //======================================================================= | |
90 | //function : UVBounds | |
91 | //purpose : | |
92 | //======================================================================= | |
93 | ||
94 | void BRepTools::UVBounds(const TopoDS_Face& F, | |
95 | const TopoDS_Wire& W, | |
96 | Standard_Real& UMin, Standard_Real& UMax, | |
97 | Standard_Real& VMin, Standard_Real& VMax) | |
98 | { | |
99 | Bnd_Box2d B; | |
100 | AddUVBounds(F,W,B); | |
413b1c1a | 101 | if (!B.IsVoid()) |
102 | { | |
103 | B.Get(UMin,VMin,UMax,VMax); | |
104 | } | |
105 | else | |
106 | { | |
107 | UMin = UMax = VMin = VMax = 0.0; | |
108 | } | |
7fd59977 | 109 | } |
110 | ||
111 | ||
112 | //======================================================================= | |
113 | //function : UVBounds | |
114 | //purpose : | |
115 | //======================================================================= | |
116 | ||
117 | void BRepTools::UVBounds(const TopoDS_Face& F, | |
118 | const TopoDS_Edge& E, | |
119 | Standard_Real& UMin, Standard_Real& UMax, | |
120 | Standard_Real& VMin, Standard_Real& VMax) | |
121 | { | |
122 | Bnd_Box2d B; | |
123 | AddUVBounds(F,E,B); | |
413b1c1a | 124 | if (!B.IsVoid()) |
125 | { | |
126 | B.Get(UMin,VMin,UMax,VMax); | |
127 | } | |
128 | else | |
129 | { | |
130 | UMin = UMax = VMin = VMax = 0.0; | |
131 | } | |
7fd59977 | 132 | } |
133 | ||
134 | //======================================================================= | |
135 | //function : AddUVBounds | |
136 | //purpose : | |
137 | //======================================================================= | |
138 | ||
139 | void BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B) | |
140 | { | |
141 | TopoDS_Face F = FF; | |
142 | F.Orientation(TopAbs_FORWARD); | |
143 | TopExp_Explorer ex(F,TopAbs_EDGE); | |
144 | ||
145 | // fill box for the given face | |
146 | Bnd_Box2d aBox; | |
147 | for (;ex.More();ex.Next()) { | |
148 | BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),aBox); | |
149 | } | |
150 | ||
151 | // if the box is empty (face without edges or without pcurves), | |
152 | // get natural bounds | |
153 | if (aBox.IsVoid()) { | |
154 | Standard_Real UMin,UMax,VMin,VMax; | |
155 | TopLoc_Location L; | |
413b1c1a | 156 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(F, L); |
157 | if (aSurf.IsNull()) | |
158 | { | |
159 | return; | |
160 | } | |
161 | ||
162 | aSurf->Bounds(UMin,UMax,VMin,VMax); | |
7fd59977 | 163 | aBox.Update(UMin,VMin,UMax,VMax); |
164 | } | |
165 | ||
166 | // add face box to result | |
167 | B.Add ( aBox ); | |
168 | } | |
169 | ||
170 | ||
171 | //======================================================================= | |
172 | //function : AddUVBounds | |
173 | //purpose : | |
174 | //======================================================================= | |
7fd59977 | 175 | void BRepTools::AddUVBounds(const TopoDS_Face& F, |
176 | const TopoDS_Wire& W, | |
177 | Bnd_Box2d& B) | |
178 | { | |
179 | TopExp_Explorer ex; | |
180 | for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) { | |
181 | BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),B); | |
182 | } | |
183 | } | |
184 | ||
185 | ||
186 | //======================================================================= | |
187 | //function : AddUVBounds | |
188 | //purpose : | |
189 | //======================================================================= | |
59495dbe | 190 | void BRepTools::AddUVBounds(const TopoDS_Face& aF, |
6219c44c | 191 | const TopoDS_Edge& aE, |
192 | Bnd_Box2d& aB) | |
7fd59977 | 193 | { |
413b1c1a | 194 | Standard_Real aT1, aT2, aXmin = 0.0, aYmin = 0.0, aXmax = 0.0, aYmax = 0.0; |
59495dbe | 195 | Standard_Real aUmin, aUmax, aVmin, aVmax; |
196 | Bnd_Box2d aBoxC, aBoxS; | |
197 | TopLoc_Location aLoc; | |
198 | // | |
199 | const Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); | |
200 | if (aC2D.IsNull()) { | |
201 | return; | |
202 | } | |
203 | // | |
204 | BndLib_Add2dCurve::Add(aC2D, aT1, aT2, 0., aBoxC); | |
413b1c1a | 205 | if (!aBoxC.IsVoid()) |
206 | { | |
207 | aBoxC.Get(aXmin, aYmin, aXmax, aYmax); | |
208 | } | |
59495dbe | 209 | // |
210 | Handle(Geom_Surface) aS = BRep_Tool::Surface(aF, aLoc); | |
211 | aS->Bounds(aUmin, aUmax, aVmin, aVmax); | |
212 | ||
213 | if(aS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) | |
214 | { | |
215 | const Handle(Geom_RectangularTrimmedSurface) aSt = | |
216 | Handle(Geom_RectangularTrimmedSurface)::DownCast(aS); | |
217 | aS = aSt->BasisSurface(); | |
7fd59977 | 218 | } |
7fd59977 | 219 | |
59495dbe | 220 | // |
221 | if(!aS->IsUPeriodic()) | |
222 | { | |
6219c44c | 223 | Standard_Boolean isUPeriodic = Standard_False; |
224 | ||
225 | // Additional verification for U-periodicity for B-spline surfaces | |
226 | // 1. Verify that the surface is U-closed (if such flag is false). Verification uses 2 points | |
227 | // 2. Verify periodicity of surface inside UV-bounds of the edge. Verification uses 3 or 6 points. | |
228 | if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) && | |
229 | (aXmin < aUmin || aXmax > aUmax)) | |
9c06009a | 230 | { |
6219c44c | 231 | Standard_Real aTol2 = 100 * Precision::Confusion() * Precision::Confusion(); |
232 | isUPeriodic = Standard_True; | |
233 | gp_Pnt P1, P2; | |
234 | // 1. Verify that the surface is U-closed | |
235 | if (!aS->IsUClosed()) | |
236 | { | |
237 | Standard_Real aVStep = aVmax - aVmin; | |
238 | for (Standard_Real aV = aVmin; aV <= aVmax; aV += aVStep) | |
239 | { | |
240 | P1 = aS->Value(aUmin, aV); | |
241 | P2 = aS->Value(aUmax, aV); | |
242 | if (P1.SquareDistance(P2) > aTol2) | |
243 | { | |
244 | isUPeriodic = Standard_False; | |
245 | break; | |
246 | } | |
247 | } | |
248 | } | |
249 | // 2. Verify periodicity of surface inside UV-bounds of the edge | |
250 | if (isUPeriodic) // the flag still not changed | |
251 | { | |
252 | Standard_Real aV = (aVmin + aVmax) * 0.5; | |
253 | Standard_Real aU[6]; // values of U lying out of surface boundaries | |
254 | Standard_Real aUpp[6]; // corresponding U-values plus/minus period | |
255 | Standard_Integer aNbPnt = 0; | |
256 | if (aXmin < aUmin) | |
257 | { | |
258 | aU[0] = aXmin; | |
259 | aU[1] = (aXmin + aUmin) * 0.5; | |
260 | aU[2] = aUmin; | |
261 | aUpp[0] = aU[0] + aUmax - aUmin; | |
262 | aUpp[1] = aU[1] + aUmax - aUmin; | |
263 | aUpp[2] = aU[2] + aUmax - aUmin; | |
264 | aNbPnt += 3; | |
265 | } | |
266 | if (aXmax > aUmax) | |
267 | { | |
268 | aU[aNbPnt] = aUmax; | |
269 | aU[aNbPnt + 1] = (aXmax + aUmax) * 0.5; | |
270 | aU[aNbPnt + 2] = aXmax; | |
271 | aUpp[aNbPnt] = aU[aNbPnt] - aUmax + aUmin; | |
272 | aUpp[aNbPnt + 1] = aU[aNbPnt + 1] - aUmax + aUmin; | |
273 | aUpp[aNbPnt + 2] = aU[aNbPnt + 2] - aUmax + aUmin; | |
274 | aNbPnt += 3; | |
275 | } | |
276 | for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++) | |
277 | { | |
278 | P1 = aS->Value(aU[anInd], aV); | |
279 | P2 = aS->Value(aUpp[anInd], aV); | |
280 | if (P1.SquareDistance(P2) > aTol2) | |
281 | { | |
282 | isUPeriodic = Standard_False; | |
283 | break; | |
284 | } | |
285 | } | |
286 | } | |
9c06009a | 287 | } |
6219c44c | 288 | |
289 | if (!isUPeriodic) | |
59495dbe | 290 | { |
6219c44c | 291 | if((aXmin<aUmin) && (aUmin < aXmax)) |
292 | { | |
293 | aXmin=aUmin; | |
294 | } | |
295 | if((aXmin < aUmax) && (aUmax < aXmax)) | |
296 | { | |
297 | aXmax=aUmax; | |
298 | } | |
7fd59977 | 299 | } |
59495dbe | 300 | } |
7fd59977 | 301 | |
59495dbe | 302 | if(!aS->IsVPeriodic()) |
303 | { | |
6219c44c | 304 | Standard_Boolean isVPeriodic = Standard_False; |
305 | ||
306 | // Additional verification for V-periodicity for B-spline surfaces | |
307 | // 1. Verify that the surface is V-closed (if such flag is false). Verification uses 2 points | |
308 | // 2. Verify periodicity of surface inside UV-bounds of the edge. Verification uses 3 or 6 points. | |
309 | if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) && | |
310 | (aYmin < aVmin || aYmax > aVmax)) | |
59495dbe | 311 | { |
6219c44c | 312 | Standard_Real aTol2 = 100 * Precision::Confusion() * Precision::Confusion(); |
313 | isVPeriodic = Standard_True; | |
314 | gp_Pnt P1, P2; | |
315 | // 1. Verify that the surface is V-closed | |
316 | if (!aS->IsVClosed()) | |
317 | { | |
318 | Standard_Real aUStep = aUmax - aUmin; | |
319 | for (Standard_Real aU = aUmin; aU <= aUmax; aU += aUStep) | |
320 | { | |
321 | P1 = aS->Value(aU, aVmin); | |
322 | P2 = aS->Value(aU, aVmax); | |
323 | if (P1.SquareDistance(P2) > aTol2) | |
324 | { | |
325 | isVPeriodic = Standard_False; | |
326 | break; | |
327 | } | |
328 | } | |
329 | } | |
330 | // 2. Verify periodicity of surface inside UV-bounds of the edge | |
331 | if (isVPeriodic) // the flag still not changed | |
332 | { | |
333 | Standard_Real aU = (aUmin + aUmax) * 0.5; | |
334 | Standard_Real aV[6]; // values of V lying out of surface boundaries | |
335 | Standard_Real aVpp[6]; // corresponding V-values plus/minus period | |
336 | Standard_Integer aNbPnt = 0; | |
337 | if (aYmin < aVmin) | |
338 | { | |
339 | aV[0] = aYmin; | |
340 | aV[1] = (aYmin + aVmin) * 0.5; | |
341 | aV[2] = aVmin; | |
342 | aVpp[0] = aV[0] + aVmax - aVmin; | |
343 | aVpp[1] = aV[1] + aVmax - aVmin; | |
344 | aVpp[2] = aV[2] + aVmax - aVmin; | |
345 | aNbPnt += 3; | |
346 | } | |
347 | if (aYmax > aVmax) | |
348 | { | |
349 | aV[aNbPnt] = aVmax; | |
350 | aV[aNbPnt + 1] = (aYmax + aVmax) * 0.5; | |
351 | aV[aNbPnt + 2] = aYmax; | |
352 | aVpp[aNbPnt] = aV[aNbPnt] - aVmax + aVmin; | |
353 | aVpp[aNbPnt + 1] = aV[aNbPnt + 1] - aVmax + aVmin; | |
354 | aVpp[aNbPnt + 2] = aV[aNbPnt + 2] - aVmax + aVmin; | |
355 | aNbPnt += 3; | |
356 | } | |
357 | for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++) | |
358 | { | |
359 | P1 = aS->Value(aU, aV[anInd]); | |
360 | P2 = aS->Value(aU, aVpp[anInd]); | |
361 | if (P1.SquareDistance(P2) > aTol2) | |
362 | { | |
363 | isVPeriodic = Standard_False; | |
364 | break; | |
365 | } | |
366 | } | |
367 | } | |
7fd59977 | 368 | } |
6219c44c | 369 | |
370 | if (!isVPeriodic) | |
59495dbe | 371 | { |
6219c44c | 372 | if((aYmin<aVmin) && (aVmin < aYmax)) |
373 | { | |
374 | aYmin=aVmin; | |
375 | } | |
376 | if((aYmin < aVmax) && (aVmax < aYmax)) | |
377 | { | |
378 | aYmax=aVmax; | |
379 | } | |
59495dbe | 380 | } |
7fd59977 | 381 | } |
59495dbe | 382 | |
383 | aBoxS.Update(aXmin, aYmin, aXmax, aYmax); | |
384 | ||
385 | aB.Add(aBoxS); | |
7fd59977 | 386 | } |
387 | ||
388 | //======================================================================= | |
389 | //function : Update | |
390 | //purpose : | |
391 | //======================================================================= | |
392 | ||
393 | void BRepTools::Update(const TopoDS_Vertex&) | |
394 | { | |
395 | } | |
396 | ||
397 | //======================================================================= | |
398 | //function : Update | |
399 | //purpose : | |
400 | //======================================================================= | |
401 | ||
402 | void BRepTools::Update(const TopoDS_Edge&) | |
403 | { | |
404 | } | |
405 | ||
406 | //======================================================================= | |
407 | //function : Update | |
408 | //purpose : | |
409 | //======================================================================= | |
410 | ||
411 | void BRepTools::Update(const TopoDS_Wire&) | |
412 | { | |
413 | } | |
414 | ||
415 | //======================================================================= | |
416 | //function : Update | |
417 | //purpose : | |
418 | //======================================================================= | |
419 | ||
420 | void BRepTools::Update(const TopoDS_Face& F) | |
421 | { | |
422 | if (!F.Checked()) { | |
423 | UpdateFaceUVPoints(F); | |
424 | F.TShape()->Checked(Standard_True); | |
425 | } | |
426 | } | |
427 | ||
428 | //======================================================================= | |
429 | //function : Update | |
430 | //purpose : | |
431 | //======================================================================= | |
432 | ||
433 | void BRepTools::Update(const TopoDS_Shell& S) | |
434 | { | |
435 | TopExp_Explorer ex(S,TopAbs_FACE); | |
436 | while (ex.More()) { | |
437 | Update(TopoDS::Face(ex.Current())); | |
438 | ex.Next(); | |
439 | } | |
440 | } | |
441 | ||
442 | //======================================================================= | |
443 | //function : Update | |
444 | //purpose : | |
445 | //======================================================================= | |
446 | ||
447 | void BRepTools::Update(const TopoDS_Solid& S) | |
448 | { | |
449 | TopExp_Explorer ex(S,TopAbs_FACE); | |
450 | while (ex.More()) { | |
451 | Update(TopoDS::Face(ex.Current())); | |
452 | ex.Next(); | |
453 | } | |
454 | } | |
455 | ||
456 | //======================================================================= | |
457 | //function : Update | |
458 | //purpose : | |
459 | //======================================================================= | |
460 | ||
461 | void BRepTools::Update(const TopoDS_CompSolid& CS) | |
462 | { | |
463 | TopExp_Explorer ex(CS,TopAbs_FACE); | |
464 | while (ex.More()) { | |
465 | Update(TopoDS::Face(ex.Current())); | |
466 | ex.Next(); | |
467 | } | |
468 | } | |
469 | ||
470 | //======================================================================= | |
471 | //function : Update | |
472 | //purpose : | |
473 | //======================================================================= | |
474 | ||
475 | void BRepTools::Update(const TopoDS_Compound& C) | |
476 | { | |
477 | TopExp_Explorer ex(C,TopAbs_FACE); | |
478 | while (ex.More()) { | |
479 | Update(TopoDS::Face(ex.Current())); | |
480 | ex.Next(); | |
481 | } | |
482 | } | |
483 | ||
484 | //======================================================================= | |
485 | //function : Update | |
486 | //purpose : | |
487 | //======================================================================= | |
488 | ||
489 | void BRepTools::Update(const TopoDS_Shape& S) | |
490 | { | |
491 | switch (S.ShapeType()) { | |
492 | ||
493 | case TopAbs_VERTEX : | |
494 | Update(TopoDS::Vertex(S)); | |
495 | break; | |
496 | ||
497 | case TopAbs_EDGE : | |
498 | Update(TopoDS::Edge(S)); | |
499 | break; | |
500 | ||
501 | case TopAbs_WIRE : | |
502 | Update(TopoDS::Wire(S)); | |
503 | break; | |
504 | ||
505 | case TopAbs_FACE : | |
506 | Update(TopoDS::Face(S)); | |
507 | break; | |
508 | ||
509 | case TopAbs_SHELL : | |
510 | Update(TopoDS::Shell(S)); | |
511 | break; | |
512 | ||
513 | case TopAbs_SOLID : | |
514 | Update(TopoDS::Solid(S)); | |
515 | break; | |
516 | ||
517 | case TopAbs_COMPSOLID : | |
518 | Update(TopoDS::CompSolid(S)); | |
519 | break; | |
520 | ||
521 | case TopAbs_COMPOUND : | |
522 | Update(TopoDS::Compound(S)); | |
523 | break; | |
524 | ||
525 | default: | |
526 | break; | |
527 | ||
528 | } | |
529 | } | |
530 | ||
7fd59977 | 531 | //======================================================================= |
532 | //function : UpdateFaceUVPoints | |
e50ebf1f | 533 | //purpose : Reset the UV points of edges on the Face |
7fd59977 | 534 | //======================================================================= |
e50ebf1f | 535 | void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& theF) |
7fd59977 | 536 | { |
e50ebf1f | 537 | // For each edge of the face <F> reset the UV points to the bounding |
538 | // points of the parametric curve of the edge on the face. | |
7fd59977 | 539 | |
e50ebf1f | 540 | // Get surface of the face |
541 | TopLoc_Location aLoc; | |
542 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(theF, aLoc); | |
543 | // Iterate on edges and reset UV points | |
544 | TopExp_Explorer anExpE(theF, TopAbs_EDGE); | |
545 | for (; anExpE.More(); anExpE.Next()) | |
7fd59977 | 546 | { |
e50ebf1f | 547 | const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current()); |
548 | ||
549 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape()); | |
550 | if (TE->Locked()) | |
551 | return; | |
552 | ||
553 | const TopLoc_Location aELoc = aLoc.Predivided(aE.Location()); | |
554 | // Edge representations | |
555 | BRep_ListOfCurveRepresentation& aLCR = TE->ChangeCurves(); | |
556 | BRep_ListIteratorOfListOfCurveRepresentation itLCR(aLCR); | |
557 | for (; itLCR.More(); itLCR.Next()) | |
558 | { | |
559 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itLCR.Value()); | |
560 | if (!GC.IsNull() && GC->IsCurveOnSurface(aSurf, aELoc)) | |
561 | { | |
562 | // Update UV points | |
563 | GC->Update(); | |
564 | break; | |
7fd59977 | 565 | } |
566 | } | |
7fd59977 | 567 | } |
568 | } | |
569 | ||
7fd59977 | 570 | //======================================================================= |
571 | //function : Compare | |
572 | //purpose : | |
573 | //======================================================================= | |
574 | ||
575 | Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1, | |
576 | const TopoDS_Vertex& V2) | |
577 | { | |
578 | if (V1.IsSame(V2)) return Standard_True; | |
579 | gp_Pnt p1 = BRep_Tool::Pnt(V1); | |
580 | gp_Pnt p2 = BRep_Tool::Pnt(V2); | |
581 | Standard_Real l = p1.Distance(p2); | |
582 | if (l <= BRep_Tool::Tolerance(V1)) return Standard_True; | |
583 | if (l <= BRep_Tool::Tolerance(V2)) return Standard_True; | |
584 | return Standard_False; | |
585 | } | |
586 | ||
587 | //======================================================================= | |
588 | //function : Compare | |
589 | //purpose : | |
590 | //======================================================================= | |
591 | ||
592 | Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1, | |
593 | const TopoDS_Edge& E2) | |
594 | { | |
595 | if (E1.IsSame(E2)) return Standard_True; | |
596 | return Standard_False; | |
597 | } | |
598 | ||
599 | //======================================================================= | |
600 | //function : OuterWire | |
601 | //purpose : | |
602 | //======================================================================= | |
603 | ||
604 | TopoDS_Wire BRepTools::OuterWire(const TopoDS_Face& F) | |
605 | { | |
606 | TopoDS_Wire Wres; | |
607 | TopExp_Explorer expw (F,TopAbs_WIRE); | |
608 | ||
609 | if (expw.More()) { | |
610 | Wres = TopoDS::Wire(expw.Current()); | |
611 | expw.Next(); | |
612 | if (expw.More()) { | |
613 | Standard_Real UMin, UMax, VMin, VMax; | |
614 | Standard_Real umin, umax, vmin, vmax; | |
615 | BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax); | |
616 | while (expw.More()) { | |
617 | const TopoDS_Wire& W = TopoDS::Wire(expw.Current()); | |
618 | BRepTools::UVBounds(F,W,umin, umax, vmin, vmax); | |
619 | if ((umin <= UMin) && | |
620 | (umax >= UMax) && | |
621 | (vmin <= VMin) && | |
622 | (vmax >= VMax)) { | |
623 | Wres = W; | |
624 | UMin = umin; | |
625 | UMax = umax; | |
626 | VMin = vmin; | |
627 | VMax = vmax; | |
628 | } | |
629 | expw.Next(); | |
630 | } | |
631 | } | |
632 | } | |
633 | return Wres; | |
634 | } | |
635 | ||
7fd59977 | 636 | //======================================================================= |
637 | //function : Map3DEdges | |
638 | //purpose : | |
639 | //======================================================================= | |
640 | ||
641 | void BRepTools::Map3DEdges(const TopoDS_Shape& S, | |
642 | TopTools_IndexedMapOfShape& M) | |
643 | { | |
644 | TopExp_Explorer Ex; | |
645 | for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) { | |
646 | if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current()))) | |
647 | M.Add(Ex.Current()); | |
648 | } | |
649 | } | |
650 | ||
651 | //======================================================================= | |
652 | //function : Dump | |
653 | //purpose : | |
654 | //======================================================================= | |
655 | ||
656 | void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S) | |
657 | { | |
658 | BRepTools_ShapeSet SS; | |
659 | SS.Add(Sh); | |
660 | SS.Dump(Sh,S); | |
661 | SS.Dump(S); | |
662 | } | |
663 | ||
7fd59977 | 664 | //======================================================================= |
665 | //function : Write | |
666 | //purpose : | |
667 | //======================================================================= | |
668 | ||
669 | void BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S, | |
6d8f9f4a | 670 | const Handle(Message_ProgressIndicator)& theProgress) |
7fd59977 | 671 | { |
672 | BRepTools_ShapeSet SS; | |
7fd59977 | 673 | SS.Add(Sh); |
6d8f9f4a | 674 | SS.Write(S, theProgress); |
7fd59977 | 675 | SS.Write(Sh,S); |
676 | } | |
677 | ||
678 | ||
679 | //======================================================================= | |
680 | //function : Read | |
681 | //purpose : | |
682 | //======================================================================= | |
683 | ||
684 | void BRepTools::Read(TopoDS_Shape& Sh, | |
04232180 | 685 | std::istream& S, |
7fd59977 | 686 | const BRep_Builder& B, |
6d8f9f4a | 687 | const Handle(Message_ProgressIndicator)& theProgress) |
7fd59977 | 688 | { |
689 | BRepTools_ShapeSet SS(B); | |
6d8f9f4a | 690 | SS.Read(S, theProgress); |
7fd59977 | 691 | SS.Read(Sh,S); |
692 | } | |
693 | ||
694 | //======================================================================= | |
695 | //function : Write | |
696 | //purpose : | |
697 | //======================================================================= | |
698 | ||
699 | Standard_Boolean BRepTools::Write(const TopoDS_Shape& Sh, | |
700 | const Standard_CString File, | |
6d8f9f4a | 701 | const Handle(Message_ProgressIndicator)& theProgress) |
7fd59977 | 702 | { |
04232180 | 703 | std::ofstream os; |
704 | OSD_OpenStream(os, File, std::ios::out); | |
fc8918ad | 705 | if (!os.is_open() || !os.good()) |
706 | return Standard_False; | |
7fd59977 | 707 | |
708 | Standard_Boolean isGood = (os.good() && !os.eof()); | |
709 | if(!isGood) | |
710 | return isGood; | |
711 | ||
712 | BRepTools_ShapeSet SS; | |
7fd59977 | 713 | SS.Add(Sh); |
714 | ||
715 | os << "DBRep_DrawableShape\n"; // for easy Draw read | |
6d8f9f4a | 716 | SS.Write(os, theProgress); |
7fd59977 | 717 | isGood = os.good(); |
718 | if(isGood ) | |
719 | SS.Write(Sh,os); | |
720 | os.flush(); | |
721 | isGood = os.good(); | |
722 | ||
723 | errno = 0; | |
724 | os.close(); | |
7fd59977 | 725 | isGood = os.good() && isGood && !errno; |
726 | ||
727 | return isGood; | |
728 | } | |
729 | ||
730 | //======================================================================= | |
731 | //function : Read | |
732 | //purpose : | |
733 | //======================================================================= | |
734 | ||
735 | Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh, | |
736 | const Standard_CString File, | |
737 | const BRep_Builder& B, | |
6d8f9f4a | 738 | const Handle(Message_ProgressIndicator)& theProgress) |
7fd59977 | 739 | { |
04232180 | 740 | std::filebuf fic; |
741 | std::istream in(&fic); | |
742 | OSD_OpenStream (fic, File, std::ios::in); | |
94708556 | 743 | if(!fic.is_open()) return Standard_False; |
744 | ||
7fd59977 | 745 | BRepTools_ShapeSet SS(B); |
6d8f9f4a | 746 | SS.Read(in, theProgress); |
7fd59977 | 747 | if(!SS.NbShapes()) return Standard_False; |
748 | SS.Read(Sh,in); | |
749 | return Standard_True; | |
750 | } | |
751 | ||
752 | ||
753 | //======================================================================= | |
754 | //function : Clean | |
755 | //purpose : | |
756 | //======================================================================= | |
757 | ||
128654b6 | 758 | void BRepTools::Clean (const TopoDS_Shape& theShape) |
7fd59977 | 759 | { |
128654b6 | 760 | if (theShape.IsNull()) |
761 | return; | |
762 | ||
d0a994c7 | 763 | BRep_Builder aBuilder; |
764 | Handle(Poly_Triangulation) aNullTriangulation; | |
765 | Handle(Poly_PolygonOnTriangulation) aNullPoly; | |
7fd59977 | 766 | |
128654b6 | 767 | TopTools_MapOfShape aShapeMap; |
768 | const TopLoc_Location anEmptyLoc; | |
d0a994c7 | 769 | |
770 | TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); | |
771 | for (; aFaceIt.More(); aFaceIt.Next()) | |
772 | { | |
128654b6 | 773 | TopoDS_Shape aFaceNoLoc = aFaceIt.Value(); |
774 | aFaceNoLoc.Location (anEmptyLoc); | |
775 | if (!aShapeMap.Add (aFaceNoLoc)) | |
776 | { | |
777 | // the face has already been processed | |
778 | continue; | |
779 | } | |
780 | ||
781 | const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current()); | |
782 | if (!BRep_Tool::IsGeometric (aFace)) | |
783 | { | |
784 | // Do not remove triangulation as there is no surface to recompute it. | |
785 | continue; | |
786 | } | |
787 | ||
d0a994c7 | 788 | |
789 | TopLoc_Location aLoc; | |
790 | const Handle(Poly_Triangulation)& aTriangulation = | |
791 | BRep_Tool::Triangulation(aFace, aLoc); | |
792 | ||
793 | if (aTriangulation.IsNull()) | |
794 | continue; | |
795 | ||
796 | // Nullify edges | |
128654b6 | 797 | // Theoretically, the edges on the face (with surface) may have no geometry |
798 | // (no curve 3d or 2d or both). Such faces should be considered as invalid and | |
799 | // are not supported by current implementation. So, both triangulation of the face | |
800 | // and polygon on triangulation of the edges are removed unconditionally. | |
d0a994c7 | 801 | TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); |
802 | for (; aEdgeIt.More(); aEdgeIt.Next()) | |
803 | { | |
804 | const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current()); | |
805 | aBuilder.UpdateEdge(aEdge, aNullPoly, aTriangulation, aLoc); | |
7fd59977 | 806 | } |
d0a994c7 | 807 | |
808 | aBuilder.UpdateFace(aFace, aNullTriangulation); | |
7fd59977 | 809 | } |
a4ab454c | 810 | |
811 | // Iterate over all edges seeking for 3d polygons | |
812 | Handle (Poly_Polygon3D) aNullPoly3d; | |
813 | TopExp_Explorer aEdgeIt (theShape, TopAbs_EDGE); | |
814 | for (; aEdgeIt.More (); aEdgeIt.Next ()) | |
815 | { | |
128654b6 | 816 | TopoDS_Edge anEdgeNoLoc = TopoDS::Edge (aEdgeIt.Value()); |
817 | anEdgeNoLoc.Location (anEmptyLoc); | |
818 | ||
819 | if (!aShapeMap.Add (anEdgeNoLoc)) | |
820 | { | |
821 | // the edge has already been processed | |
822 | continue; | |
823 | } | |
824 | ||
825 | if (!BRep_Tool::IsGeometric (TopoDS::Edge (anEdgeNoLoc))) | |
826 | { | |
827 | // Do not remove polygon 3d as there is no curve to recompute it. | |
828 | continue; | |
829 | } | |
a4ab454c | 830 | |
831 | TopLoc_Location aLoc; | |
128654b6 | 832 | Handle (Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (anEdgeNoLoc, aLoc); |
833 | if (aPoly3d.IsNull()) | |
a4ab454c | 834 | continue; |
835 | ||
128654b6 | 836 | aBuilder.UpdateEdge (anEdgeNoLoc, aNullPoly3d); |
a4ab454c | 837 | } |
7fd59977 | 838 | } |
4b114473 | 839 | //======================================================================= |
840 | //function : CleanGeometry | |
841 | //purpose : | |
842 | //======================================================================= | |
843 | ||
844 | void BRepTools::CleanGeometry(const TopoDS_Shape& theShape) | |
845 | { | |
846 | if (theShape.IsNull()) | |
847 | return; | |
848 | ||
849 | BRep_Builder aBuilder; | |
850 | ||
851 | for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next()) | |
852 | { | |
853 | TopLoc_Location aLocation; | |
854 | const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current()); | |
855 | const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(aFace, aLocation); | |
856 | ||
857 | for (TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); aEdgeIt.More(); aEdgeIt.Next()) | |
858 | { | |
859 | const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Current()); | |
860 | aBuilder.UpdateEdge(anEdge, Handle(Geom2d_Curve)(), aSurface, | |
861 | aLocation, BRep_Tool::Tolerance(anEdge)); | |
862 | } | |
863 | ||
864 | aBuilder.UpdateFace(aFace, Handle(Geom_Surface)(), aFace.Location(), BRep_Tool::Tolerance(aFace)); | |
865 | } | |
866 | ||
867 | for (TopExp_Explorer aEdgeIt2(theShape, TopAbs_EDGE); aEdgeIt2.More(); aEdgeIt2.Next()) | |
868 | { | |
869 | const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt2.Current()); | |
870 | ||
871 | aBuilder.UpdateEdge(anEdge, Handle(Geom_Curve)(), | |
872 | TopLoc_Location(), BRep_Tool::Tolerance(anEdge)); | |
873 | } | |
874 | } | |
875 | ||
7fd59977 | 876 | |
01697018 J |
877 | //======================================================================= |
878 | //function : RemoveUnusedPCurves | |
879 | //purpose : | |
880 | //======================================================================= | |
881 | ||
882 | void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S) | |
883 | { | |
884 | TColStd_MapOfTransient UsedSurfaces; | |
885 | ||
886 | TopExp_Explorer Explo(S, TopAbs_FACE); | |
887 | for (; Explo.More(); Explo.Next()) | |
888 | { | |
889 | TopoDS_Face aFace = TopoDS::Face(Explo.Current()); | |
890 | TopLoc_Location aLoc; | |
891 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc); | |
892 | UsedSurfaces.Add(aSurf); | |
893 | } | |
894 | ||
895 | TopTools_IndexedMapOfShape Emap; | |
896 | TopExp::MapShapes(S, TopAbs_EDGE, Emap); | |
7fd59977 | 897 | |
01697018 J |
898 | Standard_Integer i; |
899 | for (i = 1; i <= Emap.Extent(); i++) | |
900 | { | |
901 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape()); | |
902 | BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves(); | |
903 | BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr ); | |
904 | while (itrep.More()) | |
905 | { | |
906 | Standard_Boolean ToRemove = Standard_False; | |
907 | ||
908 | Handle(BRep_CurveRepresentation) CurveRep = itrep.Value(); | |
909 | if (CurveRep->IsCurveOnSurface()) | |
910 | { | |
911 | Handle(Geom_Surface) aSurface = CurveRep->Surface(); | |
912 | if (!UsedSurfaces.Contains(aSurface)) | |
913 | ToRemove = Standard_True; | |
914 | } | |
915 | else if (CurveRep->IsRegularity()) | |
916 | { | |
917 | Handle(Geom_Surface) Surf1 = CurveRep->Surface(); | |
918 | Handle(Geom_Surface) Surf2 = CurveRep->Surface2(); | |
919 | ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2)); | |
920 | } | |
921 | ||
922 | if (ToRemove) | |
923 | lcr.Remove(itrep); | |
924 | else | |
925 | itrep.Next(); | |
926 | } | |
927 | } | |
928 | } | |
7fd59977 | 929 | |
930 | //======================================================================= | |
931 | //function : Triangulation | |
932 | //purpose : | |
933 | //======================================================================= | |
934 | ||
29263c94 | 935 | Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& theShape, |
936 | const Standard_Real theLinDefl, | |
937 | const Standard_Boolean theToCheckFreeEdges) | |
7fd59977 | 938 | { |
29263c94 | 939 | TopExp_Explorer anEdgeIter; |
940 | TopLoc_Location aDummyLoc; | |
941 | for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next()) | |
942 | { | |
943 | const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current()); | |
944 | const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation (aFace, aDummyLoc); | |
945 | if (aTri.IsNull() | |
946 | || aTri->Deflection() > theLinDefl) | |
947 | { | |
7fd59977 | 948 | return Standard_False; |
7fd59977 | 949 | } |
29263c94 | 950 | |
951 | for (anEdgeIter.Init (aFace, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next()) | |
952 | { | |
953 | const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current()); | |
954 | const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTri, aDummyLoc); | |
955 | if (aPoly.IsNull()) | |
956 | { | |
957 | return Standard_False; | |
958 | } | |
959 | } | |
960 | } | |
961 | if (!theToCheckFreeEdges) | |
962 | { | |
963 | return Standard_True; | |
7fd59977 | 964 | } |
29263c94 | 965 | |
966 | Handle(Poly_Triangulation) anEdgeTri; | |
967 | for (anEdgeIter.Init (theShape, TopAbs_EDGE, TopAbs_FACE); anEdgeIter.More(); anEdgeIter.Next()) | |
968 | { | |
969 | const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current()); | |
970 | const Handle(Poly_Polygon3D)& aPolygon = BRep_Tool::Polygon3D (anEdge, aDummyLoc); | |
971 | if (!aPolygon.IsNull()) | |
972 | { | |
973 | if (aPolygon->Deflection() > theLinDefl) | |
974 | { | |
975 | return Standard_False; | |
976 | } | |
977 | } | |
978 | else | |
979 | { | |
980 | const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeTri, aDummyLoc); | |
981 | if (aPoly.IsNull() | |
982 | || anEdgeTri.IsNull() | |
983 | || anEdgeTri->Deflection() > theLinDefl) | |
984 | { | |
985 | return Standard_False; | |
986 | } | |
987 | } | |
988 | } | |
989 | ||
7fd59977 | 990 | return Standard_True; |
991 | } | |
992 | ||
993 | ||
994 | //======================================================================= | |
995 | //function : IsReallyClosed | |
996 | //purpose : | |
997 | //======================================================================= | |
998 | ||
999 | Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E, | |
1000 | const TopoDS_Face& F) | |
1001 | { | |
1002 | if (!BRep_Tool::IsClosed(E,F)) { | |
1003 | return Standard_False; | |
1004 | } | |
1005 | Standard_Integer nbocc = 0; | |
1006 | TopExp_Explorer exp; | |
1007 | for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) { | |
1008 | if (exp.Current().IsSame(E)) { | |
1009 | nbocc++; | |
1010 | } | |
1011 | } | |
1012 | return nbocc == 2; | |
1013 | } | |
1014 | ||
11af6cdd | 1015 | //======================================================================= |
1016 | //function : DetectClosedness | |
1017 | //purpose : | |
1018 | //======================================================================= | |
1019 | ||
1020 | void BRepTools::DetectClosedness(const TopoDS_Face& theFace, | |
1021 | Standard_Boolean& theUclosed, | |
1022 | Standard_Boolean& theVclosed) | |
1023 | { | |
1024 | theUclosed = theVclosed = Standard_False; | |
1025 | ||
11af6cdd | 1026 | TopExp_Explorer Explo(theFace, TopAbs_EDGE); |
1027 | for (; Explo.More(); Explo.Next()) | |
1028 | { | |
1029 | const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current()); | |
85c103d2 | 1030 | if (BRep_Tool::IsClosed(anEdge, theFace) && |
1031 | BRepTools::IsReallyClosed(anEdge, theFace)) | |
11af6cdd | 1032 | { |
1033 | Standard_Real fpar, lpar; | |
85c103d2 | 1034 | Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar); |
1035 | Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(anEdge.Reversed()), | |
1036 | theFace, fpar, lpar); | |
1037 | gp_Pnt2d Point1 = PCurve1->Value(fpar); | |
1038 | gp_Pnt2d Point2 = PCurve2->Value(fpar); | |
1039 | Standard_Boolean IsUiso = (Abs(Point1.X() - Point2.X()) > Abs(Point1.Y() - Point2.Y())); | |
1040 | if (IsUiso) | |
11af6cdd | 1041 | theUclosed = Standard_True; |
85c103d2 | 1042 | else |
11af6cdd | 1043 | theVclosed = Standard_True; |
11af6cdd | 1044 | } |
1045 | } | |
1046 | } | |
1047 | ||
2651bfde | 1048 | //======================================================================= |
1049 | //function : EvalAndUpdateTol | |
1050 | //purpose : | |
1051 | //======================================================================= | |
1052 | ||
1053 | Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE, | |
1054 | const Handle(Geom_Curve)& C3d, | |
1055 | const Handle(Geom2d_Curve) C2d, | |
1056 | const Handle(Geom_Surface)& S, | |
1057 | const Standard_Real f, | |
1058 | const Standard_Real l) | |
1059 | { | |
1060 | Standard_Real newtol = 0.; | |
1061 | Standard_Real first = f, last = l; | |
1062 | //Set first, last to avoid ErrosStatus = 2 because of | |
1063 | //too strong checking of limits in class CheckCurveOnSurface | |
1064 | // | |
1065 | if(!C3d->IsPeriodic()) | |
1066 | { | |
1067 | first = Max(first, C3d->FirstParameter()); | |
1068 | last = Min(last, C3d->LastParameter()); | |
1069 | } | |
1070 | if(!C2d->IsPeriodic()) | |
1071 | { | |
1072 | first = Max(first, C2d->FirstParameter()); | |
1073 | last = Min(last, C2d->LastParameter()); | |
1074 | } | |
1075 | ||
1076 | GeomLib_CheckCurveOnSurface CT(C3d, S, first, last); | |
1077 | CT.Perform(C2d); | |
1078 | if(CT.IsDone()) | |
1079 | { | |
1080 | newtol = CT.MaxDistance(); | |
1081 | } | |
1082 | else | |
1083 | { | |
1084 | if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 && | |
1085 | (C3d->IsPeriodic() || C2d->IsPeriodic()))) | |
1086 | { | |
1087 | //Try to estimate by sample points | |
1088 | Standard_Integer nbint = 22; | |
1089 | Standard_Real dt = (last - first) / nbint; | |
1090 | dt = Max(dt, Precision::Confusion()); | |
1091 | Standard_Real d, dmax = 0.; | |
1092 | gp_Pnt2d aP2d; | |
1093 | gp_Pnt aPC, aPS; | |
1094 | Standard_Integer cnt = 0; | |
1095 | Standard_Real t = first; | |
1096 | for(; t <= last; t += dt) | |
1097 | { | |
1098 | cnt++; | |
1099 | C2d->D0(t, aP2d); | |
1100 | C3d->D0(t, aPC); | |
1101 | S->D0(aP2d.X(), aP2d.Y(), aPS); | |
1102 | d = aPS.SquareDistance(aPC); | |
1103 | if(d > dmax) | |
1104 | { | |
1105 | dmax = d; | |
1106 | } | |
1107 | } | |
1108 | if(cnt < nbint + 1) | |
1109 | { | |
1110 | t = last; | |
1111 | C2d->D0(t, aP2d); | |
1112 | C3d->D0(t, aPC); | |
1113 | S->D0(aP2d.X(), aP2d.Y(), aPS); | |
1114 | d = aPS.SquareDistance(aPC); | |
1115 | if(d > dmax) | |
1116 | { | |
1117 | dmax = d; | |
1118 | } | |
1119 | } | |
1120 | ||
1121 | newtol = 1.2 * Sqrt(dmax); | |
1122 | } | |
1123 | } | |
1124 | Standard_Real Tol = BRep_Tool::Tolerance(theE); | |
1125 | if(newtol > Tol) | |
1126 | { | |
1127 | Tol = newtol; | |
1128 | BRep_Builder B; | |
1129 | B.UpdateEdge(theE, Tol); | |
1130 | } | |
1131 | ||
1132 | return Tol; | |
1133 | ||
1134 | } | |
7fd59977 | 1135 | |
eff3eff9 | 1136 | //======================================================================= |
1137 | //function : OriEdgeInFace | |
1138 | //purpose : | |
1139 | //======================================================================= | |
7fd59977 | 1140 | |
eff3eff9 | 1141 | TopAbs_Orientation BRepTools::OriEdgeInFace (const TopoDS_Edge& E, |
1142 | const TopoDS_Face& F ) | |
1143 | ||
1144 | { | |
1145 | TopExp_Explorer Exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE); | |
1146 | ||
1147 | for (; Exp.More() ;Exp.Next()) { | |
1148 | if (Exp.Current().IsSame(E)) { | |
1149 | return Exp.Current().Orientation(); | |
1150 | } | |
1151 | } | |
1152 | throw Standard_ConstructionError("BRepTools::OriEdgeInFace"); | |
1153 | } | |
09543c2d | 1154 | |
1155 | ||
1156 | namespace | |
1157 | { | |
1158 | //======================================================================= | |
1159 | //function : findInternalsToKeep | |
1160 | //purpose : Looks for internal sub-shapes which has to be kept to preserve | |
1161 | // topological connectivity. | |
1162 | //======================================================================= | |
1163 | static void findInternalsToKeep (const TopoDS_Shape& theS, | |
1164 | TopTools_MapOfShape& theAllNonInternals, | |
1165 | TopTools_MapOfShape& theAllInternals, | |
1166 | TopTools_MapOfShape& theShapesToKeep) | |
1167 | { | |
1168 | for (TopoDS_Iterator it (theS, Standard_True); it.More(); it.Next()) | |
1169 | { | |
1170 | const TopoDS_Shape& aSS = it.Value(); | |
1171 | findInternalsToKeep (aSS, theAllNonInternals, theAllInternals, theShapesToKeep); | |
1172 | ||
1173 | if (aSS.Orientation() == TopAbs_INTERNAL) | |
1174 | theAllInternals.Add (aSS); | |
1175 | else | |
1176 | theAllNonInternals.Add (aSS); | |
1177 | ||
1178 | if (theAllNonInternals.Contains(aSS) && theAllInternals.Contains (aSS)) | |
1179 | theShapesToKeep.Add (aSS); | |
1180 | } | |
1181 | } | |
1182 | ||
1183 | //======================================================================= | |
1184 | //function : removeShapes | |
1185 | //purpose : Removes sub-shapes from the shape | |
1186 | //======================================================================= | |
1187 | static void removeShapes (TopoDS_Shape& theS, | |
1188 | const TopTools_ListOfShape& theLS) | |
1189 | { | |
1190 | BRep_Builder aBB; | |
1191 | Standard_Boolean isFree = theS.Free(); | |
1192 | theS.Free (Standard_True); | |
1193 | ||
1194 | for (TopTools_ListOfShape::Iterator it (theLS); it.More(); it.Next()) | |
1195 | { | |
1196 | aBB.Remove (theS, it.Value()); | |
1197 | } | |
1198 | theS.Free (isFree); | |
1199 | } | |
1200 | ||
1201 | //======================================================================= | |
1202 | //function : removeInternals | |
1203 | //purpose : Removes recursively all internal sub-shapes from the given shape. | |
1204 | // Returns true if all sub-shapes have been removed from the shape. | |
1205 | //======================================================================= | |
1206 | static Standard_Boolean removeInternals (TopoDS_Shape& theS, | |
1207 | const TopTools_MapOfShape* theShapesToKeep) | |
1208 | { | |
1209 | TopTools_ListOfShape aLRemove; | |
1210 | for (TopoDS_Iterator it (theS, Standard_True); it.More(); it.Next()) | |
1211 | { | |
1212 | const TopoDS_Shape& aSS = it.Value(); | |
1213 | if (aSS.Orientation() == TopAbs_INTERNAL) | |
1214 | { | |
1215 | if (!theShapesToKeep || !theShapesToKeep->Contains (aSS)) | |
1216 | aLRemove.Append (aSS); | |
1217 | } | |
1218 | else | |
1219 | { | |
1220 | if (removeInternals (*(TopoDS_Shape*)&aSS, theShapesToKeep)) | |
1221 | aLRemove.Append (aSS); | |
1222 | } | |
1223 | } | |
1224 | ||
1225 | Standard_Integer aNbSToRemove = aLRemove.Extent(); | |
1226 | if (aNbSToRemove) | |
1227 | { | |
1228 | removeShapes (theS, aLRemove); | |
1229 | return (theS.NbChildren() == 0); | |
1230 | } | |
1231 | return Standard_False; | |
1232 | } | |
1233 | ||
1234 | } | |
1235 | ||
1236 | //======================================================================= | |
1237 | //function : RemoveInternals | |
1238 | //purpose : | |
1239 | //======================================================================= | |
1240 | void BRepTools::RemoveInternals (TopoDS_Shape& theS, | |
1241 | const Standard_Boolean theForce) | |
1242 | { | |
1243 | TopTools_MapOfShape *pMKeep = NULL, aMKeep; | |
1244 | if (!theForce) | |
1245 | { | |
1246 | // Find all internal sub-shapes which has to be kept to preserve topological connectivity. | |
1247 | // Note that if the multi-connected shape is not directly contained in some shape, | |
1248 | // but as a part of bigger sub-shape which will be removed, the multi-connected | |
1249 | // shape is going to be removed also, breaking topological connectivity. | |
1250 | // For instance, <theS> is a compound of the face and edge, which does not | |
1251 | // belong to the face. The face contains internal wire and the edge shares | |
1252 | // the vertex with one of the vertices of that wire. The vertex is not directly | |
1253 | // contained in the face, thus will be removed as part of internal wire, and topological | |
1254 | // connectivity between edge and face will be lost. | |
1255 | TopTools_MapOfShape anAllNonInternals, anAllInternals; | |
1256 | findInternalsToKeep (theS, anAllNonInternals, anAllInternals, aMKeep); | |
1257 | if (aMKeep.Extent()) | |
1258 | pMKeep = &aMKeep; | |
1259 | } | |
1260 | ||
1261 | removeInternals (theS, pMKeep); | |
1262 | } |