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