849e588f4a39ddfacf5e314a1efa0883fcfa6270
[occt.git] / src / BRepFill / BRepFill_NSections.cxx
1 // Created on: 1998-12-29
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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
63 static 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
76 static 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
123     // case of looping sections
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)) {
132         // degenerated edge : construction of a point curve
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 {
143         // return the curve on the edge
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
152       // transformation into BSpline reparameterized on [i-1,i]
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       
170       // initialization
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)) {
177           // degenerated edge : construction of a point curve
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 {
188           // return the curve on the edge
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
197         // transformation into BSpline reparameterized on [i-1,i]
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
227       // return the final section
228       BS = CompBS.BSplineCurve();
229       section.AddCurve(BS);
230
231       // case of looping sections
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
355 BRepFill_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
376 BRepFill_NSections::BRepFill_NSections(const TopTools_SequenceOfShape& S,
377                                        const GeomFill_SequenceOfTrsf& Transformations,
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;
404     myTrsfs = Transformations;
405     VFirst = VF;
406     VLast = VL;
407     Init(P,Build);
408   }
409 }
410
411 //=======================================================================
412 //function : Init
413 //purpose  : Create a table of GeomFill_SectionLaw
414 //=======================================================================
415 void 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
429   // Check if the start and end wires are punctual
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
441   // Check if the start and end wires are identical
442   vclosed = myShapes(1).IsSame(myShapes(NbSects));
443
444   // Count the number of non-degenerated edges
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
450   myEdges = new (TopTools_HArray2OfShape) (1, NbEdge, 1, NbSects);
451   
452   // Fill tables
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
467   // Is the law closed by U ?
468
469     wClosed = W.Closed();
470     if (!wClosed) {
471       // if unsure about the flag, make check
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
506   // point sections at end
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    
532   // Increase the degree so that the position D2 
533   // on GeomFill_NSections could be correct
534   // see comments in GeomFill_NSections
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
546   // Fill tables
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;
577             CBis = C->Reversed(); // To avoid the spoiling of the topology
578             aux = C->ReversedParameter(First);
579             First = C->ReversedParameter(Last);
580             Last = aux;
581             C =  CBis;
582           } 
583           if ((ii>1) || (!E.Closed()) ) { // Cut C
584             Handle(Geom_TrimmedCurve) TC = 
585               new (Geom_TrimmedCurve) (C,First, Last);
586             C  = TC;
587           } 
588           //  otherwise preserve the integrity of the curve
589         }
590         NC.Append(C);
591       }
592  
593       Standard_Real Ufirst = ii-1;
594       Standard_Real Ulast = ii;
595       myLaws->ChangeValue(ii) = new (GeomFill_NSections)(NC, myTrsfs, myParams,
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
660 //purpose  : Evaluate the hole between 2 edges of the section
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()) ) {
668     if (!uclosed) return Tol; //The least possible error
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     }
739     Law = new (GeomFill_NSections)(NCompo, myTrsfs, myParams, 
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;
757  GeomAbs_Shape cont = GeomAbs_C0; 
758
759  for (jj=1; jj<=myShapes.Length(); jj++) {
760
761    TopoDS_Edge Edge1, Edge2;
762    if ( (Index==0) || (Index==myEdges->ColLength()) ) {
763      if (!uclosed) return GeomAbs_C0; //The least possible error
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