7fd59977 |
1 | // File: BRepOffset_Offset.cxx |
2 | // Created: Thu Oct 19 14:59:59 1995 |
3 | // Author: Bruno DUMORTIER |
4 | // <dub@fuegox> |
5 | |
6 | |
7 | #include <BRepOffset_Offset.ixx> |
8 | |
9 | #include <Adaptor3d_HCurveOnSurface.hxx> |
10 | #include <Adaptor3d_CurveOnSurface.hxx> |
11 | #include <BRepOffset.hxx> |
12 | #include <BRepLib.hxx> |
13 | #include <BRepLib_MakeFace.hxx> |
14 | #include <BRepTools.hxx> |
15 | #include <BRep_Tool.hxx> |
16 | #include <BRep_Builder.hxx> |
17 | #include <ElSLib.hxx> |
18 | #include <GeomAPI.hxx> |
19 | #include <Geom2d_Curve.hxx> |
20 | #include <Geom2d_Line.hxx> |
21 | #include <Geom2d_TrimmedCurve.hxx> |
22 | #include <Geom_Line.hxx> |
23 | #include <Geom_Circle.hxx> |
24 | #include <Geom_Curve.hxx> |
25 | #include <Geom_TrimmedCurve.hxx> |
26 | #include <Geom_RectangularTrimmedSurface.hxx> |
27 | #include <Geom_Surface.hxx> |
28 | #include <Geom_OffsetSurface.hxx> |
29 | #include <Geom_SphericalSurface.hxx> |
30 | #include <Geom_ConicalSurface.hxx> |
31 | #include <GeomAdaptor_HSurface.hxx> |
32 | #include <GeomAdaptor_Surface.hxx> |
33 | #include <GeomAdaptor_HCurve.hxx> |
34 | #include <GeomAdaptor_Curve.hxx> |
35 | #include <Geom2dAdaptor_HCurve.hxx> |
36 | #include <Geom2dAdaptor_Curve.hxx> |
37 | #include <GeomFill_Pipe.hxx> |
38 | #include <GeomProjLib.hxx> |
39 | #include <GeomConvert_ApproxSurface.hxx> |
40 | #include <Precision.hxx> |
41 | #include <Standard_ConstructionError.hxx> |
42 | #include <TopoDS.hxx> |
43 | #include <TopoDS_Wire.hxx> |
44 | #include <TopExp.hxx> |
45 | #include <TopExp_Explorer.hxx> |
46 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
47 | #include <gp.hxx> |
48 | #include <gp_Ax3.hxx> |
49 | #include <gp_Cylinder.hxx> |
50 | #include <gp_Torus.hxx> |
51 | #include <gp_Lin.hxx> |
52 | #include <gp_Pnt2d.hxx> |
53 | |
54 | #include <BRep_GCurve.hxx> |
55 | #include <BRep_TEdge.hxx> |
56 | #include <BRep_ListOfCurveRepresentation.hxx> |
57 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
58 | |
59 | #include <TopTools_SequenceOfShape.hxx> |
60 | #include <TopTools_MapOfShape.hxx> |
61 | #include <BRepOffset_Tool.hxx> |
62 | #include <GeomAPI_ExtremaCurveCurve.hxx> |
63 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
64 | #include <GeomLib.hxx> |
65 | |
66 | #ifdef DEB |
67 | static Standard_Boolean Affich = Standard_False; |
68 | static Standard_Integer NbOFFSET = 0; |
69 | #endif |
70 | #ifdef DRAW |
71 | #include <DrawTrSurf.hxx> |
72 | #include <DBRep.hxx> |
73 | #endif |
74 | #include <stdio.h> |
75 | |
76 | //======================================================================= |
77 | //function : UpdateEdge |
78 | //purpose : |
79 | //======================================================================= |
80 | |
81 | static void UpdateEdge(const TopoDS_Edge& E, |
82 | const Handle(Geom_Curve)& C, |
83 | const TopLoc_Location& L, |
84 | const Standard_Real Tol) |
85 | { |
86 | // Detrime les courbes pour eviter des copies dans |
87 | //les extensions. |
88 | BRep_Builder B; |
89 | Handle(Geom_TrimmedCurve) BC = Handle(Geom_TrimmedCurve)::DownCast(C); |
90 | if (!BC.IsNull()) { |
91 | B.UpdateEdge(E,BC->BasisCurve(),L,Tol); |
92 | } |
93 | else { |
94 | B.UpdateEdge(E,C,L,Tol); |
95 | } |
96 | } |
97 | |
98 | //======================================================================= |
99 | //function : UpdateEdge |
100 | //purpose : |
101 | //======================================================================= |
102 | |
103 | static void UpdateEdge(const TopoDS_Edge& E, |
104 | const Handle(Geom2d_Curve)& C, |
105 | const TopoDS_Face& F, |
106 | const Standard_Real Tol) |
107 | { |
108 | // Detrime les courbes pour eviter des copies dans |
109 | //les extensions. |
110 | BRep_Builder B; |
111 | Handle(Geom2d_TrimmedCurve) BC = Handle(Geom2d_TrimmedCurve)::DownCast(C); |
112 | if (!BC.IsNull()) { |
113 | B.UpdateEdge(E,BC->BasisCurve(),F,Tol); |
114 | } |
115 | else { |
116 | B.UpdateEdge(E,C,F,Tol); |
117 | } |
118 | } |
119 | |
120 | //======================================================================= |
121 | //function : UpdateEdge |
122 | //purpose : |
123 | //======================================================================= |
124 | |
125 | static void UpdateEdge (const TopoDS_Edge& E, |
126 | const Handle(Geom2d_Curve)& C1, |
127 | const Handle(Geom2d_Curve)& C2, |
128 | const TopoDS_Face& F, |
129 | const Standard_Real Tol) |
130 | { |
131 | // Detrime les courbes pour eviter des copies dans |
132 | //les extensions. |
133 | BRep_Builder B; |
134 | Handle(Geom2d_Curve) NC1,NC2; |
135 | Handle(Geom2d_TrimmedCurve) BC1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1); |
136 | Handle(Geom2d_TrimmedCurve) BC2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2); |
137 | if (!BC1.IsNull()) NC1 = BC1->BasisCurve(); else NC1 = C1; |
138 | if (!BC2.IsNull()) NC2 = BC2->BasisCurve(); else NC2 = C2; |
139 | B.UpdateEdge(E,NC1,NC2,F,Tol); |
140 | } |
141 | |
142 | //======================================================================= |
143 | //function : Range3d |
144 | //purpose : Set the range only on the 3d curve |
145 | // en attendant que le BRep_Builder le fasse !! |
146 | //======================================================================= |
147 | |
148 | static void Range3d (const TopoDS_Edge& E, |
149 | const Standard_Real First, |
150 | const Standard_Real Last) |
151 | { |
152 | // set the range to all the representations |
153 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape()); |
154 | |
155 | BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves(); |
156 | BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr); |
157 | Handle(BRep_GCurve) GC; |
158 | |
159 | while (itcr.More()) { |
160 | GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
161 | if (!GC.IsNull()) { |
162 | if (GC->IsCurve3D()) { |
163 | GC->SetRange(First,Last); |
164 | // Set the closedness flag to the correct value. |
165 | Handle(Geom_Curve) C = GC->Curve3D(); |
166 | if ( !C.IsNull() ) { |
167 | Standard_Boolean closed = |
168 | C->Value(First).IsEqual(C->Value(Last),BRep_Tool::Tolerance(E)); |
169 | TE->Closed(closed); |
170 | } |
171 | } |
172 | } |
173 | itcr.Next(); |
174 | } |
175 | |
176 | TE->Modified(Standard_True); |
177 | } |
178 | |
179 | |
180 | //======================================================================= |
181 | //function : ComputeCurve3d |
182 | //purpose : Particular case of Curve On Surface. |
183 | //======================================================================= |
184 | |
185 | static void ComputeCurve3d(TopoDS_Edge Edge, |
186 | Handle(Geom2d_Curve) Curve, |
187 | Handle(Geom_Surface) Surf, |
188 | const TopLoc_Location Loc, |
189 | Standard_Real Tol) |
190 | { |
191 | // try to find the particular case |
192 | // if not found call BRepLib::BuildCurve3d |
193 | |
194 | Standard_Boolean IsComputed = Standard_False; |
195 | |
196 | // Seach only isos on analytiques surfaces. |
197 | Geom2dAdaptor_Curve C(Curve); |
198 | GeomAdaptor_Surface S(Surf); |
199 | GeomAbs_CurveType CTy = C.GetType(); |
200 | GeomAbs_SurfaceType STy = S.GetType(); |
201 | BRep_Builder TheBuilder; |
202 | |
203 | if ( STy != GeomAbs_Plane) { // if plane buildcurve3d gere KPart |
204 | if ( CTy == GeomAbs_Line) { |
205 | gp_Dir2d D = C.Line().Direction(); |
206 | if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V. |
207 | if ( STy == GeomAbs_Sphere) { |
208 | gp_Pnt2d P = C.Line().Location(); |
209 | if ( Abs( Abs(P.Y()) -PI/2. ) < Precision::PConfusion()) { |
210 | TheBuilder.Degenerated(Edge, Standard_True); |
211 | } |
212 | else { |
213 | gp_Sphere Sph = S.Sphere(); |
214 | gp_Ax3 Axis = Sph.Position(); |
215 | gp_Circ Ci = ElSLib::SphereVIso(Axis, |
216 | Sph.Radius(), |
217 | P.Y()); |
218 | gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection()); |
219 | gp_Ax1 AxeRev(Axis.Location(), DRev); |
220 | Ci.Rotate(AxeRev, P.X()); |
221 | Handle(Geom_Circle) Circle = new Geom_Circle(Ci); |
222 | if ( D.IsOpposite(gp::DX2d(),Precision::Angular())) |
223 | Circle->Reverse(); |
224 | UpdateEdge(Edge, Circle, Loc, Tol); |
225 | } |
226 | IsComputed = Standard_True; |
227 | } |
228 | else if ( STy == GeomAbs_Cylinder) { |
229 | gp_Cylinder Cyl = S.Cylinder(); |
230 | gp_Pnt2d P = C.Line().Location(); |
231 | gp_Ax3 Axis = Cyl.Position(); |
232 | gp_Circ Ci = ElSLib::CylinderVIso(Axis, |
233 | Cyl.Radius(), |
234 | P.Y()); |
235 | gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection()); |
236 | gp_Ax1 AxeRev(Axis.Location(), DRev); |
237 | Ci.Rotate(AxeRev, P.X()); |
238 | Handle(Geom_Circle) Circle = new Geom_Circle(Ci); |
239 | if ( D.IsOpposite(gp::DX2d(),Precision::Angular())) |
240 | Circle->Reverse(); |
241 | UpdateEdge(Edge, Circle, Loc, Tol); |
242 | IsComputed = Standard_True; |
243 | } |
244 | else if ( STy == GeomAbs_Cone) { |
245 | gp_Cone Cone = S.Cone(); |
246 | gp_Pnt2d P = C.Line().Location(); |
247 | gp_Ax3 Axis = Cone.Position(); |
248 | gp_Circ Ci = ElSLib::ConeVIso(Axis, |
249 | Cone.RefRadius(), |
250 | Cone.SemiAngle(), |
251 | P.Y()); |
252 | gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection()); |
253 | gp_Ax1 AxeRev(Axis.Location(), DRev); |
254 | Ci.Rotate(AxeRev, P.X()); |
255 | Handle(Geom_Circle) Circle = new Geom_Circle(Ci); |
256 | if ( D.IsOpposite(gp::DX2d(),Precision::Angular())) |
257 | Circle->Reverse(); |
258 | UpdateEdge(Edge, Circle, Loc, Tol); |
259 | IsComputed = Standard_True; |
260 | } |
261 | else if ( STy == GeomAbs_Torus) { |
262 | gp_Torus Tore = S.Torus(); |
263 | gp_Pnt2d P = C.Line().Location(); |
264 | gp_Ax3 Axis = Tore.Position(); |
265 | gp_Circ Ci = ElSLib::TorusVIso(Axis, |
266 | Tore.MajorRadius(), |
267 | Tore.MinorRadius(), |
268 | P.Y()); |
269 | gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection()); |
270 | gp_Ax1 AxeRev(Axis.Location(), DRev); |
271 | Ci.Rotate(AxeRev, P.X()); |
272 | Handle(Geom_Circle) Circle = new Geom_Circle(Ci); |
273 | if ( D.IsOpposite(gp::DX2d(),Precision::Angular())) |
274 | Circle->Reverse(); |
275 | UpdateEdge(Edge, Circle, Loc, Tol); |
276 | IsComputed = Standard_True; |
277 | } |
278 | } |
279 | else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U. |
280 | if ( STy == GeomAbs_Sphere) { |
281 | gp_Sphere Sph = S.Sphere(); |
282 | gp_Pnt2d P = C.Line().Location(); |
283 | gp_Ax3 Axis = Sph.Position(); |
284 | // calculde l'iso 0. |
285 | gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.); |
286 | |
287 | // mise a sameparameter (rotation du cercle - decalage du Y) |
288 | gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction()); |
289 | gp_Ax1 AxeRev(Axis.Location(),DRev); |
290 | Ci.Rotate(AxeRev, P.Y()); |
291 | |
292 | // transformation en iso U ( = P.X()) |
293 | DRev = Axis.XDirection().Crossed(Axis.YDirection()); |
294 | AxeRev = gp_Ax1(Axis.Location(), DRev); |
295 | Ci.Rotate(AxeRev, P.X()); |
296 | Handle(Geom_Circle) Circle = new Geom_Circle(Ci); |
297 | |
298 | if ( D.IsOpposite(gp::DY2d(),Precision::Angular())) |
299 | Circle->Reverse(); |
300 | UpdateEdge(Edge, Circle, Loc, Tol); |
301 | IsComputed = Standard_True; |
302 | } |
303 | else if ( STy == GeomAbs_Cylinder) { |
304 | gp_Cylinder Cyl = S.Cylinder(); |
305 | gp_Pnt2d P = C.Line().Location(); |
306 | gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(), |
307 | Cyl.Radius(), |
308 | P.X()); |
309 | gp_Vec Tr(L.Direction()); |
310 | Tr.Multiply(P.Y()); |
311 | L.Translate(Tr); |
312 | Handle(Geom_Line) Line = new Geom_Line(L); |
313 | if ( D.IsOpposite(gp::DY2d(),Precision::Angular())) |
314 | Line->Reverse(); |
315 | UpdateEdge(Edge, Line, Loc, Tol); |
316 | IsComputed = Standard_True; |
317 | } |
318 | else if ( STy == GeomAbs_Cone) { |
319 | gp_Cone Cone = S.Cone(); |
320 | gp_Pnt2d P = C.Line().Location(); |
321 | gp_Lin L = ElSLib::ConeUIso(Cone.Position(), |
322 | Cone.RefRadius(), |
323 | Cone.SemiAngle(), |
324 | P.X()); |
325 | gp_Vec Tr(L.Direction()); |
326 | Tr.Multiply(P.Y()); |
327 | L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L); |
328 | if ( D.IsOpposite(gp::DY2d(),Precision::Angular())) |
329 | Line->Reverse(); |
330 | UpdateEdge(Edge, Line, Loc, Tol); |
331 | IsComputed = Standard_True; |
332 | } |
333 | else if ( STy == GeomAbs_Torus) { |
334 | gp_Torus Tore = S.Torus(); |
335 | gp_Pnt2d P = C.Line().Location(); |
336 | gp_Ax3 Axis = Tore.Position(); |
337 | gp_Circ Ci = ElSLib::TorusUIso(Axis, |
338 | Tore.MajorRadius(), |
339 | Tore.MinorRadius(), |
340 | P.X()); |
341 | Ci.Rotate(Ci.Axis(),P.Y()); |
342 | Handle(Geom_Circle) Circle = new Geom_Circle(Ci); |
343 | |
344 | if ( D.IsOpposite(gp::DY2d(),Precision::Angular())) |
345 | Circle->Reverse(); |
346 | UpdateEdge(Edge, Circle, Loc, Tol); |
347 | IsComputed = Standard_True; |
348 | } |
349 | } |
350 | } |
351 | } |
352 | else { // Cas Plan |
353 | Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane()); |
354 | UpdateEdge(Edge, C3d, Loc, Tol); |
355 | IsComputed = Standard_True; |
356 | } |
357 | if ( !IsComputed) { |
358 | //BRepLib::BuildCurves3d(Edge,Tol); |
359 | //Les Courbes 3d des edges dans le cas general ne sont calcules que si |
360 | // necessaire |
361 | //ie dans les tuyaux et les bouchons .. |
362 | // dans la derniere etapes de MakeShells on reconstruira les courbes3d |
363 | // des edges du resultat qui n en ont pas. |
364 | } |
365 | } |
366 | |
367 | |
368 | //======================================================================= |
369 | //function : BRepOffset_Offset |
370 | //purpose : |
371 | //======================================================================= |
372 | |
373 | BRepOffset_Offset::BRepOffset_Offset() |
374 | { |
375 | } |
376 | |
377 | |
378 | //======================================================================= |
379 | //function : BRepOffset_Offset |
380 | //purpose : |
381 | //======================================================================= |
382 | |
383 | BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Face& Face, |
384 | const Standard_Real Offset, |
385 | const Standard_Boolean OffsetOutside, |
386 | const GeomAbs_JoinType JoinType) |
387 | { |
388 | Init(Face, Offset, OffsetOutside, JoinType); |
389 | } |
390 | |
391 | |
392 | //======================================================================= |
393 | //function : BRepOffset_Offset |
394 | //purpose : |
395 | //======================================================================= |
396 | |
397 | BRepOffset_Offset::BRepOffset_Offset |
398 | (const TopoDS_Face& Face, |
399 | const Standard_Real Offset, |
400 | const TopTools_DataMapOfShapeShape& Created, |
401 | const Standard_Boolean OffsetOutside, |
402 | const GeomAbs_JoinType JoinType) |
403 | { |
404 | Init(Face,Offset,Created,OffsetOutside,JoinType); |
405 | } |
406 | |
407 | |
408 | //======================================================================= |
409 | //function : BRepOffset_Offset |
410 | //purpose : |
411 | //======================================================================= |
412 | |
413 | BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Edge& Path, |
414 | const TopoDS_Edge& Edge1, |
415 | const TopoDS_Edge& Edge2, |
416 | const Standard_Real Offset, |
417 | const Standard_Boolean Polynomial, |
418 | const Standard_Real Tol, |
419 | const GeomAbs_Shape Conti) |
420 | { |
421 | Init(Path,Edge1,Edge2,Offset,Polynomial,Tol,Conti); |
422 | } |
423 | |
424 | |
425 | //======================================================================= |
426 | //function : BRepOffset_Offset |
427 | //purpose : |
428 | //======================================================================= |
429 | |
430 | BRepOffset_Offset::BRepOffset_Offset |
431 | (const TopoDS_Edge& Path, |
432 | const TopoDS_Edge& Edge1, |
433 | const TopoDS_Edge& Edge2, |
434 | const Standard_Real Offset, |
435 | const TopoDS_Edge& FirstEdge, |
436 | const TopoDS_Edge& LastEdge, |
437 | const Standard_Boolean Polynomial, |
438 | const Standard_Real Tol, |
439 | const GeomAbs_Shape Conti) |
440 | { |
441 | Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti); |
442 | } |
443 | |
444 | |
445 | //======================================================================= |
446 | //function : BRepOffset_Offset |
447 | //purpose : |
448 | //======================================================================= |
449 | |
450 | BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Vertex& Vertex, |
451 | const TopTools_ListOfShape& LEdge, |
452 | const Standard_Real Offset, |
453 | const Standard_Boolean Polynomial, |
454 | const Standard_Real Tol, |
455 | const GeomAbs_Shape Conti) |
456 | { |
457 | Init(Vertex,LEdge,Offset,Polynomial,Tol,Conti); |
458 | } |
459 | |
460 | |
461 | //======================================================================= |
462 | //function : Init |
463 | //purpose : |
464 | //======================================================================= |
465 | |
466 | void BRepOffset_Offset::Init(const TopoDS_Face& Face, |
467 | const Standard_Real Offset, |
468 | const Standard_Boolean OffsetOutside, |
469 | const GeomAbs_JoinType JoinType) |
470 | { |
471 | TopTools_DataMapOfShapeShape Empty; |
472 | Init(Face,Offset,Empty,OffsetOutside,JoinType); |
473 | } |
474 | |
475 | |
476 | //======================================================================= |
477 | //function : Init |
478 | //purpose : |
479 | //======================================================================= |
480 | |
481 | void BRepOffset_Offset::Init(const TopoDS_Face& Face, |
482 | const Standard_Real Offset, |
483 | const TopTools_DataMapOfShapeShape& Created, |
484 | const Standard_Boolean OffsetOutside, |
485 | const GeomAbs_JoinType JoinType) |
486 | { |
487 | myShape = Face; |
488 | Standard_Real myOffset = Offset; |
489 | if ( Face.Orientation() == TopAbs_REVERSED) |
490 | myOffset *= -1.; |
491 | |
492 | TopLoc_Location L; |
493 | Handle(Geom_Surface) S = BRep_Tool::Surface(Face,L); |
494 | |
495 | // On detrime les surfaces, evite des recopies dans les extensions. |
496 | Handle(Geom_RectangularTrimmedSurface) RT = |
497 | Handle(Geom_RectangularTrimmedSurface)::DownCast(S); |
498 | if (!RT.IsNull()) S = RT->BasisSurface(); |
499 | |
500 | // particular case of cone |
501 | Handle(Geom_ConicalSurface) Co; |
502 | Co = Handle(Geom_ConicalSurface)::DownCast(S); |
503 | if ( !Co.IsNull()) { |
504 | Standard_Real Uc,Vc; |
505 | gp_Pnt Apex = Co->Apex(); |
506 | ElSLib::Parameters( Co->Cone(),Apex,Uc,Vc); |
507 | Standard_Real UU1,UU2,VV1,VV2; |
508 | BRepTools::UVBounds(Face,UU1,UU2,VV1,VV2); |
509 | if ( VV2 < Vc && Co->SemiAngle() > 0 ) |
510 | myOffset *= -1; |
511 | else if ( VV1 > Vc && Co->SemiAngle() < 0 ) |
512 | myOffset *= -1; |
513 | if ( !Co->Position().Direct()) myOffset *= -1; |
514 | } |
515 | |
516 | Handle(Geom_Surface) TheSurf = |
517 | BRepOffset::Surface( S, myOffset, myStatus); |
518 | |
519 | //processing offsets of faces with possible degenerated edges |
520 | Standard_Boolean VminDegen = Standard_False; |
521 | Standard_Boolean VmaxDegen = Standard_False; |
522 | gp_Pnt MinApex, MaxApex; |
523 | Standard_Boolean HasSingularity = Standard_False; |
524 | Standard_Real uf1, uf2, vf1, vf2, fpar, lpar; |
525 | BRepTools::UVBounds(Face, uf1, uf2, vf1, vf2); |
526 | if (!(OffsetOutside && JoinType == GeomAbs_Arc) && |
527 | (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface) || |
528 | TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))) |
529 | { |
530 | TopTools_SequenceOfShape DegEdges; |
531 | TopExp_Explorer Explo(Face, TopAbs_EDGE); |
532 | for (; Explo.More(); Explo.Next()) |
533 | { |
534 | const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current()); |
535 | if (BRep_Tool::Degenerated(anEdge)) |
536 | DegEdges.Append(anEdge); |
537 | } |
538 | if (!DegEdges.IsEmpty()) |
539 | { |
540 | const Standard_Real TolApex = 1.e-5; |
541 | if (DegEdges.Length() == 2) |
542 | { |
543 | VminDegen = Standard_True; |
544 | VmaxDegen = Standard_True; |
545 | } |
546 | else //DegEdges.Length() == 1 |
547 | { |
548 | const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1)); |
549 | Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar); |
550 | gp_Pnt2d aPnt2d = aCurve->Value(fpar); |
551 | if (Abs(aPnt2d.Y() - vf1) <= Precision::Confusion()) |
552 | VminDegen = Standard_True; |
553 | else |
554 | VmaxDegen = Standard_True; |
555 | } |
556 | if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface)) |
557 | { |
558 | gp_Cone theCone = (*((Handle(Geom_ConicalSurface)*)&TheSurf))->Cone(); |
559 | gp_Pnt apex = theCone.Apex(); |
560 | Standard_Real Uapex, Vapex; |
561 | ElSLib::Parameters( theCone, apex, Uapex, Vapex ); |
562 | if (VminDegen) |
563 | { |
564 | TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, Vapex, vf2); |
565 | MinApex = apex; |
566 | HasSingularity = Standard_True; |
567 | } |
568 | else if (VmaxDegen) |
569 | { |
570 | TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, Vapex); |
571 | MaxApex = apex; |
572 | HasSingularity = Standard_True; |
573 | } |
574 | } |
575 | else //TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface) |
576 | { |
577 | if (VminDegen) |
578 | { |
579 | Handle(Geom_Curve) viso = TheSurf->VIso( vf1 ); |
580 | if (BRepOffset_Tool::Gabarit( viso ) > TolApex) |
581 | { |
582 | Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface(); |
583 | gp_Pnt Papex, Pfirst, Plast, Pmid; |
584 | Papex = BasisSurf->Value( uf1, vf1 ); |
585 | Pfirst = TheSurf->Value( uf1, vf1 ); |
586 | Plast = TheSurf->Value( uf2, vf1 ); |
587 | Pmid = TheSurf->Value( (uf1+uf2)/2., vf1 ); |
588 | gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast); |
589 | Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex ); |
590 | gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 ); |
591 | Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix ); |
592 | GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex ); |
593 | gp_Pnt Pint1, Pint2; |
594 | theExtrema.NearestPoints(Pint1, Pint2); |
595 | Standard_Real length = Pfirst.Distance(Pint1); |
596 | if (OffsetOutside) |
597 | { |
598 | TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2); |
599 | GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1, |
600 | Standard_False, Standard_False); |
601 | Standard_Real u1, u2, v1, v2; |
602 | TheSurf->Bounds( u1, u2, v1, v2 ); |
603 | MinApex = TheSurf->Value( uf1, v1 ); |
604 | } |
605 | else |
606 | { |
607 | Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 ); |
608 | GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso ); |
609 | Standard_Real NewFirstV = Projector.LowerDistanceParameter(); |
610 | TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2); |
611 | MinApex = TheSurf->Value( uf1, NewFirstV ); |
612 | //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2); |
613 | //MinApex = TheSurf->Value( uf1, vf1+length ); |
614 | } |
615 | HasSingularity = Standard_True; |
616 | } |
617 | } //end of if (VminDegen) |
618 | if (VmaxDegen) |
619 | { |
620 | Handle(Geom_Curve) viso = TheSurf->VIso( vf2 ); |
621 | if (BRepOffset_Tool::Gabarit( viso ) > TolApex) |
622 | { |
623 | Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface(); |
624 | gp_Pnt Papex, Pfirst, Plast, Pmid; |
625 | Papex = BasisSurf->Value( uf1, vf2 ); |
626 | Pfirst = TheSurf->Value( uf1, vf2 ); |
627 | Plast = TheSurf->Value( uf2, vf2 ); |
628 | Pmid = TheSurf->Value( (uf1+uf2)/2., vf2 ); |
629 | gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast); |
630 | Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex ); |
631 | gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 ); |
632 | Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix ); |
633 | GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex ); |
634 | gp_Pnt Pint1, Pint2; |
635 | theExtrema.NearestPoints(Pint1, Pint2); |
636 | Standard_Real length = Pfirst.Distance(Pint1); |
637 | if (OffsetOutside) |
638 | { |
639 | TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2); |
640 | GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1, |
641 | Standard_False, Standard_True); |
642 | Standard_Real u1, u2, v1, v2; |
643 | TheSurf->Bounds( u1, u2, v1, v2 ); |
644 | MaxApex = TheSurf->Value( uf1, v2 ); |
645 | } |
646 | else |
647 | { |
648 | Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 ); |
649 | GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso ); |
650 | Standard_Real NewLastV = Projector.LowerDistanceParameter(); |
651 | TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV); |
652 | MaxApex = TheSurf->Value( uf1, NewLastV ); |
653 | //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length); |
654 | //MaxApex = TheSurf->Value( uf1, vf2-length ); |
655 | } |
656 | HasSingularity = Standard_True; |
657 | } |
658 | } //end of if (VmaxDegen) |
659 | } //end of else (case of Geom_OffsetSurface) |
660 | } //end of if (!DegEdges.IsEmpty()) |
661 | } //end of processing offsets of faces with possible degenerated edges |
662 | |
663 | // find the PCurves of the edges of <Faces> |
664 | |
665 | BRep_Builder myBuilder; |
666 | myBuilder.MakeFace(myFace); |
667 | myBuilder.UpdateFace(myFace,TheSurf,L,BRep_Tool::Tolerance(Face)); |
668 | |
669 | TopTools_DataMapOfShapeShape MapSS; |
670 | |
671 | // mise a jour de la map sur les vertex deja crees |
672 | TopoDS_Shape aLocalShape = Face.Oriented(TopAbs_FORWARD); |
673 | TopoDS_Face CurFace = TopoDS::Face(aLocalShape); |
674 | // TopoDS_Face CurFace = TopoDS::Face(Face.Oriented(TopAbs_FORWARD)); |
675 | |
676 | TopTools_MapOfShape VonDegen; |
677 | Standard_Real u1, u2, v1, v2; |
678 | TheSurf->Bounds( u1, u2, v1, v2 ); |
679 | |
680 | TopExp_Explorer exp(CurFace, TopAbs_EDGE); |
681 | for ( ; exp.More(); exp.Next()) { |
682 | const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); |
683 | TopoDS_Vertex V1,V2,OV1,OV2; |
684 | TopExp::Vertices(E ,V1 ,V2 ); |
685 | if (HasSingularity && BRep_Tool::Degenerated(E)) |
686 | VonDegen.Add( V1 ); |
687 | if (Created.IsBound(E)) { |
688 | const TopoDS_Edge& OE = TopoDS::Edge(Created(E)); |
689 | TopExp::Vertices(OE,OV1,OV2); |
690 | if (!MapSS.IsBound(V1)) MapSS.Bind(V1,OV1); |
691 | if (!MapSS.IsBound(V2)) MapSS.Bind(V2,OV2); |
692 | } |
693 | if (Created.IsBound(V1)) { |
694 | if (!MapSS.IsBound(V1)) MapSS.Bind(V1,Created(V1)); |
695 | } |
696 | if (Created.IsBound(V2)) { |
697 | if (!MapSS.IsBound(V2)) MapSS.Bind(V2,Created(V2)); |
698 | } |
699 | } |
700 | |
701 | TopExp_Explorer expw(CurFace, TopAbs_WIRE); |
702 | for ( ; expw.More(); expw.Next()) { |
703 | const TopoDS_Wire& W = TopoDS::Wire(expw.Current()); |
704 | TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD), |
705 | TopAbs_EDGE); |
706 | TopoDS_Wire OW; |
707 | myBuilder.MakeWire(OW); |
708 | for ( ; expe.More(); expe.Next()) { |
709 | const TopoDS_Edge& E = TopoDS::Edge(expe.Current()); |
710 | TopoDS_Vertex V1,V2; |
711 | TopExp::Vertices(E,V1,V2); |
712 | gp_Pnt2d P2d1, P2d2; |
713 | gp_Pnt P1, P2; |
714 | Standard_Real vstart, vend; |
715 | Standard_Real f,l; |
716 | Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,CurFace,f,l); |
717 | TopoDS_Edge OE; |
718 | if (MapSS.IsBound(E) && |
719 | !VonDegen.Contains(V1) && !VonDegen.Contains(V2)) { // c`est un edge de couture |
720 | OE = TopoDS::Edge(MapSS(E)); |
721 | TopoDS_Shape aLocalShape = E.Reversed(); |
722 | Handle(Geom2d_Curve) C2d_1 = |
723 | BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l); |
724 | // Handle(Geom2d_Curve) C2d_1 = |
725 | // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),CurFace,f,l); |
726 | if ( E.Orientation() == TopAbs_FORWARD) |
727 | UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E)); |
728 | else |
729 | UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E)); |
730 | myBuilder.Range(OE,f,l); |
731 | } |
732 | else { |
733 | TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD); |
734 | TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape); |
735 | P2d1 = C2d->Value(BRep_Tool::Parameter(V1,Eforward,CurFace)); |
736 | P2d2 = C2d->Value(BRep_Tool::Parameter(V2,Eforward,CurFace)); |
737 | if (VonDegen.Contains(V1)) |
738 | { |
739 | if (Abs(P2d1.Y() - vf1) <= Precision::Confusion()) |
740 | { |
741 | P1 = MinApex; vstart = v1; |
742 | } |
743 | else |
744 | { |
745 | P1 = MaxApex; vstart = v2; |
746 | } |
747 | } |
748 | else |
749 | { |
750 | TheSurf->D0(P2d1.X(),P2d1.Y(),P1); |
751 | P1.Transform(L.Transformation()); |
752 | vstart = P2d1.Y(); |
753 | } |
754 | if (VonDegen.Contains(V2)) |
755 | { |
756 | if (Abs(P2d2.Y() - vf1) <= Precision::Confusion()) |
757 | { |
758 | P2 = MinApex; vend = v1; |
759 | } |
760 | else |
761 | { |
762 | P2 = MaxApex; vend = v2; |
763 | } |
764 | } |
765 | else |
766 | { |
767 | TheSurf->D0(P2d2.X(),P2d2.Y(),P2); |
768 | P2.Transform(L.Transformation()); |
769 | vend = P2d2.Y(); |
770 | } |
771 | // E a-t-il ume image dans la Map des Created ? |
772 | if ( Created.IsBound(E)) { |
773 | OE = TopoDS::Edge(Created(E)); |
774 | } |
775 | else if (MapSS.IsBound(E)) //seam edge |
776 | OE = TopoDS::Edge(MapSS(E)); |
777 | else { |
778 | myBuilder.MakeEdge(OE); |
779 | TopoDS_Vertex OV1,OV2; |
780 | if ( MapSS.IsBound(V1)) { |
781 | OV1 = TopoDS::Vertex(MapSS(V1)); |
782 | } |
783 | else { |
784 | myBuilder.MakeVertex(OV1); |
785 | myBuilder.UpdateVertex(OV1,P1,BRep_Tool::Tolerance(V1)); |
786 | MapSS.Bind(V1,OV1); |
787 | } |
788 | if ( MapSS.IsBound(V2)) { |
789 | OV2 = TopoDS::Vertex(MapSS(V2)); |
790 | } |
791 | else { |
792 | myBuilder.MakeVertex(OV2); |
793 | myBuilder.UpdateVertex(OV2,P2,BRep_Tool::Tolerance(V2)); |
794 | MapSS.Bind(V2,OV2); |
795 | } |
796 | myBuilder.Add(OE,OV1.Oriented(V1.Orientation())); |
797 | myBuilder.Add(OE,OV2.Oriented(V2.Orientation())); |
798 | if (BRep_Tool::Degenerated(E)) { |
799 | myBuilder.Degenerated(OE, Standard_True); |
800 | /* |
801 | #ifdef DEB |
802 | gp_Pnt P1,P2; |
803 | gp_Pnt2d P2d; |
804 | P2d = C2d->Value(f); TheSurf->D0(P2d.X(),P2d.Y(),P1); |
805 | P2d = C2d->Value(l); TheSurf->D0(P2d.X(),P2d.Y(),P2); |
806 | Standard_Real Tol = BRep_Tool::Tolerance(V1); |
807 | if (!P1.IsEqual(P2,Tol)) { |
808 | cout <<"BRepOffset_Offset : E degenerated -> OE not degenerated"<<endl; |
809 | } |
810 | #endif |
811 | */ |
812 | } |
813 | } |
814 | if (VonDegen.Contains(V1) || VonDegen.Contains(V2)) |
815 | { |
816 | if (VonDegen.Contains(V1)) |
817 | P2d1.SetY( vstart ); |
818 | if (VonDegen.Contains(V2)) |
819 | P2d2.SetY( vend ); |
820 | C2d = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) ); |
821 | f = 0.; l = P2d1.Distance( P2d2 ); |
822 | if (MapSS.IsBound(E)) //seam edge |
823 | { |
824 | Handle(Geom2d_Curve) C2d_1 = BRep_Tool::CurveOnSurface(OE, myFace, f, l); |
825 | if (E.Orientation() == TopAbs_FORWARD) |
826 | UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E)); |
827 | else |
828 | UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E)); |
829 | } |
830 | else |
831 | UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E)); |
832 | //myBuilder.Range(OE,f,l); |
833 | myBuilder.Range(OE, myFace, f, l); |
834 | if (!BRep_Tool::Degenerated(E) && TheSurf->IsUClosed()) |
835 | { |
836 | TopoDS_Shape aLocalShape = E.Reversed(); |
837 | Handle(Geom2d_Curve) C2d_1 = |
838 | BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l); |
839 | P2d1 = C2d_1->Value(BRep_Tool::Parameter(V1,E,CurFace)); |
840 | P2d2 = C2d_1->Value(BRep_Tool::Parameter(V2,E,CurFace)); |
841 | if (VonDegen.Contains(V1)) |
842 | P2d1.SetY( vstart ); |
843 | if (VonDegen.Contains(V2)) |
844 | P2d2.SetY( vend ); |
845 | C2d_1 = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) ); |
846 | if ( E.Orientation() == TopAbs_FORWARD) |
847 | UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E)); |
848 | else |
849 | UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E)); |
850 | } |
851 | /* |
852 | if (!BRep_Tool::Degenerated(E)) |
853 | { |
854 | Handle(Geom_Line) theLine = new Geom_Line( P1, gp_Vec(P1, P2) ); |
855 | myBuilder.UpdateEdge( OE, theLine, BRep_Tool::Tolerance(E) ); |
856 | } |
857 | */ |
858 | } |
859 | else |
860 | { |
861 | UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E)); |
862 | myBuilder.Range(OE,f,l); |
863 | //ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E)); |
864 | } |
865 | if (!BRep_Tool::Degenerated(OE)) |
866 | ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E)); |
867 | MapSS.Bind(E,OE); |
868 | } |
869 | myBuilder.Add(OW, OE.Oriented(E.Orientation())); |
870 | } |
871 | myBuilder.Add(myFace, OW.Oriented(W.Orientation())); |
872 | } |
873 | |
874 | myFace.Orientation(Face.Orientation()); |
875 | |
876 | BRepTools::Update(myFace); |
877 | } |
878 | |
879 | |
880 | //======================================================================= |
881 | //function : Init |
882 | //purpose : |
883 | //======================================================================= |
884 | |
885 | void BRepOffset_Offset::Init(const TopoDS_Edge& Path, |
886 | const TopoDS_Edge& Edge1, |
887 | const TopoDS_Edge& Edge2, |
888 | const Standard_Real Offset, |
889 | const Standard_Boolean Polynomial, |
890 | const Standard_Real Tol, |
891 | const GeomAbs_Shape Conti) |
892 | { |
893 | TopoDS_Edge FirstEdge,LastEdge; |
894 | Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti); |
895 | } |
896 | |
897 | |
898 | //======================================================================= |
899 | //function : Init |
900 | //purpose : |
901 | //======================================================================= |
902 | |
903 | void BRepOffset_Offset::Init(const TopoDS_Edge& Path, |
904 | const TopoDS_Edge& Edge1, |
905 | const TopoDS_Edge& Edge2, |
906 | const Standard_Real Offset, |
907 | const TopoDS_Edge& FirstEdge, |
908 | const TopoDS_Edge& LastEdge, |
909 | const Standard_Boolean Polynomial, |
910 | const Standard_Real Tol, |
911 | const GeomAbs_Shape Conti) |
912 | { |
913 | Standard_Boolean C1Denerated = Standard_False; |
914 | Standard_Boolean C2Denerated = Standard_False; |
915 | myStatus = BRepOffset_Good; |
916 | myShape = Path; |
917 | |
918 | TopLoc_Location Loc; |
919 | Standard_Real f[3],l[3]; |
920 | |
921 | Handle(Geom_Curve) CP = BRep_Tool::Curve(Path,Loc,f[0],l[0]); |
922 | CP = new Geom_TrimmedCurve(CP,f[0], l[0]); |
923 | CP->Transform(Loc.Transformation()); |
924 | Handle(GeomAdaptor_HCurve) HCP = new GeomAdaptor_HCurve(CP); |
925 | |
926 | Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,Loc,f[1],l[1]); |
927 | |
928 | Handle(Adaptor3d_HCurve) HEdge1; |
929 | Standard_Boolean C1is3D = Standard_True; |
930 | if (C1.IsNull()) { |
931 | C1is3D = Standard_False; |
932 | Handle(Geom2d_Curve) C12d; |
933 | Handle(Geom_Surface) S1; |
934 | BRep_Tool::CurveOnSurface(Edge1,C12d,S1,Loc,f[1],l[1]); |
935 | S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation())); |
936 | C12d = new Geom2d_TrimmedCurve(C12d,f[1],l[1]); |
937 | Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(S1); |
938 | Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C12d); |
939 | Adaptor3d_CurveOnSurface Cons(HC1,HS1); |
940 | HEdge1 = new Adaptor3d_HCurveOnSurface(Cons); |
941 | } |
942 | else { |
943 | C1 = new Geom_TrimmedCurve(C1, f[1], l[1]); |
944 | C1->Transform(Loc.Transformation()); |
945 | HEdge1 = new GeomAdaptor_HCurve(C1); |
946 | GeomAdaptor_Curve AC1(C1); |
947 | if ( AC1.GetType() == GeomAbs_Circle) { |
948 | C1Denerated = (AC1.Circle().Radius() < Precision::Confusion()); |
949 | } |
950 | } |
951 | |
952 | Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,Loc,f[2],l[2]); |
953 | |
954 | Handle(Adaptor3d_HCurve) HEdge2; |
955 | Standard_Boolean C2is3D = Standard_True; |
956 | if (C2.IsNull()) { |
957 | C2is3D = Standard_False; |
958 | Handle(Geom2d_Curve) C12d; |
959 | Handle(Geom_Surface) S1; |
960 | BRep_Tool::CurveOnSurface(Edge2,C12d,S1,Loc,f[2],l[2]); |
961 | S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation())); |
962 | C12d = new Geom2d_TrimmedCurve(C12d,f[2],l[2]); |
963 | Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(S1); |
964 | Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C12d); |
965 | Adaptor3d_CurveOnSurface Cons(HC1,HS1); |
966 | HEdge2 = new Adaptor3d_HCurveOnSurface(Cons); |
967 | } |
968 | else { |
969 | C2 = new Geom_TrimmedCurve(C2, f[2], l[2]); |
970 | C2->Transform(Loc.Transformation()); |
971 | HEdge2 = new GeomAdaptor_HCurve(C2); |
972 | GeomAdaptor_Curve AC2(C2); |
973 | if ( AC2.GetType() == GeomAbs_Circle) { |
974 | C2Denerated = (AC2.Circle().Radius() < Precision::Confusion()); |
975 | } |
976 | } |
977 | |
978 | // Calcul du tuyau |
979 | GeomFill_Pipe Pipe(HCP, HEdge1, HEdge2, Abs(Offset)); |
980 | Pipe.Perform(Tol, Polynomial, Conti); |
981 | Standard_Real ErrorPipe = Pipe.ErrorOnSurf(); |
982 | |
983 | Handle(Geom_Surface) S = Pipe.Surface(); |
984 | Standard_Boolean ExchUV = Pipe.ExchangeUV(); |
985 | Standard_Real f1,l1,f2,l2; |
986 | S->Bounds(f1,l1,f2,l2); |
987 | |
988 | // Perform the face |
989 | Standard_Real PathTol = BRep_Tool::Tolerance(Path); |
990 | Standard_Real TheTol; |
991 | BRep_Builder myBuilder; |
992 | myBuilder.MakeFace(myFace); |
993 | TopLoc_Location Id; |
994 | myBuilder.UpdateFace(myFace,S,Id,PathTol); |
995 | |
996 | // update de Edge1. (Rem : has already a 3d curve) |
997 | Standard_Real U,U1,U2; |
998 | Handle(Geom2d_Curve) PC; |
999 | if ( ExchUV) { |
1000 | PC = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)); |
1001 | U1 = f1; |
1002 | U2 = l1; |
1003 | if (!C1is3D) C1 = S->VIso(f2); |
1004 | } |
1005 | else { |
1006 | PC = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)); |
1007 | U1 = f2; |
1008 | U2 = l2; |
1009 | if (!C1is3D) C1 = S->UIso(f1); |
1010 | } |
1011 | |
1012 | Handle(Geom_Curve) Dummy; |
1013 | if (!C1is3D) |
1014 | UpdateEdge(Edge1,C1,Id,BRep_Tool::Tolerance(Edge1)); |
1015 | else if ( C1Denerated) { |
1016 | UpdateEdge(Edge1,Dummy,Id,BRep_Tool::Tolerance(Edge1)); |
1017 | myBuilder.Degenerated(Edge1,Standard_True); |
1018 | } |
1019 | |
1020 | TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge1) + ErrorPipe); |
1021 | UpdateEdge(Edge1, PC, myFace, TheTol); |
1022 | |
1023 | // mise a same range de la nouvelle pcurve. |
1024 | if ( !C1is3D && !C1Denerated) |
1025 | myBuilder.SameRange (Edge1,Standard_False); |
1026 | if ( !C1is3D && !C1Denerated) |
1027 | Range3d(Edge1,U1,U2); |
1028 | myBuilder.Range (Edge1,myFace,U1,U2); |
1029 | Range3d(Edge1,U1,U2); |
1030 | myBuilder.Range (Edge1,myFace,U1,U2); |
1031 | BRepLib::SameRange(Edge1); |
1032 | |
1033 | // mise a sameparameter pour les KPart |
1034 | if (ErrorPipe == 0) { |
1035 | TheTol = Max(TheTol, Tol); |
1036 | myBuilder.SameParameter(Edge1,Standard_False); |
1037 | BRepLib::SameParameter(Edge1, TheTol); |
1038 | } |
1039 | |
1040 | // Update de edge2. (Rem : has already a 3d curve) |
1041 | if (ExchUV) { |
1042 | PC = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)); |
1043 | U1 = f1; |
1044 | U2 = l1; |
1045 | if (!C2is3D) C2 = S->VIso(l2); |
1046 | } |
1047 | else { |
1048 | PC = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)); |
1049 | U1 = f2; |
1050 | U2 = l2; |
1051 | if (!C2is3D) C2 = S->UIso(l1); |
1052 | } |
1053 | |
1054 | if (!C2is3D) |
1055 | UpdateEdge(Edge2,C2,Id,BRep_Tool::Tolerance(Edge2)); |
1056 | else if ( C2Denerated) { |
1057 | UpdateEdge(Edge2,Dummy,Id,BRep_Tool::Tolerance(Edge2)); |
1058 | myBuilder.Degenerated(Edge2,Standard_True); |
1059 | } |
1060 | |
1061 | TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge2) + ErrorPipe); |
1062 | UpdateEdge(Edge2, PC, myFace, TheTol); |
1063 | |
1064 | // mise a same range de la nouvelle pcurve. |
1065 | myBuilder.SameRange (Edge2,Standard_False); |
1066 | if ( !C2is3D && !C2Denerated) Range3d(Edge2,U1,U2); |
1067 | myBuilder.Range(Edge2,myFace,U1,U2); |
1068 | BRepLib::SameRange(Edge2); |
1069 | |
1070 | // mise a sameparameter pour les KPart |
1071 | if (ErrorPipe == 0) { |
1072 | TheTol = Max(TheTol, Tol); |
1073 | myBuilder.SameParameter(Edge2,Standard_False); |
1074 | BRepLib::SameParameter(Edge2, TheTol); |
1075 | } |
1076 | |
1077 | TopoDS_Edge Edge3, Edge4; |
1078 | // eval edge3 |
1079 | TopoDS_Vertex V1f,V1l,V2f,V2l; |
1080 | TopExp::Vertices(Path,V1f,V1l); |
1081 | Standard_Boolean IsClosed = ( V1f.IsSame(V1l)); |
1082 | |
1083 | TopExp::Vertices(Edge1,V1f,V1l); |
1084 | TopExp::Vertices(Edge2,V2f,V2l); |
1085 | |
1086 | Standard_Boolean StartDegenerated = (V1f.IsSame(V2f)); |
1087 | Standard_Boolean EndDegenerated = (V1l.IsSame(V2l)); |
1088 | |
1089 | Standard_Boolean E3rev = Standard_False; |
1090 | Standard_Boolean E4rev = Standard_False; |
1091 | |
1092 | TopoDS_Vertex VVf,VVl; |
1093 | if ( FirstEdge.IsNull()) { |
1094 | myBuilder.MakeEdge(Edge3); |
1095 | myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD)); |
1096 | myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED)); |
1097 | } |
1098 | else { |
1099 | TopoDS_Shape aLocalEdge = FirstEdge.Oriented(TopAbs_FORWARD); |
1100 | Edge3 = TopoDS::Edge(aLocalEdge); |
1101 | // Edge3 = TopoDS::Edge(FirstEdge.Oriented(TopAbs_FORWARD)); |
1102 | TopExp::Vertices(Edge3,VVf,VVl); |
1103 | #ifdef DEB |
1104 | // si firstedge n est pas nul, il faut que les vertex soient partages |
1105 | if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) { |
1106 | cout << "Attention Vertex non partages !!!!!!" << endl; |
1107 | } |
1108 | #endif |
1109 | if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) { |
1110 | // On fait vraisemblablement des conneries !! |
1111 | // On cree un autre edge, on appelle le Sewing apres. |
1112 | myBuilder.MakeEdge(Edge3); |
1113 | myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD)); |
1114 | myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED)); |
1115 | } |
1116 | else if ( !VVf.IsSame(V1f)) { |
1117 | Edge3.Reverse(); |
1118 | E3rev = Standard_True; |
1119 | } |
1120 | } |
1121 | |
1122 | if ( IsClosed) |
1123 | Edge4 = Edge3; |
1124 | |
1125 | Standard_Real TolApp = Precision::Approximation(); |
1126 | |
1127 | Handle(Geom2d_Line) L1,L2; |
1128 | if ( IsClosed) { |
1129 | if ( ExchUV) { |
1130 | // rem : si ExchUv, il faut reverser le Wire. |
1131 | // donc l'edge Forward dans la face sera E4 : d'ou L1 et L2 |
1132 | L2 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)); |
1133 | L1 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)); |
1134 | U1 = f2; |
1135 | U2 = l2; |
1136 | } |
1137 | else { |
1138 | L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)); |
1139 | L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)); |
1140 | U1 = f1; |
1141 | U2 = l1; |
1142 | } |
1143 | if ( E3rev) { |
1144 | L1->Reverse(); L2->Reverse(); |
1145 | U = -U1; |
1146 | U1 = -U2; |
1147 | U2 = U; |
1148 | } |
1149 | UpdateEdge(Edge3, L1, L2, myFace,PathTol); |
1150 | myBuilder.Range(Edge3,myFace,U1,U2); |
1151 | if (StartDegenerated) |
1152 | myBuilder.Degenerated(Edge3,Standard_True); |
1153 | else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed |
1154 | ComputeCurve3d(Edge3,L1,S,Id,TolApp); |
1155 | } |
1156 | else { |
1157 | if ( LastEdge.IsNull()) { |
1158 | myBuilder.MakeEdge(Edge4); |
1159 | myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD)); |
1160 | myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED)); |
1161 | } |
1162 | else { |
1163 | TopoDS_Shape aLocalEdge = LastEdge.Oriented(TopAbs_FORWARD); |
1164 | Edge4 = TopoDS::Edge(aLocalEdge); |
1165 | // Edge4 = TopoDS::Edge(LastEdge.Oriented(TopAbs_FORWARD)); |
1166 | TopExp::Vertices(Edge4,VVf,VVl); |
1167 | #ifdef DEB |
1168 | // si lastedge n est pas nul, il faut que les vertex soient partages |
1169 | if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) { |
1170 | cout << "Attention Vertex non partages !!!!!!" << endl; |
1171 | } |
1172 | #endif |
1173 | if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) { |
1174 | // On fait vraisemblablement des conneries !! |
1175 | // On cree un autre edge, on appelle le Sewing apres. |
1176 | myBuilder.MakeEdge(Edge4); |
1177 | myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD)); |
1178 | myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED)); |
1179 | } |
1180 | else if ( !VVf.IsSame(V1l)) { |
1181 | Edge4.Reverse(); |
1182 | E4rev = Standard_True; |
1183 | } |
1184 | } |
1185 | |
1186 | if (ExchUV) { |
1187 | L1 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)); |
1188 | U1 = f2; |
1189 | U2 = l2; |
1190 | } |
1191 | else { |
1192 | L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)); |
1193 | U1 = f1; |
1194 | U2 = l1; |
1195 | } |
1196 | if ( E3rev) { |
1197 | L1->Reverse(); |
1198 | U = -U1; |
1199 | U1 = -U2; |
1200 | U2 = U; |
1201 | } |
1202 | UpdateEdge(Edge3,L1,myFace,PathTol); |
1203 | myBuilder.Range(Edge3,myFace,U1,U2); |
1204 | if (StartDegenerated) |
1205 | myBuilder.Degenerated(Edge3,Standard_True); |
1206 | else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed |
1207 | ComputeCurve3d(Edge3,L1,S,Id,TolApp); |
1208 | |
1209 | if (ExchUV) { |
1210 | L2 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)); |
1211 | U1 = f2; |
1212 | U2 = l2; |
1213 | } |
1214 | else { |
1215 | L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)); |
1216 | U1 = f1; |
1217 | U2 = l1; |
1218 | } |
1219 | if ( E4rev) { |
1220 | L2->Reverse(); |
1221 | U = -U1; |
1222 | U1 = -U2; |
1223 | U2 = U; |
1224 | } |
1225 | UpdateEdge(Edge4,L2 ,myFace,PathTol); |
1226 | myBuilder.Range(Edge4,myFace,U1,U2); |
1227 | if (EndDegenerated) |
1228 | myBuilder.Degenerated(Edge4,Standard_True); |
1229 | else if (LastEdge.IsNull()) // then the 3d curve has not been yet computed |
1230 | ComputeCurve3d(Edge4,L2,S,Id,TolApp); |
1231 | } |
1232 | |
1233 | // SameParameter ?? |
1234 | if ( !FirstEdge.IsNull() && !StartDegenerated) { |
1235 | BRepLib::BuildCurve3d (Edge3,PathTol); |
1236 | myBuilder.SameRange (Edge3,Standard_False); |
1237 | myBuilder.SameParameter(Edge3,Standard_False); |
1238 | BRepLib::SameParameter (Edge3, Tol); |
1239 | } |
1240 | if ( !LastEdge.IsNull() && !EndDegenerated) { |
1241 | BRepLib::BuildCurve3d (Edge4,PathTol); |
1242 | myBuilder.SameRange (Edge4,Standard_False); |
1243 | myBuilder.SameParameter(Edge4,Standard_False); |
1244 | BRepLib::SameParameter (Edge4, Tol); |
1245 | } |
1246 | |
1247 | TopoDS_Wire W; |
1248 | myBuilder.MakeWire(W); |
1249 | |
1250 | myBuilder.Add(W, Edge1.Oriented(TopAbs_REVERSED)); |
1251 | myBuilder.Add(W, Edge2.Oriented(TopAbs_FORWARD)); |
1252 | myBuilder.Add(W, Edge4.Reversed()); |
1253 | myBuilder.Add(W, Edge3); |
1254 | |
1255 | if (ExchUV) { |
1256 | W.Reverse(); |
1257 | } |
1258 | |
1259 | myBuilder.Add(myFace, W); |
1260 | if (ExchUV) myFace.Reverse(); |
1261 | |
1262 | BRepTools::Update(myFace); |
1263 | |
1264 | if ( Edge1.Orientation() == TopAbs_REVERSED) |
1265 | myFace.Reverse(); |
1266 | |
1267 | } |
1268 | |
1269 | |
1270 | //======================================================================= |
1271 | //function : Init |
1272 | //purpose : |
1273 | //======================================================================= |
1274 | |
1275 | void BRepOffset_Offset::Init(const TopoDS_Vertex& Vertex, |
1276 | const TopTools_ListOfShape& LEdge, |
1277 | const Standard_Real Offset, |
1278 | const Standard_Boolean Polynomial, |
1279 | const Standard_Real TolApp, |
1280 | const GeomAbs_Shape Conti) |
1281 | { |
1282 | myStatus = BRepOffset_Good; |
1283 | myShape = Vertex; |
1284 | |
1285 | // evaluate the Ax3 of the Sphere |
1286 | // find 3 different vertices in LEdge |
1287 | TopTools_ListIteratorOfListOfShape it; |
1288 | gp_Pnt P, P1, P2, P3; |
1289 | TopoDS_Vertex V1, V2, V3, V4; |
1290 | |
1291 | |
1292 | #ifdef DEB |
1293 | char* name = new char[100]; |
1294 | if (Affich) { |
1295 | NbOFFSET++; |
1296 | |
1297 | sprintf(name,"VOnSph_%d",NbOFFSET); |
1298 | #ifdef DRAW |
1299 | DBRep::Set(name, Vertex); |
1300 | #endif |
1301 | Standard_Integer NbEdges = 1; |
1302 | for (it.Initialize(LEdge); it.More(); it.Next()) { |
1303 | const TopoDS_Edge& CurE = TopoDS::Edge(it.Value()); |
1304 | sprintf(name,"EOnSph_%d_%d",NbOFFSET,NbEdges++); |
1305 | #ifdef DRAW |
1306 | DBRep::Set(name, CurE); |
1307 | #endif |
1308 | } |
1309 | |
1310 | } |
1311 | #endif |
1312 | |
1313 | |
1314 | it.Initialize(LEdge); |
1315 | TopExp::Vertices(TopoDS::Edge(it.Value()), V1, V2); |
1316 | P1 = BRep_Tool::Pnt(V1); |
1317 | P2 = BRep_Tool::Pnt(V2); |
1318 | |
1319 | if ( !it.More()) { |
1320 | Standard_ConstructionError::Raise("BRepOffset_Sphere"); |
1321 | } |
1322 | it.Next(); |
1323 | TopExp::Vertices(TopoDS::Edge(it.Value()), V3, V4); |
1324 | |
1325 | P3 = BRep_Tool::Pnt(V3); |
1326 | Standard_Real eps = 1.e-8; |
1327 | if ( P1.Distance(P3) < eps || P2.Distance(P3) < eps) |
1328 | P3 = BRep_Tool::Pnt(V4); |
1329 | |
1330 | P = BRep_Tool::Pnt(Vertex); |
1331 | |
1332 | gp_Vec X = gp_Vec(P1,P2) ^ gp_Vec(P1,P3); |
1333 | if ( X * gp_Vec(P1,P) < 0.) X.Reverse(); |
1334 | |
1335 | gp_Ax3 Axis( P, gp_Dir(gp_Vec(P1,P2)), gp_Dir(X)); |
1336 | Handle(Geom_Surface) S |
1337 | = new Geom_SphericalSurface( Axis, Abs(Offset)); |
1338 | |
1339 | Standard_Real f, l, Tol = BRep_Tool::Tolerance(Vertex); |
1340 | |
1341 | TopLoc_Location Loc; |
1342 | BRep_Builder myBuilder; |
1343 | myBuilder.MakeFace(myFace); |
1344 | Handle(Geom_Surface) SS = S; |
1345 | |
1346 | // En polynomial, calcul de la surface par F(u,v). |
1347 | // Pas de changement de parametre, donc ProjLib sur la Sphere |
1348 | // reste OK. |
1349 | if (Polynomial) { |
1350 | GeomConvert_ApproxSurface Approx(S,TolApp,Conti,Conti,10,10,10,1); |
1351 | if (Approx.IsDone()) { |
1352 | SS = Approx.Surface(); |
1353 | } |
1354 | } |
1355 | |
1356 | myBuilder.UpdateFace(myFace, SS, Loc, Tol); |
1357 | |
1358 | TopoDS_Wire W; |
1359 | myBuilder.MakeWire(W); |
1360 | |
1361 | #ifdef DRAW |
1362 | // POP pour NT |
1363 | // char name[100]; |
1364 | if (Affich) { |
1365 | sprintf(name,"SPHERE_%d",NbOFFSET); |
1366 | DrawTrSurf::Set(name, S); |
1367 | } |
1368 | Standard_Integer CO = 1; |
1369 | #endif |
1370 | |
1371 | for ( it.Initialize(LEdge); it.More(); it.Next()) { |
1372 | TopoDS_Edge E = TopoDS::Edge(it.Value()); |
1373 | |
1374 | Handle(Geom_Curve) C = BRep_Tool::Curve(E,Loc,f,l); |
1375 | if ( C.IsNull()) { |
1376 | BRepLib::BuildCurve3d(E,BRep_Tool::Tolerance(E)); |
1377 | C = BRep_Tool::Curve(E,Loc,f,l); |
1378 | } |
1379 | C = new Geom_TrimmedCurve(C, f, l); |
1380 | C->Transform(Loc.Transformation()); |
1381 | |
1382 | #ifdef DRAW |
1383 | if ( Affich) { |
1384 | sprintf(name,"CURVE_%d_%d",NbOFFSET,CO); |
1385 | DrawTrSurf::Set(name, C); |
1386 | CO++; |
1387 | } |
1388 | #endif |
1389 | |
1390 | Handle(Geom2d_Curve) PCurve = GeomProjLib::Curve2d(C, S); |
1391 | // check if the first point of PCurve in is the canonical boundaries |
1392 | // of the sphere. Else move it. |
1393 | // the transformation is : U` = U + PI + 2 k PI |
1394 | // V` = +/- PI + 2 k` PI |
1395 | gp_Pnt2d P2d = PCurve->Value(f); |
1396 | Standard_Boolean IsToAdjust = Standard_False; |
1397 | if ( P2d.Y() < -PI/2.) { |
1398 | IsToAdjust = Standard_True; |
1399 | PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0.,-PI/2.),gp::DX2d())); |
1400 | } |
1401 | else if ( P2d.Y() > PI/2.) { |
1402 | IsToAdjust = Standard_True; |
1403 | PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0., PI/2.),gp::DX2d())); |
1404 | } |
1405 | if ( IsToAdjust) { |
1406 | // set the u firstpoint in [0,2*pi] |
1407 | gp_Vec2d Tr( PI, 0.); |
1408 | if ( P2d.X() > PI) Tr.Reverse(); |
1409 | PCurve->Translate(Tr); |
1410 | } |
1411 | |
1412 | UpdateEdge(E, PCurve, myFace, Tol); |
1413 | myBuilder.Range(E, myFace, f, l); |
1414 | myBuilder.Add(W, E); |
1415 | } |
1416 | if ( Offset < 0.) { |
1417 | myBuilder.Add(myFace, W.Oriented(TopAbs_REVERSED)); |
1418 | myFace.Reverse(); |
1419 | } |
1420 | else { |
1421 | myBuilder.Add(myFace, W); |
1422 | } |
1423 | |
1424 | BRepTools::Update(myFace); |
1425 | } |
1426 | |
1427 | |
1428 | //======================================================================= |
1429 | //function : Init |
1430 | //purpose : |
1431 | //======================================================================= |
1432 | |
1433 | void BRepOffset_Offset::Init(const TopoDS_Edge& Edge, |
1434 | const Standard_Real Offset) |
1435 | { |
1436 | myShape = Edge; |
1437 | Standard_Real myOffset = Abs(Offset); |
1438 | |
1439 | Standard_Real f,l; |
1440 | TopLoc_Location Loc; |
1441 | |
1442 | Handle(Geom_Curve) CP = BRep_Tool::Curve(Edge,Loc,f,l); |
1443 | CP = new Geom_TrimmedCurve(CP,f,l); |
1444 | CP->Transform(Loc.Transformation()); |
1445 | |
1446 | GeomFill_Pipe Pipe(CP,myOffset); |
1447 | Pipe.Perform(); |
1448 | |
1449 | BRepLib_MakeFace MF(Pipe.Surface()); |
1450 | myFace = MF.Face(); |
1451 | |
1452 | if ( Offset < 0.) myFace.Reverse(); |
1453 | } |
1454 | |
1455 | |
1456 | //======================================================================= |
1457 | //function : Face |
1458 | //purpose : |
1459 | //======================================================================= |
1460 | |
1461 | const TopoDS_Face& BRepOffset_Offset::Face() const |
1462 | { |
1463 | return myFace; |
1464 | } |
1465 | |
1466 | |
1467 | //======================================================================= |
1468 | //function : Generated |
1469 | //purpose : |
1470 | //======================================================================= |
1471 | |
1472 | TopoDS_Shape BRepOffset_Offset::Generated(const TopoDS_Shape& Shape) const |
1473 | { |
1474 | TopoDS_Shape aShape; |
1475 | |
1476 | switch ( myShape.ShapeType()) { |
1477 | |
1478 | case TopAbs_FACE: |
1479 | { |
1480 | TopExp_Explorer exp (myShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE); |
1481 | TopExp_Explorer expo(myFace .Oriented(TopAbs_FORWARD), TopAbs_EDGE); |
1482 | for ( ; exp.More() && expo.More(); exp.Next(), expo.Next()) { |
1483 | if ( Shape.IsSame(exp.Current())) { |
1484 | if ( myShape.Orientation() == TopAbs_REVERSED) |
1485 | aShape = expo.Current().Reversed(); |
1486 | else |
1487 | aShape = expo.Current(); |
1488 | } |
1489 | } |
1490 | } |
1491 | break; |
1492 | |
1493 | case TopAbs_EDGE: |
1494 | // have generate a pipe. |
1495 | { |
1496 | TopoDS_Vertex V1, V2; |
1497 | TopExp::Vertices(TopoDS::Edge(myShape), V1, V2); |
1498 | |
1499 | TopExp_Explorer expf(myFace .Oriented(TopAbs_FORWARD), TopAbs_WIRE); |
1500 | TopExp_Explorer expo(expf.Current().Oriented(TopAbs_FORWARD), |
1501 | TopAbs_EDGE); |
1502 | expo.Next(); |
1503 | expo.Next(); |
1504 | |
1505 | if ( V2.IsSame(Shape)) { |
1506 | if ( expf.Current().Orientation() == TopAbs_REVERSED) |
1507 | aShape = expo.Current().Reversed(); |
1508 | else |
1509 | aShape = expo.Current(); |
1510 | } |
1511 | else { |
1512 | expo.Next(); |
1513 | if ( expf.Current().Orientation() == TopAbs_REVERSED) |
1514 | aShape = expo.Current().Reversed(); |
1515 | else |
1516 | aShape = expo.Current(); |
1517 | } |
1518 | if ( myFace.Orientation() == TopAbs_REVERSED) |
1519 | aShape.Reverse(); |
1520 | } |
1521 | break; |
1522 | #ifndef DEB |
1523 | default: |
1524 | break; |
1525 | #endif |
1526 | } |
1527 | |
1528 | return aShape; |
1529 | } |
1530 | |
1531 | |
1532 | //======================================================================= |
1533 | //function : Status |
1534 | //purpose : |
1535 | //======================================================================= |
1536 | |
1537 | BRepOffset_Status BRepOffset_Offset::Status() const |
1538 | { |
1539 | return myStatus; |
1540 | } |
1541 | |
1542 | |
1543 | |