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