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