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