0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / BRepFill / BRepFill_Filling.cxx
1 // Created on: 1998-08-26
2 // Created by: Julia GERASIMOVA
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 <Adaptor3d_CurveOnSurface.hxx>
19 #include <Adaptor3d_HCurveOnSurface.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_CurveRepresentation.hxx>
22 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
23 #include <BRep_TEdge.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRep_TVertex.hxx>
26 #include <BRepAdaptor_HCurve.hxx>
27 #include <BRepAdaptor_HCurve2d.hxx>
28 #include <BRepAdaptor_HSurface.hxx>
29 #include <BRepFill_CurveConstraint.hxx>
30 #include <BRepFill_EdgeFaceAndOrder.hxx>
31 #include <BRepFill_FaceAndOrder.hxx>
32 #include <BRepFill_Filling.hxx>
33 #include <BRepLib.hxx>
34 #include <BRepLib_MakeEdge.hxx>
35 #include <BRepLib_MakeEdge2d.hxx>
36 #include <BRepLib_MakeFace.hxx>
37 #include <BRepLib_MakeWire.hxx>
38 #include <BRepTools.hxx>
39 #include <BRepTools_WireExplorer.hxx>
40 #include <Geom2d_BezierCurve.hxx>
41 #include <Geom2d_TrimmedCurve.hxx>
42 #include <Geom2dAdaptor_HCurve.hxx>
43 #include <Geom_BSplineSurface.hxx>
44 #include <GeomAdaptor_HSurface.hxx>
45 #include <GeomAPI_ProjectPointOnSurf.hxx>
46 #include <GeomPlate_CurveConstraint.hxx>
47 #include <GeomPlate_MakeApprox.hxx>
48 #include <GeomPlate_PlateG0Criterion.hxx>
49 #include <GeomPlate_PointConstraint.hxx>
50 #include <GeomProjLib.hxx>
51 #include <gp_Pnt.hxx>
52 #include <Precision.hxx>
53 #include <Standard_ConstructionError.hxx>
54 #include <Standard_OutOfRange.hxx>
55 #include <StdFail_NotDone.hxx>
56 #include <TColGeom2d_HArray1OfCurve.hxx>
57 #include <TColgp_Array1OfPnt2d.hxx>
58 #include <TColgp_SequenceOfPnt.hxx>
59 #include <TColgp_SequenceOfXY.hxx>
60 #include <TColStd_HArray1OfReal.hxx>
61 #include <TopExp.hxx>
62 #include <TopoDS.hxx>
63 #include <TopoDS_Edge.hxx>
64 #include <TopoDS_Face.hxx>
65 #include <TopoDS_Shape.hxx>
66 #include <TopoDS_Vertex.hxx>
67 #include <TopoDS_Wire.hxx>
68 #include <TopTools_ListIteratorOfListOfShape.hxx>
69 #include <Geom_Surface.hxx>
70
71 static gp_Vec MakeFinVec( const TopoDS_Wire aWire, const TopoDS_Vertex aVertex )
72 {
73   TopoDS_Vertex Vfirst, Vlast, Origin;
74   BRepTools_WireExplorer Explo( aWire );
75   for (; Explo.More(); Explo.Next())
76     {
77       TopExp::Vertices( Explo.Current(), Vfirst, Vlast );
78       if (Vfirst.IsSame( aVertex ))
79         {
80           Origin = Vlast;
81           break;
82         }
83       if (Vlast.IsSame( aVertex ))
84         {
85           Origin = Vfirst;
86           break;
87         }
88     }
89   return gp_Vec( BRep_Tool::Pnt( Origin ), BRep_Tool::Pnt( aVertex ) );
90 }
91
92 static TopoDS_Wire WireFromList(TopTools_ListOfShape& Edges)
93 {
94   BRepLib_MakeWire MW;
95   TopoDS_Edge anEdge = TopoDS::Edge(Edges.First());
96   MW.Add(anEdge);
97   Edges.RemoveFirst();
98
99   while (!Edges.IsEmpty())
100   {
101     TopoDS_Wire CurWire = MW.Wire();
102     TopoDS_Vertex V1, V2;
103     TopExp::Vertices(CurWire, V1, V2);
104     TopTools_ListIteratorOfListOfShape itl(Edges);
105     for (; itl.More(); itl.Next())
106     {
107       anEdge = TopoDS::Edge(itl.Value());
108       TopoDS_Vertex V3, V4;
109       TopExp::Vertices(anEdge, V3, V4);
110       if (V1.IsSame(V3) || V1.IsSame(V4) ||
111           V2.IsSame(V3) || V2.IsSame(V4))
112         break;
113     }
114     MW.Add(anEdge);
115     Edges.Remove(itl);
116   }
117
118   return (MW.Wire());
119 }
120
121 //=======================================================================
122 //function : Constructor
123 //purpose  : 
124 //======================================================================
125 BRepFill_Filling::BRepFill_Filling( const Standard_Integer Degree,
126                                     const Standard_Integer NbPtsOnCur,
127                                     const Standard_Integer NbIter,
128                                     const Standard_Boolean Anisotropie,
129                                     const Standard_Real Tol2d,
130                                     const Standard_Real Tol3d,
131                                     const Standard_Real TolAng,
132                                     const Standard_Real TolCurv,
133                                     const Standard_Integer MaxDeg,
134                                     const Standard_Integer MaxSegments )
135 {
136   myDegree = Degree;
137   myNbPtsOnCur = NbPtsOnCur;
138   myNbIter = NbIter;
139   myAnisotropie = Anisotropie;
140
141   myTol2d = Tol2d;
142   myTol3d = Tol3d;
143   myTolAng = TolAng;
144   myTolCurv = TolCurv;
145
146   myMaxDeg = MaxDeg;
147   myMaxSegments = MaxSegments;
148
149   myIsInitFaceGiven = Standard_False;
150
151   myIsDone = Standard_False;
152 }
153
154 //=======================================================================
155 //function : SetConstrParam
156 //purpose  : 
157 //======================================================================
158 void BRepFill_Filling::SetConstrParam( const Standard_Real Tol2d,
159                                        const Standard_Real Tol3d,
160                                        const Standard_Real TolAng,
161                                        const Standard_Real TolCurv )
162 {
163   myTol2d = Tol2d;
164   myTol3d = Tol3d;
165   myTolAng = TolAng;
166   myTolCurv = TolCurv;
167 }
168
169 //=======================================================================
170 //function : SetResolParam
171 //purpose  : 
172 //======================================================================
173 void BRepFill_Filling::SetResolParam( const Standard_Integer Degree,
174                                       const Standard_Integer NbPtsOnCur,
175                                       const Standard_Integer NbIter,
176                                       const Standard_Boolean Anisotropie )
177 {
178   myDegree = Degree;
179   myNbPtsOnCur = NbPtsOnCur;
180   myNbIter = NbIter;
181   myAnisotropie = Anisotropie;
182 }
183
184 //=======================================================================
185 //function : SetApproxParam
186 //purpose  : 
187 //======================================================================
188 void BRepFill_Filling::SetApproxParam( const Standard_Integer MaxDeg,
189                                        const Standard_Integer MaxSegments )
190 {
191   myMaxDeg      = MaxDeg;
192   myMaxSegments = MaxSegments;
193 }
194
195 //=======================================================================
196 //function : LoadInitSurface
197 //purpose  : 
198 //======================================================================
199 void BRepFill_Filling::LoadInitSurface( const TopoDS_Face& aFace )
200 {
201   myInitFace = aFace;
202   myIsInitFaceGiven = Standard_True;
203 }
204
205 //=======================================================================
206 //function : Add
207 //purpose  : adds an edge as a constraint
208 //======================================================================
209 Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
210                                         const GeomAbs_Shape Order,
211                                         const Standard_Boolean IsBound )
212 {
213   TopoDS_Face NullFace;
214   BRepFill_EdgeFaceAndOrder EdgeFaceAndOrder( anEdge, NullFace, Order );
215   if (IsBound)
216     {
217       myBoundary.Append( EdgeFaceAndOrder );
218       TopTools_ListOfShape EmptyList;
219       myOldNewMap.Bind(anEdge, EmptyList);
220       return myBoundary.Length();
221     }
222   else
223     {
224       myConstraints.Append( EdgeFaceAndOrder );
225       return (myBoundary.Length() + myFreeConstraints.Length() + myConstraints.Length());
226     }
227 }
228
229 //=======================================================================
230 //function : Add
231 //purpose  : adds an edge with supporting face as a constraint
232 //======================================================================
233 Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
234                                         const TopoDS_Face& Support,
235                                         const GeomAbs_Shape Order,
236                                         const Standard_Boolean IsBound )
237 {
238   BRepFill_EdgeFaceAndOrder EdgeFaceAndOrder( anEdge, Support, Order );
239   if (IsBound)
240     {
241       myBoundary.Append( EdgeFaceAndOrder );
242       TopTools_ListOfShape EmptyList;
243       myOldNewMap.Bind(anEdge, EmptyList);
244       return myBoundary.Length();
245     }
246   else
247     {
248       myConstraints.Append( EdgeFaceAndOrder );
249       return (myBoundary.Length() + myFreeConstraints.Length() + myConstraints.Length());
250     }
251 }
252
253 //=======================================================================
254 //function : Add
255 //purpose  : adds a "free constraint": face without edge
256 //======================================================================
257 Standard_Integer BRepFill_Filling::Add( const TopoDS_Face& Support,
258                                         const GeomAbs_Shape Order )
259 {
260   BRepFill_FaceAndOrder FaceAndOrder( Support, Order );
261   myFreeConstraints.Append( FaceAndOrder );
262   return (myBoundary.Length() + myFreeConstraints.Length());
263 }
264
265 //=======================================================================
266 //function : Add
267 //purpose  : adds a point constraint
268 //======================================================================
269 Standard_Integer BRepFill_Filling::Add( const gp_Pnt& Point )
270 {
271   Handle( GeomPlate_PointConstraint ) aPC = new GeomPlate_PointConstraint( Point, GeomAbs_C0, myTol3d );
272   myPoints.Append( aPC );
273   return (myBoundary.Length() + myFreeConstraints.Length() + myConstraints.Length() + myPoints.Length());
274 }
275
276 //=======================================================================
277 //function : Add
278 //purpose  : adds a point constraint on a face
279 //======================================================================
280 Standard_Integer BRepFill_Filling::Add( const Standard_Real U,
281                                         const Standard_Real V,
282                                         const TopoDS_Face& Support,
283                                         const GeomAbs_Shape Order )
284 {
285   Handle( BRepAdaptor_HSurface ) HSurf = new BRepAdaptor_HSurface();
286   HSurf->ChangeSurface().Initialize( Support );
287   Handle( GeomPlate_PointConstraint ) aPC = 
288     new GeomPlate_PointConstraint( U, V, BRep_Tool::Surface( HSurf->ChangeSurface().Face() ), Order,
289                                    myTol3d, myTolAng, myTolCurv );
290   myPoints.Append( aPC );
291   return (myBoundary.Length() + myFreeConstraints.Length() + myConstraints.Length() + myPoints.Length());
292 }
293
294
295 //=======================================================================
296 //function : AddConstraints
297 //purpose  : 
298 //======================================================================
299 void BRepFill_Filling::AddConstraints( const BRepFill_SequenceOfEdgeFaceAndOrder& SeqOfConstraints )
300 {
301   TopoDS_Edge CurEdge;
302   TopoDS_Face CurFace;
303   GeomAbs_Shape CurOrder;
304
305   Handle(GeomPlate_CurveConstraint) Constr;
306   Standard_Integer i;
307   for (i = 1; i <= SeqOfConstraints.Length(); i++)
308     {
309       CurEdge = SeqOfConstraints(i).myEdge;
310       CurFace = SeqOfConstraints(i).myFace;
311       CurOrder = SeqOfConstraints(i).myOrder;
312       
313       if (CurFace.IsNull()) {
314         if (CurOrder == GeomAbs_C0) {
315           Handle( BRepAdaptor_HCurve ) HCurve = new BRepAdaptor_HCurve();
316           HCurve->ChangeCurve().Initialize( CurEdge );
317           const Handle(Adaptor3d_HCurve)& aHCurve = HCurve; // to avoid ambiguity
318           Constr = new BRepFill_CurveConstraint(aHCurve,
319                                                 CurOrder,
320                                                 myNbPtsOnCur,
321                                                 myTol3d );
322         }
323         else { // Pas de representation Topologique
324           // On prend une representation Geometrique : au pif !
325           Handle( Geom_Surface ) Surface;
326           Handle( Geom2d_Curve ) C2d;
327           TopLoc_Location loc;
328           Standard_Real f, l;
329           BRep_Tool::CurveOnSurface( CurEdge, C2d, Surface, loc, f, l);
330           if (Surface.IsNull()) {
331             Standard_Failure::Raise( "Add" );
332             return;
333           }
334           Surface = Handle(Geom_Surface)::DownCast(Surface->Copy());
335           Surface->Transform(loc.Transformation());
336           Handle( GeomAdaptor_HSurface ) Surf = new GeomAdaptor_HSurface(Surface);
337           Handle( Geom2dAdaptor_HCurve ) Curve2d = new Geom2dAdaptor_HCurve(C2d);
338           
339           Adaptor3d_CurveOnSurface CurvOnSurf( Curve2d, Surf );
340           Handle (Adaptor3d_HCurveOnSurface) HCurvOnSurf = new Adaptor3d_HCurveOnSurface( CurvOnSurf );
341           
342           Constr = new GeomPlate_CurveConstraint(HCurvOnSurf,
343                                                  CurOrder,
344                                                  myNbPtsOnCur,
345                                                  myTol3d,
346                                                  myTolAng,
347                                                  myTolCurv );
348         }
349       }
350       else
351         {
352           Handle( BRepAdaptor_HSurface ) Surf = new BRepAdaptor_HSurface();
353           Surf->ChangeSurface().Initialize( CurFace );
354           Handle( BRepAdaptor_HCurve2d ) Curve2d = new BRepAdaptor_HCurve2d();
355           Curve2d->ChangeCurve2d().Initialize( CurEdge, CurFace );
356           // If CurEdge has no 2d representation on CurFace,
357           // there will be exception "Attempt to access to null object"
358           // in this initialization (null pcurve).
359           Adaptor3d_CurveOnSurface CurvOnSurf( Curve2d, Surf );
360           Handle (Adaptor3d_HCurveOnSurface) HCurvOnSurf = new Adaptor3d_HCurveOnSurface( CurvOnSurf );
361
362           Constr = new BRepFill_CurveConstraint( HCurvOnSurf,
363                                                  CurOrder,
364                                                  myNbPtsOnCur,
365                                                  myTol3d,
366                                                  myTolAng,
367                                                  myTolCurv );
368         }
369       if (myIsInitFaceGiven)
370         {
371           Handle( Geom2d_Curve ) Curve2d;
372           Standard_Real FirstPar, LastPar;
373           Curve2d = BRep_Tool::CurveOnSurface( CurEdge, myInitFace, FirstPar, LastPar );
374           if (! Curve2d.IsNull()) 
375             {
376               Curve2d = new Geom2d_TrimmedCurve( Curve2d, FirstPar, LastPar );
377               Constr->SetCurve2dOnSurf( Curve2d );
378             }
379         }
380       myBuilder.Add( Constr );
381     }
382 }
383
384 //=======================================================================
385 //function : BuildWires
386 //purpose  : 
387 //======================================================================
388 void BRepFill_Filling::BuildWires( TopTools_ListOfShape& EdgeList, TopTools_ListOfShape& WireList )
389 {
390   TopTools_ListIteratorOfListOfShape Itl;
391   Standard_Integer i, j;
392
393   while (! EdgeList.IsEmpty())
394     {
395       BRepLib_MakeWire MW;
396       TopoDS_Edge FirstEdge = TopoDS::Edge(EdgeList.First());
397       MW.Add(FirstEdge);
398       EdgeList.RemoveFirst();
399       TopoDS_Vertex V_wire[2], V_edge[2];
400
401       for (;;)
402       {
403         TopoDS_Wire CurWire = MW.Wire();
404         TopExp::Vertices(CurWire, V_wire[0], V_wire[1]);
405         Standard_Boolean found = Standard_False;
406         for (Itl.Initialize( EdgeList ); Itl.More(); Itl.Next())
407         {
408           TopoDS_Edge CurEdge = TopoDS::Edge(Itl.Value());
409           TopExp::Vertices(CurEdge, V_edge[0], V_edge[1]);
410           for (i = 0; i < 2; i++)
411           {
412             for (j = 0; j < 2; j++)
413               if (V_wire[i].IsSame(V_edge[j]))
414               {
415                 MW.Add(CurEdge);
416                 EdgeList.Remove(Itl);
417                 found = Standard_True;
418                 break;
419               }
420             if (found)
421               break;
422           }
423           if (found)
424             break;
425         }
426         if (!found) //try to find geometric coincidence
427         {
428           gp_Pnt P_wire[2];
429           P_wire[0] = BRep_Tool::Pnt(V_wire[0]);
430           P_wire[1] = BRep_Tool::Pnt(V_wire[1]);
431           for (Itl.Initialize( EdgeList ); Itl.More(); Itl.Next())
432           {
433             TopoDS_Edge CurEdge = TopoDS::Edge(Itl.Value());
434             TopExp::Vertices(CurEdge, V_edge[0], V_edge[1]);
435             for (i = 0; i < 2; i++)
436             {
437               for (j = 0; j < 2; j++)
438               {
439                 Standard_Real aDist = P_wire[i].Distance(BRep_Tool::Pnt(V_edge[j]));
440                 if (aDist < BRep_Tool::Tolerance(V_wire[i]) &&
441                     aDist < BRep_Tool::Tolerance(V_edge[j]))
442                 {
443                   MW.Add(CurEdge);
444                   myOldNewMap(CurEdge).Append(MW.Edge());
445                   EdgeList.Remove(Itl);
446                   found = Standard_True;
447                   break;
448                 }
449               }
450               if (found)
451                 break;
452             }
453             if (found)
454               break;
455           }
456         }
457         if (!found) //end of current wire, begin next wire
458         {
459           WireList.Append( MW.Wire() );
460           break;
461         }
462       } //end of for (;;)
463     } //end of while (! EdgeList.IsEmpty())  
464 }
465
466 //=======================================================================
467 //function : FindExtremitiesOfHoles
468 //purpose  : 
469 //======================================================================
470 void BRepFill_Filling::FindExtremitiesOfHoles(const TopTools_ListOfShape& WireList,
471                                               TopTools_SequenceOfShape& VerSeq ) const
472 {
473   TopTools_SequenceOfShape WireSeq;
474   TopTools_ListIteratorOfListOfShape Itl(WireList);
475   for (; Itl.More(); Itl.Next())
476     WireSeq.Append(Itl.Value());
477        
478   TopoDS_Wire theWire;
479   theWire = TopoDS::Wire(WireSeq(1));
480   WireSeq.Remove(1);
481
482   if (theWire.Closed())
483     return;
484
485   TopoDS_Vertex Vfirst, Vlast;
486   TopExp::Vertices( theWire, Vfirst, Vlast );
487   gp_Vec FinVec = MakeFinVec( theWire, Vlast );
488   TopoDS_Vertex theVertex = Vlast;
489   VerSeq.Append( Vlast );
490
491   while (! WireSeq.IsEmpty())
492     {
493       TopoDS_Vertex MinVtx;
494       Standard_Integer i, MinInd = 1;
495       Standard_Boolean IsLast = Standard_False;
496       Standard_Real MinAngle = M_PI;
497       
498       for (i = 1; i <= WireSeq.Length(); i++)
499         {
500           const TopoDS_Wire& CurWire = TopoDS::Wire( WireSeq(i) );
501           TopExp::Vertices( CurWire, Vfirst, Vlast );
502           
503           Standard_Real angle =
504             FinVec.Angle(gp_Vec(BRep_Tool::Pnt(theVertex), BRep_Tool::Pnt(Vfirst)));
505           if (angle < MinAngle)
506             {
507               MinAngle = angle;
508               MinVtx = Vfirst;
509               MinInd = i;
510               IsLast = Standard_True;
511             }
512           angle = FinVec.Angle(gp_Vec(BRep_Tool::Pnt(theVertex), BRep_Tool::Pnt(Vlast)));
513           if (angle < MinAngle)
514             {
515               MinAngle = angle;
516               MinVtx = Vlast;
517               MinInd = i;
518               IsLast = Standard_False;
519             }
520         }
521       VerSeq.Append( MinVtx );
522       const TopoDS_Wire& MinWire = TopoDS::Wire(WireSeq(MinInd));
523       TopExp::Vertices( MinWire, Vfirst, Vlast );
524       if (IsLast)
525         {
526           FinVec = MakeFinVec( MinWire, Vlast );
527           theVertex = Vlast;
528         }
529       else
530         {
531           FinVec = MakeFinVec( MinWire, Vfirst );
532           theVertex = Vfirst;
533         }
534       VerSeq.Append( theVertex );
535       WireSeq.Remove(MinInd);
536     }
537   TopExp::Vertices( theWire, Vfirst, Vlast );
538   VerSeq.Append( Vfirst );
539 }
540
541 //=======================================================================
542 //function : Build
543 //purpose  : builds the resulting face
544 //======================================================================
545 void BRepFill_Filling::Build()
546 {
547   GeomPlate_BuildPlateSurface thebuild( myDegree, myNbPtsOnCur, myNbIter,
548                                         myTol2d, myTol3d, myTolAng, myTolCurv, myAnisotropie );
549
550   myBuilder = thebuild;
551   TopoDS_Edge CurEdge;
552   TopoDS_Face CurFace;
553   Standard_Integer i, j;
554
555   //Creating array of vertices: extremities of wires
556   TopTools_SequenceOfShape VerSeq;
557
558   //Building missing bounds
559   TopTools_ListOfShape EdgeList, WireList;
560   for (i = 1; i <= myBoundary.Length(); i++)
561     EdgeList.Append( myBoundary(i).myEdge );
562
563   BuildWires( EdgeList, WireList );
564   FindExtremitiesOfHoles( WireList, VerSeq );
565   
566   //Searching for surfaces for missing bounds
567   for (j = 1; j <= myFreeConstraints.Length(); j++)
568     {
569       GeomAPI_ProjectPointOnSurf Projector;
570       Quantity_Parameter U1, V1, U2, V2;
571
572       CurFace = myFreeConstraints(j).myFace;
573       Handle( BRepAdaptor_HSurface ) HSurf = new BRepAdaptor_HSurface();
574       HSurf->ChangeSurface().Initialize( CurFace );
575       Handle( Geom_Surface ) CurSurface = BRep_Tool::Surface( HSurf->ChangeSurface().Face() );
576       //BRepTopAdaptor_FClass2d Classifier( CurFace, Precision::Confusion() );
577           
578       for (i = 1; i <= VerSeq.Length(); i += 2)
579         {
580           const TopoDS_Vertex& FirstVtx = TopoDS::Vertex(VerSeq(i));
581           const TopoDS_Vertex& LastVtx  = TopoDS::Vertex(VerSeq(i+1));
582           
583           gp_Pnt FirstPnt = BRep_Tool::Pnt(FirstVtx);
584           Projector.Init( FirstPnt, CurSurface );
585           if (Projector.LowerDistance() > Precision::Confusion())
586             continue;
587           Projector.LowerDistanceParameters( U1, V1 );
588           
589           /*
590           State = Classifier.Perform(gp_Pnt2d( U1, V1 ),
591                                      ((HSurf->IsUPeriodic() || HSurf->IsVPeriodic())? Standard_True : Standard_False));
592           if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
593             continue;
594           */
595
596           gp_Pnt LastPnt = BRep_Tool::Pnt(LastVtx);
597           Projector.Init( LastPnt, CurSurface );
598           if (Projector.LowerDistance() > Precision::Confusion())
599             continue;
600           Projector.LowerDistanceParameters( U2, V2 );
601           
602           /*
603           State = Classifier.Perform(gp_Pnt2d( U2, V2 ),
604                                      ((HSurf->IsUPeriodic() || HSurf->IsVPeriodic())? Standard_True : Standard_False));
605           if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
606             continue;
607           */
608           
609           //Making the constraint
610           TColgp_Array1OfPnt2d Points( 1, 2 );
611           Points(1) = gp_Pnt2d( U1, V1 );
612           Points(2) = gp_Pnt2d( U2, V2 );
613           Handle( Geom2d_BezierCurve ) Line2d = new Geom2d_BezierCurve( Points );
614           TopoDS_Edge E = BRepLib_MakeEdge( Line2d, CurSurface, FirstVtx, LastVtx );
615           Add( E, CurFace, myFreeConstraints(j).myOrder );
616           VerSeq.Remove( i, i+1 );
617           break;
618         } //for (i = 1; i <= VerSeq.Length(); i += 2)
619     } //for (j = 1; j <= myFreeConstraints.Length(); j++)
620   
621   //Load initial surface to myBuilder if it is given
622   if (myIsInitFaceGiven)
623     {
624       Handle( BRepAdaptor_HSurface ) HSurfInit = new BRepAdaptor_HSurface();
625       HSurfInit->ChangeSurface().Initialize( myInitFace );
626       myBuilder.LoadInitSurface( BRep_Tool::Surface( HSurfInit->ChangeSurface().Face() ) );
627     }
628
629   //Adding constraints to myBuilder
630   AddConstraints( myBoundary );
631   myBuilder.SetNbBounds( myBoundary.Length() );
632   AddConstraints( myConstraints );
633   for (i = 1; i <= myPoints.Length(); i++)
634     myBuilder.Add( myPoints(i) );
635
636   myBuilder.Perform();
637   if (myBuilder.IsDone())
638     myIsDone = Standard_True;
639   else
640     {
641       myIsDone = Standard_False;
642       return;
643     }
644
645   Handle( GeomPlate_Surface ) GPlate = myBuilder.Surface();
646   Handle( Geom_BSplineSurface ) Surface;
647   // Approximation
648   Standard_Real dmax = 1.1 * myBuilder.G0Error(); //???????????
649   //Standard_Real dmax = myTol3d;
650   if (! myIsInitFaceGiven)
651     {
652      Standard_Real seuil; //?????
653
654      TColgp_SequenceOfXY S2d;
655      TColgp_SequenceOfXYZ S3d;
656      myBuilder.Disc2dContour(4,S2d);
657      myBuilder.Disc3dContour(4,0,S3d);
658      seuil = Max( myTol3d, 10*myBuilder.G0Error() ); //????????
659      GeomPlate_PlateG0Criterion Criterion( S2d, S3d, seuil );
660      GeomPlate_MakeApprox Approx( GPlate, Criterion, myTol3d, myMaxSegments, myMaxDeg );
661      Surface = Approx.Surface();
662    }
663   else
664     {
665       GeomPlate_MakeApprox Approx( GPlate, myTol3d, myMaxSegments, myMaxDeg, dmax, 0 ); //?????????????
666       //GeomConvert_ApproxSurface Approx( GPlate, myTol3d, GeomAbs_C1, GeomAbs_C1, myMaxDeg, myMaxDeg, myMaxSegments, 1 );
667       //Approx.Dump( cout );
668       Surface = Approx.Surface();
669     }
670
671   //Build the final wire and final face
672   TopTools_ListOfShape FinalEdges;
673   Handle(TColGeom2d_HArray1OfCurve) CurvesOnPlate = myBuilder.Curves2d();
674   BRep_Builder BB;
675   for (i = 1; i <= myBoundary.Length(); i++)
676   {
677     const TopoDS_Edge& InitEdge = myBoundary(i).myEdge;
678     TopoDS_Edge anEdge = InitEdge;
679     if (!myOldNewMap(anEdge).IsEmpty())
680       anEdge = TopoDS::Edge( myOldNewMap(anEdge).First() );
681     Handle(Geom2d_Curve) aCurveOnPlate = CurvesOnPlate->Value(i);
682
683     TopoDS_Edge NewEdge = TopoDS::Edge(anEdge.EmptyCopied());
684
685     TopoDS_Vertex V1, V2;
686     TopExp::Vertices(anEdge, V1, V2, Standard_True); //with orientation
687     BB.UpdateVertex(V1, dmax);
688     BB.UpdateVertex(V2, dmax);
689     BB.Add(NewEdge, V1);
690     BB.Add(NewEdge, V2);
691     TopLoc_Location Loc;
692     BB.UpdateEdge(NewEdge, aCurveOnPlate, Surface, Loc, dmax);
693     //BRepLib::SameRange(NewEdge);
694     BRepLib::SameParameter(NewEdge, dmax, Standard_True);
695     FinalEdges.Append(NewEdge);
696     myOldNewMap(InitEdge).Clear();
697     myOldNewMap(InitEdge).Append(NewEdge);
698   }
699   
700   TopoDS_Wire FinalWire = WireFromList(FinalEdges);
701   if (!(FinalWire.Closed()))
702     Standard_Failure::Raise("Wire is not closed");
703   
704   myFace = BRepLib_MakeFace( Surface, FinalWire );
705 }
706
707 //=======================================================================
708 //function : IsDone
709 //purpose  : 
710 //======================================================================
711 Standard_Boolean BRepFill_Filling::IsDone() const
712 {
713   return myIsDone;
714 }
715
716 //=======================================================================
717 //function : Face
718 //purpose  : returns the result
719 //======================================================================
720 TopoDS_Face BRepFill_Filling::Face() const
721 {
722   return myFace;
723 }
724
725 //=======================================================================
726 //function : Generated
727 //purpose  : returns the new edge (first in list) made from old edge "S"
728 //=======================================================================
729  const TopTools_ListOfShape& BRepFill_Filling::Generated(const TopoDS_Shape& S) 
730 {
731   myGenerated.Clear();
732   
733   if (myOldNewMap.IsBound(S))
734     myGenerated.Append(myOldNewMap(S));
735   
736   return myGenerated;
737 }
738
739 //==========================================================================
740 //function : G0Error
741 //purpose  : returns maximum distance from boundary to the resulting surface
742 //==========================================================================
743 Standard_Real BRepFill_Filling::G0Error() const
744 {
745   return myBuilder.G0Error();
746 }
747
748 //=======================================================================
749 //function : G1Error
750 //purpose  : returns maximum angle between the resulting surface
751 //           and constraint surfaces at boundaries
752 //======================================================================
753 Standard_Real BRepFill_Filling::G1Error() const
754 {
755   return myBuilder.G1Error();
756 }
757
758 //=======================================================================
759 //function : G2Error
760 //purpose  : returns maximum difference of curvature between
761 //           the resulting surface and constraint surfaces at boundaries
762 //======================================================================
763 Standard_Real BRepFill_Filling::G2Error() const
764 {
765   return myBuilder.G2Error();
766 }
767
768 //==========================================================================
769 //function : G0Error
770 //purpose  : returns maximum distance between the constraint number Index
771 //           and the resulting surface
772 //==========================================================================
773 Standard_Real BRepFill_Filling::G0Error( const Standard_Integer Index )
774 {
775   return myBuilder.G0Error( Index );
776 }
777
778 //==========================================================================
779 //function : G1Error
780 //purpose  : returns maximum angle between the constraint number Index
781 //           and the resulting surface
782 //==========================================================================
783 Standard_Real BRepFill_Filling::G1Error( const Standard_Integer Index )
784 {
785   return myBuilder.G1Error( Index );
786 }
787
788 //==========================================================================
789 //function : G2Error
790 //purpose  : returns maximum difference of curvature between
791 //           the constraint number Index and the resulting surface
792 //==========================================================================
793 Standard_Real BRepFill_Filling::G2Error( const Standard_Integer Index )
794 {
795   return myBuilder.G2Error( Index );
796 }