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