b311480e |
1 | // Created on: 1996-04-23 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1996-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | |
23 | #include <BRepFeat.ixx> |
24 | |
25 | //#include <BRepAlgo_Cut.hxx> |
26 | |
27 | #include <BRepBuilderAPI.hxx> |
28 | #include <BRepAdaptor_Curve.hxx> |
29 | #include <TopExp_Explorer.hxx> |
30 | #include <TopTools_MapOfShape.hxx> |
31 | #include <BRep_Tool.hxx> |
32 | #include <BRep_Builder.hxx> |
33 | #include <Geom_Curve.hxx> |
34 | #include <Geom_TrimmedCurve.hxx> |
35 | #include <Geom2d_TrimmedCurve.hxx> |
36 | #include <Extrema_ExtPC.hxx> |
37 | #include <GeomAdaptor_Curve.hxx> |
38 | #include <BRepLProp.hxx> |
39 | #include <TopoDS.hxx> |
40 | #include <TopoDS_Vertex.hxx> |
41 | #include <TopoDS_Face.hxx> |
42 | #include <TopoDS_Edge.hxx> |
43 | #include <TopoDS_Shell.hxx> |
44 | #include <TopoDS_Solid.hxx> |
45 | #include <Precision.hxx> |
46 | #include <GCPnts_QuasiUniformDeflection.hxx> |
47 | #include <BRepTopAdaptor_FClass2d.hxx> |
48 | #include <Geom2dAdaptor_Curve.hxx> |
49 | #include <GeomProjLib.hxx> |
50 | #include <gp_Vec2d.hxx> |
51 | #include <BRepTools.hxx> |
52 | #include <Geom_Surface.hxx> |
53 | #include <Bnd_Box.hxx> |
54 | #include <BRepBndLib.hxx> |
55 | #include <BRepLib_MakeFace.hxx> |
56 | #include <Geom_RectangularTrimmedSurface.hxx> |
57 | #include <Geom_Plane.hxx> |
58 | #include <Geom_CylindricalSurface.hxx> |
59 | #include <Geom_ConicalSurface.hxx> |
60 | #include <LocOpe_CSIntersector.hxx> |
61 | #include <LocOpe_PntFace.hxx> |
62 | #include <LocOpe_BuildShape.hxx> |
63 | |
64 | #include <TColGeom_SequenceOfCurve.hxx> |
65 | |
66 | |
67 | #include <LocOpe.hxx> |
68 | |
69 | #define NECHANTBARYC 11 |
70 | |
71 | //======================================================================= |
72 | //function : SampleEdges |
73 | //purpose : |
74 | //======================================================================= |
75 | |
76 | void BRepFeat::SampleEdges(const TopoDS_Shape& theShape, |
77 | TColgp_SequenceOfPnt& theSeq) |
78 | { |
79 | LocOpe::SampleEdges(theShape,theSeq); |
80 | } |
81 | |
82 | |
83 | |
84 | //======================================================================= |
85 | //function : Barycenter |
86 | //purpose : Calcul du barycentre des edges d'un shape |
87 | //======================================================================= |
88 | |
89 | void BRepFeat::Barycenter(const TopoDS_Shape& S, |
90 | gp_Pnt& B) |
91 | { |
92 | TopTools_MapOfShape theMap; |
93 | TopExp_Explorer exp(S,TopAbs_EDGE); |
94 | TopLoc_Location Loc; |
95 | Handle(Geom_Curve) C; |
96 | Standard_Real f,l,prm; |
97 | gp_XYZ Bar(0.,0.,0.); |
98 | Standard_Integer i, nbp= 0; |
99 | |
100 | for (; exp.More(); exp.Next()) { |
101 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
102 | if (!theMap.Add(edg)) { |
103 | continue; |
104 | } |
105 | if (!BRep_Tool::Degenerated(edg)) { |
106 | C = BRep_Tool::Curve(edg,Loc,f,l); |
107 | C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation())); |
108 | for (i=1;i<NECHANTBARYC; i++) { |
109 | prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC; |
110 | Bar += C->Value(prm).XYZ(); |
111 | nbp++; |
112 | } |
113 | } |
114 | } |
115 | // Adds every vertex |
116 | for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) { |
117 | if (theMap.Add(exp.Current())) { |
118 | Bar += (BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()))).XYZ(); |
119 | nbp++; |
120 | } |
121 | } |
122 | |
123 | Bar.Divide((Standard_Real)nbp); |
124 | B.SetXYZ(Bar); |
125 | } |
126 | |
127 | |
128 | //======================================================================= |
129 | //function : ParametricBarycenter |
130 | //purpose : Calcul du barycentre "parametrique" shape sur une courbe |
131 | //======================================================================= |
132 | |
133 | Standard_Real BRepFeat::ParametricBarycenter(const TopoDS_Shape& S, |
134 | const Handle(Geom_Curve)& CC) |
135 | { |
136 | TopTools_MapOfShape theMap; |
137 | TopExp_Explorer exp(S,TopAbs_EDGE); |
138 | TopLoc_Location Loc; |
139 | Handle(Geom_Curve) C; |
140 | Standard_Real f,l,prm; |
141 | Standard_Integer i, nbp= 0; |
142 | GeomAdaptor_Curve TheCurve(CC); |
143 | Extrema_ExtPC extpc; |
144 | extpc.Initialize(TheCurve,CC->FirstParameter(),CC->LastParameter()); |
145 | Standard_Real parbar = 0; |
146 | |
147 | for (; exp.More(); exp.Next()) { |
148 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
149 | if (!theMap.Add(edg)) { |
150 | continue; |
151 | } |
152 | if (!BRep_Tool::Degenerated(edg)) { |
153 | C = BRep_Tool::Curve(edg,Loc,f,l); |
154 | C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation())); |
155 | for (i=1;i<NECHANTBARYC; i++) { |
156 | prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC; |
157 | gp_Pnt pone = C->Value(prm); |
158 | // On projette sur CC |
159 | extpc.Perform(pone); |
160 | if (extpc.IsDone() && extpc.NbExt() >= 1) { |
161 | Standard_Real Dist2Min = extpc.SquareDistance(1); |
162 | Standard_Integer kmin = 1; |
163 | for (Standard_Integer k=2; k<=extpc.NbExt(); k++) { |
164 | Standard_Real Dist2 = extpc.SquareDistance(k); |
165 | if (Dist2 < Dist2Min) { |
166 | Dist2Min = Dist2; |
167 | kmin = k; |
168 | } |
169 | } |
170 | nbp++; |
171 | Standard_Real prmp = extpc.Point(kmin).Parameter(); |
172 | parbar += prmp; |
173 | } |
174 | } |
175 | } |
176 | } |
177 | // Adds every vertex |
178 | for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) { |
179 | if (theMap.Add(exp.Current())) { |
180 | gp_Pnt pone = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current())); |
181 | // On projette sur CC |
182 | extpc.Perform(pone); |
183 | if (extpc.IsDone() && extpc.NbExt() >= 1) { |
184 | Standard_Real Dist2Min = extpc.SquareDistance(1); |
185 | Standard_Integer kmin = 1; |
186 | for (Standard_Integer k=2; k<=extpc.NbExt(); k++) { |
187 | Standard_Real Dist2 = extpc.SquareDistance(k); |
188 | if (Dist2 < Dist2Min) { |
189 | Dist2Min = Dist2; |
190 | kmin = k; |
191 | } |
192 | } |
193 | nbp++; |
194 | #ifdef DEB |
195 | Standard_Real prmp = extpc.Point(kmin).Parameter(); |
196 | #else |
197 | extpc.Point(kmin).Parameter(); |
198 | #endif |
199 | } |
200 | } |
201 | } |
202 | |
203 | parbar /=((Standard_Real)nbp); |
204 | return parbar; |
205 | } |
206 | |
207 | |
208 | //======================================================================= |
209 | //function : ParametricBarycenter |
210 | //purpose : Calcul du barycentre "parametrique" shape sur une courbe |
211 | //======================================================================= |
212 | |
213 | void BRepFeat::ParametricMinMax(const TopoDS_Shape& S, |
214 | const Handle(Geom_Curve)& CC, |
215 | Standard_Real& prmin, |
216 | Standard_Real& prmax, |
217 | Standard_Real& prbmin, |
218 | Standard_Real& prbmax, |
219 | Standard_Boolean& flag, |
220 | const Standard_Boolean Ori) |
221 | { |
222 | LocOpe_CSIntersector ASI(S); |
223 | TColGeom_SequenceOfCurve scur; |
224 | scur.Append(CC); |
225 | ASI.Perform(scur); |
226 | if(ASI.IsDone() && ASI.NbPoints(1) >=1) { |
227 | if (!Ori) { |
228 | prmin = Min(ASI.Point(1,1).Parameter(), |
229 | ASI.Point(1, ASI.NbPoints(1)).Parameter()); |
230 | prmax = Max(ASI.Point(1,1).Parameter(), |
231 | ASI.Point(1, ASI.NbPoints(1)).Parameter()); |
232 | } |
233 | else { |
234 | TopAbs_Orientation Ori = ASI.Point(1,1).Orientation(); |
235 | if (Ori == TopAbs_FORWARD) { |
236 | prmin = ASI.Point(1,1).Parameter(); |
237 | prmax = ASI.Point(1, ASI.NbPoints(1)).Parameter(); |
238 | } |
239 | else { |
240 | prmax = ASI.Point(1,1).Parameter(); |
241 | prmin = ASI.Point(1, ASI.NbPoints(1)).Parameter(); |
242 | } |
243 | } |
244 | flag = Standard_True; |
245 | } |
246 | else { |
247 | prmax = RealFirst(); |
248 | prmin = RealLast(); |
249 | flag = Standard_False; |
250 | } |
251 | |
252 | TopTools_MapOfShape theMap; |
253 | TopExp_Explorer exp(S,TopAbs_EDGE); |
254 | TopLoc_Location Loc; |
255 | Handle(Geom_Curve) C; |
256 | Standard_Real f,l,prm; |
257 | // Standard_Integer i, nbp= 0; |
258 | Standard_Integer i; |
259 | GeomAdaptor_Curve TheCurve(CC); |
260 | Extrema_ExtPC extpc; |
261 | extpc.Initialize(TheCurve,CC->FirstParameter(),CC->LastParameter()); |
262 | prbmin = RealLast(); |
263 | prbmax = RealFirst(); |
264 | for (; exp.More(); exp.Next()) { |
265 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
266 | if (!theMap.Add(edg)) { |
267 | continue; |
268 | } |
269 | if (!BRep_Tool::Degenerated(edg)) { |
270 | C = BRep_Tool::Curve(edg,Loc,f,l); |
271 | C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation())); |
272 | for (i=1;i<NECHANTBARYC; i++) { |
273 | prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC; |
274 | gp_Pnt pone = C->Value(prm); |
275 | // On projette sur CC |
276 | extpc.Perform(pone); |
277 | if (extpc.IsDone() && extpc.NbExt() >= 1) { |
278 | Standard_Real Dist2Min = extpc.SquareDistance(1); |
279 | Standard_Integer kmin = 1; |
280 | for (Standard_Integer k=2; k<=extpc.NbExt(); k++) { |
281 | Standard_Real Dist2 = extpc.SquareDistance(k); |
282 | if (Dist2 < Dist2Min) { |
283 | Dist2Min = Dist2; |
284 | kmin = k; |
285 | } |
286 | } |
287 | Standard_Real prmp = extpc.Point(kmin).Parameter(); |
288 | if (prmp <= prbmin) { |
289 | prbmin = prmp; |
290 | } |
291 | if (prmp >= prbmax) { |
292 | prbmax = prmp; |
293 | } |
294 | } |
295 | } |
296 | } |
297 | } |
298 | // Adds every vertex |
299 | for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) { |
300 | if (theMap.Add(exp.Current())) { |
301 | gp_Pnt pone = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current())); |
302 | // On projette sur CC |
303 | extpc.Perform(pone); |
304 | if (extpc.IsDone() && extpc.NbExt() >= 1) { |
305 | Standard_Real Dist2Min = extpc.SquareDistance(1); |
306 | Standard_Integer kmin = 1; |
307 | for (Standard_Integer k=2; k<=extpc.NbExt(); k++) { |
308 | Standard_Real Dist2 = extpc.SquareDistance(k); |
309 | if (Dist2 < Dist2Min) { |
310 | Dist2Min = Dist2; |
311 | kmin = k; |
312 | } |
313 | } |
314 | Standard_Real prmp = extpc.Point(kmin).Parameter(); |
315 | if (prmp <= prbmin) { |
316 | prbmin = prmp; |
317 | } |
318 | if (prmp >= prbmax) { |
319 | prbmax = prmp; |
320 | } |
321 | } |
322 | } |
323 | } |
324 | } |
325 | |
326 | |
327 | |
328 | |
329 | //======================================================================= |
330 | //function : IsIn |
331 | //purpose : |
332 | //======================================================================= |
333 | |
334 | static Standard_Boolean IsIn (BRepTopAdaptor_FClass2d& FC, |
335 | Geom2dAdaptor_Curve AC) |
336 | { |
337 | Standard_Real Def = 100*Precision::Confusion(); |
338 | GCPnts_QuasiUniformDeflection QU(AC,Def); |
339 | |
340 | for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) { |
341 | gp_Pnt2d P = AC.Value(QU.Parameter(i)); |
342 | if (FC.Perform(P, Standard_False) == TopAbs_OUT) { |
343 | return Standard_False; |
344 | break; |
345 | } |
346 | } |
347 | return Standard_True; |
348 | } |
349 | |
350 | |
351 | //======================================================================= |
352 | //function : PutInBoundsU |
353 | //purpose : Recadre la courbe 2d dans les bounds de la face |
354 | //======================================================================= |
355 | //--------------- |
356 | // Recadre en U. |
357 | //--------------- |
358 | |
359 | static void PutInBoundsU (Standard_Real umin, |
360 | Standard_Real umax, |
361 | Standard_Real eps, |
362 | Standard_Real period, |
363 | Standard_Real f, |
364 | Standard_Real l, |
365 | Handle(Geom2d_Curve)& C2d) |
366 | { |
367 | gp_Pnt2d Pf = C2d->Value(f); |
368 | gp_Pnt2d Pl = C2d->Value(l); |
369 | gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l); |
370 | Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X()); |
371 | Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X()); |
372 | Standard_Real du = 0.; |
373 | if (minC< umin - eps) { |
374 | du = (int((umin - minC)/period) + 1)*period; |
375 | } |
376 | if (minC > umax + eps) { |
377 | du = -(int((minC - umax)/period) + 1)*period; |
378 | } |
379 | if (du != 0) { |
380 | gp_Vec2d T1(du,0.); |
381 | C2d->Translate(T1); |
382 | minC += du; maxC += du; |
383 | } |
384 | // Ajuste au mieux la courbe dans le domaine. |
385 | if (maxC > umax +100*eps) { |
386 | Standard_Real d1 = maxC - umax; |
387 | Standard_Real d2 = umin - minC + period; |
388 | if (d2 < d1) du =-period; |
389 | if ( du != 0.) { |
390 | gp_Vec2d T2(du,0.); |
391 | C2d->Translate(T2); |
392 | } |
393 | } |
394 | } |
395 | |
396 | |
397 | //======================================================================= |
398 | //function : PutInBoundsU |
399 | //purpose : Recadre la courbe 2d dans les bounds de la face |
400 | //======================================================================= |
401 | //--------------- |
402 | // Recadre en V. |
403 | //--------------- |
404 | |
405 | static void PutInBoundsV (Standard_Real vmin, |
406 | Standard_Real vmax, |
407 | Standard_Real eps, |
408 | Standard_Real period, |
409 | Standard_Real f, |
410 | Standard_Real l, |
411 | Handle(Geom2d_Curve)& C2d) |
412 | { |
413 | gp_Pnt2d Pf = C2d->Value(f); |
414 | gp_Pnt2d Pl = C2d->Value(l); |
415 | gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l); |
416 | Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y()); |
417 | Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y()); |
418 | Standard_Real dv = 0.; |
419 | if (minC< vmin - eps) { |
420 | dv = (int((vmin - minC)/period) + 1)*period; |
421 | } |
422 | if (minC > vmax + eps) { |
423 | dv = -(int((minC - vmax)/period) + 1)*period; |
424 | } |
425 | if (dv != 0) { |
426 | gp_Vec2d T1(0.,dv); |
427 | C2d->Translate(T1); |
428 | minC += dv; maxC += dv; |
429 | } |
430 | // Ajuste au mieux la courbe dans le domaine. |
431 | if (maxC > vmax +100*eps) { |
432 | Standard_Real d1 = maxC - vmax; |
433 | Standard_Real d2 = vmin - minC + period; |
434 | if (d2 < d1) dv =-period; |
435 | if ( dv != 0.) { |
436 | gp_Vec2d T2(0.,dv); |
437 | C2d->Translate(T2); |
438 | } |
439 | } |
440 | } |
441 | |
442 | |
443 | //======================================================================= |
444 | //function : IsInside |
445 | //purpose : |
446 | //======================================================================= |
447 | |
448 | |
449 | Standard_Boolean BRepFeat::IsInside(const TopoDS_Face& F1, |
450 | const TopoDS_Face& F2) |
451 | { |
452 | TopExp_Explorer exp; |
453 | exp.Init(F1, TopAbs_EDGE); |
454 | |
455 | Standard_Real umin,umax,vmin,vmax, uperiod=0, vperiod=0; |
456 | Standard_Integer flagu = 0, flagv = 0; |
457 | TopLoc_Location L; // Recup S avec la location pour eviter la copie. |
458 | Handle (Geom_Surface) S = BRep_Tool::Surface(F2); |
459 | // Standard_Real periodu, periodv; |
460 | BRepTools::UVBounds(F2,umin,umax,vmin,vmax); |
461 | |
462 | if (S->IsUPeriodic()) { |
463 | flagu = 1; |
464 | uperiod = S->UPeriod(); |
465 | } |
466 | |
467 | if (S->IsVPeriodic()) { |
468 | flagv = 1; |
469 | vperiod = S->VPeriod(); |
470 | } |
471 | TopoDS_Shape aLocalShape = F2.Oriented(TopAbs_FORWARD); |
472 | BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalShape),Precision::Confusion()); |
473 | // BRepTopAdaptor_FClass2d FC (TopoDS::Face(F2.Oriented(TopAbs_FORWARD)), |
474 | // Precision::Confusion()); |
475 | for(; exp.More(); exp.Next()) { |
476 | Standard_Real f1,l1; |
477 | Handle(Geom_Curve) C0 = BRep_Tool::Curve(TopoDS::Edge(exp.Current()),f1,l1); |
478 | Handle(Geom2d_Curve) C = GeomProjLib::Curve2d(C0,f1,l1,S); |
479 | TopoDS_Edge E = TopoDS::Edge(exp.Current()); |
480 | if(flagu == 1 || flagv == 1) { |
481 | Standard_Real eps = BRep_Tool::Tolerance(E); |
482 | BRep_Tool::Range(E,f1,l1); |
483 | if(flagu == 1) PutInBoundsU(umin, umax, eps, uperiod, f1, l1, C); |
484 | if(flagv == 1) PutInBoundsV(vmin, vmax, eps, vperiod, f1, l1, C); |
485 | } |
486 | Geom2dAdaptor_Curve AC(C,f1,l1); |
487 | if (!IsIn(FC,AC)) { |
488 | return Standard_False; |
489 | break; |
490 | } |
491 | } |
492 | return Standard_True; |
493 | } |
494 | |
495 | |
496 | |
497 | //======================================================================= |
498 | //function : FaceUntil |
499 | //purpose : |
500 | //======================================================================= |
501 | |
502 | |
503 | void BRepFeat::FaceUntil(const TopoDS_Shape& Sbase, |
504 | TopoDS_Face& FUntil) |
505 | { |
506 | Bnd_Box B; |
507 | BRepBndLib::Add(Sbase,B); |
508 | Standard_Real c[6], bnd; |
509 | B.Get(c[0],c[2],c[4],c[1],c[3],c[5]); |
510 | bnd = c[0]; |
511 | for(Standard_Integer i = 1 ; i < 6; i++) { |
512 | if(c[i] > bnd) bnd = c[i]; |
513 | } |
514 | bnd = 10*bnd; |
515 | |
516 | |
517 | Handle(Geom_Surface) s = BRep_Tool::Surface(FUntil); |
518 | Handle(Standard_Type) styp = s->DynamicType(); |
519 | if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
520 | s = Handle(Geom_RectangularTrimmedSurface)::DownCast(s)->BasisSurface(); |
521 | styp = s->DynamicType(); |
522 | } |
523 | Handle(Geom_RectangularTrimmedSurface) str; |
524 | if (styp == STANDARD_TYPE(Geom_Plane)) { |
525 | str = new Geom_RectangularTrimmedSurface |
526 | (s, bnd, -bnd, bnd, -bnd, Standard_True, Standard_True); |
527 | } |
528 | else if (styp == STANDARD_TYPE(Geom_CylindricalSurface)) { |
529 | str = new Geom_RectangularTrimmedSurface |
c6541a0c |
530 | (s, 0., 2.*M_PI, bnd, -bnd, Standard_True, Standard_True); |
7fd59977 |
531 | } |
532 | else if (styp == STANDARD_TYPE(Geom_ConicalSurface)) { |
533 | str = new Geom_RectangularTrimmedSurface |
c6541a0c |
534 | (s, 0., 2.*M_PI, bnd, -bnd, Standard_True, Standard_True); |
7fd59977 |
535 | } |
536 | else { |
537 | FUntil.Nullify(); |
538 | return; |
539 | } |
540 | |
1c72dff6 |
541 | FUntil = BRepLib_MakeFace(str, Precision::Confusion()); |
7fd59977 |
542 | } |
543 | |
544 | |
545 | |
546 | //======================================================================= |
547 | //function : Tool |
548 | //purpose : |
549 | //======================================================================= |
550 | |
551 | TopoDS_Solid BRepFeat::Tool(const TopoDS_Shape& SRef, |
552 | const TopoDS_Face& Fac, |
553 | const TopAbs_Orientation Orf) |
554 | { |
555 | TopTools_ListOfShape lfaces; |
556 | // for (TopExp_Explorer exp(SRef,TopAbs_FACE); exp.More(); exp.Next()) { |
557 | TopExp_Explorer exp(SRef,TopAbs_FACE) ; |
558 | for ( ; exp.More(); exp.Next()) { |
559 | if (exp.Current().ShapeType() == TopAbs_FACE) { |
560 | lfaces.Append(exp.Current()); |
561 | } |
562 | } |
563 | |
564 | LocOpe_BuildShape bs(lfaces); |
565 | const TopoDS_Shape& Res = bs.Shape(); |
566 | TopoDS_Shell Sh; |
567 | if (Res.ShapeType() == TopAbs_SHELL) { |
568 | // faire un solide |
569 | Sh = TopoDS::Shell(Res); |
570 | } |
571 | else if (Res.ShapeType() == TopAbs_SOLID) { |
572 | exp.Init(Res,TopAbs_SHELL); |
573 | Sh = TopoDS::Shell(exp.Current()); |
574 | exp.Next(); |
575 | if (exp.More()) { |
576 | Sh.Nullify(); |
577 | } |
578 | } |
579 | |
580 | if (Sh.IsNull()) { |
581 | TopoDS_Solid So; |
582 | return So; |
583 | } |
584 | |
585 | |
586 | Sh.Orientation(TopAbs_FORWARD); |
587 | #ifdef DEB |
588 | TopAbs_Orientation orient; |
589 | #else |
590 | TopAbs_Orientation orient = TopAbs_FORWARD; |
591 | #endif |
592 | for (exp.Init(Sh,TopAbs_FACE); exp.More(); exp.Next()) { |
593 | if (exp.Current().IsSame(Fac)) { |
594 | orient = exp.Current().Orientation(); |
595 | break; |
596 | } |
597 | } |
598 | |
599 | Standard_Boolean reverse = Standard_False; |
600 | if ((orient == Fac.Orientation() && Orf == TopAbs_REVERSED) || |
601 | (orient != Fac.Orientation() && Orf == TopAbs_FORWARD)) { |
602 | reverse = Standard_True; |
603 | } |
604 | |
605 | if (reverse) { |
606 | Sh.Reverse(); |
607 | } |
608 | |
609 | BRep_Builder B; |
610 | TopoDS_Solid Soc; |
611 | B.MakeSolid(Soc); |
612 | B.Add(Soc,Sh); |
613 | return Soc; |
614 | } |
615 | |
616 | |
617 | //======================================================================= |
618 | //function : Print |
619 | //purpose : Print the error Description of a StatusError on a stream. |
620 | //======================================================================= |
621 | |
622 | Standard_OStream& BRepFeat::Print(const BRepFeat_StatusError se, |
623 | Standard_OStream& s) |
624 | { |
625 | switch(se) { |
626 | case BRepFeat_OK : |
627 | s << "No error"; |
628 | break; |
629 | case BRepFeat_BadDirect : |
630 | s << "Directions must be opposite"; |
631 | break; |
632 | case BRepFeat_BadIntersect : |
633 | s << "Intersection failure"; |
634 | break; |
635 | case BRepFeat_EmptyBaryCurve : |
636 | s << "Empty BaryCurve"; |
637 | break; |
638 | case BRepFeat_EmptyCutResult : |
639 | s << "Failure in Cut : Empty resulting shape"; |
640 | break;; |
641 | case BRepFeat_FalseSide : |
642 | s << "Verify plane and wire orientation"; |
643 | break; |
644 | case BRepFeat_IncDirection : |
645 | s << "Incoherent Direction for shapes From and Until"; |
646 | break; |
647 | case BRepFeat_IncSlidFace : |
648 | s << "Sliding face not in Base shape"; |
649 | break; |
650 | case BRepFeat_IncParameter : |
651 | s << "Incoherent Parameter : shape Until before shape From"; |
652 | break; |
653 | case BRepFeat_IncTypes : |
654 | s << "Invalid option for faces From and Until : 1 Support and 1 not"; |
655 | break; |
656 | case BRepFeat_IntervalOverlap : |
657 | s << "Shapes From and Until overlap"; |
658 | break; |
659 | case BRepFeat_InvFirstShape : |
660 | s << "Invalid First shape : more than 1 face"; |
661 | break; |
662 | case BRepFeat_InvOption : |
663 | s << "Invalid option"; |
664 | break; |
665 | case BRepFeat_InvShape : |
666 | s << "Invalid shape"; |
667 | break; |
668 | case BRepFeat_LocOpeNotDone : |
669 | s << "Local Operation not done"; |
670 | break; |
671 | case BRepFeat_LocOpeInvNotDone : |
672 | s << "Local Operation : intersection line conflict"; |
673 | break; |
674 | case BRepFeat_NoExtFace : |
675 | s << "No Extreme faces"; |
676 | break; |
677 | case BRepFeat_NoFaceProf : |
678 | s << "No Face Profile"; |
679 | break; |
680 | case BRepFeat_NoGluer : |
681 | s << "Gluer Failure"; |
682 | break; |
683 | case BRepFeat_NoIntersectF : |
684 | s << "No intersection between Feature and shape From"; |
685 | break; |
686 | case BRepFeat_NoIntersectU : |
687 | s << "No intersection between Feature and shape Until"; |
688 | break; |
689 | case BRepFeat_NoParts : |
690 | s << "No parts of tool kept"; |
691 | break; |
692 | case BRepFeat_NoProjPt : |
693 | s << "No projection points"; |
694 | break; |
695 | case BRepFeat_NotInitialized : |
696 | s << "Fields not initialized"; |
697 | break; |
698 | case BRepFeat_NotYetImplemented : |
699 | s << "Not yet implemented"; |
700 | break; |
701 | case BRepFeat_NullRealTool : |
702 | s << "Real Tool : Null DPrism"; |
703 | break; |
704 | case BRepFeat_NullToolF : |
705 | s << "Null Tool : Invalid type for shape Form"; |
706 | break; |
707 | case BRepFeat_NullToolU : |
708 | s << "Null Tool : Invalid type for shape Until"; |
709 | break; |
710 | } |
711 | return s; |
712 | } |
713 | |