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