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