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