1// Created on: 1995-07-17
2// Created by: Modelistation
3// Copyright (c) 1995-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 CurveGen_hxx
18#include <GeomAbs_CurveType.hxx>
19#include <GeomAbs_Shape.hxx>
20#include <Geom_BezierCurve.hxx>
21#include <Geom_BSplineCurve.hxx>
22
23#include <TColStd_Array1OfReal.hxx>
24#include <TColStd_Array1OfBoolean.hxx>
25#include <gce_MakeLin.hxx>
26#include <gp_Pnt.hxx>
27#include <gp_Lin.hxx>
28
29#define myMinPnts 5
30//============================================================
31Standard_Integer IntCurveSurface_HCurveTool::NbSamples (const CurveGen& C,
32						       const Standard_Real U0,
33						       const Standard_Real U1) {
34  GeomAbs_CurveType typC = C->GetType();
35  const Standard_Real nbsOther = 10.0;
36  Standard_Real nbs = nbsOther;
37
38  if(typC == GeomAbs_Line)
39    nbs = 2;
40  else if(typC == GeomAbs_BezierCurve)
41    nbs = 3 + C->NbPoles();
42  else if(typC == GeomAbs_BSplineCurve) {
43    nbs = C->NbKnots();
44    nbs*= C->Degree();
45    nbs*= C->LastParameter()- C->FirstParameter();
46    nbs/= U1-U0;
47    if(nbs < 2.0) nbs=2;
48  }
49  if(nbs>50)
50    nbs = 50;
51  return((Standard_Integer)nbs);
52}
53//============================================================
54void IntCurveSurface_HCurveTool::SamplePars (const CurveGen& C,
55					     const Standard_Real U0,
56					     const Standard_Real U1,
57					     const Standard_Real Defl,
58					     const Standard_Integer NbMin,
59					     Handle(TColStd_HArray1OfReal)& Pars) {
60  GeomAbs_CurveType typC = C->GetType();
61  const Standard_Real nbsOther = 10.0;
62  Standard_Real nbs = nbsOther;
63
64  if(typC == GeomAbs_Line)
65    nbs = 2;
66  else if(typC == GeomAbs_BezierCurve) {
67    nbs = 3 + C->NbPoles();
68  }
69
70  if(typC != GeomAbs_BSplineCurve) {
71    if(nbs>50)
72      nbs = 50;
73    Standard_Integer nnbs = (Standard_Integer)nbs;
74
75    Pars = new TColStd_HArray1OfReal(1, nnbs);
76    Standard_Real du = (U1-U0)/(nnbs - 1);
77
78    Pars->SetValue(1, U0);
79    Pars->SetValue(nnbs, U1);
80    Standard_Integer i;
81    Standard_Real u;
82    for(i = 2, u = U0+du; i < nnbs; ++i, u += du) {
83      Pars->SetValue(i, u);
84    }
85    return;
86  }
87
88  const Handle(Geom_BSplineCurve)& aBC = C->BSpline();
89
90  Standard_Integer i, j, k, nbi;
91  Standard_Real t1, t2, dt;
92  Standard_Integer ui1 = aBC->FirstUKnotIndex();
93  Standard_Integer ui2 = aBC->LastUKnotIndex();
94
95  for(i = ui1; i < ui2; ++i) {
96    if(U0 >= aBC->Knot(i) && U0 < aBC->Knot(i+1)) {
97      ui1 = i;
98      break;
99    }
100  }
101
102  for(i = ui2; i > ui1; --i) {
103    if(U1 <= aBC->Knot(i) && U1 > aBC->Knot(i-1)) {
104      ui2 = i;
105      break;
106    }
107  }
108
109  Standard_Integer nbsu = ui2-ui1+1; nbsu += (nbsu - 1) * (aBC->Degree()-1);
110  Standard_Boolean bUniform = Standard_False;
111  if(nbsu < NbMin) {
112    nbsu = NbMin;
113    bUniform = Standard_True;
114  }
115
116  TColStd_Array1OfReal aPars(1, nbsu);
117  TColStd_Array1OfBoolean aFlg(1, nbsu);
118  //Filling of sample parameters
119  if(bUniform) {
120    t1 = U0;
121    t2 = U1;
122    dt = (t2 - t1)/(nbsu - 1);
123    aPars(1) = t1;
124    aFlg(1) = Standard_False;
125    aPars(nbsu) = t2;
126    aFlg(nbsu) = Standard_False;
127    for(i = 2, t1 += dt; i < nbsu; ++i, t1 += dt) {
128      aPars(i) = t1;
129      aFlg(i) = Standard_False;
130    }
131  }
132  else {
133    nbi = aBC->Degree();
134    k = 0;
135    t1 = U0;
136    for(i = ui1+1; i <= ui2; ++i) {
137      if(i == ui2) t2 = U1;
138      else t2 = aBC->Knot(i);
139      dt = (t2 - t1)/nbi;
140      j = 1;
141      do {
142	++k;
143	aPars(k) = t1;
144	aFlg(k) = Standard_False;
145	t1 += dt;
146      }
147      while (++j <= nbi);
148      t1 = t2;
149    }
150    ++k;
151    aPars(k) = t1;
152  }
153 //Analysis of deflection
154
155
156  Standard_Real aDefl2 = Max(Defl*Defl, 1.e-9);
157  Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
158  Standard_Integer l;
159
160  Standard_Integer NbSamples = 2;
161  aFlg(1) = Standard_True;
162  aFlg(nbsu) = Standard_True;
163  j = 1;
164  Standard_Boolean bCont = Standard_True;
165  while (j < nbsu-1 && bCont) {
166
167    if(aFlg(j+1)) {
168      ++j;
169      continue;
170    }
171
172    t2 = aPars(j);
173    gp_Pnt p1 = aBC->Value(t2);
174    for(k = j+2; k <= nbsu; ++k) {
175      t2 = aPars(k);
176      gp_Pnt p2 = aBC->Value(t2);
177
178      if(p1.SquareDistance(p2) <= tol) continue;
179
180      gce_MakeLin MkLin(p1, p2);
181      const gp_Lin& lin = MkLin.Value();
182      Standard_Boolean ok = Standard_True;
183      for(l = j+1; l < k; ++l) {
184
185	if(aFlg(l)) {
186	  ok = Standard_False;
187	  break;
188	}
189
190	gp_Pnt pp =  aBC->Value(aPars(l));
191	Standard_Real d = lin.SquareDistance(pp);
192
193	if(d <= aDefl2) continue;
194
195	ok = Standard_False;
196	break;
197      }
198
199      if(!ok) {
200	j = k - 1;
201	aFlg(j) = Standard_True;
202	++NbSamples;
203	break;
204      }
205
206      if(aFlg(k)) {
207	j = k;
208	break;
209      }
210
211
212    }
213
214    if(k >= nbsu) bCont = Standard_False;
215
216  }
217
218  if(NbSamples < myMinPnts) {
219    //uniform distribution
220    NbSamples = myMinPnts;
221    Pars = new TColStd_HArray1OfReal(1, NbSamples);
222    t1 = U0;
223    t2 = U1;
224    dt = (t2 - t1)/(NbSamples - 1);
225    Pars->SetValue(1, t1);
226    Pars->SetValue(NbSamples, t2);
227    for(i = 2, t1 += dt; i < NbSamples; ++i, t1 += dt) {
228      Pars->SetValue(i, t1);
229    }
230    return;
231  }
232
233  Pars = new TColStd_HArray1OfReal(1, NbSamples);
234  j = 0;
235  for(i = 1; i <= nbsu; ++i) {
236    if(aFlg(i)) {
237      ++j;
238      Pars->SetValue(j,aPars(i));
239    }
240  }
241
242
243
244}
245