1// Created on: 1992-10-12
2// Created by: Laurent BUCHARD
3// Copyright (c) 1992-1999 Matra Datavision
4// Copyright (c) 1999-2014 OPEN CASCADE SAS
5//
6// This file is part of Open CASCADE Technology software library.
7//
8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
13//
14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
16
17#include <Standard_ConstructionError.hxx>
18#include <Bnd_Box.hxx>
19#include <TColgp_Array1OfPnt.hxx>
20#include <gp_Lin.hxx>
21#include <gp_Vec.hxx>
22#include <gp_Dir.hxx>
23
24
25//======================================================================
26//== On echantillonne sur le Domain de la Curve  NbPts Points
27//== a parametres constants.
28//==
29//== On estime la fleche maximum en prenant la distance maxi entre la
30//== droite Curve.Value(X(i))-->Curve.Value(X(i+1))
31//== et le point Curve.Value(X(i+1/2))
32//======================================================================
33IntCurveSurface_Polygon::IntCurveSurface_Polygon(const TheCurve&        C,
34						 const Standard_Integer tNbPts):
35       ThePnts(1,(tNbPts<5)? 5 : tNbPts)
36{
37  Standard_Integer NbPts = (tNbPts<5)? 5 : tNbPts;
38  NbPntIn = NbPts;
39  Binf = TheCurveTool::FirstParameter(C);
40  Bsup = TheCurveTool::LastParameter(C);
41  Init(C);
42}
43
44
45
46IntCurveSurface_Polygon::IntCurveSurface_Polygon(const TheCurve&        C,
47						 const Standard_Real    U1,
48						 const Standard_Real    U2,
49						 const Standard_Integer tNbPts):
50       ThePnts(1,(tNbPts<5)? 5 : tNbPts) , Binf(U1) , Bsup(U2)
51{
52
53
54  Standard_Integer NbPts = (tNbPts<5)? 5 : tNbPts;
55  NbPntIn = NbPts;
56  Init(C);
57}
58
59//=======================================================================
60//function : IntCurveSurface_Polygon
61//purpose  :
62//=======================================================================
63
64IntCurveSurface_Polygon::IntCurveSurface_Polygon(const TheCurve&        C,
65						 const TColStd_Array1OfReal& Upars):
66       ThePnts(1,Upars.Length()) , Binf(Upars(Upars.Lower())) , Bsup(Upars(Upars.Upper()))
67{
68
69  //ddout << "IntCurveSurface_Polygon::IntCurveSurface_Polygon" << endl;
70  Standard_Integer NbPts = Upars.Length();
71  //ddout << "NbPts :" << NbPts << endl;
72  NbPntIn = NbPts;
73  Init(C, Upars);
74}
75
76
77void IntCurveSurface_Polygon::Init(const TheCurve&        C) {
78
79  Standard_Real u=Binf;
80  Standard_Real u1=Bsup;
81  Standard_Real du=(u1-u)/(Standard_Real)(NbPntIn-1);
82  Standard_Integer i=1;
83  gp_Pnt P;
84  do {
85    TheCurveTool::D0(C,u,P);
86    TheBnd.Add(P);
87    ThePnts.SetValue(i,P);
88    u+=du;
89    i++;
90  }
91  while(i<=NbPntIn);
92
93
94  //-----------------------------------------------------
95  //--- Calcul d un majorant de fleche approche
96  //---
97  TheDeflection = 0.0;
98
99  if(NbPntIn>3) {
100
101    i=1;
102    u=Binf;
103    u+=du * 0.5;
104
105    do {
106      gp_Pnt Pm=TheCurveTool::Value(C,u);
107      gp_Pnt P1=ThePnts.Value(i);
108      gp_Pnt P2=ThePnts.Value(i+1);
109      gp_Lin L(P1,gp_Dir(gp_Vec(P1,P2)));
110      Standard_Real t=L.Distance(Pm);
111
112      if(t>TheDeflection) {
113	TheDeflection = t;
114      }
115      u+=du;
116      i++;
117    }
118    while(i<NbPntIn);
119
120    TheBnd.Enlarge(1.5*TheDeflection);
121  }
122  else {
123    TheBnd.Enlarge(1e-10);
124  }
125  ClosedPolygon = Standard_False;
126}
127
128//=======================================================================
129//function : Init
130//purpose  :
131//=======================================================================
132
133void IntCurveSurface_Polygon::Init(const TheCurve&        C,
134				   const TColStd_Array1OfReal& Upars) {
135
136  //ddout << "IntCurveSurface_Polygon::Init" << endl;
137  Standard_Real u=Binf;
138  Standard_Integer i=1, i0 = Upars.Lower()-1;
139  gp_Pnt P;
140
141  myParams = new TColStd_HArray1OfReal(1, Upars.Length());
142  do {
143    //ddout << "-------------Parameter : " << i << " " << Upars(i+i0) << endl;
144    myParams->SetValue(i, Upars(i+i0));
145    TheCurveTool::D0(C,Upars(i+i0),P);
146    //ddout << "P : " << P.X() << " " << P.Y() << " " << P.Z() << endl;
147    TheBnd.Add(P);
148    ThePnts.SetValue(i,P);
149    i++;
150  }
151  while(i<=NbPntIn);
152
153
154  //-----------------------------------------------------
155  //--- Calcul d un majorant de fleche approche
156  //---
157  TheDeflection = 0.0;
158
159  if(NbPntIn>3) {
160
161    i=1;
162    //ddout << "Deflection estimation" << endl;
163    do {
164      u = 0.5*(Upars(i0+i)+Upars(i0+i+1));
165      //ddout << "===========Parameter : " << i << " " << u << endl;
166      gp_Pnt Pm=TheCurveTool::Value(C,u);
167      //ddout << "Pm : " << Pm.X() << " " << Pm.Y() << " " << Pm.Z() << endl;
168      gp_Pnt P1=ThePnts.Value(i);
169      //ddout << "P1 : " << P1.X() << " " << P1.Y() << " " << P1.Z() << endl;
170      gp_Pnt P2=ThePnts.Value(i+1);
171      //ddout << "P2 : " << P2.X() << " " << P2.Y() << " " << P2.Z() << endl;
172      gp_Lin L(P1,gp_Dir(gp_Vec(P1,P2)));
173      Standard_Real t=L.Distance(Pm);
174      //ddout << "Distance " << t << endl;
175      if(t>TheDeflection) {
176	TheDeflection = t;
177      }
178      i++;
179    }
180    while(i<NbPntIn);
181    //ddout << " TheDeflection = " << TheDeflection << endl;
182    TheBnd.Enlarge(1.5*TheDeflection);
183  }
184  else {
185    TheBnd.Enlarge(1e-10);
186  }
187  ClosedPolygon = Standard_False;
188}
189
190
191//======================================================================
192Standard_Real IntCurveSurface_Polygon::ApproxParamOnCurve(const Standard_Integer TheIndex,
193							  const Standard_Real    TheParamOnLine) const
194{
195  //ddout << "IntCurveSurface_Polygon::ApproxParamOnCurve" << endl;
196  if(TheParamOnLine < 0.0 || TheParamOnLine >1.0) {
197#ifdef OCCT_DEBUG
198    std::cout<<" ParamOnLine  =  "<<TheParamOnLine<<"  avec Index = "
199      <<TheIndex<<"  dans IntCurveSurface_Polygon::ApproxParamOnCurve"<<std::endl;
200#endif
201    return(Binf+(TheParamOnLine*(Bsup-Binf))/(Standard_Real)(NbPntIn-1));
202  }
203
204  Standard_Integer Index = TheIndex;
205  Standard_Real    ParamOnLine = TheParamOnLine;
206#ifdef OCCT_DEBUG
207  if (Index > NbPntIn) {
208    std::cout << "OutOfRange Polygon::ApproxParamOnCurve " <<std::endl;
209  }
210#endif
211  if((Index == NbPntIn) && (ParamOnLine == 0.0)) {
212    Index--; ParamOnLine=1.0;
213  }
214
215  Standard_Real du, u;
216  if (myParams.IsNull())
217    {
218      du = (Bsup-Binf)/(Standard_Real)(NbPntIn-1);
219      u  = Binf + du * (Standard_Real)(Index-1);
220    }
221  else
222    {
223      du = myParams->Value(Index+1) - myParams->Value(Index);
224      u  = myParams->Value(Index);
225    }
226
227  u += du * ParamOnLine;
228  return (u);
229}
230
231
232//======================================================================
233void IntCurveSurface_Polygon::Dump(void) const {
234#if 0
235  static Standard_Integer Compteur=0;
236  char tamp[100];
237  Compteur++;
238  sprintf(tamp,"Poly%d",Compteur);
239  std::cout<<"  @@@@@@@@@@@ F i c h i e r   :   "<<tamp<<" @@@@@@@@@@"<<std::endl;
240  FILE *fp;
241  fp=fopen(tamp,"w");
242  if(fp==NULL) {
243    std::cout<<"PolyGonGen::Erreur en Ouverture Fichier"<<tamp<<std::endl;
244    return;
245  }
246  fprintf(fp,"\n#Discretisation de : %f ---> %f \n",Binf,Bsup);
247  fprintf(fp,"\npol %d %d %f",Compteur,NbPntIn,TheDeflection);
248  gp_Pnt p1,p2;
249  for (Standard_Integer iObje=1; iObje<=NbSegments(); iObje++) {
250    p1=BeginOfSeg(iObje);
251    fprintf(fp,"\npnt %d %f %f",Compteur,p1.X(),p1.Y());
252  }
253  p1=EndOfSeg(NbSegments());
254  fprintf(fp,"\npnt %d %f %f",Compteur,p1.X(),p1.Y());
255  fprintf(fp,"\ndispol %d\n#\n",Compteur);
256  fclose(fp);
257#endif
258}
259//======================================================================
260//======================================================================
261