1 // Created on: 1995-10-19
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepOffset_Offset.ixx>
19 #include <Adaptor3d_HCurveOnSurface.hxx>
20 #include <Adaptor3d_CurveOnSurface.hxx>
21 #include <BRepOffset.hxx>
22 #include <BRepLib.hxx>
23 #include <BRepLib_MakeFace.hxx>
24 #include <BRepTools.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRep_Builder.hxx>
28 #include <GeomAPI.hxx>
29 #include <Geom2d_Curve.hxx>
30 #include <Geom2d_Line.hxx>
31 #include <Geom2d_TrimmedCurve.hxx>
32 #include <Geom_Line.hxx>
33 #include <Geom_Circle.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_TrimmedCurve.hxx>
36 #include <Geom_RectangularTrimmedSurface.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_OffsetSurface.hxx>
39 #include <Geom_SphericalSurface.hxx>
40 #include <Geom_ConicalSurface.hxx>
41 #include <GeomAdaptor_HSurface.hxx>
42 #include <GeomAdaptor_Surface.hxx>
43 #include <GeomAdaptor_HCurve.hxx>
44 #include <GeomAdaptor_Curve.hxx>
45 #include <Geom2dAdaptor_HCurve.hxx>
46 #include <Geom2dAdaptor_Curve.hxx>
47 #include <GeomFill_Pipe.hxx>
48 #include <GeomProjLib.hxx>
49 #include <GeomConvert_ApproxSurface.hxx>
50 #include <Precision.hxx>
51 #include <Standard_ConstructionError.hxx>
53 #include <TopoDS_Wire.hxx>
55 #include <TopExp_Explorer.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
59 #include <gp_Cylinder.hxx>
60 #include <gp_Torus.hxx>
62 #include <gp_Pnt2d.hxx>
64 #include <BRep_GCurve.hxx>
65 #include <BRep_TEdge.hxx>
66 #include <BRep_ListOfCurveRepresentation.hxx>
67 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
69 #include <TopTools_SequenceOfShape.hxx>
70 #include <TopTools_MapOfShape.hxx>
71 #include <BRepOffset_Tool.hxx>
72 #include <GeomAPI_ExtremaCurveCurve.hxx>
73 #include <GeomAPI_ProjectPointOnCurve.hxx>
74 #include <GeomLib.hxx>
77 static Standard_Boolean Affich = Standard_False;
78 static Standard_Integer NbOFFSET = 0;
81 #include <DrawTrSurf.hxx>
86 //=======================================================================
87 //function : UpdateEdge
89 //=======================================================================
91 static void UpdateEdge(const TopoDS_Edge& E,
92 const Handle(Geom_Curve)& C,
93 const TopLoc_Location& L,
94 const Standard_Real Tol)
96 // Cut curves to avoid copies in the extensions.
98 Handle(Geom_TrimmedCurve) BC = Handle(Geom_TrimmedCurve)::DownCast(C);
100 B.UpdateEdge(E,BC->BasisCurve(),L,Tol);
103 B.UpdateEdge(E,C,L,Tol);
107 //=======================================================================
108 //function : UpdateEdge
110 //=======================================================================
112 static void UpdateEdge(const TopoDS_Edge& E,
113 const Handle(Geom2d_Curve)& C,
114 const TopoDS_Face& F,
115 const Standard_Real Tol)
117 // Cut curves to avoid copies in the extensions.
119 Handle(Geom2d_TrimmedCurve) BC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
121 B.UpdateEdge(E,BC->BasisCurve(),F,Tol);
124 B.UpdateEdge(E,C,F,Tol);
128 //=======================================================================
129 //function : UpdateEdge
131 //=======================================================================
133 static void UpdateEdge (const TopoDS_Edge& E,
134 const Handle(Geom2d_Curve)& C1,
135 const Handle(Geom2d_Curve)& C2,
136 const TopoDS_Face& F,
137 const Standard_Real Tol)
139 // Cut curves to avoid copies in the extensions.
141 Handle(Geom2d_Curve) NC1,NC2;
142 Handle(Geom2d_TrimmedCurve) BC1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
143 Handle(Geom2d_TrimmedCurve) BC2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
144 if (!BC1.IsNull()) NC1 = BC1->BasisCurve(); else NC1 = C1;
145 if (!BC2.IsNull()) NC2 = BC2->BasisCurve(); else NC2 = C2;
146 B.UpdateEdge(E,NC1,NC2,F,Tol);
149 //=======================================================================
151 //purpose : Set the range only on the 3d curve
152 // waitint that BRep_Builder does it !!
153 //=======================================================================
155 static void Range3d (const TopoDS_Edge& E,
156 const Standard_Real First,
157 const Standard_Real Last)
159 // set the range to all the representations
160 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
162 BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
163 BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
164 Handle(BRep_GCurve) GC;
166 while (itcr.More()) {
167 GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
169 if (GC->IsCurve3D()) {
170 GC->SetRange(First,Last);
171 // Set the closedness flag to the correct value.
172 Handle(Geom_Curve) C = GC->Curve3D();
174 Standard_Boolean closed =
175 C->Value(First).IsEqual(C->Value(Last),BRep_Tool::Tolerance(E));
183 TE->Modified(Standard_True);
187 //=======================================================================
188 //function : ComputeCurve3d
189 //purpose : Particular case of Curve On Surface.
190 //=======================================================================
192 static void ComputeCurve3d(TopoDS_Edge Edge,
193 Handle(Geom2d_Curve) Curve,
194 Handle(Geom_Surface) Surf,
195 const TopLoc_Location Loc,
198 // try to find the particular case
199 // if not found call BRepLib::BuildCurve3d
201 Standard_Boolean IsComputed = Standard_False;
203 // Search only isos on analytic surfaces.
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;
210 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d manage KPart
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();
216 if ( Abs( Abs(P.Y()) -M_PI/2. ) < Precision::PConfusion()) {
217 TheBuilder.Degenerated(Edge, Standard_True);
220 gp_Sphere Sph = S.Sphere();
221 gp_Ax3 Axis = Sph.Position();
222 gp_Circ Ci = ElSLib::SphereVIso(Axis,
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()))
231 UpdateEdge(Edge, Circle, Loc, Tol);
233 IsComputed = Standard_True;
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,
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()))
248 UpdateEdge(Edge, Circle, Loc, Tol);
249 IsComputed = Standard_True;
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,
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()))
265 UpdateEdge(Edge, Circle, Loc, Tol);
266 IsComputed = Standard_True;
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,
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()))
282 UpdateEdge(Edge, Circle, Loc, Tol);
283 IsComputed = Standard_True;
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();
292 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
294 // set to sameparameter (rotation of circle - offset of Y)
295 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
296 gp_Ax1 AxeRev(Axis.Location(),DRev);
297 Ci.Rotate(AxeRev, P.Y());
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);
305 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
307 UpdateEdge(Edge, Circle, Loc, Tol);
308 IsComputed = Standard_True;
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(),
316 gp_Vec Tr(L.Direction());
319 Handle(Geom_Line) Line = new Geom_Line(L);
320 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
322 UpdateEdge(Edge, Line, Loc, Tol);
323 IsComputed = Standard_True;
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(),
332 gp_Vec Tr(L.Direction());
334 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
335 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
337 UpdateEdge(Edge, Line, Loc, Tol);
338 IsComputed = Standard_True;
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,
348 Ci.Rotate(Ci.Axis(),P.Y());
349 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
351 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
353 UpdateEdge(Edge, Circle, Loc, Tol);
354 IsComputed = Standard_True;
360 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
361 UpdateEdge(Edge, C3d, Loc, Tol);
362 IsComputed = Standard_True;
365 //BRepLib::BuildCurves3d(Edge,Tol);
366 //Les Courbes 3d des edges dans le cas general ne sont calcules que si
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.
375 //=======================================================================
376 //function : BRepOffset_Offset
378 //=======================================================================
380 BRepOffset_Offset::BRepOffset_Offset()
385 //=======================================================================
386 //function : BRepOffset_Offset
388 //=======================================================================
390 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Face& Face,
391 const Standard_Real Offset,
392 const Standard_Boolean OffsetOutside,
393 const GeomAbs_JoinType JoinType)
395 Init(Face, Offset, OffsetOutside, JoinType);
399 //=======================================================================
400 //function : BRepOffset_Offset
402 //=======================================================================
404 BRepOffset_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)
411 Init(Face,Offset,Created,OffsetOutside,JoinType);
415 //=======================================================================
416 //function : BRepOffset_Offset
418 //=======================================================================
420 BRepOffset_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)
428 Init(Path,Edge1,Edge2,Offset,Polynomial,Tol,Conti);
432 //=======================================================================
433 //function : BRepOffset_Offset
435 //=======================================================================
437 BRepOffset_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)
448 Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti);
452 //=======================================================================
453 //function : BRepOffset_Offset
455 //=======================================================================
457 BRepOffset_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)
464 Init(Vertex,LEdge,Offset,Polynomial,Tol,Conti);
468 //=======================================================================
471 //=======================================================================
473 void BRepOffset_Offset::Init(const TopoDS_Face& Face,
474 const Standard_Real Offset,
475 const Standard_Boolean OffsetOutside,
476 const GeomAbs_JoinType JoinType)
478 TopTools_DataMapOfShapeShape Empty;
479 Init(Face,Offset,Empty,OffsetOutside,JoinType);
483 //=======================================================================
486 //=======================================================================
488 void 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)
495 Standard_Real myOffset = Offset;
496 if ( Face.Orientation() == TopAbs_REVERSED)
500 Handle(Geom_Surface) S = BRep_Tool::Surface(Face,L);
502 // On detrime les surfaces, evite des recopies dans les extensions.
503 Handle(Geom_RectangularTrimmedSurface) RT =
504 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
505 if (!RT.IsNull()) S = RT->BasisSurface();
507 // particular case of cone
508 Handle(Geom_ConicalSurface) Co;
509 Co = Handle(Geom_ConicalSurface)::DownCast(S);
512 gp_Pnt Apex = Co->Apex();
513 ElSLib::Parameters( Co->Cone(),Apex,Uc,Vc);
514 Standard_Real UU1,UU2,VV1,VV2;
515 BRepTools::UVBounds(Face,UU1,UU2,VV1,VV2);
516 if ( VV2 < Vc && Co->SemiAngle() > 0 )
518 else if ( VV1 > Vc && Co->SemiAngle() < 0 )
520 if ( !Co->Position().Direct()) myOffset *= -1;
523 Handle(Geom_Surface) TheSurf =
524 BRepOffset::Surface( S, myOffset, myStatus);
526 //processing offsets of faces with possible degenerated edges
527 Standard_Boolean VminDegen = Standard_False;
528 Standard_Boolean VmaxDegen = Standard_False;
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)))
537 TopTools_SequenceOfShape DegEdges;
538 TopExp_Explorer Explo(Face, TopAbs_EDGE);
539 for (; Explo.More(); Explo.Next())
541 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
542 if (BRep_Tool::Degenerated(anEdge))
543 DegEdges.Append(anEdge);
545 if (!DegEdges.IsEmpty())
547 const Standard_Real TolApex = 1.e-5;
548 if (DegEdges.Length() == 2)
550 VminDegen = Standard_True;
551 VmaxDegen = Standard_True;
553 else //DegEdges.Length() == 1
555 const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
556 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
557 gp_Pnt2d aPnt2d = aCurve->Value(fpar);
558 if (Abs(aPnt2d.Y() - vf1) <= Precision::Confusion())
559 VminDegen = Standard_True;
561 VmaxDegen = Standard_True;
563 if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
565 gp_Cone theCone = (*((Handle(Geom_ConicalSurface)*)&TheSurf))->Cone();
566 gp_Pnt apex = theCone.Apex();
567 Standard_Real Uapex, Vapex;
568 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
571 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, Vapex, vf2);
573 HasSingularity = Standard_True;
577 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, Vapex);
579 HasSingularity = Standard_True;
582 else //TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)
586 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
587 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
589 Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
590 gp_Pnt Papex, Pfirst, Plast, Pmid;
591 Papex = BasisSurf->Value( uf1, vf1 );
592 Pfirst = TheSurf->Value( uf1, vf1 );
593 Plast = TheSurf->Value( uf2, vf1 );
594 Pmid = TheSurf->Value( (uf1+uf2)/2., vf1 );
595 gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast);
596 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
597 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
598 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
599 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
601 theExtrema.NearestPoints(Pint1, Pint2);
602 Standard_Real length = Pfirst.Distance(Pint1);
605 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
606 GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
607 Standard_False, Standard_False);
608 Standard_Real u1, u2, v1, v2;
609 TheSurf->Bounds( u1, u2, v1, v2 );
610 MinApex = TheSurf->Value( uf1, v1 );
614 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
615 GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
616 Standard_Real NewFirstV = Projector.LowerDistanceParameter();
617 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2);
618 MinApex = TheSurf->Value( uf1, NewFirstV );
619 //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2);
620 //MinApex = TheSurf->Value( uf1, vf1+length );
622 HasSingularity = Standard_True;
624 } //end of if (VminDegen)
627 Handle(Geom_Curve) viso = TheSurf->VIso( vf2 );
628 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
630 Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
631 gp_Pnt Papex, Pfirst, Plast, Pmid;
632 Papex = BasisSurf->Value( uf1, vf2 );
633 Pfirst = TheSurf->Value( uf1, vf2 );
634 Plast = TheSurf->Value( uf2, vf2 );
635 Pmid = TheSurf->Value( (uf1+uf2)/2., vf2 );
636 gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast);
637 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
638 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
639 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
640 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
642 theExtrema.NearestPoints(Pint1, Pint2);
643 Standard_Real length = Pfirst.Distance(Pint1);
646 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
647 GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
648 Standard_False, Standard_True);
649 Standard_Real u1, u2, v1, v2;
650 TheSurf->Bounds( u1, u2, v1, v2 );
651 MaxApex = TheSurf->Value( uf1, v2 );
655 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
656 GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
657 Standard_Real NewLastV = Projector.LowerDistanceParameter();
658 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV);
659 MaxApex = TheSurf->Value( uf1, NewLastV );
660 //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length);
661 //MaxApex = TheSurf->Value( uf1, vf2-length );
663 HasSingularity = Standard_True;
665 } //end of if (VmaxDegen)
666 } //end of else (case of Geom_OffsetSurface)
667 } //end of if (!DegEdges.IsEmpty())
668 } //end of processing offsets of faces with possible degenerated edges
670 // find the PCurves of the edges of <Faces>
672 BRep_Builder myBuilder;
673 myBuilder.MakeFace(myFace);
674 myBuilder.UpdateFace(myFace,TheSurf,L,BRep_Tool::Tolerance(Face));
676 TopTools_DataMapOfShapeShape MapSS;
678 // mise a jour de la map sur les vertex deja crees
679 TopoDS_Shape aLocalShape = Face.Oriented(TopAbs_FORWARD);
680 TopoDS_Face CurFace = TopoDS::Face(aLocalShape);
681 // TopoDS_Face CurFace = TopoDS::Face(Face.Oriented(TopAbs_FORWARD));
683 TopTools_MapOfShape VonDegen;
684 Standard_Real u1, u2, v1, v2;
685 TheSurf->Bounds( u1, u2, v1, v2 );
687 TopExp_Explorer exp(CurFace, TopAbs_EDGE);
688 for ( ; exp.More(); exp.Next()) {
689 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
690 TopoDS_Vertex V1,V2,OV1,OV2;
691 TopExp::Vertices(E ,V1 ,V2 );
692 if (HasSingularity && BRep_Tool::Degenerated(E))
694 if (Created.IsBound(E)) {
695 const TopoDS_Edge& OE = TopoDS::Edge(Created(E));
696 TopExp::Vertices(OE,OV1,OV2);
697 if (!MapSS.IsBound(V1)) MapSS.Bind(V1,OV1);
698 if (!MapSS.IsBound(V2)) MapSS.Bind(V2,OV2);
700 if (Created.IsBound(V1)) {
701 if (!MapSS.IsBound(V1)) MapSS.Bind(V1,Created(V1));
703 if (Created.IsBound(V2)) {
704 if (!MapSS.IsBound(V2)) MapSS.Bind(V2,Created(V2));
708 TopExp_Explorer expw(CurFace, TopAbs_WIRE);
709 for ( ; expw.More(); expw.Next()) {
710 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
711 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
714 myBuilder.MakeWire(OW);
715 for ( ; expe.More(); expe.Next()) {
716 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
718 TopExp::Vertices(E,V1,V2);
721 Standard_Real vstart, vend;
723 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,CurFace,f,l);
725 if (MapSS.IsBound(E) &&
726 !VonDegen.Contains(V1) && !VonDegen.Contains(V2)) { // c`est un edge de couture
727 OE = TopoDS::Edge(MapSS(E));
728 TopoDS_Shape aLocalShape = E.Reversed();
729 Handle(Geom2d_Curve) C2d_1 =
730 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l);
731 // Handle(Geom2d_Curve) C2d_1 =
732 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),CurFace,f,l);
733 if ( E.Orientation() == TopAbs_FORWARD)
734 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
736 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
737 myBuilder.Range(OE,f,l);
740 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
741 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
742 P2d1 = C2d->Value(BRep_Tool::Parameter(V1,Eforward,CurFace));
743 P2d2 = C2d->Value(BRep_Tool::Parameter(V2,Eforward,CurFace));
744 if (VonDegen.Contains(V1))
746 if (Abs(P2d1.Y() - vf1) <= Precision::Confusion())
748 P1 = MinApex; vstart = v1;
752 P1 = MaxApex; vstart = v2;
757 TheSurf->D0(P2d1.X(),P2d1.Y(),P1);
758 P1.Transform(L.Transformation());
761 if (VonDegen.Contains(V2))
763 if (Abs(P2d2.Y() - vf1) <= Precision::Confusion())
765 P2 = MinApex; vend = v1;
769 P2 = MaxApex; vend = v2;
774 TheSurf->D0(P2d2.X(),P2d2.Y(),P2);
775 P2.Transform(L.Transformation());
778 // E a-t-il ume image dans la Map des Created ?
779 if ( Created.IsBound(E)) {
780 OE = TopoDS::Edge(Created(E));
782 else if (MapSS.IsBound(E)) //seam edge
783 OE = TopoDS::Edge(MapSS(E));
785 myBuilder.MakeEdge(OE);
786 TopoDS_Vertex OV1,OV2;
787 if ( MapSS.IsBound(V1)) {
788 OV1 = TopoDS::Vertex(MapSS(V1));
791 myBuilder.MakeVertex(OV1);
792 myBuilder.UpdateVertex(OV1,P1,BRep_Tool::Tolerance(V1));
795 if ( MapSS.IsBound(V2)) {
796 OV2 = TopoDS::Vertex(MapSS(V2));
799 myBuilder.MakeVertex(OV2);
800 myBuilder.UpdateVertex(OV2,P2,BRep_Tool::Tolerance(V2));
803 myBuilder.Add(OE,OV1.Oriented(V1.Orientation()));
804 myBuilder.Add(OE,OV2.Oriented(V2.Orientation()));
805 if (BRep_Tool::Degenerated(E)) {
806 myBuilder.Degenerated(OE, Standard_True);
811 P2d = C2d->Value(f); TheSurf->D0(P2d.X(),P2d.Y(),P1);
812 P2d = C2d->Value(l); TheSurf->D0(P2d.X(),P2d.Y(),P2);
813 Standard_Real Tol = BRep_Tool::Tolerance(V1);
814 if (!P1.IsEqual(P2,Tol)) {
815 cout <<"BRepOffset_Offset : E degenerated -> OE not degenerated"<<endl;
821 if (VonDegen.Contains(V1) || VonDegen.Contains(V2))
823 if (VonDegen.Contains(V1))
825 if (VonDegen.Contains(V2))
827 C2d = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) );
828 f = 0.; l = P2d1.Distance( P2d2 );
829 if (MapSS.IsBound(E)) //seam edge
831 Handle(Geom2d_Curve) C2d_1 = BRep_Tool::CurveOnSurface(OE, myFace, f, l);
832 if (E.Orientation() == TopAbs_FORWARD)
833 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
835 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
838 UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E));
839 //myBuilder.Range(OE,f,l);
840 myBuilder.Range(OE, myFace, f, l);
841 if (!BRep_Tool::Degenerated(E) && TheSurf->IsUClosed())
843 TopoDS_Shape aLocalShape = E.Reversed();
844 Handle(Geom2d_Curve) C2d_1 =
845 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l);
846 P2d1 = C2d_1->Value(BRep_Tool::Parameter(V1,E,CurFace));
847 P2d2 = C2d_1->Value(BRep_Tool::Parameter(V2,E,CurFace));
848 if (VonDegen.Contains(V1))
850 if (VonDegen.Contains(V2))
852 C2d_1 = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) );
853 if ( E.Orientation() == TopAbs_FORWARD)
854 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
856 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
859 if (!BRep_Tool::Degenerated(E))
861 Handle(Geom_Line) theLine = new Geom_Line( P1, gp_Vec(P1, P2) );
862 myBuilder.UpdateEdge( OE, theLine, BRep_Tool::Tolerance(E) );
868 UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E));
869 myBuilder.Range(OE,f,l);
870 //ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
872 if (!BRep_Tool::Degenerated(OE))
873 ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
876 myBuilder.Add(OW, OE.Oriented(E.Orientation()));
878 myBuilder.Add(myFace, OW.Oriented(W.Orientation()));
881 myFace.Orientation(Face.Orientation());
883 BRepTools::Update(myFace);
887 //=======================================================================
890 //=======================================================================
892 void BRepOffset_Offset::Init(const TopoDS_Edge& Path,
893 const TopoDS_Edge& Edge1,
894 const TopoDS_Edge& Edge2,
895 const Standard_Real Offset,
896 const Standard_Boolean Polynomial,
897 const Standard_Real Tol,
898 const GeomAbs_Shape Conti)
900 TopoDS_Edge FirstEdge,LastEdge;
901 Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti);
905 //=======================================================================
908 //=======================================================================
910 void BRepOffset_Offset::Init(const TopoDS_Edge& Path,
911 const TopoDS_Edge& Edge1,
912 const TopoDS_Edge& Edge2,
913 const Standard_Real Offset,
914 const TopoDS_Edge& FirstEdge,
915 const TopoDS_Edge& LastEdge,
916 const Standard_Boolean Polynomial,
917 const Standard_Real Tol,
918 const GeomAbs_Shape Conti)
920 Standard_Boolean C1Denerated = Standard_False;
921 Standard_Boolean C2Denerated = Standard_False;
922 myStatus = BRepOffset_Good;
926 Standard_Real f[3],l[3];
928 Handle(Geom_Curve) CP = BRep_Tool::Curve(Path,Loc,f[0],l[0]);
929 CP = new Geom_TrimmedCurve(CP,f[0], l[0]);
930 CP->Transform(Loc.Transformation());
931 Handle(GeomAdaptor_HCurve) HCP = new GeomAdaptor_HCurve(CP);
933 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,Loc,f[1],l[1]);
935 Handle(Adaptor3d_HCurve) HEdge1;
936 Standard_Boolean C1is3D = Standard_True;
938 C1is3D = Standard_False;
939 Handle(Geom2d_Curve) C12d;
940 Handle(Geom_Surface) S1;
941 BRep_Tool::CurveOnSurface(Edge1,C12d,S1,Loc,f[1],l[1]);
942 S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation()));
943 C12d = new Geom2d_TrimmedCurve(C12d,f[1],l[1]);
944 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(S1);
945 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C12d);
946 Adaptor3d_CurveOnSurface Cons(HC1,HS1);
947 HEdge1 = new Adaptor3d_HCurveOnSurface(Cons);
950 C1 = new Geom_TrimmedCurve(C1, f[1], l[1]);
951 C1->Transform(Loc.Transformation());
952 HEdge1 = new GeomAdaptor_HCurve(C1);
953 GeomAdaptor_Curve AC1(C1);
954 if ( AC1.GetType() == GeomAbs_Circle) {
955 C1Denerated = (AC1.Circle().Radius() < Precision::Confusion());
959 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,Loc,f[2],l[2]);
961 Handle(Adaptor3d_HCurve) HEdge2;
962 Standard_Boolean C2is3D = Standard_True;
964 C2is3D = Standard_False;
965 Handle(Geom2d_Curve) C12d;
966 Handle(Geom_Surface) S1;
967 BRep_Tool::CurveOnSurface(Edge2,C12d,S1,Loc,f[2],l[2]);
968 S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation()));
969 C12d = new Geom2d_TrimmedCurve(C12d,f[2],l[2]);
970 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(S1);
971 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C12d);
972 Adaptor3d_CurveOnSurface Cons(HC1,HS1);
973 HEdge2 = new Adaptor3d_HCurveOnSurface(Cons);
976 C2 = new Geom_TrimmedCurve(C2, f[2], l[2]);
977 C2->Transform(Loc.Transformation());
978 HEdge2 = new GeomAdaptor_HCurve(C2);
979 GeomAdaptor_Curve AC2(C2);
980 if ( AC2.GetType() == GeomAbs_Circle) {
981 C2Denerated = (AC2.Circle().Radius() < Precision::Confusion());
986 GeomFill_Pipe Pipe(HCP, HEdge1, HEdge2, Abs(Offset));
987 Pipe.Perform(Tol, Polynomial, Conti);
988 Standard_Real ErrorPipe = Pipe.ErrorOnSurf();
990 Handle(Geom_Surface) S = Pipe.Surface();
991 Standard_Boolean ExchUV = Pipe.ExchangeUV();
992 Standard_Real f1,l1,f2,l2;
993 S->Bounds(f1,l1,f2,l2);
996 Standard_Real PathTol = BRep_Tool::Tolerance(Path);
997 Standard_Real TheTol;
998 BRep_Builder myBuilder;
999 myBuilder.MakeFace(myFace);
1001 myBuilder.UpdateFace(myFace,S,Id,PathTol);
1003 // update de Edge1. (Rem : has already a 3d curve)
1004 Standard_Real U,U1,U2;
1005 Handle(Geom2d_Curve) PC;
1007 PC = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1010 if (!C1is3D) C1 = S->VIso(f2);
1013 PC = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1016 if (!C1is3D) C1 = S->UIso(f1);
1019 Handle(Geom_Curve) Dummy;
1021 UpdateEdge(Edge1,C1,Id,BRep_Tool::Tolerance(Edge1));
1022 else if ( C1Denerated) {
1023 UpdateEdge(Edge1,Dummy,Id,BRep_Tool::Tolerance(Edge1));
1024 myBuilder.Degenerated(Edge1,Standard_True);
1027 TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge1) + ErrorPipe);
1028 UpdateEdge(Edge1, PC, myFace, TheTol);
1030 // mise a same range de la nouvelle pcurve.
1031 if ( !C1is3D && !C1Denerated)
1032 myBuilder.SameRange (Edge1,Standard_False);
1033 if ( !C1is3D && !C1Denerated)
1034 Range3d(Edge1,U1,U2);
1035 myBuilder.Range (Edge1,myFace,U1,U2);
1036 Range3d(Edge1,U1,U2);
1037 myBuilder.Range (Edge1,myFace,U1,U2);
1038 BRepLib::SameRange(Edge1);
1040 // mise a sameparameter pour les KPart
1041 if (ErrorPipe == 0) {
1042 TheTol = Max(TheTol, Tol);
1043 myBuilder.SameParameter(Edge1,Standard_False);
1044 BRepLib::SameParameter(Edge1, TheTol);
1047 // Update de edge2. (Rem : has already a 3d curve)
1049 PC = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1052 if (!C2is3D) C2 = S->VIso(l2);
1055 PC = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1058 if (!C2is3D) C2 = S->UIso(l1);
1062 UpdateEdge(Edge2,C2,Id,BRep_Tool::Tolerance(Edge2));
1063 else if ( C2Denerated) {
1064 UpdateEdge(Edge2,Dummy,Id,BRep_Tool::Tolerance(Edge2));
1065 myBuilder.Degenerated(Edge2,Standard_True);
1068 TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge2) + ErrorPipe);
1069 UpdateEdge(Edge2, PC, myFace, TheTol);
1071 // mise a same range de la nouvelle pcurve.
1072 myBuilder.SameRange (Edge2,Standard_False);
1073 if ( !C2is3D && !C2Denerated) Range3d(Edge2,U1,U2);
1074 myBuilder.Range(Edge2,myFace,U1,U2);
1075 BRepLib::SameRange(Edge2);
1077 // mise a sameparameter pour les KPart
1078 if (ErrorPipe == 0) {
1079 TheTol = Max(TheTol, Tol);
1080 myBuilder.SameParameter(Edge2,Standard_False);
1081 BRepLib::SameParameter(Edge2, TheTol);
1084 TopoDS_Edge Edge3, Edge4;
1086 TopoDS_Vertex V1f,V1l,V2f,V2l;
1087 TopExp::Vertices(Path,V1f,V1l);
1088 Standard_Boolean IsClosed = ( V1f.IsSame(V1l));
1090 TopExp::Vertices(Edge1,V1f,V1l);
1091 TopExp::Vertices(Edge2,V2f,V2l);
1093 Standard_Boolean StartDegenerated = (V1f.IsSame(V2f));
1094 Standard_Boolean EndDegenerated = (V1l.IsSame(V2l));
1096 Standard_Boolean E3rev = Standard_False;
1097 Standard_Boolean E4rev = Standard_False;
1099 TopoDS_Vertex VVf,VVl;
1100 if ( FirstEdge.IsNull()) {
1101 myBuilder.MakeEdge(Edge3);
1102 myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD));
1103 myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED));
1106 TopoDS_Shape aLocalEdge = FirstEdge.Oriented(TopAbs_FORWARD);
1107 Edge3 = TopoDS::Edge(aLocalEdge);
1108 // Edge3 = TopoDS::Edge(FirstEdge.Oriented(TopAbs_FORWARD));
1109 TopExp::Vertices(Edge3,VVf,VVl);
1111 // si firstedge n est pas nul, il faut que les vertex soient partages
1112 if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) {
1113 cout << "Attention Vertex non partages !!!!!!" << endl;
1116 if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) {
1117 // On fait vraisemblablement des conneries !!
1118 // On cree un autre edge, on appelle le Sewing apres.
1119 myBuilder.MakeEdge(Edge3);
1120 myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD));
1121 myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED));
1123 else if ( !VVf.IsSame(V1f)) {
1125 E3rev = Standard_True;
1132 Standard_Real TolApp = Precision::Approximation();
1134 Handle(Geom2d_Line) L1,L2;
1137 // rem : si ExchUv, il faut reverser le Wire.
1138 // donc l'edge Forward dans la face sera E4 : d'ou L1 et L2
1139 L2 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1140 L1 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1145 L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1146 L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1151 L1->Reverse(); L2->Reverse();
1156 UpdateEdge(Edge3, L1, L2, myFace,PathTol);
1157 myBuilder.Range(Edge3,myFace,U1,U2);
1158 if (StartDegenerated)
1159 myBuilder.Degenerated(Edge3,Standard_True);
1160 else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed
1161 ComputeCurve3d(Edge3,L1,S,Id,TolApp);
1164 if ( LastEdge.IsNull()) {
1165 myBuilder.MakeEdge(Edge4);
1166 myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD));
1167 myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED));
1170 TopoDS_Shape aLocalEdge = LastEdge.Oriented(TopAbs_FORWARD);
1171 Edge4 = TopoDS::Edge(aLocalEdge);
1172 // Edge4 = TopoDS::Edge(LastEdge.Oriented(TopAbs_FORWARD));
1173 TopExp::Vertices(Edge4,VVf,VVl);
1175 // si lastedge n est pas nul, il faut que les vertex soient partages
1176 if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) {
1177 cout << "Attention Vertex non partages !!!!!!" << endl;
1180 if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) {
1181 // On fait vraisemblablement des conneries !!
1182 // On cree un autre edge, on appelle le Sewing apres.
1183 myBuilder.MakeEdge(Edge4);
1184 myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD));
1185 myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED));
1187 else if ( !VVf.IsSame(V1l)) {
1189 E4rev = Standard_True;
1194 L1 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1199 L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1209 UpdateEdge(Edge3,L1,myFace,PathTol);
1210 myBuilder.Range(Edge3,myFace,U1,U2);
1211 if (StartDegenerated)
1212 myBuilder.Degenerated(Edge3,Standard_True);
1213 else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed
1214 ComputeCurve3d(Edge3,L1,S,Id,TolApp);
1217 L2 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1222 L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1232 UpdateEdge(Edge4,L2 ,myFace,PathTol);
1233 myBuilder.Range(Edge4,myFace,U1,U2);
1235 myBuilder.Degenerated(Edge4,Standard_True);
1236 else if (LastEdge.IsNull()) // then the 3d curve has not been yet computed
1237 ComputeCurve3d(Edge4,L2,S,Id,TolApp);
1241 if ( !FirstEdge.IsNull() && !StartDegenerated) {
1242 BRepLib::BuildCurve3d (Edge3,PathTol);
1243 myBuilder.SameRange (Edge3,Standard_False);
1244 myBuilder.SameParameter(Edge3,Standard_False);
1245 BRepLib::SameParameter (Edge3, Tol);
1247 if ( !LastEdge.IsNull() && !EndDegenerated) {
1248 BRepLib::BuildCurve3d (Edge4,PathTol);
1249 myBuilder.SameRange (Edge4,Standard_False);
1250 myBuilder.SameParameter(Edge4,Standard_False);
1251 BRepLib::SameParameter (Edge4, Tol);
1255 myBuilder.MakeWire(W);
1257 myBuilder.Add(W, Edge1.Oriented(TopAbs_REVERSED));
1258 myBuilder.Add(W, Edge2.Oriented(TopAbs_FORWARD));
1259 myBuilder.Add(W, Edge4.Reversed());
1260 myBuilder.Add(W, Edge3);
1266 myBuilder.Add(myFace, W);
1267 if (ExchUV) myFace.Reverse();
1269 BRepTools::Update(myFace);
1271 if ( Edge1.Orientation() == TopAbs_REVERSED)
1277 //=======================================================================
1280 //=======================================================================
1282 void BRepOffset_Offset::Init(const TopoDS_Vertex& Vertex,
1283 const TopTools_ListOfShape& LEdge,
1284 const Standard_Real Offset,
1285 const Standard_Boolean Polynomial,
1286 const Standard_Real TolApp,
1287 const GeomAbs_Shape Conti)
1289 myStatus = BRepOffset_Good;
1292 // evaluate the Ax3 of the Sphere
1293 // find 3 different vertices in LEdge
1294 TopTools_ListIteratorOfListOfShape it;
1295 gp_Pnt P, P1, P2, P3;
1296 TopoDS_Vertex V1, V2, V3, V4;
1300 char* name = new char[100];
1304 sprintf(name,"VOnSph_%d",NbOFFSET);
1306 DBRep::Set(name, Vertex);
1308 Standard_Integer NbEdges = 1;
1309 for (it.Initialize(LEdge); it.More(); it.Next()) {
1310 sprintf(name,"EOnSph_%d_%d",NbOFFSET,NbEdges++);
1312 DBRep::Set(name, CurE);
1320 it.Initialize(LEdge);
1321 TopExp::Vertices(TopoDS::Edge(it.Value()), V1, V2);
1322 P1 = BRep_Tool::Pnt(V1);
1323 P2 = BRep_Tool::Pnt(V2);
1326 Standard_ConstructionError::Raise("BRepOffset_Sphere");
1329 TopExp::Vertices(TopoDS::Edge(it.Value()), V3, V4);
1331 P3 = BRep_Tool::Pnt(V3);
1332 Standard_Real eps = 1.e-8;
1333 if ( P1.Distance(P3) < eps || P2.Distance(P3) < eps)
1334 P3 = BRep_Tool::Pnt(V4);
1336 P = BRep_Tool::Pnt(Vertex);
1338 gp_Vec X = gp_Vec(P1,P2) ^ gp_Vec(P1,P3);
1339 if ( X * gp_Vec(P1,P) < 0.) X.Reverse();
1341 gp_Ax3 Axis( P, gp_Dir(gp_Vec(P1,P2)), gp_Dir(X));
1342 Handle(Geom_Surface) S
1343 = new Geom_SphericalSurface( Axis, Abs(Offset));
1345 Standard_Real f, l, Tol = BRep_Tool::Tolerance(Vertex);
1347 TopLoc_Location Loc;
1348 BRep_Builder myBuilder;
1349 myBuilder.MakeFace(myFace);
1350 Handle(Geom_Surface) SS = S;
1352 // En polynomial, calcul de la surface par F(u,v).
1353 // Pas de changement de parametre, donc ProjLib sur la Sphere
1356 GeomConvert_ApproxSurface Approx(S,TolApp,Conti,Conti,10,10,10,1);
1357 if (Approx.IsDone()) {
1358 SS = Approx.Surface();
1362 myBuilder.UpdateFace(myFace, SS, Loc, Tol);
1365 myBuilder.MakeWire(W);
1371 sprintf(name,"SPHERE_%d",NbOFFSET);
1372 DrawTrSurf::Set(name, S);
1374 Standard_Integer CO = 1;
1377 for ( it.Initialize(LEdge); it.More(); it.Next()) {
1378 TopoDS_Edge E = TopoDS::Edge(it.Value());
1380 Handle(Geom_Curve) C = BRep_Tool::Curve(E,Loc,f,l);
1382 BRepLib::BuildCurve3d(E,BRep_Tool::Tolerance(E));
1383 C = BRep_Tool::Curve(E,Loc,f,l);
1385 C = new Geom_TrimmedCurve(C, f, l);
1386 C->Transform(Loc.Transformation());
1390 sprintf(name,"CURVE_%d_%d",NbOFFSET,CO);
1391 DrawTrSurf::Set(name, C);
1396 Handle(Geom2d_Curve) PCurve = GeomProjLib::Curve2d(C, S);
1397 // check if the first point of PCurve in is the canonical boundaries
1398 // of the sphere. Else move it.
1399 // the transformation is : U` = U + PI + 2 k PI
1400 // V` = +/- PI + 2 k` PI
1401 gp_Pnt2d P2d = PCurve->Value(f);
1402 Standard_Boolean IsToAdjust = Standard_False;
1403 if ( P2d.Y() < -M_PI/2.) {
1404 IsToAdjust = Standard_True;
1405 PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0.,-M_PI/2.),gp::DX2d()));
1407 else if ( P2d.Y() > M_PI/2.) {
1408 IsToAdjust = Standard_True;
1409 PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0., M_PI/2.),gp::DX2d()));
1412 // set the u firstpoint in [0,2*pi]
1413 gp_Vec2d Tr( M_PI, 0.);
1414 if ( P2d.X() > M_PI) Tr.Reverse();
1415 PCurve->Translate(Tr);
1418 UpdateEdge(E, PCurve, myFace, Tol);
1419 myBuilder.Range(E, myFace, f, l);
1420 myBuilder.Add(W, E);
1423 myBuilder.Add(myFace, W.Oriented(TopAbs_REVERSED));
1427 myBuilder.Add(myFace, W);
1430 BRepTools::Update(myFace);
1434 //=======================================================================
1437 //=======================================================================
1439 void BRepOffset_Offset::Init(const TopoDS_Edge& Edge,
1440 const Standard_Real Offset)
1443 Standard_Real myOffset = Abs(Offset);
1446 TopLoc_Location Loc;
1448 Handle(Geom_Curve) CP = BRep_Tool::Curve(Edge,Loc,f,l);
1449 CP = new Geom_TrimmedCurve(CP,f,l);
1450 CP->Transform(Loc.Transformation());
1452 GeomFill_Pipe Pipe(CP,myOffset);
1455 BRepLib_MakeFace MF(Pipe.Surface(), Precision::Confusion());
1458 if ( Offset < 0.) myFace.Reverse();
1462 //=======================================================================
1465 //=======================================================================
1467 const TopoDS_Face& BRepOffset_Offset::Face() const
1473 //=======================================================================
1474 //function : Generated
1476 //=======================================================================
1478 TopoDS_Shape BRepOffset_Offset::Generated(const TopoDS_Shape& Shape) const
1480 TopoDS_Shape aShape;
1482 switch ( myShape.ShapeType()) {
1486 TopExp_Explorer exp (myShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1487 TopExp_Explorer expo(myFace .Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1488 for ( ; exp.More() && expo.More(); exp.Next(), expo.Next()) {
1489 if ( Shape.IsSame(exp.Current())) {
1490 if ( myShape.Orientation() == TopAbs_REVERSED)
1491 aShape = expo.Current().Reversed();
1493 aShape = expo.Current();
1500 // have generate a pipe.
1502 TopoDS_Vertex V1, V2;
1503 TopExp::Vertices(TopoDS::Edge(myShape), V1, V2);
1505 TopExp_Explorer expf(myFace .Oriented(TopAbs_FORWARD), TopAbs_WIRE);
1506 TopExp_Explorer expo(expf.Current().Oriented(TopAbs_FORWARD),
1511 if ( V2.IsSame(Shape)) {
1512 if ( expf.Current().Orientation() == TopAbs_REVERSED)
1513 aShape = expo.Current().Reversed();
1515 aShape = expo.Current();
1519 if ( expf.Current().Orientation() == TopAbs_REVERSED)
1520 aShape = expo.Current().Reversed();
1522 aShape = expo.Current();
1524 if ( myFace.Orientation() == TopAbs_REVERSED)
1536 //=======================================================================
1539 //=======================================================================
1541 BRepOffset_Status BRepOffset_Offset::Status() const