Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1998-12-29 |
2 | // Created by: Joelle CHAUVET | |
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 | |
17 | #include <stdio.h> | |
18 | ||
19 | #include <BRepFill_NSections.ixx> | |
20 | ||
21 | #include <BRepFill.hxx> | |
22 | #include <BRepTools_WireExplorer.hxx> | |
23 | #include <BRep_Builder.hxx> | |
24 | #include <BRep_Tool.hxx> | |
25 | #include <BRepAdaptor_Curve.hxx> | |
26 | #include <BRepLProp.hxx> | |
27 | ||
28 | #include <BRepLib_MakeWire.hxx> | |
29 | #include <BRepLib_MakeEdge.hxx> | |
30 | #include <TopExp.hxx> | |
31 | #include <TopoDS.hxx> | |
32 | #include <TopoDS_Vertex.hxx> | |
33 | #include <TopoDS_Wire.hxx> | |
34 | ||
35 | #include <Geom_Curve.hxx> | |
36 | #include <Geom_Line.hxx> | |
37 | #include <Geom_TrimmedCurve.hxx> | |
38 | #include <Geom_BSplineCurve.hxx> | |
39 | #include <Geom_Conic.hxx> | |
40 | #include <GeomFill_UniformSection.hxx> | |
41 | #include <GeomFill_EvolvedSection.hxx> | |
42 | #include <GeomFill_HArray1OfSectionLaw.hxx> | |
43 | #include <GeomFill_NSections.hxx> | |
44 | #include <TColGeom_SequenceOfCurve.hxx> | |
45 | #include <GeomFill_SectionGenerator.hxx> | |
46 | #include <GeomFill_Line.hxx> | |
47 | #include <GeomFill_AppSurf.hxx> | |
48 | #include <GeomConvert.hxx> | |
49 | #include <GeomConvert_ApproxCurve.hxx> | |
50 | #include <GeomConvert_CompCurveToBSplineCurve.hxx> | |
51 | #include <Geom_BSplineSurface.hxx> | |
52 | #include <BSplCLib.hxx> | |
53 | ||
54 | #include <TColgp_HArray1OfPnt.hxx> | |
55 | #include <TColStd_HArray1OfReal.hxx> | |
56 | #include <TColStd_HArray1OfInteger.hxx> | |
57 | #include <Geom_BezierCurve.hxx> | |
58 | #include <TopTools_Array1OfShape.hxx> | |
59 | ||
60 | #include <Precision.hxx> | |
61 | ||
62 | #ifdef DEB | |
63 | static Standard_Boolean Affich = 0; | |
64 | #endif | |
65 | ||
66 | #ifdef DRAW | |
67 | #include <DrawTrSurf.hxx> | |
68 | #include <DBRep.hxx> | |
69 | #endif | |
70 | ||
71 | //======================================================================= | |
72 | //function : totalsurf | |
73 | //purpose : | |
74 | //======================================================================= | |
75 | ||
76 | static Handle(Geom_BSplineSurface) totalsurf(const TopTools_Array2OfShape& shapes, | |
77 | const Standard_Integer NbSects, | |
78 | const Standard_Integer NbEdges, | |
79 | const TColStd_SequenceOfReal& params, | |
80 | const Standard_Boolean w1Point, | |
81 | const Standard_Boolean w2Point, | |
82 | const Standard_Boolean uClosed, | |
83 | const Standard_Boolean vClosed, | |
84 | const Standard_Real myPres3d) | |
85 | { | |
86 | Standard_Integer i,j,jdeb=1,jfin=NbSects; | |
87 | TopoDS_Edge edge; | |
88 | TopLoc_Location loc; | |
89 | Standard_Real first, last; | |
90 | TopoDS_Vertex vf,vl; | |
91 | ||
92 | GeomFill_SectionGenerator section; | |
93 | Handle(Geom_BSplineSurface) surface; | |
94 | Handle(Geom_BSplineCurve) BS, BS1; | |
95 | Handle(Geom_TrimmedCurve) curvTrim; | |
96 | Handle(Geom_BSplineCurve) curvBS; | |
97 | ||
98 | if (w1Point) { | |
99 | jdeb++; | |
100 | edge = TopoDS::Edge(shapes.Value(1,1)); | |
101 | TopExp::Vertices(edge,vl,vf); | |
102 | TColgp_Array1OfPnt Extremities(1,2); | |
103 | Extremities(1) = BRep_Tool::Pnt(vf); | |
104 | Extremities(2) = BRep_Tool::Pnt(vl); | |
105 | TColStd_Array1OfReal Bounds(1,2); | |
106 | Bounds(1) = 0.; | |
107 | Bounds(2) = 1.; | |
108 | Standard_Real Deg = 1; | |
109 | TColStd_Array1OfInteger Mult(1,2); | |
110 | Mult(1) = (Standard_Integer) Deg+1; | |
111 | Mult(2) = (Standard_Integer) Deg+1; | |
112 | Handle(Geom_BSplineCurve) BSPoint | |
113 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,(Standard_Integer ) Deg); | |
114 | section.AddCurve(BSPoint); | |
115 | } | |
116 | ||
117 | if (w2Point) { | |
118 | jfin--; | |
119 | } | |
120 | ||
121 | for (j=jdeb; j<=jfin; j++) { | |
122 | ||
0d969553 | 123 | // case of looping sections |
7fd59977 | 124 | if (j==jfin && vClosed) { |
125 | section.AddCurve(BS1); | |
126 | } | |
127 | ||
128 | else { | |
129 | // read the first edge to initialise CompBS; | |
130 | edge = TopoDS::Edge(shapes.Value(1,j)); | |
131 | if (BRep_Tool::Degenerated(edge)) { | |
0d969553 | 132 | // degenerated edge : construction of a point curve |
7fd59977 | 133 | TopExp::Vertices(edge,vl,vf); |
134 | TColgp_Array1OfPnt Extremities(1,2); | |
135 | Extremities(1) = BRep_Tool::Pnt(vf); | |
136 | Extremities(2) = BRep_Tool::Pnt(vl); | |
137 | Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities); | |
138 | curvTrim = new Geom_TrimmedCurve(curv, | |
139 | curv->FirstParameter(), | |
140 | curv->LastParameter()); | |
141 | } | |
142 | else { | |
0d969553 | 143 | // return the curve on the edge |
7fd59977 | 144 | Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last); |
145 | curvTrim = new Geom_TrimmedCurve(curv, first, last); | |
146 | curvTrim->Transform(loc.Transformation()); | |
147 | } | |
148 | if (edge.Orientation() == TopAbs_REVERSED) { | |
149 | curvTrim->Reverse(); | |
150 | } | |
151 | ||
0d969553 | 152 | // transformation into BSpline reparameterized on [i-1,i] |
7fd59977 | 153 | curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim); |
154 | if (curvBS.IsNull()) { | |
155 | Handle(Geom_Curve) theCurve = curvTrim->BasisCurve(); | |
156 | if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic))) | |
157 | { | |
158 | GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14); | |
159 | if (appr.HasResult()) | |
160 | curvBS = appr.Curve(); | |
161 | } | |
162 | if (curvBS.IsNull()) | |
163 | curvBS = GeomConvert::CurveToBSplineCurve(curvTrim); | |
164 | } | |
165 | TColStd_Array1OfReal BSK(1,curvBS->NbKnots()); | |
166 | curvBS->Knots(BSK); | |
167 | BSplCLib::Reparametrize(0.,1.,BSK); | |
168 | curvBS->SetKnots(BSK); | |
169 | ||
0d969553 | 170 | // initialization |
7fd59977 | 171 | GeomConvert_CompCurveToBSplineCurve CompBS(curvBS); |
172 | ||
173 | for (i=2; i<=NbEdges; i++) { | |
174 | // read the edge | |
175 | edge = TopoDS::Edge(shapes.Value(i,j)); | |
176 | if (BRep_Tool::Degenerated(edge)) { | |
0d969553 | 177 | // degenerated edge : construction of a point curve |
7fd59977 | 178 | TopExp::Vertices(edge,vl,vf); |
179 | TColgp_Array1OfPnt Extremities(1,2); | |
180 | Extremities(1) = BRep_Tool::Pnt(vf); | |
181 | Extremities(2) = BRep_Tool::Pnt(vl); | |
182 | Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities); | |
183 | curvTrim = new Geom_TrimmedCurve(curv, | |
184 | curv->FirstParameter(), | |
185 | curv->LastParameter()); | |
186 | } | |
187 | else { | |
0d969553 | 188 | // return the curve on the edge |
7fd59977 | 189 | Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last); |
190 | curvTrim = new Geom_TrimmedCurve(curv, first, last); | |
191 | curvTrim->Transform(loc.Transformation()); | |
192 | } | |
193 | if (edge.Orientation() == TopAbs_REVERSED) { | |
194 | curvTrim->Reverse(); | |
195 | } | |
196 | ||
0d969553 | 197 | // transformation into BSpline reparameterized on [i-1,i] |
7fd59977 | 198 | curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim); |
199 | if (curvBS.IsNull()) { | |
200 | Handle(Geom_Curve) theCurve = curvTrim->BasisCurve(); | |
201 | if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic))) | |
202 | { | |
203 | GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14); | |
204 | if (appr.HasResult()) | |
205 | curvBS = appr.Curve(); | |
206 | } | |
207 | if (curvBS.IsNull()) | |
208 | curvBS = GeomConvert::CurveToBSplineCurve(curvTrim); | |
209 | } | |
210 | TColStd_Array1OfReal BSK(1,curvBS->NbKnots()); | |
211 | curvBS->Knots(BSK); | |
212 | BSplCLib::Reparametrize(i-1,i,BSK); | |
213 | curvBS->SetKnots(BSK); | |
214 | ||
215 | // concatenation | |
216 | TopoDS_Vertex ComV; | |
217 | Standard_Real epsV; | |
218 | Standard_Boolean Bof = | |
219 | TopExp::CommonVertex(TopoDS::Edge(shapes.Value(i-1,j)), edge, ComV); | |
220 | if (Bof) epsV = BRep_Tool::Tolerance(ComV); | |
221 | else epsV = Precision::Confusion(); | |
222 | Bof = CompBS.Add(curvBS, epsV, Standard_True, Standard_False, 1); | |
223 | if (!Bof) Bof = CompBS.Add(curvBS, 200*epsV, | |
224 | Standard_True, Standard_False, 1); | |
225 | } | |
226 | ||
0d969553 | 227 | // return the final section |
7fd59977 | 228 | BS = CompBS.BSplineCurve(); |
229 | section.AddCurve(BS); | |
230 | ||
0d969553 | 231 | // case of looping sections |
7fd59977 | 232 | if (j==jdeb && vClosed) { |
233 | BS1 = BS; | |
234 | } | |
235 | ||
236 | } | |
237 | } | |
238 | ||
239 | if (w2Point) { | |
240 | edge = TopoDS::Edge(shapes.Value(NbEdges,NbSects)); | |
241 | TopExp::Vertices(edge,vl,vf); | |
242 | TColgp_Array1OfPnt Extremities(1,2); | |
243 | Extremities(1) = BRep_Tool::Pnt(vf); | |
244 | Extremities(2) = BRep_Tool::Pnt(vl); | |
245 | TColStd_Array1OfReal Bounds(1,2); | |
246 | Bounds(1) = 0.; | |
247 | Bounds(2) = 1.; | |
248 | Standard_Real Deg = 1; | |
249 | TColStd_Array1OfInteger Mult(1,2); | |
250 | Mult(1) = (Standard_Integer) Deg+1; | |
251 | Mult(2) = (Standard_Integer) Deg+1; | |
252 | Handle(Geom_BSplineCurve) BSPoint | |
253 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,(Standard_Integer ) Deg); | |
254 | section.AddCurve(BSPoint); | |
255 | } | |
256 | ||
257 | Handle(TColStd_HArray1OfReal) HPar | |
258 | = new TColStd_HArray1OfReal(1,params.Length()); | |
259 | for (i=1; i<=params.Length(); i++) { | |
260 | HPar->SetValue(i,params(i)); | |
261 | } | |
262 | section.SetParam(HPar); | |
263 | section.Perform(Precision::PConfusion()); | |
264 | Handle(GeomFill_Line) line = new GeomFill_Line(NbSects); | |
265 | Standard_Integer nbIt = 0, degmin = 2, degmax = 6; | |
266 | Standard_Boolean knownP = Standard_True; | |
267 | GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt, knownP); | |
268 | Standard_Boolean SpApprox = Standard_True; | |
269 | anApprox.Perform(line, section, SpApprox); | |
270 | Standard_Boolean uperiodic = uClosed; | |
271 | Standard_Boolean vperiodic = vClosed; | |
272 | Standard_Integer nup = anApprox.SurfPoles().ColLength(), | |
273 | nvp = anApprox.SurfPoles().RowLength(); | |
274 | TColStd_Array1OfInteger Umults(1,anApprox.SurfUKnots().Length()); | |
275 | Umults = anApprox.SurfUMults(); | |
276 | TColStd_Array1OfInteger Vmults(1,anApprox.SurfVKnots().Length()); | |
277 | Vmults = anApprox.SurfVMults(); | |
278 | ||
279 | if (uperiodic) { | |
280 | Standard_Integer nbuk = anApprox.SurfUKnots().Length(); | |
281 | Umults(1) --; | |
282 | Umults(nbuk) --; | |
283 | nup --; | |
284 | } | |
285 | ||
286 | if (vperiodic) { | |
287 | Standard_Integer nbvk = anApprox.SurfVKnots().Length(); | |
288 | Vmults(1) --; | |
289 | Vmults(nbvk) --; | |
290 | nvp --; | |
291 | } | |
292 | ||
293 | TColgp_Array2OfPnt poles (1, nup, 1, nvp); | |
294 | TColStd_Array2OfReal weights(1, nup, 1, nvp); | |
295 | for (j = 1; j <= nvp; j++) { | |
296 | for (i = 1; i <= nup; i++) { | |
297 | poles(i, j) = anApprox.SurfPoles()(i,j); | |
298 | weights(i, j) = anApprox.SurfWeights()(i,j); | |
299 | } | |
300 | } | |
301 | ||
302 | // To create non-rational surface if possible | |
303 | Standard_Real TolEps = 1.e-13; | |
304 | Standard_Boolean Vrational = Standard_False, Urational = Standard_False; | |
305 | for (j = 1; j <= weights.UpperCol(); j++) | |
306 | if (!Vrational) | |
307 | for (i = 1; i <= weights.UpperRow()-1; i++) | |
308 | { | |
309 | //Standard_Real signeddelta = weights(i,j) - weights(i+1,j); | |
310 | Standard_Real delta = Abs( weights(i,j) - weights(i+1,j) ); | |
311 | // Standard_Real eps = Epsilon( Abs(weights(i,j)) ); | |
312 | if (delta > TolEps/* || delta > 3.*eps*/) | |
313 | { | |
314 | Vrational = Standard_True; | |
315 | break; | |
316 | } | |
317 | } | |
318 | for (i = 1; i <= weights.UpperRow(); i++) | |
319 | if (!Urational) | |
320 | for (j = 1; j <= weights.UpperCol()-1; j++) | |
321 | { | |
322 | //Standard_Real signeddelta = weights(i,j) - weights(i,j+1); | |
323 | Standard_Real delta = Abs( weights(i,j) - weights(i,j+1) ); | |
324 | // Standard_Real eps = Epsilon( Abs(weights(i,j)) ); | |
325 | if (delta > TolEps/* || delta > 3.*eps*/) | |
326 | { | |
327 | Urational = Standard_True; | |
328 | break; | |
329 | } | |
330 | } | |
331 | if (!Vrational && !Urational) | |
332 | { | |
333 | Standard_Real theWeight = weights(1,1); | |
334 | for (i = 1; i <= weights.UpperRow(); i++) | |
335 | for (j = 1; j <= weights.UpperCol(); j++) | |
336 | weights(i,j) = theWeight; | |
337 | } | |
338 | ||
339 | surface = | |
340 | new Geom_BSplineSurface(poles, weights, | |
341 | anApprox.SurfUKnots(), anApprox.SurfVKnots(), | |
342 | Umults, Vmults, | |
343 | anApprox.UDegree(), anApprox.VDegree(), | |
344 | uperiodic, vperiodic); | |
345 | return surface; | |
346 | ||
347 | } | |
348 | ||
349 | ||
350 | //======================================================================= | |
351 | //function : Create | |
352 | //purpose : WSeq | |
353 | //======================================================================= | |
354 | ||
355 | BRepFill_NSections::BRepFill_NSections(const TopTools_SequenceOfShape& S, | |
356 | const Standard_Boolean Build) | |
357 | ||
358 | { | |
359 | myShapes = S; | |
360 | VFirst = 0.; | |
361 | VLast = 1.; | |
362 | TColStd_SequenceOfReal par; | |
363 | par.Clear(); | |
364 | for (Standard_Integer i=1;i<=S.Length();i++) { | |
365 | par.Append(i-1); | |
366 | } | |
367 | myParams = par; | |
368 | Init(par,Build); | |
369 | } | |
370 | ||
371 | //======================================================================= | |
372 | //function : Create | |
373 | //purpose : WSeq + Param | |
374 | //======================================================================= | |
375 | ||
376 | BRepFill_NSections::BRepFill_NSections(const TopTools_SequenceOfShape& S, | |
d7325741 | 377 | const GeomFill_SequenceOfTrsf& Transformations, |
7fd59977 | 378 | const TColStd_SequenceOfReal & P, |
379 | const Standard_Real VF, | |
380 | const Standard_Real VL, | |
381 | const Standard_Boolean Build) | |
382 | ||
383 | { | |
384 | #ifdef DEB | |
385 | if ( Affich) { | |
386 | #ifdef DRAW | |
387 | Standard_Integer NBSECT = 0; | |
388 | for (Standard_Integer i=1;i<=S.Length();i++) { | |
389 | NBSECT++; | |
390 | char name[256]; | |
391 | sprintf(name,"WIRE_%d",NBSECT); | |
392 | DBRep::Set(name,TopoDS::Wire(S.Value(i))); | |
393 | } | |
394 | #endif | |
395 | } | |
396 | #endif | |
397 | Standard_Boolean ok = Standard_True; | |
398 | for (Standard_Integer iseq=1;iseq<P.Length();iseq++) { | |
399 | ok = ok && (P.Value(iseq)<P.Value(iseq+1)); | |
400 | } | |
401 | if (ok) { | |
402 | myParams = P; | |
403 | myShapes = S; | |
d7325741 | 404 | myTrsfs = Transformations; |
7fd59977 | 405 | VFirst = VF; |
406 | VLast = VL; | |
407 | Init(P,Build); | |
408 | } | |
409 | } | |
410 | ||
411 | //======================================================================= | |
412 | //function : Init | |
0d969553 | 413 | //purpose : Create a table of GeomFill_SectionLaw |
7fd59977 | 414 | //======================================================================= |
415 | void BRepFill_NSections::Init(const TColStd_SequenceOfReal & P, | |
416 | const Standard_Boolean Build) | |
417 | { | |
418 | BRepTools_WireExplorer wexp; | |
419 | // Class BRep_Tool without fields and without Constructor : | |
420 | // BRep_Tool B; | |
421 | TopoDS_Edge E; | |
422 | Standard_Integer ii, NbEdge, jj, NbSects = P.Length(); | |
423 | Standard_Integer ideb = 1, ifin = NbSects; | |
424 | Standard_Boolean wClosed, w1Point = Standard_True, | |
425 | w2Point = Standard_True; | |
426 | Standard_Real First, Last; | |
427 | TopoDS_Wire W; | |
428 | ||
0d969553 | 429 | // Check if the start and end wires are punctual |
7fd59977 | 430 | W = TopoDS::Wire(myShapes(1)); |
431 | for (wexp.Init(W); wexp.More(); wexp.Next()) | |
432 | // w1Point = w1Point && B.Degenerated(wexp.Current()); | |
433 | w1Point = w1Point && BRep_Tool::Degenerated(wexp.Current()); | |
434 | if (w1Point) ideb++; | |
435 | W = TopoDS::Wire(myShapes(NbSects)); | |
436 | for (wexp.Init(W); wexp.More(); wexp.Next()) | |
437 | // w2Point = w2Point && B.Degenerated(wexp.Current()); | |
438 | w2Point = w2Point && BRep_Tool::Degenerated(wexp.Current()); | |
439 | if (w2Point) ifin--; | |
440 | ||
0d969553 | 441 | // Check if the start and end wires are identical |
7fd59977 | 442 | vclosed = myShapes(1).IsSame(myShapes(NbSects)); |
443 | ||
0d969553 | 444 | // Count the number of non-degenerated edges |
7fd59977 | 445 | W = TopoDS::Wire(myShapes(ideb)); |
446 | for (NbEdge=0, wexp.Init(W); wexp.More(); wexp.Next()) | |
447 | // if (! B.Degenerated(wexp.Current())) NbEdge++; | |
448 | if (! BRep_Tool::Degenerated(wexp.Current())) NbEdge++; | |
449 | ||
7fd59977 | 450 | myEdges = new (TopTools_HArray2OfShape) (1, NbEdge, 1, NbSects); |
451 | ||
0d969553 | 452 | // Fill tables |
7fd59977 | 453 | uclosed = Standard_True; |
454 | for (jj=ideb;jj<=ifin;jj++){ | |
455 | ||
456 | W = TopoDS::Wire(myShapes(jj)); | |
457 | ||
458 | for (ii=1, wexp.Init(W); ii<=NbEdge ; wexp.Next(), ii++) { | |
459 | E = wexp.Current(); | |
460 | ||
461 | // if ( ! B.Degenerated(E)) { | |
462 | if ( ! BRep_Tool::Degenerated(E)) { | |
463 | myEdges->SetValue(ii,jj, E); | |
464 | } | |
465 | } | |
466 | ||
0d969553 | 467 | // Is the law closed by U ? |
7fd59977 | 468 | |
469 | wClosed = W.Closed(); | |
470 | if (!wClosed) { | |
0d969553 | 471 | // if unsure about the flag, make check |
7fd59977 | 472 | TopoDS_Edge Edge1, Edge2; |
473 | TopoDS_Vertex V1,V2; | |
474 | Edge1 = TopoDS::Edge (myEdges->Value(NbEdge,jj)); | |
475 | Edge2 = TopoDS::Edge (myEdges->Value(1,jj)); | |
476 | ||
477 | if ( Edge1.Orientation() == TopAbs_REVERSED) { | |
478 | V1 = TopExp::FirstVertex(Edge1); | |
479 | } | |
480 | else { | |
481 | V1 = TopExp::LastVertex(Edge1); | |
482 | } | |
483 | if ( Edge2.Orientation() == TopAbs_REVERSED) { | |
484 | V2 = TopExp::LastVertex(Edge2); | |
485 | } | |
486 | else { | |
487 | V2 = TopExp::FirstVertex(Edge2); | |
488 | } | |
489 | if (V1.IsSame(V2)) { | |
490 | wClosed = Standard_True; | |
491 | } | |
492 | else { | |
493 | BRepAdaptor_Curve Curve1(Edge1); | |
494 | BRepAdaptor_Curve Curve2(Edge2); | |
495 | Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1); | |
496 | Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2); | |
497 | Standard_Real Eps = BRep_Tool::Tolerance(V2) + | |
498 | BRep_Tool::Tolerance(V1); | |
499 | ||
500 | wClosed = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps); | |
501 | } | |
502 | } | |
503 | if (!wClosed) uclosed = Standard_False; | |
504 | } | |
505 | ||
0d969553 | 506 | // point sections at end |
7fd59977 | 507 | if (w1Point) { |
508 | W = TopoDS::Wire(myShapes(1)); | |
509 | wexp.Init(W); | |
510 | E = wexp.Current(); | |
511 | for (ii=1; ii<=NbEdge ; ii++) { | |
512 | myEdges->SetValue(ii, 1, E); | |
513 | } | |
514 | } | |
515 | ||
516 | if (w2Point) { | |
517 | W = TopoDS::Wire(myShapes(NbSects)); | |
518 | wexp.Init(W); | |
519 | E = wexp.Current(); | |
520 | for (ii=1; ii<=NbEdge ; ii++) { | |
521 | myEdges->SetValue(ii, NbSects, E); | |
522 | } | |
523 | } | |
524 | ||
525 | ||
526 | myLaws = new (GeomFill_HArray1OfSectionLaw) (1, NbEdge); | |
527 | ||
528 | Standard_Real tol = Precision::Confusion(); | |
529 | mySurface = totalsurf(myEdges->Array2(),myShapes.Length(),NbEdge, | |
530 | myParams,w1Point,w2Point,uclosed,vclosed,tol); | |
531 | ||
0d969553 Y |
532 | // Increase the degree so that the position D2 |
533 | // on GeomFill_NSections could be correct | |
534 | // see comments in GeomFill_NSections | |
7fd59977 | 535 | if (mySurface->VDegree()<2) { |
536 | mySurface->IncreaseDegree(mySurface->UDegree(),2); | |
537 | } | |
538 | #ifdef DRAW | |
539 | if ( Affich) { | |
540 | char* name = new char[100]; | |
541 | sprintf(name,"Ref_Surf"); | |
542 | DrawTrSurf::Set(name,mySurface); | |
543 | } | |
544 | #endif | |
545 | ||
0d969553 | 546 | // Fill tables |
7fd59977 | 547 | if (Build) { |
548 | for (ii=1; ii<=NbEdge ; ii++) { | |
549 | TColGeom_SequenceOfCurve NC; | |
550 | NC.Clear(); | |
551 | for (jj=1;jj<=NbSects;jj++) { | |
552 | E = TopoDS::Edge (myEdges->Value(ii,jj)); | |
553 | Handle(Geom_Curve) C; | |
554 | // if (B.Degenerated(E)) { | |
555 | if (BRep_Tool::Degenerated(E)) { | |
556 | TopoDS_Vertex vf,vl; | |
557 | TopExp::Vertices(E,vl,vf); | |
558 | TColgp_Array1OfPnt Extremities(1,2); | |
559 | Extremities(1) = BRep_Tool::Pnt(vf); | |
560 | Extremities(2) = BRep_Tool::Pnt(vl); | |
561 | TColStd_Array1OfReal Bounds(1,2); | |
562 | Bounds(1) = 0.; | |
563 | Bounds(2) = 1.; | |
564 | TColStd_Array1OfInteger Mult(1,2); | |
565 | Mult(1) = 2; | |
566 | Mult(2) = 2; | |
567 | Handle(Geom_BSplineCurve) BSPoint | |
568 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,1); | |
569 | C = BSPoint; | |
570 | } | |
571 | else { | |
572 | C = BRep_Tool::Curve(E,First,Last); | |
573 | ||
574 | if (E.Orientation() == TopAbs_REVERSED) { | |
575 | Standard_Real aux; | |
576 | Handle(Geom_Curve) CBis; | |
0d969553 | 577 | CBis = C->Reversed(); // To avoid the spoiling of the topology |
7fd59977 | 578 | aux = C->ReversedParameter(First); |
579 | First = C->ReversedParameter(Last); | |
580 | Last = aux; | |
581 | C = CBis; | |
582 | } | |
0d969553 | 583 | if ((ii>1) || (!E.Closed()) ) { // Cut C |
7fd59977 | 584 | Handle(Geom_TrimmedCurve) TC = |
585 | new (Geom_TrimmedCurve) (C,First, Last); | |
586 | C = TC; | |
587 | } | |
0d969553 | 588 | // otherwise preserve the integrity of the curve |
7fd59977 | 589 | } |
590 | NC.Append(C); | |
591 | } | |
592 | ||
593 | Standard_Real Ufirst = ii-1; | |
594 | Standard_Real Ulast = ii; | |
d7325741 | 595 | myLaws->ChangeValue(ii) = new (GeomFill_NSections)(NC, myTrsfs, myParams, |
7fd59977 | 596 | Ufirst,Ulast, |
597 | VFirst,VLast, | |
598 | mySurface); | |
599 | } | |
600 | ||
601 | } | |
602 | ||
603 | } | |
604 | ||
605 | ||
606 | //======================================================================= | |
607 | //function : IsVertex | |
608 | //purpose : | |
609 | //======================================================================= | |
610 | Standard_Boolean BRepFill_NSections::IsVertex() const | |
611 | { | |
612 | return Standard_False; | |
613 | } | |
614 | ||
615 | //======================================================================= | |
616 | //function : IsConstant | |
617 | //purpose : | |
618 | //======================================================================= | |
619 | Standard_Boolean BRepFill_NSections::IsConstant() const | |
620 | { | |
621 | return Standard_False; | |
622 | } | |
623 | ||
624 | //======================================================================= | |
625 | //function : Vertex | |
626 | //purpose : | |
627 | //======================================================================= | |
628 | TopoDS_Vertex | |
629 | BRepFill_NSections::Vertex(const Standard_Integer Index, | |
630 | const Standard_Real Param) const | |
631 | { | |
632 | BRep_Builder B; | |
633 | TopoDS_Vertex V; | |
634 | B.MakeVertex(V); | |
635 | gp_Pnt P; | |
636 | ||
637 | if (Index <= myEdges->ColLength()) { | |
638 | Handle(Geom_BSplineCurve) Curve | |
639 | = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(Index)-> | |
640 | BSplineSurface()->VIso(Param)); | |
641 | Standard_Real first = Curve ->FirstParameter(); | |
642 | Curve->D0(first, P); | |
643 | B.UpdateVertex(V, P, Precision::Confusion()); | |
644 | } | |
645 | else if (Index == myEdges->ColLength()+1) { | |
646 | Handle(Geom_BSplineCurve) Curve | |
647 | = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(Index-1)-> | |
648 | BSplineSurface()->VIso(Param)); | |
649 | Standard_Real last = Curve ->LastParameter(); | |
650 | Curve->D0(last, P); | |
651 | B.UpdateVertex(V, P, Precision::Confusion()); | |
652 | } | |
653 | ||
654 | return V; | |
655 | } | |
656 | ||
657 | ||
658 | ///======================================================================= | |
659 | //function : VertexTol | |
0d969553 | 660 | //purpose : Evaluate the hole between 2 edges of the section |
7fd59977 | 661 | //======================================================================= |
662 | Standard_Real BRepFill_NSections::VertexTol(const Standard_Integer Index, | |
663 | const Standard_Real Param) const | |
664 | { | |
665 | Standard_Real Tol = Precision::Confusion(); | |
666 | Standard_Integer I1, I2; | |
667 | if ( (Index==0) || (Index==myEdges->ColLength()) ) { | |
0d969553 | 668 | if (!uclosed) return Tol; //The least possible error |
7fd59977 | 669 | I1 = myEdges->ColLength(); |
670 | I2 = 1; | |
671 | } | |
672 | else { | |
673 | I1 = Index; | |
674 | I2 = I1 +1; | |
675 | } | |
676 | ||
677 | Handle(GeomFill_SectionLaw) Loi; | |
678 | Standard_Integer NbPoles, NbKnots, Degree; | |
679 | Handle(TColgp_HArray1OfPnt) Poles; | |
680 | Handle(TColStd_HArray1OfReal) Knots, Weigth; | |
681 | Handle(TColStd_HArray1OfInteger) Mults; | |
682 | Handle(Geom_BSplineCurve) BS; | |
683 | gp_Pnt PFirst; | |
684 | ||
685 | Loi = myLaws->Value(I1); | |
686 | Loi->SectionShape( NbPoles, NbKnots, Degree); | |
687 | Poles = new (TColgp_HArray1OfPnt) (1, NbPoles); | |
688 | Weigth = new (TColStd_HArray1OfReal) (1, NbPoles); | |
689 | Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1()); | |
690 | Knots = new (TColStd_HArray1OfReal) (1, NbKnots); | |
691 | Loi->Knots(Knots->ChangeArray1()); | |
692 | Mults = new (TColStd_HArray1OfInteger) (1, NbKnots); | |
693 | Loi->Mults(Mults->ChangeArray1()); | |
694 | BS = new (Geom_BSplineCurve) (Poles->Array1(), | |
695 | Weigth->Array1(), | |
696 | Knots->Array1(), | |
697 | Mults->Array1(), | |
698 | Degree, | |
699 | Loi->IsUPeriodic()); | |
700 | PFirst = BS->Value( Knots->Value(Knots->Length()) ); | |
701 | ||
702 | Loi = myLaws->Value(I2); | |
703 | Loi->SectionShape( NbPoles, NbKnots, Degree); | |
704 | Poles = new (TColgp_HArray1OfPnt) (1, NbPoles); | |
705 | Weigth = new (TColStd_HArray1OfReal) (1, NbPoles); | |
706 | Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1()); | |
707 | Knots = new (TColStd_HArray1OfReal) (1, NbKnots); | |
708 | Loi->Knots(Knots->ChangeArray1()); | |
709 | Mults = new (TColStd_HArray1OfInteger) (1, NbKnots); | |
710 | Loi->Mults(Mults->ChangeArray1()); | |
711 | BS = new (Geom_BSplineCurve) (Poles->Array1(), | |
712 | Weigth->Array1(), | |
713 | Knots->Array1(), | |
714 | Mults->Array1(), | |
715 | Degree, | |
716 | Loi->IsUPeriodic()); | |
717 | Tol += PFirst.Distance(BS->Value( Knots->Value(1))); | |
718 | return Tol; | |
719 | } | |
720 | ||
721 | //======================================================================= | |
722 | //function : ConcatenedLaw | |
723 | //purpose : | |
724 | //======================================================================= | |
725 | ||
726 | Handle(GeomFill_SectionLaw) BRepFill_NSections::ConcatenedLaw() const | |
727 | { | |
728 | Handle(GeomFill_SectionLaw) Law; | |
729 | if (myLaws->Length() == 1) | |
730 | return myLaws->Value(1); | |
731 | else { | |
732 | Standard_Real Ufirst, Ulast, Vfirst, Vlast; | |
733 | mySurface->Bounds(Ufirst, Ulast, Vfirst, Vlast); | |
734 | TColGeom_SequenceOfCurve NCompo; | |
735 | NCompo.Clear(); | |
736 | for (Standard_Integer jj=1; jj<=myShapes.Length(); jj++) { | |
737 | NCompo.Append(mySurface->VIso(myParams(jj))); | |
738 | } | |
d7325741 | 739 | Law = new (GeomFill_NSections)(NCompo, myTrsfs, myParams, |
7fd59977 | 740 | Ufirst, Ulast, |
741 | Vfirst, Vlast, | |
742 | mySurface); | |
743 | } | |
744 | return Law; | |
745 | } | |
746 | ||
747 | //======================================================================= | |
748 | //function : Continuity | |
749 | //purpose : | |
750 | //======================================================================= | |
751 | GeomAbs_Shape BRepFill_NSections::Continuity(const Standard_Integer Index, | |
752 | const Standard_Real TolAngular) const | |
753 | { | |
754 | ||
755 | Standard_Integer jj; | |
756 | GeomAbs_Shape cont_jj; | |
7fd59977 | 757 | GeomAbs_Shape cont = GeomAbs_C0; |
7fd59977 | 758 | |
759 | for (jj=1; jj<=myShapes.Length(); jj++) { | |
760 | ||
761 | TopoDS_Edge Edge1, Edge2; | |
762 | if ( (Index==0) || (Index==myEdges->ColLength()) ) { | |
0d969553 | 763 | if (!uclosed) return GeomAbs_C0; //The least possible error |
7fd59977 | 764 | |
765 | Edge1 = TopoDS::Edge (myEdges->Value(myEdges->ColLength(),jj)); | |
766 | Edge2 = TopoDS::Edge (myEdges->Value(1,jj)); | |
767 | } | |
768 | else { | |
769 | Edge1 = TopoDS::Edge (myEdges->Value(Index,jj)); | |
770 | Edge2 = TopoDS::Edge (myEdges->Value(Index+1,jj)); | |
771 | } | |
772 | ||
773 | TopoDS_Vertex V1,V2; | |
774 | if ( Edge1.Orientation() == TopAbs_REVERSED) { | |
775 | V1 = TopExp::FirstVertex(Edge1); | |
776 | } | |
777 | else { | |
778 | V1 = TopExp::LastVertex(Edge1); | |
779 | } | |
780 | if ( Edge2.Orientation() == TopAbs_REVERSED) { | |
781 | V2 = TopExp::LastVertex(Edge2); | |
782 | } | |
783 | else { | |
784 | V2 = TopExp::FirstVertex(Edge2); | |
785 | } | |
786 | ||
787 | if (BRep_Tool::Degenerated(Edge1) || BRep_Tool::Degenerated(Edge2)) | |
788 | cont_jj = GeomAbs_CN; | |
789 | else | |
790 | { | |
791 | Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1); | |
792 | Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2); | |
793 | BRepAdaptor_Curve Curve1(Edge1); | |
794 | BRepAdaptor_Curve Curve2(Edge2); | |
795 | Standard_Real Eps = BRep_Tool::Tolerance(V2) + | |
796 | BRep_Tool::Tolerance(V1); | |
797 | cont_jj = BRepLProp::Continuity(Curve1,Curve2,U1,U2, Eps, TolAngular); | |
798 | } | |
799 | ||
800 | if (jj==1) cont = cont_jj; | |
801 | if (cont>cont_jj) cont = cont_jj; | |
802 | ||
803 | } | |
804 | ||
805 | return cont; | |
806 | } | |
807 | ||
808 | //======================================================================= | |
809 | //function : D0 | |
810 | //purpose : | |
811 | //======================================================================= | |
812 | void BRepFill_NSections::D0(const Standard_Real V, TopoDS_Shape& S) | |
813 | { | |
814 | TopoDS_Wire W; | |
815 | BRepLib_MakeWire MW; | |
816 | Standard_Integer ii, NbEdge = myLaws->Length(); | |
817 | for (ii=1; ii<=NbEdge ; ii++) { | |
818 | Handle(Geom_BSplineCurve) Curve | |
819 | = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(ii)->BSplineSurface()->VIso(V)); | |
820 | Standard_Real first = Curve ->FirstParameter(), | |
821 | last = Curve ->LastParameter(); | |
822 | TopoDS_Edge E = BRepLib_MakeEdge(Curve,first,last); | |
823 | MW.Add(E); | |
824 | } | |
825 | TopAbs_Orientation Orien = TopAbs_FORWARD; | |
826 | TopoDS_Shape aLocalShape = MW.Wire().Oriented(Orien); | |
827 | S = TopoDS::Wire(aLocalShape); | |
828 | // S = TopoDS::Wire(MW.Wire().Oriented(Orien)); | |
829 | ||
830 | } | |
831 |