Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1998-01-07 |
2 | // Created by: Philippe MANGIN | |
3 | // Copyright (c) 1998-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_HCurveOnSurface.hxx> |
7fd59977 | 19 | #include <Approx_CurveOnSurface.hxx> |
20 | #include <Approx_SameParameter.hxx> | |
42cf5bc1 | 21 | #include <Bnd_Box.hxx> |
7fd59977 | 22 | #include <BRep_Builder.hxx> |
42cf5bc1 | 23 | #include <BRep_CurveRepresentation.hxx> |
24 | #include <BRep_GCurve.hxx> | |
7fd59977 | 25 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
26 | #include <BRep_TEdge.hxx> | |
42cf5bc1 | 27 | #include <BRep_Tool.hxx> |
7fd59977 | 28 | #include <BRep_TVertex.hxx> |
42cf5bc1 | 29 | #include <BRepAdaptor_HCurve.hxx> |
30 | #include <BRepAdaptor_HCurve2d.hxx> | |
31 | #include <BRepAdaptor_HSurface.hxx> | |
32 | #include <BRepBuilderAPI_MakeWire.hxx> | |
33 | #include <BRepCheck_Edge.hxx> | |
34 | #include <BRepFill_CurveConstraint.hxx> | |
35 | #include <BRepFill_LocationLaw.hxx> | |
36 | #include <BRepFill_SectionLaw.hxx> | |
37 | #include <BRepFill_Sweep.hxx> | |
38 | #include <BRepFill_TrimShellCorner.hxx> | |
7fd59977 | 39 | #include <BRepLib.hxx> |
42cf5bc1 | 40 | #include <BRepLib_FaceError.hxx> |
41 | #include <BRepLib_FindSurface.hxx> | |
7fd59977 | 42 | #include <BRepLib_MakeEdge.hxx> |
43 | #include <BRepLib_MakeFace.hxx> | |
42cf5bc1 | 44 | #include <BRepTools_Substitution.hxx> |
45 | #include <BRepTools_WireExplorer.hxx> | |
46 | #include <GCPnts_AbscissaPoint.hxx> | |
47 | #include <Geom2d_BSplineCurve.hxx> | |
48 | #include <Geom2d_Line.hxx> | |
49 | #include <Geom2d_TrimmedCurve.hxx> | |
50 | #include <Geom2dAdaptor_HCurve.hxx> | |
51 | #include <Geom_BezierCurve.hxx> | |
52 | #include <Geom_BSplineCurve.hxx> | |
53 | #include <Geom_Curve.hxx> | |
54 | #include <Geom_Plane.hxx> | |
55 | #include <Geom_RectangularTrimmedSurface.hxx> | |
56 | #include <Geom_Surface.hxx> | |
57 | #include <Geom_SurfaceOfRevolution.hxx> | |
58 | #include <GeomAdaptor_HCurve.hxx> | |
59 | #include <GeomAdaptor_HSurface.hxx> | |
60 | #include <GeomConvert_ApproxSurface.hxx> | |
61 | #include <GeomFill_LocationLaw.hxx> | |
62 | #include <GeomFill_SectionLaw.hxx> | |
63 | #include <GeomFill_Sweep.hxx> | |
64 | #include <GeomLib.hxx> | |
65 | #include <GeomLib_IsPlanarSurface.hxx> | |
66 | #include <gp_Pnt2d.hxx> | |
67 | #include <gp_Vec2d.hxx> | |
68 | #include <Precision.hxx> | |
69 | #include <Standard_ConstructionError.hxx> | |
70 | #include <Standard_OutOfRange.hxx> | |
71 | #include <StdFail_NotDone.hxx> | |
72 | #include <TColGeom_Array2OfSurface.hxx> | |
73 | #include <TColgp_Array1OfPnt.hxx> | |
74 | #include <TColStd_Array1OfBoolean.hxx> | |
75 | #include <TColStd_Array1OfReal.hxx> | |
dde68833 | 76 | #include <TColStd_Array2OfBoolean.hxx> |
42cf5bc1 | 77 | #include <TColStd_Array2OfInteger.hxx> |
78 | #include <TColStd_Array2OfReal.hxx> | |
79 | #include <TColStd_HArray1OfInteger.hxx> | |
80 | #include <TopAbs_Orientation.hxx> | |
81 | #include <TopExp.hxx> | |
82 | #include <TopExp_Explorer.hxx> | |
7fd59977 | 83 | #include <TopoDS.hxx> |
42cf5bc1 | 84 | #include <TopoDS_Compound.hxx> |
7fd59977 | 85 | #include <TopoDS_Edge.hxx> |
86 | #include <TopoDS_Face.hxx> | |
42cf5bc1 | 87 | #include <TopoDS_Iterator.hxx> |
88 | #include <TopoDS_Shape.hxx> | |
7fd59977 | 89 | #include <TopoDS_Shell.hxx> |
42cf5bc1 | 90 | #include <TopoDS_Wire.hxx> |
7fd59977 | 91 | #include <TopTools_Array1OfShape.hxx> |
92 | #include <TopTools_Array2OfShape.hxx> | |
42cf5bc1 | 93 | #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx> |
7fd59977 | 94 | #include <TopTools_HArray1OfShape.hxx> |
42cf5bc1 | 95 | #include <TopTools_HArray2OfShape.hxx> |
7fd59977 | 96 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
42cf5bc1 | 97 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
98 | #include <TopTools_ListOfShape.hxx> | |
99 | #include <TopTools_SequenceOfShape.hxx> | |
7fd59977 | 100 | |
42cf5bc1 | 101 | #include <stdio.h> |
102 | //#include <BRepFill_TrimCorner.hxx> | |
103 | // modified by NIZHNY-MKK Wed Oct 22 12:25:45 2003 | |
104 | //#include <GeomPlate_BuildPlateSurface.hxx> | |
105 | //#include <GeomPlate_Surface.hxx> | |
106 | //#include <GeomPlate_PointConstraint.hxx> | |
7fd59977 | 107 | //OCC500(apo) |
7fd59977 | 108 | #ifdef DRAW |
109 | #include <Draw.hxx> | |
110 | #include <DrawTrSurf.hxx> | |
111 | #include <DBRep.hxx> | |
ec357c5c | 112 | #include <Geom_BoundedSurface.hxx> |
7fd59977 | 113 | static Standard_Boolean Affich = 0; |
114 | #endif | |
115 | ||
116 | //======================================================================= | |
117 | //function : NumberOfPoles | |
118 | //purpose : | |
119 | //======================================================================= | |
120 | static Standard_Integer NumberOfPoles(const TopoDS_Wire& W) | |
121 | { | |
122 | Standard_Integer NbPoints = 0; | |
123 | ||
124 | TopoDS_Iterator iter(W); | |
125 | for (; iter.More(); iter.Next()) | |
126 | { | |
127 | BRepAdaptor_Curve c(TopoDS::Edge(iter.Value())); | |
128 | ||
129 | Standard_Real dfUf = c.FirstParameter(); | |
130 | Standard_Real dfUl = c.LastParameter(); | |
131 | if (IsEqual(dfUf,dfUl)) | |
132 | // Degenerate | |
133 | continue; | |
134 | ||
135 | switch (c.GetType()) | |
136 | { | |
137 | case GeomAbs_BezierCurve: | |
138 | { | |
139 | // Put all poles for bezier | |
140 | Handle(Geom_BezierCurve) GC = c.Bezier(); | |
141 | Standard_Integer iNbPol = GC->NbPoles(); | |
142 | if ( iNbPol >= 2) | |
143 | NbPoints += iNbPol; | |
144 | break; | |
145 | } | |
146 | case GeomAbs_BSplineCurve: | |
147 | { | |
148 | // Put all poles for bspline | |
149 | Handle(Geom_BSplineCurve) GC = c.BSpline(); | |
150 | Standard_Integer iNbPol = GC->NbPoles(); | |
151 | if ( iNbPol >= 2) | |
152 | NbPoints += iNbPol; | |
153 | break; | |
154 | } | |
155 | case GeomAbs_Line: | |
156 | { | |
157 | NbPoints += 2; | |
158 | break; | |
159 | } | |
160 | case GeomAbs_Circle: | |
161 | case GeomAbs_Ellipse: | |
162 | case GeomAbs_Hyperbola: | |
163 | case GeomAbs_Parabola: | |
164 | { | |
165 | NbPoints += 4; | |
166 | break; | |
167 | } | |
168 | default: | |
169 | NbPoints += 15 + c.NbIntervals(GeomAbs_C3); | |
170 | } // switch (c.GetType()) ... | |
171 | } // for (; iter.More(); iter.Next()) | |
172 | ||
173 | return NbPoints; | |
174 | } | |
175 | ||
176 | //======================================================================= | |
177 | //function : HasPCurves | |
178 | //purpose : | |
179 | //======================================================================= | |
180 | static Standard_Boolean HasPCurves(const TopoDS_Edge& E) | |
181 | { | |
182 | Standard_Boolean haspcurves = Standard_False; | |
183 | ||
184 | BRep_ListIteratorOfListOfCurveRepresentation itcr | |
185 | ((*((Handle(BRep_TEdge)*)&E.TShape()))->Curves()); | |
186 | for (; itcr.More(); itcr.Next()) | |
187 | { | |
188 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); | |
189 | if (cr->IsCurveOnSurface()) | |
190 | { | |
191 | haspcurves = Standard_True; | |
192 | break; | |
193 | } | |
194 | } | |
195 | return haspcurves; | |
196 | } | |
197 | ||
198 | //======================================================================= | |
199 | //function : Translate | |
0d969553 | 200 | //purpose : Copy a column from one table to another. |
7fd59977 | 201 | //======================================================================= |
202 | static void Translate(const Handle(TopTools_HArray2OfShape)& ArrayIn, | |
203 | const Standard_Integer In, | |
204 | Handle(TopTools_HArray2OfShape)& ArrayOut, | |
205 | const Standard_Integer Out) | |
206 | { | |
207 | Standard_Integer ii, Nb; | |
208 | Nb = ArrayOut->ColLength(); | |
209 | for (ii=1; ii<=Nb; ii++) { | |
210 | ArrayOut->SetValue(ii, Out, ArrayIn->Value(ii, In)); | |
211 | } | |
212 | } | |
213 | ||
214 | ||
215 | //======================================================================= | |
216 | //function : Box | |
0d969553 | 217 | //purpose : Bounding box of a section. |
7fd59977 | 218 | //======================================================================= |
219 | static void Box(Handle(GeomFill_SectionLaw)& Sec, | |
220 | const Standard_Real U, | |
221 | Bnd_Box& Box) | |
222 | ||
223 | { | |
224 | Standard_Integer NbPoles, bid; | |
225 | Box.SetVoid(); | |
226 | Sec->SectionShape(NbPoles, bid, bid); | |
227 | TColgp_Array1OfPnt Poles(1, NbPoles); | |
228 | TColStd_Array1OfReal W(1, NbPoles); | |
229 | Sec->D0(U, Poles, W); | |
230 | for (Standard_Integer ii=1; ii<=NbPoles; ii++) { | |
231 | Box.Add(Poles(ii)); | |
232 | } | |
233 | } | |
234 | ||
235 | //======================================================================= | |
236 | //function : Couture | |
0d969553 Y |
237 | //purpose : Check if E is an edge of sewing on S |
238 | // and make the representation HadHoc | |
7fd59977 | 239 | //======================================================================= |
240 | static Handle(Geom2d_Curve) Couture(const TopoDS_Edge& E, | |
241 | const Handle(Geom_Surface)& S, | |
242 | const TopLoc_Location& L) | |
243 | { | |
244 | TopLoc_Location l = L.Predivided(E.Location()); | |
245 | Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED); | |
246 | ||
247 | // find the representation | |
248 | BRep_ListIteratorOfListOfCurveRepresentation itcr | |
249 | ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves()); | |
250 | ||
251 | while (itcr.More()) { | |
252 | Handle(BRep_CurveRepresentation)& cr = itcr.Value(); | |
253 | if (cr->IsCurveOnSurface(S,l)) { | |
a1eb3afd | 254 | Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr)); |
7fd59977 | 255 | if (GC->IsCurveOnClosedSurface() && Eisreversed) |
256 | return GC->PCurve2(); | |
257 | else | |
258 | return GC->PCurve(); | |
259 | } | |
260 | itcr.Next(); | |
261 | } | |
262 | Handle(Geom2d_Curve) pc; | |
263 | pc.Nullify(); | |
264 | return pc; | |
265 | } | |
266 | ||
267 | //======================================================================= | |
268 | //function : CheckSameParameter | |
0d969553 | 269 | //purpose : Check a posteriori that sameparameter has worked correctly |
7fd59977 | 270 | //======================================================================= |
271 | ||
272 | static Standard_Boolean CheckSameParameter | |
273 | (const Handle(Adaptor3d_HCurve)& C3d, | |
471ce736 | 274 | const Handle(Geom2d_Curve)& Pcurv, |
7fd59977 | 275 | const Handle(Adaptor3d_HSurface)& S, |
276 | const Standard_Real tol3d, | |
277 | Standard_Real& tolreached) | |
278 | { | |
279 | tolreached = 0.; | |
280 | Standard_Real f = C3d->FirstParameter(); | |
281 | Standard_Real l = C3d->LastParameter(); | |
282 | Standard_Integer nbp = 45; | |
283 | Standard_Real step = 1./(nbp -1); | |
284 | for(Standard_Integer i = 0; i < nbp; i++){ | |
285 | Standard_Real t,u,v; | |
286 | t = step * i; | |
287 | t = (1-t) * f + t * l; | |
288 | Pcurv->Value(t).Coord(u,v); | |
289 | gp_Pnt pS = S->Value(u,v); | |
290 | gp_Pnt pC = C3d->Value(t); | |
291 | Standard_Real d2 = pS.SquareDistance(pC); | |
292 | tolreached = Max(tolreached,d2); | |
293 | } | |
294 | tolreached = sqrt(tolreached); | |
295 | if(tolreached > tol3d){ | |
296 | tolreached *= 2.; | |
297 | return Standard_False; | |
298 | } | |
299 | tolreached *= 2.; | |
300 | tolreached = Max(tolreached,Precision::Confusion()); | |
301 | return Standard_True; | |
302 | } | |
303 | ||
304 | //======================================================================= | |
305 | //function : SameParameter | |
0d969553 Y |
306 | //purpose : Encapsulation of Sameparameter |
307 | // Boolean informs if the pcurve was computed or not... | |
308 | // The tolerance is always OK. | |
7fd59977 | 309 | //======================================================================= |
310 | ||
311 | static Standard_Boolean SameParameter(TopoDS_Edge& E, | |
312 | Handle(Geom2d_Curve)& Pcurv, | |
313 | const Handle(Geom_Surface)& Surf, | |
314 | const Standard_Real tol3d, | |
315 | Standard_Real& tolreached) | |
316 | { | |
317 | //Handle(BRepAdaptor_HCurve) C3d = new (BRepAdaptor_HCurve)(E); | |
318 | Standard_Real f, l; | |
319 | Handle(Geom_Curve) C3d = BRep_Tool::Curve( E, f, l ); | |
320 | GeomAdaptor_Curve GAC3d( C3d, f, l ); | |
321 | Handle(GeomAdaptor_HCurve) HC3d = new GeomAdaptor_HCurve( GAC3d ); | |
322 | ||
323 | Handle(GeomAdaptor_HSurface) S = new (GeomAdaptor_HSurface)(Surf); | |
324 | Standard_Real ResTol; | |
325 | ||
326 | if(CheckSameParameter( HC3d, Pcurv, S, tol3d, tolreached )) | |
327 | return Standard_True; | |
328 | ||
329 | if (!HasPCurves(E)) | |
330 | { | |
331 | Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( Pcurv ); | |
332 | Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(), | |
333 | Precision::Confusion(), GeomAbs_C1, 10, 10, Standard_True); | |
334 | if (AppCurve.IsDone() && AppCurve.HasResult()) | |
335 | { | |
336 | C3d = AppCurve.Curve3d(); | |
337 | tolreached = AppCurve.MaxError3d(); | |
338 | BRep_Builder B; | |
339 | B.UpdateEdge( E, C3d, tolreached ); | |
340 | return Standard_True; | |
341 | } | |
342 | } | |
343 | ||
543a9964 | 344 | const Handle(Adaptor3d_HCurve)& aHCurve = HC3d; // to avoid ambiguity |
345 | Approx_SameParameter sp (aHCurve, Pcurv, S, tol3d ); | |
7fd59977 | 346 | if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d(); |
347 | else if(!sp.IsDone() && !sp.IsSameParameter()){ | |
0797d9d3 | 348 | #ifdef OCCT_DEBUG |
7fd59977 | 349 | cout<<"echec SameParameter"<<endl; |
350 | #endif | |
351 | return Standard_False; | |
352 | } | |
353 | ||
354 | ResTol = sp.TolReached(); | |
355 | if(ResTol > tolreached ){ | |
0797d9d3 | 356 | #ifdef OCCT_DEBUG |
0d969553 Y |
357 | cout<<"SameParameter : Tolerance not reached!"<<endl; |
358 | cout<<"tol visee : "<<tol3d<<" tol obtained : "<<ResTol<<endl; | |
7fd59977 | 359 | #endif |
360 | return Standard_False; | |
361 | } | |
362 | else { | |
363 | tolreached = 1.1*ResTol; | |
364 | if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d(); | |
365 | } | |
366 | return Standard_True; | |
367 | } | |
368 | ||
833e7561 | 369 | static void CorrectSameParameter(TopoDS_Edge& theEdge, |
370 | const TopoDS_Face& theFace1, | |
371 | const TopoDS_Face& theFace2) | |
372 | { | |
373 | if (BRep_Tool::Degenerated(theEdge)) | |
374 | return; | |
375 | ||
376 | Standard_Real fpar, lpar; | |
377 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, fpar, lpar); | |
378 | ||
379 | Standard_Boolean PCurveExists [2] = {Standard_False, Standard_False}; | |
380 | BRepAdaptor_Curve BAcurve [2]; | |
381 | ||
382 | if (!theFace1.IsNull()) | |
383 | { | |
384 | PCurveExists[0] = Standard_True; | |
385 | BAcurve[0].Initialize(theEdge, theFace1); | |
386 | } | |
387 | if (!theFace1.IsNull() && | |
388 | theFace1.IsSame(theFace2)) | |
389 | theEdge.Reverse(); | |
390 | if (!theFace2.IsNull()) | |
391 | { | |
392 | PCurveExists[1] = Standard_True; | |
393 | BAcurve[1].Initialize(theEdge, theFace2); | |
394 | } | |
395 | ||
396 | Standard_Real MaxSqDist = 0.; | |
397 | const Standard_Integer NCONTROL = 23; | |
398 | Standard_Real delta = (lpar - fpar)/NCONTROL; | |
399 | ||
400 | for (Standard_Integer i = 0; i <= NCONTROL; i++) | |
401 | { | |
402 | Standard_Real aParam = fpar + i*delta; | |
403 | gp_Pnt aPnt = aCurve->Value(aParam); | |
404 | for (Standard_Integer j = 0; j < 2; j++) | |
405 | if (PCurveExists[j]) | |
406 | { | |
407 | gp_Pnt aPntFromFace = BAcurve[j].Value(aParam); | |
408 | Standard_Real aSqDist = aPnt.SquareDistance(aPntFromFace); | |
409 | if (aSqDist > MaxSqDist) | |
410 | MaxSqDist = aSqDist; | |
411 | } | |
412 | } | |
413 | ||
414 | Standard_Real aTol = sqrt(MaxSqDist); | |
415 | BRep_Builder BB; | |
416 | BB.UpdateEdge(theEdge, aTol); | |
417 | } | |
418 | ||
7fd59977 | 419 | //======================================================================= |
0d969553 Y |
420 | //Objet : Orientate an edge of natural restriction |
421 | // : General | |
7fd59977 | 422 | //======================================================================= |
423 | static void Oriente(const Handle(Geom_Surface)& S, | |
424 | TopoDS_Edge& E) | |
425 | { | |
426 | gp_Pnt2d P; | |
427 | gp_Vec2d D, URef(1, 0), VRef(0, 1); | |
428 | Standard_Boolean isuiso, isfirst, isopposite; | |
429 | Standard_Real UFirst, ULast, VFirst, VLast, f, l; | |
430 | S->Bounds(UFirst, ULast, VFirst, VLast); | |
431 | Handle(Geom2d_Curve) C; | |
432 | TopLoc_Location bid; | |
433 | ||
434 | C = BRep_Tool::CurveOnSurface(E, S, bid, f, l); | |
435 | C->D1((f+l)/2, P, D); | |
436 | ||
437 | isuiso = D.IsParallel(VRef, 0.1); | |
438 | ||
439 | if ( isuiso ) { | |
440 | isfirst = (Abs (P.X()-UFirst) < Precision::Confusion()); | |
441 | isopposite = D.IsOpposite(VRef, 0.1); | |
442 | E.Orientation(TopAbs_REVERSED); | |
443 | } | |
444 | else { | |
445 | isfirst = (Abs (P.Y()-VFirst) < Precision::Confusion()); | |
446 | isopposite = D.IsOpposite(URef, 0.1); | |
447 | E.Orientation(TopAbs_FORWARD); | |
448 | } | |
449 | ||
450 | if (!isfirst) E.Reverse(); | |
451 | if (isopposite) E.Reverse(); | |
452 | } | |
453 | //OCC500(apo)-> | |
454 | static void UpdateEdgeOnPlane(const TopoDS_Face& F, const TopoDS_Edge& E, | |
455 | const BRep_Builder& BB) | |
456 | { | |
457 | Standard_Real f, l; | |
458 | Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l); | |
459 | Handle(Geom_Surface) S = BRep_Tool::Surface(F); | |
460 | TopLoc_Location Loc; | |
461 | Standard_Real Tol = BRep_Tool::Tolerance(E); | |
462 | BB.UpdateEdge(E, C2d, S, Loc, Tol); | |
463 | BRepCheck_Edge Check(E); | |
464 | Tol = Max(Tol,Check.Tolerance()); | |
465 | BB.UpdateEdge(E, Tol); | |
466 | TopoDS_Vertex V; | |
467 | Tol *= 1.01; | |
468 | V = TopExp::FirstVertex(E); | |
469 | if(BRep_Tool::Tolerance(V) < Tol) BB.UpdateVertex(V, Tol); | |
470 | V = TopExp::LastVertex(E); | |
471 | if(BRep_Tool::Tolerance(V) < Tol) BB.UpdateVertex(V, Tol); | |
472 | } | |
473 | //<-OCC500(apo) | |
474 | //======================================================================= | |
475 | //Function : BuildFace | |
0d969553 Y |
476 | //Objet : Construct a Face via a surface and 4 Edges (natural borders) |
477 | // : Only one Hypothesis : isos u and v are switched : | |
478 | // Edge1/3 are iso u (recp v) | |
479 | // Edge2/4 are iso v (recp u) | |
7fd59977 | 480 | //======================================================================= |
481 | static void BuildFace(const Handle(Geom_Surface)& S, | |
482 | const TopoDS_Edge& E1, | |
483 | const TopoDS_Edge& E2, | |
484 | const TopoDS_Edge& E3, | |
485 | const TopoDS_Edge& E4, | |
486 | TopTools_DataMapOfShapeShape& EEmap, | |
487 | const Standard_Boolean ExchUV, | |
488 | const Standard_Boolean UReverse, | |
489 | TopoDS_Face& F) | |
490 | { | |
491 | Standard_Real Tol; | |
492 | // Class BRep_Tool without fields and without Constructor : | |
493 | // BRep_Tool BT; | |
494 | TopoDS_Edge e1, e2, E; | |
495 | TopoDS_Wire WW; | |
496 | BRep_Builder BB; | |
497 | BRepBuilderAPI_MakeWire B; | |
498 | TopoDS_Iterator Iter; | |
499 | //gp_Pnt2d P; | |
500 | ||
0d969553 | 501 | //Is the surface planar ? |
7fd59977 | 502 | Standard_Real Tol1, Tol2, Tol3, Tol4; |
503 | Tol1 = BRep_Tool::Tolerance( E1 ); | |
504 | Tol2 = BRep_Tool::Tolerance( E2 ); | |
505 | Tol3 = BRep_Tool::Tolerance( E3 ); | |
506 | Tol4 = BRep_Tool::Tolerance( E4 ); | |
507 | // Tol = Min( BT.Tolerance(E1), BT.Tolerance(E2)); | |
508 | Tol = Min( Tol1, Tol2 ); | |
509 | // Tol = Min(Tol, Min(BT.Tolerance(E3),BT.Tolerance(E4))); | |
510 | Tol = Min( Tol, Min( Tol3, Tol4 ) ); | |
511 | Standard_Boolean IsPlan = Standard_False; | |
512 | Handle(Geom_Plane) thePlane; | |
513 | ||
514 | if (!E1.IsSame(E3) && !E2.IsSame(E4)) //exclude cases with seam edges: they are not planar | |
515 | { | |
516 | GeomLib_IsPlanarSurface IsP(S, Tol); | |
517 | if (IsP.IsPlanar()) | |
518 | { | |
519 | IsPlan = Standard_True; | |
520 | thePlane = new Geom_Plane( IsP.Plan() ); | |
521 | } | |
522 | else | |
523 | { | |
524 | Handle(BRep_TEdge)& TE1 = *((Handle(BRep_TEdge)*)&E1.TShape()); | |
525 | Handle(BRep_TEdge)& TE2 = *((Handle(BRep_TEdge)*)&E2.TShape()); | |
526 | Handle(BRep_TEdge)& TE3 = *((Handle(BRep_TEdge)*)&E3.TShape()); | |
527 | Handle(BRep_TEdge)& TE4 = *((Handle(BRep_TEdge)*)&E4.TShape()); | |
528 | TE1->Tolerance( Precision::Confusion() ); | |
529 | TE2->Tolerance( Precision::Confusion() ); | |
530 | TE3->Tolerance( Precision::Confusion() ); | |
531 | TE4->Tolerance( Precision::Confusion() ); | |
532 | ||
533 | TopoDS_Wire theWire = BRepLib_MakeWire( E1, E2, E3, E4 ); | |
534 | Standard_Integer NbPoints = NumberOfPoles( theWire ); | |
535 | if (NbPoints <= 100) //limitation for CPU | |
536 | { | |
537 | BRepLib_FindSurface FS( theWire, -1, Standard_True ); | |
538 | if (FS.Found()) | |
539 | { | |
540 | IsPlan = Standard_True; | |
541 | thePlane = Handle(Geom_Plane)::DownCast(FS.Surface()); | |
542 | } | |
543 | } | |
544 | BB.UpdateEdge( E1, Tol1 ); | |
545 | BB.UpdateEdge( E2, Tol2 ); | |
546 | BB.UpdateEdge( E3, Tol3 ); | |
547 | BB.UpdateEdge( E4, Tol4 ); | |
548 | } | |
549 | } | |
550 | ||
0d969553 | 551 | // Construction of the wire |
7fd59977 | 552 | // B.MakeWire(WW); |
553 | e1 = E1; | |
554 | Oriente(S, e1); | |
555 | // if (!IsPlan || !BT.Degenerated(e1)) | |
556 | if (!IsPlan || !BRep_Tool::Degenerated(e1)) | |
557 | B.Add(e1); | |
558 | ||
559 | e2 = E2; | |
560 | Oriente(S, e2); | |
561 | // if (!IsPlan || !BT.Degenerated(e2)) | |
562 | if (!IsPlan || !BRep_Tool::Degenerated(e2)) | |
563 | { | |
564 | B.Add(e2); | |
565 | if (!BRep_Tool::Degenerated(e2)) | |
566 | { | |
567 | WW = B.Wire(); | |
568 | TopoDS_Shape NewEdge; | |
569 | //take the last edge added to WW | |
570 | for (Iter.Initialize( WW ); Iter.More(); Iter.Next()) | |
571 | NewEdge = Iter.Value(); | |
572 | if (! e2.IsSame(NewEdge)) | |
573 | EEmap.Bind( e2, NewEdge ); | |
574 | } | |
575 | } | |
576 | ||
577 | if (E3.IsSame(E1)) { | |
578 | E = e1; | |
579 | E.Reverse(); | |
580 | } | |
581 | else { | |
582 | E = E3; | |
583 | Oriente(S, E); | |
584 | } | |
585 | // if (!IsPlan || !BT.Degenerated(E)) | |
586 | if (!IsPlan || !BRep_Tool::Degenerated(E)) | |
587 | { | |
588 | B.Add(E); | |
589 | if (!BRep_Tool::Degenerated(E)) | |
590 | { | |
591 | WW = B.Wire(); | |
592 | TopoDS_Shape NewEdge; | |
593 | //take the last edge added to WW | |
594 | for (Iter.Initialize( WW ); Iter.More(); Iter.Next()) | |
595 | NewEdge = Iter.Value(); | |
596 | if (! E.IsSame(NewEdge)) | |
597 | EEmap.Bind( E, NewEdge ); | |
598 | } | |
599 | } | |
600 | ||
601 | if (E4.IsSame(E2)) { | |
602 | E = e2; | |
603 | E.Reverse(); | |
604 | } | |
605 | else { | |
606 | E = E4; | |
607 | Oriente(S, E); | |
608 | } | |
609 | // if (!IsPlan || !BT.Degenerated(E)) | |
610 | if (!IsPlan || !BRep_Tool::Degenerated(E)) | |
611 | { | |
612 | B.Add(E); | |
613 | if (!BRep_Tool::Degenerated(E)) | |
614 | { | |
615 | WW = B.Wire(); | |
616 | TopoDS_Shape NewEdge; | |
617 | //take the last edge added to WW | |
618 | for (Iter.Initialize( WW ); Iter.More(); Iter.Next()) | |
619 | NewEdge = Iter.Value(); | |
620 | if (! E.IsSame(NewEdge)) | |
621 | EEmap.Bind( E, NewEdge ); | |
622 | } | |
623 | } | |
624 | ||
625 | WW = B.Wire(); | |
626 | #if DRAW | |
c0695321 A |
627 | if (Affich) |
628 | DBRep::Set("wire-on-face", WW); | |
7fd59977 | 629 | #endif |
630 | ||
0d969553 Y |
631 | // Construction of the face. |
632 | if (IsPlan) { // Suspend representation 2d | |
633 | // and construct face Plane | |
7fd59977 | 634 | |
635 | //BRepLib_MakeFace MkF(IsP.Plan(), WW); | |
636 | gp_Pnt aPnt; | |
637 | gp_Vec DU, DV, NS, NP; | |
638 | Standard_Real Ufirst, Ulast, Vfirst, Vlast; | |
639 | S->Bounds( Ufirst, Ulast, Vfirst, Vlast ); | |
640 | S->D1( (Ufirst+Ulast)/2., (Vfirst+Vlast)/2., aPnt, DU, DV ); | |
641 | NS = DU ^ DV; | |
642 | NP = thePlane->Pln().Axis().Direction(); | |
643 | if (NS.Dot(NP) < 0.) | |
644 | thePlane->UReverse(); | |
645 | BRepLib_MakeFace MkF( thePlane, WW ); | |
646 | if (MkF.Error() != BRepLib_FaceDone) { | |
0797d9d3 | 647 | #ifdef OCCT_DEBUG |
7fd59977 | 648 | BRepLib_FaceError Err = MkF.Error(); |
649 | cout << "Planar Face Error :" << Err << endl; | |
650 | #endif | |
651 | } | |
652 | else { | |
653 | Handle(Geom2d_Curve) NullC2d; | |
654 | TopLoc_Location Loc; | |
655 | BB.UpdateEdge( E1, NullC2d, S, Loc, Tol1 ); | |
656 | BB.UpdateEdge( E2, NullC2d, S, Loc, Tol2 ); | |
657 | BB.UpdateEdge( E3, NullC2d, S, Loc, Tol3 ); | |
658 | BB.UpdateEdge( E4, NullC2d, S, Loc, Tol4 ); | |
659 | ||
660 | F = MkF.Face(); | |
661 | UpdateEdgeOnPlane(F,E1,BB); | |
662 | UpdateEdgeOnPlane(F,E2,BB); | |
663 | UpdateEdgeOnPlane(F,E3,BB); | |
664 | UpdateEdgeOnPlane(F,E4,BB); | |
665 | /*OCC500(apo)-> | |
666 | TopLoc_Location Loc; | |
667 | Handle(Geom2d_Curve) NC; | |
668 | NC.Nullify(); | |
669 | // B.UpdateEdge(E1, NC, S, Loc, BT.Tolerance(E1)); | |
670 | BB.UpdateEdge(E1, NC, S, Loc, BRep_Tool::Tolerance(E1)); | |
671 | // B.UpdateEdge(E2, NC, S, Loc, BT.Tolerance(E2)); | |
672 | BB.UpdateEdge(E2, NC, S, Loc, BRep_Tool::Tolerance(E2)); | |
673 | // B.UpdateEdge(E3, NC, S, Loc, BT.Tolerance(E3)); | |
674 | BB.UpdateEdge(E3, NC, S, Loc, BRep_Tool::Tolerance(E3)); | |
675 | // B.UpdateEdge(E4, NC, S, Loc, BT.Tolerance(E4)); | |
676 | BB.UpdateEdge(E4, NC, S, Loc, BRep_Tool::Tolerance(E4)); | |
677 | <-OCC500(apo)*/ | |
678 | } | |
679 | } | |
680 | ||
681 | if (!IsPlan) {// Cas Standard : Ajout | |
682 | BB.MakeFace(F, S, Precision::Confusion()); | |
683 | BB.Add(F, WW); | |
684 | } | |
685 | ||
686 | // Reorientation | |
687 | if (ExchUV) F.Reverse(); | |
688 | if (UReverse) F.Reverse(); | |
689 | } | |
690 | ||
691 | ||
692 | //======================================================================= | |
693 | //Fonction : BuildEdge | |
0d969553 | 694 | //Objet : Construct non-closed Edge |
7fd59977 | 695 | //======================================================================= |
696 | static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d, | |
697 | Handle(Geom2d_Curve)& C2d, | |
698 | Handle(Geom_Surface)& S, | |
699 | const TopoDS_Vertex& VF, | |
700 | const TopoDS_Vertex& VL, | |
701 | const Standard_Real f, | |
702 | const Standard_Real l, | |
703 | const Standard_Real Tol3d) | |
704 | { | |
705 | gp_Pnt P1, P2, P; | |
706 | Standard_Real Tol1, Tol2, Tol, d; | |
707 | // Class BRep_Tool without fields and without Constructor : | |
708 | // BRep_Tool BT; | |
709 | BRep_Builder B; | |
710 | TopoDS_Edge E; | |
711 | ||
712 | // P1 = BT.Pnt(VF); | |
713 | P1 = BRep_Tool::Pnt(VF); | |
714 | // Tol1 = BT.Tolerance(VF); | |
715 | Tol1 = BRep_Tool::Tolerance(VF); | |
716 | // P2 = BT.Pnt(VL); | |
717 | P2 = BRep_Tool::Pnt(VL); | |
718 | // Tol2 = BT.Tolerance(VF); | |
10a55e0d | 719 | Tol2 = BRep_Tool::Tolerance(VL); |
7fd59977 | 720 | Tol = Max(Tol1, Tol2); |
721 | ||
722 | if (VF.IsSame(VL) || | |
723 | (P1.Distance(P2) < Tol ) ) { | |
0d969553 | 724 | // Degenerated case |
7fd59977 | 725 | gp_Pnt2d P2d; |
726 | C2d->D0(f, P2d); | |
727 | S->D0(P2d.X(), P2d.Y(), P); | |
728 | d = P1.Distance(P); | |
729 | if (d > Tol) Tol = d; | |
730 | C2d->D0(l, P2d); | |
731 | S->D0(P2d.X(), P2d.Y(), P); | |
732 | d = P2.Distance(P); | |
733 | if (d > Tol) Tol = d; | |
734 | ||
735 | B.UpdateVertex(VF, Tol); | |
736 | B.UpdateVertex(VL, Tol); | |
737 | ||
738 | B.MakeEdge(E); | |
739 | B.UpdateEdge(E,C2d,S,TopLoc_Location(), Tol); | |
740 | B.Add(E,VF); | |
741 | B.Add(E,VL); | |
742 | B.Range(E,f,l); | |
743 | B.Degenerated(E, Standard_True); | |
744 | ||
745 | return E; | |
746 | } | |
747 | ||
748 | C3d->D0(f, P); | |
749 | d = P1.Distance(P); | |
750 | if (d > Tol1) | |
751 | B.UpdateVertex(VF, d); | |
752 | ||
753 | // P1 = BT.Pnt(VL); | |
754 | P1 = BRep_Tool::Pnt(VL); | |
755 | C3d->D0(l, P); | |
756 | d = P2.Distance(P); | |
757 | if (d > Tol2) | |
758 | B.UpdateVertex(VL, d); | |
759 | ||
760 | BRepLib_MakeEdge MkE (C3d, VF, VL, f, l); | |
0d969553 | 761 | if (!MkE.IsDone()) { // Error of construction !! |
7fd59977 | 762 | #ifdef DRAW |
763 | char name[100]; | |
764 | sprintf(name,"firstvertex_error"); | |
765 | DBRep::Set(name, VF); | |
766 | sprintf(name,"lastvertex_error"); | |
767 | DBRep::Set(name, VL); | |
768 | sprintf(name,"curve3d_error"); | |
769 | char* Temp = name ; | |
770 | DrawTrSurf::Set(Temp, C3d); | |
771 | // DrawTrSurf::Set(name, C3d); | |
9775fa61 | 772 | throw Standard_ConstructionError("BRepFill_Sweep::BuildEdge"); |
7fd59977 | 773 | #endif |
774 | } | |
775 | ||
776 | E = MkE.Edge(); | |
777 | TopLoc_Location Loc; | |
778 | B.UpdateEdge(E, C2d, S, Loc, Tol3d); | |
779 | ||
780 | return E; | |
781 | } | |
782 | ||
783 | ||
784 | //======================================================================= | |
785 | //Fonction : Filling | |
0d969553 | 786 | //Objet : Construct the faces of filling |
7fd59977 | 787 | //======================================================================= |
788 | static Standard_Boolean Filling(const TopoDS_Shape& EF, | |
789 | const TopoDS_Shape& F1, | |
790 | const TopoDS_Shape& EL, | |
791 | const TopoDS_Shape& F2, | |
792 | TopTools_DataMapOfShapeShape& EEmap, | |
793 | const Standard_Real Tol, | |
794 | const gp_Ax2& Axe, | |
795 | const gp_Vec& TangentOnPart1, | |
796 | TopoDS_Edge& Aux1, | |
797 | TopoDS_Edge& Aux2, | |
798 | TopoDS_Face& Result) | |
799 | { | |
800 | BRep_Builder B; | |
801 | // Class BRep_Tool without fields and without Constructor : | |
802 | // BRep_Tool BT; | |
803 | // Standard_Integer NbInt =0; | |
804 | // Standard_Real Tol3d = Tol; | |
805 | Standard_Boolean WithE3, WithE4; | |
806 | ||
0d969553 | 807 | // Return constraints |
7fd59977 | 808 | TopoDS_Vertex V1, V2, Vf, Vl; |
809 | TopoDS_Edge E1, E2, E3, E4; | |
810 | E1 = TopoDS::Edge(EF); | |
811 | E2 = TopoDS::Edge(EL); | |
812 | ||
813 | TopExp::Vertices(E1, Vf, Vl); | |
814 | Vf.Orientation(TopAbs_FORWARD); | |
815 | Vl.Orientation(TopAbs_FORWARD); | |
816 | ||
817 | TopExp::Vertices(E2, V1, V2); | |
818 | V1.Orientation(TopAbs_REVERSED); | |
819 | V2.Orientation(TopAbs_REVERSED); | |
820 | ||
821 | B.MakeEdge(E3); | |
822 | B.MakeEdge(E4); | |
823 | ||
824 | WithE3 = WithE4 = Standard_False; | |
825 | ||
826 | if ((!Aux1.IsNull()) && (!Vf.IsSame(V1))) { | |
827 | E3 = Aux1; | |
828 | // E3 = TopoDS::Edge(Aux1); | |
829 | WithE3 = Standard_True; | |
830 | } | |
831 | ||
832 | if (Vf.IsSame(Vl)) { | |
833 | E4 = E3; | |
834 | E4.Reverse(); | |
835 | WithE4 = WithE3; | |
836 | } | |
837 | else if (!Aux2.IsNull() && (!Vl.IsSame(V2))) { | |
838 | E4 = Aux2; | |
839 | // E4 = TopoDS::Edge(Aux2); | |
840 | WithE4 = Standard_True; | |
841 | } | |
842 | ||
843 | #if DRAW | |
844 | if (Affich) { | |
845 | DBRep::Set("Fill_Edge1", E1); | |
846 | DBRep::Set("Fill_Edge2", E2); | |
847 | if (!E3.IsNull()) | |
848 | DBRep::Set("Fill_Edge3", E3); | |
849 | if (!E4.IsNull()) | |
850 | DBRep::Set("Fill_Edge4", E4); | |
851 | } | |
852 | #endif | |
853 | ||
0d969553 | 854 | // Construction of a surface of revolution |
7fd59977 | 855 | Handle(Geom_Curve) Prof1, Prof2; |
856 | //Standard_Integer ii, jj;//, Nb; | |
857 | Standard_Real f1, f2, l1, l2,/*d1, d2,*/ Angle;//, Eps = 1.e-9; | |
858 | // Prof1 = BT.Curve(E1, f1, l1); | |
859 | Prof1 = BRep_Tool::Curve(E1, f1, l1); | |
860 | // Prof2 = BT.Curve(E2, f2, l2); | |
861 | Prof2 = BRep_Tool::Curve(E2, f2, l2); | |
c37f5702 | 862 | |
863 | // Indeed, both Prof1 and Prof2 are the same curves but in different positions | |
864 | ||
7fd59977 | 865 | gp_Pnt P1, P2, P; |
c37f5702 | 866 | |
867 | // Choose the angle of opening | |
868 | gp_Trsf aTf; | |
869 | aTf.SetTransformation(Axe); | |
870 | ||
871 | // Choose the furthest point from the "center of revolution" | |
872 | // to provide correct angle measurement. | |
873 | const Standard_Real aPrm[] = {f1, 0.5*(f1 + l1), l1}; | |
874 | const gp_Pnt aP1[] = {Prof1->Value(aPrm[0]).Transformed(aTf), | |
875 | Prof1->Value(aPrm[1]).Transformed(aTf), | |
876 | Prof1->Value(aPrm[2]).Transformed(aTf)}; | |
877 | ||
878 | Standard_Integer aMaxIdx = -1; | |
879 | Standard_Real aMaxDist = RealFirst(); | |
880 | for (Standard_Integer i = 0; i < 3; i++) | |
881 | { | |
882 | const Standard_Real aDist = aP1[i].X()*aP1[i].X() + aP1[i].Z()*aP1[i].Z(); | |
883 | if (aDist > aMaxDist) | |
884 | { | |
885 | aMaxDist = aDist; | |
886 | aMaxIdx = i; | |
887 | } | |
888 | } | |
889 | ||
890 | const gp_Pnt aP2 = Prof2->Value(aPrm[aMaxIdx]).Transformed(aTf); | |
891 | const gp_Vec2d aV1(aP1[aMaxIdx].Z(), aP1[aMaxIdx].X()); | |
892 | const gp_Vec2d aV2(aP2.Z(), aP2.X()); | |
893 | if (aV1.SquareMagnitude() <= gp::Resolution() || | |
894 | aV2.SquareMagnitude() <= gp::Resolution()) | |
895 | { | |
7fd59977 | 896 | return Standard_False; |
c37f5702 | 897 | } |
898 | ||
899 | Angle = aV1.Angle(aV2); | |
7fd59977 | 900 | |
901 | gp_Ax1 axe(Axe.Location(), Axe.YDirection()); | |
902 | ||
903 | if (Angle < 0) { | |
904 | Angle = -Angle; | |
905 | axe.Reverse(); | |
906 | } | |
907 | ||
908 | Handle(Geom_SurfaceOfRevolution) Rev = | |
909 | new (Geom_SurfaceOfRevolution) (Prof1, axe); | |
c37f5702 | 910 | |
7fd59977 | 911 | Handle(Geom_Surface) Surf = |
912 | new (Geom_RectangularTrimmedSurface) (Rev, 0, Angle, f1, l1); | |
913 | ||
0d969553 | 914 | // Control the direction of the rotation |
7fd59977 | 915 | Standard_Boolean ToReverseResult = Standard_False; |
916 | gp_Vec d1u; | |
917 | d1u = Surf->DN(0, (f1+l1)/2, 1, 0); | |
c6541a0c | 918 | if (d1u.Angle(TangentOnPart1) > M_PI/2) { //Invert everything |
7fd59977 | 919 | ToReverseResult = Standard_True; |
920 | /* | |
921 | axe.Reverse(); | |
c6541a0c | 922 | Angle = 2*M_PI - Angle; |
7fd59977 | 923 | Rev = new (Geom_SurfaceOfRevolution) (Prof1, axe); |
924 | Surf = new (Geom_RectangularTrimmedSurface) | |
925 | (Rev, 0, Angle, f1, l1); | |
926 | */ | |
927 | } | |
928 | ||
929 | #if DRAW | |
930 | if (Affich) { | |
931 | char* Temp = "Surf_Init" ; | |
932 | DrawTrSurf::Set(Temp, Surf); | |
933 | } | |
934 | #endif | |
935 | ||
936 | Handle(Geom2d_Curve) C1, C2, C3, C4; | |
937 | /* | |
0d969553 | 938 | // Deform the surface of revolution. |
7fd59977 | 939 | GeomPlate_BuildPlateSurface BPS; |
940 | ||
941 | Handle(BRepAdaptor_HSurface) AS; | |
942 | Handle(BRepAdaptor_HCurve2d) AC2d; | |
943 | Handle(Adaptor3d_HCurveOnSurface) HConS; | |
944 | */ | |
945 | Handle(Geom2d_Line) L; | |
946 | gp_Pnt2d P2d(0.,0.); | |
947 | ||
948 | L = new (Geom2d_Line) (P2d, gp::DY2d()); | |
949 | C1 = new (Geom2d_TrimmedCurve) (L, f1, l1); | |
950 | ||
951 | P2d.SetCoord(Angle,0.); | |
952 | L = new (Geom2d_Line) (P2d, gp::DY2d()); | |
953 | C2 = new (Geom2d_TrimmedCurve) (L, f1, l1); | |
954 | ||
0d969553 | 955 | // It is required to control the direction and the range. |
7fd59977 | 956 | C2->D0(f1, P2d); |
957 | Surf->D0(P2d.X(), P2d.Y(), P1); | |
958 | C2->D0(l1, P2d); | |
959 | Surf->D0(P2d.X(), P2d.Y(), P2); | |
960 | // P = BT.Pnt(V1); | |
961 | P = BRep_Tool::Pnt(V1); | |
962 | if (P.Distance(P2)+Tol < P.Distance(P1)) { | |
0d969553 | 963 | // E2 is parsed in the direction opposite to E1 |
7fd59977 | 964 | C2->Reverse(); |
965 | TopoDS_Vertex aux; | |
966 | aux = V2; | |
967 | V2 = V1; | |
968 | V1 = aux; | |
969 | } | |
970 | GeomLib::SameRange(Precision::PConfusion(), C2, | |
971 | C2->FirstParameter(), | |
972 | C2->LastParameter(), | |
973 | f2, l2, C3); | |
974 | C2 = C3; | |
975 | ||
7fd59977 | 976 | // P1 = BT.Pnt(Vf); |
977 | P1 = BRep_Tool::Pnt(Vf); | |
978 | // P2 = BT.Pnt(V1); | |
979 | P2 = BRep_Tool::Pnt(V1); | |
980 | // pointu_f = Vf.IsSame(V1) || (P1.Distance(P2) < BT.Tolerance(Vf)); | |
7fd59977 | 981 | // P1 = BT.Pnt(Vl); |
982 | P1 = BRep_Tool::Pnt(Vl); | |
983 | // P2 = BT.Pnt(V2); | |
984 | P2 = BRep_Tool::Pnt(V2); | |
985 | // pointu_l = Vl.IsSame(V2) || (P1.Distance(P2) < BT.Tolerance(Vl)); | |
7fd59977 | 986 | |
987 | P2d.SetCoord(0.,f1); | |
988 | L = new (Geom2d_Line) (P2d, gp::DX2d()); | |
989 | C3 = new (Geom2d_TrimmedCurve) (L, 0, Angle); | |
990 | ||
991 | ||
992 | P2d.SetCoord(0.,l1); | |
993 | L = new (Geom2d_Line) (P2d, gp::DX2d()); | |
994 | C4 = new (Geom2d_TrimmedCurve) (L, 0, Angle); | |
995 | /* | |
0d969553 Y |
996 | // Determine the constraints and |
997 | // their parametric localisation. | |
7fd59977 | 998 | if (!E1.IsNull()) { |
999 | AS = new BRepAdaptor_HSurface(TopoDS::Face(F1)); | |
1000 | AC2d = new BRepAdaptor_HCurve2d(); | |
1001 | AC2d->ChangeCurve2d().Initialize(E1,TopoDS::Face(F1)); | |
1002 | HConS = new (Adaptor3d_HCurveOnSurface)(); | |
1003 | HConS->ChangeCurve().Load(AC2d); | |
1004 | HConS->ChangeCurve().Load(AS); | |
1005 | ||
1006 | Handle(BRepFill_CurveConstraint) Cont | |
1007 | = new BRepFill_CurveConstraint(HConS, 1, 15); | |
1008 | Cont->SetCurve2dOnSurf(C1); | |
1009 | ||
1010 | BPS.Add(Cont); | |
1011 | NbInt = HConS->NbIntervals(GeomAbs_CN); | |
1012 | } | |
1013 | ||
1014 | if (!E2.IsNull()) { | |
1015 | AS = new BRepAdaptor_HSurface(TopoDS::Face(F2)); | |
1016 | AC2d = new BRepAdaptor_HCurve2d(); | |
1017 | AC2d->ChangeCurve2d().Initialize(E2,TopoDS::Face(F2)); | |
1018 | HConS = new (Adaptor3d_HCurveOnSurface); | |
1019 | ||
1020 | HConS->ChangeCurve().Load(AC2d); | |
1021 | HConS->ChangeCurve().Load(AS); | |
1022 | ||
1023 | Handle(BRepFill_CurveConstraint) Cont | |
1024 | = new BRepFill_CurveConstraint(HConS, 1, 15); | |
1025 | Cont->SetCurve2dOnSurf(C2); | |
1026 | BPS.Add(Cont); | |
1027 | } | |
1028 | ||
1029 | if (WithE3) { | |
1030 | Handle(BRepAdaptor_HCurve) AC = new (BRepAdaptor_HCurve) (E3); | |
1031 | Handle(BRepFill_CurveConstraint) Cont | |
1032 | = new BRepFill_CurveConstraint(AC, 0); | |
1033 | Cont->SetCurve2dOnSurf(C3); | |
1034 | BPS.Add(Cont); | |
1035 | } | |
1036 | else if (pointu_f) { | |
1037 | Standard_Real delta = Angle / 11; | |
1038 | // P = BT.Pnt(Vf); | |
1039 | P = BRep_Tool::Pnt(Vf); | |
1040 | Handle(GeomPlate_PointConstraint) PC; | |
1041 | for (ii=1; ii<=10; ii++) { | |
1042 | C3->D0(ii*delta, P2d); | |
1043 | PC = new (GeomPlate_PointConstraint) (P, 0); | |
1044 | PC->SetPnt2dOnSurf(P2d); | |
1045 | BPS.Add(PC); | |
1046 | } | |
1047 | } | |
1048 | ||
1049 | ||
1050 | if (WithE4) { | |
1051 | Handle(BRepAdaptor_HCurve) AC = new (BRepAdaptor_HCurve) (E4); | |
1052 | Handle(BRepFill_CurveConstraint) Cont | |
1053 | = new BRepFill_CurveConstraint(AC, 0); | |
1054 | Cont->SetCurve2dOnSurf(C4); | |
1055 | BPS.Add(Cont); | |
1056 | } | |
1057 | else if (pointu_l) { | |
1058 | Standard_Real delta = Angle / 11; | |
1059 | // P = BT.Pnt(Vl); | |
1060 | P = BRep_Tool::Pnt(Vl); | |
1061 | Handle(GeomPlate_PointConstraint) PC; | |
1062 | for (ii=1; ii<=10; ii++) { | |
1063 | C4->D0(ii*delta, P2d); | |
1064 | PC = new (GeomPlate_PointConstraint) (P, 0); | |
1065 | PC->SetPnt2dOnSurf(P2d); | |
1066 | BPS.Add(PC); | |
1067 | } | |
1068 | } | |
1069 | ||
1070 | BPS.LoadInitSurface(Surf); | |
1071 | BPS.Perform(); | |
1072 | ||
1073 | // Controle s'il y a une deformation effective | |
1074 | Handle(GeomPlate_Surface) plate; | |
1075 | plate = BPS.Surface(); | |
1076 | plate->SetBounds(0, Angle, f1, l1); | |
1077 | Standard_Boolean Ok=Standard_True; | |
1078 | Standard_Real u, v; | |
1079 | d1 = (l1-f1)/5; | |
1080 | d2 = Angle/5; | |
1081 | for (ii=0; ii<=5 && Ok; ii++) { | |
1082 | u = f1 + ii*d1; | |
1083 | for (jj=0; jj<=5 && Ok; jj++) { | |
1084 | v = jj*d2; | |
1085 | plate->D0(u, v, P1); | |
1086 | Surf->D0(u, v, P2); | |
1087 | Ok = (P2.IsEqual(P1, Tol)); | |
1088 | } | |
1089 | } | |
1090 | ||
1091 | ||
1092 | if (!Ok) { | |
1093 | // Approx de la plate surface | |
1094 | // Bords naturelles => pas besoin de criteres. | |
1095 | GeomConvert_ApproxSurface App(BPS.Surface(), | |
1096 | Tol3d, | |
1097 | GeomAbs_C1, GeomAbs_C1, | |
1098 | 8, 8, 2*NbInt, 0); | |
1099 | if (!App.HasResult()) { | |
0797d9d3 | 1100 | #ifdef OCCT_DEBUG |
7fd59977 | 1101 | cout << "Filling_Approx : Pas de resultat" << endl; |
1102 | #endif | |
1103 | return Standard_False; | |
1104 | } | |
0797d9d3 | 1105 | #ifdef OCCT_DEBUG |
7fd59977 | 1106 | cout << "Filling_Approx Error 3d = " << |
1107 | App.MaxError() << endl; | |
1108 | #endif | |
1109 | Surf = App.Surface(); | |
1110 | Tol3d = App.MaxError(); | |
1111 | } | |
1112 | */ | |
1113 | ||
1114 | // Update des Edges | |
1115 | TopLoc_Location Loc; | |
1116 | Handle(Geom_Curve) C3d; | |
1117 | B.UpdateEdge(E1, C1, Surf, Loc, /*Tol3d*/Precision::Confusion()); | |
1118 | B.UpdateEdge(E2, C2, Surf, Loc, /*Tol3d*/Precision::Confusion()); | |
1119 | ||
1120 | if (E3.IsSame(E4)) { | |
1121 | if (!WithE3) | |
1122 | { | |
1123 | C3d = Surf->VIso(f1); | |
1124 | E3 = BuildEdge(C3d, C3, Surf, Vf, V1, 0, Angle, /*Tol3d*/Precision::Confusion()); | |
1125 | } | |
1126 | else | |
1127 | { | |
1128 | BRepAdaptor_Curve aCurve(E3); | |
1129 | Standard_Real AngleOld = aCurve.LastParameter(); | |
1130 | if (Angle > AngleOld) | |
1131 | { | |
1132 | B.Range( E3, 0, Angle ); | |
1133 | TopoDS_Vertex V (TopExp::LastVertex(E3)); | |
1134 | Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*) &V.TShape()); | |
1135 | TVlast->Tolerance( Precision::Confusion() ); | |
1136 | } | |
1137 | } | |
1138 | ||
1139 | B.UpdateEdge(E3, C3, C4, Surf, Loc, /*Tol3d*/Precision::Confusion()); | |
1140 | E4 = E3; | |
1141 | E4.Reverse(); | |
1142 | } | |
1143 | else { | |
1144 | if (!WithE3) | |
1145 | { | |
1146 | C3d = Surf->VIso(f1); | |
1147 | E3 = BuildEdge(C3d, C3, Surf, Vf, V1, 0, Angle, /*Tol3d*/Precision::Confusion()); | |
1148 | } | |
1149 | else | |
1150 | { | |
1151 | BRepAdaptor_Curve aCurve(E3); | |
1152 | Standard_Real AngleOld = aCurve.LastParameter(); | |
1153 | if (Angle > AngleOld) | |
1154 | { | |
1155 | B.Range( E3, 0, Angle ); | |
1156 | TopoDS_Vertex V(TopExp::LastVertex(E3)); | |
1157 | Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*) &V.TShape()); | |
1158 | TVlast->Tolerance( Precision::Confusion() ); | |
1159 | } | |
1160 | ||
1161 | B.UpdateEdge(E3, C3, Surf, Loc, /*Tol3d*/Precision::Confusion()); | |
1162 | } | |
1163 | ||
1164 | if (!WithE4) | |
1165 | { | |
1166 | C3d = Surf->VIso(l1); | |
1167 | E4 = BuildEdge(C3d, C4, Surf, Vl, V2, 0, Angle, /*Tol3d*/Precision::Confusion()); | |
1168 | } | |
1169 | else | |
1170 | { | |
1171 | BRepAdaptor_Curve aCurve(E4); | |
1172 | Standard_Real AngleOld = aCurve.LastParameter(); | |
1173 | if (Angle > AngleOld) | |
1174 | { | |
1175 | B.Range( E4, 0, Angle ); | |
1176 | TopoDS_Vertex V (TopExp::LastVertex(E4)); | |
1177 | Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*)&V.TShape()); | |
1178 | TVlast->Tolerance( Precision::Confusion() ); | |
1179 | } | |
1180 | ||
1181 | B.UpdateEdge(E4, C4, Surf, Loc, /*Tol3d*/Precision::Confusion()); | |
1182 | } | |
1183 | } | |
1184 | ||
0d969553 | 1185 | //Construct face |
7fd59977 | 1186 | BuildFace(Surf,E1, E3, E2, E4, EEmap, |
1187 | Standard_False, Standard_False, | |
1188 | Result); | |
1189 | ||
0d969553 | 1190 | // Set the continuities. |
7fd59977 | 1191 | B.Continuity(E1, TopoDS::Face(F1), Result, GeomAbs_G1); |
1192 | B.Continuity(E2, TopoDS::Face(F2), Result, GeomAbs_G1); | |
1193 | ||
0d969553 | 1194 | // Render the calculated borders. |
7fd59977 | 1195 | // if (!BT.Degenerated(E3)) |
1196 | if (!BRep_Tool::Degenerated(E3)) | |
1197 | Aux1 = E3; | |
1198 | else | |
1199 | B.MakeEdge(Aux1); //Nullify | |
1200 | ||
1201 | // if (!BT.Degenerated(E4)) | |
1202 | if (!BRep_Tool::Degenerated(E4)) | |
1203 | Aux2 = E4; | |
1204 | else | |
1205 | B.MakeEdge(Aux2); | |
1206 | ||
0d969553 | 1207 | // Set the orientation |
c37f5702 | 1208 | |
1209 | // Provide correct normals computation | |
1210 | // (the normal will be computed not in | |
1211 | // singularity point definitely). | |
1212 | Angle = RealFirst(); | |
1213 | for (Standard_Integer i = 0; i < 3; i++) | |
1214 | { | |
1215 | gp_Vec D1U, D1V, N1, N2; | |
1216 | C1->D0(aPrm[i], P2d); | |
1217 | Surf->D1(P2d.X(), P2d.Y(), P, D1U, D1V); | |
1218 | N1 = D1U^D1V; | |
1219 | ||
1220 | if (N1.SquareMagnitude() < Precision::SquareConfusion()) | |
1221 | continue; | |
1222 | ||
1223 | // C1 = BT.CurveOnSurface(E1, TopoDS::Face(F1), f2, l2); | |
1224 | C1 = BRep_Tool::CurveOnSurface(E1, TopoDS::Face(F1), f2, l2); | |
1225 | C1->D0(aPrm[i], P2d); | |
1226 | Handle(BRepAdaptor_HSurface) AS = new BRepAdaptor_HSurface(TopoDS::Face(F1)); | |
1227 | AS->D1(P2d.X(), P2d.Y(), P, D1U, D1V); | |
1228 | N2 = D1U^D1V; | |
1229 | ||
1230 | if (N2.SquareMagnitude() < Precision::SquareConfusion()) | |
1231 | continue; | |
1232 | ||
1233 | Angle = N1.Angle(N2); | |
1234 | ||
1235 | break; | |
1236 | } | |
7fd59977 | 1237 | |
c37f5702 | 1238 | if (Angle == RealFirst()) |
1239 | return Standard_False; | |
1240 | ||
1241 | if ( (F1.Orientation() == TopAbs_REVERSED) ^ (Angle>M_PI/2)) | |
7fd59977 | 1242 | Result.Orientation(TopAbs_REVERSED); |
1243 | else Result.Orientation(TopAbs_FORWARD); | |
1244 | ||
1245 | if (ToReverseResult) | |
1246 | Result.Reverse(); | |
1247 | ||
1248 | #if DRAW | |
1249 | if (Affich) DBRep::Set("BoucheTrou", Result); | |
1250 | #endif | |
1251 | ||
1252 | return Standard_True; | |
1253 | } | |
1254 | ||
1255 | //======================================================================= | |
1256 | //function : Substitute | |
1257 | //purpose : | |
1258 | //======================================================================= | |
1259 | static void Substitute(BRepTools_Substitution& aSubstitute, | |
1260 | const TopoDS_Edge& Old, | |
1261 | const TopoDS_Edge& New) | |
1262 | { | |
1263 | TopTools_ListOfShape listShape; | |
1264 | ||
1265 | TopoDS_Vertex OldV1, OldV2, NewV1, NewV2; | |
1266 | TopExp::Vertices( Old, OldV1, OldV2 ); | |
1267 | TopExp::Vertices( New, NewV1, NewV2 ); | |
1268 | ||
1269 | if (!aSubstitute.IsCopied( OldV1 )) | |
1270 | { | |
1271 | listShape.Append( NewV1.Oriented(TopAbs_FORWARD) ); | |
1272 | aSubstitute.Substitute( OldV1, listShape ); | |
1273 | listShape.Clear(); | |
1274 | } | |
1275 | if (!aSubstitute.IsCopied( OldV2 )) | |
1276 | { | |
1277 | listShape.Append( NewV2.Oriented(TopAbs_FORWARD) ); | |
1278 | aSubstitute.Substitute( OldV2, listShape ); | |
1279 | listShape.Clear(); | |
1280 | } | |
1281 | if (!aSubstitute.IsCopied( Old )) | |
1282 | { | |
1283 | listShape.Append( New.Oriented(TopAbs_FORWARD) ); | |
1284 | aSubstitute.Substitute( Old, listShape ); | |
1285 | } | |
1286 | } | |
1287 | ||
1288 | //======================================================================= | |
1289 | //Function : SetCommonEdgeInFace | |
0d969553 | 1290 | //Purpose : Replace an edge of the face by the corresponding edge from |
7fd59977 | 1291 | // myUEdges |
1292 | //======================================================================= | |
1293 | /* | |
1294 | static void SetCommonEdgeInFace(BRepTools_Substitution& aSubstitute, | |
1295 | const TopoDS_Shape& Face, | |
1296 | const TopoDS_Shape& Edge) | |
1297 | { | |
1298 | if (Edge.IsNull()) | |
1299 | return; | |
1300 | ||
1301 | Standard_Boolean done = Standard_False; | |
1302 | // Class BRep_Tool without fields and without Constructor : | |
1303 | // BRep_Tool BT; | |
1304 | Standard_Real f, l; | |
1305 | TopExp_Explorer Exp(Face, TopAbs_EDGE); | |
1306 | Handle(Geom_Curve) Cref, C; | |
1307 | TopLoc_Location Lref, L; | |
1308 | // Cref = BT.Curve(TopoDS::Edge(Edge), Lref, f, l); | |
1309 | const TopoDS_Edge& NewEdge = TopoDS::Edge(Edge); | |
1310 | Cref = BRep_Tool::Curve( NewEdge, Lref, f, l ); | |
1311 | ||
1312 | for ( ; Exp.More() && !done; Exp.Next()) { | |
1313 | // C = BT.Curve(TopoDS::Edge(Exp.Current()), L, f, l); | |
1314 | const TopoDS_Edge& OldEdge = TopoDS::Edge(Exp.Current()); | |
1315 | C = BRep_Tool::Curve(OldEdge, L, f, l); | |
1316 | if ((Cref==C) && (Lref == L)) { | |
1317 | done = Standard_True; | |
1318 | Substitute( aSubstitute, OldEdge, NewEdge ); | |
1319 | } | |
1320 | } | |
0797d9d3 | 1321 | #ifdef OCCT_DEBUG |
7fd59977 | 1322 | if (!done) cout << "Substitution of Edge failed" << endl; |
1323 | #endif | |
1324 | } | |
1325 | */ | |
1326 | ||
1327 | //======================================================================= | |
1328 | //Fonction : KeepEdge | |
0d969553 | 1329 | //Objet : Find edges of the face supported by the same Curve. |
7fd59977 | 1330 | //======================================================================= |
1331 | static void KeepEdge(const TopoDS_Shape& Face, | |
1332 | const TopoDS_Shape& Edge, | |
1333 | TopTools_ListOfShape& List) | |
1334 | { | |
1335 | List.Clear(); | |
1336 | // Class BRep_Tool without fields and without Constructor : | |
1337 | // BRep_Tool BT; | |
1338 | Standard_Real f, l; | |
1339 | TopExp_Explorer Exp(Face, TopAbs_EDGE); | |
1340 | Handle(Geom_Curve) Cref, C; | |
1341 | TopLoc_Location Lref, L; | |
1342 | // Cref = BT.Curve(TopoDS::Edge(Edge), Lref, f, l); | |
1343 | Cref = BRep_Tool::Curve(TopoDS::Edge(Edge), Lref, f, l); | |
1344 | ||
1345 | for ( ; Exp.More(); Exp.Next()) { | |
1346 | // C = BT.Curve(TopoDS::Edge(Exp.Current()), L, f, l); | |
1347 | C = BRep_Tool::Curve(TopoDS::Edge(Exp.Current()), L, f, l); | |
1348 | if ((Cref==C) && (Lref == L)) { | |
1349 | List.Append(Exp.Current()); | |
1350 | } | |
1351 | } | |
1352 | } | |
1353 | ||
1354 | //======================================================================= | |
1355 | //Function : | |
0d969553 | 1356 | //Objet : Construct a vertex via an iso |
7fd59977 | 1357 | //======================================================================= |
1358 | static void BuildVertex(const Handle(Geom_Curve)& Iso, | |
1359 | const Standard_Boolean isfirst, | |
1360 | const Standard_Real First, | |
1361 | const Standard_Real Last, | |
1362 | TopoDS_Shape& Vertex) | |
1363 | { | |
1364 | BRep_Builder B; | |
1365 | Standard_Real val; | |
1366 | ||
1367 | if (isfirst) val = First; | |
1368 | else val = Last; | |
1369 | B.MakeVertex(TopoDS::Vertex(Vertex), | |
1370 | Iso->Value(val), | |
1371 | Precision::Confusion()); | |
1372 | } | |
1373 | ||
1374 | //======================================================================= | |
1375 | //Function : | |
0d969553 | 1376 | //Objet : Construct an empty edge |
7fd59977 | 1377 | //======================================================================= |
1378 | static TopoDS_Edge NullEdge(TopoDS_Shape& Vertex) | |
1379 | { | |
1380 | TopoDS_Edge E; | |
1381 | BRep_Builder B; | |
1382 | B.MakeEdge(E); | |
1383 | Vertex.Orientation(TopAbs_FORWARD); | |
1384 | B.Add(E, Vertex); | |
1385 | B.Add(E, Vertex.Reversed()); | |
1386 | B.Degenerated(E, Standard_True); | |
1387 | return E; | |
1388 | ||
1389 | } | |
1390 | ||
1391 | //======================================================================= | |
1392 | //Function : | |
0d969553 | 1393 | //Objet : Construct an edge via an iso |
7fd59977 | 1394 | //======================================================================= |
1395 | static TopoDS_Edge BuildEdge(const Handle(Geom_Surface)& S, | |
1396 | const Standard_Boolean isUiso, | |
1397 | const Standard_Real ValIso, | |
1398 | const TopoDS_Shape& VFirst, | |
1399 | const TopoDS_Shape& VLast, | |
1400 | const Standard_Real Tol) | |
1401 | { | |
1402 | TopoDS_Edge E; | |
1403 | BRep_Builder B; | |
1404 | Handle(Geom_Curve) Iso; | |
1405 | Standard_Boolean sing = Standard_False; | |
1406 | if (isUiso) { | |
1407 | Iso = S->UIso(ValIso); | |
1408 | } | |
1409 | else { | |
1410 | Iso = S->VIso(ValIso); | |
1411 | } | |
1412 | ||
0d969553 | 1413 | if (VFirst.IsSame(VLast)) { // Singular case ? |
7fd59977 | 1414 | gp_Pnt P; |
1415 | // Class BRep_Tool without fields and without Constructor : | |
1416 | // BRep_Tool BT; | |
1417 | const TopoDS_Vertex& V = TopoDS::Vertex(VFirst); | |
1418 | // Standard_Real tol = BT.Tolerance(V); | |
1419 | Standard_Real tol = BRep_Tool::Tolerance(V); | |
1420 | if (Tol > tol) tol = Tol; | |
1421 | Iso->D0((Iso->FirstParameter()+Iso->LastParameter())/2, P); | |
1422 | // if (P.Distance(BT.Pnt(V)) < tol) { | |
1423 | if (P.Distance(BRep_Tool::Pnt(V)) < tol) { | |
1424 | GeomAdaptor_Curve AC(Iso); | |
1425 | sing = GCPnts_AbscissaPoint::Length(AC, tol/4) < tol; | |
1426 | } | |
1427 | } | |
1428 | ||
1429 | ||
0d969553 | 1430 | if (sing) { // Singular case |
7fd59977 | 1431 | TopoDS_Shape V; |
1432 | V = VFirst; | |
1433 | E = NullEdge(V); | |
1434 | // Iso.Nullify(); | |
1435 | // B.UpdateEdge(E, Iso, Precision::Confusion()); | |
1436 | B.Degenerated(E, Standard_True); | |
1437 | } | |
1438 | ||
1439 | else { | |
0d969553 | 1440 | // Construction Via 3d |
7fd59977 | 1441 | // if (isUiso) { |
1442 | // Iso = S->UIso(ValIso); | |
1443 | gp_Pnt P1,P2; | |
1444 | Standard_Real p1, p2, p11, p12, p21, p22; | |
1445 | Standard_Boolean fwd = Standard_False; | |
1446 | p1 = Iso->FirstParameter(); | |
1447 | p2 = Iso->LastParameter(); | |
1448 | P1 = Iso->Value(p1); | |
1449 | P2 = Iso->Value(p2); | |
1450 | ||
1451 | Standard_Real t1 = BRep_Tool::Tolerance(TopoDS::Vertex(VFirst)); | |
1452 | Standard_Real t2 = BRep_Tool::Tolerance(TopoDS::Vertex(VLast)); | |
1453 | ||
1454 | BRep_Builder BB; | |
1455 | ||
1456 | p11 = P1.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VFirst))); | |
1457 | p22 = P2.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VLast))); | |
1458 | p12 = P1.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VLast))); | |
1459 | p21 = P2.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VFirst))); | |
1460 | ||
1461 | if(p11 < p12 && p22 < p21) fwd = Standard_True; | |
1462 | ||
1463 | if(fwd) { //OCC500(apo) | |
1464 | if (p11 >= t1) BB.UpdateVertex(TopoDS::Vertex(VFirst), 1.01*p11); | |
1465 | if (p22 >= t2) BB.UpdateVertex(TopoDS::Vertex(VLast), 1.01*p22); | |
1466 | } | |
1467 | else { | |
1468 | // Iso = S->VIso(ValIso); | |
1469 | if (p12 >= t2) BB.UpdateVertex(TopoDS::Vertex(VLast), 1.01*p12); | |
1470 | if (p21 >= t1) BB.UpdateVertex(TopoDS::Vertex(VFirst), 1.01*p21); | |
1471 | } | |
1472 | ||
1473 | BRepLib_MakeEdge MkE; | |
1474 | ||
1475 | // MkE.Init(Iso, | |
1476 | // TopoDS::Vertex(VFirst), | |
1477 | // TopoDS::Vertex(VLast), | |
1478 | // Iso->FirstParameter(), | |
1479 | // Iso->LastParameter()); | |
1480 | if(fwd) | |
1481 | MkE.Init(Iso, | |
1482 | TopoDS::Vertex(VFirst), | |
1483 | TopoDS::Vertex(VLast), | |
1484 | Iso->FirstParameter(), | |
1485 | Iso->LastParameter()); | |
1486 | else | |
1487 | MkE.Init(Iso, | |
1488 | TopoDS::Vertex(VLast), | |
1489 | TopoDS::Vertex(VFirst), | |
1490 | Iso->FirstParameter(), | |
1491 | Iso->LastParameter()); | |
1492 | ||
1493 | // if (!MkE.IsDone()) { // Il faut peut etre permuter les Vertex | |
1494 | // MkE.Init(Iso, | |
1495 | // TopoDS::Vertex(VLast), | |
1496 | // TopoDS::Vertex(VFirst), | |
1497 | // Iso->FirstParameter(), | |
1498 | // Iso->LastParameter()); | |
1499 | // } | |
1500 | ||
1501 | if (!MkE.IsDone()) { // Erreur de construction !! | |
1502 | #ifdef DRAW | |
1503 | char name[100]; | |
1504 | sprintf(name,"firstvertex_error"); | |
1505 | DBRep::Set(name, VFirst); | |
1506 | sprintf(name,"lastvertex_error"); | |
1507 | DBRep::Set(name, VLast); | |
1508 | sprintf(name,"curve3d_error"); | |
1509 | char* Temp = name ; | |
1510 | DrawTrSurf::Set(Temp,Iso); | |
1511 | // DrawTrSurf::Set(name,Iso); | |
1512 | #endif | |
9775fa61 | 1513 | throw Standard_ConstructionError("BRepFill_Sweep::BuildEdge"); |
7fd59977 | 1514 | } |
1515 | ||
1516 | E = MkE.Edge(); | |
1517 | } | |
1518 | ||
0d969553 | 1519 | // Associate 2d |
7fd59977 | 1520 | Handle(Geom2d_Line) L; |
1521 | TopLoc_Location Loc; | |
9ba2c30f | 1522 | Standard_Real Umin, Umax, Vmin, Vmax; |
1523 | S->Bounds(Umin, Umax, Vmin, Vmax); | |
7fd59977 | 1524 | if (isUiso) { |
9ba2c30f | 1525 | //gp_Pnt2d P(ValIso, 0); |
1526 | gp_Pnt2d P( ValIso, Vmin - Iso->FirstParameter() ); | |
7fd59977 | 1527 | gp_Vec2d V(0., 1.); |
1528 | L = new (Geom2d_Line) (P, V); | |
1529 | } | |
1530 | else { | |
9ba2c30f | 1531 | //gp_Pnt2d P(0., ValIso); |
1532 | gp_Pnt2d P( Umin -Iso->FirstParameter() , ValIso ); | |
7fd59977 | 1533 | gp_Vec2d V(1., 0.); |
1534 | L = new (Geom2d_Line) (P, V); | |
1535 | } | |
1536 | ||
1537 | B.UpdateEdge(E, L, S, Loc, Precision::Confusion()); | |
1538 | if (sing) B.Range(E, S, Loc, | |
1539 | Iso->FirstParameter(), | |
1540 | Iso->LastParameter()); | |
1541 | ||
471ce736 | 1542 | Standard_Real MaxTol = 1.e-4; |
1543 | Standard_Real theTol; | |
1544 | GeomAdaptor_Curve GAiso(Iso); | |
1545 | Handle(GeomAdaptor_HCurve) GAHiso = new GeomAdaptor_HCurve(GAiso); | |
1546 | GeomAdaptor_Surface GAsurf(S); | |
1547 | Handle(GeomAdaptor_HSurface) GAHsurf = new GeomAdaptor_HSurface(GAsurf); | |
1548 | CheckSameParameter( GAHiso, L, GAHsurf, MaxTol, theTol); | |
1549 | B.UpdateEdge(E, theTol); | |
1550 | ||
7fd59977 | 1551 | return E; |
1552 | } | |
1553 | ||
1554 | //======================================================================= | |
1555 | //Function : | |
0d969553 | 1556 | //Objet : Complete an edge via an iso |
7fd59977 | 1557 | //======================================================================= |
1558 | static void UpdateEdge(TopoDS_Edge& E, | |
1559 | const Handle(Geom_Surface)& S, | |
1560 | const Standard_Boolean isUiso, | |
1561 | const Standard_Real ValIso) | |
1562 | { | |
1563 | BRep_Builder B; | |
1564 | Handle(Geom2d_Line) L; | |
1565 | Handle(Geom2d_Curve) PCurve, CL; | |
1566 | TopLoc_Location Loc; | |
1567 | Standard_Real UFirst, ULast, VFirst, VLast, F2d, L2d; | |
1568 | S->Bounds( UFirst, ULast, VFirst, VLast); | |
1569 | ||
1570 | Standard_Boolean sing = Standard_False; | |
1571 | Handle(Geom_Curve) Iso; | |
1572 | if (isUiso) { | |
1573 | Iso = S->UIso(ValIso); | |
1574 | } | |
1575 | else { | |
1576 | Iso = S->VIso(ValIso); | |
1577 | } | |
1578 | ||
1579 | TopoDS_Vertex Vf, Vl; | |
1580 | TopExp::Vertices(E, Vf, Vl); | |
0d969553 | 1581 | if (Vf.IsSame(Vl)) { // Singular case ? |
7fd59977 | 1582 | gp_Pnt Pmid; |
1583 | Standard_Real tol = BRep_Tool::Tolerance(Vf); | |
1584 | Iso->D0((Iso->FirstParameter()+Iso->LastParameter())/2, Pmid); | |
1585 | if (Pmid.Distance(BRep_Tool::Pnt(Vf)) < tol) { | |
1586 | GeomAdaptor_Curve AC(Iso); | |
1587 | sing = GCPnts_AbscissaPoint::Length(AC, tol/4) < tol; | |
1588 | } | |
1589 | } | |
1590 | ||
1591 | if (isUiso) { | |
1592 | gp_Pnt2d P(ValIso, 0); | |
1593 | gp_Vec2d V(0., 1.); | |
1594 | L = new (Geom2d_Line) (P, V); | |
1595 | F2d = VFirst; | |
1596 | L2d = VLast; | |
1597 | } | |
1598 | else { | |
1599 | gp_Pnt2d P(0., ValIso); | |
1600 | gp_Vec2d V(1., 0.); | |
1601 | L = new (Geom2d_Line) (P, V); | |
1602 | F2d = UFirst; | |
1603 | L2d = ULast; | |
1604 | } | |
1605 | CL = new (Geom2d_TrimmedCurve) (L, F2d, L2d); | |
1606 | ||
0d969553 | 1607 | // Control direction & Range |
7fd59977 | 1608 | Standard_Real R, First, Last, Tol=1.e-4; |
1609 | Standard_Boolean reverse = Standard_False;; | |
1610 | ||
1611 | ||
1612 | // Class BRep_Tool without fields and without Constructor : | |
1613 | // BRep_Tool BT; | |
1614 | gp_Pnt POnS; | |
1615 | gp_Pnt2d P2d; | |
1616 | // BT.Range(E, First, Last); | |
1617 | BRep_Tool::Range(E, First, Last); | |
1618 | ||
1619 | if (!Vf.IsSame(Vl)) { | |
0d969553 | 1620 | // Test distances between "FirstPoint" and "Vertex" |
7fd59977 | 1621 | P2d = CL->Value(F2d); |
1622 | POnS = S->Value(P2d.X(), P2d.Y()); | |
1623 | // reverse = POnS.Distance(BT.Pnt(Vl)) < POnS.Distance(BT.Pnt(Vf)); | |
1624 | reverse = POnS.Distance(BRep_Tool::Pnt(Vl)) < POnS.Distance(BRep_Tool::Pnt(Vf)); | |
1625 | } | |
1626 | else if (!sing) { | |
0d969553 | 1627 | // Test angle between "First Tangente" |
7fd59977 | 1628 | gp_Vec2d V2d; |
1629 | gp_Vec V3d, du, dv, dC3d; | |
1630 | BRepAdaptor_Curve C3d(E); | |
1631 | ||
1632 | C3d.D1(First, POnS, dC3d); | |
1633 | CL->D1(F2d, P2d, V2d); | |
1634 | S->D1(P2d.X(), P2d.Y(), POnS, du, dv); | |
1635 | V3d.SetLinearForm(V2d.X(), du, V2d.Y(), dv); | |
1636 | reverse = ( dC3d.Angle(V3d) > Tol); | |
1637 | } | |
0d969553 | 1638 | if (reverse ) { // Return curve 2d |
7fd59977 | 1639 | CL = new (Geom2d_TrimmedCurve)(L, F2d, L2d); |
1640 | CL->Reverse(); | |
1641 | F2d = CL->FirstParameter(); | |
1642 | L2d = CL->LastParameter(); | |
1643 | } | |
1644 | ||
1645 | if (sing) | |
1646 | { | |
1647 | Handle(Geom_Curve) NullCurve; | |
1648 | B.UpdateEdge(E, NullCurve, 0.); | |
1649 | B.Degenerated(E, Standard_True); | |
1650 | B.Range(E, F2d, L2d); | |
1651 | First = F2d; | |
1652 | Last = L2d; | |
1653 | } | |
1654 | ||
1655 | if (First != F2d || Last != L2d) { | |
1656 | Handle(Geom2d_Curve) C2d; | |
1657 | GeomLib::SameRange(Precision::PConfusion(), CL, | |
1658 | F2d, L2d, First, Last, | |
1659 | C2d); | |
1660 | CL = new (Geom2d_TrimmedCurve)(C2d, First, Last); | |
1661 | } | |
1662 | ||
1663 | // Update des Vertex | |
1664 | ||
1665 | TopoDS_Vertex V; | |
1666 | ||
1667 | P2d = CL->Value(First); | |
1668 | POnS = S->Value(P2d.X(), P2d.Y()); | |
1669 | V = TopExp::FirstVertex(E); | |
1670 | // R = POnS.Distance(BT.Pnt(V)); | |
1671 | R = POnS.Distance(BRep_Tool::Pnt(V)); | |
1672 | B.UpdateVertex(V, R); | |
1673 | ||
1674 | P2d = CL->Value(Last); | |
1675 | POnS = S->Value(P2d.X(), P2d.Y()); | |
1676 | V = TopExp::LastVertex(E); | |
1677 | // R = POnS.Distance(BT.Pnt(V)); | |
1678 | R = POnS.Distance(BRep_Tool::Pnt(V)); | |
1679 | B.UpdateVertex(V, R); | |
1680 | ||
0d969553 | 1681 | // Update Edge |
7fd59977 | 1682 | if (!sing && SameParameter(E, CL, S, Tol, R)) { |
1683 | B.UpdateEdge(E, R); | |
1684 | } | |
1685 | ||
1686 | PCurve = Couture(E, S, Loc); | |
1687 | if (PCurve.IsNull()) | |
1688 | B.UpdateEdge(E, CL, S, Loc, Precision::Confusion()); | |
0d969553 | 1689 | else { // Sewing edge |
7fd59977 | 1690 | TopoDS_Edge e = E; |
1691 | Oriente(S, e); | |
1692 | if (e.Orientation() == TopAbs_REVERSED) | |
1693 | B.UpdateEdge(E, CL, PCurve, S, Loc, Precision::Confusion()); | |
1694 | else | |
1695 | B.UpdateEdge(E, PCurve, CL, S, Loc, Precision::Confusion()); | |
1696 | } | |
1697 | ||
0d969553 | 1698 | // Attention to case not SameRange on its shapes (PRO13551) |
7fd59977 | 1699 | // if (!BT.SameRange(E)) B.Range(E, S, Loc, First, Last); |
1700 | if (!BRep_Tool::SameRange(E)) B.Range(E, S, Loc, First, Last); | |
1701 | } | |
1702 | ||
1703 | //======================================================================= | |
0d969553 | 1704 | // Object : Check if a surface is degenerated |
7fd59977 | 1705 | //======================================================================= |
1706 | static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S, | |
1707 | const Standard_Real Tol) | |
1708 | { | |
1709 | Standard_Integer Nb = 5; | |
1710 | Standard_Boolean B = Standard_True; | |
1711 | Standard_Real Umax, Umin, Vmax, Vmin, t, dt, l; | |
1712 | Standard_Integer ii; | |
1713 | Handle(Geom_Curve) Iso; | |
1714 | gp_Pnt P1,P2,P3; | |
1715 | GCPnts_AbscissaPoint GC; | |
1716 | ||
1717 | S->Bounds(Umin, Umax, Vmin, Vmax); | |
1718 | ||
0d969553 | 1719 | // Check the length of Iso-U |
7fd59977 | 1720 | t = (Umin + Umax)/2; |
1721 | S->D0(t, Vmin, P1); | |
1722 | S->D0(t, (Vmin+Vmax)/2, P2); | |
1723 | S->D0(t, Vmax, P3); | |
1724 | B = ((P1.Distance(P2) + P2.Distance(P3)) < Tol); | |
1725 | ||
1726 | for (ii=1, dt = (Umax-Umin)/(Nb+1); B && (ii<=Nb); ii++) { | |
1727 | t = Umin + ii*dt; | |
1728 | Iso = S->UIso(t); | |
1729 | GeomAdaptor_Curve AC(Iso); | |
1730 | l = GC.Length(AC, Tol/4); | |
1731 | B = (l <= Tol); | |
1732 | } | |
1733 | ||
1734 | if (B) return Standard_True; | |
1735 | ||
0d969553 | 1736 | // Check the length of Iso-V |
7fd59977 | 1737 | t = (Vmin + Vmax)/2; |
1738 | S->D0(Umin, t, P1); | |
1739 | S->D0((Umin+Umax)/2, t, P2); | |
1740 | S->D0(Umax, t, P3); | |
1741 | B = ((P1.Distance(P2) + P2.Distance(P3)) < Tol); | |
1742 | ||
1743 | ||
1744 | for (ii=1, dt = (Vmax-Vmin)/(Nb+1); B && (ii<=Nb); ii++) { | |
1745 | t = Vmin + ii*dt; | |
1746 | Iso = S->VIso(t); | |
1747 | GeomAdaptor_Curve AC(Iso); | |
1748 | l = GC.Length(AC, Tol/4); | |
1749 | B = (l <= Tol); | |
1750 | } | |
1751 | ||
1752 | return B; | |
1753 | } | |
1754 | ||
833e7561 | 1755 | static void ReverseEdgeInFirstOrLastWire(TopoDS_Shape& theWire, |
1756 | const TopoDS_Shape& theEdge) | |
1757 | { | |
1758 | TopoDS_Shape EdgeToReverse; | |
1759 | TopoDS_Iterator itw(theWire); | |
1760 | ||
1761 | for (; itw.More(); itw.Next()) | |
1762 | { | |
1763 | const TopoDS_Shape& anEdge = itw.Value(); | |
1764 | if (anEdge.IsSame(theEdge)) | |
1765 | { | |
1766 | EdgeToReverse = anEdge; | |
1767 | break; | |
1768 | } | |
1769 | } | |
1770 | ||
1771 | if (!EdgeToReverse.IsNull()) | |
1772 | { | |
1773 | BRep_Builder BB; | |
1774 | theWire.Free(Standard_True); | |
1775 | BB.Remove(theWire, EdgeToReverse); | |
1776 | EdgeToReverse.Reverse(); | |
1777 | BB.Add(theWire, EdgeToReverse); | |
1778 | } | |
1779 | } | |
1780 | ||
1781 | static void ReverseModifiedEdges(TopoDS_Wire& theWire, | |
1782 | const TopTools_MapOfShape& theEmap) | |
1783 | { | |
1784 | if (theEmap.IsEmpty()) | |
1785 | return; | |
1786 | ||
1787 | TopoDS_Iterator itw(theWire); | |
1788 | BRep_Builder BB; | |
1789 | ||
1790 | TopTools_ListOfShape Ledges; | |
1791 | for (; itw.More(); itw.Next()) | |
1792 | Ledges.Append(itw.Value()); | |
1793 | ||
1794 | theWire.Free(Standard_True); | |
1795 | TopTools_ListIteratorOfListOfShape itl(Ledges); | |
1796 | for (; itl.More(); itl.Next()) | |
1797 | BB.Remove(theWire, itl.Value()); | |
1798 | ||
1799 | for (itl.Initialize(Ledges); itl.More(); itl.Next()) | |
1800 | { | |
1801 | TopoDS_Shape anEdge = itl.Value(); | |
1802 | if (theEmap.Contains(anEdge)) | |
1803 | anEdge.Reverse(); | |
1804 | BB.Add(theWire, anEdge); | |
1805 | } | |
1806 | } | |
1807 | ||
1808 | ||
7fd59977 | 1809 | //======================================================================= |
1810 | //function : Constructeur | |
1811 | //purpose : | |
1812 | //====================================================================== | |
1813 | BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, | |
1814 | const Handle(BRepFill_LocationLaw)& Location, | |
1815 | const Standard_Boolean WithKPart) : | |
1816 | isDone(Standard_False), | |
1817 | KPart(WithKPart) | |
1818 | ||
1819 | ||
1820 | { | |
1821 | mySec = Section; | |
1822 | myLoc = Location; | |
1823 | ||
1824 | SetTolerance(1.e-4); | |
1825 | SetAngularControl(); | |
1826 | myAuxShape.Clear(); | |
1827 | ||
1828 | myApproxStyle = GeomFill_Location; | |
1829 | myContinuity = GeomAbs_C2; | |
1830 | myDegmax = 11; | |
1831 | mySegmax = 30; | |
a31abc03 | 1832 | myForceApproxC1 = Standard_False; |
7fd59977 | 1833 | } |
1834 | ||
1835 | //======================================================================= | |
1836 | //function : SetBounds | |
0d969553 | 1837 | //purpose : Define start and end shapes |
7fd59977 | 1838 | //====================================================================== |
1839 | void BRepFill_Sweep::SetBounds(const TopoDS_Wire& First, | |
1840 | const TopoDS_Wire& Last) | |
1841 | { | |
1842 | FirstShape = First; | |
1843 | LastShape = Last; | |
1844 | ||
0d969553 | 1845 | // It is necessary to check the SameRange on its (PRO13551) |
0797d9d3 | 1846 | #ifdef OCCT_DEBUG |
7fd59977 | 1847 | Standard_Boolean issame = Standard_True; |
96a95605 | 1848 | #endif |
7fd59977 | 1849 | BRep_Builder B; |
1850 | BRepTools_WireExplorer wexp; | |
1851 | if (!FirstShape.IsNull()) { | |
1852 | for (wexp.Init(FirstShape); wexp.More(); wexp.Next()) { | |
1853 | if (!BRepLib::CheckSameRange(wexp.Current())) { | |
1854 | B.SameRange(wexp.Current(), Standard_False); | |
1855 | B.SameParameter(wexp.Current(), Standard_False); | |
0797d9d3 | 1856 | #ifdef OCCT_DEBUG |
7fd59977 | 1857 | issame = Standard_False; |
96a95605 | 1858 | #endif |
7fd59977 | 1859 | } |
1860 | } | |
1861 | } | |
1862 | ||
1863 | if (!LastShape.IsNull()) { | |
1864 | for (wexp.Init(LastShape); wexp.More(); wexp.Next()) { | |
1865 | if (!BRepLib::CheckSameRange(wexp.Current())) { | |
1866 | B.SameRange(wexp.Current(), Standard_False); | |
1867 | B.SameParameter(wexp.Current(), Standard_False); | |
0797d9d3 | 1868 | #ifdef OCCT_DEBUG |
7fd59977 | 1869 | issame = Standard_False; |
96a95605 | 1870 | #endif |
7fd59977 | 1871 | } |
1872 | } | |
1873 | } | |
1874 | ||
0797d9d3 | 1875 | #ifdef OCCT_DEBUG |
7fd59977 | 1876 | if (!issame) |
0d969553 | 1877 | cout<<"Sweep Warning : Edge not SameRange in the limits"<<endl; |
7fd59977 | 1878 | #endif |
1879 | } | |
1880 | ||
1881 | //======================================================================= | |
1882 | //function : SetTolerance | |
1883 | //purpose : | |
1884 | //====================================================================== | |
1885 | void BRepFill_Sweep::SetTolerance(const Standard_Real Tol3d, | |
1886 | const Standard_Real BoundTol, | |
1887 | const Standard_Real Tol2d, | |
1888 | const Standard_Real TolAngular) | |
1889 | { | |
1890 | myTol3d = Tol3d; | |
1891 | myBoundTol = BoundTol; | |
1892 | myTol2d =Tol2d; | |
1893 | myTolAngular = TolAngular; | |
1894 | } | |
1895 | //======================================================================= | |
1896 | //function : SetAngularControl | |
1897 | //purpose : | |
1898 | //====================================================================== | |
1899 | void BRepFill_Sweep::SetAngularControl(const Standard_Real MinAngle, | |
1900 | const Standard_Real MaxAngle) | |
1901 | { | |
1902 | myAngMin = Max (MinAngle, Precision::Angular()); | |
1903 | myAngMax = Min (MaxAngle, 6.28); | |
1904 | } | |
1905 | ||
a31abc03 | 1906 | //======================================================================= |
1907 | //function : SetForceApproxC1 | |
1908 | //purpose : Set the flag that indicates attempt to approximate | |
1909 | // a C1-continuous surface if a swept surface proved | |
1910 | // to be C0. | |
1911 | //======================================================================= | |
1912 | void BRepFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1) | |
1913 | { | |
1914 | myForceApproxC1 = ForceApproxC1; | |
1915 | } | |
1916 | ||
7fd59977 | 1917 | ///======================================================================= |
1918 | //function : CorrectApproxParameters | |
1919 | //purpose : | |
1920 | //======================================================================= | |
1921 | Standard_Boolean BRepFill_Sweep::CorrectApproxParameters() | |
1922 | { | |
1923 | TopoDS_Wire thePath = myLoc->Wire(); | |
1924 | GeomAbs_Shape NewCont = myContinuity; | |
1925 | Standard_Integer NewSegmax = mySegmax; | |
1926 | ||
1927 | TopoDS_Iterator iter(thePath); | |
1928 | for (; iter.More(); iter.Next()) | |
1929 | { | |
1930 | TopoDS_Edge anEdge = TopoDS::Edge(iter.Value()); | |
1931 | BRepAdaptor_Curve aBAcurve(anEdge); | |
1932 | GeomAbs_Shape aContinuity = aBAcurve.Continuity(); | |
1933 | Standard_Integer aNbInterv = aBAcurve.NbIntervals(GeomAbs_CN); | |
1934 | if (aContinuity < NewCont) | |
1935 | NewCont = aContinuity; | |
1936 | if (aNbInterv > NewSegmax) | |
1937 | NewSegmax = aNbInterv; | |
1938 | } | |
1939 | ||
1940 | Standard_Boolean Corrected = Standard_False; | |
1941 | if (NewCont != myContinuity || NewSegmax != mySegmax) | |
1942 | Corrected = Standard_True; | |
1943 | myContinuity = NewCont; | |
1944 | mySegmax = NewSegmax; | |
1945 | return Corrected; | |
1946 | } | |
1947 | ||
1948 | //======================================================================= | |
1949 | //function : BuildWire | |
0d969553 | 1950 | //purpose : Construit a wire by sweeping |
7fd59977 | 1951 | //====================================================================== |
1952 | Standard_Boolean BRepFill_Sweep:: | |
1953 | BuildWire(const BRepFill_TransitionStyle /*Transition*/) | |
1954 | { | |
1955 | Standard_Integer ipath, isec = 1; | |
1956 | gp_Pnt P1;//, P2; | |
1957 | ||
1958 | BRep_Builder B; | |
1959 | // Class BRep_Tool without fields and without Constructor : | |
1960 | // BRep_Tool BT; | |
1961 | Standard_Integer NbPath = myLoc->NbLaw(); | |
1962 | Standard_Boolean vclose; | |
1963 | vclose = (myLoc->IsClosed() && (myLoc->IsG1(0, myTol3d)>= 0)); | |
1964 | Error = 0.; | |
1965 | Handle(Geom_Surface) S; | |
1966 | Handle(Geom_Curve) Iso; | |
1967 | Standard_Real val, bid, First, Last, Tol; | |
1968 | ||
1969 | TopoDS_Wire wire; | |
1970 | TopoDS_Edge E; | |
1971 | B.MakeWire(wire); | |
1972 | ||
0d969553 | 1973 | // (1) Construction of all curves |
7fd59977 | 1974 | |
0d969553 | 1975 | // (1.1) Construction of Tables |
7fd59977 | 1976 | myFaces = new (TopTools_HArray2OfShape) (1, 1, 1, NbPath); |
1977 | myUEdges = new (TopTools_HArray2OfShape) (1, 2, 1, NbPath); | |
1978 | myVEdges = new (TopTools_HArray2OfShape) (1, 1, 1, NbPath+1); | |
1979 | ||
0d969553 | 1980 | // (1.2) Calculate curves / vertex / edge |
7fd59977 | 1981 | for (ipath=1; ipath <=NbPath; ipath++) { |
0d969553 | 1982 | // Curve by iso value |
7fd59977 | 1983 | GeomFill_Sweep Sweep(myLoc->Law(ipath), KPart); |
1984 | Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular); | |
a31abc03 | 1985 | Sweep.SetForceApproxC1(myForceApproxC1); |
7fd59977 | 1986 | Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax); |
1987 | if (!Sweep.IsDone()) | |
1988 | return Standard_False; | |
1989 | S = Sweep.Surface(); | |
1990 | if (Sweep.ExchangeUV()) { | |
1991 | if (Sweep.UReversed()) S->Bounds(First, Last, bid, val); | |
1992 | else S->Bounds(First, Last, val, bid); | |
1993 | Iso = S->VIso(val); | |
1994 | } | |
1995 | else { | |
1996 | if (Sweep.UReversed()) S->Bounds(bid, val, First, Last); | |
1997 | else S->Bounds(val, bid, First, Last); | |
1998 | Iso = S->UIso(val); | |
1999 | } | |
0d969553 | 2000 | // Vertex by position |
7fd59977 | 2001 | if (ipath < NbPath) |
2002 | BuildVertex(Iso, Standard_False, First, Last, | |
2003 | myVEdges->ChangeValue(1, ipath+1)); | |
2004 | else { | |
2005 | if (vclose) { | |
2006 | TopoDS_Vertex& V = TopoDS::Vertex(myVEdges->ChangeValue(1, 1)); | |
2007 | myVEdges->SetValue(1, ipath+1, V); | |
2008 | Iso->D0(Last, P1); | |
2009 | // Tol = P1.Distance(BT.Pnt(V)); | |
2010 | Tol = P1.Distance(BRep_Tool::Pnt(V)); | |
2011 | B.UpdateVertex(V, Tol); | |
2012 | } | |
2013 | else { | |
2014 | if (!LastShape.IsNull()) myVEdges->SetValue(1, NbPath, FirstShape); | |
2015 | else BuildVertex(Iso, Standard_False, First, Last, | |
2016 | myVEdges->ChangeValue(1, NbPath+1)); | |
2017 | } | |
2018 | } | |
2019 | ||
2020 | if (ipath > 1) { | |
2021 | Iso->D0(First, P1); | |
2022 | TopoDS_Vertex& V = TopoDS::Vertex(myVEdges->ChangeValue(1, ipath)); | |
2023 | // Tol = P1.Distance(BT.Pnt(V)); | |
2024 | Tol = P1.Distance(BRep_Tool::Pnt(V)); | |
2025 | B.UpdateVertex(V, Tol); | |
2026 | } | |
2027 | if (ipath == 1) { | |
2028 | if (!FirstShape.IsNull()) myVEdges->SetValue(1,1, FirstShape); | |
2029 | else BuildVertex(Iso, Standard_True, First, Last, | |
2030 | myVEdges->ChangeValue(1, 1)); | |
2031 | } | |
2032 | ||
0d969553 | 2033 | // Construction of the edge |
7fd59977 | 2034 | BRepLib_MakeEdge MkE; |
2035 | MkE.Init(Iso, | |
2036 | TopoDS::Vertex(myVEdges->Value(1, ipath)), | |
2037 | TopoDS::Vertex(myVEdges->Value(1, ipath+1)), | |
2038 | Iso->FirstParameter(), | |
2039 | Iso->LastParameter()); | |
0d969553 | 2040 | if (!MkE.IsDone()) { // Error of construction !! |
7fd59977 | 2041 | #ifdef DRAW |
2042 | char name[100]; | |
2043 | sprintf(name,"firstvertex_error"); | |
2044 | DBRep::Set(name, myVEdges->Value(1, ipath)); | |
2045 | sprintf(name,"lastvertex_error"); | |
2046 | DBRep::Set(name, myVEdges->Value(1, ipath+1)); | |
2047 | sprintf(name,"curve3d_error"); | |
2048 | char* Temp = name ; | |
2049 | DrawTrSurf::Set(Temp,Iso); | |
2050 | // DrawTrSurf::Set(name,Iso); | |
9775fa61 | 2051 | throw Standard_ConstructionError("BRepFill_Sweep::BuildEdge"); |
7fd59977 | 2052 | #endif |
2053 | return Standard_False; | |
2054 | } | |
2055 | E = MkE.Edge(); | |
2056 | #if DRAW | |
2057 | if (Affich) { | |
2058 | sprintf(name,"Surf_%d", ipath); | |
2059 | char* Temp = name; | |
2060 | DrawTrSurf::Set(Temp, S); | |
2061 | // DrawTrSurf::Set(name, S); | |
2062 | sprintf(name,"Edge_%d", ipath); | |
2063 | DBRep::Set(name, E); | |
2064 | } | |
2065 | #endif | |
2066 | B.UpdateEdge(E, Sweep.ErrorOnSurface()); | |
2067 | B.Add(wire, E); | |
2068 | myFaces->SetValue(1, ipath, E); | |
2069 | } | |
2070 | myShape = wire; | |
2071 | return Standard_True; | |
2072 | } | |
2073 | ||
2074 | //======================================================================= | |
2075 | //function : BuildShell | |
0d969553 | 2076 | //purpose : Construct a Shell by sweeping |
7fd59977 | 2077 | //====================================================================== |
2078 | Standard_Boolean BRepFill_Sweep:: | |
2079 | BuildShell(const BRepFill_TransitionStyle /*Transition*/, | |
2080 | const Standard_Integer IFirst, | |
2081 | const Standard_Integer ILast, | |
c8ea5b8e | 2082 | TopTools_MapOfShape& ReversedEdges, |
2083 | BRepFill_DataMapOfShapeHArray2OfShape& Tapes, | |
8e817497 | 2084 | BRepFill_DataMapOfShapeHArray2OfShape& Rails, |
7fd59977 | 2085 | const Standard_Real ExtendFirst, |
2086 | const Standard_Real ExtendLast) | |
2087 | { | |
2088 | Standard_Integer ipath, isec, IPath; | |
2089 | #ifdef DRAW | |
2090 | char name[100]; | |
2091 | #endif | |
2092 | BRep_Builder B; | |
2093 | Standard_Integer NbPath = ILast - IFirst; | |
2094 | Standard_Integer NbLaw = mySec->NbLaw(); | |
d60e8dde | 2095 | Standard_Boolean uclose, vclose, global_vclose, constSection, hasdegen = Standard_False; |
7fd59977 | 2096 | constSection = mySec->IsConstant(); |
2097 | uclose = mySec->IsUClosed(); | |
d60e8dde | 2098 | global_vclose = (myLoc->IsClosed()) && (myLoc->IsG1(0, myTol3d)>= 0); |
2099 | vclose = global_vclose && (mySec->IsVClosed()) && (NbPath == myLoc->NbLaw()); | |
7fd59977 | 2100 | Error = 0.; |
2101 | ||
0d969553 | 2102 | // (1) Construction of all surfaces |
7fd59977 | 2103 | |
0d969553 | 2104 | // (1.1) Construction of Tables |
7fd59977 | 2105 | |
dde68833 | 2106 | TColStd_Array2OfBoolean ExchUV (1, NbLaw, 1, NbPath); |
2107 | TColStd_Array2OfBoolean UReverse (1, NbLaw, 1, NbPath); | |
2108 | TColStd_Array2OfBoolean Degenerated(1, NbLaw, 1, NbPath); | |
2109 | Degenerated.Init (false); | |
0d969553 | 2110 | // No VReverse for the moment... |
7fd59977 | 2111 | TColStd_Array2OfReal TabErr(1, NbLaw , 1, NbPath); |
2112 | TColGeom_Array2OfSurface TabS(1, NbLaw , 1, NbPath); | |
2113 | ||
2114 | TopTools_Array2OfShape UEdge(1, NbLaw+1, 1, NbPath); | |
2115 | TopTools_Array2OfShape VEdge(1, NbLaw , 1, NbPath+1); | |
2116 | TopTools_Array2OfShape Vertex(1,NbLaw+1, 1, NbPath+1); | |
2117 | ||
2118 | TopoDS_Vertex VNULL; | |
2119 | VNULL.Nullify(); | |
2120 | Vertex.Init(VNULL); | |
2121 | ||
2122 | TopTools_Array1OfShape SecVertex(1, NbLaw+1); | |
2123 | TColStd_Array1OfReal VError(1, NbLaw+1); | |
2124 | TColStd_Array1OfReal Vi(1, NbPath+1); | |
2125 | ||
0d969553 Y |
2126 | //Initialization of management of parametric intervals |
2127 | //(Case of evolutionary sections) | |
7fd59977 | 2128 | Standard_Real Length, SecDom, SecDeb; |
2129 | myLoc->CurvilinearBounds(myLoc->NbLaw(), SecDom, Length); | |
2130 | mySec->Law(1)->GetDomain(SecDeb, SecDom); | |
2131 | SecDom -= SecDeb; | |
2132 | if (IFirst > 1) { | |
2133 | Standard_Real Lf, Ll; | |
2134 | myLoc->CurvilinearBounds(IFirst-1, Lf, Ll); | |
2135 | Vi(1) = SecDeb + (Ll/Length)*SecDom; | |
2136 | } | |
2137 | else | |
2138 | Vi(1) = SecDeb; | |
2139 | ||
0d969553 | 2140 | // Error a priori on vertices |
7fd59977 | 2141 | if (constSection) { |
2142 | for (isec=1; isec<=NbLaw+1; isec++) { | |
2143 | VError(isec) = mySec->VertexTol(isec-1, 0.); | |
2144 | SecVertex(isec) = mySec->Vertex(isec, 0.); | |
2145 | } | |
2146 | } | |
2147 | ||
2148 | ||
0d969553 | 2149 | // (1.2) Calculate surfaces |
7fd59977 | 2150 | for (ipath=1, IPath=IFirst; ipath <=NbPath; ipath++, IPath++) { |
2151 | ||
2152 | GeomFill_Sweep Sweep(myLoc->Law(IPath), KPart); | |
2153 | Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular); | |
a31abc03 | 2154 | Sweep.SetForceApproxC1(myForceApproxC1); |
7fd59977 | 2155 | |
0d969553 | 2156 | // Case of evolutionary section, definition of parametric correspondence |
7fd59977 | 2157 | if (!constSection) { |
2158 | Standard_Real lf, ll, Lf, Ll; | |
2159 | myLoc->Law(IPath)->GetDomain(lf, ll); | |
2160 | myLoc->CurvilinearBounds(IPath, Lf, Ll); | |
2161 | Vi(ipath+1) = SecDeb + (Ll/Length)*SecDom; | |
2162 | Sweep.SetDomain(lf, ll, Vi(ipath), Vi(ipath+1)); | |
2163 | } | |
2164 | else //section is constant | |
2165 | { | |
2166 | Standard_Real lf, ll, Lf, Ll; | |
2167 | myLoc->Law(IPath)->GetDomain(lf, ll); | |
2168 | myLoc->CurvilinearBounds(IPath, Lf, Ll); | |
2169 | Vi(ipath+1) = SecDeb + (Ll/Length)*SecDom; | |
2170 | } | |
2171 | ||
2172 | for(isec=1; isec<=NbLaw; isec++) { | |
2173 | Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax); | |
2174 | if (!Sweep.IsDone()) | |
2175 | return Standard_False; | |
2176 | TabS(isec,ipath) = Sweep.Surface(); | |
2177 | TabErr(isec,ipath) = Sweep.ErrorOnSurface(); | |
2178 | ExchUV(isec, ipath) = Sweep.ExchangeUV(); | |
2179 | UReverse(isec, ipath) = Sweep.UReversed(); | |
2180 | if (Sweep.ErrorOnSurface()>Error) Error = Sweep.ErrorOnSurface(); | |
2181 | ||
2182 | if ((ipath==1)&&(ExtendFirst>0)) { | |
2183 | Handle(Geom_BoundedSurface) BndS; | |
2184 | BndS = Handle(Geom_BoundedSurface)::DownCast(TabS(isec,ipath)); | |
2185 | GeomLib::ExtendSurfByLength(BndS, ExtendFirst, 1, | |
2186 | Sweep.ExchangeUV(), Standard_False); | |
2187 | TabS(isec,ipath) = BndS; | |
2188 | } | |
2189 | if ((ipath==NbPath)&&(ExtendLast>0)){ | |
2190 | Handle(Geom_BoundedSurface) BndS; | |
2191 | BndS = Handle(Geom_BoundedSurface)::DownCast(TabS(isec,ipath)); | |
2192 | GeomLib::ExtendSurfByLength(BndS, ExtendLast, 1, | |
2193 | Sweep.ExchangeUV(), Standard_True); | |
2194 | TabS(isec,ipath) = BndS; | |
2195 | } | |
2196 | ||
2197 | #ifdef DRAW | |
2198 | if (Affich) { | |
2199 | sprintf(name,"Surf_%d_%d", isec, IPath); | |
2200 | char* Temp = name ; | |
2201 | DrawTrSurf::Set(Temp, TabS(isec,ipath)); | |
2202 | } | |
2203 | #endif | |
2204 | } | |
2205 | } | |
2206 | ||
0d969553 | 2207 | // (2) Construction of Edges |
7fd59977 | 2208 | Standard_Real UFirst, ULast, VFirst, VLast; |
2209 | Standard_Boolean exuv, singu, singv; | |
2210 | Handle(Geom_Surface) S; | |
2211 | ||
833e7561 | 2212 | //Correct <FirstShape> and <LastShape>: reverse modified edges |
2213 | ReverseModifiedEdges(FirstShape, ReversedEdges); | |
2214 | ReverseModifiedEdges(LastShape, ReversedEdges); | |
2215 | ||
cf3327f4 | 2216 | // (2.0) return preexisting Edges and vertices |
2217 | TopoDS_Edge E; | |
c8ea5b8e | 2218 | TColStd_Array1OfBoolean IsBuilt(1, NbLaw); |
2219 | IsBuilt.Init(Standard_False); | |
2220 | TopTools_Array1OfShape StartEdges(1, NbLaw); | |
cf3327f4 | 2221 | if (! FirstShape.IsNull() && (IFirst==1)) { |
2222 | mySec->Init(FirstShape); | |
2223 | for (isec=1; isec<=NbLaw; isec++) { | |
2224 | E = mySec->CurrentEdge(); | |
8e817497 | 2225 | TopoDS_Vertex Vfirst, Vlast; |
2226 | TopExp::Vertices(E, Vfirst, Vlast); | |
cf3327f4 | 2227 | VEdge(isec, 1) = E; |
2228 | if (E.Orientation() == TopAbs_REVERSED) | |
8e817497 | 2229 | Vertex(isec+1, 1) = Vfirst; //TopExp::FirstVertex(E); |
cf3327f4 | 2230 | else |
8e817497 | 2231 | Vertex(isec+1, 1) = Vlast; //TopExp::LastVertex(E); |
cf3327f4 | 2232 | UpdateVertex(IFirst-1, isec+1, |
2233 | TabErr(isec, 1), Vi(1), Vertex(isec+1, 1)); | |
c8ea5b8e | 2234 | |
2235 | StartEdges(isec) = E; | |
2236 | if (Tapes.IsBound(E)) | |
2237 | { | |
2238 | IsBuilt(isec) = Standard_True; | |
2239 | ||
2240 | //Initialize VEdge, UEdge, Vertex and myFaces | |
2241 | Standard_Integer j; | |
2242 | for (j = 1; j <= NbPath+1; j++) | |
2243 | { | |
2244 | VEdge(isec, j) = Tapes(E)->Value(1, j); | |
2245 | VEdge(isec, j).Reverse(); //direction of round is reversed | |
2246 | } | |
2247 | Standard_Integer ifirst = isec+1, ilast = isec; //direction of round is reversed | |
2248 | for (j = 1; j <= NbPath; j++) | |
2249 | UEdge(ifirst, j) = Tapes(E)->Value(2, j); | |
2250 | for (j = 1; j <= NbPath; j++) | |
2251 | UEdge(ilast, j) = Tapes(E)->Value(3, j); | |
2252 | for (j = 1; j <= NbPath+1; j++) | |
2253 | Vertex(ifirst, j) = Tapes(E)->Value(4, j); | |
2254 | for (j = 1; j <= NbPath+1; j++) | |
2255 | Vertex(ilast, j) = Tapes(E)->Value(5, j); | |
2256 | for (j = 1; j <= NbPath; j++) | |
2257 | myFaces->SetValue(isec, j, Tapes(E)->Value(6, j)); | |
2258 | ||
2259 | if (uclose && isec == 1) | |
2260 | { | |
2261 | for (j = 1; j <= NbPath; j++) | |
2262 | UEdge(NbLaw+1, j) = UEdge(1, j); | |
2263 | for (j = 1; j <= NbPath+1; j++) | |
2264 | Vertex(NbLaw+1, j) = Vertex(1, j); | |
2265 | } | |
2266 | if (uclose && isec == NbLaw) | |
2267 | { | |
2268 | for (j = 1; j <= NbPath; j++) | |
2269 | UEdge(1, j) = UEdge(NbLaw+1, j); | |
2270 | for (j = 1; j <= NbPath+1; j++) | |
2271 | Vertex(1, j) = Vertex(NbLaw+1, j); | |
2272 | } | |
2273 | } | |
2274 | else | |
2275 | { | |
2276 | Handle(TopTools_HArray2OfShape) EmptyArray = new TopTools_HArray2OfShape(1, 6, 1, NbPath+1); | |
2277 | Tapes.Bind(E, EmptyArray); | |
8e817497 | 2278 | Standard_Integer j; |
2279 | if (Rails.IsBound(Vfirst)) | |
2280 | { | |
2281 | Standard_Integer ind = (E.Orientation() == TopAbs_REVERSED)? isec+1 : isec; | |
2282 | for (j = 1; j <= NbPath; j++) | |
2283 | UEdge(ind, j) = Rails(Vfirst)->Value(1, j); | |
2284 | for (j = 1; j <= NbPath+1; j++) | |
2285 | Vertex(ind, j) = Rails(Vfirst)->Value(2, j); | |
2286 | } | |
2287 | if (Rails.IsBound(Vlast)) | |
2288 | { | |
2289 | Standard_Integer ind = (E.Orientation() == TopAbs_FORWARD)? isec+1 : isec; | |
2290 | for (j = 1; j <= NbPath; j++) | |
2291 | UEdge(ind, j) = Rails(Vlast)->Value(1, j); | |
2292 | for (j = 1; j <= NbPath+1; j++) | |
2293 | Vertex(ind, j) = Rails(Vlast)->Value(2, j); | |
2294 | } | |
c8ea5b8e | 2295 | } |
7fd59977 | 2296 | } |
c8ea5b8e | 2297 | |
cf3327f4 | 2298 | if (VEdge(1, 1).Orientation() == TopAbs_REVERSED) |
2299 | Vertex(1, 1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, 1))); | |
2300 | else | |
2301 | Vertex(1, 1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, 1))); | |
2302 | UpdateVertex(IFirst-1, 1, | |
2303 | TabErr(1, 1), Vi(1), Vertex(1, 1)); | |
2304 | } | |
c8ea5b8e | 2305 | |
2306 | Standard_Real u, v, aux; | |
2307 | Standard_Boolean ureverse; | |
2308 | for (isec=1; isec<=NbLaw+1; isec++) { | |
2309 | // Return data | |
2310 | if (isec >NbLaw) { | |
2311 | S = TabS(NbLaw, 1); | |
2312 | ureverse = UReverse(NbLaw, 1); | |
2313 | exuv = ExchUV(NbLaw, 1); | |
2314 | } | |
2315 | else { | |
2316 | S = TabS(isec, 1); | |
2317 | ureverse = UReverse(isec, 1); | |
2318 | exuv = ExchUV(isec, 1); | |
2319 | } | |
2320 | S->Bounds(UFirst, ULast, VFirst, VLast); | |
2321 | ||
2322 | // Choice of parameters | |
2323 | if (ureverse) { | |
2324 | if (exuv) { | |
2325 | aux = VFirst; VFirst = VLast; VLast = aux; | |
7fd59977 | 2326 | } |
cf3327f4 | 2327 | else { |
c8ea5b8e | 2328 | aux = UFirst; UFirst = ULast; ULast = aux; |
cf3327f4 | 2329 | } |
c8ea5b8e | 2330 | } |
2331 | if (isec!= NbLaw+1) { | |
2332 | u = UFirst; | |
2333 | v = VFirst; | |
2334 | } | |
2335 | else { | |
2336 | if (exuv) { | |
cf3327f4 | 2337 | u = UFirst; |
8e817497 | 2338 | v = VLast; |
cf3327f4 | 2339 | } |
2340 | else { | |
c8ea5b8e | 2341 | u = ULast; |
2342 | v = VFirst; | |
7fd59977 | 2343 | } |
c8ea5b8e | 2344 | } |
2345 | ||
2346 | // construction of vertices | |
2347 | if (Vertex(isec, 1).IsNull()) | |
cf3327f4 | 2348 | B.MakeVertex(TopoDS::Vertex(Vertex(isec, 1)), |
2349 | S->Value(u,v), | |
2350 | mySec->VertexTol(isec-1,Vi(1))); | |
c8ea5b8e | 2351 | else |
2352 | { | |
2353 | TopLoc_Location Identity; | |
2354 | Vertex(isec, 1).Location(Identity); | |
2355 | B.UpdateVertex(TopoDS::Vertex(Vertex(isec, 1)), | |
2356 | S->Value(u,v), | |
2357 | mySec->VertexTol(isec-1,Vi(1))); | |
cf3327f4 | 2358 | } |
c8ea5b8e | 2359 | } //end of for (isec=1; isec<=NbLaw+1; isec++) |
2360 | ||
cf3327f4 | 2361 | if (! LastShape.IsNull() && (ILast==myLoc->NbLaw()+1) ) { |
2362 | mySec->Init(LastShape); | |
2363 | for (isec=1; isec<=NbLaw; isec++) { | |
2364 | E = mySec->CurrentEdge(); | |
c8ea5b8e | 2365 | if (VEdge(isec, NbPath+1).IsNull()) |
2366 | VEdge(isec, NbPath+1) = E; | |
2367 | ||
2368 | if (Vertex(isec+1, NbPath+1).IsNull()) | |
2369 | { | |
2370 | if (VEdge(isec, NbPath+1).Orientation() == TopAbs_REVERSED) | |
2371 | Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(isec, NbPath+1))); | |
2372 | else | |
2373 | Vertex(isec+1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(isec, NbPath+1))); | |
2374 | } | |
cf3327f4 | 2375 | UpdateVertex(ILast-1, isec+1, TabErr(isec, NbPath), |
2376 | Vi(NbPath+1), Vertex(isec+1, NbPath+1)); | |
2377 | } | |
c8ea5b8e | 2378 | |
2379 | if (Vertex(1, NbPath+1).IsNull()) | |
2380 | { | |
2381 | if (VEdge(1, NbPath+1).Orientation() == TopAbs_REVERSED) | |
2382 | Vertex(1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, NbPath+1))); | |
2383 | else | |
2384 | Vertex(1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1))); | |
2385 | } | |
cf3327f4 | 2386 | UpdateVertex(ILast-1, 1, |
2387 | TabErr(1, NbPath), Vi(NbPath+1), Vertex(1, NbPath+1 )); | |
c8ea5b8e | 2388 | } |
2389 | ||
2390 | for (isec=1; isec<=NbLaw+1; isec++) { | |
2391 | // Return data | |
2392 | if (isec >NbLaw) { | |
cf3327f4 | 2393 | S = TabS(NbLaw, NbPath); |
2394 | ureverse = UReverse(NbLaw, NbPath); | |
2395 | exuv = ExchUV(NbLaw, NbPath); | |
c8ea5b8e | 2396 | } |
2397 | else { | |
2398 | S = TabS(isec, NbPath); | |
2399 | ureverse = UReverse(isec, NbPath); | |
2400 | exuv = ExchUV(isec, NbPath); | |
2401 | } | |
2402 | S->Bounds(UFirst, ULast, VFirst, VLast); | |
2403 | ||
2404 | // Choice of parametres | |
2405 | if (ureverse) { | |
2406 | if (exuv) { | |
2407 | aux = VFirst; VFirst = VLast; VLast = aux; | |
cf3327f4 | 2408 | } |
2409 | else { | |
c8ea5b8e | 2410 | aux = UFirst; UFirst = ULast; ULast = aux; |
cf3327f4 | 2411 | } |
c8ea5b8e | 2412 | } |
2413 | if (isec == NbLaw+1) { | |
2414 | u = ULast; | |
2415 | v = VLast; | |
2416 | } | |
2417 | else { | |
2418 | if (exuv) { | |
cf3327f4 | 2419 | u = ULast; |
c8ea5b8e | 2420 | v = VFirst; |
7fd59977 | 2421 | } |
cf3327f4 | 2422 | else { |
c8ea5b8e | 2423 | u = UFirst; |
2424 | v = VLast; | |
cf3327f4 | 2425 | } |
c8ea5b8e | 2426 | } |
2427 | ||
2428 | // construction of vertex | |
2429 | if (Vertex(isec, NbPath+1).IsNull()) | |
cf3327f4 | 2430 | B.MakeVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), |
2431 | S->Value(u,v), | |
2432 | mySec->VertexTol(isec-1, Vi(NbPath+1))); | |
c8ea5b8e | 2433 | else |
2434 | { | |
2435 | TopLoc_Location Identity; | |
2436 | Vertex(isec, NbPath+1).Location(Identity); | |
2437 | B.UpdateVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), | |
2438 | S->Value(u,v), | |
2439 | mySec->VertexTol(isec-1, Vi(NbPath+1))); | |
2440 | } | |
2441 | } //end of for (isec=1; isec<=NbLaw+1; isec++) | |
7fd59977 | 2442 | |
2443 | ||
0d969553 | 2444 | // ---------- Creation of Vertex and edge ------------ |
7fd59977 | 2445 | for (ipath=1, IPath=IFirst; ipath<=NbPath; |
2446 | ipath++, IPath++) { | |
2447 | for (isec=1; isec <=NbLaw; isec++) { | |
c8ea5b8e | 2448 | if (IsBuilt(isec)) |
2449 | continue; | |
2450 | ||
7fd59977 | 2451 | S = TabS(isec, ipath); |
2452 | exuv = ExchUV(isec, ipath); | |
2453 | S->Bounds(UFirst, ULast, VFirst, VLast); | |
2454 | if (UReverse(isec, ipath)) { | |
51740958 | 2455 | Standard_Real aux2; |
7fd59977 | 2456 | if (exuv) { |
51740958 | 2457 | aux2 = VFirst; VFirst = VLast; VLast = aux2; |
7fd59977 | 2458 | } |
2459 | else { | |
51740958 | 2460 | aux2 = UFirst; UFirst = ULast; ULast = aux2; |
7fd59977 | 2461 | } |
2462 | } | |
2463 | ||
0d969553 | 2464 | // (2.1) Construction of new vertices |
7fd59977 | 2465 | if (isec == 1) { |
2466 | if (ipath == 1 && Vertex(1, 1).IsNull()) { | |
0d969553 | 2467 | // All first |
7fd59977 | 2468 | if (constSection) |
2469 | myLoc->PerformVertex(IPath-1, | |
2470 | TopoDS::Vertex(SecVertex(1)), | |
2471 | VError(1), | |
2472 | TopoDS::Vertex(Vertex(1, 1))); | |
2473 | else | |
2474 | myLoc->PerformVertex(IPath-1, | |
2475 | mySec->Vertex(1,Vi(1)), | |
2476 | mySec->VertexTol(0,Vi(1)), | |
2477 | TopoDS::Vertex(Vertex(1, 1))); | |
2478 | } | |
0d969553 | 2479 | // the first and the next column |
7fd59977 | 2480 | if (vclose &&(ipath == NbPath) ) { |
2481 | Vertex(1, ipath+1) = Vertex(1, 1); | |
2482 | } | |
2483 | else if (Vertex(1, ipath+1).IsNull()) { | |
2484 | if (constSection) | |
2485 | myLoc->PerformVertex(IPath, | |
2486 | TopoDS::Vertex(SecVertex(1)), | |
2487 | TabErr(1,ipath)+VError(1), | |
2488 | TopoDS::Vertex(Vertex(1, ipath+1)) ); | |
2489 | else | |
2490 | myLoc->PerformVertex(IPath, | |
2491 | mySec->Vertex(1,Vi(ipath+1)), | |
2492 | TabErr(1,ipath) + | |
2493 | mySec->VertexTol(0,Vi(ipath+1)), | |
2494 | TopoDS::Vertex(Vertex(1, ipath+1))); | |
2495 | ||
2496 | if (MergeVertex(Vertex(1,ipath), Vertex(1,ipath+1))) { | |
2497 | UEdge(1, ipath) = NullEdge(Vertex(1,ipath)); | |
2498 | } | |
2499 | } | |
2500 | } | |
2501 | ||
eafb234b | 2502 | if (ipath == 1) { |
2503 | if (uclose && (isec == NbLaw)) { | |
2504 | Vertex(isec+1, 1) = Vertex(1, 1); | |
2505 | } | |
2506 | else if (Vertex(isec+1, 1).IsNull()) { | |
2507 | if (constSection) | |
2508 | myLoc->PerformVertex(IPath-1, | |
2509 | TopoDS::Vertex(SecVertex(isec+1)), | |
2510 | TabErr(isec,1)+VError(isec+1), | |
2511 | TopoDS::Vertex(Vertex(isec+1, 1)) ); | |
2512 | else | |
2513 | myLoc->PerformVertex(IPath-1, | |
2514 | mySec->Vertex(isec+1,Vi(1)), | |
2515 | TabErr(isec,1) + | |
2516 | mySec->VertexTol(isec,Vi(1)), | |
2517 | TopoDS::Vertex(Vertex(isec+1, 1)) ); | |
c8ea5b8e | 2518 | |
eafb234b | 2519 | if (MergeVertex(Vertex(isec,1), Vertex(isec+1,1))) { |
2520 | VEdge(isec, 1) = NullEdge(Vertex(isec, 1)); | |
2521 | } | |
2522 | } | |
2523 | } | |
7fd59977 | 2524 | |
2525 | if (uclose && (isec == NbLaw)) { | |
2526 | Vertex(isec+1, ipath+1) = Vertex(1, ipath+1); | |
2527 | } | |
2528 | else if (vclose && (ipath == NbPath)) { | |
2529 | Vertex(isec+1, ipath+1) = Vertex(isec+1, 1); | |
2530 | } | |
2531 | else if (Vertex(isec+1, ipath+1).IsNull()) { | |
2532 | if (constSection) | |
2533 | myLoc->PerformVertex(IPath, | |
2534 | TopoDS::Vertex(SecVertex(isec+1)), | |
2535 | TabErr(isec, ipath)+ VError(isec+1), | |
2536 | TopoDS::Vertex(Vertex(isec+1, ipath+1)) ); | |
2537 | else | |
2538 | myLoc->PerformVertex(IPath, | |
2539 | mySec->Vertex(isec+1,Vi(ipath+1)), | |
2540 | TabErr(isec, ipath) + | |
2541 | mySec->VertexTol(isec, Vi(ipath+1)), | |
2542 | TopoDS::Vertex(Vertex(isec+1, ipath+1)) ); | |
2543 | } | |
2544 | ||
0d969553 | 2545 | // Singular cases |
7fd59977 | 2546 | singv = MergeVertex(Vertex(isec,ipath+1), Vertex(isec+1,ipath+1)); |
2547 | singu = MergeVertex(Vertex(isec+1,ipath), Vertex(isec+1,ipath+1)); | |
2548 | ||
2549 | ||
2550 | ||
2551 | if (singu || singv) { | |
2552 | Degenerated(isec, ipath) = IsDegen(TabS(isec,ipath), | |
2553 | Max(myTol3d, TabErr(isec,ipath))); | |
2554 | } | |
2555 | if (Degenerated(isec, ipath)) { | |
0797d9d3 | 2556 | #ifdef OCCT_DEBUG |
0d969553 | 2557 | cout << "Sweep : Degenerated case" << endl; |
7fd59977 | 2558 | #endif |
2559 | hasdegen = Standard_True; | |
0d969553 | 2560 | // Particular construction of edges |
7fd59977 | 2561 | if (UEdge(isec+1, ipath).IsNull()) { |
2562 | if (singu) { | |
0d969553 | 2563 | // Degenerated edge |
7fd59977 | 2564 | UEdge(isec+1, ipath) = NullEdge(Vertex(isec+1,ipath)); |
2565 | } | |
0d969553 | 2566 | else { // Copy the previous edge |
7fd59977 | 2567 | UEdge(isec+1, ipath) = UEdge(isec, ipath); |
2568 | } | |
2569 | } | |
2570 | if (VEdge(isec, ipath+1).IsNull()) { | |
2571 | if (singv) { | |
0d969553 | 2572 | // Degenerated Edge |
7fd59977 | 2573 | VEdge(isec, ipath+1) = NullEdge(Vertex(isec,ipath+1)); |
2574 | } | |
0d969553 | 2575 | else { // Copy the previous edge |
7fd59977 | 2576 | VEdge(isec, ipath+1) = VEdge(isec, ipath); |
2577 | } | |
2578 | } | |
2579 | } | |
0d969553 | 2580 | else { // Construction of edges by isos |
7fd59977 | 2581 | if (exuv) { |
2582 | Standard_Real UV; | |
2583 | UV = UFirst; UFirst = VFirst; VFirst = UV; | |
2584 | UV = ULast ; ULast = VLast ; VLast = UV; | |
2585 | } | |
2586 | ||
2587 | // (2.2) Iso-u | |
c8ea5b8e | 2588 | if (isec == 1 && UEdge(1, ipath).IsNull()) { |
7fd59977 | 2589 | if (!Vertex(1,ipath).IsSame(Vertex(1,ipath+1))) { |
2590 | gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath))); | |
2591 | gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath+1))); | |
2592 | if (P1.Distance(P2) <= myTol3d) | |
2593 | Vertex(1,ipath+1) = Vertex(1,ipath); | |
2594 | } | |
2595 | UEdge(1, ipath) = BuildEdge(S, !exuv, UFirst, | |
2596 | Vertex(1,ipath), | |
2597 | Vertex(1,ipath+1), | |
2598 | myTol3d); | |
2599 | } | |
73920cd4 | 2600 | else |
2601 | { | |
2602 | if (UEdge(isec, ipath).IsNull()) //sweep failed | |
2603 | return Standard_False; | |
2604 | UpdateEdge(TopoDS::Edge(UEdge(isec, ipath)), | |
2605 | S, !exuv, UFirst); | |
2606 | } | |
7fd59977 | 2607 | |
2608 | if (uclose && (isec==NbLaw)) { | |
21b7d8be | 2609 | if (UEdge(1, ipath).IsNull()) //degenerated case |
2610 | { | |
2611 | UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, | |
2612 | Vertex(isec+1, ipath), | |
2613 | Vertex(isec+1, ipath+1), | |
2614 | myTol3d); | |
2615 | } | |
2616 | else { | |
2617 | UpdateEdge(TopoDS::Edge(UEdge(1, ipath)), | |
2618 | S, !exuv, ULast); | |
2619 | UEdge(isec+1, ipath) = UEdge(1, ipath); | |
2620 | } | |
7fd59977 | 2621 | } |
2622 | else { | |
c8ea5b8e | 2623 | if (UEdge(isec+1, ipath).IsNull()) |
2624 | UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, | |
2625 | Vertex(isec+1, ipath), | |
2626 | Vertex(isec+1, ipath+1), | |
2627 | myTol3d); | |
2628 | else | |
2629 | UpdateEdge(TopoDS::Edge(UEdge(isec+1, ipath)), S, !exuv, ULast); | |
7fd59977 | 2630 | } |
2631 | ||
2632 | // (2.3) Iso-v | |
c8ea5b8e | 2633 | if (ipath == 1) |
2634 | { | |
2635 | TopoDS_Edge aNewFirstEdge = BuildEdge(S, exuv, VFirst, | |
2636 | Vertex(isec , 1), | |
2637 | Vertex(isec+1, 1), | |
2638 | myTol3d); | |
2639 | if (VEdge(isec, ipath).IsNull()) | |
2640 | VEdge(isec, ipath) = aNewFirstEdge; | |
2641 | else //rebuild first edge | |
d3dfddae | 2642 | { |
c8ea5b8e | 2643 | RebuildTopOrBottomEdge(aNewFirstEdge, |
2644 | TopoDS::Edge(VEdge(isec, ipath)), | |
2645 | ReversedEdges); | |
d3dfddae | 2646 | if (ReversedEdges.Contains(VEdge(isec, ipath))) |
833e7561 | 2647 | { |
2648 | ReverseEdgeInFirstOrLastWire(FirstShape, VEdge(isec, ipath)); | |
d3dfddae | 2649 | StartEdges(isec).Reverse(); |
833e7561 | 2650 | } |
d3dfddae | 2651 | } |
c8ea5b8e | 2652 | } |
7fd59977 | 2653 | |
2654 | else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath)), | |
2655 | S, exuv, VFirst); | |
2656 | ||
2657 | if (vclose && (ipath == NbPath)) { | |
21b7d8be | 2658 | if (VEdge(isec, 1).IsNull()) //degenerated case |
2659 | { | |
2660 | VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast, | |
2661 | Vertex(isec , ipath+1), | |
2662 | Vertex(isec+1, ipath+1), | |
2663 | myTol3d); | |
2664 | } | |
2665 | else { | |
2666 | UpdateEdge(TopoDS::Edge(VEdge(isec, 1)), | |
2667 | S, exuv, VLast); | |
2668 | VEdge(isec, ipath+1) = VEdge(isec, 1); | |
2669 | } | |
7fd59977 | 2670 | } |
2671 | else if (VEdge(isec, ipath+1).IsNull()) | |
2672 | VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast, | |
2673 | Vertex(isec , ipath+1), | |
2674 | Vertex(isec+1, ipath+1), | |
2675 | myTol3d); | |
c8ea5b8e | 2676 | else |
2677 | { | |
d60e8dde | 2678 | if (ipath != NbPath || |
2679 | vclose || | |
2680 | (global_vclose && ILast == myLoc->NbLaw()+1)) | |
2681 | ||
c8ea5b8e | 2682 | UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), |
2683 | S, exuv, VLast); | |
2684 | else //ipath == NbPath && !vclose => rebuild last edge | |
2685 | { | |
2686 | TopoDS_Edge aNewLastEdge = BuildEdge(S, exuv, VLast, | |
2687 | Vertex(isec , ipath+1), | |
2688 | Vertex(isec+1, ipath+1), | |
2689 | myTol3d); | |
2690 | RebuildTopOrBottomEdge(aNewLastEdge, | |
2691 | TopoDS::Edge(VEdge(isec, ipath+1)), | |
2692 | ReversedEdges); | |
833e7561 | 2693 | if (ReversedEdges.Contains(VEdge(isec, ipath+1))) |
2694 | ReverseEdgeInFirstOrLastWire(LastShape, VEdge(isec, ipath+1)); | |
c8ea5b8e | 2695 | } |
2696 | } | |
7fd59977 | 2697 | } |
0d969553 | 2698 | }// End of construction of edges |
7fd59977 | 2699 | } |
2700 | ||
0d969553 | 2701 | // (3) Construction of Faces |
7fd59977 | 2702 | TopoDS_Face face; |
2703 | ||
2704 | #ifdef DRAW | |
2705 | if (Affich) { | |
2706 | for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) { | |
2707 | for (isec=1; isec <=NbLaw+1; isec++){ | |
2708 | sprintf(name,"uedge_%d_%d", isec, IPath); | |
2709 | DBRep::Set(name,UEdge(isec, ipath)); | |
2710 | } | |
2711 | } | |
2712 | ||
2713 | for (ipath=1, IPath=IFirst; ipath<=NbPath+1; ipath++, IPath++) { | |
2714 | for (isec=1; isec <=NbLaw; isec++){ | |
2715 | sprintf(name,"vedge_%d_%d", isec, IPath); | |
2716 | DBRep::Set(name,VEdge(isec, ipath)); | |
2717 | } | |
2718 | ||
2719 | for (isec=1; isec <=NbLaw+1; isec++){ | |
2720 | sprintf(name,"vertex_%d_%d", isec, IPath); | |
2721 | DBRep::Set(name,Vertex(isec, ipath)); | |
2722 | } | |
2723 | } | |
2724 | } | |
2725 | #endif | |
2726 | ||
2727 | for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) { | |
2728 | for (isec=1; isec <=NbLaw; isec++) { | |
2729 | if (Degenerated(isec, ipath)) { | |
2730 | if (UEdge(isec, ipath).IsSame(UEdge(isec+1, ipath))) | |
2731 | myFaces->SetValue(isec, IPath, UEdge(isec, ipath)); | |
2732 | else | |
2733 | myFaces->SetValue(isec, IPath, VEdge(isec, ipath)); | |
2734 | } | |
c8ea5b8e | 2735 | else if (myFaces->Value(isec, IPath).IsNull()) { |
7fd59977 | 2736 | BuildFace(TabS(isec,ipath), |
2737 | TopoDS::Edge(UEdge(isec, ipath)), | |
2738 | TopoDS::Edge(VEdge(isec, ipath)), | |
2739 | TopoDS::Edge(UEdge(isec+1, ipath)), | |
2740 | TopoDS::Edge(VEdge(isec, ipath+1)), | |
2741 | myVEdgesModified, | |
2742 | ExchUV(isec, ipath), | |
2743 | UReverse(isec, ipath), | |
2744 | face); | |
2745 | myFaces->SetValue(isec, IPath, face); | |
2746 | } | |
2747 | } | |
2748 | } | |
2749 | ||
c8ea5b8e | 2750 | // (3.1) Reverse the faces that have been built ealier |
2751 | for (ipath = 1; ipath <= NbPath; ipath++) | |
2752 | for (isec = 1; isec <= NbLaw; isec++) | |
2753 | if (IsBuilt(isec)) | |
2754 | myFaces->ChangeValue(isec, ipath).Reverse(); | |
2755 | ||
7fd59977 | 2756 | |
0d969553 | 2757 | // (4) History and Continuity |
7fd59977 | 2758 | |
2759 | if (hasdegen) { | |
0d969553 | 2760 | //(4.1) // Degenerated case => Sledgehammer |
7fd59977 | 2761 | TopoDS_Compound Comp; |
2762 | B.MakeCompound(Comp); | |
2763 | for (isec=1; isec <= NbLaw+1; isec++) | |
2764 | for (ipath=1, IPath=IFirst; ipath<= NbPath+1; ipath++, IPath++) { | |
ef444297 | 2765 | if (ipath <= NbPath) myUEdges->SetValue(isec, IPath, UEdge(isec, ipath)); |
2766 | if (isec <= NbLaw) myVEdges->SetValue(isec, IPath, VEdge(isec, ipath)); | |
2767 | if ((ipath <= NbPath) && (isec <= NbLaw) && | |
2768 | !myFaces->Value(isec, IPath).IsNull() && | |
2769 | myFaces->Value(isec, IPath).ShapeType() == TopAbs_FACE) | |
2770 | B.Add(Comp, myFaces->Value(isec, IPath)); | |
7fd59977 | 2771 | } |
2772 | BRepLib::EncodeRegularity(Comp, myTolAngular); | |
2773 | } | |
2774 | else { | |
0d969553 | 2775 | //(4.2) // General case => Tweezers |
7fd59977 | 2776 | Standard_Boolean isG1; |
2777 | TopoDS_Face FF; | |
51740958 | 2778 | TopoDS_Edge anEdge; |
7fd59977 | 2779 | |
2780 | for (isec=1; isec <= NbLaw+1; isec++) { | |
2781 | if (isec>1) isG1 = | |
2782 | (mySec->Continuity(isec-1, myTolAngular) >= GeomAbs_G1); | |
2783 | else isG1 = Standard_False; | |
2784 | for (ipath=1, IPath=IFirst; ipath<= NbPath; ipath++, IPath++) { | |
2785 | myUEdges->SetValue(isec, IPath, UEdge(isec, ipath)); | |
2786 | if (isG1) { | |
2787 | if (isec == NbLaw+1) FF = TopoDS::Face(myFaces->Value(1, IPath)); | |
2788 | else FF = TopoDS::Face(myFaces->Value(isec, IPath)); | |
2789 | B.Continuity(TopoDS::Edge(myUEdges->Value(isec, IPath)), | |
2790 | TopoDS::Face(myFaces->Value(isec-1, IPath)), | |
2791 | FF, GeomAbs_G1); | |
2792 | } | |
2793 | } | |
2794 | } | |
2795 | ||
2796 | Standard_Integer nbpath = NbPath; | |
0d969553 | 2797 | if (vclose) nbpath++; //Another test G1 |
7fd59977 | 2798 | for (ipath=1, IPath=IFirst; ipath<= NbPath+1; ipath++, IPath++) { |
2799 | if ((ipath > 1) && (ipath <=nbpath)) | |
2800 | isG1 = (myLoc->IsG1(IPath-1, myTol3d, myTolAngular) >= 0); | |
2801 | else isG1 = Standard_False; | |
2802 | for (isec=1; isec <= NbLaw; isec++) { | |
2803 | myVEdges->SetValue(isec, IPath, VEdge(isec, ipath)); | |
2804 | if (isG1) { | |
2805 | if (ipath==NbPath+1) FF = TopoDS::Face(myFaces->Value(isec, 1)); | |
2806 | else FF = TopoDS::Face(myFaces->Value(isec, IPath)); | |
51740958 | 2807 | anEdge = TopoDS::Edge(myVEdges->Value(isec, IPath)); |
2808 | BRepLib::EncodeRegularity(anEdge, FF, | |
7fd59977 | 2809 | TopoDS::Face(myFaces->Value(isec, IPath-1)), |
2810 | myTolAngular); | |
2811 | } | |
2812 | } | |
2813 | } | |
2814 | } | |
c8ea5b8e | 2815 | |
8e817497 | 2816 | // (5) Update Tapes and Rails |
c8ea5b8e | 2817 | Standard_Integer j; |
2818 | if (IFirst == 1 && !Tapes.IsEmpty()) //works only in case of single shell | |
2819 | { | |
2820 | for (isec = 1; isec <= NbLaw; isec++) | |
2821 | { | |
2822 | for (j = 1; j <= NbPath+1; j++) | |
2823 | Tapes(StartEdges(isec))->SetValue(1, j, myVEdges->Value(isec, j)); | |
2824 | for (j = 1; j <= NbPath; j++) | |
2825 | Tapes(StartEdges(isec))->SetValue(2, j, myUEdges->Value(isec, j)); | |
2826 | for (j = 1; j <= NbPath; j++) | |
2827 | Tapes(StartEdges(isec))->SetValue(3, j, myUEdges->Value(isec+1, j)); | |
2828 | for (j = 1; j <= NbPath+1; j++) | |
2829 | Tapes(StartEdges(isec))->SetValue(4, j, Vertex(isec, j)); | |
2830 | for (j = 1; j <= NbPath+1; j++) | |
2831 | Tapes(StartEdges(isec))->SetValue(5, j, Vertex(isec+1, j)); | |
2832 | for (j = 1; j <= NbPath; j++) | |
2833 | Tapes(StartEdges(isec))->SetValue(6, j, myFaces->Value(isec, j)); | |
8e817497 | 2834 | TopoDS_Vertex Vfirst, Vlast; |
d3dfddae | 2835 | TopExp::Vertices(TopoDS::Edge(StartEdges(isec)), Vfirst, Vlast, Standard_True); //with orientation |
8e817497 | 2836 | if (!Rails.IsBound(Vfirst)) |
2837 | { | |
2838 | Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1); | |
2839 | for (j = 1; j <= NbPath; j++) | |
2840 | anArray->SetValue(1, j, myUEdges->Value(isec, j)); | |
2841 | for (j = 1; j <= NbPath+1; j++) | |
2842 | anArray->SetValue(2, j, Vertex(isec, j)); | |
2843 | Rails.Bind(Vfirst, anArray); | |
2844 | } | |
2845 | if (!Rails.IsBound(Vlast)) | |
2846 | { | |
2847 | Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1); | |
2848 | for (j = 1; j <= NbPath; j++) | |
2849 | anArray->SetValue(1, j, myUEdges->Value(isec+1, j)); | |
2850 | for (j = 1; j <= NbPath+1; j++) | |
2851 | anArray->SetValue(2, j, Vertex(isec+1, j)); | |
2852 | Rails.Bind(Vlast, anArray); | |
2853 | } | |
c8ea5b8e | 2854 | } |
2855 | } | |
2856 | ||
7fd59977 | 2857 | return Standard_True; |
2858 | } | |
2859 | ||
2860 | //======================================================================= | |
2861 | //function : Build | |
0d969553 | 2862 | //purpose : Construt the result of sweeping |
7fd59977 | 2863 | //====================================================================== |
c8ea5b8e | 2864 | void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges, |
2865 | BRepFill_DataMapOfShapeHArray2OfShape& Tapes, | |
8e817497 | 2866 | BRepFill_DataMapOfShapeHArray2OfShape& Rails, |
c8ea5b8e | 2867 | const BRepFill_TransitionStyle Transition, |
2868 | const GeomAbs_Shape Continuity, | |
2869 | const GeomFill_ApproxStyle Approx, | |
2870 | const Standard_Integer Degmax, | |
2871 | const Standard_Integer Segmax) | |
7fd59977 | 2872 | { |
7fd59977 | 2873 | myContinuity = Continuity; |
a31abc03 | 2874 | myApproxStyle = Approx; |
7fd59977 | 2875 | myDegmax = Degmax; |
2876 | mySegmax = Segmax; | |
2877 | ||
2878 | CorrectApproxParameters(); | |
2879 | ||
2880 | // Wire | |
2881 | if (mySec->IsVertex()) isDone = BuildWire(Transition); | |
2882 | ||
2883 | else { // Shell | |
2884 | Standard_Integer NbTrous = myLoc->NbHoles(myTol3d), | |
2885 | NbPath = myLoc->NbLaw(), | |
2886 | NbLaw = mySec->NbLaw(), ii, jj, NbPart=1; | |
2887 | Standard_Integer ipath, isec; | |
2888 | BRep_Builder B; | |
2889 | myUEdges = new (TopTools_HArray2OfShape) (1, NbLaw+1, 1, NbPath); | |
2890 | myVEdges = new (TopTools_HArray2OfShape) (1, NbLaw, 1, NbPath+1); | |
2891 | myFaces = new (TopTools_HArray2OfShape) (1, NbLaw, 1, NbPath); | |
953d87f3 | 2892 | myTapes = new (TopTools_HArray1OfShape) (1, NbLaw); |
2893 | BRep_Builder BB; | |
2894 | for (Standard_Integer i = 1; i <= NbLaw; i++) | |
2895 | { | |
2896 | TopoDS_Shell aShell; | |
2897 | BB.MakeShell(aShell); | |
2898 | myTapes->ChangeValue(i) = aShell; | |
2899 | } | |
7fd59977 | 2900 | Handle (TopTools_HArray2OfShape) Bounds = |
2901 | new (TopTools_HArray2OfShape) (1, NbLaw, 1, 2); | |
2902 | ||
2903 | Handle(TColStd_HArray1OfInteger) Trous; | |
2904 | ||
0d969553 | 2905 | if (NbTrous>0) { // How many sub-parts ? |
7fd59977 | 2906 | Trous = new (TColStd_HArray1OfInteger) (1, NbTrous); |
2907 | myLoc->Holes(Trous->ChangeArray1()); | |
2908 | NbPart += NbTrous; | |
2909 | if (Trous->Value(NbTrous) == NbPath+1) NbPart--; | |
2910 | } | |
0d969553 | 2911 | if (NbPart == 1) { // This is done at once |
7fd59977 | 2912 | Standard_Real Extend = 0.0; |
2913 | if (NbTrous==1) Extend = EvalExtrapol(1, Transition); | |
2914 | isDone = BuildShell(Transition, | |
2915 | 1, NbPath+1, | |
c8ea5b8e | 2916 | ReversedEdges, |
8e817497 | 2917 | Tapes, Rails, |
7fd59977 | 2918 | Extend, Extend); |
2919 | } | |
0d969553 | 2920 | else { // This is done piece by piece |
7fd59977 | 2921 | Standard_Integer IFirst = 1, ILast; |
2922 | for (ii=1, isDone=Standard_True; | |
2923 | ii<=NbPart && isDone; ii++) { | |
2924 | if (ii > NbTrous) ILast = NbPath+1; | |
2925 | else ILast = Trous->Value(ii); | |
2926 | isDone = BuildShell(Transition, | |
2927 | IFirst, ILast, | |
c8ea5b8e | 2928 | ReversedEdges, |
8e817497 | 2929 | Tapes, Rails, |
7fd59977 | 2930 | EvalExtrapol(IFirst, Transition), |
2931 | EvalExtrapol(ILast, Transition)); | |
2932 | if (IFirst>1) { | |
2933 | Translate(myVEdges, IFirst, Bounds, 2); | |
2934 | PerformCorner(IFirst, | |
2935 | Transition, Bounds); | |
2936 | } | |
2937 | IFirst = ILast; | |
2938 | Translate(myVEdges, IFirst, Bounds, 1); | |
2939 | } | |
2940 | } | |
0d969553 | 2941 | // Management of looping ends |
7fd59977 | 2942 | if ( (NbTrous>0) && (myLoc->IsClosed()) && |
2943 | (Trous->Value(NbTrous) == NbPath+1) ) { | |
a922aab5 | 2944 | Translate(myVEdges, NbPath+1, Bounds, 1); |
2945 | Translate(myVEdges, 1, Bounds, 2); | |
7fd59977 | 2946 | PerformCorner(1, Transition, Bounds); |
a922aab5 | 2947 | Translate(myVEdges, 1, myVEdges, NbPath+1); |
7fd59977 | 2948 | } |
2949 | ||
0d969553 | 2950 | // Construction of the shell |
7fd59977 | 2951 | TopoDS_Shell shell; |
2952 | B.MakeShell(shell); | |
2953 | for (ipath=1; ipath<=NbPath; ipath++) | |
2954 | for (isec=1; isec <=NbLaw; isec++) { | |
2955 | const TopoDS_Shape& face = myFaces->Value(isec, ipath); | |
2956 | if (!face.IsNull() && | |
2957 | (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face); | |
2958 | } | |
2959 | ||
2960 | TopTools_ListIteratorOfListOfShape It(myAuxShape); | |
2961 | for (; It.More(); It.Next()) { | |
2962 | const TopoDS_Shape& face = It.Value(); | |
2963 | if (!face.IsNull() && | |
2964 | (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face); | |
2965 | } | |
2966 | //Set common Uedges to faces | |
2967 | BRepTools_Substitution aSubstitute; | |
2968 | /* | |
2969 | for (ii = 1; ii <= NbLaw; ii++) | |
2970 | for (jj = 1; jj <= NbPath; jj++) | |
2971 | { | |
2972 | SetCommonEdgeInFace(aSubstitute, | |
2973 | myFaces->Value(ii, jj), | |
2974 | myUEdges->Value(ii, jj)); | |
2975 | SetCommonEdgeInFace(aSubstitute, | |
2976 | myFaces->Value(ii, jj), | |
2977 | myUEdges->Value(ii+1, jj)); | |
2978 | } | |
2979 | if (mySec->IsUClosed()) | |
2980 | for (jj = 1; jj <= NbPath; jj++) | |
2981 | SetCommonEdgeInFace(aSubstitute, | |
2982 | myFaces->Value( 1, jj ), | |
2983 | myUEdges->Value( NbLaw+1, jj)); | |
2984 | */ | |
2985 | TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( myVEdgesModified ); | |
2986 | for (; mapit.More(); mapit.Next()) | |
2987 | { | |
2988 | const TopoDS_Edge& OldEdge = TopoDS::Edge(mapit.Key()); | |
2989 | const TopoDS_Edge& NewEdge = TopoDS::Edge(mapit.Value()); | |
2990 | Substitute( aSubstitute, OldEdge, NewEdge ); | |
2991 | } | |
2992 | aSubstitute.Build( shell ); | |
2993 | if (aSubstitute.IsCopied( shell )) { | |
2994 | const TopTools_ListOfShape& listSh = aSubstitute.Copy( shell ); | |
2995 | shell = TopoDS::Shell( listSh.First() ); | |
2996 | } | |
2997 | ||
2998 | for (ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) { | |
2999 | for (jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++) { | |
3000 | const TopoDS_Shape& aLocalShape = myFaces->Value(ii, jj); | |
3001 | ||
3002 | if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) { | |
3003 | const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape); | |
3004 | ||
3005 | if(!aList.IsEmpty()) | |
3006 | myFaces->ChangeValue(ii, jj) = aList.First(); | |
3007 | } | |
3008 | } | |
3009 | } | |
3010 | ||
3011 | for (ii = myVEdges->LowerRow(); ii <= myVEdges->UpperRow(); ii++) { | |
3012 | for (jj = myVEdges->LowerCol(); jj <= myVEdges->UpperCol(); jj++) { | |
3013 | const TopoDS_Shape& aLocalShape = myVEdges->Value(ii, jj); | |
3014 | ||
3015 | if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) { | |
3016 | const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape); | |
3017 | ||
3018 | if(!aList.IsEmpty()) | |
3019 | myVEdges->ChangeValue(ii, jj) = aList.First(); | |
3020 | } | |
3021 | } | |
3022 | } | |
3023 | ||
3024 | for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) { | |
3025 | for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++) { | |
3026 | const TopoDS_Shape& aLocalShape = myUEdges->Value(ii, jj); | |
3027 | ||
3028 | if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) { | |
3029 | const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape); | |
3030 | ||
3031 | if(!aList.IsEmpty()) | |
3032 | myUEdges->ChangeValue(ii, jj) = aList.First(); | |
3033 | } | |
3034 | } | |
3035 | } | |
3036 | ||
833e7561 | 3037 | //Ensure Same Parameter on U-edges |
3038 | for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) | |
3039 | { | |
3040 | if (mySec->IsUClosed() && ii == myUEdges->UpperRow()) | |
3041 | continue; | |
3042 | for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++) | |
3043 | { | |
3044 | TopoDS_Edge anEdge = TopoDS::Edge(myUEdges->Value(ii, jj)); | |
a922aab5 | 3045 | if (anEdge.IsNull() || |
3046 | BRep_Tool::Degenerated(anEdge)) | |
833e7561 | 3047 | continue; |
3048 | TopoDS_Face Face1, Face2; | |
3049 | Standard_Integer i1 = ii-1, i2 = ii; | |
3050 | if (i1 == 0 && mySec->IsUClosed()) | |
3051 | i1 = myFaces->UpperRow(); | |
3052 | if (i2 > myFaces->UpperRow()) | |
3053 | i2 = 0; | |
3054 | if (i1 != 0) | |
3055 | Face1 = TopoDS::Face(myFaces->Value(i1, jj)); | |
3056 | if (i2 != 0) | |
3057 | Face2 = TopoDS::Face(myFaces->Value(i2, jj)); | |
3058 | CorrectSameParameter(anEdge, Face1, Face2); | |
3059 | } | |
3060 | } | |
3061 | ||
953d87f3 | 3062 | for (ii = 1; ii <= NbLaw; ii++) |
3063 | for (jj = 1; jj <= NbPath; jj++) | |
3064 | { | |
3065 | const TopoDS_Shape& aFace = myFaces->Value(ii,jj); | |
3066 | if (!aFace.IsNull() && aFace.ShapeType() == TopAbs_FACE) | |
3067 | BB.Add(myTapes->ChangeValue(ii), aFace); | |
3068 | } | |
3069 | ||
0d969553 | 3070 | // Is it Closed ? |
7fd59977 | 3071 | if (myLoc->IsClosed() && mySec->IsUClosed()) { |
0d969553 | 3072 | //Check |
7fd59977 | 3073 | Standard_Boolean closed = Standard_True; |
3074 | Standard_Integer iedge; | |
3075 | TopTools_IndexedDataMapOfShapeListOfShape EFmap; | |
3076 | TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, | |
3077 | TopAbs_FACE, EFmap); | |
3078 | ||
3079 | for (iedge = 1; iedge <=EFmap.Extent() && closed; iedge++) { | |
3080 | const TopoDS_Edge& theEdge = TopoDS::Edge(EFmap.FindKey(iedge)); | |
3081 | if (BRep_Tool::Degenerated(theEdge)) continue; | |
3082 | closed = ( EFmap(iedge).Extent() > 1); | |
3083 | } | |
3084 | shell.Closed(closed); | |
3085 | } | |
3086 | myShape = shell; | |
3087 | } | |
3088 | } | |
3089 | ||
3090 | ||
3091 | //======================================================================= | |
3092 | //function : IsDone | |
3093 | //purpose : | |
3094 | //======================================================================= | |
3095 | Standard_Boolean BRepFill_Sweep::IsDone() const | |
3096 | { | |
3097 | return isDone; | |
3098 | } | |
3099 | ||
3100 | //======================================================================= | |
3101 | //function : Shape | |
3102 | //purpose : | |
3103 | //======================================================================= | |
3104 | TopoDS_Shape BRepFill_Sweep::Shape() const | |
3105 | { | |
3106 | return myShape; | |
3107 | } | |
3108 | ||
3109 | //======================================================================= | |
3110 | //function : ErrorOnSurface | |
3111 | //purpose : | |
3112 | //======================================================================= | |
3113 | Standard_Real BRepFill_Sweep::ErrorOnSurface() const | |
3114 | { | |
3115 | return Error; | |
3116 | } | |
3117 | ||
3118 | //======================================================================= | |
3119 | //function : SubShape | |
0d969553 | 3120 | //purpose : Faces obtained by sweeping |
7fd59977 | 3121 | //======================================================================= |
3122 | Handle(TopTools_HArray2OfShape) BRepFill_Sweep::SubShape() const | |
3123 | { | |
3124 | return myFaces; | |
3125 | } | |
3126 | ||
3127 | //======================================================================= | |
3128 | //function : InterFaces | |
0d969553 | 3129 | //purpose : Edges obtained by sweeping |
7fd59977 | 3130 | //======================================================================= |
3131 | Handle(TopTools_HArray2OfShape) BRepFill_Sweep::InterFaces() const | |
3132 | { | |
3133 | return myUEdges; | |
3134 | } | |
3135 | ||
3136 | //======================================================================= | |
3137 | //function : Sections | |
0d969553 | 3138 | //purpose : Edges or Face (or compound of 2) Transition between 2 sweepings |
7fd59977 | 3139 | //======================================================================= |
3140 | Handle(TopTools_HArray2OfShape) BRepFill_Sweep::Sections() const | |
3141 | { | |
3142 | return myVEdges; | |
3143 | } | |
3144 | ||
953d87f3 | 3145 | //======================================================================= |
3146 | //function : Tape | |
3147 | //purpose : returns the Tape corresponding to Index-th edge of section | |
3148 | //======================================================================= | |
3149 | TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const | |
3150 | { | |
3151 | return myTapes->Value(Index); | |
3152 | } | |
3153 | ||
7fd59977 | 3154 | //======================================================================= |
3155 | //function : PerformCorner | |
0d969553 | 3156 | //purpose : Trim and/or loop a corner |
7fd59977 | 3157 | //====================================================================== |
3158 | void BRepFill_Sweep::PerformCorner(const Standard_Integer Index, | |
3159 | const BRepFill_TransitionStyle Transition, | |
3160 | const Handle(TopTools_HArray2OfShape)& Bounds) | |
3161 | { | |
3162 | ||
0d969553 | 3163 | if (Transition == BRepFill_Modified) return; // Do nothing. |
7fd59977 | 3164 | |
3165 | BRepFill_TransitionStyle TheTransition = Transition; | |
3166 | Standard_Boolean isTangent=Standard_False; | |
3167 | Standard_Real F, L; | |
3168 | Standard_Integer I1, I2, ii; //, jj; | |
3169 | gp_Pnt P1,P2; | |
3170 | gp_Vec T1, T2, Tang, Sortant; | |
3171 | // gp_Mat M; | |
3172 | //Handle(TopTools_HArray1OfShape) TheShape = | |
3173 | //new TopTools_HArray1OfShape( 1, mySec->NbLaw() ); | |
3174 | // TopTools_ListIteratorOfListOfShape Iterator; | |
3175 | ||
3176 | if (Index > 1) { | |
3177 | I1 = Index-1; | |
3178 | I2 = Index; | |
3179 | } | |
3180 | else { | |
3181 | I1 = myLoc->NbLaw(); | |
3182 | I2 = 1; | |
3183 | } | |
3184 | ||
0d969553 | 3185 | // Construct an axis supported by the bissectrice |
7fd59977 | 3186 | myLoc->Law(I1)->GetDomain(F, L); |
3187 | myLoc->Law(I1)->GetCurve()->D1(L, P1, T1); | |
3188 | T1.Normalize(); | |
3189 | ||
3190 | myLoc->Law(I2)->GetDomain(F, L); | |
3191 | myLoc->Law(I2)->GetCurve()->D1(F, P2, T2); | |
3192 | T2.Normalize(); | |
3193 | ||
3194 | if (T1.Angle(T2) < myAngMin) { | |
3195 | isTangent = Standard_True; | |
3196 | gp_Vec t1, t2, V; | |
3197 | gp_Mat M; | |
3198 | myLoc->Law(I1)->GetDomain(F, L); | |
3199 | myLoc->Law(I1)->D0(L, M, V); | |
3200 | t1 = M.Column(3); | |
3201 | myLoc->Law(I2)->GetDomain(F, L); | |
3202 | myLoc->Law(I2)->D0(L, M, V); | |
3203 | t2 = M.Column(3); | |
3204 | ||
3205 | if (t1.Angle(t2) < myAngMin) { | |
0797d9d3 | 3206 | #ifdef OCCT_DEBUG |
0d969553 | 3207 | cout << "BRepFill_Sweep::PerformCorner : This is not a corner !" << endl; |
7fd59977 | 3208 | #endif |
3209 | return; | |
3210 | } | |
3211 | Sortant = t2 - t1; | |
3212 | } | |
3213 | ||
3214 | if ((TheTransition == BRepFill_Right) | |
3215 | && (T1.Angle(T2) > myAngMax) ) { | |
3216 | TheTransition = BRepFill_Round; | |
3217 | } | |
3218 | ||
0d969553 | 3219 | Tang = T1 + T2; //Average direction |
7fd59977 | 3220 | gp_Dir NormalOfBisPlane = Tang; |
3221 | ||
3222 | if (isTangent) { | |
3223 | Sortant -= Tang.Dot(Tang)*Tang; | |
3224 | } | |
3225 | else { | |
0d969553 Y |
3226 | Sortant = T2-T1; //Direction input |
3227 | Sortant *= -1; // " " output | |
7fd59977 | 3228 | Tang -= (Tang.Dot(T2))*T2; |
3229 | } | |
3230 | ||
3231 | P1.BaryCenter(0.5, P2, 0.5); | |
3232 | gp_Dir N(Sortant); | |
3233 | gp_Dir Dx(Tang); | |
3234 | ||
3235 | gp_Ax2 Axe (P1, N, Dx); | |
3236 | gp_Ax2 AxeOfBisPlane( P1, NormalOfBisPlane ); | |
3237 | ||
0d969553 | 3238 | // Construct 2 intersecting Shells |
7fd59977 | 3239 | Handle (TopTools_HArray2OfShape) UEdges = |
3240 | new TopTools_HArray2OfShape( 1, mySec->NbLaw()+1, 1, myLoc->NbLaw() ); | |
3241 | UEdges->ChangeArray2() = myUEdges->Array2(); | |
3242 | ||
3243 | // modified by NIZHNY-MKK Wed Oct 29 18:31:47 2003.BEGIN | |
3244 | Handle (TopTools_HArray2OfShape) aFaces = | |
3245 | new TopTools_HArray2OfShape(myFaces->LowerRow(), myFaces->UpperRow(), 1, 2); | |
3246 | Translate(myFaces, I1, aFaces, 1); | |
3247 | Translate(myFaces, I2, aFaces, 2); | |
3248 | ||
3249 | Handle (TopTools_HArray2OfShape) aUEdges = | |
3250 | new TopTools_HArray2OfShape(myUEdges->LowerRow(), myUEdges->UpperRow(), 1, 2); | |
3251 | Translate(myUEdges, I1, aUEdges, 1); | |
3252 | Translate(myUEdges, I2, aUEdges, 2); | |
3253 | ||
3254 | gp_Vec aNormal = T2 + T1; | |
3255 | TopoDS_Face aPlaneF; | |
3256 | ||
3257 | if(aNormal.Magnitude() > gp::Resolution()) { | |
3258 | gp_Pln pl(P1, gp_Dir(aNormal)); | |
3259 | BRepLib_MakeFace aFMaker(pl); | |
3260 | ||
3261 | if(aFMaker.Error() == BRepLib_FaceDone) { | |
3262 | aPlaneF = aFMaker.Face(); | |
3263 | BRep_Builder aBB; | |
3264 | aBB.UpdateFace(aPlaneF, Precision::Confusion() * 10.); | |
3265 | } | |
3266 | } | |
3267 | ||
833e7561 | 3268 | BRepFill_TrimShellCorner aTrim(aFaces, Transition, AxeOfBisPlane); |
7fd59977 | 3269 | aTrim.AddBounds(Bounds); |
3270 | aTrim.AddUEdges(aUEdges); | |
a922aab5 | 3271 | aTrim.AddVEdges(myVEdges, Index); |
7fd59977 | 3272 | aTrim.Perform(); |
3273 | ||
3274 | if (aTrim.IsDone()) { | |
a922aab5 | 3275 | |
7fd59977 | 3276 | TopTools_ListOfShape listmodif; |
a922aab5 | 3277 | for (ii = 1; ii <= mySec->NbLaw(); ii++) |
3278 | { | |
3279 | listmodif.Clear(); | |
3280 | aTrim.Modified(myVEdges->Value(ii, Index), listmodif); | |
3281 | ||
3282 | if (listmodif.IsEmpty()) | |
3283 | { | |
3284 | TopoDS_Edge NullEdge; | |
3285 | myVEdges->SetValue(ii, Index, NullEdge); | |
3286 | } | |
3287 | else | |
3288 | myVEdges->SetValue(ii, Index, listmodif.First()); | |
3289 | } | |
3290 | ||
3291 | listmodif.Clear(); | |
7fd59977 | 3292 | Standard_Integer iit = 0; |
3293 | ||
3294 | for(iit = 0; iit < 2; iit++) { | |
3295 | Standard_Integer II = (iit == 0) ? I1 : I2; | |
3296 | ||
3297 | for (ii = 1; ii <= mySec->NbLaw(); ii++) { | |
3298 | aTrim.Modified(myFaces->Value(ii, II), listmodif); | |
3299 | ||
3300 | if(!listmodif.IsEmpty()) { | |
3301 | myFaces->SetValue(ii, II, listmodif.First()); | |
3302 | } | |
3303 | } | |
3304 | ||
3305 | for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) { | |
3306 | aTrim.Modified(myUEdges->Value(ii, II), listmodif); | |
3307 | ||
3308 | if(!listmodif.IsEmpty()) { | |
3309 | myUEdges->SetValue(ii, II, listmodif.First()); | |
3310 | } | |
3311 | } | |
3312 | } | |
3313 | } | |
3314 | else if ((TheTransition == BRepFill_Right) || | |
3315 | aTrim.HasSection() ) { | |
0797d9d3 | 3316 | #ifdef OCCT_DEBUG |
0d969553 | 3317 | cout << "Fail of TrimCorner" << endl; |
7fd59977 | 3318 | #endif |
0d969553 | 3319 | return; // Nothing is touched |
7fd59977 | 3320 | } |
3321 | ||
3322 | if (mySec->IsUClosed()) | |
3323 | { | |
3324 | myUEdges->SetValue( 1, I1, myUEdges->Value(mySec->NbLaw()+1, I1) ); | |
3325 | myUEdges->SetValue( 1, I2, myUEdges->Value(mySec->NbLaw()+1, I2) ); | |
3326 | } | |
3327 | ||
3328 | if (TheTransition == BRepFill_Round) { | |
0d969553 | 3329 | // Filling |
7fd59977 | 3330 | TopTools_ListOfShape list1, list2; |
3331 | TopoDS_Edge Bord1, Bord2, BordFirst; | |
3332 | BordFirst.Nullify(); | |
3333 | Bord1.Nullify(); | |
3334 | Bord2.Nullify(); | |
3335 | Standard_Boolean HasFilling = Standard_False; | |
3336 | TopoDS_Face FF; | |
3337 | for (ii=1; ii<=mySec->NbLaw(); ii++) { | |
3338 | KeepEdge(myFaces->Value(ii, I1), Bounds->Value(ii, 1), list1); | |
3339 | KeepEdge(myFaces->Value(ii, I2), Bounds->Value(ii, 2), list2); | |
3340 | if (list1.Extent() == list2.Extent()) { | |
3341 | TopTools_ListIteratorOfListOfShape It1(list1); | |
3342 | TopTools_ListIteratorOfListOfShape It2(list2); | |
3343 | Standard_Boolean B; | |
3344 | for (; It1.More(); It1.Next(), It2.Next()) { | |
0d969553 | 3345 | if (HasFilling) { // Transversal choice of constraints |
7fd59977 | 3346 | TopoDS_Vertex VF, VL, VC; |
3347 | TopoDS_Edge E = TopoDS::Edge(It1.Value()); | |
3348 | TopoDS_Edge E1, E2; | |
3349 | E1.Nullify(); | |
3350 | E2.Nullify(); | |
3351 | TopExp::Vertices(E, VF, VL); | |
3352 | if (!Bord1.IsNull() && | |
3353 | TopExp::CommonVertex(E, Bord1, VC)) { | |
3354 | if (VC.IsSame(VF)) E1 = Bord1; | |
3355 | else E2 = Bord1; | |
3356 | } | |
3357 | if (!Bord2.IsNull() && | |
3358 | TopExp::CommonVertex(E, Bord2, VC)) { | |
3359 | if (VC.IsSame(VF)) E1 = Bord2; | |
3360 | else E2 = Bord2; | |
3361 | } | |
3362 | if (!BordFirst.IsNull() && | |
3363 | TopExp::CommonVertex(E, BordFirst, VC)) { | |
3364 | if (VC.IsSame(VF)) E1 = BordFirst; | |
3365 | else E2 = BordFirst; | |
3366 | } | |
3367 | Bord1 = E1; | |
3368 | Bord2 = E2; | |
3369 | } | |
3370 | ||
0d969553 | 3371 | // Filling |
7fd59977 | 3372 | B = Filling(It1.Value(), myFaces->Value(ii, I1), |
3373 | It2.Value(), myFaces->Value(ii, I2), | |
3374 | myVEdgesModified, myTol3d, Axe, T1, Bord1, Bord2, FF); | |
3375 | ||
3376 | if (B) { | |
3377 | myAuxShape.Append(FF); | |
953d87f3 | 3378 | BRep_Builder BB; |
a922aab5 | 3379 | TopoDS_Shape aVshape = myVEdges->Value(ii, I2); |
3380 | TopoDS_Compound aCompound; | |
3381 | BB.MakeCompound(aCompound); | |
3382 | if (!aVshape.IsNull()) | |
3383 | BB.Add(aCompound, aVshape); | |
3384 | BB.Add(aCompound, FF); | |
3385 | myVEdges->ChangeValue(ii, I2) = aCompound; | |
3386 | ||
953d87f3 | 3387 | BB.Add(myTapes->ChangeValue(ii), FF); |
7fd59977 | 3388 | HasFilling = Standard_True; |
3389 | } | |
3390 | if (ii==1) BordFirst = Bord1; | |
3391 | } | |
3392 | } | |
0797d9d3 | 3393 | #ifdef OCCT_DEBUG |
0d969553 | 3394 | else cout << "PerformCorner : Unsymmetry of free border" << endl; |
7fd59977 | 3395 | #endif |
3396 | } | |
3397 | } | |
3398 | ||
3399 | /* | |
3400 | #if DRAW | |
3401 | if (Affich) { | |
3402 | Standard_Integer jj; | |
3403 | char name[100]; | |
3404 | DBRep::Set("TrimmedShell", TheShape); | |
3405 | for (jj=1; jj <=myFaces->ColLength(); jj++){ | |
3406 | sprintf(name,"Tfaces_%d_%d", jj, I1); | |
3407 | DBRep::Set(name, myFaces->Value(jj, I1)); | |
3408 | sprintf(name,"Tfaces_%d_%d", jj, I2); | |
3409 | DBRep::Set(name, myFaces->Value(jj, I2)); | |
3410 | } | |
3411 | } | |
3412 | #endif | |
3413 | */ | |
3414 | } | |
3415 | ||
3416 | //======================================================================= | |
3417 | //function : EvalExtrapol | |
3418 | //purpose : | |
3419 | //====================================================================== | |
3420 | Standard_Real BRepFill_Sweep:: | |
3421 | EvalExtrapol(const Standard_Integer Index, | |
3422 | const BRepFill_TransitionStyle Transition) const | |
3423 | { | |
3424 | Standard_Real Extrap = 0.0; | |
3425 | if (Transition == BRepFill_Right) { | |
3426 | Standard_Integer I1, I2; | |
3427 | if ((Index == 1) || (Index ==myLoc->NbLaw()+1) ) { | |
3428 | if (!myLoc->IsClosed() || !mySec->IsVClosed()) return Extrap; | |
3429 | I1 = myLoc->NbLaw(); | |
3430 | I2 = 1; | |
3431 | } | |
3432 | else { | |
3433 | I1 = Index-1; | |
3434 | I2 = Index; | |
3435 | } | |
3436 | ||
3437 | gp_Vec V1, V2, T1, T2; | |
3438 | gp_Mat M1, M2; | |
3439 | Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax, R, f, l; | |
3440 | ||
3441 | myLoc->Law(I1)->GetDomain(f, l); | |
3442 | myLoc->Law(I1)->D0(l, M1, V1); | |
3443 | T1.SetXYZ(M1.Column(3)); | |
3444 | myLoc->Law(I2)->GetDomain(f, l); | |
3445 | myLoc->Law(I2)->D0(f, M2, V2); | |
3446 | T2.SetXYZ(M2.Column(3)); | |
3447 | ||
3448 | Standard_Real alpha = T1.Angle(T2); | |
3449 | if ((alpha > myAngMax) || (alpha < myAngMin)) { | |
0d969553 Y |
3450 | //Angle too great => No "straight" connection |
3451 | //Angle too small => No connection | |
7fd59977 | 3452 | return Extrap; // = 0.0 |
3453 | } | |
3454 | ||
3455 | Handle(GeomFill_SectionLaw) Sec; | |
3456 | Sec = mySec->ConcatenedLaw(); | |
3457 | ||
3458 | //Calculating parameter U | |
3459 | Standard_Real U, Length, SecFirst, SecLen, Lf, Ll; | |
3460 | myLoc->CurvilinearBounds( myLoc->NbLaw(), Lf, Length ); | |
3461 | mySec->Law(1)->GetDomain( SecFirst, SecLen ); | |
3462 | SecLen -= SecFirst; | |
3463 | myLoc->CurvilinearBounds( I1, Lf, Ll ); | |
3464 | U = SecFirst + (Ll/Length)*SecLen; | |
3465 | ||
3466 | Bnd_Box box; | |
3467 | //Box(Sec, 0., box); | |
3468 | Box(Sec, U, box); | |
3469 | box.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); | |
3470 | ||
3471 | R = Max(Max(Abs(Xmin), Abs(Xmax)),Max(Abs(Ymin), Abs(Ymax))); | |
3472 | //R *= 1.1; | |
3473 | // modified by NIZHNY-MKK Fri Oct 31 18:57:51 2003 | |
3474 | // Standard_Real coef = 1.2; | |
3475 | Standard_Real coef = 2.; | |
3476 | R *= coef; | |
3477 | Extrap = Max(Abs(Zmin), Abs(Zmax)) + 100*myTol3d; | |
3478 | Extrap += R*Tan(alpha/2); | |
3479 | } | |
3480 | return Extrap; | |
3481 | } | |
3482 | ||
3483 | //======================================================================= | |
3484 | //function : MergeVertex | |
0d969553 | 3485 | //purpose : Make V2 = V1 if V2 is too close to V1 |
7fd59977 | 3486 | //====================================================================== |
3487 | Standard_Boolean BRepFill_Sweep::MergeVertex(const TopoDS_Shape& V1, | |
3488 | TopoDS_Shape& V2) const | |
3489 | { | |
3490 | // Class BRep_Tool without fields and without Constructor : | |
3491 | // BRep_Tool BT; | |
3492 | const TopoDS_Vertex& v1 = TopoDS::Vertex(V1); | |
3493 | const TopoDS_Vertex& v2 = TopoDS::Vertex(V2); | |
3494 | Standard_Real tol; | |
3495 | // tol = Max(BT.Tolerance(v1), BT.Tolerance(v2)); | |
3496 | tol = Max(BRep_Tool::Tolerance(v1), BRep_Tool::Tolerance(v2)); | |
3497 | if (tol < myTol3d) tol = myTol3d; | |
3498 | // if (BT.Pnt(v1).Distance(BT.Pnt(v2)) <= tol ){ | |
3499 | if (BRep_Tool::Pnt(v1).Distance(BRep_Tool::Pnt(v2)) <= tol ){ | |
3500 | V2 = V1; | |
3501 | return Standard_True; | |
3502 | } | |
3503 | return Standard_False; | |
3504 | } | |
3505 | ||
3506 | ||
3507 | //======================================================================= | |
3508 | //function : UpdateVertex | |
0d969553 | 3509 | //purpose : Update the Tolerance of Vertices depending on Laws. |
7fd59977 | 3510 | //====================================================================== |
3511 | void BRepFill_Sweep::UpdateVertex(const Standard_Integer ipath, | |
3512 | const Standard_Integer isec, | |
3513 | const Standard_Real ErrApp, | |
3514 | const Standard_Real Param, | |
3515 | TopoDS_Shape& V) const | |
3516 | { | |
3517 | TopoDS_Vertex vv, TheV; | |
3518 | TheV = TopoDS::Vertex(V); | |
3519 | myLoc->PerformVertex(ipath, | |
3520 | mySec->Vertex(isec, Param), | |
3521 | ErrApp+mySec->VertexTol(isec-1, Param), | |
3522 | vv); | |
3523 | // Class BRep_Tool without fields and without Constructor : | |
3524 | // BRep_Tool BT; | |
3525 | gp_Pnt P1, P2; | |
3526 | // P1 = BT.Pnt(vv); | |
3527 | P1 = BRep_Tool::Pnt(vv); | |
3528 | // P2 = BT.Pnt(TheV); | |
3529 | P2 = BRep_Tool::Pnt(TheV); | |
3530 | ||
3531 | // Standard_Real Tol = BT.Tolerance(vv); | |
3532 | Standard_Real Tol = BRep_Tool::Tolerance(vv); | |
3533 | Tol += P1.Distance(P2); | |
3534 | ||
3535 | // if (Tol > BT.Tolerance(TheV)) { | |
3536 | if (Tol > BRep_Tool::Tolerance(TheV)) { | |
3537 | BRep_Builder B; | |
3538 | B.UpdateVertex(TheV, Tol); | |
3539 | } | |
3540 | } | |
c8ea5b8e | 3541 | |
3542 | //======================================================================= | |
3543 | //function : RebuildTopOrBottomEdge | |
3544 | //purpose : Rebuild v-iso edge of top or bottom section | |
3545 | // inserting new 3d and 2d curves taken from swept surfaces | |
3546 | //====================================================================== | |
3547 | void BRepFill_Sweep::RebuildTopOrBottomEdge(const TopoDS_Edge& aNewEdge, | |
3548 | TopoDS_Edge& anEdge, | |
3549 | TopTools_MapOfShape& ReversedEdges) const | |
3550 | { | |
3551 | Standard_Real fpar, lpar; | |
3552 | Handle(Geom_Curve) aNewCurve = BRep_Tool::Curve(aNewEdge, fpar, lpar); | |
3553 | TopLoc_Location Identity; | |
3554 | ||
3555 | Standard_Boolean ToReverse = Standard_False; | |
3556 | Standard_Boolean IsDegen = BRep_Tool::Degenerated(aNewEdge); | |
3557 | if (IsDegen) | |
3558 | BRep_Tool::Range(aNewEdge, fpar, lpar); | |
3559 | else | |
3560 | { | |
3561 | TopoDS_Vertex V1, V2, NewV1, NewV2; | |
3562 | TopExp::Vertices(anEdge, V1, V2); | |
3563 | if (!V1.IsSame(V2)) | |
3564 | { | |
3565 | TopExp::Vertices(aNewEdge, NewV1, NewV2); | |
3566 | V1.Location(Identity); | |
3567 | if (!V1.IsSame(NewV1)) | |
3568 | { | |
3569 | if (V1.IsSame(NewV2)) | |
3570 | ToReverse = Standard_True; | |
3571 | else | |
3572 | { | |
3573 | gp_Pnt Pnt1 = BRep_Tool::Pnt(V1); | |
3574 | gp_Pnt NewPnt1 = BRep_Tool::Pnt(NewV1); | |
3575 | Standard_Real TolSum = BRep_Tool::Tolerance(V1) + BRep_Tool::Tolerance(NewV1); | |
3576 | if (!Pnt1.IsEqual(NewPnt1, TolSum)) | |
3577 | ToReverse = Standard_True; | |
3578 | } | |
3579 | } | |
3580 | } | |
3581 | else | |
3582 | { | |
3583 | Standard_Real OldFirst, OldLast; | |
3584 | Handle(Geom_Curve) OldCurve = BRep_Tool::Curve(anEdge, OldFirst, OldLast); | |
3585 | gp_Vec OldD1, NewD1; | |
3586 | gp_Pnt MidPnt; | |
3587 | OldCurve->D1(0.5*(OldFirst + OldLast), MidPnt, OldD1); | |
3588 | aNewCurve->D1(0.5*(fpar + lpar), MidPnt, NewD1); | |
3589 | if (OldD1 * NewD1 < 0.) | |
3590 | ToReverse = Standard_True; | |
3591 | } | |
3592 | } | |
3593 | ||
3594 | anEdge.Location(Identity); | |
3595 | const Handle(BRep_TEdge)& TEdge = *((Handle(BRep_TEdge)*) &anEdge.TShape()); | |
3596 | TEdge->Tolerance(BRep_Tool::Tolerance(aNewEdge)); | |
3597 | BRep_Builder BB; | |
3598 | BB.Range(anEdge, fpar, lpar); | |
3599 | BB.UpdateEdge(anEdge, aNewCurve, Precision::Confusion()); | |
3600 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &aNewEdge.TShape()); | |
3601 | const BRep_ListOfCurveRepresentation& lcr = TE->Curves(); | |
3602 | BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr); | |
3603 | for (; itrep.More(); itrep.Next()) | |
3604 | { | |
3605 | const Handle(BRep_CurveRepresentation)& CurveRep = itrep.Value(); | |
3606 | if (CurveRep->IsCurveOnSurface()) | |
3607 | { | |
c5f3a425 | 3608 | Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (CurveRep)); |
c8ea5b8e | 3609 | Handle(Geom2d_Curve) aPCurve = GC->PCurve(); |
3610 | Handle(Geom_Surface) aSurf = GC->Surface(); | |
3611 | TopLoc_Location aLoc = aNewEdge.Location() * GC->Location(); | |
3612 | BB.UpdateEdge(anEdge, aPCurve, aSurf, aLoc, Precision::Confusion()); | |
3613 | } | |
3614 | } | |
3615 | ||
3616 | anEdge.Free(Standard_True); | |
3617 | TopoDS_Vertex V1, V2; | |
3618 | TopExp::Vertices(anEdge, V1, V2); | |
3619 | ||
3620 | TopoDS_Shape anEdgeFORWARD = anEdge.Oriented(TopAbs_FORWARD); | |
3621 | ||
3622 | BB.Remove(anEdgeFORWARD, V1); | |
3623 | BB.Remove(anEdgeFORWARD, V2); | |
3624 | ||
3625 | V1.Location(Identity); | |
3626 | V2.Location(Identity); | |
3627 | if (ToReverse) | |
3628 | { | |
3629 | V2.Orientation(TopAbs_FORWARD); | |
3630 | V1.Orientation(TopAbs_REVERSED); | |
3631 | } | |
3632 | BB.Add(anEdgeFORWARD, V1); | |
3633 | BB.Add(anEdgeFORWARD, V2); | |
3634 | ||
3635 | if (ToReverse) | |
3636 | { | |
3637 | anEdge.Reverse(); | |
3638 | ReversedEdges.Add(anEdge); | |
3639 | } | |
3640 | ||
3641 | BB.Degenerated(anEdge, IsDegen); | |
3642 | } |