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