0024048: "Basic Runtime Checks" option of VS projects should be equal to "RTC1"
[occt.git] / src / ChFi3d / ChFi3d_FilBuilder_C2.cxx
1 // Created on: 1994-03-29
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <ChFi3d_FilBuilder.jxx>
23
24 #include <ChFi3d.hxx>
25 #include <ChFi3d_Builder_0.hxx>
26
27 #include <StdFail_NotDone.hxx>
28 #include <Standard_NotImplemented.hxx>
29 #include <Standard_ErrorHandler.hxx>
30
31 #include <math_Vector.hxx>
32 #include <TColgp_Array1OfPnt.hxx>
33 #include <TColgp_Array1OfPnt2d.hxx>
34 #include <TColStd_Array1OfReal.hxx>
35 #include <TColStd_Array1OfInteger.hxx>
36 #include <TColStd_ListOfInteger.hxx>
37 #include <gp_Pnt.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <gp_Dir.hxx>
40 #include <gp_Lin.hxx>
41 #include <gp_Pln.hxx>
42 #include <gp_Ax3.hxx>
43 #include <Geom_BSplineCurve.hxx>
44 #include <Geom2d_TrimmedCurve.hxx>
45 #include <Geom2d_BSplineCurve.hxx>
46 #include <Law_Linear.hxx>
47 #include <BRepBlend_CSCircular.hxx>
48 #include <BRepBlend_Line.hxx>
49 #include <Geom2dConvert.hxx>
50 #include <BSplCLib.hxx>
51
52 #include <Adaptor3d_CurveOnSurface.hxx>
53 #include <Adaptor3d_HCurveOnSurface.hxx>
54 #include <BRepLProp_CLProps.hxx>
55 #include <GeomAdaptor_Curve.hxx>
56 #include <GeomAdaptor_HCurve.hxx>
57 #include <Geom2dAdaptor_Curve.hxx>
58 #include <Geom2dAdaptor_HCurve.hxx>
59 #include <GeomAdaptor_Surface.hxx>
60 #include <GeomAdaptor_HSurface.hxx>
61 #include <BRep_Tool.hxx>
62 #include <BRepAdaptor_Curve2d.hxx>
63 #include <BRepAdaptor_Curve.hxx>
64 #include <BRepAdaptor_HCurve.hxx>
65 #include <BRepAdaptor_Surface.hxx>
66 #include <BRepAdaptor_HSurface.hxx>
67 #include <BRepTopAdaptor_TopolTool.hxx> 
68 #include <GeomFill_ConstrainedFilling.hxx>
69 #include <GeomFill_SimpleBound.hxx>
70
71 #include <IntSurf_LineOn2S.hxx>
72 #include <IntSurf_Transition.hxx>
73 #include <IntSurf_TypeTrans.hxx>
74 #include <IntCurveSurface_HInter.hxx>
75 #include <IntCurveSurface_IntersectionPoint.hxx>
76
77 #include <TopoDS.hxx>
78 #include <TopoDS_Vertex.hxx>
79 #include <TopoDS_Face.hxx>
80 #include <TopOpeBRepDS_DataStructure.hxx>
81 #include <TopOpeBRepDS_ListOfInterference.hxx>
82 #include <TopAbs.hxx>
83 #include <TopAbs_Orientation.hxx>
84 #include <TopExp.hxx>
85 #include <TopTools_ListIteratorOfListOfShape.hxx>
86 #include <TopOpeBRepDS_HDataStructure.hxx>
87 #include <ChFiDS_Regul.hxx>
88 #include <ChFiDS_State.hxx>
89 #include <ChFiDS_SequenceOfSurfData.hxx>
90 #include <ChFiDS_SurfData.hxx>
91 #include <ChFiDS_FaceInterference.hxx>
92 #include <ChFiDS_ListIteratorOfListOfStripe.hxx>
93 #include <ChFiDS_Stripe.hxx>
94 #include <ChFiDS_Spine.hxx>
95 #include <ChFiDS_FilSpine.hxx>
96 #include <ChFiDS_HData.hxx>
97 #include <ChFiDS_CommonPoint.hxx>
98
99 #include <ChFiKPart_ComputeData.hxx>
100
101 #ifdef DRAW
102 #include <DrawTrSurf.hxx>
103 #endif
104 #ifdef DEB
105 #include <Geom_TrimmedCurve.hxx>
106 extern Standard_Boolean ChFi3d_GettraceDRAWSPINE();
107 extern Standard_Boolean ChFi3d_GetcontextFORCEFILLING();
108 #include <OSD_Chronometer.hxx>
109
110 extern Standard_Real  t_t2cornerinit ,t_perf2cornerbyinter,t_chfikpartcompdata,
111                      t_cheminement,t_remplissage,t_t2cornerDS;
112 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
113 extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
114 #endif
115
116 //=======================================================================
117 //function : ToricRotule
118 //purpose  : Test if it is a particular case of torus routine.
119 //           Three planes with two constant incident fillets
120 //           of the same radius and the third face perpendicular to  
121 //           two others are required.
122 //=======================================================================
123
124 static Standard_Boolean ToricRotule(const BRepAdaptor_Surface& fac,
125                                     const BRepAdaptor_Surface& s1,
126                                     const BRepAdaptor_Surface& s2,
127                                     const Handle(ChFiDS_Stripe)& c1,
128                                     const Handle(ChFiDS_Stripe)& c2)
129
130 {
131   Standard_Real tolesp = 1.e-7;
132
133   Handle(ChFiDS_FilSpine) sp1=Handle(ChFiDS_FilSpine)::DownCast(c1->Spine()); 
134   Handle(ChFiDS_FilSpine) sp2=Handle(ChFiDS_FilSpine)::DownCast(c2->Spine()); 
135   if(sp1.IsNull() || sp2.IsNull()) return Standard_False;
136   if (!sp1->IsConstant() || !sp2->IsConstant()) 
137     return Standard_False;
138   if ((fac.GetType() != GeomAbs_Plane) ||
139       (s1.GetType() != GeomAbs_Plane) ||
140       (s2.GetType() != GeomAbs_Plane)) return Standard_False;
141   gp_Dir df = fac.Plane().Position().Direction();
142   gp_Dir ds1 = s1.Plane().Position().Direction();
143   gp_Dir ds2 = s2.Plane().Position().Direction();
144   if ( Abs(df.Dot(ds1)) >= tolesp || Abs(df.Dot(ds2)) >= tolesp ) 
145     return Standard_False;
146   Standard_Real r1 = sp1->Radius();
147   Standard_Real r2 = sp2->Radius();
148   if(Abs(r1 - r2) >= tolesp) return Standard_False;
149   return Standard_True;
150 }
151
152 static void RemoveSD(Handle(ChFiDS_Stripe)& Stripe,
153                       const Standard_Integer num1,
154                       const Standard_Integer num2 )
155 {
156   ChFiDS_SequenceOfSurfData& Seq = 
157     Stripe->ChangeSetOfSurfData()->ChangeSequence();
158   if(Seq.IsEmpty()) return;
159   if (num1==num2) 
160     Seq.Remove(num1);
161   else
162     Seq.Remove(num1,num2);
163 }
164
165
166 //=======================================================================
167 //function : PerformTwoCorner
168 //purpose  : 
169 //=======================================================================
170
171 void ChFi3d_FilBuilder::PerformTwoCorner(const Standard_Integer Index)
172 {
173 #ifdef DEB 
174   OSD_Chronometer ch;
175   ChFi3d_InitChron(ch); // init perf initialisation 
176 #endif 
177   
178   done = 0;
179   const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index);
180   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
181   ChFiDS_ListIteratorOfListOfStripe It;
182   It.Initialize(myVDataMap(Index));
183   Handle(ChFiDS_Stripe)  st1,st2;
184   Standard_Integer Sens1,Sens2;
185   Standard_Integer Isd1,Isd2,i1,i2;
186   Handle(ChFiDS_SurfData) sd1,sd2;
187   ChFiDS_SequenceOfSurfData SeqFil1,SeqFil2;
188   Handle(Geom_Surface) surf1,surf2;
189   Standard_Boolean  OkinterCC,Okvisavis,SameSide;
190   Standard_Integer IFaCo1,IFaCo2;
191   Standard_Real UIntPC1,UIntPC2;
192   TopoDS_Face FaCo;
193   TopoDS_Edge E1,E2,E;
194   TopoDS_Vertex V1,V2;
195 //  gp_Pnt P1,P2;
196   Standard_Integer nbsurf1,nbsurf2,deb1,fin1,deb2,fin2;
197   Standard_Real parE1,parE2;
198   //Necessary information on fillets is extracted 
199   //------------------------------------------------------
200   
201   //the first
202   //----------
203  
204   st1 = It.Value(); 
205   Isd1 = ChFi3d_IndexOfSurfData(Vtx,st1,Sens1);
206   
207   
208   //the second
209   //----------
210   It.Next();
211   st2 = It.Value();
212   if(st2 == st1) {
213     Sens2 = -1;
214     Isd2 = st2->SetOfSurfData()->Length();
215   }
216   else{ Isd2 = ChFi3d_IndexOfSurfData(Vtx,st2,Sens2); }
217   
218   // If two edges to rounded are tangent GeomPlate is called
219
220   if (Sens1==1)  E1= st1->Spine()->Edges(1);
221   else E1= st1->Spine()->Edges( st1->Spine()->NbEdges());
222   
223   if (Sens2==1)  E2= st2->Spine()->Edges(1);
224   else E2= st2->Spine()->Edges( st2->Spine()->NbEdges());
225   
226   BRepAdaptor_Curve BCurv1(E1);
227   BRepAdaptor_Curve BCurv2(E2);
228   parE1=BRep_Tool::Parameter(Vtx,E1);
229   parE2=BRep_Tool::Parameter(Vtx,E2);
230   BRepLProp_CLProps CL1(BCurv1,parE1 , 1, 1.e-4);
231   BRepLProp_CLProps CL2(BCurv2,parE2 , 1, 1.e-4);
232   gp_Dir dir1,dir2 ;
233   CL1.Tangent(dir1);
234   CL2.Tangent(dir2);
235   if (Sens1==-1)  dir1.Reverse();
236   if (Sens2==-1)  dir2.Reverse();
237   Standard_Real ang1;
238   ang1=Abs(dir1.Angle(dir2));
239   if (ang1<M_PI/180.) {
240     PerformMoreThreeCorner(Index,2);
241     done=1;
242     return;
243   }
244
245   OkinterCC = ChFi3d_IsInFront(DStr,st1,st2,Isd1,Isd2,Sens1,Sens2,
246                                UIntPC1,UIntPC2,FaCo,SameSide,
247                                IFaCo1,IFaCo2,Okvisavis,Vtx,Standard_True);
248
249   Standard_Boolean trouve=Standard_False;  
250   if (!Okvisavis) {
251
252   
253 // one is not limited to the first or the last surfdata 
254 // to find the opposing data
255     nbsurf1=st1->SetOfSurfData()->Length();
256     nbsurf2=st2->SetOfSurfData()->Length();
257     deb1=1; 
258     deb2=1;
259     fin1=1;
260     fin2=1;
261     if (nbsurf1!=1) {
262       if (Sens1==1) {
263         deb1=1;
264         fin1=2;
265       }
266       else  {
267         deb1=nbsurf1-1;
268         fin1=nbsurf1;
269       }
270     }
271     if (nbsurf2!=1) {
272       if (Sens2==1 ) {
273         deb2=1;
274         fin2=2;
275       }
276       else {
277         deb2=nbsurf2-1;
278         fin2=nbsurf2;
279       }
280     }
281   
282     for (i1=deb1;i1<=fin1 &&!trouve;i1++) {
283       Isd1=i1;
284       for (i2=deb2;i2<=fin2 &&!trouve;i2++) {
285         Isd2=i2;
286  
287         OkinterCC = ChFi3d_IsInFront(DStr,st1,st2,Isd1,Isd2,Sens1,Sens2,
288                                UIntPC1,UIntPC2,FaCo,SameSide,
289                                IFaCo1,IFaCo2,Okvisavis,Vtx,Standard_True);
290         trouve=Okvisavis;
291       }
292     } 
293     if (!trouve){
294       PerformMoreThreeCorner(Index,2);
295       done=1;
296       return;
297     }
298     else {
299       if (Sens1==1 && Isd1!=1) RemoveSD(st1,1,1);
300       if (Sens1!=1 && Isd1!=nbsurf1) RemoveSD(st1,fin1,fin1);
301       if (Sens2==1 && Isd2!=1) RemoveSD(st2,1,1);
302       if (Sens2!=1 && Isd2!=nbsurf2) RemoveSD(st2,fin2,fin2);
303
304     }
305     Isd1=ChFi3d_IndexOfSurfData(Vtx,st1,Sens1);
306     Isd2=ChFi3d_IndexOfSurfData(Vtx,st2,Sens2);
307   }
308    // StdFail_NotDone::Raise("TwoCorner : no common face");
309   Standard_Integer IFaArc1 = 3-IFaCo1, IFaArc2 = 3-IFaCo2;
310   SeqFil1 = st1->ChangeSetOfSurfData()->ChangeSequence();
311   SeqFil2 = st2->ChangeSetOfSurfData()->ChangeSequence();
312   sd1 = SeqFil1.ChangeValue(Isd1);
313   surf1 = DStr.Surface(sd1->Surf()).Surface();
314   sd2 = SeqFil2.ChangeValue(Isd2);
315   surf2 = DStr.Surface(sd2->Surf()).Surface();
316   TopAbs_Orientation OFaCo = FaCo.Orientation(); 
317   // The concavities are analyzed and the opposite face and the
318   // eventual intersection of 2 pcurves on this face are found.
319   
320   ChFiDS_State Stat1,Stat2;
321   Standard_Boolean isfirst1 = (Sens1 == 1);
322   Standard_Boolean isfirst2 = (Sens2 == 1);
323   Stat1 = st1->Spine()->Status(isfirst1);
324   Stat2 = st2->Spine()->Status(isfirst2);
325   Standard_Boolean c1biseau = (Stat1 == ChFiDS_AllSame); 
326   Standard_Boolean c1rotule = (Stat1 == ChFiDS_OnSame && Stat2 == ChFiDS_OnSame);
327   
328   // It is checked if the fillets have a commonpoint on a common arc. 
329   // This edge is the pivot of the bevel or the knee.
330   
331   ChFiDS_CommonPoint& CP1 = sd1->ChangeVertex(isfirst1,IFaArc1);
332   ChFiDS_CommonPoint& CP2 = sd2->ChangeVertex(isfirst2,IFaArc2);
333   
334   Standard_Boolean resetcp1 = 0;
335   Standard_Boolean resetcp2 = 0;
336   
337   TopoDS_Edge pivot;
338   Standard_Boolean yapiv = Standard_False;
339   if(CP1.IsOnArc()) pivot = CP1.Arc();
340   else {
341     PerformMoreThreeCorner(Index,2);
342     done=1;
343     return;
344   }
345   if(CP1.IsOnArc()&& CP2.IsOnArc()){
346     yapiv = (pivot.IsSame(CP2.Arc()));
347   }
348   Handle(BRepAdaptor_HCurve) Hpivot;
349   Standard_Boolean sameparam = Standard_False;
350   Standard_Real parCP1 = 0., parCP2 = 0.;
351   if(yapiv) {
352     Hpivot = new BRepAdaptor_HCurve(pivot);
353     parCP1 = CP1.ParameterOnArc();
354     parCP2 = CP2.ParameterOnArc();
355     gp_Pnt tst1 = Hpivot->Value(parCP1);
356     gp_Pnt tst2 = Hpivot->Value(parCP2);
357     sameparam = tst1.Distance(tst2) <= tolesp;
358   }
359   Handle(BRepAdaptor_HSurface) HFaCo = new BRepAdaptor_HSurface();
360   Handle(BRepAdaptor_HSurface) HFaPiv;
361   Handle(BRepAdaptor_HSurface) HBRS1 = new BRepAdaptor_HSurface();
362   Handle(BRepAdaptor_HSurface) HBRS2 = new BRepAdaptor_HSurface();
363   
364   BRepAdaptor_Surface& BRS1 = HBRS1->ChangeSurface();
365   BRepAdaptor_Surface& BRS2 = HBRS2->ChangeSurface();
366   BRepAdaptor_Surface& BRFaCo = HFaCo->ChangeSurface();
367   BRFaCo.Initialize(FaCo);
368   
369   TopoDS_Face FF1,FF2,F,FaPiv;
370   TopAbs_Orientation pctrans = TopAbs_FORWARD ;
371   Handle(Geom2d_BSplineCurve) PCurveOnPiv;
372   FF1 = TopoDS::Face(DStr.Shape(sd1->Index(IFaArc1)));
373   FF2 = TopoDS::Face(DStr.Shape(sd2->Index(IFaArc2)));
374   if (FF1.IsNull()||FF2.IsNull()) 
375   {PerformMoreThreeCorner(Index,2);
376    done=1;
377    return;
378   }
379   BRS1.Initialize(FF1);
380   BRS2.Initialize(FF2);
381   
382   if(yapiv ) {
383     TopTools_ListIteratorOfListOfShape Kt;
384     Standard_Boolean ok1 = Standard_False, ok2 = Standard_False;
385     for (Kt.Initialize(myEFMap(pivot)); Kt.More(); Kt.Next()){
386       F = TopoDS::Face(Kt.Value());
387       if(!ok1 && FF1.IsSame(F)){
388         ok1 = Standard_True;
389       }
390       if(!ok2 && FF2.IsSame(F)){
391         ok2 = Standard_True;
392       }
393     }
394     if(!ok1 || !ok2){
395       PerformMoreThreeCorner(Index,2);
396       done=1;
397       return;
398     }
399   }
400   
401 #ifdef DEB  
402   ChFi3d_ResultChron(ch ,t_t2cornerinit);//result perf initialisation 
403 #endif 
404   
405   //bevel
406   //------
407   ChFiDS_CommonPoint cp11,cp12,cp21,cp22;
408   ChFiDS_FaceInterference intf11,intf12,intf21,intf22;
409
410   if(c1biseau){
411 #ifdef DEB   
412     ChFi3d_InitChron(ch); // init perf PerformTwoCornerbyInter
413 #endif 
414     
415     done = PerformTwoCornerbyInter(Index);
416     
417 #ifdef DEB 
418     ChFi3d_ResultChron(ch , t_perf2cornerbyinter); // result perf  PerformTwoCornerbyInter
419 #endif 
420    
421     if (!done){
422       PerformMoreThreeCorner(Index,2);
423       done=1;
424       return;
425     }
426   } 
427   else if(c1rotule){//save.
428     cp11 = sd1->Vertex(isfirst1,1);
429     cp12 = sd1->Vertex(isfirst1,2);
430     cp21 = sd2->Vertex(isfirst2,1);
431     cp22 = sd2->Vertex(isfirst2,2);
432     intf11 = sd1->InterferenceOnS1();
433     intf12 = sd1->InterferenceOnS2();
434     intf21 = sd2->InterferenceOnS1();
435     intf22 = sd2->InterferenceOnS2();
436 #ifdef DEB   
437     ChFi3d_InitChron(ch); // init perf PerformTwoCornerbyInter
438 #endif 
439       
440     done = PerformTwoCornerbyInter(Index);
441       
442 #ifdef DEB 
443       ChFi3d_ResultChron(ch , t_perf2cornerbyinter); // result perf  PerformTwoCornerbyInter
444 #endif 
445     if (!done) {
446       // restore
447       sd1->ChangeVertex(isfirst1,1) = cp11;
448       sd1->ChangeVertex(isfirst1,2) = cp12;
449       sd2->ChangeVertex(isfirst2,1) = cp21;
450       sd2->ChangeVertex(isfirst2,2) = cp22;
451       sd1->ChangeInterferenceOnS1() = intf11;
452       sd1->ChangeInterferenceOnS2() = intf12;
453       sd2->ChangeInterferenceOnS1() = intf21;
454       sd2->ChangeInterferenceOnS2() = intf22;
455       done = 0;
456     }
457   }
458   
459   if(!c1biseau && !done){
460     //new cornerdata is created
461     //-------------------------------
462     Handle(ChFiDS_Stripe) corner = new ChFiDS_Stripe();
463     Handle(ChFiDS_HData)& cornerset = corner->ChangeSetOfSurfData();
464     cornerset = new ChFiDS_HData();
465     Handle(ChFiDS_SurfData) coin = new ChFiDS_SurfData();
466     cornerset->Append(coin);
467     
468     if (SameSide) {
469       if(ToricRotule(BRFaCo,BRS1,BRS2,st1,st2)){
470         // Direct construction.
471         // ---------------------
472         
473         Standard_Integer bid;
474         TopAbs_Orientation ori = OFaCo;
475         TopAbs_Orientation oriS = st1->Orientation(IFaCo1);
476         TopAbs_Orientation OFF1 = FF1.Orientation(); 
477         TopAbs_Orientation oriSFF1 = st1->Orientation(IFaArc1);
478         bid = 1;
479         bid = ChFi3d::NextSide(ori,OFF1,oriS,oriSFF1,bid);
480         TopAbs_Orientation op1,op2;
481         if(yapiv) bid = ChFi3d::ConcaveSide(BRS1,BRS2,pivot,op1,op2);
482         op1 = TopAbs::Reverse(op1);
483         op2 = TopAbs::Reverse(op2);
484 #ifdef DEB  
485         ChFi3d_InitChron(ch);// init perf ChFiKPart_ComputeData 
486 #endif 
487         Standard_Real radius = 
488           Handle(ChFiDS_FilSpine)::DownCast(st1->Spine())->Radius();
489         done = ChFiKPart_ComputeData::ComputeCorner(DStr,coin,HFaCo,HBRS1,HBRS2,
490                                                     OFaCo,ori,op1,op2,radius);
491 #ifdef DEB 
492         ChFi3d_ResultChron(ch , t_chfikpartcompdata);//result perf ChFiKPart_ComputeData 
493 #endif 
494       }
495       else {
496         // Construction by filling remplissage
497         // ----------------------------
498         Standard_Real  uPCArc1,  uPCArc2;
499         gp_Pnt2d p2da1,p2df1,p2da2,p2df2,p2dfac1,p2dfac2;
500         gp_Vec2d v2dfac1,v2dfac2;
501         Handle(GeomFill_Boundary) B1,B2,Bpiv,Bfac;
502         uPCArc1 = sd1->Interference(IFaArc1).Parameter(isfirst1);
503         p2da1 = sd1->Interference(IFaArc1).PCurveOnSurf()->Value(uPCArc1);
504         p2df1 = sd1->Interference(IFaCo1).PCurveOnSurf()->Value(uPCArc1);
505         sd1->Interference(IFaCo1).PCurveOnFace()->D1(uPCArc1,p2dfac1,v2dfac1);
506         uPCArc2 = sd2->Interference(IFaArc2).Parameter(isfirst2);
507         p2da2 = sd2->Interference(IFaArc2).PCurveOnSurf()->Value(uPCArc2);
508         p2df2 = sd2->Interference(IFaCo2).PCurveOnSurf()->Value(uPCArc2);
509         sd2->Interference(IFaCo2).PCurveOnFace()->D1(uPCArc2,p2dfac2,v2dfac2);
510 #ifdef DEB 
511         ChFi3d_InitChron(ch ); // init perf filling
512 #endif 
513         B1 = ChFi3d_mkbound(surf1,p2df1,p2da1,tolesp,2.e-4);
514         B2 = ChFi3d_mkbound(surf2,p2df2,p2da2,tolesp,2.e-4);
515         Handle(Geom2d_Curve) PCurveOnFace;
516         Bfac = ChFi3d_mkbound(HFaCo,PCurveOnFace,Sens1,p2dfac1,v2dfac1,
517                               Sens2,p2dfac2,v2dfac2,tolesp,2.e-4);
518         GeomFill_ConstrainedFilling fil(8,20);
519         if(sameparam) {
520           fil.Init(Bfac,B2,B1,1);
521         }
522         else {
523           Handle(Adaptor3d_HCurve) HPivTrim = Hpivot->ChangeCurve().
524             Trim(Min(parCP1,parCP2),Max(parCP1,parCP2),tolesp);
525           Bpiv = new GeomFill_SimpleBound(HPivTrim,tolesp,2.e-4);
526           fil.Init(Bfac,B2,Bpiv,B1,1);
527           BRepAdaptor_Curve2d pcpivot;
528           gp_Vec dArc,dcf;
529           gp_Pnt bidon;
530           Hpivot->D1(parCP1,bidon,dArc);
531           Standard_Real fb1,lb1;
532           B1->Bounds(fb1,lb1);
533           B1->D1(lb1,bidon,dcf);
534           Standard_Boolean pivotverslebas = dArc.Dot(dcf) <= 0.; 
535           Standard_Boolean pcfalenvers = (parCP1 > parCP2);
536           if((pivotverslebas && !pcfalenvers)||
537              (!pivotverslebas && pcfalenvers)) {
538             FaPiv = FF2;
539             HFaPiv = HBRS2;
540             resetcp2 = 1;
541           }
542           else {
543             FaPiv = FF1;
544             HFaPiv = HBRS1;
545             resetcp1 = 1;
546           }
547           FaPiv.Orientation(TopAbs_FORWARD);
548           pcpivot.Initialize(pivot,FaPiv);
549           TopExp_Explorer Expl;
550           for(Expl.Init(FaPiv,TopAbs_EDGE); Expl.More(); Expl.Next()){
551             if(Expl.Current().IsSame(pivot)) {
552               pctrans = Expl.Current().Orientation();
553               break;
554             }
555           }
556           if(pcpivot.GetType() != GeomAbs_BSplineCurve){
557             Handle(Geom2d_TrimmedCurve) 
558               trc = new Geom2d_TrimmedCurve(pcpivot.Curve(),
559                                             Min(parCP1,parCP2),
560                                             Max(parCP1,parCP2));
561             PCurveOnPiv = Geom2dConvert::CurveToBSplineCurve(trc);
562           }
563           else {
564             PCurveOnPiv = Geom2dConvert::SplitBSplineCurve
565               (Handle(Geom2d_BSplineCurve)::DownCast(pcpivot.Curve()),
566                Min(parCP1,parCP2),Max(parCP1,parCP2),tol2d);
567           }
568           TColStd_Array1OfReal kk(1,PCurveOnPiv->NbKnots());
569           PCurveOnPiv->Knots(kk);
570           BSplCLib::Reparametrize(0.,1.,kk);
571           PCurveOnPiv->SetKnots(kk);
572           if(pcfalenvers) {
573             PCurveOnPiv->Reverse();
574             pctrans = TopAbs::Reverse(pctrans);
575           }
576         }
577         Handle(Geom_Surface) Surfcoin = fil.Surface();
578         done = CompleteData(coin,Surfcoin,
579                             HFaCo,PCurveOnFace,
580                             HFaPiv,PCurveOnPiv,OFaCo,1,
581                             0,0,0,0);
582 #ifdef DEB 
583         ChFi3d_ResultChron(ch , t_remplissage);// result perf filling 
584 #endif 
585       }
586 #ifdef DEB   
587       ChFi3d_InitChron(ch); // init perf update DS
588 #endif 
589       if (done){
590         // Update 3 CornerData and the DS
591         // ----------------------------------------
592         if(resetcp1){
593           gp_Pnt pjyl = CP1.Point();
594           Standard_Real tolsav = CP1.Tolerance();
595           CP1.Reset();
596           CP1.SetPoint(pjyl);
597           CP1.SetTolerance(tolsav);
598         }
599         else if(resetcp2){
600           gp_Pnt pjyl = CP2.Point();
601           Standard_Real tolsav = CP2.Tolerance();
602           CP2.Reset();
603           CP2.SetPoint(pjyl);
604           CP2.SetTolerance(tolsav);
605         }
606         Standard_Real P1deb,P2deb,P1fin,P2fin;
607         Standard_Integer If1,If2,Il1,Il2,Icf,Icl;
608         const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1();
609         ChFiDS_CommonPoint& Pf2 = coin->ChangeVertexFirstOnS2();
610         const ChFiDS_CommonPoint& Pl1 = coin->VertexLastOnS1();
611         ChFiDS_CommonPoint& Pl2 = coin->ChangeVertexLastOnS2();
612         Pf2 = CP1;
613         Pl2 = CP2;
614         
615         // the corner to start,
616         // -----------------------
617         ChFiDS_Regul regdeb, regfin;
618         If1 = ChFi3d_IndexPointInDS(Pf1,DStr);
619         If2 = ChFi3d_IndexPointInDS(Pf2,DStr);
620         Il1 = ChFi3d_IndexPointInDS(Pl1,DStr);
621         if(sameparam) Il2 = If2;
622         else Il2 = ChFi3d_IndexPointInDS(Pl2,DStr);
623         
624         gp_Pnt2d pp1,pp2;
625         pp1 = coin->InterferenceOnS1().PCurveOnSurf()->
626           Value(coin->InterferenceOnS1().FirstParameter());
627         pp2 = coin->InterferenceOnS2().PCurveOnSurf()->
628           Value(coin->InterferenceOnS2().FirstParameter());
629         Handle(Geom_Curve) C3d;
630         Standard_Real tolreached;
631         ChFi3d_ComputeArete(Pf1,pp1,Pf2,pp2,
632                             DStr.Surface(coin->Surf()).Surface(),C3d,
633                             corner->ChangeFirstPCurve(),P1deb,P2deb,
634                             tolesp,tol2d,tolreached,0);
635         Standard_Real par1 = sd1->Interference(IFaArc1).Parameter(isfirst1);
636         pp1 = sd1->Interference(IFaCo1).PCurveOnSurf()->Value(par1);
637         pp2 = sd1->Interference(IFaArc1).PCurveOnSurf()->Value(par1);
638         Standard_Real tolr1;
639         ChFi3d_ComputePCurv(C3d,pp1,pp2,st1->ChangePCurve(isfirst1),
640                             DStr.Surface(sd1->Surf()).Surface(),
641                             P1deb,P2deb,tolesp,tolr1);
642         tolreached = Max(tolreached,tolr1);
643         TopOpeBRepDS_Curve Tcurv1(C3d,tolreached);
644         Icf = DStr.AddCurve(Tcurv1);
645         regdeb.SetCurve(Icf);
646         regdeb.SetS1(coin->Surf(),0);
647         regdeb.SetS2(sd1->Surf(),0);
648         myRegul.Append(regdeb);
649         corner->ChangeFirstCurve(Icf);
650         corner->ChangeFirstParameters(P1deb,P2deb);
651         corner->ChangeIndexFirstPointOnS1(If1);
652         corner->ChangeIndexFirstPointOnS2(If2);
653       
654         pp1 = coin->InterferenceOnS1().PCurveOnSurf()->
655           Value(coin->InterferenceOnS1().LastParameter());
656         pp2 = coin->InterferenceOnS2().PCurveOnSurf()->
657           Value(coin->InterferenceOnS2().LastParameter());
658         ChFi3d_ComputeArete(Pl1,pp1,Pl2,pp2,
659                             DStr.Surface(coin->Surf()).Surface(),C3d,
660                             corner->ChangeLastPCurve(),P1fin,P2fin,
661                             tolesp,tol2d,tolreached,0);
662         Standard_Real par2 = sd2->Interference(IFaArc2).Parameter(isfirst2);
663         pp1 = sd2->Interference(IFaCo2).PCurveOnSurf()->Value(par2);
664         pp2 = sd2->Interference(IFaArc2).PCurveOnSurf()->Value(par2);
665         Standard_Real tolr2;
666         ChFi3d_ComputePCurv(C3d,pp1,pp2,st2->ChangePCurve(isfirst2),
667                             DStr.Surface(sd2->Surf()).Surface(),
668                             P1deb,P2deb,tolesp,tolr2);
669         tolreached = Max(tolreached,tolr2);
670         TopOpeBRepDS_Curve Tcurv2(C3d,tolreached);
671         Icl = DStr.AddCurve(Tcurv2);
672         regfin.SetCurve(Icl);
673         regfin.SetS1(coin->Surf(),0);
674         regfin.SetS2(sd2->Surf(),0);
675         myRegul.Append(regfin);
676         corner->ChangeLastCurve(Icl);
677         corner->ChangeLastParameters(P1fin,P2fin);
678         corner->ChangeIndexLastPointOnS1(Il1);
679         corner->ChangeIndexLastPointOnS2(Il2);
680         
681         coin->ChangeIndexOfS1(DStr.AddShape(FaCo));
682         if(sameparam) coin->ChangeIndexOfS2(0);
683         else {
684           coin->ChangeIndexOfS2(DStr.AddShape(FaPiv));
685           coin->ChangeInterferenceOnS2().SetTransition(pctrans);
686         }
687         corner->SetSolidIndex(st1->SolidIndex());
688         
689         // then the starting Stripe,
690         // ------------------------
691         st1->SetCurve(Icf,isfirst1);
692         st1->SetIndexPoint(If1,isfirst1,IFaCo1);
693         st1->SetIndexPoint(If2,isfirst1,IFaArc1);
694         st1->SetParameters(isfirst1,P1deb,P2deb);
695         sd1->ChangeVertex(isfirst1,IFaCo1) = Pf1;
696         sd1->ChangeVertex(isfirst1,IFaArc1) = Pf2;
697         sd1->ChangeInterference(IFaCo1).SetParameter(par1,isfirst1);
698         if (IFaCo1 == 2) st1->SetOrientation(TopAbs_REVERSED,isfirst1);
699         
700         // then the end Stripe,
701         // -------------------------
702         st2->SetCurve(Icl,isfirst2);
703         st2->SetIndexPoint(Il1,isfirst2,IFaCo2);
704         st2->SetIndexPoint(Il2,isfirst2,IFaArc2);
705         st2->SetParameters(isfirst2,P1fin,P2fin);
706         sd2->ChangeVertex(isfirst2,IFaCo2) = Pl1;
707         sd2->ChangeVertex(isfirst2,IFaArc2) = Pl2;
708         sd2->ChangeInterference(IFaCo2).SetParameter(par2,isfirst2);
709         if (IFaCo2 == 2) st2->SetOrientation(TopAbs_REVERSED,isfirst2);
710       }
711 #ifdef DEB   
712       ChFi3d_ResultChron(ch , t_t2cornerDS);// result perf update DS 
713 #endif 
714     }
715     else {
716       //it is necessary to make difference with
717       if(!OkinterCC) {
718         Standard_Failure::Raise("TwoCorner : No intersection pc pc");
719       }
720       Handle(ChFiDS_Stripe) stsam, stdif;
721       Handle(ChFiDS_SurfData) sdsam, sddif;
722       Standard_Real uintpcsam = 0., uintpcdif = 0.;
723       Standard_Integer ifacosam = 0, ifacodif = 0, ifaopsam = 0, ifaopdif = 0;
724       Standard_Boolean isfirstsam = Standard_False, isfirstdif = Standard_False;
725       if(Stat1 == ChFiDS_OnSame && Stat2 == ChFiDS_OnDiff){
726         stsam = st1; sdsam = sd1; uintpcsam = UIntPC1; 
727         ifacosam = IFaCo1; ifaopsam = IFaArc1; isfirstsam = isfirst1;
728         stdif = st2; sddif = sd2; uintpcdif = UIntPC2; 
729         ifacodif = IFaCo2; ifaopdif = IFaArc2; isfirstdif = isfirst2;
730       }
731       else if(Stat1 == ChFiDS_OnDiff && Stat2 == ChFiDS_OnSame){
732         stsam = st2; sdsam = sd2; uintpcsam = UIntPC2; 
733         ifacosam = IFaCo2; ifaopsam = IFaArc2; isfirstsam = isfirst2;
734         stdif = st1; sddif = sd1; uintpcdif = UIntPC1; 
735         ifacodif = IFaCo1; ifaopdif = IFaArc1; isfirstdif = isfirst1;
736       }
737       else {
738         Standard_Failure::Raise("TwoCorner : Config unknown");
739       }
740       //It is checked if surface ondiff has a point on arc from the side opposed
741       //to the common face and if this arc is connected to the base face  
742       //opposed to common face of the surface onsame.
743       ChFiDS_CommonPoint& cpopdif = sddif->ChangeVertex(isfirstdif,ifaopdif);
744       if(!cpopdif.IsOnArc()) {
745         Standard_Failure::Raise
746           ("TwoCorner : No point on restriction on surface OnDiff");
747       }
748       const TopoDS_Edge& Arcopdif = cpopdif.Arc();
749       const TopoDS_Face& Fopsam = TopoDS::Face(DStr.Shape(sdsam->Index(ifaopsam)));
750       TopExp_Explorer ex;
751       for(ex.Init(Fopsam,TopAbs_EDGE); ex.More(); ex.Next()){
752         if(ex.Current().IsSame(Arcopdif)) {
753           break;
754         }
755         else if(!ex.More()) {
756           Standard_Failure::Raise
757             ("TwoCorner : No common face to loop the contour");
758         }
759       }
760 #ifdef DEB 
761       ChFi3d_InitChron(ch ); // init perf filling 
762 #endif 
763       Handle(GeomFill_Boundary) Bsam,Bdif,Bfac;
764       gp_Pnt2d ppopsam = 
765         sdsam->Interference(ifaopsam).PCurveOnSurf()->Value(uintpcsam);
766       gp_Pnt2d ppcosam = 
767         sdsam->Interference(ifacosam).PCurveOnSurf()->Value(uintpcsam);
768       Handle(Geom_Surface) surfsam = DStr.Surface(sdsam->Surf()).Surface();
769       Handle(GeomAdaptor_HSurface) Hsurfsam = new GeomAdaptor_HSurface(surfsam);
770       Handle(Geom2d_Curve) pcsurfsam;
771       Bsam = ChFi3d_mkbound(Hsurfsam,pcsurfsam,ppopsam,ppcosam,tolesp,2.e-4);
772       Standard_Real upcopdif = sddif->Interference(ifaopdif).Parameter(isfirstdif);
773       gp_Pnt2d ppopdif = 
774         sddif->Interference(ifaopdif).PCurveOnSurf()->Value(upcopdif);
775       gp_Pnt2d ppcodif = 
776         sddif->Interference(ifacodif).PCurveOnSurf()->Value(uintpcdif);
777       Handle(Geom_Surface) surfdif = DStr.Surface(sddif->Surf()).Surface();
778       Handle(GeomAdaptor_HSurface) Hsurfdif = new GeomAdaptor_HSurface(surfdif);
779       Handle(Geom2d_Curve) pcsurfdif;
780       Bdif = ChFi3d_mkbound(Hsurfdif,pcsurfdif,ppcodif,ppopdif,tolesp,2.e-4);
781       gp_Pnt2d ppfacsam,ppfacdif;
782       gp_Pnt PPfacsam,PPfacdif;
783       gp_Vec VVfacsam,VVfacdif;
784       sdsam->Interference(ifaopsam).PCurveOnFace()->D0(uintpcsam,ppfacsam);
785       const Handle(Geom_Curve)& curvopsam = 
786         DStr.Curve(sdsam->Interference(ifaopsam).LineIndex()).Curve();
787       curvopsam->D1(uintpcsam,PPfacsam,VVfacsam);
788       BRepAdaptor_Curve2d PCArcFac(Arcopdif,Fopsam);
789       PCArcFac.D0(cpopdif.ParameterOnArc(),ppfacdif);
790       BRepAdaptor_Curve CArcFac(Arcopdif);
791       CArcFac.D1(cpopdif.ParameterOnArc(),PPfacdif,VVfacdif);
792       Handle(BRepAdaptor_HSurface) HBRFopsam = new BRepAdaptor_HSurface();
793       BRepAdaptor_Surface& BRFopsam = HBRFopsam->ChangeSurface();
794       BRFopsam.Initialize(Fopsam,Standard_False);
795       Handle(Geom2d_Curve) pcFopsam = ChFi3d_BuildPCurve(HBRFopsam,
796                                                          ppfacsam,VVfacsam,
797                                                          ppfacdif,VVfacdif,1);
798       Bfac = ChFi3d_mkbound(HBRFopsam,pcFopsam,tolesp,2.e-4);
799       GeomFill_ConstrainedFilling fil(8,20);
800       fil.Init(Bsam,Bdif,Bfac,1);
801 #if 0
802       for(Standard_Integer ib = 0; ib < 4; ib++){
803         if(ib == 2) continue;
804         fil.CheckCoonsAlgPatch(ib);
805         fil.CheckTgteField(ib);
806         fil.CheckApprox(ib);
807         fil.CheckResult(ib);
808       }
809 #endif
810       Handle(Geom_Surface) Surfcoin = fil.Surface();
811       TopAbs_Orientation Osurfsam = sdsam->Orientation();
812       Handle(Geom2d_Curve) pcnul;
813       done = CompleteData(coin,Surfcoin,
814                           Hsurfsam,pcsurfsam,
815                           HBRFopsam,pcnul,Osurfsam,1,
816                           0,0,0,0);
817 #ifdef DEB 
818       ChFi3d_ResultChron(ch , t_remplissage);// result perf filling 
819 #endif 
820       if(!done) Standard_Failure::Raise("concavites inverted : fail");
821 #ifdef DEB   
822       ChFi3d_InitChron(ch); // init perf update DS
823 #endif 
824       // Update 3 CornerData and the DS
825       // ----------------------------------------
826       // the corner to start,
827       // -----------------------
828       Standard_Real P1deb,P2deb,P1fin,P2fin;
829       Standard_Integer If1,If2,Il1,Il2,Icf,Icl;
830       const ChFiDS_CommonPoint& Pf1 = coin->VertexFirstOnS1();
831       ChFiDS_CommonPoint& Pf2 = coin->ChangeVertexFirstOnS2();
832       const ChFiDS_CommonPoint& Pl1 = coin->VertexLastOnS1();
833       ChFiDS_CommonPoint& Pl2 = coin->ChangeVertexLastOnS2();
834       Pf2 = Pl2 = cpopdif;
835         
836       ChFiDS_Regul regdeb, regfin;
837       If1 = ChFi3d_IndexPointInDS(Pf1,DStr);
838       If2 = ChFi3d_IndexPointInDS(Pf2,DStr);
839       Il1 = ChFi3d_IndexPointInDS(Pl1,DStr);
840       Il2 = If2;
841         
842       gp_Pnt2d pp1,pp2;
843       pp1 = coin->InterferenceOnS1().PCurveOnSurf()->
844         Value(coin->InterferenceOnS1().FirstParameter());
845       pp2 = coin->InterferenceOnS2().PCurveOnSurf()->
846         Value(coin->InterferenceOnS2().FirstParameter());
847       Handle(Geom_Curve) C3d;
848       Standard_Real tolreached;
849       ChFi3d_ComputeArete(Pf1,pp1,Pf2,pp2,
850                           DStr.Surface(coin->Surf()).Surface(),C3d,
851                           corner->ChangeFirstPCurve(),P1deb,P2deb,
852                           tolesp,tol2d,tolreached,0);
853       Standard_Real tolr1;
854       Handle(GeomAdaptor_HCurve) HC3d = new GeomAdaptor_HCurve(C3d);
855       ChFi3d_SameParameter(HC3d,pcFopsam,HBRFopsam,tolesp,tolr1);
856       tolreached = Max(tolreached,tolr1);
857       TopOpeBRepDS_Curve Tcurv1(C3d,tolreached);
858       Icf = DStr.AddCurve(Tcurv1);
859       // place the pcurve on face in the DS
860       TopAbs_Orientation OpcFopsam = sdsam->Interference(ifaopsam).Transition();
861       Standard_Integer IFopsam = sdsam->Index(ifaopsam);
862       if(isfirstsam) OpcFopsam = TopAbs::Reverse(OpcFopsam);
863       Handle(TopOpeBRepDS_SurfaceCurveInterference) 
864         interf = ChFi3d_FilCurveInDS(Icf,IFopsam,pcFopsam,OpcFopsam);
865       DStr.ChangeShapeInterferences(IFopsam).Append(interf);
866
867       regdeb.SetCurve(Icf);
868       regdeb.SetS1(coin->Surf(),0);
869       regdeb.SetS2(IFopsam,1);
870       myRegul.Append(regdeb);
871       corner->ChangeFirstCurve(Icf);
872       corner->ChangeFirstParameters(P1deb,P2deb);
873       corner->ChangeIndexFirstPointOnS1(If1);
874       corner->ChangeIndexFirstPointOnS2(If2);
875       
876       pp1 = coin->InterferenceOnS1().PCurveOnSurf()->
877         Value(coin->InterferenceOnS1().LastParameter());
878       pp2 = coin->InterferenceOnS2().PCurveOnSurf()->
879         Value(coin->InterferenceOnS2().LastParameter());
880       ChFi3d_ComputeArete(Pl1,pp1,Pl2,pp2,
881                           DStr.Surface(coin->Surf()).Surface(),C3d,
882                           corner->ChangeLastPCurve(),P1fin,P2fin,
883                           tolesp,tol2d,tolreached,0);
884       Standard_Real tolr2;
885       HC3d->ChangeCurve().Load(C3d);
886       ChFi3d_SameParameter(HC3d,pcsurfdif,Hsurfdif,tolesp,tolr2);
887       tolreached = Max(tolreached,tolr2);
888       TopOpeBRepDS_Curve Tcurv2(C3d,tolreached);
889       Icl = DStr.AddCurve(Tcurv2);
890       regfin.SetCurve(Icl);
891       regfin.SetS1(coin->Surf(),0);
892       regfin.SetS2(sddif->Surf(),0);
893       myRegul.Append(regfin);
894       corner->ChangeLastCurve(Icl);
895       corner->ChangeLastParameters(P1fin,P2fin);
896       corner->ChangeIndexLastPointOnS1(Il1);
897       corner->ChangeIndexLastPointOnS2(Il2);
898         
899       coin->ChangeIndexOfS1(-sdsam->Surf());
900       coin->ChangeIndexOfS2(0);
901
902       corner->SetSolidIndex(stsam->SolidIndex());
903         
904       // then Stripe OnSame
905       // ---------------------
906       const ChFiDS_FaceInterference& intcoin1 = coin->InterferenceOnS1();
907       stsam->SetCurve(intcoin1.LineIndex(),isfirstsam);
908       stsam->InDS(isfirstsam); // filDS already works from the corner.
909       stsam->ChangePCurve(isfirstsam) = coin->InterferenceOnS1().PCurveOnFace();
910       stsam->SetIndexPoint(If1,isfirstsam,ifaopsam);
911       stsam->SetIndexPoint(Il1,isfirstsam,ifacosam);
912       stsam->SetParameters(isfirstsam,
913                            intcoin1.FirstParameter(),
914                            intcoin1.LastParameter());
915       sdsam->ChangeVertex(isfirstsam,ifaopsam) = Pf1;
916       sdsam->ChangeVertex(isfirstsam,ifacosam) = Pl1;
917       sdsam->ChangeInterferenceOnS1().SetParameter(uintpcsam,isfirstsam);
918       sdsam->ChangeInterferenceOnS2().SetParameter(uintpcsam,isfirstsam);
919       if (ifaopsam == 2) stsam->SetOrientation(TopAbs_REVERSED,isfirstsam);
920         
921       // then Stripe OnDiff
922       // ---------------------
923       stdif->SetCurve(Icl,isfirstdif);
924       stdif->ChangePCurve(isfirstdif) = pcsurfdif;
925       stdif->SetIndexPoint(Il2,isfirstdif,ifaopdif);
926       stdif->SetIndexPoint(Il1,isfirstdif,ifacodif);
927       stdif->SetParameters(isfirstdif,P1fin,P2fin);
928       sddif->ChangeVertex(isfirstdif,ifaopdif) = Pl2;
929       sddif->ChangeVertex(isfirstdif,ifacodif) = Pl1;
930       sddif->ChangeInterference(ifacodif).SetParameter(uintpcdif,isfirstdif);
931       if (ifaopdif == 1) stdif->SetOrientation(TopAbs_REVERSED,isfirstdif);
932 #ifdef DEB   
933       ChFi3d_ResultChron(ch , t_t2cornerDS);// result perf update DS 
934 #endif 
935     }
936     if(!myEVIMap.IsBound(Vtx)){
937       TColStd_ListOfInteger li;
938       myEVIMap.Bind(Vtx,li);
939     }
940     myEVIMap.ChangeFind(Vtx).Append(coin->Surf());
941     myListStripe.Append(corner);
942   }
943 }  
944