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
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.
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.
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.
22 #include <Standard_NotImplemented.hxx>
23 #include <Precision.hxx>
24 #include <TColStd_SequenceOfInteger.hxx>
25 #include <TColStd_Array1OfInteger.hxx>
26 #include <TColStd_Array1OfReal.hxx>
28 #include <gp_Pnt2d.hxx>
29 #include <gp_Dir2d.hxx>
31 #include <gp_Circ.hxx>
32 #include <TColgp_Array1OfPnt2d.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>
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>
60 #include <TopoDS_Edge.hxx>
62 #include <TopOpeBRepDS_Curve.hxx>
63 #include <TopOpeBRepDS_Surface.hxx>
65 #include <ChFiKPart_RstMap.hxx>
67 #include <ChFi3d_Builder.jxx>
68 #include <ChFi3d_Builder_0.hxx>
70 extern Standard_Boolean ChFi3d_GettraceDRAWFIL();
71 extern void ChFi3d_CheckSurfData(const TopOpeBRepDS_DataStructure& DStr,
72 const Handle(ChFiDS_SurfData)& Data);
74 //=======================================================================
76 //purpose : Calculate the Transition from start point.
77 //=======================================================================
79 static TopAbs_Orientation CompTra (const TopAbs_Orientation O1,
80 const TopAbs_Orientation O2,
81 const Standard_Boolean isfirst)
83 if(isfirst) return TopAbs::Reverse(TopAbs::Compose(O1,O2));
84 else return TopAbs::Compose(O1,O2);
88 //=======================================================================
89 //function : CompCommonpoint
90 //purpose : Fill the commonpoint in case of a vertex.
91 //=======================================================================
93 static void CompCommonPoint (ChFiDS_CommonPoint& FilPoint,
94 const TopoDS_Edge& arc,
95 const HatchGen_PointOnElement& PE,
96 const TopAbs_Orientation Or)
98 TopAbs_Orientation pos = PE.Position();
100 if ( pos == TopAbs_FORWARD ) {
101 V = TopExp::FirstVertex(arc);
104 V = TopExp::LastVertex(arc);
106 FilPoint.SetVertex(V);
107 FilPoint.SetArc(Precision::PIntersection(),arc,
108 PE.Parameter(),TopAbs::Compose(arc.Orientation(),Or));
112 //=======================================================================
113 //function : CpInterf
114 //purpose : Construct new SurfData sharing faces, surface and curves.
115 //=======================================================================
117 static ChFiDS_FaceInterference CpInterf (TopOpeBRepDS_DataStructure& DStr,
118 const ChFiDS_FaceInterference& FI)
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())));
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());
137 //=======================================================================
139 //purpose : Construct new SurfData sharing faces, surface and curves.
140 //=======================================================================
142 static Handle(ChFiDS_SurfData) CpSD ( TopOpeBRepDS_DataStructure& DStr,
143 const Handle(ChFiDS_SurfData)& Data)
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());
158 //=======================================================================
159 //function : AdjustParam
161 //=======================================================================
163 static Standard_Boolean AdjustParam(const HatchGen_Domain& Dom,
166 const Standard_Real wref,
167 const Standard_Real period,
168 const Standard_Real pitol)
170 if(Dom.HasFirstPoint())
171 f = Dom.FirstPoint().Parameter();
173 if(Dom.HasSecondPoint())
174 l = Dom.SecondPoint().Parameter();
176 if (period == 0.) return Standard_False;
178 f = ElCLib::InPeriod(f,wref - pitol, wref + period - pitol);
179 l = ElCLib::InPeriod(l,wref + pitol, wref + period + pitol);
182 return Standard_True;
184 return Standard_False;
186 //=======================================================================
187 //function : ComputeAbscissa
189 //=======================================================================
191 static Standard_Real ComputeAbscissa(const BRepAdaptor_Curve& C,
192 const Standard_Real U)
194 switch (C.GetType()) {
198 return C.Circle().Radius()*U;
204 //=======================================================================
205 //function : ParamOnSpine
207 //=======================================================================
209 static Standard_Real ParamOnSpine(const TopOpeBRepDS_DataStructure& DStr,
210 const Standard_Real ptg,
211 const Handle(ChFiDS_SurfData)& CD,
212 const Handle(ChFiDS_Spine)& Spine,
213 const Standard_Integer iedge,
214 const Standard_Boolean intf,
215 const Standard_Boolean intl,
216 const Standard_Real tol,
217 Standard_Boolean& pok)
220 Standard_Real f = Spine->FirstParameter(iedge);
221 Standard_Real l = Spine->LastParameter(iedge);
223 Nl = ComputeAbscissa(Spine->CurrentElementarySpine(iedge),ptg) + f;
224 if ((Nl >= (f - tol) || intf) &&
225 (Nl <= (l + tol) || intl) ) {
230 //construction of the plane containing the section of CD with parameter ptg.
233 Handle(Geom_Curve) c3d;
234 if (CD->InterferenceOnS1().LineIndex() != 0) {
235 c3d = DStr.Curve(CD->InterferenceOnS1().LineIndex()).Curve();
238 c3d = DStr.Curve(CD->InterferenceOnS2().LineIndex()).Curve();
242 gp_Pln nlp(PP,gp_Dir(VV));
243 Handle(Geom_Plane) pln = new Geom_Plane(nlp);
244 Handle(GeomAdaptor_HSurface)
245 plan = new GeomAdaptor_HSurface(GeomAdaptor_Surface(pln));
247 // intersection plane spine.
248 Standard_Boolean found = Standard_False;
249 Standard_Boolean fini = Standard_False;
250 Standard_Integer sens = 1;
251 if (Nl <= f) sens = -1;
252 Standard_Integer ii = iedge + sens;
253 if (Spine->IsPeriodic()) {
254 if (ii <= 0) ii += Spine->NbEdges();
255 if (ii > Spine->NbEdges()) ii -= Spine->NbEdges();
257 else if(ii < 1 || ii > Spine->NbEdges()) {
261 Handle(BRepAdaptor_HCurve) HE = new BRepAdaptor_HCurve();
262 BRepAdaptor_Curve& CE = HE->ChangeCurve();
264 while (!found && !fini) {
265 TopAbs_Orientation O = Spine->Edges(ii).Orientation();
266 Standard_Boolean First = ((O == TopAbs_FORWARD && sens == 1) ||
267 (O == TopAbs_REVERSED && sens == -1));
268 CE.Initialize(Spine->Edges(ii));
269 Standard_Real tolc = CE.Resolution(tol);
270 found = ChFi3d_InterPlaneEdge(plan,HE,Nl,First,tolc);
271 gp_Pnt point = CE.Value(Nl);
273 cout<<"******* ParamOnSpine() for edge "<<iedge<<endl;
275 cout<<"point ped "<<point.X()<<" "<<point.Y()<<" "<<point.Z()<<endl;
277 if(found) Nl = Spine->Absc(Nl,ii);
278 point = Spine->Value(Nl);
280 if (found) cout << "found by edge " << ii << " : ";
282 cout<<"point psp "<<point.X()<<" "<<point.Y()<<" "<<point.Z()<<endl;
287 if (Spine->IsPeriodic()) {
288 if (ii <= 0) ii += Spine->NbEdges();
289 if (ii > Spine->NbEdges()) ii -= Spine->NbEdges();
290 fini = (ii == iedge);
293 fini = (ii < 1 || ii > Spine->NbEdges());
301 //=======================================================================
302 //function : YaUnVoisin
304 //=======================================================================
306 static Standard_Boolean YaUnVoisin(const Handle(ChFiDS_Spine)& Spine,
307 const Standard_Integer iedge,
308 Standard_Integer& ivois,
309 const Standard_Boolean isfirst)
311 Standard_Integer nbed = Spine->NbEdges();
312 if(nbed == 1) return 0;
313 Standard_Boolean periodic = Spine->IsPeriodic();
314 if(isfirst) ivois = iedge - 1;
315 else ivois = iedge + 1;
317 if(ivois == 0) ivois = nbed;
318 if(ivois == nbed+1) ivois = 1;
320 return (ivois > 0 && ivois <= nbed);
323 //=======================================================================
326 //=======================================================================
328 void ChFi3d_Builder::Trunc(const Handle(ChFiDS_SurfData)& SD,
329 const Handle(ChFiDS_Spine)& Spine,
330 const Handle(Adaptor3d_HSurface)& S1,
331 const Handle(Adaptor3d_HSurface)& S2,
332 const Standard_Integer iedge,
333 const Standard_Boolean isfirst,
334 const Standard_Integer cntlFiOnS)
336 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
337 // Return points and tangents on edge and spine.
338 Standard_Real wtg = SD->InterferenceOnS1().Parameter(isfirst);
339 Standard_Boolean bid;
340 Standard_Real wsp = ParamOnSpine(DStr,wtg,SD,Spine,iedge,0,0,tolesp,bid);
343 TopoDS_Vertex bout1,bout2,boutemp;
346 const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge);
347 //Modif against Vertex isolated on spine
348 TopoDS_Edge support = bc.Edge();
349 TopExp::Vertices(support,bout1,bout2);
350 if (support.Orientation() == TopAbs_REVERSED) {
359 Standard_Real edf = bc.FirstParameter(), edl = bc.LastParameter();
360 Standard_Real edglen = edl - edf;
361 if(Spine->Edges(iedge).Orientation() == TopAbs_FORWARD) {
362 bc.D1(wtg+edf,ped,ded);
365 bc.D1(-wtg+edl,ped,ded);
368 Spine->D1(wsp,psp,dsp);
370 const Handle(Geom_Surface)& surf = DStr.Surface(SD->Surf()).Surface();
372 pp1 = SD->InterferenceOnS1().PCurveOnSurf()->Value(wtg);
373 pp2 = SD->InterferenceOnS2().PCurveOnSurf()->Value(wtg);
374 p1 = surf->Value(pp1.X(),pp1.Y());
375 p2 = surf->Value(pp2.X(),pp2.Y());
376 Standard_Boolean tron = Standard_False;
377 Standard_Real Ang = dsp.Angle(ded);
378 Standard_Real dis1 = psp.Distance(ped);
379 Standard_Real dis2 = p1.Distance(p2);
380 if(Ang > M_PI/18.) tron = Standard_True;
381 if(dis1 >= 0.1*dis2) tron = Standard_True;
382 Standard_Integer ivois;
383 if(!tron && YaUnVoisin(Spine,iedge,ivois,isfirst)) {
384 Handle(BRepAdaptor_HSurface) BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1);
385 Handle(BRepAdaptor_HSurface) BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2);
386 if(!BS1.IsNull() && !BS2.IsNull()) {
388 TopoDS_Face F1 = BS1->ChangeSurface().Face();
389 TopoDS_Face F2 = BS2->ChangeSurface().Face();
390 const ChFiDS_CommonPoint& cp1 = SD->Vertex(isfirst,1);
391 const ChFiDS_CommonPoint& cp2 = SD->Vertex(isfirst,2);
392 if(!(cp1.IsOnArc() && SearchFace(Spine,cp1,F1,FBID) ||
393 cp2.IsOnArc() && SearchFace(Spine,cp2,F2,FBID))) {
394 tron = ChFi3d_KParticular(Spine,ivois,BS1->ChangeSurface(),BS2->ChangeSurface());
398 //modification of lvt against isolated vertex
399 if(!tron && YaUnVoisin(Spine,iedge,ivois,isfirst)) {
400 TopTools_ListIteratorOfListOfShape It;
401 Standard_Integer nbed = -2;
402 for (It.Initialize(myVEMap(bout1));It.More();It.Next()) {
405 if(nbed<3) tron = Standard_True;
410 Standard_Real par = 0., x, y, dPar=0;
411 if(!isfirst) par = edglen;
413 // detect the case where FaceInterference ends before the place we are
414 // going to truncate SD. Then we cut so that FaceInterference length to
415 // be at least zero, not negative (eap, occ354)
416 Standard_Real fiPar = SD->Interference(cntlFiOnS).Parameter(!isfirst);
417 Standard_Boolean isTheCase = isfirst ? (par > fiPar) : (par < fiPar);
423 for (Standard_Integer i = 1; i <= 2; i++) {
424 SD->ChangeInterference(i).SetParameter(par,isfirst);
425 Handle(Geom2d_Curve) pc = SD->Interference(i).PCurveOnSurf();
426 pc->Value(par).Coord(x,y);
427 SD->ChangeVertex(isfirst,i).Reset();
428 SD->ChangeVertex(isfirst,i).SetPoint(surf->Value(x,y));
429 if(isfirst) SD->FirstSpineParam(Spine->FirstParameter(iedge)-dPar);
430 else SD->LastSpineParam (Spine->LastParameter(iedge) -dPar);
435 //=======================================================================
436 //function : ResetProl
438 //=======================================================================
440 static Standard_Real ResetProl(const TopOpeBRepDS_DataStructure& DStr,
441 const Handle(ChFiDS_SurfData)& CD,
442 const Handle(ChFiDS_Spine)& Spine,
443 const Standard_Integer iedge,
444 const Standard_Boolean isfirst)
446 const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge);
447 Standard_Real edglen = bc.LastParameter() - bc.FirstParameter();
448 const Handle(Geom_Surface)& surf = DStr.Surface(CD->Surf()).Surface();
449 Standard_Real par = 0., x, y;
450 if(!isfirst) par = edglen;
452 for (Standard_Integer i = 1; i <= 2; i++) {
453 CD->ChangeInterference(i).SetParameter(par,isfirst);
454 Handle(Geom2d_Curve) pc = CD->Interference(i).PCurveOnSurf();
455 pc->Value(par).Coord(x,y);
456 CD->ChangeVertex(isfirst,i).Reset();
457 CD->ChangeVertex(isfirst,i).SetPoint(surf->Value(x,y));
459 sppar = Spine->FirstParameter(iedge);
460 CD->FirstSpineParam(sppar);
463 sppar = Spine->LastParameter(iedge);
464 CD->LastSpineParam (sppar);
469 //=======================================================================
472 //=======================================================================
474 static Standard_Boolean Tri(const Geom2dHatch_Hatcher& H,
475 const Standard_Integer iH,
476 TColStd_Array1OfInteger& Ind,
477 const Standard_Real wref,
478 const Standard_Real period,
479 const Standard_Real pitol,
480 Standard_Integer& Nbdom)
482 // for (Standard_Integer i = 1; i <= Nbdom; i++) { Ind(i) = i; }
484 for ( i = 1; i <= Nbdom; i++) { Ind(i) = i; }
485 Standard_Real f1,f2,l;
486 Standard_Integer tmp;
487 Standard_Boolean Invert = Standard_True;
490 Invert = Standard_False;
491 for ( i = 1; i < Nbdom; i++) {
492 AdjustParam(H.Domain(iH,Ind(i)),f1,l,wref,period,pitol);
493 AdjustParam(H.Domain(iH,Ind(i+1)),f2,l,wref,period,pitol);
498 Invert = Standard_True;
503 Standard_Integer iSansFirst = 0, iSansLast = 0;
506 for ( i = 1; i <= Nbdom; i++) {
507 if (!H.Domain(iH,Ind(i)).HasFirstPoint()) {
510 if (!H.Domain(iH,Ind(i)).HasSecondPoint()) {
515 if (iSansFirst != 0) {
516 if (iSansLast == 0) {
518 cout<<"Parsing : Pb of Hatcher"<<endl;
522 HatchGen_Domain* Dom = ((HatchGen_Domain*) (void*) &H.Domain(iH,Ind(iSansFirst)));
523 HatchGen_PointOnHatching* PH =
524 ((HatchGen_PointOnHatching*) (void*) &H.Domain(iH,Ind(iSansLast)).FirstPoint());
525 Standard_Real NewPar = H.HatchingCurve(iH).FirstParameter() - period +
526 H.Domain(iH,Ind(iSansLast)).FirstPoint().Parameter();
527 PH->SetParameter(NewPar);
528 Dom->SetFirstPoint(*PH);
530 for (Standard_Integer k = iSansLast; k < Nbdom; k++) {
538 //=======================================================================
541 //=======================================================================
543 static void FillSD (TopOpeBRepDS_DataStructure& DStr,
544 Handle(ChFiDS_SurfData)& CD,
546 const HatchGen_Domain& Dom,
547 const Standard_Real ponH,
548 const Standard_Boolean isFirst,
549 const Standard_Integer ons,
550 const Standard_Real pitol,
551 const TopoDS_Vertex bout)
554 Standard_Integer opp = 3 - ons;
555 ChFiDS_CommonPoint& Pons = CD->ChangeVertex(isFirst,ons);
556 ChFiDS_CommonPoint& Popp = CD->ChangeVertex(isFirst,opp);
558 const HatchGen_PointOnHatching* pPH = 0;
559 if(isFirst && Dom.HasFirstPoint()) {
560 const HatchGen_PointOnHatching& PHtemp = Dom.FirstPoint();
563 else if(!isFirst && Dom.HasSecondPoint()) {
564 const HatchGen_PointOnHatching& PHtemp = Dom.SecondPoint();
568 Handle(Geom_Surface) Surf = DStr.Surface(CD->Surf()).Surface();
570 CD->ChangeInterference(ons).SetParameter(ponH,isFirst);
571 Handle(Geom2d_Curve) pcons = CD->Interference(ons).PCurveOnSurf();
572 pcons->Value(ponH).Coord(x,y);
573 CD->ChangeVertex(isFirst,ons).SetPoint(Surf->Value(x,y));
576 //Modification to find already existing vertexes
577 Standard_Integer LeType = 1;
578 Standard_Integer NbInt = pPH->NbPoints();
580 Standard_Boolean trouve = Standard_True;
582 TopoDS_Vertex V1 , V2;
583 Standard_Boolean suite = Standard_True;
585 const HatchGen_PointOnElement& PEtemp = pPH->Point(LeType);
587 Handle(BRepAdaptor_HCurve2d) HE = Handle(BRepAdaptor_HCurve2d::DownCast(M(IE)));
589 const TopoDS_Edge& Etemp = HE->ChangeCurve2d().Edge();
590 TopExp::Vertices(Etemp,V1,V2);
593 suite = Standard_False;
595 if(((V1.IsSame(bout)) || (V2.IsSame(bout))) && suite) {
596 trouve = Standard_True;
600 suite = Standard_True;
601 trouve = Standard_False;
604 trouve = Standard_True;
610 const HatchGen_PointOnElement& PE = pPH->Point(LeType);
611 Standard_Integer IE = PE.Index();
612 Handle(BRepAdaptor_HCurve2d)
613 HE = Handle(BRepAdaptor_HCurve2d)::DownCast(M(IE));
614 if(HE.IsNull()) return;
615 const TopoDS_Edge& E = HE->ChangeCurve2d().Edge();
617 if (PE.Position() != TopAbs_INTERNAL) {
618 TopAbs_Orientation O = CD->Interference(ons).Transition();
619 if(isFirst) O = TopAbs::Reverse(O);
620 CompCommonPoint(Pons,E,PE,O);
623 Pons.SetArc(pitol,E,PE.Parameter(),
624 CompTra(CD->Interference(ons).Transition(),E.Orientation(),isFirst));
626 Handle(Geom2d_Curve) pcadj = CD->Interference(ons).PCurveOnSurf();
627 pcadj->Value(ponH).Coord(x,y);
628 CD->ChangeInterference(ons).SetParameter(ponH,isFirst);
629 CD->ChangeVertex(isFirst,ons).SetPoint(Surf->Value(x,y));
631 if(!Popp.IsOnArc()) {
632 CD->ChangeInterference(opp).SetParameter(ponH,isFirst);
633 Handle(Geom2d_Curve) pcopp = CD->Interference(opp).PCurveOnSurf();
634 pcopp->Value(ponH).Coord(x,y);
635 CD->ChangeVertex(isFirst,opp).SetPoint(Surf->Value(x,y));
639 //=======================================================================
640 //function : SplitKPart
641 //purpose : Reconstruct SurfData depending on restrictions of faces.
642 //=======================================================================
644 Standard_Boolean ChFi3d_Builder::SplitKPart
645 (const Handle(ChFiDS_SurfData)& Data,
646 ChFiDS_SequenceOfSurfData& SetData,
647 const Handle(ChFiDS_Spine)& Spine,
648 const Standard_Integer Iedge,
649 const Handle(Adaptor3d_HSurface)& S1,
650 const Handle(Adaptor3d_TopolTool)& I1,
651 const Handle(Adaptor3d_HSurface)& S2,
652 const Handle(Adaptor3d_TopolTool)& I2,
653 Standard_Boolean& intf,
654 Standard_Boolean& intl)
656 //The the hatching of each faces is started by tangency lines.
658 Standard_Real pitol = Precision::PIntersection();
660 ChFiKPart_RstMap M1, M2;
661 Standard_Integer iH1 = 0,iH2 = 0;
662 Standard_Integer Nb1 = 1,Nb2 = 1;
664 // Cutting of tangency lines (hatching).
665 Geom2dHatch_Intersector Inter(pitol,pitol);
666 Geom2dHatch_Hatcher H1(Inter,tol2d,tolesp), H2(Inter,tol2d,tolesp);
668 Handle(Geom2d_Curve) C1 = Data->InterferenceOnS1().PCurveOnFace();
669 Geom2dAdaptor_Curve ll1;
672 for(I1->Init(); I1->More(); I1->Next()) {
673 Handle(BRepAdaptor_HCurve2d)
674 Bc = Handle(BRepAdaptor_HCurve2d)::DownCast(I1->Value());
675 Handle(Geom2dAdaptor_HCurve)
676 Gc = Handle(Geom2dAdaptor_HCurve)::DownCast(I1->Value());
677 if(Bc.IsNull()) ie = H1.AddElement(Gc->ChangeCurve2d(),TopAbs_FORWARD);
678 else ie = H1.AddElement(Bc->ChangeCurve2d(),
679 Bc->ChangeCurve2d().Edge().Orientation());
680 M1.Bind(ie,I1->Value());
683 H1.ComputeDomains(iH1);
684 if(!H1.IsDone(iH1)) return 0;
685 Nb1 = H1.NbDomains(iH1);
688 cout<<"SplitKPart : tangency line out of the face"<<endl;
690 return Standard_False;
694 Handle(Geom2d_Curve) C2 = Data->InterferenceOnS2().PCurveOnFace();
695 Geom2dAdaptor_Curve ll2;
698 for(I2->Init(); I2->More(); I2->Next()) {
699 Handle(BRepAdaptor_HCurve2d)
700 Bc = Handle(BRepAdaptor_HCurve2d)::DownCast(I2->Value());
701 Handle(Geom2dAdaptor_HCurve)
702 Gc = Handle(Geom2dAdaptor_HCurve)::DownCast(I2->Value());
703 if(Bc.IsNull()) ie = H2.AddElement(Gc->ChangeCurve2d(),TopAbs_FORWARD);
704 else ie = H2.AddElement(Bc->ChangeCurve2d(),
705 Bc->ChangeCurve2d().Edge().Orientation());
706 M2.Bind(ie,I2->Value());
709 H2.ComputeDomains(iH2);
710 if(!H2.IsDone(iH2)) return 0;
711 Nb2 = H2.NbDomains(iH2);
714 cout<<"SplitKPart : tangency line out of the face"<<endl;
716 return Standard_False;
720 //Return start and end vertexes of the Spine
721 TopoDS_Vertex bout1,bout2,boutemp;
722 const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(Iedge);
723 TopoDS_Edge support = bc.Edge();
724 TopExp::Vertices(support,bout1,bout2);
725 if(support.Orientation() == TopAbs_REVERSED) {
733 Handle(BRepAdaptor_HSurface)
734 bhs = Handle(BRepAdaptor_HSurface)::DownCast(S1);
735 if(!bhs.IsNull()) F1 = bhs->ChangeSurface().Face();
736 bhs = Handle(BRepAdaptor_HSurface)::DownCast(S2);
737 if(!bhs.IsNull()) F2 = bhs->ChangeSurface().Face();
740 // Restriction of SurfDatas by cut lines.
741 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
742 Handle(ChFiDS_SurfData) CD = Data;
743 CD->ChangeIndexOfS1(DStr.AddShape(F1));
744 CD->ChangeIndexOfS2(DStr.AddShape(F2));
746 Standard_Real f1,l1,f2,l2;
747 TColStd_Array1OfInteger Ind1(1,Nb1), Ind2(1,Nb2);
748 Standard_Real wref = 0.;
750 Standard_Integer onS = 1; // switcher of access to surfs of SurfData, eap occ293
751 Standard_Integer cntlFiOnS = 0; // FaceInterference to control length in OnSame
752 // situation, eap occ354
754 if (C1.IsNull() && C2.IsNull()) {
756 cout<<"SplitData : 2 zero lines hatching impossible"<<endl;
758 return Standard_False;
760 else if (C1.IsNull() || (Nb1 == 1 && !H1.Domain(iH1,1).HasFirstPoint())) {
761 // It is checked if the point 2d of the degenerated edge is in the face.
763 gp_Pnt2d p2d1 = CD->Get2dPoints(0,1);
764 TopAbs_State situ = I1->Classify(p2d1,1.e-8,0);
765 if(situ == TopAbs_OUT) return Standard_False;
768 // Parsing of domains by increasing parameters,
769 if(!Tri(H2,iH2,Ind2,wref,0.,pitol,Nb2)) return 0;
770 // Filling of SurfData
771 for(Standard_Integer i = 1; i <= Nb2; i++) {
772 const HatchGen_Domain& Dom2 = H2.Domain(iH2,Ind2(i));
773 FillSD(DStr,CD,M2,Dom2,Dom2.FirstPoint().Parameter(),1,2,pitol,bout1);
774 FillSD(DStr,CD,M2,Dom2,Dom2.SecondPoint().Parameter(),0,2,pitol,bout2);
779 Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(1);
780 ChFiDS_CommonPoint& CP2 = sd->ChangeVertexFirstOnS2();
781 if(CP2.IsOnArc() && Spine->FirstStatus() == ChFiDS_OnSame) {
782 intf = !SearchFace(Spine,CP2,F2,FBID);
784 else intf = Standard_False;
787 Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(SetData.Length());
788 ChFiDS_CommonPoint& CP2 = sd->ChangeVertexLastOnS2();
789 if(CP2.IsOnArc() && Spine->LastStatus() == ChFiDS_OnSame) {
790 intl = !SearchFace(Spine,CP2,F2,FBID);
792 else intl = Standard_False;
795 else if (C2.IsNull() || (Nb2 == 1 && !H2.Domain(iH2,1).HasFirstPoint())) {
796 // It is checked if the point 2d of the degenerated is in the face.
798 gp_Pnt2d p2d2 = CD->Get2dPoints(0,2);
799 TopAbs_State situ = I2->Classify(p2d2,1.e-8,0);
800 if(situ == TopAbs_OUT) return Standard_False;
803 // Parsing of domains by increasing parameters,
804 if(!Tri(H1,iH1,Ind1,wref,0.,pitol,Nb1)) return 0;
805 // Filling of SurfData
806 for(Standard_Integer i = 1; i <= Nb1; i++) {
807 const HatchGen_Domain& Dom1 = H1.Domain(iH1,Ind1(i));
808 FillSD(DStr,CD,M1,Dom1,Dom1.FirstPoint().Parameter(),1,1,pitol,bout1);
809 FillSD(DStr,CD,M1,Dom1,Dom1.SecondPoint().Parameter(),0,1,pitol,bout2);
814 Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(1);
815 ChFiDS_CommonPoint& CP1 = sd->ChangeVertexFirstOnS1();
816 if(CP1.IsOnArc() && Spine->FirstStatus() == ChFiDS_OnSame) {
817 intf = !SearchFace(Spine,CP1,F1,FBID);
819 else intf = Standard_False;
822 Handle(ChFiDS_SurfData)& sd = SetData.ChangeValue(SetData.Length());
823 ChFiDS_CommonPoint& CP1 = sd->ChangeVertexLastOnS1();
824 if(CP1.IsOnArc() && Spine->LastStatus() == ChFiDS_OnSame) {
825 intl = !SearchFace(Spine,CP1,F1,FBID);
827 else intl = Standard_False;
832 // Parsing of domains by increasing parameters,
833 // if there is a 2d circle on a plane, one goes on 2D line of opposite face.
834 Standard_Real period1 = 0., period2 = 0.;
835 if(ll1.IsPeriodic()) {
836 if(!Tri(H2,iH2,Ind2,wref,0.,pitol,Nb2)) return 0;
837 period1 = ll1.Period();
838 if(!Tri(H1,iH1,Ind1,wref,period1,pitol,Nb1)) return 0;
841 if(!Tri(H1,iH1,Ind1,wref,0.,pitol,Nb1)) return 0;
842 if(ll2.IsPeriodic()) { period2 = ll2.Period(); }
843 if(!Tri(H2,iH2,Ind2,wref,period2,pitol,Nb2)) return 0;
847 // Filling of SurfData
848 TColStd_SequenceOfInteger ion1, ion2;
849 for(Standard_Integer i = 1; i <= Nb1; i++) {
850 const HatchGen_Domain& Dom1 = H1.Domain(iH1,Ind1(i));
851 Standard_Integer nbcoup1 = 1;
852 Standard_Boolean acheval1 = AdjustParam(Dom1,f1,l1,wref,period1,pitol);
853 if(acheval1) nbcoup1 = 2;
854 for (Standard_Integer icoup1 = 1; icoup1 <= nbcoup1; icoup1++) {
855 for(Standard_Integer j = 1; j <= Nb2; j++) {
856 const HatchGen_Domain& Dom2 = H2.Domain(iH2,j);
857 Standard_Integer nbcoup2 = 1;
858 Standard_Boolean acheval2 =
859 AdjustParam(Dom2,f2,l2,wref,period2,pitol);
860 if(acheval2) nbcoup2 = 2;
861 for (Standard_Integer icoup2 = 1; icoup2 <= nbcoup2; icoup2++) {
862 if(f2 <= l1 && f1 <= l2) {
863 if (f1 >= f2 - tol2d)
864 FillSD(DStr,CD,M1,Dom1,f1,1,1,pitol,bout1);
865 if (f2 >= f1 - tol2d)
866 FillSD(DStr,CD,M2,Dom2,f2,1,2,pitol,bout1);
867 if (l1 >= l2 - tol2d)
868 FillSD(DStr,CD,M2,Dom2,l2,0,2,pitol,bout2);
869 if (l2 >= l1 - tol2d)
870 FillSD(DStr,CD,M1,Dom1,l1,0,1,pitol,bout2);
885 // Processing of extensions.
886 // Do not truncate, otherwise, problems of intersection for PerformCorner
887 // -----------------------------------------------------------------
888 // After call of SplitKPart in PerformSetOfKPart, spines have been
889 // extended to the extremities by methods Extent to permit
890 // intersections. Extensions of SurfData are preserved.
893 // We are at the beginning of the spine
894 //-------------------------
895 Standard_Integer ifirst = 0;
896 Standard_Real dist = RealLast(), ptg, dsp;
897 const BRepAdaptor_Curve& ed = Spine->CurrentElementarySpine(Iedge);
898 for (Standard_Integer i1 = 1; i1 <= SetData.Length(); i1++) {
899 Handle(ChFiDS_SurfData)& CD1 = SetData.ChangeValue(i1);
900 ChFiDS_CommonPoint& CP1 = CD1->ChangeVertexFirstOnS1();
901 ChFiDS_CommonPoint& CP2 = CD1->ChangeVertexFirstOnS2();
902 if(CP1.IsOnArc()&&!SearchFace(Spine,CP1,F1,FBID)) {
903 ptg = CD1->InterferenceOnS1().FirstParameter();
904 dsp = ComputeAbscissa(ed,ptg);
905 if(Abs(dsp) < dist) {
910 else if(CP2.IsOnArc()&&!SearchFace(Spine,CP2,F2,FBID)) {
911 ptg = CD1->InterferenceOnS2().FirstParameter();
912 dsp = ComputeAbscissa(ed,ptg);
913 if(Abs(dsp) < dist) {
920 SetData.Remove(1,ifirst-1);
921 ion1.Remove(1,ifirst-1);
922 ion2.Remove(1,ifirst-1);
924 if(SetData.IsEmpty()) return Standard_False;
925 Handle(ChFiDS_SurfData)& CD2 = SetData.ChangeValue(1);
926 ChFiDS_CommonPoint& CP1 = CD2->ChangeVertexFirstOnS1();
927 ChFiDS_CommonPoint& CP2 = CD2->ChangeVertexFirstOnS2();
928 ChFiDS_CommonPoint sov;
930 if(CP1.IsOnArc() && CP2.IsOnArc()) {
931 intf = !SearchFace(Spine,CP1,F1,FBID) && !SearchFace(Spine,CP2,F2,FBID);
933 else if(CP1.IsOnArc()) {
935 if(!SearchFace(Spine,CP1,F1,FBID)) {
936 FillSD(DStr,CD2,M2,H2.Domain(iH2,Ind2(ion2.First())),
937 H2.Domain(iH2,Ind2(ion2.First())).FirstPoint().Parameter(),1,2,pitol,bout1);
938 if(!CP2.IsOnArc() || (CP2.IsOnArc() && SearchFace(Spine,CP2,F2,FBID))) {
940 if(Spine->FirstStatus() != ChFiDS_OnSame) {
941 CD2->ChangeInterference(2).
942 SetParameter(CD2->Interference(1).Parameter(1),1);
943 intf = Standard_False;
947 else intf = Standard_False;
949 else if(CP2.IsOnArc()) {
951 if(!SearchFace(Spine,CP2,F2,FBID)) {
952 FillSD(DStr,CD2,M1,H1.Domain(iH1,Ind1(ion1.First())),
953 H1.Domain(iH1,Ind1(ion1.First())).FirstPoint().Parameter(),1,1,pitol,bout1);
954 if(!CP1.IsOnArc() || (CP1.IsOnArc() && SearchFace(Spine,CP1,F1,FBID))) {
956 if(Spine->FirstStatus() != ChFiDS_OnSame) {
957 CD2->ChangeInterference(1).
958 SetParameter(CD2->Interference(2).Parameter(1),1);
959 intf = Standard_False;
963 else intf = Standard_False;
965 // select <onS> switcher so that to get on spine params from
966 // Interference with a face where both edges at corner are OnSame
968 if (intf && Spine->FirstStatus() == ChFiDS_OnSame) {
969 TopoDS_Edge threeE[3];
970 ChFi3d_cherche_element(bout1,support,F1,threeE[0],boutemp);
971 ChFi3d_cherche_element(bout1,support,F2,threeE[1],boutemp);
973 if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame)
978 if (threeE[0].IsSame(threeE[1]))
979 cout << "SplitKPart(), wrong corner vertex at switcher search" << endl;
985 // we are at the end of the spine
986 //-----------------------
987 Standard_Integer ilast = 0;
988 Standard_Real dist = RealLast(), ptg, dsp;
989 Standard_Real f = Spine->FirstParameter(Iedge);
990 Standard_Real l = Spine->LastParameter(Iedge);
991 const BRepAdaptor_Curve& ed = Spine->CurrentElementarySpine(Iedge);
992 for (Standard_Integer i2 = 1; i2<= SetData.Length(); i2++) {
993 Handle(ChFiDS_SurfData)& CD3 = SetData.ChangeValue(i2);
994 ChFiDS_CommonPoint& CP1 = CD3->ChangeVertexLastOnS1();
995 ChFiDS_CommonPoint& CP2 = CD3->ChangeVertexLastOnS2();
996 if(CP1.IsOnArc()&&!SearchFace(Spine,CP1,F1,FBID)) {
997 ptg = CD3->InterferenceOnS1().LastParameter();
998 dsp = -ComputeAbscissa(ed,ptg) - f + l;
999 if(Abs(dsp) < dist) {
1004 else if(CP2.IsOnArc()&&!SearchFace(Spine,CP2,F2,FBID)) {
1005 ptg = CD3->InterferenceOnS2().LastParameter();
1006 dsp = -ComputeAbscissa(ed,ptg) - f + l;
1007 if(Abs(dsp) < dist) {
1013 Standard_Integer lll = SetData.Length();
1015 SetData.Remove(ilast+1, lll);
1016 ion1.Remove(ilast+1, lll);
1017 ion2.Remove(ilast+1, lll);
1019 if(SetData.IsEmpty()) return Standard_False;
1020 Handle(ChFiDS_SurfData)& CD4 = SetData.ChangeValue(SetData.Length());
1021 ChFiDS_CommonPoint& CP1 = CD4->ChangeVertexLastOnS1();
1022 ChFiDS_CommonPoint& CP2 = CD4->ChangeVertexLastOnS2();
1023 ChFiDS_CommonPoint sov;
1024 if(CP1.IsOnArc() && CP2.IsOnArc()) {
1025 intl = !SearchFace(Spine,CP1,F1,FBID) && !SearchFace(Spine,CP2,F2,FBID);
1027 else if(CP1.IsOnArc()) {
1029 if(!SearchFace(Spine,CP1,F1,FBID)) {
1030 FillSD(DStr,CD4,M2,H2.Domain(iH2,Ind2(ion2.Last())),
1031 H2.Domain(iH2,Ind2(ion2.Last())).SecondPoint().Parameter(),0,2,pitol,bout2);
1032 if(!CP2.IsOnArc() || (CP2.IsOnArc() && SearchFace(Spine,CP2,F2,FBID))) {
1034 if(Spine->LastStatus() != ChFiDS_OnSame) {
1035 CD4->ChangeInterference(2).
1036 SetParameter(CD4->Interference(1).Parameter(0),0);
1037 intl = Standard_False;
1041 else intl = Standard_False;
1043 else if(CP2.IsOnArc()) {
1045 if(!SearchFace(Spine,CP2,F2,FBID)) {
1046 FillSD(DStr,CD4,M1,H1.Domain(iH1,Ind1(ion1.Last())),
1047 H1.Domain(iH1,Ind1(ion1.Last())).SecondPoint().Parameter(),0,1,pitol,bout2);
1048 if(!CP1.IsOnArc() || (CP1.IsOnArc() && SearchFace(Spine,CP1,F1,FBID))) {
1050 if(Spine->LastStatus() != ChFiDS_OnSame) {
1051 CD4->ChangeInterference(1).
1052 SetParameter(CD4->Interference(2).Parameter(0),0);
1053 intl = Standard_False;
1057 else intl = Standard_False;
1060 // select <onS> switcher so that to get on spine params from
1061 // Interference with a face where both edges at corner are OnSame
1063 if (intl && Spine->LastStatus() == ChFiDS_OnSame) {
1064 TopoDS_Edge threeE[3];
1065 ChFi3d_cherche_element(bout2,support,F1,threeE[0],boutemp);
1066 ChFi3d_cherche_element(bout2,support,F2,threeE[1],boutemp);
1067 threeE[2] = support;
1068 if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame)
1073 if (threeE[0].IsSame(threeE[1]))
1074 cout << "SplitKPart(), wrong corner vertex at switcher search" << endl;
1076 cntlFiOnS = 3 - onS;
1082 // SurfData are entirely suspended before the beginning of the edge.
1083 Standard_Boolean okdoc = SetData.IsEmpty();
1084 Standard_Integer i = 1;
1086 Handle(ChFiDS_SurfData)& CD5 = SetData.ChangeValue(i);
1087 Standard_Real ltg = CD5->Interference(onS).LastParameter();
1088 Standard_Real Nl = ComputeAbscissa(Spine->CurrentElementarySpine(Iedge),ltg);
1089 if (Nl < -tolesp) SetData.Remove(i);
1091 okdoc = (SetData.IsEmpty() || i > SetData.Length());
1095 // SurfData are entirely suspended after the end of the edge.
1096 Standard_Boolean okdoc = SetData.IsEmpty();
1097 Standard_Integer i = 1;
1099 Handle(ChFiDS_SurfData)& CD6 = SetData.ChangeValue(i);
1100 Standard_Real ftg = CD6->Interference(onS).FirstParameter();
1101 Standard_Real f = Spine->FirstParameter(Iedge);
1102 Standard_Real l = Spine->LastParameter(Iedge);
1103 Standard_Real Nl = ComputeAbscissa(Spine->CurrentElementarySpine(Iedge),ftg);
1104 if (Nl > (l - f + tolesp)) SetData.Remove(i);
1106 okdoc = (SetData.IsEmpty() || i > SetData.Length());
1109 // Add parameters of the spine on SurfDatas.
1110 // for (Standard_Integer i = 1; i <= SetData.Length(); i++) {
1112 for ( i = 1; i <= SetData.Length(); i++) {
1113 Standard_Boolean pokdeb = 0, pokfin = 0;
1114 Handle(ChFiDS_SurfData)& CD7 = SetData.ChangeValue(i);
1115 Standard_Real ftg = CD7->Interference(onS).FirstParameter();
1116 Standard_Real ltg = CD7->Interference(onS).LastParameter();
1117 Standard_Real fsp = ParamOnSpine(DStr,ftg,CD7,Spine,Iedge,intf,intl,tolesp,pokdeb);
1118 if(!pokdeb) fsp = ResetProl(DStr,CD7,Spine,Iedge,1);
1119 Standard_Real lsp = ParamOnSpine(DStr,ltg,CD7,Spine,Iedge,intf,intl,tolesp,pokfin);
1120 if(!pokfin) lsp = ResetProl(DStr,CD7,Spine,Iedge,0);
1121 if(Spine->IsPeriodic() && Iedge == Spine->NbEdges() && lsp < fsp) {
1122 lsp += Spine->Period();
1124 else if(Spine->IsPeriodic() && Iedge == 1 && lsp < fsp) {
1125 fsp -= Spine->Period();
1127 CD7->FirstSpineParam(fsp);
1128 CD7->LastSpineParam (lsp);
1131 if (intf && !SetData.IsEmpty()) {
1132 // extension of the spine
1133 Spine->SetFirstParameter(SetData.First()->FirstSpineParam());
1136 // Trnncation at the beginning.
1137 for (i = 1; i <= SetData.Length(); i++) {
1138 Handle(ChFiDS_SurfData)& CD8 = SetData.ChangeValue(i);
1139 Standard_Real fsp = CD8->FirstSpineParam();
1140 Standard_Real lsp = CD8->LastSpineParam();
1141 if (lsp > Spine->FirstParameter(Iedge)) {
1142 if (fsp > Spine->FirstParameter(Iedge)) {
1146 Trunc(CD8,Spine,S1,S2,Iedge,1,cntlFiOnS);
1152 SetData.Remove(1,i-1);
1157 if (intl && !SetData.IsEmpty()) {
1158 // extension of the spine
1159 Spine->SetLastParameter(SetData.Last()->LastSpineParam());
1162 // Truncation at the end.
1163 for (i = SetData.Length(); i >= 1; i--) {
1164 Handle(ChFiDS_SurfData)& CD9 = SetData.ChangeValue(i);
1165 Standard_Real fsp = CD9->FirstSpineParam();
1166 Standard_Real lsp = CD9->LastSpineParam();
1167 if (fsp < Spine->LastParameter(Iedge)) {
1168 if (lsp < Spine->LastParameter(Iedge)) {
1172 Trunc(CD9,Spine,S1,S2,Iedge,0,cntlFiOnS);
1177 if (i < SetData.Length()) {
1178 SetData.Remove(i+1,SetData.Length());
1182 if(ChFi3d_GettraceDRAWFIL()) {
1183 for (i = 1; i <= SetData.Length(); i++) {
1184 ChFi3d_CheckSurfData(DStr,SetData.Value(i));
1188 return Standard_True;