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