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.
18 #include <Adaptor3d_CurveOnSurface.hxx>
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>
27 #include <BRepLib.hxx>
28 #include <BRepLib_MakeFace.hxx>
29 #include <BRepLib_MakeWire.hxx>
30 #include <BRepOffset.hxx>
31 #include <BRepOffset_Offset.hxx>
32 #include <BRepOffset_Tool.hxx>
33 #include <BRepTools.hxx>
35 #include <gce_MakePln.hxx>
36 #include <Geom2d_Curve.hxx>
37 #include <Geom2d_Line.hxx>
38 #include <Geom2d_TrimmedCurve.hxx>
39 #include <Geom2dAdaptor_Curve.hxx>
40 #include <Geom2dAdaptor_HCurve.hxx>
41 #include <Geom_Circle.hxx>
42 #include <Geom_ConicalSurface.hxx>
43 #include <Geom_Curve.hxx>
44 #include <Geom_Line.hxx>
45 #include <Geom_OffsetSurface.hxx>
46 #include <Geom_RectangularTrimmedSurface.hxx>
47 #include <Geom_SphericalSurface.hxx>
48 #include <Geom_Surface.hxx>
49 #include <Geom_TrimmedCurve.hxx>
50 #include <GeomAdaptor_Curve.hxx>
51 #include <GeomAdaptor_HCurve.hxx>
52 #include <GeomAdaptor_HSurface.hxx>
53 #include <GeomAdaptor_Surface.hxx>
54 #include <GeomAPI.hxx>
55 #include <GeomAPI_ExtremaCurveCurve.hxx>
56 #include <GeomAPI_ProjectPointOnCurve.hxx>
57 #include <GeomConvert_ApproxSurface.hxx>
58 #include <GeomFill_Pipe.hxx>
59 #include <GeomLib.hxx>
60 #include <GeomProjLib.hxx>
63 #include <gp_Cylinder.hxx>
65 #include <gp_Pnt2d.hxx>
66 #include <gp_Torus.hxx>
67 #include <GProp_GProps.hxx>
68 #include <Precision.hxx>
69 #include <ShapeFix_Shape.hxx>
70 #include <Standard_ConstructionError.hxx>
72 #include <TopExp_Explorer.hxx>
74 #include <TopoDS_Edge.hxx>
75 #include <TopoDS_Face.hxx>
76 #include <TopoDS_Shape.hxx>
77 #include <TopoDS_Vertex.hxx>
78 #include <TopoDS_Wire.hxx>
79 #include <TopTools_IndexedMapOfShape.hxx>
80 #include <TopTools_ListIteratorOfListOfShape.hxx>
81 #include <TopTools_MapOfShape.hxx>
82 #include <TopTools_SequenceOfShape.hxx>
85 static Standard_Boolean Affich = Standard_False;
86 static Standard_Integer NbOFFSET = 0;
89 #include <DrawTrSurf.hxx>
95 static gp_Pnt GetFarestCorner(const TopoDS_Wire& aWire)
97 TopTools_IndexedMapOfShape Vertices;
98 TopExp::MapShapes(aWire, TopAbs_VERTEX, Vertices);
100 Standard_Real MaxDist = 0.;
102 for (Standard_Integer i = 1; i <= Vertices.Extent(); i++)
103 for (Standard_Integer j = 1; j <= Vertices.Extent(); j++)
105 const TopoDS_Vertex& V1 = TopoDS::Vertex(Vertices(i));
106 const TopoDS_Vertex& V2 = TopoDS::Vertex(Vertices(j));
107 gp_Pnt P1 = BRep_Tool::Pnt(V1);
108 gp_Pnt P2 = BRep_Tool::Pnt(V2);
109 Standard_Real aDist = P1.SquareDistance(P2);
120 //=======================================================================
121 //function : UpdateEdge
123 //=======================================================================
125 static void UpdateEdge(const TopoDS_Edge& E,
126 const Handle(Geom_Curve)& C,
127 const TopLoc_Location& L,
128 const Standard_Real Tol)
130 // Cut curves to avoid copies in the extensions.
132 Handle(Geom_TrimmedCurve) BC = Handle(Geom_TrimmedCurve)::DownCast(C);
134 B.UpdateEdge(E,BC->BasisCurve(),L,Tol);
137 B.UpdateEdge(E,C,L,Tol);
141 //=======================================================================
142 //function : UpdateEdge
144 //=======================================================================
146 static void UpdateEdge(const TopoDS_Edge& E,
147 const Handle(Geom2d_Curve)& C,
148 const TopoDS_Face& F,
149 const Standard_Real Tol)
151 // Cut curves to avoid copies in the extensions.
153 Handle(Geom2d_TrimmedCurve) BC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
155 B.UpdateEdge(E,BC->BasisCurve(),F,Tol);
158 B.UpdateEdge(E,C,F,Tol);
162 //=======================================================================
163 //function : UpdateEdge
165 //=======================================================================
167 static void UpdateEdge (const TopoDS_Edge& E,
168 const Handle(Geom2d_Curve)& C1,
169 const Handle(Geom2d_Curve)& C2,
170 const TopoDS_Face& F,
171 const Standard_Real Tol)
173 // Cut curves to avoid copies in the extensions.
175 Handle(Geom2d_Curve) NC1,NC2;
176 Handle(Geom2d_TrimmedCurve) BC1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
177 Handle(Geom2d_TrimmedCurve) BC2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
178 if (!BC1.IsNull()) NC1 = BC1->BasisCurve(); else NC1 = C1;
179 if (!BC2.IsNull()) NC2 = BC2->BasisCurve(); else NC2 = C2;
180 B.UpdateEdge(E,NC1,NC2,F,Tol);
184 //=======================================================================
185 //function : ComputeCurve3d
186 //purpose : Particular case of Curve On Surface.
187 //=======================================================================
189 static void ComputeCurve3d(TopoDS_Edge Edge,
190 const Handle(Geom2d_Curve)& Curve,
191 const Handle(Geom_Surface)& Surf,
192 const TopLoc_Location Loc,
195 // try to find the particular case
196 // if not found call BRepLib::BuildCurve3d
198 Standard_Boolean IsComputed = Standard_False;
200 // Search only isos on analytic surfaces.
201 Geom2dAdaptor_Curve C(Curve);
202 GeomAdaptor_Surface S(Surf);
203 GeomAbs_CurveType CTy = C.GetType();
204 GeomAbs_SurfaceType STy = S.GetType();
205 BRep_Builder TheBuilder;
207 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d manage KPart
208 if ( CTy == GeomAbs_Line) {
209 gp_Dir2d D = C.Line().Direction();
210 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
211 if ( STy == GeomAbs_Sphere) {
212 gp_Pnt2d P = C.Line().Location();
213 if ( Abs( Abs(P.Y()) -M_PI/2. ) < Precision::PConfusion()) {
214 TheBuilder.Degenerated(Edge, Standard_True);
217 gp_Sphere Sph = S.Sphere();
218 gp_Ax3 Axis = Sph.Position();
219 gp_Circ Ci = ElSLib::SphereVIso(Axis,
222 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
223 gp_Ax1 AxeRev(Axis.Location(), DRev);
224 Ci.Rotate(AxeRev, P.X());
225 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
226 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
228 UpdateEdge(Edge, Circle, Loc, Tol);
230 IsComputed = Standard_True;
232 else if ( STy == GeomAbs_Cylinder) {
233 gp_Cylinder Cyl = S.Cylinder();
234 gp_Pnt2d P = C.Line().Location();
235 gp_Ax3 Axis = Cyl.Position();
236 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
239 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
240 gp_Ax1 AxeRev(Axis.Location(), DRev);
241 Ci.Rotate(AxeRev, P.X());
242 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
243 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
245 UpdateEdge(Edge, Circle, Loc, Tol);
246 IsComputed = Standard_True;
248 else if ( STy == GeomAbs_Cone) {
249 gp_Cone Cone = S.Cone();
250 gp_Pnt2d P = C.Line().Location();
251 gp_Ax3 Axis = Cone.Position();
252 gp_Circ Ci = ElSLib::ConeVIso(Axis,
256 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
257 gp_Ax1 AxeRev(Axis.Location(), DRev);
258 Ci.Rotate(AxeRev, P.X());
259 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
260 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
262 UpdateEdge(Edge, Circle, Loc, Tol);
263 IsComputed = Standard_True;
265 else if ( STy == GeomAbs_Torus) {
266 gp_Torus Tore = S.Torus();
267 gp_Pnt2d P = C.Line().Location();
268 gp_Ax3 Axis = Tore.Position();
269 gp_Circ Ci = ElSLib::TorusVIso(Axis,
273 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
274 gp_Ax1 AxeRev(Axis.Location(), DRev);
275 Ci.Rotate(AxeRev, P.X());
276 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
277 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
279 UpdateEdge(Edge, Circle, Loc, Tol);
280 IsComputed = Standard_True;
283 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
284 if ( STy == GeomAbs_Sphere) {
285 gp_Sphere Sph = S.Sphere();
286 gp_Pnt2d P = C.Line().Location();
287 gp_Ax3 Axis = Sph.Position();
289 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
291 // set to sameparameter (rotation of circle - offset of Y)
292 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
293 gp_Ax1 AxeRev(Axis.Location(),DRev);
294 Ci.Rotate(AxeRev, P.Y());
296 // transformation en iso U ( = P.X())
297 DRev = Axis.XDirection().Crossed(Axis.YDirection());
298 AxeRev = gp_Ax1(Axis.Location(), DRev);
299 Ci.Rotate(AxeRev, P.X());
300 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
302 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
304 UpdateEdge(Edge, Circle, Loc, Tol);
305 IsComputed = Standard_True;
307 else if ( STy == GeomAbs_Cylinder) {
308 gp_Cylinder Cyl = S.Cylinder();
309 gp_Pnt2d P = C.Line().Location();
310 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
313 gp_Vec Tr(L.Direction());
316 Handle(Geom_Line) Line = new Geom_Line(L);
317 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
319 UpdateEdge(Edge, Line, Loc, Tol);
320 IsComputed = Standard_True;
322 else if ( STy == GeomAbs_Cone) {
323 gp_Cone Cone = S.Cone();
324 gp_Pnt2d P = C.Line().Location();
325 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
329 gp_Vec Tr(L.Direction());
331 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
332 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
334 UpdateEdge(Edge, Line, Loc, Tol);
335 IsComputed = Standard_True;
337 else if ( STy == GeomAbs_Torus) {
338 gp_Torus Tore = S.Torus();
339 gp_Pnt2d P = C.Line().Location();
340 gp_Ax3 Axis = Tore.Position();
341 gp_Circ Ci = ElSLib::TorusUIso(Axis,
345 Ci.Rotate(Ci.Axis(),P.Y());
346 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
348 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
350 UpdateEdge(Edge, Circle, Loc, Tol);
351 IsComputed = Standard_True;
357 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
358 UpdateEdge(Edge, C3d, Loc, Tol);
359 IsComputed = Standard_True;
362 //BRepLib::BuildCurves3d(Edge,Tol);
363 //Les Courbes 3d des edges dans le cas general ne sont calcules que si
365 //ie dans les tuyaux et les bouchons ..
366 // dans la derniere etapes de MakeShells on reconstruira les courbes3d
367 // des edges du resultat qui n en ont pas.
372 //=======================================================================
373 //function : BRepOffset_Offset
375 //=======================================================================
377 BRepOffset_Offset::BRepOffset_Offset()
382 //=======================================================================
383 //function : BRepOffset_Offset
385 //=======================================================================
387 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Face& Face,
388 const Standard_Real Offset,
389 const Standard_Boolean OffsetOutside,
390 const GeomAbs_JoinType JoinType)
392 Init(Face, Offset, OffsetOutside, JoinType);
396 //=======================================================================
397 //function : BRepOffset_Offset
399 //=======================================================================
401 BRepOffset_Offset::BRepOffset_Offset
402 (const TopoDS_Face& Face,
403 const Standard_Real Offset,
404 const TopTools_DataMapOfShapeShape& Created,
405 const Standard_Boolean OffsetOutside,
406 const GeomAbs_JoinType JoinType)
408 Init(Face,Offset,Created,OffsetOutside,JoinType);
412 //=======================================================================
413 //function : BRepOffset_Offset
415 //=======================================================================
417 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Edge& Path,
418 const TopoDS_Edge& Edge1,
419 const TopoDS_Edge& Edge2,
420 const Standard_Real Offset,
421 const Standard_Boolean Polynomial,
422 const Standard_Real Tol,
423 const GeomAbs_Shape Conti)
425 Init(Path,Edge1,Edge2,Offset,Polynomial,Tol,Conti);
429 //=======================================================================
430 //function : BRepOffset_Offset
432 //=======================================================================
434 BRepOffset_Offset::BRepOffset_Offset
435 (const TopoDS_Edge& Path,
436 const TopoDS_Edge& Edge1,
437 const TopoDS_Edge& Edge2,
438 const Standard_Real Offset,
439 const TopoDS_Edge& FirstEdge,
440 const TopoDS_Edge& LastEdge,
441 const Standard_Boolean Polynomial,
442 const Standard_Real Tol,
443 const GeomAbs_Shape Conti)
445 Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti);
449 //=======================================================================
450 //function : BRepOffset_Offset
452 //=======================================================================
454 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Vertex& Vertex,
455 const TopTools_ListOfShape& LEdge,
456 const Standard_Real Offset,
457 const Standard_Boolean Polynomial,
458 const Standard_Real Tol,
459 const GeomAbs_Shape Conti)
461 Init(Vertex,LEdge,Offset,Polynomial,Tol,Conti);
465 //=======================================================================
468 //=======================================================================
470 void BRepOffset_Offset::Init(const TopoDS_Face& Face,
471 const Standard_Real Offset,
472 const Standard_Boolean OffsetOutside,
473 const GeomAbs_JoinType JoinType)
475 TopTools_DataMapOfShapeShape Empty;
476 Init(Face,Offset,Empty,OffsetOutside,JoinType);
480 //=======================================================================
483 //=======================================================================
485 void BRepOffset_Offset::Init(const TopoDS_Face& Face,
486 const Standard_Real Offset,
487 const TopTools_DataMapOfShapeShape& Created,
488 const Standard_Boolean OffsetOutside,
489 const GeomAbs_JoinType JoinType)
492 Standard_Real myOffset = Offset;
493 if ( Face.Orientation() == TopAbs_REVERSED)
497 Handle(Geom_Surface) S = BRep_Tool::Surface(Face,L);
499 // On detrime les surfaces, evite des recopies dans les extensions.
500 Handle(Geom_RectangularTrimmedSurface) RT =
501 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
502 if (!RT.IsNull()) S = RT->BasisSurface();
504 // particular case of cone
505 Handle(Geom_ConicalSurface) Co;
506 Co = Handle(Geom_ConicalSurface)::DownCast(S);
509 gp_Pnt Apex = Co->Apex();
510 ElSLib::Parameters( Co->Cone(),Apex,Uc,Vc);
511 Standard_Real UU1,UU2,VV1,VV2;
512 BRepTools::UVBounds(Face,UU1,UU2,VV1,VV2);
513 if ( VV2 < Vc && Co->SemiAngle() > 0 )
515 else if ( VV1 > Vc && Co->SemiAngle() < 0 )
517 if ( !Co->Position().Direct()) myOffset *= -1;
520 Handle(Geom_Surface) TheSurf =
521 BRepOffset::Surface( S, myOffset, myStatus);
523 //processing offsets of faces with possible degenerated edges
524 Standard_Boolean UminDegen = Standard_False;
525 Standard_Boolean UmaxDegen = Standard_False;
526 Standard_Boolean VminDegen = Standard_False;
527 Standard_Boolean VmaxDegen = Standard_False;
528 Standard_Boolean UisoDegen = 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 //define the iso of singularity (u or v)
549 const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
550 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
551 gp_Pnt2d fp2d = aCurve->Value(fpar);
552 gp_Pnt2d lp2d = aCurve->Value(lpar);
553 if (Abs(fp2d.X() - lp2d.X()) <= Precision::PConfusion())
554 UisoDegen = Standard_True;
556 if (DegEdges.Length() == 2)
559 { UminDegen = Standard_True; UmaxDegen = Standard_True; }
561 { VminDegen = Standard_True; VmaxDegen = Standard_True; }
563 else //DegEdges.Length() == 1
565 const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
566 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
569 if (Abs(fp2d.X() - uf1) <= Precision::Confusion())
570 UminDegen = Standard_True;
572 UmaxDegen = Standard_True;
576 if (Abs(fp2d.Y() - vf1) <= Precision::Confusion())
577 VminDegen = Standard_True;
579 VmaxDegen = Standard_True;
582 if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
584 gp_Cone theCone = Handle(Geom_ConicalSurface)::DownCast (TheSurf)->Cone();
585 gp_Pnt apex = theCone.Apex();
586 Standard_Real Uapex, Vapex;
587 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
590 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, Vapex, vf2);
592 HasSingularity = Standard_True;
596 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, Vapex);
598 HasSingularity = Standard_True;
601 else //TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)
605 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
606 if (BRepOffset_Tool::Gabarit( uiso ) > TolApex)
608 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (TheSurf)->BasisSurface();
609 gp_Pnt Papex, Pfirst, Pquart, Pmid;
610 Papex = BasisSurf->Value( uf1, vf1 );
611 Pfirst = TheSurf->Value( uf1, vf1 );
612 Pquart = TheSurf->Value( uf1, 0.75*vf1+0.25*vf2 );
613 Pmid = TheSurf->Value( uf1, 0.5*(vf1+vf2) );
614 gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
615 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
616 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 1, 0 );
617 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
618 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
620 theExtrema.NearestPoints(Pint1, Pint2);
621 Standard_Real length = Pfirst.Distance(Pint1);
624 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
625 GeomLib::ExtendSurfByLength (aSurf, length, 1, Standard_True, Standard_False);
627 Standard_Real u1, u2, v1, v2;
628 TheSurf->Bounds( u1, u2, v1, v2 );
629 MinApex = TheSurf->Value( u1, vf1 );
633 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
634 GeomAPI_ProjectPointOnCurve Projector( Pint1, viso );
635 Standard_Real NewFirstU = Projector.LowerDistanceParameter();
636 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, NewFirstU, uf2, vf1, vf2);
637 MinApex = TheSurf->Value( NewFirstU, vf1 );
639 HasSingularity = Standard_True;
641 } //end of if (UminDegen)
644 Handle(Geom_Curve) uiso = TheSurf->UIso( uf2 );
645 if (BRepOffset_Tool::Gabarit( uiso ) > TolApex)
647 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (TheSurf)->BasisSurface();
648 gp_Pnt Papex, Pfirst, Pquart, Pmid;
649 Papex = BasisSurf->Value( uf2, vf1 );
650 Pfirst = TheSurf->Value( uf2, vf1 );
651 Pquart = TheSurf->Value( uf2, 0.75*vf1+0.25*vf2 );
652 Pmid = TheSurf->Value( uf2, 0.5*(vf1+vf2) );
653 gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
654 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
655 gp_Vec DirGeneratrix = BasisSurf->DN( uf2, vf1, 1, 0 );
656 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
657 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
659 theExtrema.NearestPoints(Pint1, Pint2);
660 Standard_Real length = Pfirst.Distance(Pint1);
663 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
664 GeomLib::ExtendSurfByLength(aSurf, length, 1, Standard_True, Standard_True);
666 Standard_Real u1, u2, v1, v2;
667 TheSurf->Bounds( u1, u2, v1, v2 );
668 MaxApex = TheSurf->Value( u2, vf1 );
672 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
673 GeomAPI_ProjectPointOnCurve Projector( Pint1, viso );
674 Standard_Real NewLastU = Projector.LowerDistanceParameter();
675 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, NewLastU, vf1, vf2);
676 MaxApex = TheSurf->Value( NewLastU, vf1 );
678 HasSingularity = Standard_True;
680 } //end of if (UmaxDegen)
683 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
684 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
686 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (TheSurf)->BasisSurface();
687 gp_Pnt Papex, Pfirst, Pquart, Pmid;
688 Papex = BasisSurf->Value( uf1, vf1 );
689 Pfirst = TheSurf->Value( uf1, vf1 );
690 Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf1 );
691 Pmid = TheSurf->Value( 0.5*(uf1+uf2), vf1 );
692 gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
693 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
694 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
695 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
696 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
698 theExtrema.NearestPoints(Pint1, Pint2);
699 Standard_Real length = Pfirst.Distance(Pint1);
702 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
703 GeomLib::ExtendSurfByLength(aSurf, length, 1, Standard_False, Standard_False);
705 Standard_Real u1, u2, v1, v2;
706 TheSurf->Bounds( u1, u2, v1, v2 );
707 MinApex = TheSurf->Value( uf1, v1 );
711 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
712 GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
713 Standard_Real NewFirstV = Projector.LowerDistanceParameter();
714 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2);
715 MinApex = TheSurf->Value( uf1, NewFirstV );
716 //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2);
717 //MinApex = TheSurf->Value( uf1, vf1+length );
719 HasSingularity = Standard_True;
721 } //end of if (VminDegen)
724 Handle(Geom_Curve) viso = TheSurf->VIso( vf2 );
725 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
727 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (TheSurf)->BasisSurface();
728 gp_Pnt Papex, Pfirst, Pquart, Pmid;
729 Papex = BasisSurf->Value( uf1, vf2 );
730 Pfirst = TheSurf->Value( uf1, vf2 );
731 Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf2 );
732 Pmid = TheSurf->Value( 0.5*(uf1+uf2), vf2 );
733 gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
734 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
735 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
736 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
737 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
739 theExtrema.NearestPoints(Pint1, Pint2);
740 Standard_Real length = Pfirst.Distance(Pint1);
743 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
744 GeomLib::ExtendSurfByLength(aSurf, length, 1, Standard_False, Standard_True);
746 Standard_Real u1, u2, v1, v2;
747 TheSurf->Bounds( u1, u2, v1, v2 );
748 MaxApex = TheSurf->Value( uf1, v2 );
752 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
753 GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
754 Standard_Real NewLastV = Projector.LowerDistanceParameter();
755 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV);
756 MaxApex = TheSurf->Value( uf1, NewLastV );
757 //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length);
758 //MaxApex = TheSurf->Value( uf1, vf2-length );
760 HasSingularity = Standard_True;
762 } //end of if (VmaxDegen)
763 } //end of else (case of Geom_OffsetSurface)
764 } //end of if (!DegEdges.IsEmpty())
765 } //end of processing offsets of faces with possible degenerated edges
767 // find the PCurves of the edges of <Faces>
769 BRep_Builder myBuilder;
770 myBuilder.MakeFace(myFace);
771 myBuilder.UpdateFace(myFace,TheSurf,L,BRep_Tool::Tolerance(Face));
773 TopTools_DataMapOfShapeShape MapSS;
775 // mise a jour de la map sur les vertex deja crees
776 TopoDS_Shape aLocalShape = Face.Oriented(TopAbs_FORWARD);
777 TopoDS_Face CurFace = TopoDS::Face(aLocalShape);
778 // TopoDS_Face CurFace = TopoDS::Face(Face.Oriented(TopAbs_FORWARD));
780 TopTools_MapOfShape VonDegen;
781 Standard_Real u1, u2, v1, v2;
782 TheSurf->Bounds( u1, u2, v1, v2 );
784 TopExp_Explorer exp(CurFace, TopAbs_EDGE);
785 for ( ; exp.More(); exp.Next()) {
786 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
787 TopoDS_Vertex V1,V2,OV1,OV2;
788 TopExp::Vertices(E ,V1 ,V2 );
789 if (HasSingularity && BRep_Tool::Degenerated(E))
791 if (Created.IsBound(E)) {
792 const TopoDS_Edge& OE = TopoDS::Edge(Created(E));
793 TopExp::Vertices(OE,OV1,OV2);
794 if (!MapSS.IsBound(V1)) MapSS.Bind(V1,OV1);
795 if (!MapSS.IsBound(V2)) MapSS.Bind(V2,OV2);
797 if (Created.IsBound(V1)) {
798 if (!MapSS.IsBound(V1)) MapSS.Bind(V1,Created(V1));
800 if (Created.IsBound(V2)) {
801 if (!MapSS.IsBound(V2)) MapSS.Bind(V2,Created(V2));
805 TopExp_Explorer expw(CurFace, TopAbs_WIRE);
806 for ( ; expw.More(); expw.Next()) {
807 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
808 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
811 myBuilder.MakeWire(OW);
812 for ( ; expe.More(); expe.Next()) {
813 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
815 TopExp::Vertices(E,V1,V2);
818 Standard_Real vstart, vend;
820 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,CurFace,f,l);
822 if (MapSS.IsBound(E) &&
823 !VonDegen.Contains(V1) && !VonDegen.Contains(V2)) { // c`est un edge de couture
824 OE = TopoDS::Edge(MapSS(E));
825 TopoDS_Shape aLocalShape = E.Reversed();
826 Handle(Geom2d_Curve) C2d_1 =
827 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l);
828 // Handle(Geom2d_Curve) C2d_1 =
829 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),CurFace,f,l);
830 if ( E.Orientation() == TopAbs_FORWARD)
831 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
833 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
834 myBuilder.Range(OE,f,l);
837 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
838 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
839 P2d1 = C2d->Value(BRep_Tool::Parameter(V1,Eforward,CurFace));
840 P2d2 = C2d->Value(BRep_Tool::Parameter(V2,Eforward,CurFace));
841 if (VonDegen.Contains(V1))
843 if (Abs(P2d1.Y() - vf1) <= Precision::Confusion())
845 P1 = MinApex; vstart = v1;
849 P1 = MaxApex; vstart = v2;
854 TheSurf->D0(P2d1.X(),P2d1.Y(),P1);
855 P1.Transform(L.Transformation());
858 if (VonDegen.Contains(V2))
860 if (Abs(P2d2.Y() - vf1) <= Precision::Confusion())
862 P2 = MinApex; vend = v1;
866 P2 = MaxApex; vend = v2;
871 TheSurf->D0(P2d2.X(),P2d2.Y(),P2);
872 P2.Transform(L.Transformation());
875 // E a-t-il ume image dans la Map des Created ?
876 if ( Created.IsBound(E)) {
877 OE = TopoDS::Edge(Created(E));
879 else if (MapSS.IsBound(E)) //seam edge
880 OE = TopoDS::Edge(MapSS(E));
882 myBuilder.MakeEdge(OE);
883 TopoDS_Vertex OV1,OV2;
884 if ( MapSS.IsBound(V1)) {
885 OV1 = TopoDS::Vertex(MapSS(V1));
888 myBuilder.MakeVertex(OV1);
889 myBuilder.UpdateVertex(OV1,P1,BRep_Tool::Tolerance(V1));
892 if ( MapSS.IsBound(V2)) {
893 OV2 = TopoDS::Vertex(MapSS(V2));
896 myBuilder.MakeVertex(OV2);
897 myBuilder.UpdateVertex(OV2,P2,BRep_Tool::Tolerance(V2));
900 myBuilder.Add(OE,OV1.Oriented(V1.Orientation()));
901 myBuilder.Add(OE,OV2.Oriented(V2.Orientation()));
902 if (BRep_Tool::Degenerated(E)) {
903 myBuilder.Degenerated(OE, Standard_True);
908 P2d = C2d->Value(f); TheSurf->D0(P2d.X(),P2d.Y(),P1);
909 P2d = C2d->Value(l); TheSurf->D0(P2d.X(),P2d.Y(),P2);
910 Standard_Real Tol = BRep_Tool::Tolerance(V1);
911 if (!P1.IsEqual(P2,Tol)) {
912 cout <<"BRepOffset_Offset : E degenerated -> OE not degenerated"<<endl;
918 if (VonDegen.Contains(V1) || VonDegen.Contains(V2))
920 if (VonDegen.Contains(V1))
922 if (VonDegen.Contains(V2))
924 C2d = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) );
925 f = 0.; l = P2d1.Distance( P2d2 );
926 if (MapSS.IsBound(E)) //seam edge
928 Handle(Geom2d_Curve) C2d_1 = BRep_Tool::CurveOnSurface(OE, myFace, f, l);
929 if (E.Orientation() == TopAbs_FORWARD)
930 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
932 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
935 UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E));
936 //myBuilder.Range(OE,f,l);
937 myBuilder.Range(OE, myFace, f, l);
938 if (!BRep_Tool::Degenerated(E) && TheSurf->IsUClosed())
940 TopoDS_Shape aLocalShape = E.Reversed();
941 Handle(Geom2d_Curve) C2d_1 =
942 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l);
943 P2d1 = C2d_1->Value(BRep_Tool::Parameter(V1,E,CurFace));
944 P2d2 = C2d_1->Value(BRep_Tool::Parameter(V2,E,CurFace));
945 if (VonDegen.Contains(V1))
947 if (VonDegen.Contains(V2))
949 C2d_1 = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) );
950 if ( E.Orientation() == TopAbs_FORWARD)
951 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
953 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
956 if (!BRep_Tool::Degenerated(E))
958 Handle(Geom_Line) theLine = new Geom_Line( P1, gp_Vec(P1, P2) );
959 myBuilder.UpdateEdge( OE, theLine, BRep_Tool::Tolerance(E) );
965 UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E));
966 myBuilder.Range(OE,f,l);
967 //ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
969 if (!BRep_Tool::Degenerated(OE))
970 ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
973 myBuilder.Add(OW, OE.Oriented(E.Orientation()));
975 myBuilder.Add(myFace, OW.Oriented(W.Orientation()));
978 myFace.Orientation(Face.Orientation());
980 BRepTools::Update(myFace);
984 //=======================================================================
987 //=======================================================================
989 void BRepOffset_Offset::Init(const TopoDS_Edge& Path,
990 const TopoDS_Edge& Edge1,
991 const TopoDS_Edge& Edge2,
992 const Standard_Real Offset,
993 const Standard_Boolean Polynomial,
994 const Standard_Real Tol,
995 const GeomAbs_Shape Conti)
997 TopoDS_Edge FirstEdge,LastEdge;
998 Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti);
1002 //=======================================================================
1005 //=======================================================================
1007 void BRepOffset_Offset::Init(const TopoDS_Edge& Path,
1008 const TopoDS_Edge& Edge1,
1009 const TopoDS_Edge& Edge2,
1010 const Standard_Real Offset,
1011 const TopoDS_Edge& FirstEdge,
1012 const TopoDS_Edge& LastEdge,
1013 const Standard_Boolean Polynomial,
1014 const Standard_Real Tol,
1015 const GeomAbs_Shape Conti)
1017 Standard_Boolean C1Denerated = Standard_False;
1018 Standard_Boolean C2Denerated = Standard_False;
1019 myStatus = BRepOffset_Good;
1022 TopLoc_Location Loc;
1023 Standard_Real f[3],l[3];
1025 Handle(Geom_Curve) CP = BRep_Tool::Curve(Path,Loc,f[0],l[0]);
1026 CP = new Geom_TrimmedCurve(CP,f[0], l[0]);
1027 CP->Transform(Loc.Transformation());
1028 Handle(GeomAdaptor_HCurve) HCP = new GeomAdaptor_HCurve(CP);
1030 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,Loc,f[1],l[1]);
1032 Handle(Adaptor3d_HCurve) HEdge1;
1033 Standard_Boolean C1is3D = Standard_True;
1035 C1is3D = Standard_False;
1036 Handle(Geom2d_Curve) C12d;
1037 Handle(Geom_Surface) S1;
1038 BRep_Tool::CurveOnSurface(Edge1,C12d,S1,Loc,f[1],l[1]);
1039 S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation()));
1040 C12d = new Geom2d_TrimmedCurve(C12d,f[1],l[1]);
1041 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(S1);
1042 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C12d);
1043 Adaptor3d_CurveOnSurface Cons(HC1,HS1);
1044 HEdge1 = new Adaptor3d_HCurveOnSurface(Cons);
1047 C1 = new Geom_TrimmedCurve(C1, f[1], l[1]);
1048 C1->Transform(Loc.Transformation());
1049 HEdge1 = new GeomAdaptor_HCurve(C1);
1050 GeomAdaptor_Curve AC1(C1);
1051 if ( AC1.GetType() == GeomAbs_Circle) {
1052 C1Denerated = (AC1.Circle().Radius() < Precision::Confusion());
1056 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,Loc,f[2],l[2]);
1058 Handle(Adaptor3d_HCurve) HEdge2;
1059 Standard_Boolean C2is3D = Standard_True;
1061 C2is3D = Standard_False;
1062 Handle(Geom2d_Curve) C12d;
1063 Handle(Geom_Surface) S1;
1064 BRep_Tool::CurveOnSurface(Edge2,C12d,S1,Loc,f[2],l[2]);
1065 S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation()));
1066 C12d = new Geom2d_TrimmedCurve(C12d,f[2],l[2]);
1067 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface(S1);
1068 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C12d);
1069 Adaptor3d_CurveOnSurface Cons(HC1,HS1);
1070 HEdge2 = new Adaptor3d_HCurveOnSurface(Cons);
1073 C2 = new Geom_TrimmedCurve(C2, f[2], l[2]);
1074 C2->Transform(Loc.Transformation());
1075 HEdge2 = new GeomAdaptor_HCurve(C2);
1076 GeomAdaptor_Curve AC2(C2);
1077 if ( AC2.GetType() == GeomAbs_Circle) {
1078 C2Denerated = (AC2.Circle().Radius() < Precision::Confusion());
1083 GeomFill_Pipe Pipe(HCP, HEdge1, HEdge2, Abs(Offset));
1084 Pipe.Perform(Tol, Polynomial, Conti);
1085 Standard_Real ErrorPipe = Pipe.ErrorOnSurf();
1087 Handle(Geom_Surface) S = Pipe.Surface();
1088 Standard_Boolean ExchUV = Pipe.ExchangeUV();
1089 Standard_Real f1,l1,f2,l2;
1090 S->Bounds(f1,l1,f2,l2);
1093 Standard_Real PathTol = BRep_Tool::Tolerance(Path);
1094 Standard_Real TheTol;
1095 BRep_Builder myBuilder;
1096 myBuilder.MakeFace(myFace);
1098 myBuilder.UpdateFace(myFace,S,Id,PathTol);
1100 // update de Edge1. (Rem : has already a 3d curve)
1101 Standard_Real U,U1,U2;
1102 Handle(Geom2d_Curve) PC;
1104 PC = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1107 if (!C1is3D) C1 = S->VIso(f2);
1110 PC = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1113 if (!C1is3D) C1 = S->UIso(f1);
1116 Handle(Geom_Curve) Dummy;
1118 UpdateEdge(Edge1,C1,Id,BRep_Tool::Tolerance(Edge1));
1119 else if ( C1Denerated) {
1120 UpdateEdge(Edge1,Dummy,Id,BRep_Tool::Tolerance(Edge1));
1121 myBuilder.Degenerated(Edge1,Standard_True);
1124 TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge1) + ErrorPipe);
1125 UpdateEdge(Edge1, PC, myFace, TheTol);
1127 // mise a same range de la nouvelle pcurve.
1128 if ( !C1is3D && !C1Denerated)
1130 myBuilder.SameRange (Edge1,Standard_False);
1131 myBuilder.Range(Edge1,U1,U2, Standard_True);
1133 myBuilder.Range(Edge1,myFace,U1,U2);
1134 BRepLib::SameRange(Edge1);
1136 // mise a sameparameter pour les KPart
1137 if (ErrorPipe == 0) {
1138 TheTol = Max(TheTol, Tol);
1139 myBuilder.SameParameter(Edge1,Standard_False);
1140 BRepLib::SameParameter(Edge1, TheTol);
1143 // Update de edge2. (Rem : has already a 3d curve)
1145 PC = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1148 if (!C2is3D) C2 = S->VIso(l2);
1151 PC = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1154 if (!C2is3D) C2 = S->UIso(l1);
1158 UpdateEdge(Edge2,C2,Id,BRep_Tool::Tolerance(Edge2));
1159 else if ( C2Denerated) {
1160 UpdateEdge(Edge2,Dummy,Id,BRep_Tool::Tolerance(Edge2));
1161 myBuilder.Degenerated(Edge2,Standard_True);
1164 TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge2) + ErrorPipe);
1165 UpdateEdge(Edge2, PC, myFace, TheTol);
1167 // mise a same range de la nouvelle pcurve.
1168 myBuilder.SameRange (Edge2,Standard_False);
1169 if ( !C2is3D && !C2Denerated)
1170 myBuilder.Range(Edge2, U1, U2, Standard_True);
1171 myBuilder.Range(Edge2,myFace,U1,U2);
1172 BRepLib::SameRange(Edge2);
1174 // mise a sameparameter pour les KPart
1175 if (ErrorPipe == 0) {
1176 TheTol = Max(TheTol, Tol);
1177 myBuilder.SameParameter(Edge2,Standard_False);
1178 BRepLib::SameParameter(Edge2, TheTol);
1181 TopoDS_Edge Edge3, Edge4;
1183 TopoDS_Vertex V1f,V1l,V2f,V2l;
1184 TopExp::Vertices(Path,V1f,V1l);
1185 Standard_Boolean IsClosed = ( V1f.IsSame(V1l));
1187 TopExp::Vertices(Edge1,V1f,V1l);
1188 TopExp::Vertices(Edge2,V2f,V2l);
1190 Standard_Boolean StartDegenerated = (V1f.IsSame(V2f));
1191 Standard_Boolean EndDegenerated = (V1l.IsSame(V2l));
1193 Standard_Boolean E3rev = Standard_False;
1194 Standard_Boolean E4rev = Standard_False;
1196 TopoDS_Vertex VVf,VVl;
1197 if ( FirstEdge.IsNull()) {
1198 myBuilder.MakeEdge(Edge3);
1199 myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD));
1200 myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED));
1203 TopoDS_Shape aLocalEdge = FirstEdge.Oriented(TopAbs_FORWARD);
1204 Edge3 = TopoDS::Edge(aLocalEdge);
1205 // Edge3 = TopoDS::Edge(FirstEdge.Oriented(TopAbs_FORWARD));
1206 TopExp::Vertices(Edge3,VVf,VVl);
1208 // si firstedge n est pas nul, il faut que les vertex soient partages
1209 if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) {
1210 cout << "Attention Vertex non partages !!!!!!" << endl;
1213 if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) {
1214 // On fait vraisemblablement des conneries !!
1215 // On cree un autre edge, on appelle le Sewing apres.
1216 myBuilder.MakeEdge(Edge3);
1217 myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD));
1218 myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED));
1220 else if ( !VVf.IsSame(V1f)) {
1222 E3rev = Standard_True;
1229 Standard_Real TolApp = Precision::Approximation();
1231 Handle(Geom2d_Line) L1,L2;
1234 // rem : si ExchUv, il faut reverser le Wire.
1235 // donc l'edge Forward dans la face sera E4 : d'ou L1 et L2
1236 L2 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1237 L1 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1242 L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1243 L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1248 L1->Reverse(); L2->Reverse();
1253 UpdateEdge(Edge3, L1, L2, myFace,PathTol);
1254 myBuilder.Range(Edge3,myFace,U1,U2);
1255 if (StartDegenerated)
1256 myBuilder.Degenerated(Edge3,Standard_True);
1257 else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed
1258 ComputeCurve3d(Edge3,L1,S,Id,TolApp);
1261 if ( LastEdge.IsNull()) {
1262 myBuilder.MakeEdge(Edge4);
1263 myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD));
1264 myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED));
1267 TopoDS_Shape aLocalEdge = LastEdge.Oriented(TopAbs_FORWARD);
1268 Edge4 = TopoDS::Edge(aLocalEdge);
1269 // Edge4 = TopoDS::Edge(LastEdge.Oriented(TopAbs_FORWARD));
1270 TopExp::Vertices(Edge4,VVf,VVl);
1272 // si lastedge n est pas nul, il faut que les vertex soient partages
1273 if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) {
1274 cout << "Attention Vertex non partages !!!!!!" << endl;
1277 if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) {
1278 // On fait vraisemblablement des conneries !!
1279 // On cree un autre edge, on appelle le Sewing apres.
1280 myBuilder.MakeEdge(Edge4);
1281 myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD));
1282 myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED));
1284 else if ( !VVf.IsSame(V1l)) {
1286 E4rev = Standard_True;
1291 L1 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1296 L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1306 UpdateEdge(Edge3,L1,myFace,PathTol);
1307 myBuilder.Range(Edge3,myFace,U1,U2);
1308 if (StartDegenerated)
1309 myBuilder.Degenerated(Edge3,Standard_True);
1310 else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed
1311 ComputeCurve3d(Edge3,L1,S,Id,TolApp);
1314 L2 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1319 L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1329 UpdateEdge(Edge4,L2 ,myFace,PathTol);
1330 myBuilder.Range(Edge4,myFace,U1,U2);
1332 myBuilder.Degenerated(Edge4,Standard_True);
1333 else if (LastEdge.IsNull()) // then the 3d curve has not been yet computed
1334 ComputeCurve3d(Edge4,L2,S,Id,TolApp);
1338 if ( !FirstEdge.IsNull() && !StartDegenerated) {
1339 BRepLib::BuildCurve3d (Edge3,PathTol);
1340 myBuilder.SameRange (Edge3,Standard_False);
1341 myBuilder.SameParameter(Edge3,Standard_False);
1342 BRepLib::SameParameter (Edge3, Tol);
1344 if ( !LastEdge.IsNull() && !EndDegenerated) {
1345 BRepLib::BuildCurve3d (Edge4,PathTol);
1346 myBuilder.SameRange (Edge4,Standard_False);
1347 myBuilder.SameParameter(Edge4,Standard_False);
1348 BRepLib::SameParameter (Edge4, Tol);
1352 myBuilder.MakeWire(W);
1354 myBuilder.Add(W, Edge1.Oriented(TopAbs_REVERSED));
1355 myBuilder.Add(W, Edge2.Oriented(TopAbs_FORWARD));
1356 myBuilder.Add(W, Edge4.Reversed());
1357 myBuilder.Add(W, Edge3);
1363 myBuilder.Add(myFace, W);
1364 if (ExchUV) myFace.Reverse();
1366 BRepTools::Update(myFace);
1368 if ( Edge1.Orientation() == TopAbs_REVERSED)
1374 //=======================================================================
1377 //=======================================================================
1379 void BRepOffset_Offset::Init(const TopoDS_Vertex& Vertex,
1380 const TopTools_ListOfShape& LEdge,
1381 const Standard_Real Offset,
1382 const Standard_Boolean Polynomial,
1383 const Standard_Real TolApp,
1384 const GeomAbs_Shape Conti)
1386 myStatus = BRepOffset_Good;
1389 // evaluate the Ax3 of the Sphere
1390 // find 3 different vertices in LEdge
1391 TopTools_ListIteratorOfListOfShape it;
1392 gp_Pnt P, P1, P2, P3;
1393 TopoDS_Vertex V1, V2, V3, V4;
1397 char* name = new char[100];
1401 sprintf(name,"VOnSph_%d",NbOFFSET);
1403 DBRep::Set(name, Vertex);
1405 Standard_Integer NbEdges = 1;
1406 for (it.Initialize(LEdge); it.More(); it.Next()) {
1407 sprintf(name,"EOnSph_%d_%d",NbOFFSET,NbEdges++);
1409 const TopoDS_Shape& CurE = it.Value();
1410 DBRep::Set(name, CurE);
1417 gp_Pnt Origin = BRep_Tool::Pnt(Vertex);
1419 //// Find the axis of the sphere to exclude
1420 //// degenerated and seam edges from the face under construction
1421 BRepLib_MakeWire MW;
1423 TopoDS_Wire theWire = MW.Wire();
1425 ShapeFix_Shape Fixer(theWire);
1427 theWire = TopoDS::Wire(Fixer.Shape());
1429 GProp_GProps GlobalProps;
1430 BRepGProp::LinearProperties(theWire, GlobalProps);
1431 gp_Pnt BaryCenter = GlobalProps.CentreOfMass();
1432 gp_Vec Xdir(BaryCenter, Origin);
1434 gp_Pnt FarestCorner = GetFarestCorner(theWire);
1435 gp_Pln thePlane = gce_MakePln(Origin, BaryCenter, FarestCorner);
1436 gp_Dir Vdir = thePlane.Axis().Direction();
1438 gp_Ax3 Axis(Origin, Vdir, Xdir);
1440 Handle(Geom_Surface) S
1441 = new Geom_SphericalSurface( Axis, Abs(Offset));
1443 Standard_Real f, l, Tol = BRep_Tool::Tolerance(Vertex);
1445 TopLoc_Location Loc;
1446 BRep_Builder myBuilder;
1447 myBuilder.MakeFace(myFace);
1448 Handle(Geom_Surface) SS = S;
1450 // En polynomial, calcul de la surface par F(u,v).
1451 // Pas de changement de parametre, donc ProjLib sur la Sphere
1454 GeomConvert_ApproxSurface Approx(S,TolApp,Conti,Conti,10,10,10,1);
1455 if (Approx.IsDone()) {
1456 SS = Approx.Surface();
1460 myBuilder.UpdateFace(myFace, SS, Loc, Tol);
1463 myBuilder.MakeWire(W);
1469 sprintf(name,"SPHERE_%d",NbOFFSET);
1470 DrawTrSurf::Set(name, S);
1472 Standard_Integer CO = 1;
1475 for ( it.Initialize(LEdge); it.More(); it.Next()) {
1476 TopoDS_Edge E = TopoDS::Edge(it.Value());
1478 Handle(Geom_Curve) C = BRep_Tool::Curve(E,Loc,f,l);
1480 BRepLib::BuildCurve3d(E,BRep_Tool::Tolerance(E));
1481 C = BRep_Tool::Curve(E,Loc,f,l);
1483 C = new Geom_TrimmedCurve(C, f, l);
1484 C->Transform(Loc.Transformation());
1488 sprintf(name,"CURVE_%d_%d",NbOFFSET,CO);
1489 DrawTrSurf::Set(name, C);
1494 Handle(Geom2d_Curve) PCurve = GeomProjLib::Curve2d(C, S);
1495 // check if the first point of PCurve in is the canonical boundaries
1496 // of the sphere. Else move it.
1497 // the transformation is : U` = U + PI + 2 k PI
1498 // V` = +/- PI + 2 k` PI
1499 gp_Pnt2d P2d = PCurve->Value(f);
1500 Standard_Boolean IsToAdjust = Standard_False;
1501 if ( P2d.Y() < -M_PI/2.) {
1502 IsToAdjust = Standard_True;
1503 PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0.,-M_PI/2.),gp::DX2d()));
1505 else if ( P2d.Y() > M_PI/2.) {
1506 IsToAdjust = Standard_True;
1507 PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0., M_PI/2.),gp::DX2d()));
1510 // set the u firstpoint in [0,2*pi]
1511 gp_Vec2d Tr( M_PI, 0.);
1512 if ( P2d.X() > M_PI) Tr.Reverse();
1513 PCurve->Translate(Tr);
1516 UpdateEdge(E, PCurve, myFace, Tol);
1517 myBuilder.Range(E, myFace, f, l);
1518 myBuilder.Add(W, E);
1521 myBuilder.Add(myFace, W.Oriented(TopAbs_REVERSED));
1525 myBuilder.Add(myFace, W);
1528 BRepTools::Update(myFace);
1532 //=======================================================================
1535 //=======================================================================
1537 void BRepOffset_Offset::Init(const TopoDS_Edge& Edge,
1538 const Standard_Real Offset)
1541 Standard_Real myOffset = Abs(Offset);
1544 TopLoc_Location Loc;
1546 Handle(Geom_Curve) CP = BRep_Tool::Curve(Edge,Loc,f,l);
1547 CP = new Geom_TrimmedCurve(CP,f,l);
1548 CP->Transform(Loc.Transformation());
1550 GeomFill_Pipe Pipe(CP,myOffset);
1553 BRepLib_MakeFace MF(Pipe.Surface(), Precision::Confusion());
1556 if ( Offset < 0.) myFace.Reverse();
1560 //=======================================================================
1563 //=======================================================================
1565 const TopoDS_Face& BRepOffset_Offset::Face() const
1571 //=======================================================================
1572 //function : Generated
1574 //=======================================================================
1576 TopoDS_Shape BRepOffset_Offset::Generated(const TopoDS_Shape& Shape) const
1578 TopoDS_Shape aShape;
1580 switch ( myShape.ShapeType()) {
1584 TopExp_Explorer exp (myShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1585 TopExp_Explorer expo(myFace .Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1586 for ( ; exp.More() && expo.More(); exp.Next(), expo.Next()) {
1587 if ( Shape.IsSame(exp.Current())) {
1588 if ( myShape.Orientation() == TopAbs_REVERSED)
1589 aShape = expo.Current().Reversed();
1591 aShape = expo.Current();
1598 // have generate a pipe.
1600 TopoDS_Vertex V1, V2;
1601 TopExp::Vertices(TopoDS::Edge(myShape), V1, V2);
1603 TopExp_Explorer expf(myFace .Oriented(TopAbs_FORWARD), TopAbs_WIRE);
1604 TopExp_Explorer expo(expf.Current().Oriented(TopAbs_FORWARD),
1609 if ( V2.IsSame(Shape)) {
1610 if ( expf.Current().Orientation() == TopAbs_REVERSED)
1611 aShape = expo.Current().Reversed();
1613 aShape = expo.Current();
1617 if ( expf.Current().Orientation() == TopAbs_REVERSED)
1618 aShape = expo.Current().Reversed();
1620 aShape = expo.Current();
1622 if ( myFace.Orientation() == TopAbs_REVERSED)
1634 //=======================================================================
1637 //=======================================================================
1639 BRepOffset_Status BRepOffset_Offset::Status() const