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 | ||
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 | { | |
543a9964 | 115 | const Handle(Geom_Curve)& aCurve = aTrimCurve; // to avoid ambiguity |
116 | GeomConvert_ApproxCurve anAppr (aCurve, 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); | |
363 | } | |
364 | ||
365 | //======================================================================= | |
366 | //function : Create | |
367 | //purpose : WSeq + Param | |
368 | //======================================================================= | |
369 | ||
370 | BRepFill_NSections::BRepFill_NSections(const TopTools_SequenceOfShape& S, | |
d7325741 | 371 | const GeomFill_SequenceOfTrsf& Transformations, |
7fd59977 | 372 | const TColStd_SequenceOfReal & P, |
373 | const Standard_Real VF, | |
374 | const Standard_Real VL, | |
375 | const Standard_Boolean Build) | |
376 | ||
377 | { | |
0797d9d3 | 378 | #ifdef OCCT_DEBUG |
7fd59977 | 379 | if ( Affich) { |
380 | #ifdef DRAW | |
381 | Standard_Integer NBSECT = 0; | |
382 | for (Standard_Integer i=1;i<=S.Length();i++) { | |
383 | NBSECT++; | |
384 | char name[256]; | |
385 | sprintf(name,"WIRE_%d",NBSECT); | |
386 | DBRep::Set(name,TopoDS::Wire(S.Value(i))); | |
387 | } | |
388 | #endif | |
389 | } | |
390 | #endif | |
391 | Standard_Boolean ok = Standard_True; | |
392 | for (Standard_Integer iseq=1;iseq<P.Length();iseq++) { | |
393 | ok = ok && (P.Value(iseq)<P.Value(iseq+1)); | |
394 | } | |
395 | if (ok) { | |
396 | myParams = P; | |
397 | myShapes = S; | |
d7325741 | 398 | myTrsfs = Transformations; |
7fd59977 | 399 | VFirst = VF; |
400 | VLast = VL; | |
401 | Init(P,Build); | |
402 | } | |
403 | } | |
404 | ||
405 | //======================================================================= | |
406 | //function : Init | |
0d969553 | 407 | //purpose : Create a table of GeomFill_SectionLaw |
7fd59977 | 408 | //======================================================================= |
409 | void BRepFill_NSections::Init(const TColStd_SequenceOfReal & P, | |
410 | const Standard_Boolean Build) | |
411 | { | |
412 | BRepTools_WireExplorer wexp; | |
413 | // Class BRep_Tool without fields and without Constructor : | |
414 | // BRep_Tool B; | |
415 | TopoDS_Edge E; | |
416 | Standard_Integer ii, NbEdge, jj, NbSects = P.Length(); | |
417 | Standard_Integer ideb = 1, ifin = NbSects; | |
418 | Standard_Boolean wClosed, w1Point = Standard_True, | |
419 | w2Point = Standard_True; | |
420 | Standard_Real First, Last; | |
421 | TopoDS_Wire W; | |
422 | ||
0d969553 | 423 | // Check if the start and end wires are punctual |
7fd59977 | 424 | W = TopoDS::Wire(myShapes(1)); |
425 | for (wexp.Init(W); wexp.More(); wexp.Next()) | |
426 | // w1Point = w1Point && B.Degenerated(wexp.Current()); | |
427 | w1Point = w1Point && BRep_Tool::Degenerated(wexp.Current()); | |
428 | if (w1Point) ideb++; | |
429 | W = TopoDS::Wire(myShapes(NbSects)); | |
430 | for (wexp.Init(W); wexp.More(); wexp.Next()) | |
431 | // w2Point = w2Point && B.Degenerated(wexp.Current()); | |
432 | w2Point = w2Point && BRep_Tool::Degenerated(wexp.Current()); | |
433 | if (w2Point) ifin--; | |
434 | ||
0d969553 | 435 | // Check if the start and end wires are identical |
7fd59977 | 436 | vclosed = myShapes(1).IsSame(myShapes(NbSects)); |
437 | ||
0d969553 | 438 | // Count the number of non-degenerated edges |
7fd59977 | 439 | W = TopoDS::Wire(myShapes(ideb)); |
440 | for (NbEdge=0, wexp.Init(W); wexp.More(); wexp.Next()) | |
441 | // if (! B.Degenerated(wexp.Current())) NbEdge++; | |
442 | if (! BRep_Tool::Degenerated(wexp.Current())) NbEdge++; | |
443 | ||
7fd59977 | 444 | myEdges = new (TopTools_HArray2OfShape) (1, NbEdge, 1, NbSects); |
445 | ||
0d969553 | 446 | // Fill tables |
7fd59977 | 447 | uclosed = Standard_True; |
448 | for (jj=ideb;jj<=ifin;jj++){ | |
449 | ||
450 | W = TopoDS::Wire(myShapes(jj)); | |
451 | ||
452 | for (ii=1, wexp.Init(W); ii<=NbEdge ; wexp.Next(), ii++) { | |
453 | E = wexp.Current(); | |
454 | ||
455 | // if ( ! B.Degenerated(E)) { | |
456 | if ( ! BRep_Tool::Degenerated(E)) { | |
457 | myEdges->SetValue(ii,jj, E); | |
458 | } | |
459 | } | |
460 | ||
0d969553 | 461 | // Is the law closed by U ? |
7fd59977 | 462 | |
463 | wClosed = W.Closed(); | |
464 | if (!wClosed) { | |
0d969553 | 465 | // if unsure about the flag, make check |
7fd59977 | 466 | TopoDS_Edge Edge1, Edge2; |
467 | TopoDS_Vertex V1,V2; | |
468 | Edge1 = TopoDS::Edge (myEdges->Value(NbEdge,jj)); | |
469 | Edge2 = TopoDS::Edge (myEdges->Value(1,jj)); | |
470 | ||
471 | if ( Edge1.Orientation() == TopAbs_REVERSED) { | |
472 | V1 = TopExp::FirstVertex(Edge1); | |
473 | } | |
474 | else { | |
475 | V1 = TopExp::LastVertex(Edge1); | |
476 | } | |
477 | if ( Edge2.Orientation() == TopAbs_REVERSED) { | |
478 | V2 = TopExp::LastVertex(Edge2); | |
479 | } | |
480 | else { | |
481 | V2 = TopExp::FirstVertex(Edge2); | |
482 | } | |
483 | if (V1.IsSame(V2)) { | |
484 | wClosed = Standard_True; | |
485 | } | |
486 | else { | |
487 | BRepAdaptor_Curve Curve1(Edge1); | |
488 | BRepAdaptor_Curve Curve2(Edge2); | |
489 | Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1); | |
490 | Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2); | |
491 | Standard_Real Eps = BRep_Tool::Tolerance(V2) + | |
492 | BRep_Tool::Tolerance(V1); | |
493 | ||
494 | wClosed = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps); | |
495 | } | |
496 | } | |
497 | if (!wClosed) uclosed = Standard_False; | |
498 | } | |
499 | ||
0d969553 | 500 | // point sections at end |
7fd59977 | 501 | if (w1Point) { |
502 | W = TopoDS::Wire(myShapes(1)); | |
503 | wexp.Init(W); | |
504 | E = wexp.Current(); | |
505 | for (ii=1; ii<=NbEdge ; ii++) { | |
506 | myEdges->SetValue(ii, 1, E); | |
507 | } | |
508 | } | |
509 | ||
510 | if (w2Point) { | |
511 | W = TopoDS::Wire(myShapes(NbSects)); | |
512 | wexp.Init(W); | |
513 | E = wexp.Current(); | |
514 | for (ii=1; ii<=NbEdge ; ii++) { | |
515 | myEdges->SetValue(ii, NbSects, E); | |
516 | } | |
517 | } | |
518 | ||
519 | ||
520 | myLaws = new (GeomFill_HArray1OfSectionLaw) (1, NbEdge); | |
521 | ||
522 | Standard_Real tol = Precision::Confusion(); | |
523 | mySurface = totalsurf(myEdges->Array2(),myShapes.Length(),NbEdge, | |
524 | myParams,w1Point,w2Point,uclosed,vclosed,tol); | |
525 | ||
0d969553 Y |
526 | // Increase the degree so that the position D2 |
527 | // on GeomFill_NSections could be correct | |
528 | // see comments in GeomFill_NSections | |
7fd59977 | 529 | if (mySurface->VDegree()<2) { |
530 | mySurface->IncreaseDegree(mySurface->UDegree(),2); | |
531 | } | |
532 | #ifdef DRAW | |
533 | if ( Affich) { | |
534 | char* name = new char[100]; | |
535 | sprintf(name,"Ref_Surf"); | |
536 | DrawTrSurf::Set(name,mySurface); | |
537 | } | |
538 | #endif | |
539 | ||
0d969553 | 540 | // Fill tables |
7fd59977 | 541 | if (Build) { |
542 | for (ii=1; ii<=NbEdge ; ii++) { | |
543 | TColGeom_SequenceOfCurve NC; | |
544 | NC.Clear(); | |
545 | for (jj=1;jj<=NbSects;jj++) { | |
546 | E = TopoDS::Edge (myEdges->Value(ii,jj)); | |
547 | Handle(Geom_Curve) C; | |
548 | // if (B.Degenerated(E)) { | |
549 | if (BRep_Tool::Degenerated(E)) { | |
550 | TopoDS_Vertex vf,vl; | |
551 | TopExp::Vertices(E,vl,vf); | |
552 | TColgp_Array1OfPnt Extremities(1,2); | |
553 | Extremities(1) = BRep_Tool::Pnt(vf); | |
554 | Extremities(2) = BRep_Tool::Pnt(vl); | |
555 | TColStd_Array1OfReal Bounds(1,2); | |
556 | Bounds(1) = 0.; | |
557 | Bounds(2) = 1.; | |
558 | TColStd_Array1OfInteger Mult(1,2); | |
559 | Mult(1) = 2; | |
560 | Mult(2) = 2; | |
561 | Handle(Geom_BSplineCurve) BSPoint | |
562 | = new Geom_BSplineCurve(Extremities,Bounds,Mult,1); | |
563 | C = BSPoint; | |
564 | } | |
565 | else { | |
566 | C = BRep_Tool::Curve(E,First,Last); | |
567 | ||
568 | if (E.Orientation() == TopAbs_REVERSED) { | |
569 | Standard_Real aux; | |
570 | Handle(Geom_Curve) CBis; | |
0d969553 | 571 | CBis = C->Reversed(); // To avoid the spoiling of the topology |
7fd59977 | 572 | aux = C->ReversedParameter(First); |
573 | First = C->ReversedParameter(Last); | |
574 | Last = aux; | |
575 | C = CBis; | |
576 | } | |
da72a17c | 577 | if ((ii>1) || (!BRep_Tool::IsClosed(E)) ) { // Cut C |
7fd59977 | 578 | Handle(Geom_TrimmedCurve) TC = |
579 | new (Geom_TrimmedCurve) (C,First, Last); | |
580 | C = TC; | |
581 | } | |
0d969553 | 582 | // otherwise preserve the integrity of the curve |
7fd59977 | 583 | } |
584 | NC.Append(C); | |
585 | } | |
586 | ||
587 | Standard_Real Ufirst = ii-1; | |
588 | Standard_Real Ulast = ii; | |
d7325741 | 589 | myLaws->ChangeValue(ii) = new (GeomFill_NSections)(NC, myTrsfs, myParams, |
7fd59977 | 590 | Ufirst,Ulast, |
591 | VFirst,VLast, | |
592 | mySurface); | |
593 | } | |
594 | ||
595 | } | |
596 | ||
597 | } | |
598 | ||
599 | ||
600 | //======================================================================= | |
601 | //function : IsVertex | |
602 | //purpose : | |
603 | //======================================================================= | |
604 | Standard_Boolean BRepFill_NSections::IsVertex() const | |
605 | { | |
606 | return Standard_False; | |
607 | } | |
608 | ||
609 | //======================================================================= | |
610 | //function : IsConstant | |
611 | //purpose : | |
612 | //======================================================================= | |
613 | Standard_Boolean BRepFill_NSections::IsConstant() const | |
614 | { | |
615 | return Standard_False; | |
616 | } | |
617 | ||
618 | //======================================================================= | |
619 | //function : Vertex | |
620 | //purpose : | |
621 | //======================================================================= | |
622 | TopoDS_Vertex | |
623 | BRepFill_NSections::Vertex(const Standard_Integer Index, | |
624 | const Standard_Real Param) const | |
625 | { | |
626 | BRep_Builder B; | |
627 | TopoDS_Vertex V; | |
628 | B.MakeVertex(V); | |
629 | gp_Pnt P; | |
630 | ||
631 | if (Index <= myEdges->ColLength()) { | |
632 | Handle(Geom_BSplineCurve) Curve | |
633 | = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(Index)-> | |
634 | BSplineSurface()->VIso(Param)); | |
635 | Standard_Real first = Curve ->FirstParameter(); | |
636 | Curve->D0(first, P); | |
637 | B.UpdateVertex(V, P, Precision::Confusion()); | |
638 | } | |
639 | else if (Index == myEdges->ColLength()+1) { | |
640 | Handle(Geom_BSplineCurve) Curve | |
641 | = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(Index-1)-> | |
642 | BSplineSurface()->VIso(Param)); | |
643 | Standard_Real last = Curve ->LastParameter(); | |
644 | Curve->D0(last, P); | |
645 | B.UpdateVertex(V, P, Precision::Confusion()); | |
646 | } | |
647 | ||
648 | return V; | |
649 | } | |
650 | ||
651 | ||
652 | ///======================================================================= | |
653 | //function : VertexTol | |
0d969553 | 654 | //purpose : Evaluate the hole between 2 edges of the section |
7fd59977 | 655 | //======================================================================= |
656 | Standard_Real BRepFill_NSections::VertexTol(const Standard_Integer Index, | |
657 | const Standard_Real Param) const | |
658 | { | |
659 | Standard_Real Tol = Precision::Confusion(); | |
660 | Standard_Integer I1, I2; | |
661 | if ( (Index==0) || (Index==myEdges->ColLength()) ) { | |
0d969553 | 662 | if (!uclosed) return Tol; //The least possible error |
7fd59977 | 663 | I1 = myEdges->ColLength(); |
664 | I2 = 1; | |
665 | } | |
666 | else { | |
667 | I1 = Index; | |
668 | I2 = I1 +1; | |
669 | } | |
670 | ||
671 | Handle(GeomFill_SectionLaw) Loi; | |
672 | Standard_Integer NbPoles, NbKnots, Degree; | |
673 | Handle(TColgp_HArray1OfPnt) Poles; | |
674 | Handle(TColStd_HArray1OfReal) Knots, Weigth; | |
675 | Handle(TColStd_HArray1OfInteger) Mults; | |
676 | Handle(Geom_BSplineCurve) BS; | |
677 | gp_Pnt PFirst; | |
678 | ||
679 | Loi = myLaws->Value(I1); | |
680 | Loi->SectionShape( NbPoles, NbKnots, Degree); | |
681 | Poles = new (TColgp_HArray1OfPnt) (1, NbPoles); | |
682 | Weigth = new (TColStd_HArray1OfReal) (1, NbPoles); | |
683 | Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1()); | |
684 | Knots = new (TColStd_HArray1OfReal) (1, NbKnots); | |
685 | Loi->Knots(Knots->ChangeArray1()); | |
686 | Mults = new (TColStd_HArray1OfInteger) (1, NbKnots); | |
687 | Loi->Mults(Mults->ChangeArray1()); | |
688 | BS = new (Geom_BSplineCurve) (Poles->Array1(), | |
689 | Weigth->Array1(), | |
690 | Knots->Array1(), | |
691 | Mults->Array1(), | |
692 | Degree, | |
693 | Loi->IsUPeriodic()); | |
694 | PFirst = BS->Value( Knots->Value(Knots->Length()) ); | |
695 | ||
696 | Loi = myLaws->Value(I2); | |
697 | Loi->SectionShape( NbPoles, NbKnots, Degree); | |
698 | Poles = new (TColgp_HArray1OfPnt) (1, NbPoles); | |
699 | Weigth = new (TColStd_HArray1OfReal) (1, NbPoles); | |
700 | Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1()); | |
701 | Knots = new (TColStd_HArray1OfReal) (1, NbKnots); | |
702 | Loi->Knots(Knots->ChangeArray1()); | |
703 | Mults = new (TColStd_HArray1OfInteger) (1, NbKnots); | |
704 | Loi->Mults(Mults->ChangeArray1()); | |
705 | BS = new (Geom_BSplineCurve) (Poles->Array1(), | |
706 | Weigth->Array1(), | |
707 | Knots->Array1(), | |
708 | Mults->Array1(), | |
709 | Degree, | |
710 | Loi->IsUPeriodic()); | |
711 | Tol += PFirst.Distance(BS->Value( Knots->Value(1))); | |
712 | return Tol; | |
713 | } | |
714 | ||
715 | //======================================================================= | |
716 | //function : ConcatenedLaw | |
717 | //purpose : | |
718 | //======================================================================= | |
719 | ||
720 | Handle(GeomFill_SectionLaw) BRepFill_NSections::ConcatenedLaw() const | |
721 | { | |
722 | Handle(GeomFill_SectionLaw) Law; | |
723 | if (myLaws->Length() == 1) | |
724 | return myLaws->Value(1); | |
725 | else { | |
726 | Standard_Real Ufirst, Ulast, Vfirst, Vlast; | |
727 | mySurface->Bounds(Ufirst, Ulast, Vfirst, Vlast); | |
728 | TColGeom_SequenceOfCurve NCompo; | |
729 | NCompo.Clear(); | |
730 | for (Standard_Integer jj=1; jj<=myShapes.Length(); jj++) { | |
731 | NCompo.Append(mySurface->VIso(myParams(jj))); | |
732 | } | |
d7325741 | 733 | Law = new (GeomFill_NSections)(NCompo, myTrsfs, myParams, |
7fd59977 | 734 | Ufirst, Ulast, |
735 | Vfirst, Vlast, | |
736 | mySurface); | |
737 | } | |
738 | return Law; | |
739 | } | |
740 | ||
741 | //======================================================================= | |
742 | //function : Continuity | |
743 | //purpose : | |
744 | //======================================================================= | |
745 | GeomAbs_Shape BRepFill_NSections::Continuity(const Standard_Integer Index, | |
746 | const Standard_Real TolAngular) const | |
747 | { | |
748 | ||
749 | Standard_Integer jj; | |
750 | GeomAbs_Shape cont_jj; | |
7fd59977 | 751 | GeomAbs_Shape cont = GeomAbs_C0; |
7fd59977 | 752 | |
753 | for (jj=1; jj<=myShapes.Length(); jj++) { | |
754 | ||
755 | TopoDS_Edge Edge1, Edge2; | |
756 | if ( (Index==0) || (Index==myEdges->ColLength()) ) { | |
0d969553 | 757 | if (!uclosed) return GeomAbs_C0; //The least possible error |
7fd59977 | 758 | |
759 | Edge1 = TopoDS::Edge (myEdges->Value(myEdges->ColLength(),jj)); | |
760 | Edge2 = TopoDS::Edge (myEdges->Value(1,jj)); | |
761 | } | |
762 | else { | |
763 | Edge1 = TopoDS::Edge (myEdges->Value(Index,jj)); | |
764 | Edge2 = TopoDS::Edge (myEdges->Value(Index+1,jj)); | |
765 | } | |
766 | ||
767 | TopoDS_Vertex V1,V2; | |
768 | if ( Edge1.Orientation() == TopAbs_REVERSED) { | |
769 | V1 = TopExp::FirstVertex(Edge1); | |
770 | } | |
771 | else { | |
772 | V1 = TopExp::LastVertex(Edge1); | |
773 | } | |
774 | if ( Edge2.Orientation() == TopAbs_REVERSED) { | |
775 | V2 = TopExp::LastVertex(Edge2); | |
776 | } | |
777 | else { | |
778 | V2 = TopExp::FirstVertex(Edge2); | |
779 | } | |
780 | ||
781 | if (BRep_Tool::Degenerated(Edge1) || BRep_Tool::Degenerated(Edge2)) | |
782 | cont_jj = GeomAbs_CN; | |
783 | else | |
784 | { | |
785 | Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1); | |
786 | Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2); | |
787 | BRepAdaptor_Curve Curve1(Edge1); | |
788 | BRepAdaptor_Curve Curve2(Edge2); | |
789 | Standard_Real Eps = BRep_Tool::Tolerance(V2) + | |
790 | BRep_Tool::Tolerance(V1); | |
791 | cont_jj = BRepLProp::Continuity(Curve1,Curve2,U1,U2, Eps, TolAngular); | |
792 | } | |
793 | ||
794 | if (jj==1) cont = cont_jj; | |
795 | if (cont>cont_jj) cont = cont_jj; | |
796 | ||
797 | } | |
798 | ||
799 | return cont; | |
800 | } | |
801 | ||
802 | //======================================================================= | |
803 | //function : D0 | |
804 | //purpose : | |
805 | //======================================================================= | |
806 | void BRepFill_NSections::D0(const Standard_Real V, TopoDS_Shape& S) | |
807 | { | |
808 | TopoDS_Wire W; | |
809 | BRepLib_MakeWire MW; | |
810 | Standard_Integer ii, NbEdge = myLaws->Length(); | |
811 | for (ii=1; ii<=NbEdge ; ii++) { | |
812 | Handle(Geom_BSplineCurve) Curve | |
813 | = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(ii)->BSplineSurface()->VIso(V)); | |
814 | Standard_Real first = Curve ->FirstParameter(), | |
815 | last = Curve ->LastParameter(); | |
816 | TopoDS_Edge E = BRepLib_MakeEdge(Curve,first,last); | |
817 | MW.Add(E); | |
818 | } | |
819 | TopAbs_Orientation Orien = TopAbs_FORWARD; | |
820 | TopoDS_Shape aLocalShape = MW.Wire().Oriented(Orien); | |
821 | S = TopoDS::Wire(aLocalShape); | |
822 | // S = TopoDS::Wire(MW.Wire().Oriented(Orien)); | |
823 | ||
824 | } | |
825 |