0030694: Data Exchange - support non-standard GB2312-encoded STEP files
[occt.git] / src / BRepFill / BRepFill_Generator.cxx
1 // Created on: 1994-03-07
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-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 <BRepFill_Generator.hxx>
21 #include <BRepLib.hxx>
22 #include <BRepTools.hxx>
23 #include <BRepTools_WireExplorer.hxx>
24 #include <Geom2d_BezierCurve.hxx>
25 #include <Geom2d_Line.hxx>
26 #include <Geom_BezierCurve.hxx>
27 #include <Geom_BSplineCurve.hxx>
28 #include <Geom_Circle.hxx>
29 #include <Geom_ConicalSurface.hxx>
30 #include <Geom_Curve.hxx>
31 #include <Geom_CylindricalSurface.hxx>
32 #include <Geom_Line.hxx>
33 #include <Geom_Plane.hxx>
34 #include <Geom_RectangularTrimmedSurface.hxx>
35 #include <Geom_Surface.hxx>
36 #include <Geom_TrimmedCurve.hxx>
37 #include <GeomAbs_Shape.hxx>
38 #include <GeomAdaptor_Curve.hxx>
39 #include <GeomConvert.hxx>
40 #include <GeomFill.hxx>
41 #include <GeomFill_Generator.hxx>
42 #include <gp_Ax1.hxx>
43 #include <gp_Ax3.hxx>
44 #include <gp_Circ.hxx>
45 #include <gp_Dir2d.hxx>
46 #include <gp_Lin.hxx>
47 #include <gp_Pnt2d.hxx>
48 #include <gp_Vec.hxx>
49 #include <Precision.hxx>
50 #include <Standard_NullObject.hxx>
51 #include <TColgp_Array1OfPnt.hxx>
52 #include <TColgp_Array1OfPnt2d.hxx>
53 #include <TopExp.hxx>
54 #include <TopExp_Explorer.hxx>
55 #include <TopLoc_Location.hxx>
56 #include <TopoDS.hxx>
57 #include <TopoDS_Edge.hxx>
58 #include <TopoDS_Face.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopoDS_Shell.hxx>
61 #include <TopoDS_Vertex.hxx>
62 #include <TopoDS_Wire.hxx>
63 #include <TopTools_DataMapOfShapeShape.hxx>
64
65 //=======================================================================
66 //function : DetectKPart
67 //purpose  : 
68 //=======================================================================
69 Standard_Integer DetectKPart(const TopoDS_Edge& Edge1,
70                              const TopoDS_Edge& Edge2)
71 {
72   // initializations
73   Standard_Integer IType = 0;
74
75   // characteristics of the first edge
76   Standard_Real first1 = 0., last1 = 0., first2, last2, ff, ll;
77   TopLoc_Location loc;
78   TopoDS_Vertex V1, V2;
79   Handle(Geom_Curve) curv1, curv;
80   GeomAdaptor_Curve AdC1;
81   Standard_Boolean degen1 = BRep_Tool::Degenerated(Edge1);
82
83   // find the particular case
84   gp_Pnt pos1, pos;
85   Standard_Real  dist;
86   Standard_Real dist1 =0.;
87   gp_Ax1 axe1, axe;
88
89   if (degen1) {
90     IType = -2;
91     TopExp::Vertices(Edge1,V1,V2);
92     pos1 = BRep_Tool::Pnt(V1);
93   }
94   else {
95     curv1 = BRep_Tool::Curve(Edge1, loc, first1, last1);
96     if (curv1.IsNull())
97       throw Standard_NullObject("Null 3D curve in edge");
98     curv1 = 
99       Handle(Geom_Curve)::DownCast(curv1->Transformed(loc.Transformation()));
100     ff = first1;
101     ll = last1;
102     if (Edge1.Orientation() == TopAbs_REVERSED) {
103       curv1->Reverse();
104       first1 = curv1->ReversedParameter(ll);
105       last1 = curv1->ReversedParameter(ff);
106     }
107     AdC1.Load(curv1);
108     if (AdC1.GetType() == GeomAbs_Circle) {
109       // first circular section 
110       IType = 1;
111       pos1 = AdC1.Circle().Location();
112       dist1 = AdC1.Circle().Radius();
113       axe1 = AdC1.Circle().Axis();
114     }
115     else if (AdC1.GetType() == GeomAbs_Line) {
116       // first straight line section 
117       IType = 4;
118       pos1 = AdC1.Line().Location();
119       dist1 = AdC1.Value(first1).Distance(AdC1.Value(last1));
120       gp_Vec vec(AdC1.Value(first1),AdC1.Value(last1));
121       gp_Dir dir(vec);
122       axe1 = gp_Ax1(AdC1.Value(first1),dir);
123     }
124     else {
125       // first section of any type
126       IType = 0;
127     }
128   }
129
130   if (IType!=0) {
131
132     Standard_Boolean degen2 = BRep_Tool::Degenerated(Edge2);
133     if (degen2) {
134       TopExp::Vertices(Edge2,V1,V2);
135       pos = BRep_Tool::Pnt(V1);
136       if (IType==1) {
137         // the only particular case with degenerated edge at end : the cone
138         if (pos.IsEqual(pos1,Precision::Confusion())) {
139           // the top is mixed with the center of the circle
140           IType = 0;
141         }
142         else {
143           gp_Vec vec(pos1,pos);
144           gp_Dir dir(vec);
145           axe = gp_Ax1(pos1,dir);
146           if (axe.IsParallel(axe1,Precision::Angular())) {
147             // the top is on the axis of the circle
148             IType = 2;
149           }
150           else {
151             // incorrect top --> no particular case
152             IType = 0;
153           }
154         }
155       }
156       else if (IType != 4) { //not a plane
157         // no particular case
158         IType = 0;
159       }
160     }
161     else {
162       curv = BRep_Tool::Curve(Edge2, loc, first2, last2);
163       if (curv.IsNull())
164         throw Standard_NullObject("Null 3D curve in edge");
165       curv = 
166         Handle(Geom_Curve)::DownCast(curv->Transformed(loc.Transformation()));
167       ff = first2;
168       ll = last2;
169       if (Edge2.Orientation() == TopAbs_REVERSED) {
170         curv->Reverse();
171         first2 = curv->ReversedParameter(ll);
172         last2 = curv->ReversedParameter(ff);
173       }
174       GeomAdaptor_Curve AdC(curv);
175     
176       if (IType>0 && IType<4) {
177         if (AdC.GetType() != GeomAbs_Circle) {
178           // section not circular --> no particular case
179           IType = 0;
180         }
181         else {
182           if (AdC.Circle().Axis()
183               .IsCoaxial(axe1,Precision::Angular(),Precision::Confusion())) {
184             // same axis
185             if (Abs(AdC.Circle().Radius()-dist1)< Precision::Confusion()) {
186               // possibility of cylinder or a piece of cylinder
187               Standard_Real h1 = Abs(last1-first1), h2 = Abs(last2-first2);
188               Standard_Boolean Same, 
189                SameParametricLength = ( Abs(h1-h2) < Precision::PConfusion() );
190               Standard_Real m1=(first1+last1)/2., m2=(first2+last2)/2.;
191               gp_Pnt P1,P2;
192               gp_Vec DU;
193               AdC1.D1(m1,P1,DU);
194               AdC.D0(m2,P2);
195               Same = SameParametricLength 
196                 && ( gp_Vec(P1,P2).IsNormal(DU,Precision::Angular()) ) ;
197               if (Same) {
198                 // cylinder or piece of cylinder
199                 IType = 1;
200               }
201               else {
202                 // the interval of definition is not correct
203                 IType = 0;
204               }
205             }
206             else {
207               // possibility of cone truncation
208               Standard_Real h1 = Abs(last1-first1), h2 = Abs(last2-first2);
209               Standard_Boolean Same, 
210                SameParametricLength = ( Abs(h1-h2) < Precision::PConfusion() );
211               Standard_Real m1=(first1+last1)/2., m2=(first2+last2)/2.;
212               gp_Pnt P1,P2;
213               gp_Vec DU;
214               AdC1.D1(m1,P1,DU);
215               AdC.D0(m2,P2);
216               Same = SameParametricLength 
217                 && ( gp_Vec(P1,P2).IsNormal(DU,Precision::Angular()) ) ;
218               if (Same) {
219                 // truncation of cone
220                 IType = 2;
221               }
222               else {
223                 // the interval of definition is not correct
224                 IType = 0;
225               }
226             }
227             if (AdC.Circle().Location().IsEqual(pos1,Precision::Confusion())) {
228               // the centers are mixed
229               IType = 0;
230             }
231           }
232           else {
233             // different axis
234             if (AdC.Circle().Radius()==dist1) {
235               // torus ?
236               IType = 3;
237             }
238             else {
239               // different radius --> no particular case
240               IType = 0;
241             }
242           }
243         }
244       }
245       else if (IType>=4) {
246         if (AdC.GetType() != GeomAbs_Line) {
247           // not a straight line section --> no particular case
248           IType = 0;
249         }
250         else {
251           pos = AdC.Line().Location();
252           dist = AdC.Value(first2).Distance(AdC.Value(last2));
253           gp_Vec vec(AdC.Value(first2),AdC.Value(last2));
254           gp_Dir aDir(vec);
255           axe = gp_Ax1(AdC.Value(first2), aDir);
256           if (axe.IsParallel(axe1,Precision::Angular())) {
257             // parallel straight line
258             if (Abs(dist-dist1)<Precision::Confusion()) {
259               gp_Dir dir(gp_Vec(AdC1.Value(first1),AdC.Value(first2)));
260               if (dir.IsNormal(gp_Dir(vec),Precision::Angular())) {
261                 // plane
262                 IType = 4;
263               }
264               else {
265                 // extrusion ?
266                 IType = 5;
267               }
268             }
269             else {
270               // different length --> no particular case
271               IType = 0;
272             }
273           }
274           else {
275             // not parallel straight line --> no particular case
276             IType = 0;
277           }
278         }
279       }
280       else if (IType==-2) {
281         if (AdC.GetType() == GeomAbs_Line)
282           IType = 4; //plane
283         else if (AdC.GetType() == GeomAbs_Circle)
284           {
285             // the only particular case with degenerated edge at the beginning the cone
286             pos = AdC.Circle().Location();
287             axe = AdC.Circle().Axis();
288             if (pos1.IsEqual(pos,Precision::Confusion())) {
289               // the top is mixed with the center of the circle
290               IType = 0;
291             }
292             else {
293               gp_Vec vec(pos1,pos);
294               gp_Dir dir(vec);
295               axe1 = gp_Ax1(pos1,dir);
296               if (axe.IsParallel(axe1,Precision::Angular())) {
297                 // the top is on the axis of the circle
298                 IType = -2;
299               }
300               else {
301                 // incorrect top --> no particular case
302                 IType = 0;
303               }
304             }
305           }
306         else
307           IType = 0;
308       }
309     }
310     
311   }
312   // torus and extrusion are not particular cases.
313   if (IType == 3 || IType == 5) IType = 0;
314   return IType;
315 }
316
317
318 //=======================================================================
319 //function : CreateKPart
320 //purpose  : 
321 //=======================================================================
322
323 void CreateKPart(const TopoDS_Edge& Edge1,const TopoDS_Edge& Edge2,
324                  const Standard_Integer IType, 
325                  Handle(Geom_Surface)& Surf)
326 {
327   // find the dimension
328   TopoDS_Vertex V1, V2;
329
330   TopLoc_Location loc;
331   Standard_Real a1, b1, aa =0., bb =0.;
332   TopoDS_Vertex v1f,v1l,v2f,v2l;
333
334   // find characteristics of the first edge
335   Handle(Geom_Curve) C1;
336   Standard_Boolean degen1 = BRep_Tool::Degenerated(Edge1);
337   if(degen1) {
338     // cone with degenerated edge at the top
339     TopExp::Vertices(Edge1,v1f,v1l);
340   }
341   else {
342     C1 = BRep_Tool::Curve(Edge1, loc, a1, b1);
343     if (C1.IsNull())
344       throw Standard_NullObject("Null 3D curve in edge");
345     C1 = Handle(Geom_Curve)::DownCast(C1->Transformed(loc.Transformation()));
346     aa = a1;
347     bb = b1;
348     if (Edge1.Orientation() == TopAbs_REVERSED) {
349       C1->Reverse();
350       aa = C1->ReversedParameter(b1);
351       bb = C1->ReversedParameter(a1);
352       TopExp::Vertices(Edge1,v1l,v1f);
353     }
354     else {
355       TopExp::Vertices(Edge1,v1f,v1l);
356     }
357   }
358
359   // find characteristics of the second edge
360   Handle(Geom_Curve) C2;
361   Standard_Boolean degen2 = BRep_Tool::Degenerated(Edge2);
362   if(degen2) {
363     // cone with degenerated edge at the top
364     TopExp::Vertices(Edge2,v2f,v2l);
365   }
366   else {
367     C2 = BRep_Tool::Curve(Edge2, loc, a1, b1);
368     if (C2.IsNull())
369       throw Standard_NullObject("Null 3D curve in edge");
370     C2 = Handle(Geom_Curve)::DownCast(C2->Transformed(loc.Transformation()));
371     if (Edge2.Orientation() == TopAbs_REVERSED) {
372       C2->Reverse();
373       if (degen1) {
374         aa = a1;
375         bb = b1;
376       }
377       TopExp::Vertices(Edge2,v2l,v2f);
378     }
379     else {
380       if (degen1) {
381         aa = a1; //C2->ReversedParameter(b1);
382         bb = b1; //C2->ReversedParameter(a1);
383       }
384       TopExp::Vertices(Edge2,v2f,v2l);
385     }
386   }
387
388   // create the new surface
389   TopoDS_Face face;
390   TopoDS_Wire W;
391   TopoDS_Edge edge1, edge2, edge3, edge4, couture;
392
393   TopoDS_Wire newW1, newW2;
394   BRep_Builder BW1, BW2;
395   BW1.MakeWire(newW1);
396   BW2.MakeWire(newW2);
397
398   GeomAdaptor_Curve aC1Adaptor;
399   if (!C1.IsNull())
400     aC1Adaptor.Load(C1);
401   GeomAdaptor_Curve aC2Adaptor;
402   if (!C2.IsNull())
403     aC2Adaptor.Load(C2);
404
405   // calculate the surface
406   Handle(Geom_Surface) surface;
407   Standard_Real V, Rad;
408   if (IType==1) {
409     // cylindrical surface
410     gp_Circ c1 = aC1Adaptor.Circle();
411     gp_Circ c2 = aC2Adaptor.Circle();
412     gp_Ax3 Ac1 = c1.Position();
413     V = gp_Vec( c1.Location(),c2.Location()).Dot(gp_Vec(Ac1.Direction()));
414     if ( V < 0.) {
415       Ac1.ZReverse();
416       V = -V;
417     }
418     Handle(Geom_CylindricalSurface) Cyl = 
419       new Geom_CylindricalSurface( Ac1, c1.Radius());
420     surface = new Geom_RectangularTrimmedSurface
421       ( Cyl, aa, bb, Min(0.,V), Max(0.,V) );
422   }
423   else if (IType==2) {
424     // conical surface
425     gp_Circ k1 = aC1Adaptor.Circle();
426     gp_Ax3 Ak1 = k1.Position();
427     if (degen2) {
428       V = gp_Vec( k1.Location(),BRep_Tool::Pnt(v2f))
429         .Dot(gp_Vec(Ak1.Direction()));
430       Rad = - k1.Radius();
431     }
432     else {
433       gp_Circ k2 = aC2Adaptor.Circle();
434       V = gp_Vec( k1.Location(),k2.Location()).Dot(gp_Vec(Ak1.Direction()));
435       Rad = k2.Radius() - k1.Radius();
436     }
437       
438     if ( V < 0.) {
439       Ak1.ZReverse();
440       V = -V;
441     }
442     Standard_Real Ang = ATan( Rad / V);
443     Handle(Geom_ConicalSurface) Cone = 
444       new Geom_ConicalSurface( Ak1, Ang, k1.Radius());
445     V /= Cos(Ang);
446     surface = new Geom_RectangularTrimmedSurface
447       ( Cone, aa, bb, Min(0.,V), Max(0.,V) );
448   }
449   else if (IType==-2) {
450     // conical surface with the top at the beginning (degen1 is true)
451     gp_Circ k2 = aC2Adaptor.Circle();
452     gp_Ax3 Ak2 = k2.Position();
453     Ak2.SetLocation(BRep_Tool::Pnt(v1f));
454     V = gp_Vec(BRep_Tool::Pnt(v1f),k2.Location())
455                                 .Dot(gp_Vec(Ak2.Direction()));
456     Rad = k2.Radius(); // - k2.Radius();      
457     if ( V < 0.) {
458       Ak2.ZReverse();
459       V = -V;
460     }
461     Standard_Real Ang = ATan( Rad / V);
462     Handle(Geom_ConicalSurface) Cone = 
463       new Geom_ConicalSurface( Ak2, Ang, 0.);
464     V /= Cos(Ang);
465     surface = new Geom_RectangularTrimmedSurface
466       ( Cone, aa, bb, Min(0.,V), Max(0.,V) );
467   }
468   else if (IType==3) {
469     // torus surface ?
470   }
471   else if (IType==4) {
472     // surface plane
473     gp_Lin L1, L2, aLine;
474     if (!degen1)
475     {
476       L1 = aC1Adaptor.Line();
477       aLine = L1;
478     }
479     if (!degen2)
480     {
481       L2 = aC2Adaptor.Line();
482       aLine = L2;
483     }
484
485     gp_Pnt P1 = (degen1)? BRep_Tool::Pnt(v1f) : L1.Location();
486     gp_Pnt P2 = (degen2)? BRep_Tool::Pnt(v2f) : L2.Location();
487
488     gp_Vec P1P2( P1, P2 ); 
489     gp_Dir D1 = aLine.Direction();
490     gp_Ax3 Ax( aLine.Location(), gp_Dir(D1.Crossed(P1P2)), D1 );
491     Handle(Geom_Plane) Plan = new Geom_Plane(Ax);
492     V = P1P2.Dot( Ax.YDirection());
493     surface = Plan;
494     //surface = new Geom_RectangularTrimmedSurface
495       //( Plan, aa, bb, Min(0.,V), Max(0.,V) );
496   }
497   else if (IType==5) {
498     // surface of extrusion ?
499   }
500   else {
501     // IType incorrect
502   }
503   Surf = surface;
504 }
505
506
507 //=======================================================================
508 //function : BRepFill_Generator
509 //purpose  : 
510 //=======================================================================
511
512 BRepFill_Generator::BRepFill_Generator()
513 {
514 }
515
516
517 //=======================================================================
518 //function : AddWire
519 //purpose  : 
520 //=======================================================================
521
522 void BRepFill_Generator::AddWire(const TopoDS_Wire& Wire)
523 {
524   myWires.Append( Wire);
525 }
526
527
528 //=======================================================================
529 //function : Perform
530 //purpose  : 
531 //=======================================================================
532
533 void BRepFill_Generator::Perform()
534 {
535   TopoDS_Shell Shell;
536   TopoDS_Face  Face;
537   TopoDS_Shape S1, S2;
538   TopoDS_Edge  Edge1, Edge2, Edge3, Edge4, Couture;
539
540   BRep_Builder B;
541   B.MakeShell(myShell);
542
543   Standard_Integer Nb = myWires.Length();
544
545   BRepTools_WireExplorer ex1,ex2;
546
547   Standard_Boolean wPoint1, wPoint2, uClosed = Standard_False, DegenFirst = Standard_False, DegenLast = Standard_False;
548   
549   for ( Standard_Integer i = 1; i <= Nb-1; i++) {
550
551     TopoDS_Wire Wire1 = TopoDS::Wire(myWires( i ));
552     TopoDS_Wire Wire2 = TopoDS::Wire(myWires(i+1));
553
554     wPoint1 = Standard_False;
555     if (i==1) {
556       wPoint1 = Standard_True;
557       for(ex1.Init(Wire1); ex1.More(); ex1.Next()) {
558         wPoint1 = wPoint1 && (BRep_Tool::Degenerated(ex1.Current()));
559       }
560       DegenFirst = wPoint1;
561
562       TopoDS_Vertex V1, V2;
563       TopExp::Vertices(Wire1, V1, V2);
564       uClosed = V1.IsSame(V2);
565     }
566
567     wPoint2 = Standard_False;
568     if (i==Nb-1) {
569       wPoint2 = Standard_True;
570       for(ex2.Init(Wire2); ex2.More(); ex2.Next()) {
571         wPoint2 = wPoint2 && (BRep_Tool::Degenerated(ex2.Current()));
572       }
573       DegenLast = wPoint2;
574     }
575
576     ex1.Init(Wire1);
577     ex2.Init(Wire2);
578
579     TopTools_DataMapOfShapeShape Map;
580     
581     Standard_Boolean tantque = ex1.More() && ex2.More();
582
583     while ( tantque ) { 
584
585       TopoDS_Vertex V1f,V1l,V2f,V2l, Vf_toMap, Vl_toMap;
586
587       Standard_Boolean degen1 
588         = BRep_Tool::Degenerated(TopoDS::Edge(ex1.Current()));
589       Standard_Boolean degen2
590         = BRep_Tool::Degenerated(TopoDS::Edge(ex2.Current()));
591
592       if ( degen1 ) {
593         TopoDS_Shape aLocalShape = ex1.Current().EmptyCopied();
594         Edge1 = TopoDS::Edge(aLocalShape);
595 //      Edge1 = TopoDS::Edge(ex1.Current().EmptyCopied());
596 //      aLocalShape = ex1.Current();
597 //      TopExp::Vertices(TopoDS::Edge(aLocalShape),V1f,V1l);
598         TopExp::Vertices(TopoDS::Edge(ex1.Current()),V1f,V1l);
599         V1f.Orientation(TopAbs_FORWARD);
600         B.Add(Edge1,V1f);
601         V1l.Orientation(TopAbs_REVERSED);
602         B.Add(Edge1,V1l);
603         B.Range(Edge1,0,1);
604       }
605       else {
606         TopoDS_Shape aLocalShape = ex1.Current();
607         Edge1 = TopoDS::Edge(aLocalShape);
608 //      Edge1 = TopoDS::Edge(ex1.Current());
609       }
610
611       if ( degen2 ) {
612         TopoDS_Shape aLocalShape = ex2.Current().EmptyCopied();
613         Edge2 = TopoDS::Edge(aLocalShape);
614 //      Edge2 = TopoDS::Edge(ex2.Current().EmptyCopied());
615         TopExp::Vertices(TopoDS::Edge(ex2.Current()),V2f,V2l);
616         V2f.Orientation(TopAbs_FORWARD);
617         B.Add(Edge2,V2f);
618         V2l.Orientation(TopAbs_REVERSED);
619         B.Add(Edge2,V2l);
620         B.Range(Edge2,0,1);
621       }
622       else {
623         Edge2 = TopoDS::Edge(ex2.Current());
624       }
625
626       Standard_Boolean Periodic = (BRep_Tool::IsClosed(Edge1) || degen1) &&
627                                   (BRep_Tool::IsClosed(Edge2) || degen2);
628       // ATTENTION : a non-punctual wire should not 
629       //             contain a punctual edge
630       if (!wPoint1) ex1.Next();
631       if (!wPoint2) ex2.Next();
632
633       // initialization of vertices
634       Handle(Geom_Surface) Surf;
635       Standard_Real f1=0, l1=1, f2=0, l2=1;
636       if (Edge1.Orientation() == TopAbs_REVERSED)
637         TopExp::Vertices(Edge1,V1l,V1f);
638       else
639         TopExp::Vertices(Edge1,V1f,V1l);
640       if (Edge2.Orientation() == TopAbs_REVERSED)
641         TopExp::Vertices(Edge2,V2l,V2f);
642       else
643         TopExp::Vertices(Edge2,V2f,V2l);
644       if (degen1)
645         {
646           Vf_toMap = V2f;
647           Vl_toMap = V2l;
648         }
649       else
650         {
651           Vf_toMap = V1f;
652           Vl_toMap = V1l;
653         }
654
655       // processing of KPart
656       Standard_Integer IType = DetectKPart(Edge1,Edge2);
657       if (IType==0) {
658         // no part cases
659         TopLoc_Location L,L1,L2;
660
661         Handle(Geom_Curve) C1, C2;
662         TColgp_Array1OfPnt Extremities(1,2);
663       
664         if (degen1) {
665           Extremities(1) = BRep_Tool::Pnt(V1f);
666           Extremities(2) = BRep_Tool::Pnt(V1l);
667           C1 = new Geom_BezierCurve(Extremities);
668         }
669         else {
670           C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
671           if (C1.IsNull())
672             throw Standard_NullObject("Null 3D curve in edge");
673         }
674         if (degen2) {
675           Extremities(1) = BRep_Tool::Pnt(V2l);
676           Extremities(2) = BRep_Tool::Pnt(V2f);
677           C2 = new Geom_BezierCurve(Extremities);
678         }
679         else {
680           C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
681           if (C2.IsNull())
682             throw Standard_NullObject("Null 3D curve in edge");
683         }
684         
685         // compute the location
686         Standard_Boolean SameLoc = Standard_False;
687         
688         // transform and trim the curves
689       
690         if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
691             Abs(l1 - C1->LastParameter())  > Precision::PConfusion()   ) {
692           C1 = new Geom_TrimmedCurve(C1,f1,l1);
693         }
694         else {
695           C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
696         }
697         if (!SameLoc) C1->Transform(L1.Transformation());
698         if (Edge1.Orientation() == TopAbs_REVERSED) {
699           C1->Reverse();
700         }
701         
702         if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
703             Abs(l2 - C2->LastParameter())  > Precision::PConfusion()   ) {
704           C2 = new Geom_TrimmedCurve(C2,f2,l2);
705         }
706         else {
707           C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
708         }
709         if (!SameLoc) C2->Transform(L2.Transformation());
710         if (Edge2.Orientation() == TopAbs_REVERSED) {
711           C2->Reverse();
712         }
713         
714         GeomFill_Generator Generator;
715         Generator.AddCurve( C1);
716         Generator.AddCurve( C2);
717         Generator.Perform( Precision::PConfusion());
718         
719         Surf = Generator.Surface();
720         B.MakeFace(Face,Surf,Precision::Confusion());
721       }
722       else {
723         // particular case
724         CreateKPart(Edge1,Edge2,IType,Surf);
725         B.MakeFace(Face,Surf,Precision::Confusion());
726       }
727       
728       // make the missing edges
729       Standard_Real first,last;
730       Surf->Bounds(f1,l1,f2,l2);
731       if (IType == 0)
732       {
733         first = f2;
734         last = l2;
735       }
736       else
737       {
738         first = 0.;
739         last = 1.;
740       }
741
742       if ( Map.IsBound(Vf_toMap)) {
743         TopoDS_Shape aLocalShape = Map(Vf_toMap).Reversed();
744         Edge3 = TopoDS::Edge(aLocalShape);
745 //      Edge3 = TopoDS::Edge(Map(V1f).Reversed());
746       }
747       else
748       {
749         if (V1f.IsSame(V2f))
750         {
751           B.MakeEdge(Edge3);
752           B.Degenerated(Edge3, Standard_True);
753         }
754         else
755         {
756           Handle(Geom_Curve) CC;
757           TColgp_Array1OfPnt Extremities(1, 2);
758           if (IType == 0) {
759             // general case : Edge3 corresponds to iso U=f1
760             CC = Surf->UIso(f1);
761           }
762           else {
763             // particular case : it is required to calculate the curve 3d
764             Extremities(1) = BRep_Tool::Pnt(V1f);
765             Extremities(2) = BRep_Tool::Pnt(V2f);
766             CC = new Geom_BezierCurve(Extremities);
767           }
768           B.MakeEdge(Edge3, CC, Precision::Confusion());
769         }
770         V1f.Orientation(TopAbs_FORWARD);
771         B.Add(Edge3, V1f);
772         V2f.Orientation(TopAbs_REVERSED);
773         B.Add(Edge3, V2f);
774         B.Range(Edge3, first, last);
775         Edge3.Reverse();
776         Map.Bind(Vf_toMap, Edge3);
777       }
778
779       Standard_Boolean CommonEdge = Standard_False;
780       if ( Map.IsBound(Vl_toMap)  ) {
781         TopoDS_Shape aLocalShape = Map(Vl_toMap).Reversed();
782         const TopoDS_Edge CommonE = TopoDS::Edge(aLocalShape);
783 //      const TopoDS_Edge CommonE = TopoDS::Edge(Map(V1l).Reversed());
784         TopoDS_Vertex V1, V2;
785         TopExp::Vertices(CommonE,V1,V2);
786         CommonEdge = V1.IsSame(V1l) && V2.IsSame(V2l);
787       }
788       if ( CommonEdge ) {
789         TopoDS_Shape aLocalShape = Map(Vl_toMap).Reversed();
790         Edge4 = TopoDS::Edge(aLocalShape);
791 //      Edge4 = TopoDS::Edge(Map(V1l).Reversed());
792       }
793       else
794       {
795         if (V1l.IsSame(V2l))
796         {
797           B.MakeEdge(Edge4);
798           B.Degenerated(Edge4, Standard_True);
799         }
800         else
801         {
802           Handle(Geom_Curve) CC;
803           TColgp_Array1OfPnt Extremities(1, 2);
804           if (IType == 0) {
805             // general case : Edge4 corresponds to iso U=l1
806             CC = Surf->UIso(l1);
807           }
808           else {
809             // particular case : it is required to calculate the curve 3d
810             Extremities(1) = BRep_Tool::Pnt(V1l);
811             Extremities(2) = BRep_Tool::Pnt(V2l);
812             CC = new Geom_BezierCurve(Extremities);
813           }
814           B.MakeEdge(Edge4, CC, Precision::Confusion());
815         }
816         V1l.Orientation(TopAbs_FORWARD);
817         B.Add(Edge4, V1l);
818         V2l.Orientation(TopAbs_REVERSED);
819         B.Add(Edge4, V2l);
820         B.Range(Edge4, first, last);
821         Map.Bind(Vl_toMap, Edge4);
822       }
823
824       // make the wire
825       
826       TopoDS_Wire W;
827       B.MakeWire(W);
828       
829       if (! (degen1 && IType == 4))
830         B.Add(W,Edge1);
831       B.Add(W,Edge4);
832       if (! (degen2 && IType == 4))
833         B.Add(W,Edge2.Reversed());
834       B.Add(W,Edge3);
835       
836       B.Add(Face,W);
837       
838       B.Add(myShell,Face);
839
840     // complete myMap for edge1
841       if (! (degen1 && IType == 4))
842         {
843           TopTools_ListOfShape Empty;
844           if (!myMap.IsBound(Edge1)) myMap.Bind(Edge1,Empty);
845           myMap(Edge1).Append(Face);
846         }
847       
848       // set the pcurves
849       
850       Standard_Real T = Precision::Confusion();
851
852       if (IType != 4) //not plane
853         {
854           if ( Edge1.Orientation() == TopAbs_REVERSED ) {
855             B.UpdateEdge(Edge1,
856                          new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
857                          Face,T);
858             B.Range(Edge1,Face,-l1,-f1);
859           }
860           else {
861             B.UpdateEdge(Edge1,
862                          new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
863                          Face,T);
864             B.Range(Edge1,Face,f1,l1);
865           }
866           
867           if ( Edge2.Orientation() == TopAbs_REVERSED ) {
868             B.UpdateEdge(Edge2,
869                          new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
870                          Face,T);
871             B.Range(Edge2,Face,-l1,-f1);
872           }
873           else {
874             B.UpdateEdge(Edge2,
875                          new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
876                          Face,T);
877             B.Range(Edge2,Face,f1,l1);
878           }
879         }
880
881       if (IType==0) {
882         if ( Periodic) {
883           B.UpdateEdge(Edge3,
884                        new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
885                        new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
886                        Face,T);
887         }
888         else {
889           B.UpdateEdge(Edge3,
890                        new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
891                        Face,T);
892           B.UpdateEdge(Edge4,
893                        new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
894                        Face,T);
895         }
896       }
897       else {
898         // KPart
899         if ( Periodic) {
900           TColgp_Array1OfPnt2d Extrem1(1,2);
901           Extrem1(1).SetCoord(l1,f2);
902           Extrem1(2).SetCoord(l1,l2);
903           TColgp_Array1OfPnt2d Extrem2(1,2);
904           Extrem2(1).SetCoord(f1,f2);
905           Extrem2(2).SetCoord(f1,l2);
906           B.UpdateEdge(Edge3,
907                        new Geom2d_BezierCurve(Extrem1),
908                        new Geom2d_BezierCurve(Extrem2),
909                        Face,T);
910         }
911         else if (IType != 4) { //not plane
912           TColgp_Array1OfPnt2d Extrem2(1,2);
913           Extrem2(1).SetCoord(f1,f2);
914           Extrem2(2).SetCoord(f1,l2);
915           B.UpdateEdge(Edge3,
916                        new Geom2d_BezierCurve(Extrem2),
917                        Face,T);
918           TColgp_Array1OfPnt2d Extrem1(1,2);
919           Extrem1(1).SetCoord(l1,f2);
920           Extrem1(2).SetCoord(l1,l2);
921           B.UpdateEdge(Edge4,
922                        new Geom2d_BezierCurve(Extrem1),
923                        Face,T);
924         }
925       }
926       // Set the non parameter flag;
927       B.SameParameter(Edge1,Standard_False);
928       B.SameParameter(Edge2,Standard_False);
929       B.SameParameter(Edge3,Standard_False);
930       B.SameParameter(Edge4,Standard_False);
931       B.SameRange(Edge1,Standard_False);
932       B.SameRange(Edge2,Standard_False);
933       B.SameRange(Edge3,Standard_False);
934       B.SameRange(Edge4,Standard_False);
935
936       tantque = ex1.More() && ex2.More();
937       if (wPoint1) tantque = ex2.More();
938       if (wPoint2) tantque = ex1.More();
939     }
940   }
941   BRepLib::SameParameter(myShell);
942
943   if (uClosed && DegenFirst && DegenLast)
944     myShell.Closed(Standard_True);
945 }
946
947
948 //=======================================================================
949 //function : GeneratedShapes
950 //purpose  : 
951 //=======================================================================
952
953 const TopTools_ListOfShape& 
954  BRepFill_Generator::GeneratedShapes (const TopoDS_Shape& SSection) const 
955 {
956   if (myMap.IsBound(SSection)) {
957     return myMap(SSection);
958   }
959   else {
960     static TopTools_ListOfShape Empty;
961     return Empty;
962   }
963 }
964
965 //=======================================================================
966 //function : Generated
967 //purpose  : 
968 //=================================================================== ====
969
970 const TopTools_DataMapOfShapeListOfShape& BRepFill_Generator::Generated() const
971 {
972   return myMap;
973 }
974
975