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