1 // File: BRepOffset_Offset.cxx
2 // Created: Thu Oct 19 14:59:59 1995
3 // Author: Bruno DUMORTIER
7 #include <BRepOffset_Offset.ixx>
9 #include <Adaptor3d_HCurveOnSurface.hxx>
10 #include <Adaptor3d_CurveOnSurface.hxx>
11 #include <BRepOffset.hxx>
12 #include <BRepLib.hxx>
13 #include <BRepLib_MakeFace.hxx>
14 #include <BRepTools.hxx>
15 #include <BRep_Tool.hxx>
16 #include <BRep_Builder.hxx>
18 #include <GeomAPI.hxx>
19 #include <Geom2d_Curve.hxx>
20 #include <Geom2d_Line.hxx>
21 #include <Geom2d_TrimmedCurve.hxx>
22 #include <Geom_Line.hxx>
23 #include <Geom_Circle.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom_TrimmedCurve.hxx>
26 #include <Geom_RectangularTrimmedSurface.hxx>
27 #include <Geom_Surface.hxx>
28 #include <Geom_OffsetSurface.hxx>
29 #include <Geom_SphericalSurface.hxx>
30 #include <Geom_ConicalSurface.hxx>
31 #include <GeomAdaptor_HSurface.hxx>
32 #include <GeomAdaptor_Surface.hxx>
33 #include <GeomAdaptor_HCurve.hxx>
34 #include <GeomAdaptor_Curve.hxx>
35 #include <Geom2dAdaptor_HCurve.hxx>
36 #include <Geom2dAdaptor_Curve.hxx>
37 #include <GeomFill_Pipe.hxx>
38 #include <GeomProjLib.hxx>
39 #include <GeomConvert_ApproxSurface.hxx>
40 #include <Precision.hxx>
41 #include <Standard_ConstructionError.hxx>
43 #include <TopoDS_Wire.hxx>
45 #include <TopExp_Explorer.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
49 #include <gp_Cylinder.hxx>
50 #include <gp_Torus.hxx>
52 #include <gp_Pnt2d.hxx>
54 #include <BRep_GCurve.hxx>
55 #include <BRep_TEdge.hxx>
56 #include <BRep_ListOfCurveRepresentation.hxx>
57 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
59 #include <TopTools_SequenceOfShape.hxx>
60 #include <TopTools_MapOfShape.hxx>
61 #include <BRepOffset_Tool.hxx>
62 #include <GeomAPI_ExtremaCurveCurve.hxx>
63 #include <GeomAPI_ProjectPointOnCurve.hxx>
64 #include <GeomLib.hxx>
67 static Standard_Boolean Affich = Standard_False;
68 static Standard_Integer NbOFFSET = 0;
71 #include <DrawTrSurf.hxx>
76 //=======================================================================
77 //function : UpdateEdge
79 //=======================================================================
81 static void UpdateEdge(const TopoDS_Edge& E,
82 const Handle(Geom_Curve)& C,
83 const TopLoc_Location& L,
84 const Standard_Real Tol)
86 // Detrime les courbes pour eviter des copies dans
89 Handle(Geom_TrimmedCurve) BC = Handle(Geom_TrimmedCurve)::DownCast(C);
91 B.UpdateEdge(E,BC->BasisCurve(),L,Tol);
94 B.UpdateEdge(E,C,L,Tol);
98 //=======================================================================
99 //function : UpdateEdge
101 //=======================================================================
103 static void UpdateEdge(const TopoDS_Edge& E,
104 const Handle(Geom2d_Curve)& C,
105 const TopoDS_Face& F,
106 const Standard_Real Tol)
108 // Detrime les courbes pour eviter des copies dans
111 Handle(Geom2d_TrimmedCurve) BC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
113 B.UpdateEdge(E,BC->BasisCurve(),F,Tol);
116 B.UpdateEdge(E,C,F,Tol);
120 //=======================================================================
121 //function : UpdateEdge
123 //=======================================================================
125 static void UpdateEdge (const TopoDS_Edge& E,
126 const Handle(Geom2d_Curve)& C1,
127 const Handle(Geom2d_Curve)& C2,
128 const TopoDS_Face& F,
129 const Standard_Real Tol)
131 // Detrime les courbes pour eviter des copies dans
134 Handle(Geom2d_Curve) NC1,NC2;
135 Handle(Geom2d_TrimmedCurve) BC1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
136 Handle(Geom2d_TrimmedCurve) BC2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
137 if (!BC1.IsNull()) NC1 = BC1->BasisCurve(); else NC1 = C1;
138 if (!BC2.IsNull()) NC2 = BC2->BasisCurve(); else NC2 = C2;
139 B.UpdateEdge(E,NC1,NC2,F,Tol);
142 //=======================================================================
144 //purpose : Set the range only on the 3d curve
145 // en attendant que le BRep_Builder le fasse !!
146 //=======================================================================
148 static void Range3d (const TopoDS_Edge& E,
149 const Standard_Real First,
150 const Standard_Real Last)
152 // set the range to all the representations
153 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
155 BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
156 BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
157 Handle(BRep_GCurve) GC;
159 while (itcr.More()) {
160 GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
162 if (GC->IsCurve3D()) {
163 GC->SetRange(First,Last);
164 // Set the closedness flag to the correct value.
165 Handle(Geom_Curve) C = GC->Curve3D();
167 Standard_Boolean closed =
168 C->Value(First).IsEqual(C->Value(Last),BRep_Tool::Tolerance(E));
176 TE->Modified(Standard_True);
180 //=======================================================================
181 //function : ComputeCurve3d
182 //purpose : Particular case of Curve On Surface.
183 //=======================================================================
185 static void ComputeCurve3d(TopoDS_Edge Edge,
186 Handle(Geom2d_Curve) Curve,
187 Handle(Geom_Surface) Surf,
188 const TopLoc_Location Loc,
191 // try to find the particular case
192 // if not found call BRepLib::BuildCurve3d
194 Standard_Boolean IsComputed = Standard_False;
196 // Seach only isos on analytiques surfaces.
197 Geom2dAdaptor_Curve C(Curve);
198 GeomAdaptor_Surface S(Surf);
199 GeomAbs_CurveType CTy = C.GetType();
200 GeomAbs_SurfaceType STy = S.GetType();
201 BRep_Builder TheBuilder;
203 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d gere KPart
204 if ( CTy == GeomAbs_Line) {
205 gp_Dir2d D = C.Line().Direction();
206 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
207 if ( STy == GeomAbs_Sphere) {
208 gp_Pnt2d P = C.Line().Location();
209 if ( Abs( Abs(P.Y()) -PI/2. ) < Precision::PConfusion()) {
210 TheBuilder.Degenerated(Edge, Standard_True);
213 gp_Sphere Sph = S.Sphere();
214 gp_Ax3 Axis = Sph.Position();
215 gp_Circ Ci = ElSLib::SphereVIso(Axis,
218 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
219 gp_Ax1 AxeRev(Axis.Location(), DRev);
220 Ci.Rotate(AxeRev, P.X());
221 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
222 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
224 UpdateEdge(Edge, Circle, Loc, Tol);
226 IsComputed = Standard_True;
228 else if ( STy == GeomAbs_Cylinder) {
229 gp_Cylinder Cyl = S.Cylinder();
230 gp_Pnt2d P = C.Line().Location();
231 gp_Ax3 Axis = Cyl.Position();
232 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
235 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
236 gp_Ax1 AxeRev(Axis.Location(), DRev);
237 Ci.Rotate(AxeRev, P.X());
238 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
239 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
241 UpdateEdge(Edge, Circle, Loc, Tol);
242 IsComputed = Standard_True;
244 else if ( STy == GeomAbs_Cone) {
245 gp_Cone Cone = S.Cone();
246 gp_Pnt2d P = C.Line().Location();
247 gp_Ax3 Axis = Cone.Position();
248 gp_Circ Ci = ElSLib::ConeVIso(Axis,
252 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
253 gp_Ax1 AxeRev(Axis.Location(), DRev);
254 Ci.Rotate(AxeRev, P.X());
255 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
256 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
258 UpdateEdge(Edge, Circle, Loc, Tol);
259 IsComputed = Standard_True;
261 else if ( STy == GeomAbs_Torus) {
262 gp_Torus Tore = S.Torus();
263 gp_Pnt2d P = C.Line().Location();
264 gp_Ax3 Axis = Tore.Position();
265 gp_Circ Ci = ElSLib::TorusVIso(Axis,
269 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
270 gp_Ax1 AxeRev(Axis.Location(), DRev);
271 Ci.Rotate(AxeRev, P.X());
272 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
273 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
275 UpdateEdge(Edge, Circle, Loc, Tol);
276 IsComputed = Standard_True;
279 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
280 if ( STy == GeomAbs_Sphere) {
281 gp_Sphere Sph = S.Sphere();
282 gp_Pnt2d P = C.Line().Location();
283 gp_Ax3 Axis = Sph.Position();
285 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
287 // mise a sameparameter (rotation du cercle - decalage du Y)
288 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
289 gp_Ax1 AxeRev(Axis.Location(),DRev);
290 Ci.Rotate(AxeRev, P.Y());
292 // transformation en iso U ( = P.X())
293 DRev = Axis.XDirection().Crossed(Axis.YDirection());
294 AxeRev = gp_Ax1(Axis.Location(), DRev);
295 Ci.Rotate(AxeRev, P.X());
296 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
298 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
300 UpdateEdge(Edge, Circle, Loc, Tol);
301 IsComputed = Standard_True;
303 else if ( STy == GeomAbs_Cylinder) {
304 gp_Cylinder Cyl = S.Cylinder();
305 gp_Pnt2d P = C.Line().Location();
306 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
309 gp_Vec Tr(L.Direction());
312 Handle(Geom_Line) Line = new Geom_Line(L);
313 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
315 UpdateEdge(Edge, Line, Loc, Tol);
316 IsComputed = Standard_True;
318 else if ( STy == GeomAbs_Cone) {
319 gp_Cone Cone = S.Cone();
320 gp_Pnt2d P = C.Line().Location();
321 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
325 gp_Vec Tr(L.Direction());
327 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
328 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
330 UpdateEdge(Edge, Line, Loc, Tol);
331 IsComputed = Standard_True;
333 else if ( STy == GeomAbs_Torus) {
334 gp_Torus Tore = S.Torus();
335 gp_Pnt2d P = C.Line().Location();
336 gp_Ax3 Axis = Tore.Position();
337 gp_Circ Ci = ElSLib::TorusUIso(Axis,
341 Ci.Rotate(Ci.Axis(),P.Y());
342 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
344 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
346 UpdateEdge(Edge, Circle, Loc, Tol);
347 IsComputed = Standard_True;
353 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
354 UpdateEdge(Edge, C3d, Loc, Tol);
355 IsComputed = Standard_True;
358 //BRepLib::BuildCurves3d(Edge,Tol);
359 //Les Courbes 3d des edges dans le cas general ne sont calcules que si
361 //ie dans les tuyaux et les bouchons ..
362 // dans la derniere etapes de MakeShells on reconstruira les courbes3d
363 // des edges du resultat qui n en ont pas.
368 //=======================================================================
369 //function : BRepOffset_Offset
371 //=======================================================================
373 BRepOffset_Offset::BRepOffset_Offset()
378 //=======================================================================
379 //function : BRepOffset_Offset
381 //=======================================================================
383 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Face& Face,
384 const Standard_Real Offset,
385 const Standard_Boolean OffsetOutside,
386 const GeomAbs_JoinType JoinType)
388 Init(Face, Offset, OffsetOutside, JoinType);
392 //=======================================================================
393 //function : BRepOffset_Offset
395 //=======================================================================
397 BRepOffset_Offset::BRepOffset_Offset
398 (const TopoDS_Face& Face,
399 const Standard_Real Offset,
400 const TopTools_DataMapOfShapeShape& Created,
401 const Standard_Boolean OffsetOutside,
402 const GeomAbs_JoinType JoinType)
404 Init(Face,Offset,Created,OffsetOutside,JoinType);
408 //=======================================================================
409 //function : BRepOffset_Offset
411 //=======================================================================
413 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Edge& Path,
414 const TopoDS_Edge& Edge1,
415 const TopoDS_Edge& Edge2,
416 const Standard_Real Offset,
417 const Standard_Boolean Polynomial,
418 const Standard_Real Tol,
419 const GeomAbs_Shape Conti)
421 Init(Path,Edge1,Edge2,Offset,Polynomial,Tol,Conti);
425 //=======================================================================
426 //function : BRepOffset_Offset
428 //=======================================================================
430 BRepOffset_Offset::BRepOffset_Offset
431 (const TopoDS_Edge& Path,
432 const TopoDS_Edge& Edge1,
433 const TopoDS_Edge& Edge2,
434 const Standard_Real Offset,
435 const TopoDS_Edge& FirstEdge,
436 const TopoDS_Edge& LastEdge,
437 const Standard_Boolean Polynomial,
438 const Standard_Real Tol,
439 const GeomAbs_Shape Conti)
441 Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti);
445 //=======================================================================
446 //function : BRepOffset_Offset
448 //=======================================================================
450 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Vertex& Vertex,
451 const TopTools_ListOfShape& LEdge,
452 const Standard_Real Offset,
453 const Standard_Boolean Polynomial,
454 const Standard_Real Tol,
455 const GeomAbs_Shape Conti)
457 Init(Vertex,LEdge,Offset,Polynomial,Tol,Conti);
461 //=======================================================================
464 //=======================================================================
466 void BRepOffset_Offset::Init(const TopoDS_Face& Face,
467 const Standard_Real Offset,
468 const Standard_Boolean OffsetOutside,
469 const GeomAbs_JoinType JoinType)
471 TopTools_DataMapOfShapeShape Empty;
472 Init(Face,Offset,Empty,OffsetOutside,JoinType);
476 //=======================================================================
479 //=======================================================================
481 void BRepOffset_Offset::Init(const TopoDS_Face& Face,
482 const Standard_Real Offset,
483 const TopTools_DataMapOfShapeShape& Created,
484 const Standard_Boolean OffsetOutside,
485 const GeomAbs_JoinType JoinType)
488 Standard_Real myOffset = Offset;
489 if ( Face.Orientation() == TopAbs_REVERSED)
493 Handle(Geom_Surface) S = BRep_Tool::Surface(Face,L);
495 // On detrime les surfaces, evite des recopies dans les extensions.
496 Handle(Geom_RectangularTrimmedSurface) RT =
497 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
498 if (!RT.IsNull()) S = RT->BasisSurface();
500 // particular case of cone
501 Handle(Geom_ConicalSurface) Co;
502 Co = Handle(Geom_ConicalSurface)::DownCast(S);
505 gp_Pnt Apex = Co->Apex();
506 ElSLib::Parameters( Co->Cone(),Apex,Uc,Vc);
507 Standard_Real UU1,UU2,VV1,VV2;
508 BRepTools::UVBounds(Face,UU1,UU2,VV1,VV2);
509 if ( VV2 < Vc && Co->SemiAngle() > 0 )
511 else if ( VV1 > Vc && Co->SemiAngle() < 0 )
513 if ( !Co->Position().Direct()) myOffset *= -1;
516 Handle(Geom_Surface) TheSurf =
517 BRepOffset::Surface( S, myOffset, myStatus);
519 //processing offsets of faces with possible degenerated edges
520 Standard_Boolean VminDegen = Standard_False;
521 Standard_Boolean VmaxDegen = Standard_False;
522 gp_Pnt MinApex, MaxApex;
523 Standard_Boolean HasSingularity = Standard_False;
524 Standard_Real uf1, uf2, vf1, vf2, fpar, lpar;
525 BRepTools::UVBounds(Face, uf1, uf2, vf1, vf2);
526 if (!(OffsetOutside && JoinType == GeomAbs_Arc) &&
527 (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface) ||
528 TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)))
530 TopTools_SequenceOfShape DegEdges;
531 TopExp_Explorer Explo(Face, TopAbs_EDGE);
532 for (; Explo.More(); Explo.Next())
534 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
535 if (BRep_Tool::Degenerated(anEdge))
536 DegEdges.Append(anEdge);
538 if (!DegEdges.IsEmpty())
540 const Standard_Real TolApex = 1.e-5;
541 if (DegEdges.Length() == 2)
543 VminDegen = Standard_True;
544 VmaxDegen = Standard_True;
546 else //DegEdges.Length() == 1
548 const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
549 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
550 gp_Pnt2d aPnt2d = aCurve->Value(fpar);
551 if (Abs(aPnt2d.Y() - vf1) <= Precision::Confusion())
552 VminDegen = Standard_True;
554 VmaxDegen = Standard_True;
556 if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
558 gp_Cone theCone = (*((Handle(Geom_ConicalSurface)*)&TheSurf))->Cone();
559 gp_Pnt apex = theCone.Apex();
560 Standard_Real Uapex, Vapex;
561 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
564 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, Vapex, vf2);
566 HasSingularity = Standard_True;
570 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, Vapex);
572 HasSingularity = Standard_True;
575 else //TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)
579 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
580 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
582 Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
583 gp_Pnt Papex, Pfirst, Plast, Pmid;
584 Papex = BasisSurf->Value( uf1, vf1 );
585 Pfirst = TheSurf->Value( uf1, vf1 );
586 Plast = TheSurf->Value( uf2, vf1 );
587 Pmid = TheSurf->Value( (uf1+uf2)/2., vf1 );
588 gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast);
589 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
590 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
591 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
592 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
594 theExtrema.NearestPoints(Pint1, Pint2);
595 Standard_Real length = Pfirst.Distance(Pint1);
598 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
599 GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
600 Standard_False, Standard_False);
601 Standard_Real u1, u2, v1, v2;
602 TheSurf->Bounds( u1, u2, v1, v2 );
603 MinApex = TheSurf->Value( uf1, v1 );
607 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
608 GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
609 Standard_Real NewFirstV = Projector.LowerDistanceParameter();
610 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2);
611 MinApex = TheSurf->Value( uf1, NewFirstV );
612 //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2);
613 //MinApex = TheSurf->Value( uf1, vf1+length );
615 HasSingularity = Standard_True;
617 } //end of if (VminDegen)
620 Handle(Geom_Curve) viso = TheSurf->VIso( vf2 );
621 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
623 Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
624 gp_Pnt Papex, Pfirst, Plast, Pmid;
625 Papex = BasisSurf->Value( uf1, vf2 );
626 Pfirst = TheSurf->Value( uf1, vf2 );
627 Plast = TheSurf->Value( uf2, vf2 );
628 Pmid = TheSurf->Value( (uf1+uf2)/2., vf2 );
629 gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast);
630 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
631 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
632 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
633 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
635 theExtrema.NearestPoints(Pint1, Pint2);
636 Standard_Real length = Pfirst.Distance(Pint1);
639 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
640 GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
641 Standard_False, Standard_True);
642 Standard_Real u1, u2, v1, v2;
643 TheSurf->Bounds( u1, u2, v1, v2 );
644 MaxApex = TheSurf->Value( uf1, v2 );
648 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
649 GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
650 Standard_Real NewLastV = Projector.LowerDistanceParameter();
651 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV);
652 MaxApex = TheSurf->Value( uf1, NewLastV );
653 //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length);
654 //MaxApex = TheSurf->Value( uf1, vf2-length );
656 HasSingularity = Standard_True;
658 } //end of if (VmaxDegen)
659 } //end of else (case of Geom_OffsetSurface)
660 } //end of if (!DegEdges.IsEmpty())
661 } //end of processing offsets of faces with possible degenerated edges
663 // find the PCurves of the edges of <Faces>
665 BRep_Builder myBuilder;
666 myBuilder.MakeFace(myFace);
667 myBuilder.UpdateFace(myFace,TheSurf,L,BRep_Tool::Tolerance(Face));
669 TopTools_DataMapOfShapeShape MapSS;
671 // mise a jour de la map sur les vertex deja crees
672 TopoDS_Shape aLocalShape = Face.Oriented(TopAbs_FORWARD);
673 TopoDS_Face CurFace = TopoDS::Face(aLocalShape);
674 // TopoDS_Face CurFace = TopoDS::Face(Face.Oriented(TopAbs_FORWARD));
676 TopTools_MapOfShape VonDegen;
677 Standard_Real u1, u2, v1, v2;
678 TheSurf->Bounds( u1, u2, v1, v2 );
680 TopExp_Explorer exp(CurFace, TopAbs_EDGE);
681 for ( ; exp.More(); exp.Next()) {
682 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
683 TopoDS_Vertex V1,V2,OV1,OV2;
684 TopExp::Vertices(E ,V1 ,V2 );
685 if (HasSingularity && BRep_Tool::Degenerated(E))
687 if (Created.IsBound(E)) {
688 const TopoDS_Edge& OE = TopoDS::Edge(Created(E));
689 TopExp::Vertices(OE,OV1,OV2);
690 if (!MapSS.IsBound(V1)) MapSS.Bind(V1,OV1);
691 if (!MapSS.IsBound(V2)) MapSS.Bind(V2,OV2);
693 if (Created.IsBound(V1)) {
694 if (!MapSS.IsBound(V1)) MapSS.Bind(V1,Created(V1));
696 if (Created.IsBound(V2)) {
697 if (!MapSS.IsBound(V2)) MapSS.Bind(V2,Created(V2));
701 TopExp_Explorer expw(CurFace, TopAbs_WIRE);
702 for ( ; expw.More(); expw.Next()) {
703 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
704 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
707 myBuilder.MakeWire(OW);
708 for ( ; expe.More(); expe.Next()) {
709 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
711 TopExp::Vertices(E,V1,V2);
714 Standard_Real vstart, vend;
716 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,CurFace,f,l);
718 if (MapSS.IsBound(E) &&
719 !VonDegen.Contains(V1) && !VonDegen.Contains(V2)) { // c`est un edge de couture
720 OE = TopoDS::Edge(MapSS(E));
721 TopoDS_Shape aLocalShape = E.Reversed();
722 Handle(Geom2d_Curve) C2d_1 =
723 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l);
724 // Handle(Geom2d_Curve) C2d_1 =
725 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),CurFace,f,l);
726 if ( E.Orientation() == TopAbs_FORWARD)
727 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
729 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
730 myBuilder.Range(OE,f,l);
733 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
734 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
735 P2d1 = C2d->Value(BRep_Tool::Parameter(V1,Eforward,CurFace));
736 P2d2 = C2d->Value(BRep_Tool::Parameter(V2,Eforward,CurFace));
737 if (VonDegen.Contains(V1))
739 if (Abs(P2d1.Y() - vf1) <= Precision::Confusion())
741 P1 = MinApex; vstart = v1;
745 P1 = MaxApex; vstart = v2;
750 TheSurf->D0(P2d1.X(),P2d1.Y(),P1);
751 P1.Transform(L.Transformation());
754 if (VonDegen.Contains(V2))
756 if (Abs(P2d2.Y() - vf1) <= Precision::Confusion())
758 P2 = MinApex; vend = v1;
762 P2 = MaxApex; vend = v2;
767 TheSurf->D0(P2d2.X(),P2d2.Y(),P2);
768 P2.Transform(L.Transformation());
771 // E a-t-il ume image dans la Map des Created ?
772 if ( Created.IsBound(E)) {
773 OE = TopoDS::Edge(Created(E));
775 else if (MapSS.IsBound(E)) //seam edge
776 OE = TopoDS::Edge(MapSS(E));
778 myBuilder.MakeEdge(OE);
779 TopoDS_Vertex OV1,OV2;
780 if ( MapSS.IsBound(V1)) {
781 OV1 = TopoDS::Vertex(MapSS(V1));
784 myBuilder.MakeVertex(OV1);
785 myBuilder.UpdateVertex(OV1,P1,BRep_Tool::Tolerance(V1));
788 if ( MapSS.IsBound(V2)) {
789 OV2 = TopoDS::Vertex(MapSS(V2));
792 myBuilder.MakeVertex(OV2);
793 myBuilder.UpdateVertex(OV2,P2,BRep_Tool::Tolerance(V2));
796 myBuilder.Add(OE,OV1.Oriented(V1.Orientation()));
797 myBuilder.Add(OE,OV2.Oriented(V2.Orientation()));
798 if (BRep_Tool::Degenerated(E)) {
799 myBuilder.Degenerated(OE, Standard_True);
804 P2d = C2d->Value(f); TheSurf->D0(P2d.X(),P2d.Y(),P1);
805 P2d = C2d->Value(l); TheSurf->D0(P2d.X(),P2d.Y(),P2);
806 Standard_Real Tol = BRep_Tool::Tolerance(V1);
807 if (!P1.IsEqual(P2,Tol)) {
808 cout <<"BRepOffset_Offset : E degenerated -> OE not degenerated"<<endl;
814 if (VonDegen.Contains(V1) || VonDegen.Contains(V2))
816 if (VonDegen.Contains(V1))
818 if (VonDegen.Contains(V2))
820 C2d = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) );
821 f = 0.; l = P2d1.Distance( P2d2 );
822 if (MapSS.IsBound(E)) //seam edge
824 Handle(Geom2d_Curve) C2d_1 = BRep_Tool::CurveOnSurface(OE, myFace, f, l);
825 if (E.Orientation() == TopAbs_FORWARD)
826 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
828 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
831 UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E));
832 //myBuilder.Range(OE,f,l);
833 myBuilder.Range(OE, myFace, f, l);
834 if (!BRep_Tool::Degenerated(E) && TheSurf->IsUClosed())
836 TopoDS_Shape aLocalShape = E.Reversed();
837 Handle(Geom2d_Curve) C2d_1 =
838 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l);
839 P2d1 = C2d_1->Value(BRep_Tool::Parameter(V1,E,CurFace));
840 P2d2 = C2d_1->Value(BRep_Tool::Parameter(V2,E,CurFace));
841 if (VonDegen.Contains(V1))
843 if (VonDegen.Contains(V2))
845 C2d_1 = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) );
846 if ( E.Orientation() == TopAbs_FORWARD)
847 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
849 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
852 if (!BRep_Tool::Degenerated(E))
854 Handle(Geom_Line) theLine = new Geom_Line( P1, gp_Vec(P1, P2) );
855 myBuilder.UpdateEdge( OE, theLine, BRep_Tool::Tolerance(E) );
861 UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E));
862 myBuilder.Range(OE,f,l);
863 //ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
865 if (!BRep_Tool::Degenerated(OE))
866 ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
869 myBuilder.Add(OW, OE.Oriented(E.Orientation()));
871 myBuilder.Add(myFace, OW.Oriented(W.Orientation()));
874 myFace.Orientation(Face.Orientation());
876 BRepTools::Update(myFace);
880 //=======================================================================
883 //=======================================================================
885 void BRepOffset_Offset::Init(const TopoDS_Edge& Path,
886 const TopoDS_Edge& Edge1,
887 const TopoDS_Edge& Edge2,
888 const Standard_Real Offset,
889 const Standard_Boolean Polynomial,
890 const Standard_Real Tol,
891 const GeomAbs_Shape Conti)
893 TopoDS_Edge FirstEdge,LastEdge;
894 Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti);
898 //=======================================================================
901 //=======================================================================
903 void BRepOffset_Offset::Init(const TopoDS_Edge& Path,
904 const TopoDS_Edge& Edge1,
905 const TopoDS_Edge& Edge2,
906 const Standard_Real Offset,
907 const TopoDS_Edge& FirstEdge,
908 const TopoDS_Edge& LastEdge,
909 const Standard_Boolean Polynomial,
910 const Standard_Real Tol,
911 const GeomAbs_Shape Conti)
913 Standard_Boolean C1Denerated = Standard_False;
914 Standard_Boolean C2Denerated = Standard_False;
915 myStatus = BRepOffset_Good;
919 Standard_Real f[3],l[3];
921 Handle(Geom_Curve) CP = BRep_Tool::Curve(Path,Loc,f[0],l[0]);
922 CP = new Geom_TrimmedCurve(CP,f[0], l[0]);
923 CP->Transform(Loc.Transformation());
924 Handle(GeomAdaptor_HCurve) HCP = new GeomAdaptor_HCurve(CP);
926 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,Loc,f[1],l[1]);
928 Handle(Adaptor3d_HCurve) HEdge1;
929 Standard_Boolean C1is3D = Standard_True;
931 C1is3D = Standard_False;
932 Handle(Geom2d_Curve) C12d;
933 Handle(Geom_Surface) S1;
934 BRep_Tool::CurveOnSurface(Edge1,C12d,S1,Loc,f[1],l[1]);
935 S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation()));
936 C12d = new Geom2d_TrimmedCurve(C12d,f[1],l[1]);
937 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(S1);
938 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C12d);
939 Adaptor3d_CurveOnSurface Cons(HC1,HS1);
940 HEdge1 = new Adaptor3d_HCurveOnSurface(Cons);
943 C1 = new Geom_TrimmedCurve(C1, f[1], l[1]);
944 C1->Transform(Loc.Transformation());
945 HEdge1 = new GeomAdaptor_HCurve(C1);
946 GeomAdaptor_Curve AC1(C1);
947 if ( AC1.GetType() == GeomAbs_Circle) {
948 C1Denerated = (AC1.Circle().Radius() < Precision::Confusion());
952 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,Loc,f[2],l[2]);
954 Handle(Adaptor3d_HCurve) HEdge2;
955 Standard_Boolean C2is3D = Standard_True;
957 C2is3D = Standard_False;
958 Handle(Geom2d_Curve) C12d;
959 Handle(Geom_Surface) S1;
960 BRep_Tool::CurveOnSurface(Edge2,C12d,S1,Loc,f[2],l[2]);
961 S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation()));
962 C12d = new Geom2d_TrimmedCurve(C12d,f[2],l[2]);
963 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(S1);
964 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C12d);
965 Adaptor3d_CurveOnSurface Cons(HC1,HS1);
966 HEdge2 = new Adaptor3d_HCurveOnSurface(Cons);
969 C2 = new Geom_TrimmedCurve(C2, f[2], l[2]);
970 C2->Transform(Loc.Transformation());
971 HEdge2 = new GeomAdaptor_HCurve(C2);
972 GeomAdaptor_Curve AC2(C2);
973 if ( AC2.GetType() == GeomAbs_Circle) {
974 C2Denerated = (AC2.Circle().Radius() < Precision::Confusion());
979 GeomFill_Pipe Pipe(HCP, HEdge1, HEdge2, Abs(Offset));
980 Pipe.Perform(Tol, Polynomial, Conti);
981 Standard_Real ErrorPipe = Pipe.ErrorOnSurf();
983 Handle(Geom_Surface) S = Pipe.Surface();
984 Standard_Boolean ExchUV = Pipe.ExchangeUV();
985 Standard_Real f1,l1,f2,l2;
986 S->Bounds(f1,l1,f2,l2);
989 Standard_Real PathTol = BRep_Tool::Tolerance(Path);
990 Standard_Real TheTol;
991 BRep_Builder myBuilder;
992 myBuilder.MakeFace(myFace);
994 myBuilder.UpdateFace(myFace,S,Id,PathTol);
996 // update de Edge1. (Rem : has already a 3d curve)
997 Standard_Real U,U1,U2;
998 Handle(Geom2d_Curve) PC;
1000 PC = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1003 if (!C1is3D) C1 = S->VIso(f2);
1006 PC = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1009 if (!C1is3D) C1 = S->UIso(f1);
1012 Handle(Geom_Curve) Dummy;
1014 UpdateEdge(Edge1,C1,Id,BRep_Tool::Tolerance(Edge1));
1015 else if ( C1Denerated) {
1016 UpdateEdge(Edge1,Dummy,Id,BRep_Tool::Tolerance(Edge1));
1017 myBuilder.Degenerated(Edge1,Standard_True);
1020 TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge1) + ErrorPipe);
1021 UpdateEdge(Edge1, PC, myFace, TheTol);
1023 // mise a same range de la nouvelle pcurve.
1024 if ( !C1is3D && !C1Denerated)
1025 myBuilder.SameRange (Edge1,Standard_False);
1026 if ( !C1is3D && !C1Denerated)
1027 Range3d(Edge1,U1,U2);
1028 myBuilder.Range (Edge1,myFace,U1,U2);
1029 Range3d(Edge1,U1,U2);
1030 myBuilder.Range (Edge1,myFace,U1,U2);
1031 BRepLib::SameRange(Edge1);
1033 // mise a sameparameter pour les KPart
1034 if (ErrorPipe == 0) {
1035 TheTol = Max(TheTol, Tol);
1036 myBuilder.SameParameter(Edge1,Standard_False);
1037 BRepLib::SameParameter(Edge1, TheTol);
1040 // Update de edge2. (Rem : has already a 3d curve)
1042 PC = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1045 if (!C2is3D) C2 = S->VIso(l2);
1048 PC = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1051 if (!C2is3D) C2 = S->UIso(l1);
1055 UpdateEdge(Edge2,C2,Id,BRep_Tool::Tolerance(Edge2));
1056 else if ( C2Denerated) {
1057 UpdateEdge(Edge2,Dummy,Id,BRep_Tool::Tolerance(Edge2));
1058 myBuilder.Degenerated(Edge2,Standard_True);
1061 TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge2) + ErrorPipe);
1062 UpdateEdge(Edge2, PC, myFace, TheTol);
1064 // mise a same range de la nouvelle pcurve.
1065 myBuilder.SameRange (Edge2,Standard_False);
1066 if ( !C2is3D && !C2Denerated) Range3d(Edge2,U1,U2);
1067 myBuilder.Range(Edge2,myFace,U1,U2);
1068 BRepLib::SameRange(Edge2);
1070 // mise a sameparameter pour les KPart
1071 if (ErrorPipe == 0) {
1072 TheTol = Max(TheTol, Tol);
1073 myBuilder.SameParameter(Edge2,Standard_False);
1074 BRepLib::SameParameter(Edge2, TheTol);
1077 TopoDS_Edge Edge3, Edge4;
1079 TopoDS_Vertex V1f,V1l,V2f,V2l;
1080 TopExp::Vertices(Path,V1f,V1l);
1081 Standard_Boolean IsClosed = ( V1f.IsSame(V1l));
1083 TopExp::Vertices(Edge1,V1f,V1l);
1084 TopExp::Vertices(Edge2,V2f,V2l);
1086 Standard_Boolean StartDegenerated = (V1f.IsSame(V2f));
1087 Standard_Boolean EndDegenerated = (V1l.IsSame(V2l));
1089 Standard_Boolean E3rev = Standard_False;
1090 Standard_Boolean E4rev = Standard_False;
1092 TopoDS_Vertex VVf,VVl;
1093 if ( FirstEdge.IsNull()) {
1094 myBuilder.MakeEdge(Edge3);
1095 myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD));
1096 myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED));
1099 TopoDS_Shape aLocalEdge = FirstEdge.Oriented(TopAbs_FORWARD);
1100 Edge3 = TopoDS::Edge(aLocalEdge);
1101 // Edge3 = TopoDS::Edge(FirstEdge.Oriented(TopAbs_FORWARD));
1102 TopExp::Vertices(Edge3,VVf,VVl);
1104 // si firstedge n est pas nul, il faut que les vertex soient partages
1105 if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) {
1106 cout << "Attention Vertex non partages !!!!!!" << endl;
1109 if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) {
1110 // On fait vraisemblablement des conneries !!
1111 // On cree un autre edge, on appelle le Sewing apres.
1112 myBuilder.MakeEdge(Edge3);
1113 myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD));
1114 myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED));
1116 else if ( !VVf.IsSame(V1f)) {
1118 E3rev = Standard_True;
1125 Standard_Real TolApp = Precision::Approximation();
1127 Handle(Geom2d_Line) L1,L2;
1130 // rem : si ExchUv, il faut reverser le Wire.
1131 // donc l'edge Forward dans la face sera E4 : d'ou L1 et L2
1132 L2 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1133 L1 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1138 L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1139 L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1144 L1->Reverse(); L2->Reverse();
1149 UpdateEdge(Edge3, L1, L2, myFace,PathTol);
1150 myBuilder.Range(Edge3,myFace,U1,U2);
1151 if (StartDegenerated)
1152 myBuilder.Degenerated(Edge3,Standard_True);
1153 else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed
1154 ComputeCurve3d(Edge3,L1,S,Id,TolApp);
1157 if ( LastEdge.IsNull()) {
1158 myBuilder.MakeEdge(Edge4);
1159 myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD));
1160 myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED));
1163 TopoDS_Shape aLocalEdge = LastEdge.Oriented(TopAbs_FORWARD);
1164 Edge4 = TopoDS::Edge(aLocalEdge);
1165 // Edge4 = TopoDS::Edge(LastEdge.Oriented(TopAbs_FORWARD));
1166 TopExp::Vertices(Edge4,VVf,VVl);
1168 // si lastedge n est pas nul, il faut que les vertex soient partages
1169 if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) {
1170 cout << "Attention Vertex non partages !!!!!!" << endl;
1173 if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) {
1174 // On fait vraisemblablement des conneries !!
1175 // On cree un autre edge, on appelle le Sewing apres.
1176 myBuilder.MakeEdge(Edge4);
1177 myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD));
1178 myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED));
1180 else if ( !VVf.IsSame(V1l)) {
1182 E4rev = Standard_True;
1187 L1 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1192 L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1202 UpdateEdge(Edge3,L1,myFace,PathTol);
1203 myBuilder.Range(Edge3,myFace,U1,U2);
1204 if (StartDegenerated)
1205 myBuilder.Degenerated(Edge3,Standard_True);
1206 else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed
1207 ComputeCurve3d(Edge3,L1,S,Id,TolApp);
1210 L2 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1215 L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1225 UpdateEdge(Edge4,L2 ,myFace,PathTol);
1226 myBuilder.Range(Edge4,myFace,U1,U2);
1228 myBuilder.Degenerated(Edge4,Standard_True);
1229 else if (LastEdge.IsNull()) // then the 3d curve has not been yet computed
1230 ComputeCurve3d(Edge4,L2,S,Id,TolApp);
1234 if ( !FirstEdge.IsNull() && !StartDegenerated) {
1235 BRepLib::BuildCurve3d (Edge3,PathTol);
1236 myBuilder.SameRange (Edge3,Standard_False);
1237 myBuilder.SameParameter(Edge3,Standard_False);
1238 BRepLib::SameParameter (Edge3, Tol);
1240 if ( !LastEdge.IsNull() && !EndDegenerated) {
1241 BRepLib::BuildCurve3d (Edge4,PathTol);
1242 myBuilder.SameRange (Edge4,Standard_False);
1243 myBuilder.SameParameter(Edge4,Standard_False);
1244 BRepLib::SameParameter (Edge4, Tol);
1248 myBuilder.MakeWire(W);
1250 myBuilder.Add(W, Edge1.Oriented(TopAbs_REVERSED));
1251 myBuilder.Add(W, Edge2.Oriented(TopAbs_FORWARD));
1252 myBuilder.Add(W, Edge4.Reversed());
1253 myBuilder.Add(W, Edge3);
1259 myBuilder.Add(myFace, W);
1260 if (ExchUV) myFace.Reverse();
1262 BRepTools::Update(myFace);
1264 if ( Edge1.Orientation() == TopAbs_REVERSED)
1270 //=======================================================================
1273 //=======================================================================
1275 void BRepOffset_Offset::Init(const TopoDS_Vertex& Vertex,
1276 const TopTools_ListOfShape& LEdge,
1277 const Standard_Real Offset,
1278 const Standard_Boolean Polynomial,
1279 const Standard_Real TolApp,
1280 const GeomAbs_Shape Conti)
1282 myStatus = BRepOffset_Good;
1285 // evaluate the Ax3 of the Sphere
1286 // find 3 different vertices in LEdge
1287 TopTools_ListIteratorOfListOfShape it;
1288 gp_Pnt P, P1, P2, P3;
1289 TopoDS_Vertex V1, V2, V3, V4;
1293 char* name = new char[100];
1297 sprintf(name,"VOnSph_%d",NbOFFSET);
1299 DBRep::Set(name, Vertex);
1301 Standard_Integer NbEdges = 1;
1302 for (it.Initialize(LEdge); it.More(); it.Next()) {
1303 const TopoDS_Edge& CurE = TopoDS::Edge(it.Value());
1304 sprintf(name,"EOnSph_%d_%d",NbOFFSET,NbEdges++);
1306 DBRep::Set(name, CurE);
1314 it.Initialize(LEdge);
1315 TopExp::Vertices(TopoDS::Edge(it.Value()), V1, V2);
1316 P1 = BRep_Tool::Pnt(V1);
1317 P2 = BRep_Tool::Pnt(V2);
1320 Standard_ConstructionError::Raise("BRepOffset_Sphere");
1323 TopExp::Vertices(TopoDS::Edge(it.Value()), V3, V4);
1325 P3 = BRep_Tool::Pnt(V3);
1326 Standard_Real eps = 1.e-8;
1327 if ( P1.Distance(P3) < eps || P2.Distance(P3) < eps)
1328 P3 = BRep_Tool::Pnt(V4);
1330 P = BRep_Tool::Pnt(Vertex);
1332 gp_Vec X = gp_Vec(P1,P2) ^ gp_Vec(P1,P3);
1333 if ( X * gp_Vec(P1,P) < 0.) X.Reverse();
1335 gp_Ax3 Axis( P, gp_Dir(gp_Vec(P1,P2)), gp_Dir(X));
1336 Handle(Geom_Surface) S
1337 = new Geom_SphericalSurface( Axis, Abs(Offset));
1339 Standard_Real f, l, Tol = BRep_Tool::Tolerance(Vertex);
1341 TopLoc_Location Loc;
1342 BRep_Builder myBuilder;
1343 myBuilder.MakeFace(myFace);
1344 Handle(Geom_Surface) SS = S;
1346 // En polynomial, calcul de la surface par F(u,v).
1347 // Pas de changement de parametre, donc ProjLib sur la Sphere
1350 GeomConvert_ApproxSurface Approx(S,TolApp,Conti,Conti,10,10,10,1);
1351 if (Approx.IsDone()) {
1352 SS = Approx.Surface();
1356 myBuilder.UpdateFace(myFace, SS, Loc, Tol);
1359 myBuilder.MakeWire(W);
1365 sprintf(name,"SPHERE_%d",NbOFFSET);
1366 DrawTrSurf::Set(name, S);
1368 Standard_Integer CO = 1;
1371 for ( it.Initialize(LEdge); it.More(); it.Next()) {
1372 TopoDS_Edge E = TopoDS::Edge(it.Value());
1374 Handle(Geom_Curve) C = BRep_Tool::Curve(E,Loc,f,l);
1376 BRepLib::BuildCurve3d(E,BRep_Tool::Tolerance(E));
1377 C = BRep_Tool::Curve(E,Loc,f,l);
1379 C = new Geom_TrimmedCurve(C, f, l);
1380 C->Transform(Loc.Transformation());
1384 sprintf(name,"CURVE_%d_%d",NbOFFSET,CO);
1385 DrawTrSurf::Set(name, C);
1390 Handle(Geom2d_Curve) PCurve = GeomProjLib::Curve2d(C, S);
1391 // check if the first point of PCurve in is the canonical boundaries
1392 // of the sphere. Else move it.
1393 // the transformation is : U` = U + PI + 2 k PI
1394 // V` = +/- PI + 2 k` PI
1395 gp_Pnt2d P2d = PCurve->Value(f);
1396 Standard_Boolean IsToAdjust = Standard_False;
1397 if ( P2d.Y() < -PI/2.) {
1398 IsToAdjust = Standard_True;
1399 PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0.,-PI/2.),gp::DX2d()));
1401 else if ( P2d.Y() > PI/2.) {
1402 IsToAdjust = Standard_True;
1403 PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0., PI/2.),gp::DX2d()));
1406 // set the u firstpoint in [0,2*pi]
1407 gp_Vec2d Tr( PI, 0.);
1408 if ( P2d.X() > PI) Tr.Reverse();
1409 PCurve->Translate(Tr);
1412 UpdateEdge(E, PCurve, myFace, Tol);
1413 myBuilder.Range(E, myFace, f, l);
1414 myBuilder.Add(W, E);
1417 myBuilder.Add(myFace, W.Oriented(TopAbs_REVERSED));
1421 myBuilder.Add(myFace, W);
1424 BRepTools::Update(myFace);
1428 //=======================================================================
1431 //=======================================================================
1433 void BRepOffset_Offset::Init(const TopoDS_Edge& Edge,
1434 const Standard_Real Offset)
1437 Standard_Real myOffset = Abs(Offset);
1440 TopLoc_Location Loc;
1442 Handle(Geom_Curve) CP = BRep_Tool::Curve(Edge,Loc,f,l);
1443 CP = new Geom_TrimmedCurve(CP,f,l);
1444 CP->Transform(Loc.Transformation());
1446 GeomFill_Pipe Pipe(CP,myOffset);
1449 BRepLib_MakeFace MF(Pipe.Surface());
1452 if ( Offset < 0.) myFace.Reverse();
1456 //=======================================================================
1459 //=======================================================================
1461 const TopoDS_Face& BRepOffset_Offset::Face() const
1467 //=======================================================================
1468 //function : Generated
1470 //=======================================================================
1472 TopoDS_Shape BRepOffset_Offset::Generated(const TopoDS_Shape& Shape) const
1474 TopoDS_Shape aShape;
1476 switch ( myShape.ShapeType()) {
1480 TopExp_Explorer exp (myShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1481 TopExp_Explorer expo(myFace .Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1482 for ( ; exp.More() && expo.More(); exp.Next(), expo.Next()) {
1483 if ( Shape.IsSame(exp.Current())) {
1484 if ( myShape.Orientation() == TopAbs_REVERSED)
1485 aShape = expo.Current().Reversed();
1487 aShape = expo.Current();
1494 // have generate a pipe.
1496 TopoDS_Vertex V1, V2;
1497 TopExp::Vertices(TopoDS::Edge(myShape), V1, V2);
1499 TopExp_Explorer expf(myFace .Oriented(TopAbs_FORWARD), TopAbs_WIRE);
1500 TopExp_Explorer expo(expf.Current().Oriented(TopAbs_FORWARD),
1505 if ( V2.IsSame(Shape)) {
1506 if ( expf.Current().Orientation() == TopAbs_REVERSED)
1507 aShape = expo.Current().Reversed();
1509 aShape = expo.Current();
1513 if ( expf.Current().Orientation() == TopAbs_REVERSED)
1514 aShape = expo.Current().Reversed();
1516 aShape = expo.Current();
1518 if ( myFace.Orientation() == TopAbs_REVERSED)
1532 //=======================================================================
1535 //=======================================================================
1537 BRepOffset_Status BRepOffset_Offset::Status() const