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