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