7fd59977 |
1 | // File: TopOpeBRepBuild_Tools_1.cxx |
2 | // Created: Fri Feb 11 17:21:51 2000 |
3 | // Author: Peter KURNEV |
4 | // <pkv@irinox> |
5 | |
6 | |
7 | #include <TopOpeBRepBuild_Tools.ixx> |
8 | |
9 | |
10 | #include <TopTools_IndexedMapOfShape.hxx> |
11 | #include <TopExp.hxx> |
12 | #include <TopExp_Explorer.hxx> |
13 | |
14 | #include <TopoDS.hxx> |
15 | #include <TopoDS_Edge.hxx> |
16 | #include <TopoDS_Vertex.hxx> |
17 | #include <TopoDS_Face.hxx> |
18 | |
19 | #include <TopLoc_Location.hxx> |
20 | |
21 | #include <BRep_TVertex.hxx> |
22 | #include <BRep_TEdge.hxx> |
23 | #include <BRep_TFace.hxx> |
24 | #include <BRep_Tool.hxx> |
25 | #include <BRep_GCurve.hxx> |
26 | #include <BRep_ListIteratorOfListOfPointRepresentation.hxx> |
27 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
28 | #include <BRep_CurveRepresentation.hxx> |
29 | #include <BRep_PointRepresentation.hxx> |
30 | |
31 | #include <Geom_Curve.hxx> |
32 | #include <Geom_Surface.hxx> |
33 | #include <Geom_Plane.hxx> |
34 | #include <Geom_TrimmedCurve.hxx> |
35 | |
36 | #include <GeomAdaptor_Curve.hxx> |
37 | #include <GeomAdaptor_HCurve.hxx> |
38 | #include <GeomAdaptor_HSurface.hxx> |
39 | |
40 | #include <Geom2d_Curve.hxx> |
41 | |
42 | #include <Geom2dAdaptor_HCurve.hxx> |
43 | #include <Geom_RectangularTrimmedSurface.hxx> |
44 | #include <Geom2dAdaptor.hxx> |
45 | #include <GeomProjLib.hxx> |
46 | |
47 | #include <gp_Pnt.hxx> |
48 | |
49 | #include <Adaptor3d_HCurve.hxx> |
50 | #include <Adaptor3d_CurveOnSurface.hxx> |
51 | #include <Adaptor3d_HCurveOnSurface.hxx> |
52 | |
53 | #include <ProjLib_ProjectedCurve.hxx> |
54 | #include <Extrema_LocateExtPC.hxx> |
55 | #include <BRepCheck_Wire.hxx> |
56 | |
57 | static |
58 | void CheckEdge (const TopoDS_Edge& E, |
59 | const Standard_Real aMaxTol); |
60 | static |
61 | void CorrectEdgeTolerance (const TopoDS_Edge& myShape, |
62 | const TopoDS_Face& S, |
63 | const Standard_Real aMaxTol); |
64 | static |
65 | Standard_Boolean Validate(const Adaptor3d_Curve& CRef, |
66 | const Adaptor3d_Curve& Other, |
67 | const Standard_Real Tol, |
68 | const Standard_Boolean SameParameter, |
69 | Standard_Real& aNewTolerance); |
70 | |
71 | //======================================================================= |
72 | // Function : CorrectTolerances |
73 | // purpose : |
74 | //======================================================================= |
75 | void TopOpeBRepBuild_Tools::CorrectTolerances(const TopoDS_Shape& aShape, |
76 | const Standard_Real aMaxTol) |
77 | { |
78 | TopOpeBRepBuild_Tools::CorrectPointOnCurve(aShape, aMaxTol); |
79 | TopOpeBRepBuild_Tools::CorrectCurveOnSurface(aShape, aMaxTol); |
80 | } |
81 | |
82 | //======================================================================= |
83 | // Function : CorrectPointOnCurve |
84 | // purpose : |
85 | //======================================================================= |
86 | void TopOpeBRepBuild_Tools::CorrectPointOnCurve(const TopoDS_Shape& S, |
87 | const Standard_Real aMaxTol) |
88 | { |
89 | Standard_Integer i, aNb; |
90 | TopTools_IndexedMapOfShape Edges; |
91 | TopExp::MapShapes (S, TopAbs_EDGE, Edges); |
92 | aNb=Edges.Extent(); |
93 | for (i=1; i<=aNb; i++) { |
94 | const TopoDS_Edge& E= TopoDS::Edge(Edges(i)); |
95 | CheckEdge(E, aMaxTol); |
96 | } |
97 | } |
98 | |
99 | //======================================================================= |
100 | // Function : CorrectCurveOnSurface |
101 | // purpose : |
102 | //======================================================================= |
103 | void TopOpeBRepBuild_Tools::CorrectCurveOnSurface(const TopoDS_Shape& S, |
104 | const Standard_Real aMaxTol) |
105 | { |
106 | Standard_Integer i, aNbFaces, j, aNbEdges; |
107 | TopTools_IndexedMapOfShape Faces; |
108 | TopExp::MapShapes (S, TopAbs_FACE, Faces); |
109 | |
110 | aNbFaces=Faces.Extent(); |
111 | for (i=1; i<=aNbFaces; i++) { |
112 | const TopoDS_Face& F= TopoDS::Face(Faces(i)); |
113 | TopTools_IndexedMapOfShape Edges; |
114 | TopExp::MapShapes (F, TopAbs_EDGE, Edges); |
115 | aNbEdges=Edges.Extent(); |
116 | for (j=1; j<=aNbEdges; j++) { |
117 | const TopoDS_Edge& E= TopoDS::Edge(Edges(j)); |
118 | CorrectEdgeTolerance (E, F, aMaxTol); |
119 | } |
120 | } |
121 | } |
122 | |
123 | //======================================================================= |
124 | // Function : CorrectEdgeTolerance |
125 | // purpose : Correct tolerances for Edge |
126 | //======================================================================= |
127 | void CorrectEdgeTolerance (const TopoDS_Edge& myShape, |
128 | const TopoDS_Face& S, |
129 | const Standard_Real aMaxTol) |
130 | { |
131 | // |
132 | // 1. Minimum of conditions to Perform |
133 | Handle (BRep_CurveRepresentation) myCref; |
134 | Handle (Adaptor3d_HCurve) myHCurve; |
135 | |
136 | myCref.Nullify(); |
137 | |
138 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape()); |
139 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); |
140 | Standard_Boolean Degenerated, SameParameter, SameRange; |
141 | |
142 | Standard_Integer unique = 0; |
143 | |
144 | Degenerated = TE->Degenerated(); |
145 | SameParameter = TE->SameParameter(); |
146 | SameRange = TE->SameRange(); |
147 | |
148 | if (!SameRange && SameParameter) { |
149 | return; |
150 | } |
151 | |
152 | while (itcr.More()) { |
153 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
154 | if (cr->IsCurve3D()) { |
155 | unique++; |
156 | if (myCref.IsNull() && !cr->Curve3D().IsNull()) { |
157 | myCref = cr; |
158 | } |
159 | } |
160 | itcr.Next(); |
161 | } |
162 | |
163 | if (unique==0) { |
164 | return;//...No3DCurve |
165 | } |
166 | if (unique>1) { |
167 | return;//...Multiple3DCurve; |
168 | } |
169 | |
170 | if (myCref.IsNull() && !Degenerated) { |
171 | itcr.Initialize(TE->Curves()); |
172 | while (itcr.More()) { |
173 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
174 | if (cr->IsCurveOnSurface()) { |
175 | myCref = cr; |
176 | break; |
177 | } |
178 | itcr.Next(); |
179 | } |
180 | } |
181 | |
182 | else if (!myCref.IsNull() && Degenerated){ |
183 | return ;//...InvalidDegeneratedFlag; |
184 | } |
185 | |
186 | if (!myCref.IsNull()) { |
187 | const Handle(BRep_GCurve)& GCref = *((Handle(BRep_GCurve)*)&myCref); |
188 | Standard_Real First,Last; |
189 | GCref->Range(First,Last); |
190 | if (Last<=First) { |
191 | myCref.Nullify(); |
192 | return ;//InvalidRange; |
193 | } |
194 | |
195 | else { |
196 | if (myCref->IsCurve3D()) { |
197 | Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast |
198 | (myCref->Curve3D()->Transformed (myCref->Location().Transformation())); |
199 | GeomAdaptor_Curve GAC3d(C3d,First,Last); |
200 | myHCurve = new GeomAdaptor_HCurve(GAC3d); |
201 | } |
202 | else { // curve on surface |
203 | Handle(Geom_Surface) Sref = myCref->Surface(); |
204 | Sref = Handle(Geom_Surface)::DownCast(Sref->Transformed(myCref->Location().Transformation())); |
205 | const Handle(Geom2d_Curve)& PCref = myCref->PCurve(); |
206 | Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref); |
207 | Handle(Geom2dAdaptor_HCurve) GHPCref = new Geom2dAdaptor_HCurve(PCref, First, Last); |
208 | Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref); |
209 | myHCurve = new Adaptor3d_HCurveOnSurface(ACSref); |
210 | } |
211 | } |
212 | } |
213 | |
214 | //=============================================== |
215 | // 2. Tolerances in InContext |
216 | { |
217 | if (myCref.IsNull()) |
218 | return; |
219 | Standard_Boolean ok=Standard_True; |
220 | |
221 | Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape)); |
222 | Standard_Real aNewTol=Tol; |
223 | |
224 | Standard_Real First = myHCurve->FirstParameter(); |
225 | Standard_Real Last = myHCurve->LastParameter(); |
226 | |
227 | Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape()); |
228 | const TopLoc_Location& Floc = S.Location(); |
229 | const TopLoc_Location& TFloc = TF->Location(); |
230 | const Handle(Geom_Surface)& Su = TF->Surface(); |
231 | TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location()); |
232 | // Standard_Boolean checkclosed = Standard_False; |
233 | Standard_Boolean pcurvefound = Standard_False; |
234 | |
235 | itcr.Initialize(TE->Curves()); |
236 | while (itcr.More()) { |
237 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
238 | if (cr != myCref && cr->IsCurveOnSurface(Su,L)) { |
239 | pcurvefound = Standard_True; |
240 | const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr); |
241 | Standard_Real f,l; |
242 | GC->Range(f,l); |
243 | if (SameRange && (f != First || l != Last)) { |
244 | return ;//BRepCheck_InvalidSameRangeFlag); |
245 | if (SameParameter) { |
246 | return; //BRepCheck_InvalidSameParameterFlag); |
247 | } |
248 | } |
249 | |
250 | Handle(Geom_Surface) Sb = cr->Surface(); |
251 | Sb = Handle(Geom_Surface)::DownCast (Su->Transformed(L.Transformation())); |
252 | Handle(Geom2d_Curve) PC = cr->PCurve(); |
253 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb); |
254 | Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l); |
255 | Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); |
256 | ok = Validate(myHCurve->Curve(), ACS, Tol, SameParameter, aNewTol); |
257 | if (ok) { |
258 | if (cr->IsCurveOnClosedSurface()) { |
259 | //return ;// BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); |
260 | } |
261 | else { |
262 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); |
263 | } |
264 | if (SameParameter) { |
265 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); |
266 | } |
267 | // printf("(Edge,1) Tolerance=%15.10lg\n", aNewTol); |
268 | if (aNewTol<aMaxTol) |
269 | TE->UpdateTolerance(aNewTol); |
270 | } |
271 | |
272 | if (cr->IsCurveOnClosedSurface()) { |
273 | // checkclosed = Standard_True; |
274 | GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds |
275 | ACS.Load(GAHS); // sans doute inutile |
276 | ACS.Load(GHPC); // meme remarque... |
277 | ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol); |
278 | if (ok) { |
279 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); |
280 | if (SameParameter) { |
281 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); |
282 | } |
283 | // printf("(Edge,2) Tolerance=%15.10lg\n", aNewTol); |
284 | if (aNewTol<aMaxTol) |
285 | TE->UpdateTolerance(aNewTol); |
286 | } |
287 | } |
288 | } |
289 | itcr.Next(); |
290 | } |
291 | |
292 | if (!pcurvefound) { |
293 | Handle(Geom_Plane) P; |
294 | Handle(Standard_Type) styp = Su->DynamicType(); |
295 | if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
296 | P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface):: |
297 | DownCast(Su)->BasisSurface()); |
298 | } |
299 | else { |
300 | P = Handle(Geom_Plane)::DownCast(Su); |
301 | } |
302 | if (P.IsNull()) { // not a plane |
303 | return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface); |
304 | } |
305 | |
306 | else {// on fait la projection a la volee, comme BRep_Tool |
307 | P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation())); |
308 | //on projette Cref sur ce plan |
309 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P); |
310 | |
311 | // Dub - Normalement myHCurve est une GeomAdaptor_HCurve |
312 | GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve(); |
313 | Handle(Geom_Curve) C3d = Gac.Curve(); |
314 | Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane |
315 | (new Geom_TrimmedCurve(C3d,First,Last), P, P->Position().Direction(), Standard_True); |
316 | |
317 | Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane); |
318 | |
319 | ProjLib_ProjectedCurve proj(GAHS,aHCurve); |
320 | Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj); |
321 | Handle(Geom2dAdaptor_HCurve) GHPC = |
322 | new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter()); |
323 | |
324 | Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); |
325 | |
326 | ok = Validate(myHCurve->Curve(),ACS, |
327 | Tol,Standard_True, aNewTol); // voir dub... |
328 | if (ok) { |
329 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); |
330 | // printf("(Edge,3) Tolerance=%15.10lg\n", aNewTol); |
331 | if (aNewTol<aMaxTol) |
332 | TE->UpdateTolerance(aNewTol); |
333 | } |
334 | } |
335 | |
336 | }//end of if (!pcurvefound) { |
337 | } // end of 2. Tolerances in InContext |
338 | |
339 | } |
340 | |
341 | #define NCONTROL 23 |
342 | //======================================================================= |
343 | //function : Validate |
344 | //purpose : |
345 | //======================================================================= |
346 | Standard_Boolean Validate(const Adaptor3d_Curve& CRef, |
347 | const Adaptor3d_Curve& Other, |
348 | const Standard_Real Tol, |
349 | const Standard_Boolean SameParameter, |
350 | Standard_Real& aNewTolerance) |
351 | { |
352 | Standard_Real First, Last, MaxDistance, aD; |
353 | |
354 | First = CRef.FirstParameter(); |
355 | Last = CRef.LastParameter(); |
356 | MaxDistance = Tol*Tol; |
357 | |
358 | Standard_Integer i, aNC1=NCONTROL-1; |
359 | |
360 | Standard_Boolean aFlag=Standard_False; |
361 | Standard_Boolean proj = (!SameParameter || |
362 | First != Other.FirstParameter() || |
363 | Last != Other.LastParameter()); |
364 | // |
365 | // 1. |
366 | if (!proj) { |
367 | for (i = 0; i < NCONTROL; i++) { |
368 | Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1; |
369 | gp_Pnt pref = CRef.Value(prm); |
370 | gp_Pnt pother = Other.Value(prm); |
371 | |
372 | aD=pref.SquareDistance(pother); |
373 | |
374 | if (aD > MaxDistance) { |
375 | MaxDistance=aD; |
376 | aFlag=Standard_True; |
377 | } |
378 | } |
379 | } |
380 | |
381 | // |
382 | // 2. |
383 | else { |
384 | Extrema_LocateExtPC refd,otherd; |
385 | Standard_Real OFirst, OLast; |
386 | OFirst = Other.FirstParameter(); |
387 | OLast = Other.LastParameter(); |
388 | |
389 | gp_Pnt pd = CRef.Value(First); |
390 | gp_Pnt pdo = Other.Value(OFirst); |
391 | |
392 | aD = pd.SquareDistance(pdo); |
393 | if (aD > MaxDistance) { |
394 | MaxDistance=aD; |
395 | aFlag=Standard_True; |
396 | } |
397 | |
398 | pd = CRef.Value(Last); |
399 | pdo = Other.Value(OLast); |
400 | aD = pd.SquareDistance(pdo); |
401 | if (aD > MaxDistance) { |
402 | MaxDistance=aD; |
403 | aFlag=Standard_True; |
404 | } |
405 | |
406 | refd.Initialize(CRef, First, Last, CRef.Resolution(Tol)); |
407 | otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol)); |
408 | |
409 | for (i = 2; i< aNC1; i++) { |
410 | Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1; |
411 | gp_Pnt pref = CRef.Value(rprm); |
412 | |
413 | Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1; |
414 | gp_Pnt pother = Other.Value(oprm); |
415 | |
416 | refd.Perform(pother,rprm); |
417 | if (!refd.IsDone() || refd.SquareDistance() > Tol * Tol) { |
418 | if (refd.IsDone()) { |
419 | aD=refd.SquareDistance(); |
420 | if (aD > MaxDistance) { |
421 | aFlag=Standard_True; |
422 | MaxDistance=aD; |
423 | } |
424 | } |
425 | } |
426 | |
427 | otherd.Perform(pref,oprm); |
428 | if (!otherd.IsDone() || otherd.SquareDistance() > Tol * Tol) { |
429 | |
430 | if (otherd.IsDone()) { |
431 | aD=otherd.SquareDistance(); |
432 | if (aD > MaxDistance) { |
433 | aFlag=Standard_True; |
434 | MaxDistance=aD; |
435 | } |
436 | } |
437 | } |
438 | } |
439 | } |
440 | |
441 | if (aFlag) { |
442 | aD=sqrt (MaxDistance); |
443 | aNewTolerance=aD*1.05; |
444 | } |
445 | |
446 | return aFlag; |
447 | |
448 | } |
449 | |
450 | //======================================================================= |
451 | // Function : CheckEdge |
452 | // purpose : Correct tolerances for Vertices on Edge |
453 | //======================================================================= |
454 | void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol) |
455 | { |
456 | TopoDS_Edge E=Ed; |
457 | E.Orientation(TopAbs_FORWARD); |
458 | |
459 | gp_Pnt Controlp; |
460 | |
461 | TopExp_Explorer aVExp; |
462 | aVExp.Init(E, TopAbs_VERTEX); |
463 | for (; aVExp.More(); aVExp.Next()) { |
464 | TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current()); |
465 | |
466 | Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape()); |
467 | const gp_Pnt& prep = TV->Pnt(); |
468 | |
469 | Standard_Real Tol, aD2, aNewTolerance, dd; |
470 | |
471 | Tol =BRep_Tool::Tolerance(aVertex); |
472 | Tol = Max(Tol, BRep_Tool::Tolerance(E)); |
473 | dd=0.1*Tol; |
474 | Tol*=Tol; |
475 | |
476 | const TopLoc_Location& Eloc = E.Location(); |
477 | BRep_ListIteratorOfListOfPointRepresentation itpr; |
478 | |
479 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape()); |
480 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); |
481 | while (itcr.More()) { |
482 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
483 | const TopLoc_Location& loc = cr->Location(); |
484 | TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location()); |
485 | |
486 | if (cr->IsCurve3D()) { |
487 | const Handle(Geom_Curve)& C = cr->Curve3D(); |
488 | if (!C.IsNull()) { |
489 | itpr.Initialize(TV->Points()); |
490 | while (itpr.More()) { |
491 | const Handle(BRep_PointRepresentation)& pr = itpr.Value(); |
492 | if (pr->IsPointOnCurve(C,L)) { |
493 | Controlp = C->Value(pr->Parameter()); |
494 | Controlp.Transform(L.Transformation()); |
495 | aD2=prep.SquareDistance(Controlp); |
496 | if (aD2 > Tol) { |
497 | aNewTolerance=sqrt(aD2)+dd; |
498 | // printf("(Vert,1) Tolerance=%15.10lg\n", aNewTolerance); |
499 | if (aNewTolerance<aMaxTol) |
500 | TV->UpdateTolerance(aNewTolerance); |
501 | } |
502 | } |
503 | itpr.Next(); |
504 | } |
505 | |
506 | TopAbs_Orientation orv = aVertex.Orientation(); |
507 | if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) { |
508 | const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr); |
509 | |
510 | if (orv==TopAbs_FORWARD) |
511 | Controlp = C->Value(GC->First()); |
512 | else |
513 | Controlp = C->Value(GC->Last()); |
514 | |
515 | Controlp.Transform(L.Transformation()); |
516 | aD2=prep.SquareDistance(Controlp); |
517 | |
518 | if (aD2 > Tol) { |
519 | aNewTolerance=sqrt(aD2)+dd; |
520 | // printf("(Vert,2) Tolerance=%15.10lg\n", aNewTolerance); |
521 | if (aNewTolerance<aMaxTol) |
522 | TV->UpdateTolerance(aNewTolerance); |
523 | } |
524 | } |
525 | } |
526 | } |
527 | itcr.Next(); |
528 | } |
529 | } |
530 | } |
531 | |
532 | //======================================================================= |
533 | //function : CheckFaceClosed2d |
534 | //purpose : |
535 | //======================================================================= |
536 | |
537 | Standard_Boolean TopOpeBRepBuild_Tools::CheckFaceClosed2d(const TopoDS_Face& theFace) |
538 | { |
539 | Standard_Boolean isClosed = Standard_True; |
540 | TopExp_Explorer ex(theFace,TopAbs_WIRE); |
541 | for (; ex.More() && isClosed; ex.Next()) { |
542 | const TopoDS_Wire& aW = TopoDS::Wire(ex.Current()); |
543 | BRepCheck_Wire aWChk(aW); |
544 | BRepCheck_Status aStatus = aWChk.Orientation(theFace); |
545 | if (aStatus != BRepCheck_NoError) |
546 | isClosed = Standard_False; |
547 | } |
548 | return isClosed; |
549 | } |