0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / IntCurveSurface / IntCurveSurface_HCurveTool.gxx
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 //============================================================
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();
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 //============================================================
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();
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 }