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