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