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.hxx>
19 #include <Adaptor3d_CurveOnSurface.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_GCurve.hxx>
22 #include <BRep_TEdge.hxx>
23 #include <BRep_Tool.hxx>
24 #include <BRepGProp.hxx>
25 #include <BRepLib.hxx>
26 #include <BRepLib_MakeFace.hxx>
27 #include <BRepLib_MakeWire.hxx>
28 #include <BRepOffset.hxx>
29 #include <BRepOffset_Tool.hxx>
30 #include <BRepTools.hxx>
32 #include <gce_MakePln.hxx>
33 #include <Geom2d_Curve.hxx>
34 #include <Geom2d_Line.hxx>
35 #include <Geom2d_TrimmedCurve.hxx>
36 #include <Geom2dAdaptor_Curve.hxx>
37 #include <Geom_Circle.hxx>
38 #include <Geom_ConicalSurface.hxx>
39 #include <Geom_Curve.hxx>
40 #include <Geom_Line.hxx>
41 #include <Geom_OffsetSurface.hxx>
42 #include <Geom_RectangularTrimmedSurface.hxx>
43 #include <Geom_SphericalSurface.hxx>
44 #include <Geom_SurfaceOfLinearExtrusion.hxx>
45 #include <Geom_SurfaceOfRevolution.hxx>
46 #include <Geom_Surface.hxx>
47 #include <Geom_TrimmedCurve.hxx>
48 #include <GeomAdaptor_Surface.hxx>
49 #include <GeomAPI.hxx>
50 #include <GeomAPI_ExtremaCurveCurve.hxx>
51 #include <GeomAPI_ProjectPointOnCurve.hxx>
52 #include <GeomConvert_ApproxSurface.hxx>
53 #include <GeomFill_Pipe.hxx>
54 #include <GeomLib.hxx>
55 #include <GeomProjLib.hxx>
58 #include <gp_Cylinder.hxx>
60 #include <gp_Pnt2d.hxx>
61 #include <gp_Torus.hxx>
62 #include <GProp_GProps.hxx>
63 #include <Precision.hxx>
64 #include <ShapeFix_Shape.hxx>
65 #include <Standard_ConstructionError.hxx>
67 #include <TopExp_Explorer.hxx>
69 #include <TopoDS_Edge.hxx>
70 #include <TopoDS_Face.hxx>
71 #include <TopoDS_Shape.hxx>
72 #include <TopoDS_Vertex.hxx>
73 #include <TopoDS_Wire.hxx>
74 #include <TopTools_IndexedMapOfShape.hxx>
75 #include <TopTools_MapOfShape.hxx>
76 #include <TopTools_SequenceOfShape.hxx>
79 static Standard_Boolean Affich = Standard_False;
80 static Standard_Integer NbOFFSET = 0;
83 #include <DrawTrSurf.hxx>
87 #include <Geom_BSplineSurface.hxx>
90 static gp_Pnt GetFarestCorner(const TopoDS_Wire& aWire)
92 TopTools_IndexedMapOfShape Vertices;
93 TopExp::MapShapes(aWire, TopAbs_VERTEX, Vertices);
95 Standard_Real MaxDist = 0.;
97 for (Standard_Integer i = 1; i <= Vertices.Extent(); i++)
98 for (Standard_Integer j = 1; j <= Vertices.Extent(); j++)
100 const TopoDS_Vertex& V1 = TopoDS::Vertex(Vertices(i));
101 const TopoDS_Vertex& V2 = TopoDS::Vertex(Vertices(j));
102 gp_Pnt P1 = BRep_Tool::Pnt(V1);
103 gp_Pnt P2 = BRep_Tool::Pnt(V2);
104 Standard_Real aDist = P1.SquareDistance(P2);
115 //=======================================================================
116 //function : UpdateEdge
118 //=======================================================================
120 static void UpdateEdge(const TopoDS_Edge& E,
121 const Handle(Geom_Curve)& C,
122 const TopLoc_Location& L,
123 const Standard_Real Tol)
125 // Cut curves to avoid copies in the extensions.
127 Handle(Geom_TrimmedCurve) BC = Handle(Geom_TrimmedCurve)::DownCast(C);
129 B.UpdateEdge(E,BC->BasisCurve(),L,Tol);
132 B.UpdateEdge(E,C,L,Tol);
136 //=======================================================================
137 //function : UpdateEdge
139 //=======================================================================
141 static void UpdateEdge(const TopoDS_Edge& E,
142 const Handle(Geom2d_Curve)& C,
143 const TopoDS_Face& F,
144 const Standard_Real Tol)
146 // Cut curves to avoid copies in the extensions.
148 Handle(Geom2d_TrimmedCurve) BC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
150 B.UpdateEdge(E,BC->BasisCurve(),F,Tol);
153 B.UpdateEdge(E,C,F,Tol);
157 //=======================================================================
158 //function : UpdateEdge
160 //=======================================================================
162 static void UpdateEdge (const TopoDS_Edge& E,
163 const Handle(Geom2d_Curve)& C1,
164 const Handle(Geom2d_Curve)& C2,
165 const TopoDS_Face& F,
166 const Standard_Real Tol)
168 // Cut curves to avoid copies in the extensions.
170 Handle(Geom2d_Curve) NC1,NC2;
171 Handle(Geom2d_TrimmedCurve) BC1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
172 Handle(Geom2d_TrimmedCurve) BC2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
173 if (!BC1.IsNull()) NC1 = BC1->BasisCurve(); else NC1 = C1;
174 if (!BC2.IsNull()) NC2 = BC2->BasisCurve(); else NC2 = C2;
175 B.UpdateEdge(E,NC1,NC2,F,Tol);
179 //=======================================================================
180 //function : ComputeCurve3d
181 //purpose : Particular case of Curve On Surface.
182 //=======================================================================
184 static void ComputeCurve3d(const TopoDS_Edge& Edge,
185 const Handle(Geom2d_Curve)& Curve,
186 const Handle(Geom_Surface)& Surf,
187 const TopLoc_Location& Loc,
190 // try to find the particular case
191 // if not found call BRepLib::BuildCurve3d
193 Standard_Boolean IsComputed = Standard_False;
195 // Search only isos on analytic surfaces.
196 Geom2dAdaptor_Curve C(Curve);
197 GeomAdaptor_Surface S(Surf);
198 GeomAbs_CurveType CTy = C.GetType();
199 GeomAbs_SurfaceType STy = S.GetType();
200 BRep_Builder TheBuilder;
202 if ( STy != GeomAbs_Plane) { // if plane buildcurve3d manage KPart
203 if ( CTy == GeomAbs_Line) {
204 gp_Dir2d D = C.Line().Direction();
205 if ( D.IsParallel(gp::DX2d(),Precision::Angular())) { // Iso V.
206 if ( STy == GeomAbs_Sphere) {
207 gp_Pnt2d P = C.Line().Location();
208 if ( Abs( Abs(P.Y()) -M_PI/2. ) < Precision::PConfusion()) {
209 TheBuilder.Degenerated(Edge, Standard_True);
212 gp_Sphere Sph = S.Sphere();
213 gp_Ax3 Axis = Sph.Position();
214 gp_Circ Ci = ElSLib::SphereVIso(Axis,
217 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
218 gp_Ax1 AxeRev(Axis.Location(), DRev);
219 Ci.Rotate(AxeRev, P.X());
220 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
221 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
223 UpdateEdge(Edge, Circle, Loc, Tol);
225 IsComputed = Standard_True;
227 else if ( STy == GeomAbs_Cylinder) {
228 gp_Cylinder Cyl = S.Cylinder();
229 gp_Pnt2d P = C.Line().Location();
230 gp_Ax3 Axis = Cyl.Position();
231 gp_Circ Ci = ElSLib::CylinderVIso(Axis,
234 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
235 gp_Ax1 AxeRev(Axis.Location(), DRev);
236 Ci.Rotate(AxeRev, P.X());
237 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
238 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
240 UpdateEdge(Edge, Circle, Loc, Tol);
241 IsComputed = Standard_True;
243 else if ( STy == GeomAbs_Cone) {
244 gp_Cone Cone = S.Cone();
245 gp_Pnt2d P = C.Line().Location();
246 gp_Ax3 Axis = Cone.Position();
247 gp_Circ Ci = ElSLib::ConeVIso(Axis,
251 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
252 gp_Ax1 AxeRev(Axis.Location(), DRev);
253 Ci.Rotate(AxeRev, P.X());
254 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
255 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
257 UpdateEdge(Edge, Circle, Loc, Tol);
258 IsComputed = Standard_True;
260 else if ( STy == GeomAbs_Torus) {
261 gp_Torus Tore = S.Torus();
262 gp_Pnt2d P = C.Line().Location();
263 gp_Ax3 Axis = Tore.Position();
264 gp_Circ Ci = ElSLib::TorusVIso(Axis,
268 gp_Dir DRev = Axis.XDirection().Crossed(Axis.YDirection());
269 gp_Ax1 AxeRev(Axis.Location(), DRev);
270 Ci.Rotate(AxeRev, P.X());
271 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
272 if ( D.IsOpposite(gp::DX2d(),Precision::Angular()))
274 UpdateEdge(Edge, Circle, Loc, Tol);
275 IsComputed = Standard_True;
278 else if ( D.IsParallel(gp::DY2d(),Precision::Angular())) { // Iso U.
279 if ( STy == GeomAbs_Sphere) {
280 gp_Sphere Sph = S.Sphere();
281 gp_Pnt2d P = C.Line().Location();
282 gp_Ax3 Axis = Sph.Position();
284 gp_Circ Ci = ElSLib::SphereUIso(Axis, Sph.Radius(),0.);
286 // set to sameparameter (rotation of circle - offset of Y)
287 gp_Dir DRev = Axis.XDirection().Crossed(Axis. Direction());
288 gp_Ax1 AxeRev(Axis.Location(),DRev);
289 Ci.Rotate(AxeRev, P.Y());
291 // transformation en iso U ( = P.X())
292 DRev = Axis.XDirection().Crossed(Axis.YDirection());
293 AxeRev = gp_Ax1(Axis.Location(), DRev);
294 Ci.Rotate(AxeRev, P.X());
295 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
297 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
299 UpdateEdge(Edge, Circle, Loc, Tol);
300 IsComputed = Standard_True;
302 else if ( STy == GeomAbs_Cylinder) {
303 gp_Cylinder Cyl = S.Cylinder();
304 gp_Pnt2d P = C.Line().Location();
305 gp_Lin L = ElSLib::CylinderUIso(Cyl.Position(),
308 gp_Vec Tr(L.Direction());
311 Handle(Geom_Line) Line = new Geom_Line(L);
312 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
314 UpdateEdge(Edge, Line, Loc, Tol);
315 IsComputed = Standard_True;
317 else if ( STy == GeomAbs_Cone) {
318 gp_Cone Cone = S.Cone();
319 gp_Pnt2d P = C.Line().Location();
320 gp_Lin L = ElSLib::ConeUIso(Cone.Position(),
324 gp_Vec Tr(L.Direction());
326 L.Translate(Tr); Handle(Geom_Line) Line = new Geom_Line(L);
327 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
329 UpdateEdge(Edge, Line, Loc, Tol);
330 IsComputed = Standard_True;
332 else if ( STy == GeomAbs_Torus) {
333 gp_Torus Tore = S.Torus();
334 gp_Pnt2d P = C.Line().Location();
335 gp_Ax3 Axis = Tore.Position();
336 gp_Circ Ci = ElSLib::TorusUIso(Axis,
340 Ci.Rotate(Ci.Axis(),P.Y());
341 Handle(Geom_Circle) Circle = new Geom_Circle(Ci);
343 if ( D.IsOpposite(gp::DY2d(),Precision::Angular()))
345 UpdateEdge(Edge, Circle, Loc, Tol);
346 IsComputed = Standard_True;
352 Handle(Geom_Curve) C3d = GeomAPI::To3d(Curve,S.Plane());
353 UpdateEdge(Edge, C3d, Loc, Tol);
354 IsComputed = Standard_True;
357 //BRepLib::BuildCurves3d(Edge,Tol);
358 //Les Courbes 3d des edges dans le cas general ne sont calcules que si
360 //ie dans les tuyaux et les bouchons ..
361 // dans la derniere etapes de MakeShells on reconstruira les courbes3d
362 // des edges du resultat qui n en ont pas.
367 //=======================================================================
368 //function : BRepOffset_Offset
370 //=======================================================================
372 BRepOffset_Offset::BRepOffset_Offset()
377 //=======================================================================
378 //function : BRepOffset_Offset
380 //=======================================================================
382 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Face& Face,
383 const Standard_Real Offset,
384 const Standard_Boolean OffsetOutside,
385 const GeomAbs_JoinType JoinType)
387 Init(Face, Offset, OffsetOutside, JoinType);
391 //=======================================================================
392 //function : BRepOffset_Offset
394 //=======================================================================
396 BRepOffset_Offset::BRepOffset_Offset
397 (const TopoDS_Face& Face,
398 const Standard_Real Offset,
399 const TopTools_DataMapOfShapeShape& Created,
400 const Standard_Boolean OffsetOutside,
401 const GeomAbs_JoinType JoinType)
403 Init(Face,Offset,Created,OffsetOutside,JoinType);
407 //=======================================================================
408 //function : BRepOffset_Offset
410 //=======================================================================
412 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Edge& Path,
413 const TopoDS_Edge& Edge1,
414 const TopoDS_Edge& Edge2,
415 const Standard_Real Offset,
416 const Standard_Boolean Polynomial,
417 const Standard_Real Tol,
418 const GeomAbs_Shape Conti)
420 Init(Path,Edge1,Edge2,Offset,Polynomial,Tol,Conti);
424 //=======================================================================
425 //function : BRepOffset_Offset
427 //=======================================================================
429 BRepOffset_Offset::BRepOffset_Offset
430 (const TopoDS_Edge& Path,
431 const TopoDS_Edge& Edge1,
432 const TopoDS_Edge& Edge2,
433 const Standard_Real Offset,
434 const TopoDS_Edge& FirstEdge,
435 const TopoDS_Edge& LastEdge,
436 const Standard_Boolean Polynomial,
437 const Standard_Real Tol,
438 const GeomAbs_Shape Conti)
440 Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti);
444 //=======================================================================
445 //function : BRepOffset_Offset
447 //=======================================================================
449 BRepOffset_Offset::BRepOffset_Offset(const TopoDS_Vertex& Vertex,
450 const TopTools_ListOfShape& LEdge,
451 const Standard_Real Offset,
452 const Standard_Boolean Polynomial,
453 const Standard_Real Tol,
454 const GeomAbs_Shape Conti)
456 Init(Vertex,LEdge,Offset,Polynomial,Tol,Conti);
460 //=======================================================================
463 //=======================================================================
465 void BRepOffset_Offset::Init(const TopoDS_Face& Face,
466 const Standard_Real Offset,
467 const Standard_Boolean OffsetOutside,
468 const GeomAbs_JoinType JoinType)
470 TopTools_DataMapOfShapeShape Empty;
471 Init(Face,Offset,Empty,OffsetOutside,JoinType);
475 //=======================================================================
478 //=======================================================================
480 void BRepOffset_Offset::Init(const TopoDS_Face& Face,
481 const Standard_Real Offset,
482 const TopTools_DataMapOfShapeShape& Created,
483 const Standard_Boolean OffsetOutside,
484 const GeomAbs_JoinType JoinType)
487 Standard_Real myOffset = Offset;
488 if ( Face.Orientation() == TopAbs_REVERSED)
492 Handle(Geom_Surface) S = BRep_Tool::Surface(Face,L);
493 // On detrime les surfaces, evite des recopies dans les extensions.
494 Handle(Geom_RectangularTrimmedSurface) RT =
495 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
496 if (!RT.IsNull()) S = RT->BasisSurface();
497 Standard_Boolean IsTransformed = Standard_False;
498 if ((S->IsKind(STANDARD_TYPE(Geom_BSplineSurface)) ||
499 S->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) ||
500 S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution)) ||
501 S->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) && !L.IsIdentity())
503 S = Handle(Geom_Surface)::DownCast(S->Copy());
504 S->Transform(L.Transformation());
505 IsTransformed = Standard_True;
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 UminDegen = Standard_False;
528 Standard_Boolean UmaxDegen = Standard_False;
529 Standard_Boolean VminDegen = Standard_False;
530 Standard_Boolean VmaxDegen = Standard_False;
531 Standard_Boolean UisoDegen = Standard_False;
532 gp_Pnt MinApex, MaxApex;
533 Standard_Boolean HasSingularity = Standard_False;
534 Standard_Real uf1, uf2, vf1, vf2, fpar, lpar;
535 BRepTools::UVBounds(Face, uf1, uf2, vf1, vf2);
536 if (!(OffsetOutside && JoinType == GeomAbs_Arc) &&
537 (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface) ||
538 TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)))
540 TopTools_SequenceOfShape DegEdges;
541 TopExp_Explorer Explo(Face, TopAbs_EDGE);
542 for (; Explo.More(); Explo.Next())
544 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
546 if (BRep_Tool::Degenerated(anEdge))
548 Standard_Real aF, aL;
549 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(anEdge, Face, aF, aL);
551 gp_Pnt2d aFPnt2d = c2d->Value(aF),
552 aLPnt2d = c2d->Value(aL);
554 gp_Pnt aFPnt = S->Value(aFPnt2d.X(), aFPnt2d.Y()),
555 aLPnt = S->Value(aLPnt2d.X(), aLPnt2d.Y());
557 // aFPnt.SquareDistance(aLPnt) > Precision::SquareConfusion() -
558 // is a sufficient condition of troubles: non-singular case, but edge is degenerated.
559 // So, normal handling of degenerated edges is not applicable in case of non-singular point.
560 if (aFPnt.SquareDistance(aLPnt) < Precision::SquareConfusion())
562 DegEdges.Append(anEdge);
566 if (!DegEdges.IsEmpty())
568 const Standard_Real TolApex = 1.e-5;
569 //define the iso of singularity (u or v)
570 TopoDS_Edge theDegEdge = TopoDS::Edge(DegEdges(1));
571 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
572 gp_Pnt2d fp2d = aCurve->Value(fpar);
573 gp_Pnt2d lp2d = aCurve->Value(lpar);
574 if (Abs(fp2d.X() - lp2d.X()) <= Precision::PConfusion())
575 UisoDegen = Standard_True;
577 if (DegEdges.Length() == 2)
580 { UminDegen = Standard_True; UmaxDegen = Standard_True; }
582 { VminDegen = Standard_True; VmaxDegen = Standard_True; }
584 else //DegEdges.Length() == 1
588 if (Abs(fp2d.X() - uf1) <= Precision::Confusion())
589 UminDegen = Standard_True;
591 UmaxDegen = Standard_True;
595 if (Abs(fp2d.Y() - vf1) <= Precision::Confusion())
596 VminDegen = Standard_True;
598 VmaxDegen = Standard_True;
601 if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
603 gp_Cone theCone = Handle(Geom_ConicalSurface)::DownCast (TheSurf)->Cone();
604 gp_Pnt apex = theCone.Apex();
605 Standard_Real Uapex, Vapex;
606 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
609 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, Vapex, vf2);
611 HasSingularity = Standard_True;
615 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, Vapex);
617 HasSingularity = Standard_True;
620 else //TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)
624 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
625 if (BRepOffset_Tool::Gabarit( uiso ) > TolApex)
627 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (TheSurf)->BasisSurface();
628 gp_Pnt Papex, Pfirst, Pquart, Pmid;
629 Papex = BasisSurf->Value( uf1, vf1 );
630 Pfirst = TheSurf->Value( uf1, vf1 );
631 Pquart = TheSurf->Value( uf1, 0.75*vf1+0.25*vf2 );
632 Pmid = TheSurf->Value( uf1, 0.5*(vf1+vf2) );
633 gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
634 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
635 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 1, 0 );
636 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
637 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
639 theExtrema.NearestPoints(Pint1, Pint2);
640 Standard_Real length = Pfirst.Distance(Pint1);
643 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
644 GeomLib::ExtendSurfByLength (aSurf, length, 1, Standard_True, Standard_False);
646 Standard_Real u1, u2, v1, v2;
647 TheSurf->Bounds( u1, u2, v1, v2 );
648 MinApex = TheSurf->Value( u1, vf1 );
652 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
653 GeomAPI_ProjectPointOnCurve Projector( Pint1, viso );
654 Standard_Real NewFirstU = Projector.LowerDistanceParameter();
655 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, NewFirstU, uf2, vf1, vf2);
656 MinApex = TheSurf->Value( NewFirstU, vf1 );
658 HasSingularity = Standard_True;
660 } //end of if (UminDegen)
663 Handle(Geom_Curve) uiso = TheSurf->UIso( uf2 );
664 if (BRepOffset_Tool::Gabarit( uiso ) > TolApex)
666 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (TheSurf)->BasisSurface();
667 gp_Pnt Papex, Pfirst, Pquart, Pmid;
668 Papex = BasisSurf->Value( uf2, vf1 );
669 Pfirst = TheSurf->Value( uf2, vf1 );
670 Pquart = TheSurf->Value( uf2, 0.75*vf1+0.25*vf2 );
671 Pmid = TheSurf->Value( uf2, 0.5*(vf1+vf2) );
672 gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
673 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
674 gp_Vec DirGeneratrix = BasisSurf->DN( uf2, vf1, 1, 0 );
675 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
676 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
678 theExtrema.NearestPoints(Pint1, Pint2);
679 Standard_Real length = Pfirst.Distance(Pint1);
682 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
683 GeomLib::ExtendSurfByLength(aSurf, length, 1, Standard_True, Standard_True);
685 Standard_Real u1, u2, v1, v2;
686 TheSurf->Bounds( u1, u2, v1, v2 );
687 MaxApex = TheSurf->Value( u2, vf1 );
691 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
692 GeomAPI_ProjectPointOnCurve Projector( Pint1, viso );
693 Standard_Real NewLastU = Projector.LowerDistanceParameter();
694 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, NewLastU, vf1, vf2);
695 MaxApex = TheSurf->Value( NewLastU, vf1 );
697 HasSingularity = Standard_True;
699 } //end of if (UmaxDegen)
702 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
703 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
705 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (TheSurf)->BasisSurface();
706 gp_Pnt Papex, Pfirst, Pquart, Pmid;
707 Papex = BasisSurf->Value( uf1, vf1 );
708 Pfirst = TheSurf->Value( uf1, vf1 );
709 Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf1 );
710 Pmid = TheSurf->Value( 0.5*(uf1+uf2), vf1 );
711 gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
712 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
713 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
714 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
715 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
717 theExtrema.NearestPoints(Pint1, Pint2);
718 Standard_Real length = Pfirst.Distance(Pint1);
721 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
722 GeomLib::ExtendSurfByLength(aSurf, length, 1, Standard_False, Standard_False);
724 Standard_Real u1, u2, v1, v2;
725 TheSurf->Bounds( u1, u2, v1, v2 );
726 MinApex = TheSurf->Value( uf1, v1 );
730 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
731 GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
732 Standard_Real NewFirstV = Projector.LowerDistanceParameter();
733 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2);
734 MinApex = TheSurf->Value( uf1, NewFirstV );
735 //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2);
736 //MinApex = TheSurf->Value( uf1, vf1+length );
738 HasSingularity = Standard_True;
740 } //end of if (VminDegen)
743 Handle(Geom_Curve) viso = TheSurf->VIso( vf2 );
744 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
746 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (TheSurf)->BasisSurface();
747 gp_Pnt Papex, Pfirst, Pquart, Pmid;
748 Papex = BasisSurf->Value( uf1, vf2 );
749 Pfirst = TheSurf->Value( uf1, vf2 );
750 Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf2 );
751 Pmid = TheSurf->Value( 0.5*(uf1+uf2), vf2 );
752 gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
753 Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
754 gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
755 Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
756 GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
758 theExtrema.NearestPoints(Pint1, Pint2);
759 Standard_Real length = Pfirst.Distance(Pint1);
762 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
763 GeomLib::ExtendSurfByLength(aSurf, length, 1, Standard_False, Standard_True);
765 Standard_Real u1, u2, v1, v2;
766 TheSurf->Bounds( u1, u2, v1, v2 );
767 MaxApex = TheSurf->Value( uf1, v2 );
771 Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
772 GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
773 Standard_Real NewLastV = Projector.LowerDistanceParameter();
774 TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV);
775 MaxApex = TheSurf->Value( uf1, NewLastV );
776 //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length);
777 //MaxApex = TheSurf->Value( uf1, vf2-length );
779 HasSingularity = Standard_True;
781 } //end of if (VmaxDegen)
782 } //end of else (case of Geom_OffsetSurface)
783 } //end of if (!DegEdges.IsEmpty())
784 } //end of processing offsets of faces with possible degenerated edges
786 // find the PCurves of the edges of <Faces>
788 BRep_Builder myBuilder;
789 myBuilder.MakeFace(myFace);
791 myBuilder.UpdateFace(myFace,TheSurf, L, BRep_Tool::Tolerance(Face));
793 myBuilder.UpdateFace(myFace,TheSurf, TopLoc_Location(), BRep_Tool::Tolerance(Face));
795 TopTools_DataMapOfShapeShape MapSS;
797 // mise a jour de la map sur les vertex deja crees
798 TopoDS_Shape aLocalShapeOriented = Face.Oriented(TopAbs_FORWARD);
799 TopoDS_Face CurFace = TopoDS::Face(aLocalShapeOriented);
800 // TopoDS_Face CurFace = TopoDS::Face(Face.Oriented(TopAbs_FORWARD));
802 TopTools_MapOfShape VonDegen;
803 Standard_Real u1, u2, v1, v2;
804 TheSurf->Bounds( u1, u2, v1, v2 );
806 TopExp_Explorer exp(CurFace, TopAbs_EDGE);
807 for ( ; exp.More(); exp.Next()) {
808 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
809 TopoDS_Vertex V1,V2,OV1,OV2;
810 TopExp::Vertices(E ,V1 ,V2 );
811 if (HasSingularity && BRep_Tool::Degenerated(E))
813 if (Created.IsBound(E)) {
814 const TopoDS_Edge& OE = TopoDS::Edge(Created(E));
815 TopExp::Vertices(OE,OV1,OV2);
816 if (!MapSS.IsBound(V1)) MapSS.Bind(V1,OV1);
817 if (!MapSS.IsBound(V2)) MapSS.Bind(V2,OV2);
819 if (Created.IsBound(V1)) {
820 if (!MapSS.IsBound(V1)) MapSS.Bind(V1,Created(V1));
822 if (Created.IsBound(V2)) {
823 if (!MapSS.IsBound(V2)) MapSS.Bind(V2,Created(V2));
827 TopExp_Explorer expw(CurFace, TopAbs_WIRE);
828 for ( ; expw.More(); expw.Next()) {
829 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
830 TopExp_Explorer expe(W.Oriented(TopAbs_FORWARD),
833 myBuilder.MakeWire(OW);
834 for ( ; expe.More(); expe.Next()) {
835 const TopoDS_Edge& E = TopoDS::Edge(expe.Current());
837 TopExp::Vertices(E,V1,V2);
840 Standard_Real vstart, vend;
842 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,CurFace,f,l);
844 if (MapSS.IsBound(E) &&
845 !VonDegen.Contains(V1) && !VonDegen.Contains(V2)) { // c`est un edge de couture
846 OE = TopoDS::Edge(MapSS(E));
847 TopoDS_Shape aLocalShape = E.Reversed();
848 Handle(Geom2d_Curve) C2d_1 =
849 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),CurFace,f,l);
850 // Handle(Geom2d_Curve) C2d_1 =
851 // BRep_Tool::CurveOnSurface(TopoDS::Edge(E.Reversed()),CurFace,f,l);
852 if ( E.Orientation() == TopAbs_FORWARD)
853 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
855 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
856 myBuilder.Range(OE,f,l);
859 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
860 TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
861 P2d1 = C2d->Value(BRep_Tool::Parameter(V1,Eforward,CurFace));
862 P2d2 = C2d->Value(BRep_Tool::Parameter(V2,Eforward,CurFace));
863 if (VonDegen.Contains(V1))
865 if (Abs(P2d1.Y() - vf1) <= Precision::Confusion())
867 P1 = MinApex; vstart = v1;
871 P1 = MaxApex; vstart = v2;
876 TheSurf->D0(P2d1.X(),P2d1.Y(),P1);
877 if (!L.IsIdentity() && !IsTransformed)
878 P1.Transform(L.Transformation());
881 if (VonDegen.Contains(V2))
883 if (Abs(P2d2.Y() - vf1) <= Precision::Confusion())
885 P2 = MinApex; vend = v1;
889 P2 = MaxApex; vend = v2;
894 TheSurf->D0(P2d2.X(),P2d2.Y(),P2);
895 if (!L.IsIdentity() && !IsTransformed)
896 P2.Transform(L.Transformation());
899 // E a-t-il ume image dans la Map des Created ?
900 if ( Created.IsBound(E)) {
901 OE = TopoDS::Edge(Created(E));
903 else if (MapSS.IsBound(E)) //seam edge
904 OE = TopoDS::Edge(MapSS(E));
906 myBuilder.MakeEdge(OE);
907 TopoDS_Vertex OV1,OV2;
908 if ( MapSS.IsBound(V1)) {
909 OV1 = TopoDS::Vertex(MapSS(V1));
912 myBuilder.MakeVertex(OV1);
913 myBuilder.UpdateVertex(OV1,P1,BRep_Tool::Tolerance(V1));
916 if ( MapSS.IsBound(V2)) {
917 OV2 = TopoDS::Vertex(MapSS(V2));
920 myBuilder.MakeVertex(OV2);
921 myBuilder.UpdateVertex(OV2,P2,BRep_Tool::Tolerance(V2));
924 myBuilder.Add(OE,OV1.Oriented(V1.Orientation()));
925 myBuilder.Add(OE,OV2.Oriented(V2.Orientation()));
926 if (BRep_Tool::Degenerated(E)) {
927 myBuilder.Degenerated(OE, Standard_True);
932 P2d = C2d->Value(f); TheSurf->D0(P2d.X(),P2d.Y(),P1);
933 P2d = C2d->Value(l); TheSurf->D0(P2d.X(),P2d.Y(),P2);
934 Standard_Real Tol = BRep_Tool::Tolerance(V1);
935 if (!P1.IsEqual(P2,Tol)) {
936 std::cout <<"BRepOffset_Offset : E degenerated -> OE not degenerated"<<std::endl;
942 if (VonDegen.Contains(V1) || VonDegen.Contains(V2))
944 if (VonDegen.Contains(V1))
946 if (VonDegen.Contains(V2))
948 C2d = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) );
949 f = 0.; l = P2d1.Distance( P2d2 );
950 if (MapSS.IsBound(E)) //seam edge
952 Handle(Geom2d_Curve) C2d_1 = BRep_Tool::CurveOnSurface(OE, myFace, f, l);
953 if (E.Orientation() == TopAbs_FORWARD)
954 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
956 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
959 UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E));
960 //myBuilder.Range(OE,f,l);
961 myBuilder.Range(OE, myFace, f, l);
962 if (!BRep_Tool::Degenerated(E) && TheSurf->IsUClosed())
964 TopoDS_Shape aLocalShapeReversedE = E.Reversed();
965 Handle(Geom2d_Curve) C2d_1 =
966 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShapeReversedE),CurFace,f,l);
967 P2d1 = C2d_1->Value(BRep_Tool::Parameter(V1,E,CurFace));
968 P2d2 = C2d_1->Value(BRep_Tool::Parameter(V2,E,CurFace));
969 if (VonDegen.Contains(V1))
971 if (VonDegen.Contains(V2))
973 C2d_1 = new Geom2d_Line( P2d1, gp_Vec2d(P2d1, P2d2) );
974 if ( E.Orientation() == TopAbs_FORWARD)
975 UpdateEdge(OE,C2d,C2d_1,myFace,BRep_Tool::Tolerance(E));
977 UpdateEdge(OE,C2d_1,C2d,myFace,BRep_Tool::Tolerance(E));
980 if (!BRep_Tool::Degenerated(E))
982 Handle(Geom_Line) theLine = new Geom_Line( P1, gp_Vec(P1, P2) );
983 myBuilder.UpdateEdge( OE, theLine, BRep_Tool::Tolerance(E) );
989 UpdateEdge(OE,C2d,myFace,BRep_Tool::Tolerance(E));
990 myBuilder.Range(OE,f,l);
991 //ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
993 if (!BRep_Tool::Degenerated(OE))
994 ComputeCurve3d(OE,C2d,TheSurf,L,BRep_Tool::Tolerance(E));
997 myBuilder.Add(OW, OE.Oriented(E.Orientation()));
999 myBuilder.Add(myFace, OW.Oriented(W.Orientation()));
1002 myFace.Orientation(Face.Orientation());
1004 BRepTools::Update(myFace);
1008 //=======================================================================
1011 //=======================================================================
1013 void BRepOffset_Offset::Init(const TopoDS_Edge& Path,
1014 const TopoDS_Edge& Edge1,
1015 const TopoDS_Edge& Edge2,
1016 const Standard_Real Offset,
1017 const Standard_Boolean Polynomial,
1018 const Standard_Real Tol,
1019 const GeomAbs_Shape Conti)
1021 TopoDS_Edge FirstEdge,LastEdge;
1022 Init(Path,Edge1,Edge2,Offset,FirstEdge,LastEdge,Polynomial,Tol,Conti);
1026 //=======================================================================
1029 //=======================================================================
1031 void BRepOffset_Offset::Init(const TopoDS_Edge& Path,
1032 const TopoDS_Edge& Edge1,
1033 const TopoDS_Edge& Edge2,
1034 const Standard_Real Offset,
1035 const TopoDS_Edge& FirstEdge,
1036 const TopoDS_Edge& LastEdge,
1037 const Standard_Boolean Polynomial,
1038 const Standard_Real Tol,
1039 const GeomAbs_Shape Conti)
1041 Standard_Boolean C1Denerated = Standard_False;
1042 Standard_Boolean C2Denerated = Standard_False;
1043 myStatus = BRepOffset_Good;
1046 TopLoc_Location Loc;
1047 Standard_Real f[3],l[3];
1049 Handle(Geom_Curve) CP = BRep_Tool::Curve(Path,Loc,f[0],l[0]);
1050 CP = new Geom_TrimmedCurve(CP,f[0], l[0]);
1051 CP->Transform(Loc.Transformation());
1052 Handle(GeomAdaptor_Curve) HCP = new GeomAdaptor_Curve(CP);
1054 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,Loc,f[1],l[1]);
1056 Handle(Adaptor3d_Curve) HEdge1;
1057 Standard_Boolean C1is3D = Standard_True;
1059 C1is3D = Standard_False;
1060 Handle(Geom2d_Curve) C12d;
1061 Handle(Geom_Surface) S1;
1062 BRep_Tool::CurveOnSurface(Edge1,C12d,S1,Loc,f[1],l[1]);
1063 S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation()));
1064 C12d = new Geom2d_TrimmedCurve(C12d,f[1],l[1]);
1065 Handle(GeomAdaptor_Surface) HS1 = new GeomAdaptor_Surface(S1);
1066 Handle(Geom2dAdaptor_Curve) HC1 = new Geom2dAdaptor_Curve(C12d);
1067 Adaptor3d_CurveOnSurface Cons(HC1,HS1);
1068 HEdge1 = new Adaptor3d_CurveOnSurface(Cons);
1071 C1 = new Geom_TrimmedCurve(C1, f[1], l[1]);
1072 C1->Transform(Loc.Transformation());
1073 HEdge1 = new GeomAdaptor_Curve(C1);
1074 GeomAdaptor_Curve AC1(C1);
1075 if ( AC1.GetType() == GeomAbs_Circle) {
1076 C1Denerated = (AC1.Circle().Radius() < Precision::Confusion());
1080 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,Loc,f[2],l[2]);
1082 Handle(Adaptor3d_Curve) HEdge2;
1083 Standard_Boolean C2is3D = Standard_True;
1085 C2is3D = Standard_False;
1086 Handle(Geom2d_Curve) C12d;
1087 Handle(Geom_Surface) S1;
1088 BRep_Tool::CurveOnSurface(Edge2,C12d,S1,Loc,f[2],l[2]);
1089 S1 = Handle(Geom_Surface)::DownCast(S1->Transformed(Loc.Transformation()));
1090 C12d = new Geom2d_TrimmedCurve(C12d,f[2],l[2]);
1091 Handle(GeomAdaptor_Surface) HS1 = new GeomAdaptor_Surface(S1);
1092 Handle(Geom2dAdaptor_Curve) HC1 = new Geom2dAdaptor_Curve(C12d);
1093 Adaptor3d_CurveOnSurface Cons(HC1,HS1);
1094 HEdge2 = new Adaptor3d_CurveOnSurface(Cons);
1097 C2 = new Geom_TrimmedCurve(C2, f[2], l[2]);
1098 C2->Transform(Loc.Transformation());
1099 HEdge2 = new GeomAdaptor_Curve(C2);
1100 GeomAdaptor_Curve AC2(C2);
1101 if ( AC2.GetType() == GeomAbs_Circle) {
1102 C2Denerated = (AC2.Circle().Radius() < Precision::Confusion());
1107 GeomFill_Pipe Pipe(HCP, HEdge1, HEdge2, Abs(Offset));
1108 Pipe.Perform(Tol, Polynomial, Conti);
1110 throw Standard_ConstructionError("GeomFill_Pipe : Cannot make a surface");
1111 Standard_Real ErrorPipe = Pipe.ErrorOnSurf();
1113 Handle(Geom_Surface) S = Pipe.Surface();
1114 Standard_Boolean ExchUV = Pipe.ExchangeUV();
1115 Standard_Real f1,l1,f2,l2;
1116 S->Bounds(f1,l1,f2,l2);
1119 Standard_Real PathTol = BRep_Tool::Tolerance(Path);
1120 Standard_Real TheTol;
1121 BRep_Builder myBuilder;
1122 myBuilder.MakeFace(myFace);
1124 myBuilder.UpdateFace(myFace,S,Id,PathTol);
1126 // update de Edge1. (Rem : has already a 3d curve)
1127 Standard_Real U,U1,U2;
1128 Handle(Geom2d_Curve) PC;
1130 PC = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1133 if (!C1is3D) C1 = S->VIso(f2);
1136 PC = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1139 if (!C1is3D) C1 = S->UIso(f1);
1142 Handle(Geom_Curve) Dummy;
1144 UpdateEdge(Edge1,C1,Id,BRep_Tool::Tolerance(Edge1));
1145 else if ( C1Denerated) {
1146 UpdateEdge(Edge1,Dummy,Id,BRep_Tool::Tolerance(Edge1));
1147 myBuilder.Degenerated(Edge1,Standard_True);
1150 TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge1) + ErrorPipe);
1151 UpdateEdge(Edge1, PC, myFace, TheTol);
1153 // mise a same range de la nouvelle pcurve.
1154 if ( !C1is3D && !C1Denerated)
1156 myBuilder.SameRange (Edge1,Standard_False);
1157 myBuilder.Range(Edge1,U1,U2, Standard_True);
1159 myBuilder.Range(Edge1,myFace,U1,U2);
1160 BRepLib::SameRange(Edge1);
1162 // mise a sameparameter pour les KPart
1163 if (ErrorPipe == 0) {
1164 TheTol = Max(TheTol, Tol);
1165 myBuilder.SameParameter(Edge1,Standard_False);
1166 BRepLib::SameParameter(Edge1, TheTol);
1169 // Update de edge2. (Rem : has already a 3d curve)
1171 PC = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1174 if (!C2is3D) C2 = S->VIso(l2);
1177 PC = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1180 if (!C2is3D) C2 = S->UIso(l1);
1184 UpdateEdge(Edge2,C2,Id,BRep_Tool::Tolerance(Edge2));
1185 else if ( C2Denerated) {
1186 UpdateEdge(Edge2,Dummy,Id,BRep_Tool::Tolerance(Edge2));
1187 myBuilder.Degenerated(Edge2,Standard_True);
1190 TheTol = Max(PathTol, BRep_Tool::Tolerance(Edge2) + ErrorPipe);
1191 UpdateEdge(Edge2, PC, myFace, TheTol);
1193 // mise a same range de la nouvelle pcurve.
1194 myBuilder.SameRange (Edge2,Standard_False);
1195 if ( !C2is3D && !C2Denerated)
1196 myBuilder.Range(Edge2, U1, U2, Standard_True);
1197 myBuilder.Range(Edge2,myFace,U1,U2);
1198 BRepLib::SameRange(Edge2);
1200 // mise a sameparameter pour les KPart
1201 if (ErrorPipe == 0) {
1202 TheTol = Max(TheTol, Tol);
1203 myBuilder.SameParameter(Edge2,Standard_False);
1204 BRepLib::SameParameter(Edge2, TheTol);
1207 TopoDS_Edge Edge3, Edge4;
1209 TopoDS_Vertex V1f,V1l,V2f,V2l;
1210 TopExp::Vertices(Path,V1f,V1l);
1211 Standard_Boolean IsClosed = ( V1f.IsSame(V1l));
1213 TopExp::Vertices(Edge1,V1f,V1l);
1214 TopExp::Vertices(Edge2,V2f,V2l);
1216 Standard_Boolean StartDegenerated = (V1f.IsSame(V2f));
1217 Standard_Boolean EndDegenerated = (V1l.IsSame(V2l));
1219 Standard_Boolean E3rev = Standard_False;
1220 Standard_Boolean E4rev = Standard_False;
1222 TopoDS_Vertex VVf,VVl;
1223 if ( FirstEdge.IsNull()) {
1224 myBuilder.MakeEdge(Edge3);
1225 myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD));
1226 myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED));
1229 TopoDS_Shape aLocalEdge = FirstEdge.Oriented(TopAbs_FORWARD);
1230 Edge3 = TopoDS::Edge(aLocalEdge);
1231 // Edge3 = TopoDS::Edge(FirstEdge.Oriented(TopAbs_FORWARD));
1232 TopExp::Vertices(Edge3,VVf,VVl);
1234 // si firstedge n est pas nul, il faut que les vertex soient partages
1235 if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) {
1236 std::cout << "Attention Vertex non partages !!!!!!" << std::endl;
1239 if ( !VVf.IsSame(V1f) && !VVf.IsSame(V2f) ) {
1240 // On fait vraisemblablement des conneries !!
1241 // On cree un autre edge, on appelle le Sewing apres.
1242 myBuilder.MakeEdge(Edge3);
1243 myBuilder.Add(Edge3,V1f.Oriented(TopAbs_FORWARD));
1244 myBuilder.Add(Edge3,V2f.Oriented(TopAbs_REVERSED));
1246 else if ( !VVf.IsSame(V1f)) {
1248 E3rev = Standard_True;
1255 Standard_Real TolApp = Precision::Approximation();
1257 Handle(Geom2d_Line) L1,L2;
1260 // rem : si ExchUv, il faut reverser le Wire.
1261 // donc l'edge Forward dans la face sera E4 : d'ou L1 et L2
1262 L2 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1263 L1 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1268 L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1269 L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1274 L1->Reverse(); L2->Reverse();
1279 UpdateEdge(Edge3, L1, L2, myFace,PathTol);
1280 myBuilder.Range(Edge3,myFace,U1,U2);
1281 if (StartDegenerated)
1282 myBuilder.Degenerated(Edge3,Standard_True);
1283 else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed
1284 ComputeCurve3d(Edge3,L1,S,Id,TolApp);
1287 if ( LastEdge.IsNull()) {
1288 myBuilder.MakeEdge(Edge4);
1289 myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD));
1290 myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED));
1293 TopoDS_Shape aLocalEdge = LastEdge.Oriented(TopAbs_FORWARD);
1294 Edge4 = TopoDS::Edge(aLocalEdge);
1295 // Edge4 = TopoDS::Edge(LastEdge.Oriented(TopAbs_FORWARD));
1296 TopExp::Vertices(Edge4,VVf,VVl);
1298 // si lastedge n est pas nul, il faut que les vertex soient partages
1299 if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) {
1300 std::cout << "Attention Vertex non partages !!!!!!" << std::endl;
1303 if ( !VVf.IsSame(V1l) && !VVf.IsSame(V2l) ) {
1304 // On fait vraisemblablement des conneries !!
1305 // On cree un autre edge, on appelle le Sewing apres.
1306 myBuilder.MakeEdge(Edge4);
1307 myBuilder.Add(Edge4,V1l.Oriented(TopAbs_FORWARD));
1308 myBuilder.Add(Edge4,V2l.Oriented(TopAbs_REVERSED));
1310 else if ( !VVf.IsSame(V1l)) {
1312 E4rev = Standard_True;
1317 L1 = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
1322 L1 = new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0));
1332 UpdateEdge(Edge3,L1,myFace,PathTol);
1333 myBuilder.Range(Edge3,myFace,U1,U2);
1334 if (StartDegenerated)
1335 myBuilder.Degenerated(Edge3,Standard_True);
1336 else if (FirstEdge.IsNull()) // then the 3d curve has not been yet computed
1337 ComputeCurve3d(Edge3,L1,S,Id,TolApp);
1340 L2 = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
1345 L2 = new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0));
1355 UpdateEdge(Edge4,L2 ,myFace,PathTol);
1356 myBuilder.Range(Edge4,myFace,U1,U2);
1358 myBuilder.Degenerated(Edge4,Standard_True);
1359 else if (LastEdge.IsNull()) // then the 3d curve has not been yet computed
1360 ComputeCurve3d(Edge4,L2,S,Id,TolApp);
1364 if ( !FirstEdge.IsNull() && !StartDegenerated) {
1365 BRepLib::BuildCurve3d (Edge3,PathTol);
1366 myBuilder.SameRange (Edge3,Standard_False);
1367 myBuilder.SameParameter(Edge3,Standard_False);
1368 BRepLib::SameParameter (Edge3, Tol);
1370 if ( !LastEdge.IsNull() && !EndDegenerated) {
1371 BRepLib::BuildCurve3d (Edge4,PathTol);
1372 myBuilder.SameRange (Edge4,Standard_False);
1373 myBuilder.SameParameter(Edge4,Standard_False);
1374 BRepLib::SameParameter (Edge4, Tol);
1378 myBuilder.MakeWire(W);
1380 myBuilder.Add(W, Edge1.Oriented(TopAbs_REVERSED));
1381 myBuilder.Add(W, Edge2.Oriented(TopAbs_FORWARD));
1382 myBuilder.Add(W, Edge4.Reversed());
1383 myBuilder.Add(W, Edge3);
1389 myBuilder.Add(myFace, W);
1390 if (ExchUV) myFace.Reverse();
1392 BRepTools::Update(myFace);
1394 if ( Edge1.Orientation() == TopAbs_REVERSED)
1400 //=======================================================================
1403 //=======================================================================
1405 void BRepOffset_Offset::Init(const TopoDS_Vertex& Vertex,
1406 const TopTools_ListOfShape& LEdge,
1407 const Standard_Real Offset,
1408 const Standard_Boolean Polynomial,
1409 const Standard_Real TolApp,
1410 const GeomAbs_Shape Conti)
1412 myStatus = BRepOffset_Good;
1415 // evaluate the Ax3 of the Sphere
1416 // find 3 different vertices in LEdge
1417 TopTools_ListIteratorOfListOfShape it;
1418 gp_Pnt P, P1, P2, P3;
1419 TopoDS_Vertex V1, V2, V3, V4;
1423 char* name = new char[100];
1427 sprintf(name,"VOnSph_%d",NbOFFSET);
1429 DBRep::Set(name, Vertex);
1431 Standard_Integer NbEdges = 1;
1432 for (it.Initialize(LEdge); it.More(); it.Next()) {
1433 sprintf(name,"EOnSph_%d_%d",NbOFFSET,NbEdges++);
1435 const TopoDS_Shape& CurE = it.Value();
1436 DBRep::Set(name, CurE);
1443 gp_Pnt Origin = BRep_Tool::Pnt(Vertex);
1445 //// Find the axis of the sphere to exclude
1446 //// degenerated and seam edges from the face under construction
1447 BRepLib_MakeWire MW;
1449 TopoDS_Wire theWire = MW.Wire();
1451 ShapeFix_Shape Fixer(theWire);
1453 theWire = TopoDS::Wire(Fixer.Shape());
1455 GProp_GProps GlobalProps;
1456 BRepGProp::LinearProperties(theWire, GlobalProps);
1457 gp_Pnt BaryCenter = GlobalProps.CentreOfMass();
1458 gp_Vec Xdir(BaryCenter, Origin);
1460 gp_Pnt FarestCorner = GetFarestCorner(theWire);
1461 gp_Pln thePlane = gce_MakePln(Origin, BaryCenter, FarestCorner);
1462 gp_Dir Vdir = thePlane.Axis().Direction();
1464 gp_Ax3 Axis(Origin, Vdir, Xdir);
1466 Handle(Geom_Surface) S
1467 = new Geom_SphericalSurface( Axis, Abs(Offset));
1469 Standard_Real f, l, Tol = BRep_Tool::Tolerance(Vertex);
1471 TopLoc_Location Loc;
1472 BRep_Builder myBuilder;
1473 myBuilder.MakeFace(myFace);
1474 Handle(Geom_Surface) SS = S;
1476 // En polynomial, calcul de la surface par F(u,v).
1477 // Pas de changement de parametre, donc ProjLib sur la Sphere
1480 GeomConvert_ApproxSurface Approx(S,TolApp,Conti,Conti,10,10,10,1);
1481 if (Approx.IsDone()) {
1482 SS = Approx.Surface();
1486 myBuilder.UpdateFace(myFace, SS, Loc, Tol);
1489 myBuilder.MakeWire(W);
1495 sprintf(name,"SPHERE_%d",NbOFFSET);
1496 DrawTrSurf::Set(name, S);
1498 Standard_Integer CO = 1;
1501 for ( it.Initialize(LEdge); it.More(); it.Next()) {
1502 TopoDS_Edge E = TopoDS::Edge(it.Value());
1504 Handle(Geom_Curve) C = BRep_Tool::Curve(E,Loc,f,l);
1506 BRepLib::BuildCurve3d(E,BRep_Tool::Tolerance(E));
1507 C = BRep_Tool::Curve(E,Loc,f,l);
1509 C = new Geom_TrimmedCurve(C, f, l);
1510 C->Transform(Loc.Transformation());
1514 sprintf(name,"CURVE_%d_%d",NbOFFSET,CO);
1515 DrawTrSurf::Set(name, C);
1520 Handle(Geom2d_Curve) PCurve = GeomProjLib::Curve2d(C, S);
1521 // check if the first point of PCurve in is the canonical boundaries
1522 // of the sphere. Else move it.
1523 // the transformation is : U` = U + PI + 2 k PI
1524 // V` = +/- PI + 2 k` PI
1525 gp_Pnt2d P2d = PCurve->Value(f);
1526 Standard_Boolean IsToAdjust = Standard_False;
1527 if ( P2d.Y() < -M_PI/2.) {
1528 IsToAdjust = Standard_True;
1529 PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0.,-M_PI/2.),gp::DX2d()));
1531 else if ( P2d.Y() > M_PI/2.) {
1532 IsToAdjust = Standard_True;
1533 PCurve->Mirror(gp_Ax2d(gp_Pnt2d(0., M_PI/2.),gp::DX2d()));
1536 // set the u firstpoint in [0,2*pi]
1537 gp_Vec2d Tr( M_PI, 0.);
1538 if ( P2d.X() > M_PI) Tr.Reverse();
1539 PCurve->Translate(Tr);
1542 UpdateEdge(E, PCurve, myFace, Tol);
1543 myBuilder.Range(E, myFace, f, l);
1544 myBuilder.Add(W, E);
1547 myBuilder.Add(myFace, W.Oriented(TopAbs_REVERSED));
1551 myBuilder.Add(myFace, W);
1554 BRepTools::Update(myFace);
1558 //=======================================================================
1561 //=======================================================================
1563 void BRepOffset_Offset::Init(const TopoDS_Edge& Edge,
1564 const Standard_Real Offset)
1567 Standard_Real myOffset = Abs(Offset);
1570 TopLoc_Location Loc;
1572 Handle(Geom_Curve) CP = BRep_Tool::Curve(Edge,Loc,f,l);
1573 CP = new Geom_TrimmedCurve(CP,f,l);
1574 CP->Transform(Loc.Transformation());
1576 GeomFill_Pipe Pipe(CP,myOffset);
1579 throw Standard_ConstructionError("GeomFill_Pipe : Cannot make a surface");
1581 BRepLib_MakeFace MF(Pipe.Surface(), Precision::Confusion());
1584 if ( Offset < 0.) myFace.Reverse();
1588 //=======================================================================
1591 //=======================================================================
1593 const TopoDS_Face& BRepOffset_Offset::Face() const
1599 //=======================================================================
1600 //function : Generated
1602 //=======================================================================
1604 TopoDS_Shape BRepOffset_Offset::Generated(const TopoDS_Shape& Shape) const
1606 TopoDS_Shape aShape;
1608 switch ( myShape.ShapeType())
1612 TopExp_Explorer exp (myShape.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1613 TopExp_Explorer expo (myFace .Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1614 for (; exp.More() && expo.More(); exp.Next(), expo.Next())
1616 if (Shape.IsSame (exp.Current()))
1618 if (myShape.Orientation() == TopAbs_REVERSED)
1619 aShape = expo.Current().Reversed();
1621 aShape = expo.Current();
1629 // have generate a pipe.
1631 TopoDS_Vertex V1, V2;
1632 TopExp::Vertices(TopoDS::Edge(myShape), V1, V2);
1634 TopExp_Explorer expf(myFace.Oriented(TopAbs_FORWARD), TopAbs_WIRE);
1635 TopExp_Explorer expo(expf.Current().Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1639 if ( V2.IsSame(Shape)) {
1640 if (expf.Current().Orientation() == TopAbs_REVERSED)
1641 aShape = expo.Current().Reversed();
1643 aShape = expo.Current();
1647 if (expf.Current().Orientation() == TopAbs_REVERSED)
1648 aShape = expo.Current().Reversed();
1650 aShape = expo.Current();
1652 if (myFace.Orientation() == TopAbs_REVERSED)
1664 //=======================================================================
1667 //=======================================================================
1669 BRepOffset_Status BRepOffset_Offset::Status() const