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