b311480e |
1 | // Created on: 1995-07-17 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
17 | #include CurveGen_hxx |
18 | #include <GeomAbs_CurveType.hxx> |
19 | #include <GeomAbs_Shape.hxx> |
cb389a77 |
20 | #include <Geom_BezierCurve.hxx> |
21 | #include <Geom_BSplineCurve.hxx> |
7fd59977 |
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 | //============================================================ |
31 | Standard_Integer IntCurveSurface_HCurveTool::NbSamples (const CurveGen& C, |
32 | const Standard_Real U0, |
33 | const Standard_Real U1) { |
34 | GeomAbs_CurveType typC = C->GetType(); |
41194117 |
35 | const Standard_Real nbsOther = 10.0; |
7fd59977 |
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 | //============================================================ |
54 | void 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(); |
41194117 |
61 | const Standard_Real nbsOther = 10.0; |
7fd59977 |
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 | } |