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