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