0030153: Visualization, TKOpenGl - AIS_ColoredShape::SynchronizeAspects() doesn't...
[occt.git] / src / ChFi3d / ChFi3d_Builder_SpKP.cxx
1 // Created on: 1994-01-20
2 // Created by: Isabelle GRIGNON
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 <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_HSurface.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
21 #include <AppBlend_Approx.hxx>
22 #include <Blend_CurvPointFuncInv.hxx>
23 #include <Blend_FuncInv.hxx>
24 #include <Blend_Function.hxx>
25 #include <Blend_RstRstFunction.hxx>
26 #include <Blend_SurfCurvFuncInv.hxx>
27 #include <Blend_SurfPointFuncInv.hxx>
28 #include <Blend_SurfRstFunction.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepAdaptor_Curve2d.hxx>
31 #include <BRepAdaptor_HCurve.hxx>
32 #include <BRepAdaptor_HCurve2d.hxx>
33 #include <BRepAdaptor_HSurface.hxx>
34 #include <BRepBlend_Line.hxx>
35 #include <BRepTopAdaptor_TopolTool.hxx>
36 #include <ChFi3d_Builder.hxx>
37 #include <ChFi3d_Builder_0.hxx>
38 #include <ChFiDS_CommonPoint.hxx>
39 #include <ChFiDS_HElSpine.hxx>
40 #include <ChFiDS_Spine.hxx>
41 #include <ChFiDS_Stripe.hxx>
42 #include <ChFiDS_SurfData.hxx>
43 #include <ChFiKPart_RstMap.hxx>
44 #include <ElCLib.hxx>
45 #include <ElSLib.hxx>
46 #include <Geom2d_BezierCurve.hxx>
47 #include <Geom2d_BSplineCurve.hxx>
48 #include <Geom2d_Curve.hxx>
49 #include <Geom2d_Line.hxx>
50 #include <Geom2dAdaptor_Curve.hxx>
51 #include <Geom2dAdaptor_HCurve.hxx>
52 #include <Geom2dHatch_Hatcher.hxx>
53 #include <Geom2dHatch_Intersector.hxx>
54 #include <Geom_Curve.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_Surface.hxx>
57 #include <GeomAbs_CurveType.hxx>
58 #include <GeomAbs_SurfaceType.hxx>
59 #include <GeomAdaptor_Curve.hxx>
60 #include <GeomAdaptor_HSurface.hxx>
61 #include <gp.hxx>
62 #include <gp_Circ.hxx>
63 #include <gp_Dir2d.hxx>
64 #include <gp_Pnt.hxx>
65 #include <gp_Pnt2d.hxx>
66 #include <HatchGen_Domain.hxx>
67 #include <HatchGen_PointOnElement.hxx>
68 #include <HatchGen_PointOnHatching.hxx>
69 #include <Precision.hxx>
70 #include <Standard_ConstructionError.hxx>
71 #include <Standard_NoSuchObject.hxx>
72 #include <Standard_NotImplemented.hxx>
73 #include <Standard_OutOfRange.hxx>
74 #include <TColgp_Array1OfPnt2d.hxx>
75 #include <TColStd_Array1OfInteger.hxx>
76 #include <TColStd_Array1OfReal.hxx>
77 #include <TColStd_SequenceOfInteger.hxx>
78 #include <TopExp.hxx>
79 #include <TopoDS_Edge.hxx>
80 #include <TopoDS_Face.hxx>
81 #include <TopoDS_Shape.hxx>
82 #include <TopoDS_Vertex.hxx>
83 #include <TopOpeBRepBuild_HBuilder.hxx>
84 #include <TopOpeBRepDS_Curve.hxx>
85 #include <TopOpeBRepDS_HDataStructure.hxx>
86 #include <TopOpeBRepDS_Surface.hxx>
87
88 #ifdef OCCT_DEBUG
89 extern Standard_Boolean ChFi3d_GettraceDRAWFIL();
90 extern void ChFi3d_CheckSurfData(const TopOpeBRepDS_DataStructure& DStr,
91                                  const Handle(ChFiDS_SurfData)& Data);
92 #endif
93 //=======================================================================
94 //function : CompTra
95 //purpose  : Calculate the Transition from start point.
96 //=======================================================================
97
98 static TopAbs_Orientation CompTra (const TopAbs_Orientation O1,
99                                    const TopAbs_Orientation O2,
100                                    const Standard_Boolean isfirst)
101 {
102   if(isfirst) return TopAbs::Reverse(TopAbs::Compose(O1,O2));
103   else return TopAbs::Compose(O1,O2);
104 }
105
106
107 //=======================================================================
108 //function : CompCommonpoint
109 //purpose  : Fill the commonpoint in case of a vertex.
110 //=======================================================================
111
112 static void CompCommonPoint (ChFiDS_CommonPoint& FilPoint, 
113                              const TopoDS_Edge& arc,
114                              const HatchGen_PointOnElement& PE,
115                              const TopAbs_Orientation Or)
116 {
117   TopAbs_Orientation pos = PE.Position();
118   TopoDS_Vertex V;
119   if ( pos == TopAbs_FORWARD ) {
120     V = TopExp::FirstVertex(arc);
121   }
122   else {
123     V = TopExp::LastVertex(arc);
124   }
125   FilPoint.SetVertex(V);
126   FilPoint.SetArc(Precision::PIntersection(),arc,
127                   PE.Parameter(),TopAbs::Compose(arc.Orientation(),Or));
128 }
129
130
131 //=======================================================================
132 //function : CpInterf
133 //purpose  : Construct new SurfData sharing faces, surface and curves.  
134 //=======================================================================
135
136 static ChFiDS_FaceInterference CpInterf (TopOpeBRepDS_DataStructure&    DStr,
137                                          const ChFiDS_FaceInterference& FI)
138 {
139   ChFiDS_FaceInterference newF = FI;
140   const TopOpeBRepDS_Curve& toc = DStr.Curve(FI.LineIndex());
141   Handle(Geom_Curve) newC;
142   if (!toc.Curve().IsNull()) 
143     newC = Handle(Geom_Curve)::DownCast(toc.Curve()->Copy());
144   newF.SetLineIndex(DStr.AddCurve(TopOpeBRepDS_Curve(newC,toc.Tolerance())));
145   
146   if (!FI.PCurveOnFace().IsNull())
147     newF.ChangePCurveOnFace() = 
148       Handle(Geom2d_Curve)::DownCast(FI.PCurveOnFace()->Copy());
149   if (!FI.PCurveOnSurf().IsNull())
150     newF.ChangePCurveOnSurf() = 
151       Handle(Geom2d_Curve)::DownCast(FI.PCurveOnSurf()->Copy());
152   return newF;
153 }
154
155
156 //=======================================================================
157 //function : CpSD
158 //purpose  : Construct new SurfData sharing faces, surface and curves.  
159 //=======================================================================
160
161 static Handle(ChFiDS_SurfData) CpSD (      TopOpeBRepDS_DataStructure&         DStr,
162                                      const Handle(ChFiDS_SurfData)& Data)
163 {
164   Handle(ChFiDS_SurfData) newData = new ChFiDS_SurfData();
165   const TopOpeBRepDS_Surface& tos = DStr.Surface(Data->Surf());
166   Handle(Geom_Surface) newS = Handle(Geom_Surface)::DownCast(tos.Surface()->Copy());
167   Standard_Real tol = tos.Tolerance();
168   newData->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(newS,tol)));
169   newData->ChangeIndexOfS1(Data->IndexOfS1());
170   newData->ChangeIndexOfS2(Data->IndexOfS2());
171   newData->ChangeOrientation() = Data->Orientation();
172   newData->ChangeInterferenceOnS1() = CpInterf(DStr,Data->InterferenceOnS1());
173   newData->ChangeInterferenceOnS2() = CpInterf(DStr,Data->InterferenceOnS2());
174   return newData;
175 }
176
177 //=======================================================================
178 //function : AdjustParam
179 //purpose  : 
180 //=======================================================================
181
182 static Standard_Boolean AdjustParam(const HatchGen_Domain& Dom,
183                                     Standard_Real& f,
184                                     Standard_Real& l,
185                                     const Standard_Real wref,
186                                     const Standard_Real period,
187                                     const Standard_Real pitol)
188 {
189   if(Dom.HasFirstPoint())
190     f = Dom.FirstPoint().Parameter();
191   else f = 0.;
192   if(Dom.HasSecondPoint())
193     l = Dom.SecondPoint().Parameter();  
194   else l = period;
195   if (period == 0.) return Standard_False;
196   
197   f = ElCLib::InPeriod(f,wref - pitol, wref + period - pitol);
198   l = ElCLib::InPeriod(l,wref + pitol, wref + period + pitol);
199   if (l < f) {
200     f -= period; 
201     return Standard_True;
202   }
203   return Standard_False;
204 }
205 //=======================================================================
206 //function : ComputeAbscissa
207 //purpose  : 
208 //=======================================================================
209
210 static Standard_Real ComputeAbscissa(const BRepAdaptor_Curve& C,
211                                      const Standard_Real U) 
212 {
213   switch (C.GetType()) {
214   case GeomAbs_Line:
215     return U;
216   case GeomAbs_Circle:
217     return C.Circle().Radius()*U;
218   default:
219     return 0;
220   }    
221 }
222
223 //=======================================================================
224 //function : ParamOnSpine
225 //purpose  : 
226 //=======================================================================
227
228 static Standard_Real ParamOnSpine(const TopOpeBRepDS_DataStructure& DStr,
229                                   const Standard_Real               ptg,
230                                   const Handle(ChFiDS_SurfData)&    CD,
231                                   const Handle(ChFiDS_Spine)&       Spine,
232                                   const Standard_Integer            iedge,
233                                   const Standard_Boolean            intf,
234                                   const Standard_Boolean            intl,
235                                   const Standard_Real               tol,
236                                   Standard_Boolean&                 pok) 
237 {
238   Standard_Real Nl;
239   Standard_Real f = Spine->FirstParameter(iedge);
240   Standard_Real l = Spine->LastParameter(iedge);
241   
242   Nl = ComputeAbscissa(Spine->CurrentElementarySpine(iedge),ptg) + f;
243   if ((Nl >= (f - tol) || intf) && 
244       (Nl <= (l + tol) || intl) ) {
245     pok = 1;
246     return Nl;
247   }
248   else {
249     //construction of the plane containing the section of CD with parameter ptg.
250     gp_Pnt PP;
251     gp_Vec VV;
252     Handle(Geom_Curve) c3d;
253     if (CD->InterferenceOnS1().LineIndex() != 0) {
254       c3d = DStr.Curve(CD->InterferenceOnS1().LineIndex()).Curve();
255     }
256     if(c3d.IsNull()) {
257       c3d = DStr.Curve(CD->InterferenceOnS2().LineIndex()).Curve();
258     }
259     c3d->D1(ptg,PP,VV);
260     
261     gp_Pln nlp(PP,gp_Dir(VV));
262     Handle(Geom_Plane) pln = new Geom_Plane(nlp);
263     Handle(GeomAdaptor_HSurface) 
264       plan = new GeomAdaptor_HSurface(GeomAdaptor_Surface(pln));
265     
266     // intersection plane spine.
267     Standard_Boolean found = Standard_False;
268     Standard_Boolean fini  = Standard_False;
269     Standard_Integer sens = 1;
270     if (Nl <= f) sens = -1;
271     Standard_Integer ii = iedge + sens;
272     if (Spine->IsPeriodic()) {
273       if (ii <= 0) ii += Spine->NbEdges();
274       if (ii >  Spine->NbEdges()) ii -= Spine->NbEdges();
275     } 
276     else if(ii < 1 || ii >  Spine->NbEdges()) {
277       pok = 1;
278       return Nl;
279     }
280     Handle(BRepAdaptor_HCurve) HE = new BRepAdaptor_HCurve();
281     BRepAdaptor_Curve& CE = HE->ChangeCurve();
282     
283     while (!found && !fini) {
284       TopAbs_Orientation O = Spine->Edges(ii).Orientation();
285       Standard_Boolean First = ((O == TopAbs_FORWARD && sens == 1) || 
286                                 (O == TopAbs_REVERSED && sens == -1));
287       CE.Initialize(Spine->Edges(ii));
288       Standard_Real tolc = CE.Resolution(tol);
289       found = ChFi3d_InterPlaneEdge(plan,HE,Nl,First,tolc);
290       gp_Pnt point = CE.Value(Nl);
291 #ifdef OCCT_DEBUG
292       cout<<"******* ParamOnSpine() for edge "<<iedge<<endl;
293       cout<<Nl<<endl;
294       cout<<"point ped "<<point.X()<<" "<<point.Y()<<" "<<point.Z()<<endl;
295 #endif
296       if(found) Nl = Spine->Absc(Nl,ii);
297       point = Spine->Value(Nl);
298 #ifdef OCCT_DEBUG
299       if (found) cout << "found by edge " << ii << " : ";
300       cout<<Nl<<endl;
301       cout<<"point psp "<<point.X()<<" "<<point.Y()<<" "<<point.Z()<<endl;
302       cout<<endl;
303 #endif
304       
305       ii +=sens;
306       if (Spine->IsPeriodic()) {
307         if (ii <= 0) ii += Spine->NbEdges();
308         if (ii >  Spine->NbEdges()) ii -= Spine->NbEdges();
309         fini = (ii == iedge);
310       } 
311       else {
312         fini = (ii < 1 || ii >  Spine->NbEdges());
313       }
314     }
315     pok = found;
316     return Nl; 
317   }
318 }
319
320 //=======================================================================
321 //function : YaUnVoisin
322 //purpose  : 
323 //=======================================================================
324
325 static Standard_Boolean YaUnVoisin(const Handle(ChFiDS_Spine)& Spine,
326                                    const Standard_Integer      iedge,
327                                    Standard_Integer&           ivois,
328                                    const Standard_Boolean      isfirst)
329 {
330   Standard_Integer nbed = Spine->NbEdges();
331   if(nbed == 1) return 0;
332   Standard_Boolean periodic = Spine->IsPeriodic();
333   if(isfirst) ivois = iedge - 1;
334   else ivois = iedge + 1;
335   if(periodic) {
336     if(ivois == 0) ivois = nbed;
337     if(ivois == nbed+1) ivois = 1;
338   }
339   return (ivois > 0 && ivois <= nbed);
340 }
341
342 //=======================================================================
343 //function : Trunc
344 //purpose  : 
345 //=======================================================================
346
347 void ChFi3d_Builder::Trunc(const Handle(ChFiDS_SurfData)&    SD,
348                            const Handle(ChFiDS_Spine)&       Spine,
349                            const Handle(Adaptor3d_HSurface)&   S1, 
350                            const Handle(Adaptor3d_HSurface)&   S2, 
351                            const Standard_Integer            iedge,
352                            const Standard_Boolean            isfirst,
353                            const Standard_Integer            cntlFiOnS)
354 {
355   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
356   // Return points and tangents on edge and spine.
357   Standard_Real wtg = SD->InterferenceOnS1().Parameter(isfirst);
358   Standard_Boolean bid;
359   Standard_Real wsp = ParamOnSpine(DStr,wtg,SD,Spine,iedge,0,0,tolesp,bid);
360   gp_Pnt ped,psp;
361   gp_Vec ded,dsp;
362   TopoDS_Vertex bout1,bout2,boutemp;
363
364   
365   const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge);
366 //Modif against Vertex isolated on spine
367   TopoDS_Edge support = bc.Edge();
368   TopExp::Vertices(support,bout1,bout2);
369   if (support.Orientation() == TopAbs_REVERSED) {
370     boutemp = bout2;
371     bout2 = bout1;
372     bout1 = boutemp;
373   }
374   if (!isfirst) {
375     bout1 = bout2;
376   }
377 //finmodif
378   Standard_Real edf = bc.FirstParameter(), edl = bc.LastParameter();
379   Standard_Real edglen = edl - edf;
380   if(Spine->Edges(iedge).Orientation() == TopAbs_FORWARD) {
381     bc.D1(wtg+edf,ped,ded);
382   }
383   else{ 
384     bc.D1(-wtg+edl,ped,ded);
385     ded.Reverse();
386   }
387   Spine->D1(wsp,psp,dsp);
388   gp_Pnt p1,p2;
389   const Handle(Geom_Surface)& surf = DStr.Surface(SD->Surf()).Surface();
390   gp_Pnt2d pp1,pp2;
391   pp1 = SD->InterferenceOnS1().PCurveOnSurf()->Value(wtg);
392   pp2 = SD->InterferenceOnS2().PCurveOnSurf()->Value(wtg);
393   p1 = surf->Value(pp1.X(),pp1.Y());
394   p2 = surf->Value(pp2.X(),pp2.Y());
395   Standard_Boolean tron = Standard_False;
396   Standard_Real Ang = dsp.Angle(ded);
397   Standard_Real dis1 = psp.Distance(ped);
398   Standard_Real dis2 = p1.Distance(p2);
399   if(Ang > M_PI/18.) tron = Standard_True;
400   if(dis1 >= 0.1*dis2) tron = Standard_True;
401   Standard_Integer ivois;
402   if(!tron && YaUnVoisin(Spine,iedge,ivois,isfirst)) {
403     Handle(BRepAdaptor_HSurface) BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1);
404     Handle(BRepAdaptor_HSurface) BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2);
405     if(!BS1.IsNull() && !BS2.IsNull()) {
406       TopoDS_Face FBID;
407       TopoDS_Face F1 = BS1->ChangeSurface().Face();
408       TopoDS_Face F2 = BS2->ChangeSurface().Face();
409       const ChFiDS_CommonPoint& cp1 = SD->Vertex(isfirst,1);
410       const ChFiDS_CommonPoint& cp2 = SD->Vertex(isfirst,2);
411       if(!((cp1.IsOnArc() && SearchFace(Spine,cp1,F1,FBID)) ||
412            (cp2.IsOnArc() && SearchFace(Spine,cp2,F2,FBID)))) { 
413         tron = ChFi3d_KParticular(Spine,ivois,BS1->ChangeSurface(),BS2->ChangeSurface());
414       }
415     }
416   }
417   //modification of lvt against isolated vertex
418   if(!tron && YaUnVoisin(Spine,iedge,ivois,isfirst)) {
419     TopTools_ListIteratorOfListOfShape It;
420     Standard_Integer nbed = -2;
421     for (It.Initialize(myVEMap(bout1));It.More();It.Next()) {
422       nbed++;
423     }
424     if(nbed<3) tron = Standard_True;
425   }
426 //finmodif
427
428   if(tron) {
429     Standard_Real par = 0., x, y, dPar=0;
430     if(!isfirst) par = edglen;
431     if (cntlFiOnS) {
432       // detect the case where FaceInterference ends before the place we are
433       // going to truncate SD. Then we cut so that FaceInterference length to
434       // be at least zero, not negative (eap, occ354)
435       Standard_Real fiPar = SD->Interference(cntlFiOnS).Parameter(!isfirst);
436       Standard_Boolean isTheCase = isfirst ? (par > fiPar) : (par < fiPar);
437       if (isTheCase) {
438         dPar = par - fiPar;
439         par = fiPar;
440       }
441     }
442     for (Standard_Integer i = 1; i <= 2; i++) { 
443       SD->ChangeInterference(i).SetParameter(par,isfirst);
444       Handle(Geom2d_Curve) pc = SD->Interference(i).PCurveOnSurf();
445       pc->Value(par).Coord(x,y);
446       SD->ChangeVertex(isfirst,i).Reset();
447       SD->ChangeVertex(isfirst,i).SetPoint(surf->Value(x,y));
448       if(isfirst) SD->FirstSpineParam(Spine->FirstParameter(iedge)-dPar);
449       else        SD->LastSpineParam (Spine->LastParameter(iedge) -dPar);
450     }
451   }
452 }
453
454 //=======================================================================
455 //function : ResetProl
456 //purpose  : 
457 //=======================================================================
458
459 static Standard_Real ResetProl(const TopOpeBRepDS_DataStructure& DStr,
460                                const Handle(ChFiDS_SurfData)&    CD,
461                                const Handle(ChFiDS_Spine)&       Spine,
462                                const Standard_Integer            iedge,
463                                const Standard_Boolean            isfirst)
464 {
465   const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge);
466   Standard_Real edglen = bc.LastParameter() - bc.FirstParameter();
467   const Handle(Geom_Surface)& surf = DStr.Surface(CD->Surf()).Surface();
468   Standard_Real par = 0., x, y;
469   if(!isfirst) par = edglen;
470   Standard_Real sppar = 0.;
471   for (Standard_Integer i = 1; i <= 2; i++) { 
472     CD->ChangeInterference(i).SetParameter(par,isfirst);
473     Handle(Geom2d_Curve) pc = CD->Interference(i).PCurveOnSurf();
474     pc->Value(par).Coord(x,y);
475     CD->ChangeVertex(isfirst,i).Reset();
476     CD->ChangeVertex(isfirst,i).SetPoint(surf->Value(x,y));
477     if(isfirst) {
478       sppar = Spine->FirstParameter(iedge);
479       CD->FirstSpineParam(sppar);
480     }
481     else{
482       sppar = Spine->LastParameter(iedge);
483       CD->LastSpineParam (sppar);
484     }
485   }
486   return sppar;
487 }
488 //=======================================================================
489 //function : Tri
490 //purpose  : 
491 //=======================================================================
492
493 static Standard_Boolean Tri(const Geom2dHatch_Hatcher& H,
494                             const Standard_Integer     iH,
495                             TColStd_Array1OfInteger&   Ind,
496                             const Standard_Real        wref,
497                             const Standard_Real        period,
498                             const Standard_Real        pitol,
499                             Standard_Integer&    Nbdom)
500 {
501 //  for (Standard_Integer i = 1; i <= Nbdom; i++) { Ind(i) = i; }
502   Standard_Integer i;
503   for ( i = 1; i <= Nbdom; i++) { Ind(i) = i; }
504   Standard_Real f1,f2,l;
505   Standard_Integer tmp;
506   Standard_Boolean Invert = Standard_True;
507   
508   while (Invert) {
509     Invert = Standard_False;
510     for ( i = 1; i < Nbdom; i++) {
511       AdjustParam(H.Domain(iH,Ind(i)),f1,l,wref,period,pitol);
512       AdjustParam(H.Domain(iH,Ind(i+1)),f2,l,wref,period,pitol);
513       if ( f2 < f1) {
514         tmp = Ind(i);
515         Ind(i) = Ind(i+1);
516         Ind(i+1) = tmp;
517         Invert = Standard_True;
518       }
519     }
520   }
521   
522   Standard_Integer iSansFirst = 0, iSansLast = 0;
523   
524   if (Nbdom != 1) {
525     for ( i = 1; i <= Nbdom; i++) {
526       if (!H.Domain(iH,Ind(i)).HasFirstPoint()) {
527         iSansFirst = i;
528       }
529       if (!H.Domain(iH,Ind(i)).HasSecondPoint()) {
530         iSansLast = i;
531       }
532     }
533   }
534   if (iSansFirst != 0) {
535     if (iSansLast == 0) {
536 #ifdef OCCT_DEBUG
537       cout<<"Parsing : Pb of Hatcher"<<endl;
538 #endif
539       return 0;
540     }
541     HatchGen_Domain* Dom = ((HatchGen_Domain*) (void*) &H.Domain(iH,Ind(iSansFirst)));    
542     HatchGen_PointOnHatching* PH = 
543       ((HatchGen_PointOnHatching*) (void*) &H.Domain(iH,Ind(iSansLast)).FirstPoint());
544     Standard_Real NewPar = H.HatchingCurve(iH).FirstParameter() - period +
545       H.Domain(iH,Ind(iSansLast)).FirstPoint().Parameter();
546     PH->SetParameter(NewPar);
547     Dom->SetFirstPoint(*PH);
548     
549     for (Standard_Integer k = iSansLast; k < Nbdom; k++) {
550       Ind(k) = Ind(k+1);
551     }
552     Nbdom--;
553   }
554   return 1;
555 }
556
557 //=======================================================================
558 //function : FillSD
559 //purpose  : 
560 //=======================================================================
561
562 static void FillSD (TopOpeBRepDS_DataStructure& DStr,
563                     Handle(ChFiDS_SurfData)&    CD,
564                     ChFiKPart_RstMap&           M,
565                     const HatchGen_Domain&      Dom,
566                     const Standard_Real         ponH,
567                     const Standard_Boolean      isFirst,
568                     const Standard_Integer      ons,
569                     const Standard_Real         pitol,
570                     const TopoDS_Vertex         bout)
571      
572 {  
573   Standard_Integer opp = 3 - ons;
574   ChFiDS_CommonPoint& Pons = CD->ChangeVertex(isFirst,ons); 
575   ChFiDS_CommonPoint& Popp = CD->ChangeVertex(isFirst,opp);   
576   
577   const HatchGen_PointOnHatching* pPH = 0;
578   if(isFirst && Dom.HasFirstPoint()) {
579     const HatchGen_PointOnHatching& PHtemp = Dom.FirstPoint();
580     pPH = &PHtemp;
581   }
582   else if(!isFirst && Dom.HasSecondPoint()) {
583     const HatchGen_PointOnHatching& PHtemp = Dom.SecondPoint();
584     pPH = &PHtemp;
585   }
586   Standard_Real x,y;
587   Handle(Geom_Surface) Surf = DStr.Surface(CD->Surf()).Surface();
588   if(pPH == 0) {
589     CD->ChangeInterference(ons).SetParameter(ponH,isFirst);
590     Handle(Geom2d_Curve) pcons = CD->Interference(ons).PCurveOnSurf();
591     pcons->Value(ponH).Coord(x,y);
592     CD->ChangeVertex(isFirst,ons).SetPoint(Surf->Value(x,y));
593   }
594   else {
595 //Modification to find already existing vertexes
596     Standard_Integer LeType = 1;
597     Standard_Integer NbInt = pPH->NbPoints();
598     if (NbInt>1) {
599       Standard_Boolean trouve = Standard_True;
600       Standard_Integer IE;
601       TopoDS_Vertex V1 , V2;
602       Standard_Boolean suite = Standard_True;
603       for(;trouve;) {
604         const HatchGen_PointOnElement& PEtemp = pPH->Point(LeType);
605         IE = PEtemp.Index();
606         Handle(BRepAdaptor_HCurve2d) HE = Handle(BRepAdaptor_HCurve2d)::DownCast(M(IE));
607         if(!HE.IsNull()) {
608           const TopoDS_Edge& Etemp = HE->ChangeCurve2d().Edge();
609           TopExp::Vertices(Etemp,V1,V2);
610         }
611         else {
612           suite = Standard_False;
613         }
614         if(((V1.IsSame(bout)) || (V2.IsSame(bout))) && suite) {
615           trouve = Standard_True;
616           break;
617         }
618         else {
619           suite = Standard_True;
620           trouve = Standard_False;
621           LeType++;
622           if(LeType>NbInt) {
623             trouve = Standard_True;
624             LeType = 1;
625           }
626         }
627       }
628     }
629     const HatchGen_PointOnElement& PE = pPH->Point(LeType);
630     Standard_Integer IE = PE.Index();
631     Handle(BRepAdaptor_HCurve2d) 
632       HE = Handle(BRepAdaptor_HCurve2d)::DownCast(M(IE));
633     if(HE.IsNull()) return;
634     const TopoDS_Edge& E = HE->ChangeCurve2d().Edge();
635     
636     if (PE.Position() != TopAbs_INTERNAL) {
637       TopAbs_Orientation O = CD->Interference(ons).Transition();
638       if(isFirst) O = TopAbs::Reverse(O);
639       CompCommonPoint(Pons,E,PE,O);
640     }
641     else{
642       Pons.SetArc(pitol,E,PE.Parameter(),
643                   CompTra(CD->Interference(ons).Transition(),E.Orientation(),isFirst));
644     }
645     Handle(Geom2d_Curve) pcadj = CD->Interference(ons).PCurveOnSurf();
646     pcadj->Value(ponH).Coord(x,y);
647     CD->ChangeInterference(ons).SetParameter(ponH,isFirst);
648     CD->ChangeVertex(isFirst,ons).SetPoint(Surf->Value(x,y));
649   }
650   if(!Popp.IsOnArc()) {
651     CD->ChangeInterference(opp).SetParameter(ponH,isFirst);
652     Handle(Geom2d_Curve) pcopp = CD->Interference(opp).PCurveOnSurf();
653     pcopp->Value(ponH).Coord(x,y);
654     CD->ChangeVertex(isFirst,opp).SetPoint(Surf->Value(x,y));
655   }
656 }
657
658 //=======================================================================
659 //function : SplitKPart
660 //purpose  : Reconstruct SurfData depending on restrictions of faces.
661 //=======================================================================
662
663 Standard_Boolean ChFi3d_Builder::SplitKPart
664   (const Handle(ChFiDS_SurfData)&   Data, 
665    ChFiDS_SequenceOfSurfData&       SetData, 
666    const Handle(ChFiDS_Spine)&      Spine,
667    const Standard_Integer           Iedge,
668    const Handle(Adaptor3d_HSurface)&  S1, 
669    const Handle(Adaptor3d_TopolTool)& I1, 
670    const Handle(Adaptor3d_HSurface)&  S2,
671    const Handle(Adaptor3d_TopolTool)& I2, 
672    Standard_Boolean&                intf,
673    Standard_Boolean&                intl)
674 {
675   //The the hatching of each faces is started by tangency lines.
676   
677   Standard_Real pitol = Precision::PIntersection();
678   
679   ChFiKPart_RstMap M1, M2;
680   Standard_Integer iH1 = 0,iH2 = 0;
681   Standard_Integer  Nb1 = 1,Nb2 = 1;
682   
683   // Cutting of tangency lines (hatching).
684   Geom2dHatch_Intersector Inter(pitol,pitol);
685   Geom2dHatch_Hatcher H1(Inter,tol2d,tolesp), H2(Inter,tol2d,tolesp);
686   Standard_Integer ie;
687   Handle(Geom2d_Curve) C1 = Data->InterferenceOnS1().PCurveOnFace(); 
688   Geom2dAdaptor_Curve  ll1;
689   if (!C1.IsNull()) {
690     ll1.Load(C1);
691     for(I1->Init(); I1->More(); I1->Next()) {
692       Handle(BRepAdaptor_HCurve2d) 
693         Bc = Handle(BRepAdaptor_HCurve2d)::DownCast(I1->Value());
694       Handle(Geom2dAdaptor_HCurve) 
695         Gc = Handle(Geom2dAdaptor_HCurve)::DownCast(I1->Value());
696       if(Bc.IsNull()) ie = H1.AddElement(Gc->ChangeCurve2d(),TopAbs_FORWARD);
697       else ie = H1.AddElement(Bc->ChangeCurve2d(),
698                               Bc->ChangeCurve2d().Edge().Orientation());
699       M1.Bind(ie,I1->Value());
700     }
701     iH1 = H1.Trim(ll1);
702     H1.ComputeDomains(iH1);
703     if(!H1.IsDone(iH1)) return 0;
704     Nb1 = H1.NbDomains(iH1);
705     if(Nb1 == 0) {
706 #ifdef OCCT_DEBUG
707       cout<<"SplitKPart : tangency line out of the face"<<endl;
708 #endif
709       return Standard_False;
710     }
711   }
712   
713   Handle(Geom2d_Curve) C2 = Data->InterferenceOnS2().PCurveOnFace(); 
714   Geom2dAdaptor_Curve  ll2;
715   if (!C2.IsNull()) {
716     ll2.Load(C2);
717     for(I2->Init(); I2->More(); I2->Next()) {
718       Handle(BRepAdaptor_HCurve2d) 
719         Bc = Handle(BRepAdaptor_HCurve2d)::DownCast(I2->Value());
720       Handle(Geom2dAdaptor_HCurve) 
721         Gc = Handle(Geom2dAdaptor_HCurve)::DownCast(I2->Value());
722       if(Bc.IsNull()) ie = H2.AddElement(Gc->ChangeCurve2d(),TopAbs_FORWARD);
723       else ie = H2.AddElement(Bc->ChangeCurve2d(),
724                               Bc->ChangeCurve2d().Edge().Orientation());
725       M2.Bind(ie,I2->Value());
726     }
727     iH2 = H2.Trim(ll2);
728     H2.ComputeDomains(iH2);
729     if(!H2.IsDone(iH2)) return 0;
730     Nb2 = H2.NbDomains(iH2);
731     if(Nb2 == 0) {
732 #ifdef OCCT_DEBUG
733       cout<<"SplitKPart : tangency line out of the face"<<endl;
734 #endif
735       return Standard_False;
736     }
737   }
738
739   //Return start and end vertexes of the Spine
740   TopoDS_Vertex bout1,bout2,boutemp;
741   const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(Iedge);
742   TopoDS_Edge support = bc.Edge();
743   TopExp::Vertices(support,bout1,bout2);
744   if(support.Orientation() == TopAbs_REVERSED) {
745     boutemp = bout2;
746     bout2 = bout1;
747     bout1 = boutemp;
748   }
749   
750   // Return faces.
751   TopoDS_Face F1, F2;
752   Handle(BRepAdaptor_HSurface) 
753     bhs = Handle(BRepAdaptor_HSurface)::DownCast(S1);
754   if(!bhs.IsNull()) F1 = bhs->ChangeSurface().Face();
755   bhs = Handle(BRepAdaptor_HSurface)::DownCast(S2);
756   if(!bhs.IsNull()) F2 = bhs->ChangeSurface().Face();
757   TopoDS_Face FBID;
758   
759   // Restriction of SurfDatas by cut lines.
760   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
761   Handle(ChFiDS_SurfData) CD = Data;
762   CD->ChangeIndexOfS1(DStr.AddShape(F1));
763   CD->ChangeIndexOfS2(DStr.AddShape(F2));
764   
765   Standard_Real f1,l1,f2,l2;
766   TColStd_Array1OfInteger Ind1(1,Nb1), Ind2(1,Nb2); 
767   Standard_Real wref = 0.;
768
769   Standard_Integer onS = 1; // switcher of access to surfs of SurfData, eap occ293
770   Standard_Integer cntlFiOnS = 0; // FaceInterference to control length in OnSame
771                                   // situation, eap occ354
772   
773   if (C1.IsNull() && C2.IsNull()) {
774 #ifdef OCCT_DEBUG
775     cout<<"SplitData : 2 zero lines hatching impossible"<<endl;
776 #endif
777     return Standard_False;
778   }
779   else if (C1.IsNull() || (Nb1 == 1 && !H1.Domain(iH1,1).HasFirstPoint())) {   
780     // It is checked if the point 2d of the degenerated edge is in the face.
781     if (C1.IsNull()) {
782       gp_Pnt2d p2d1 = CD->Get2dPoints(0,1);
783       TopAbs_State situ = I1->Classify(p2d1,1.e-8,0);
784       if(situ == TopAbs_OUT) return Standard_False;
785     }
786
787     // Parsing of domains by increasing parameters,
788     if(!Tri(H2,iH2,Ind2,wref,0.,pitol,Nb2)) return 0;
789     // Filling of SurfData
790     for(Standard_Integer i = 1; i <= Nb2; i++) {
791       const HatchGen_Domain& Dom2 = H2.Domain(iH2,Ind2(i));
792       FillSD(DStr,CD,M2,Dom2,Dom2.FirstPoint().Parameter(),1,2,pitol,bout1);
793       FillSD(DStr,CD,M2,Dom2,Dom2.SecondPoint().Parameter(),0,2,pitol,bout2);
794       SetData.Append(CD);
795       CD = CpSD(DStr,CD);
796     }
797     if(intf) {
798       Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(1);
799       ChFiDS_CommonPoint& CP2 = sd->ChangeVertexFirstOnS2();
800       if(CP2.IsOnArc() && Spine->FirstStatus() == ChFiDS_OnSame) {
801         intf = !SearchFace(Spine,CP2,F2,FBID);
802       }
803       else intf = Standard_False;
804     }
805     if(intl) {
806       Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(SetData.Length());
807       ChFiDS_CommonPoint& CP2 = sd->ChangeVertexLastOnS2();
808       if(CP2.IsOnArc() && Spine->LastStatus() == ChFiDS_OnSame) {
809         intl = !SearchFace(Spine,CP2,F2,FBID);
810       }
811       else intl = Standard_False;
812     }
813   }
814   else if (C2.IsNull() || (Nb2 == 1 && !H2.Domain(iH2,1).HasFirstPoint())) { 
815     // It is checked if the point 2d of the degenerated is in the face.
816     if (C2.IsNull()) {
817       gp_Pnt2d p2d2 = CD->Get2dPoints(0,2);
818       TopAbs_State situ = I2->Classify(p2d2,1.e-8,0);
819       if(situ == TopAbs_OUT) return Standard_False;
820     }
821
822     // Parsing of domains by increasing parameters,
823     if(!Tri(H1,iH1,Ind1,wref,0.,pitol,Nb1)) return 0;
824     // Filling of SurfData
825     for(Standard_Integer i = 1; i <= Nb1; i++) {
826       const HatchGen_Domain& Dom1 = H1.Domain(iH1,Ind1(i));
827       FillSD(DStr,CD,M1,Dom1,Dom1.FirstPoint().Parameter(),1,1,pitol,bout1);
828       FillSD(DStr,CD,M1,Dom1,Dom1.SecondPoint().Parameter(),0,1,pitol,bout2);
829       SetData.Append(CD);
830       CD = CpSD(DStr,CD);
831     }
832     if(intf) {
833       Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(1);
834       ChFiDS_CommonPoint& CP1 = sd->ChangeVertexFirstOnS1();
835       if(CP1.IsOnArc() && Spine->FirstStatus() == ChFiDS_OnSame) {
836         intf = !SearchFace(Spine,CP1,F1,FBID);
837       }
838       else intf = Standard_False;
839     }
840     if(intl) {
841       Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(SetData.Length());
842       ChFiDS_CommonPoint& CP1 = sd->ChangeVertexLastOnS1();
843       if(CP1.IsOnArc() && Spine->LastStatus() == ChFiDS_OnSame) {
844         intl = !SearchFace(Spine,CP1,F1,FBID);
845       }
846       else intl = Standard_False;
847     }
848   }
849   else {
850     
851     // Parsing of domains by increasing parameters,
852     // if there is a 2d circle on a plane, one goes on 2D line of opposite face.
853     Standard_Real period1 = 0., period2 = 0.;
854     if(ll1.IsPeriodic()) {
855       if(!Tri(H2,iH2,Ind2,wref,0.,pitol,Nb2)) return 0;
856       period1 = ll1.Period();
857       if(!Tri(H1,iH1,Ind1,wref,period1,pitol,Nb1)) return 0;
858     }
859     else{
860       if(!Tri(H1,iH1,Ind1,wref,0.,pitol,Nb1)) return 0;
861       if(ll2.IsPeriodic()) { period2 = ll2.Period(); }
862       if(!Tri(H2,iH2,Ind2,wref,period2,pitol,Nb2)) return 0;
863     }
864     
865     
866     // Filling of SurfData
867     TColStd_SequenceOfInteger ion1, ion2;
868     for(Standard_Integer i = 1; i <= Nb1; i++) {
869       const HatchGen_Domain& Dom1 = H1.Domain(iH1,Ind1(i));
870       Standard_Integer nbcoup1 = 1;
871       Standard_Boolean acheval1 = AdjustParam(Dom1,f1,l1,wref,period1,pitol);
872       if(acheval1) nbcoup1 = 2;
873       for (Standard_Integer icoup1 = 1; icoup1 <= nbcoup1; icoup1++) {
874         for(Standard_Integer j = 1; j <= Nb2; j++) {
875           const HatchGen_Domain& Dom2 = H2.Domain(iH2,j);
876           Standard_Integer nbcoup2 = 1;
877           Standard_Boolean acheval2 = 
878             AdjustParam(Dom2,f2,l2,wref,period2,pitol);
879           if(acheval2) nbcoup2 = 2;
880           for (Standard_Integer icoup2 = 1; icoup2 <= nbcoup2; icoup2++) {
881             if(f2 <= l1 && f1 <= l2) {
882               if (f1 >= f2 - tol2d)
883                 FillSD(DStr,CD,M1,Dom1,f1,1,1,pitol,bout1);
884               if (f2 >= f1 - tol2d)
885                 FillSD(DStr,CD,M2,Dom2,f2,1,2,pitol,bout1);
886               if (l1 >= l2 - tol2d)
887                 FillSD(DStr,CD,M2,Dom2,l2,0,2,pitol,bout2);
888               if (l2 >= l1 - tol2d)
889                 FillSD(DStr,CD,M1,Dom1,l1,0,1,pitol,bout2);
890               SetData.Append(CD);
891               CD = CpSD(DStr,CD);
892               ion1.Append(i);
893               ion2.Append(j);
894             }
895             f2 += period2;
896             l2 += period2;
897           }
898         }
899         f1 += period1;
900         l1 += period1;
901       }
902     }
903     
904     // Processing of extensions.
905     // Do not truncate, otherwise, problems of intersection for PerformCorner
906     // -----------------------------------------------------------------
907     // After call of SplitKPart in PerformSetOfKPart, spines have been 
908     // extended to the extremities by methods Extent to permit 
909     // intersections. Extensions of  SurfData are preserved.
910     
911     if(intf) {
912       // We are at the beginning of the spine
913       //-------------------------
914       Standard_Integer ifirst = 0;
915       Standard_Real dist = RealLast(), ptg, dsp; 
916       const BRepAdaptor_Curve& ed = Spine->CurrentElementarySpine(Iedge);
917       for (Standard_Integer i1 = 1; i1 <= SetData.Length(); i1++) {
918         Handle(ChFiDS_SurfData)& CD1 = SetData.ChangeValue(i1);
919         ChFiDS_CommonPoint& CP1 = CD1->ChangeVertexFirstOnS1();
920         ChFiDS_CommonPoint& CP2 = CD1->ChangeVertexFirstOnS2();
921         if(CP1.IsOnArc()&&!SearchFace(Spine,CP1,F1,FBID)) {
922           ptg = CD1->InterferenceOnS1().FirstParameter();
923           dsp = ComputeAbscissa(ed,ptg);
924           if(Abs(dsp) < dist) {
925             ifirst = i1;
926             dist = Abs(dsp);
927           }
928         }
929         else if(CP2.IsOnArc()&&!SearchFace(Spine,CP2,F2,FBID)) {
930           ptg = CD1->InterferenceOnS2().FirstParameter();
931           dsp = ComputeAbscissa(ed,ptg);
932           if(Abs(dsp) < dist) {
933             ifirst = i1;
934             dist = Abs(dsp);
935           }
936         }
937       }
938       if (ifirst>1) {
939         SetData.Remove(1,ifirst-1);
940         ion1.Remove(1,ifirst-1);
941         ion2.Remove(1,ifirst-1);
942       }
943       if(SetData.IsEmpty()) return Standard_False;
944       Handle(ChFiDS_SurfData)& CD2 = SetData.ChangeValue(1);
945       ChFiDS_CommonPoint& CP1 = CD2->ChangeVertexFirstOnS1();
946       ChFiDS_CommonPoint& CP2 = CD2->ChangeVertexFirstOnS2();
947       ChFiDS_CommonPoint sov; 
948       
949       if(CP1.IsOnArc() && CP2.IsOnArc()) {
950         intf = !SearchFace(Spine,CP1,F1,FBID) && !SearchFace(Spine,CP2,F2,FBID);
951       }
952       else if(CP1.IsOnArc()) {
953         sov = CP2;
954         if(!SearchFace(Spine,CP1,F1,FBID)) {
955           FillSD(DStr,CD2,M2,H2.Domain(iH2,Ind2(ion2.First())),
956                  H2.Domain(iH2,Ind2(ion2.First())).FirstPoint().Parameter(),1,2,pitol,bout1);
957           if(!CP2.IsOnArc() || (CP2.IsOnArc() && SearchFace(Spine,CP2,F2,FBID))) {
958             CP2 = sov;
959             if(Spine->FirstStatus() != ChFiDS_OnSame) {
960               CD2->ChangeInterference(2).
961                 SetParameter(CD2->Interference(1).Parameter(1),1);
962               intf = Standard_False;
963             }
964           }
965         }
966         else intf = Standard_False;
967       }
968       else if(CP2.IsOnArc()) {
969         sov = CP1;
970         if(!SearchFace(Spine,CP2,F2,FBID)) {
971           FillSD(DStr,CD2,M1,H1.Domain(iH1,Ind1(ion1.First())),
972                  H1.Domain(iH1,Ind1(ion1.First())).FirstPoint().Parameter(),1,1,pitol,bout1);
973           if(!CP1.IsOnArc() || (CP1.IsOnArc() && SearchFace(Spine,CP1,F1,FBID))) {
974             CP1 = sov;
975             if(Spine->FirstStatus() != ChFiDS_OnSame) {
976               CD2->ChangeInterference(1).
977                 SetParameter(CD2->Interference(2).Parameter(1),1);
978               intf = Standard_False;
979             }
980           }
981         }
982         else intf = Standard_False;
983       }
984       // select <onS> switcher so that to get on spine params from
985       // Interference with a face where both edges at corner are OnSame
986       // eap occ293
987       if (intf && Spine->FirstStatus() == ChFiDS_OnSame) {
988         TopoDS_Edge threeE[3];
989         ChFi3d_cherche_element(bout1,support,F1,threeE[0],boutemp);
990         ChFi3d_cherche_element(bout1,support,F2,threeE[1],boutemp);
991         threeE[2] = support;
992         if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame) 
993           onS = 1;
994         else
995           onS = 2;
996 #ifdef OCCT_DEBUG       
997         if (threeE[0].IsSame(threeE[1]))
998           cout << "SplitKPart(), wrong corner vertex at switcher search" << endl;
999 #endif
1000         cntlFiOnS = 3 - onS;
1001       }
1002     }
1003     if(intl) {
1004       // we are at the end of the spine
1005       //-----------------------
1006       Standard_Integer ilast = 0;
1007       Standard_Real dist = RealLast(), ptg, dsp; 
1008       Standard_Real f = Spine->FirstParameter(Iedge);
1009       Standard_Real l = Spine->LastParameter(Iedge);
1010       const BRepAdaptor_Curve& ed = Spine->CurrentElementarySpine(Iedge);
1011       for (Standard_Integer i2 = 1; i2<= SetData.Length(); i2++) {
1012         Handle(ChFiDS_SurfData)& CD3 = SetData.ChangeValue(i2);
1013         ChFiDS_CommonPoint& CP1 = CD3->ChangeVertexLastOnS1();
1014         ChFiDS_CommonPoint& CP2 = CD3->ChangeVertexLastOnS2();
1015         if(CP1.IsOnArc()&&!SearchFace(Spine,CP1,F1,FBID)) {
1016           ptg = CD3->InterferenceOnS1().LastParameter();
1017           dsp = -ComputeAbscissa(ed,ptg) - f + l;
1018           if(Abs(dsp) < dist) {
1019             ilast = i2;
1020             dist = Abs(dsp);
1021           }
1022         }
1023         else if(CP2.IsOnArc()&&!SearchFace(Spine,CP2,F2,FBID)) {
1024           ptg = CD3->InterferenceOnS2().LastParameter();
1025           dsp = -ComputeAbscissa(ed,ptg) - f + l;
1026           if(Abs(dsp) < dist) {
1027             ilast = i2;
1028             dist = Abs(dsp);
1029           }
1030         }
1031       }
1032       Standard_Integer lll = SetData.Length();
1033       if (ilast<lll) {
1034         SetData.Remove(ilast+1, lll);
1035         ion1.Remove(ilast+1, lll);
1036         ion2.Remove(ilast+1, lll);
1037       }
1038       if(SetData.IsEmpty()) return Standard_False;
1039       Handle(ChFiDS_SurfData)& CD4 = SetData.ChangeValue(SetData.Length());
1040       ChFiDS_CommonPoint& CP1 = CD4->ChangeVertexLastOnS1();
1041       ChFiDS_CommonPoint& CP2 = CD4->ChangeVertexLastOnS2();
1042       ChFiDS_CommonPoint sov; 
1043       if(CP1.IsOnArc() && CP2.IsOnArc()) {
1044         intl = !SearchFace(Spine,CP1,F1,FBID) && !SearchFace(Spine,CP2,F2,FBID);
1045       }
1046       else if(CP1.IsOnArc()) {
1047         sov = CP2;
1048         if(!SearchFace(Spine,CP1,F1,FBID)) {
1049           FillSD(DStr,CD4,M2,H2.Domain(iH2,Ind2(ion2.Last())),
1050                  H2.Domain(iH2,Ind2(ion2.Last())).SecondPoint().Parameter(),0,2,pitol,bout2);
1051           if(!CP2.IsOnArc() || (CP2.IsOnArc() && SearchFace(Spine,CP2,F2,FBID))) {
1052             CP2 = sov;
1053             if(Spine->LastStatus() != ChFiDS_OnSame) {
1054               CD4->ChangeInterference(2).
1055                 SetParameter(CD4->Interference(1).Parameter(0),0);
1056               intl = Standard_False;
1057             }
1058           }
1059         }
1060         else intl = Standard_False;
1061       }
1062       else if(CP2.IsOnArc()) {
1063         sov = CP1;
1064         if(!SearchFace(Spine,CP2,F2,FBID)) {
1065           FillSD(DStr,CD4,M1,H1.Domain(iH1,Ind1(ion1.Last())),
1066                  H1.Domain(iH1,Ind1(ion1.Last())).SecondPoint().Parameter(),0,1,pitol,bout2);
1067           if(!CP1.IsOnArc() || (CP1.IsOnArc() && SearchFace(Spine,CP1,F1,FBID))) {
1068             CP1 = sov;
1069             if(Spine->LastStatus() != ChFiDS_OnSame) {
1070               CD4->ChangeInterference(1).
1071                 SetParameter(CD4->Interference(2).Parameter(0),0);
1072               intl = Standard_False;
1073             }
1074           }
1075         }
1076         else intl = Standard_False;
1077       }
1078       
1079       // select <onS> switcher so that to get on spine params from
1080       // Interference with a face where both edges at corner are OnSame
1081       // eap occ293
1082       if (intl && Spine->LastStatus() == ChFiDS_OnSame) {
1083         TopoDS_Edge threeE[3];
1084         ChFi3d_cherche_element(bout2,support,F1,threeE[0],boutemp);
1085         ChFi3d_cherche_element(bout2,support,F2,threeE[1],boutemp);
1086         threeE[2] = support;
1087         if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame) 
1088           onS = 1;
1089         else
1090           onS = 2;
1091 #ifdef OCCT_DEBUG
1092         if (threeE[0].IsSame(threeE[1]))
1093           cout << "SplitKPart(), wrong corner vertex at switcher search" << endl;
1094 #endif
1095         cntlFiOnS = 3 - onS;
1096       }
1097     }
1098   }
1099
1100   if(!intf) { 
1101     // SurfData are entirely suspended before the beginning of the edge.
1102     Standard_Boolean okdoc = SetData.IsEmpty();
1103     Standard_Integer i = 1;
1104     while(!okdoc) {
1105       Handle(ChFiDS_SurfData)& CD5 = SetData.ChangeValue(i);
1106       Standard_Real ltg = CD5->Interference(onS).LastParameter();
1107       Standard_Real Nl = ComputeAbscissa(Spine->CurrentElementarySpine(Iedge),ltg);
1108       if (Nl < -tolesp) SetData.Remove(i);
1109       else i++;
1110       okdoc = (SetData.IsEmpty() || i > SetData.Length());
1111     }
1112   }
1113   if(!intl) { 
1114     // SurfData are entirely suspended after the end of the edge.
1115     Standard_Boolean okdoc = SetData.IsEmpty();
1116     Standard_Integer i = 1;
1117     while(!okdoc) {
1118       Handle(ChFiDS_SurfData)& CD6 = SetData.ChangeValue(i);
1119       Standard_Real ftg = CD6->Interference(onS).FirstParameter();
1120       Standard_Real f = Spine->FirstParameter(Iedge);
1121       Standard_Real l = Spine->LastParameter(Iedge);
1122       Standard_Real Nl = ComputeAbscissa(Spine->CurrentElementarySpine(Iedge),ftg);
1123       if (Nl > (l - f + tolesp)) SetData.Remove(i);
1124       else i++;
1125       okdoc = (SetData.IsEmpty() || i > SetData.Length());
1126     }
1127   }
1128   // Add parameters of the spine on SurfDatas.
1129 //  for (Standard_Integer i = 1; i <= SetData.Length(); i++) {
1130   Standard_Integer i;
1131   for ( i = 1; i <= SetData.Length(); i++) {
1132     Standard_Boolean pokdeb = 0, pokfin = 0;
1133     Handle(ChFiDS_SurfData)& CD7 = SetData.ChangeValue(i);
1134     Standard_Real ftg = CD7->Interference(onS).FirstParameter();
1135     Standard_Real ltg = CD7->Interference(onS).LastParameter();
1136     Standard_Real fsp = ParamOnSpine(DStr,ftg,CD7,Spine,Iedge,intf,intl,tolesp,pokdeb);
1137     if(!pokdeb) fsp = ResetProl(DStr,CD7,Spine,Iedge,1);
1138     Standard_Real lsp = ParamOnSpine(DStr,ltg,CD7,Spine,Iedge,intf,intl,tolesp,pokfin);
1139     if(!pokfin) lsp = ResetProl(DStr,CD7,Spine,Iedge,0);
1140     if(Spine->IsPeriodic() && Iedge == Spine->NbEdges() && lsp < fsp) { 
1141       lsp += Spine->Period();
1142     }
1143     else if(Spine->IsPeriodic() && Iedge == 1 && lsp < fsp) { 
1144       fsp -= Spine->Period();
1145     }
1146     CD7->FirstSpineParam(fsp);
1147     CD7->LastSpineParam (lsp);
1148   }
1149
1150   if (intf && !SetData.IsEmpty()) {
1151     // extension of the spine
1152     Spine->SetFirstParameter(SetData.First()->FirstSpineParam());
1153   }
1154   else {
1155     // Trnncation at the beginning.
1156     for (i = 1; i <= SetData.Length(); i++) {
1157       Handle(ChFiDS_SurfData)& CD8 = SetData.ChangeValue(i);
1158       Standard_Real fsp = CD8->FirstSpineParam();
1159       Standard_Real lsp = CD8->LastSpineParam();
1160       if (lsp > Spine->FirstParameter(Iedge)) {
1161         if (fsp > Spine->FirstParameter(Iedge)) {
1162           break;
1163         }
1164         else {
1165           Trunc(CD8,Spine,S1,S2,Iedge,1,cntlFiOnS);
1166           break;
1167         }
1168       }
1169     }
1170     if (i > 1 ) {
1171       SetData.Remove(1,i-1);
1172     }
1173   }
1174
1175
1176   if (intl && !SetData.IsEmpty()) {
1177     // extension of the spine
1178     Spine->SetLastParameter(SetData.Last()->LastSpineParam()); 
1179   }
1180   else {
1181     // Truncation at the end.
1182     for (i = SetData.Length(); i >= 1; i--) {
1183       Handle(ChFiDS_SurfData)& CD9 = SetData.ChangeValue(i);
1184       Standard_Real fsp = CD9->FirstSpineParam();
1185       Standard_Real lsp = CD9->LastSpineParam();
1186       if (fsp < Spine->LastParameter(Iedge)) {
1187         if (lsp < Spine->LastParameter(Iedge)) {
1188           break;
1189         }
1190         else {
1191           Trunc(CD9,Spine,S1,S2,Iedge,0,cntlFiOnS);
1192           break;
1193         }
1194       }
1195     }
1196     if (i < SetData.Length()) {
1197         SetData.Remove(i+1,SetData.Length());
1198     }
1199   }
1200 #ifdef OCCT_DEBUG
1201   if(ChFi3d_GettraceDRAWFIL()) {
1202     for (i = 1; i <= SetData.Length(); i++) {
1203       ChFi3d_CheckSurfData(DStr,SetData.Value(i));
1204     }
1205   }
1206 #endif
1207   return Standard_True;
1208 }