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