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