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