How to use taper method in SeleniumBase

Best Python code snippet using SeleniumBase

taper.py

Source:taper.py Github

copy

Full Screen

1'''2Script to calculate feeds for step boring in the lathe. An example is to3make a Morse taper by step-boring, followed by reaming.4'''5if 1: # Copyright, license6 # These "trigger strings" can be managed with trigger.py7 #∞copyright∞# Copyright (C) 2014 Don Peterson #∞copyright∞#8 #∞contact∞# gmail.com@someonesdad1 #∞contact∞#9 #∞license∞#10 # Licensed under the Open Software License version 3.0.11 # See http://opensource.org/licenses/OSL-3.0.12 #∞license∞#13 #∞what∞#14 # Calculate feeds for step-boring in lathe15 #∞what∞#16 #∞test∞# #∞test∞#17 pass18if 1: # Imports19 import sys20 import math21 import getopt22 import time23 from pprint import pprint as pp24 from pdb import set_trace as xx25if 1: # Custom imports26 from wrap import dedent27 from u import u, ParseUnit28 from get import GetNumber29 from bidict import bidict30 from frange import frange31 from sig import sig32if 1: # Global variables33 nl = "\n"34 ii = isinstance35 # indicator_size defines the range in inches of the longitudinal36 # measurement with a dial indicator on the lathe.37 indicator_size = 238 # Set dbg to True to get input data automatically for debugging39 dbg = 140class Taper(object):41 'Base class for tapers'42 def __init__(self, sizes):43 if not ii(sizes, set):44 raise ValueError("sizes must be a set")45 self.sizes = sizes46 self.data = {}47 def __str__(self):48 name = self.name49 sizes = tuple(self.sizes)50 return "{name}{sizes}".format(**locals())51 def errmsg(self, n):52 return "'{}' is a bad {} taper number".format(str(n), self.name)53 def __call__(self, size):54 '''Returns the tuple (tpf, small_diameter, length) in inches for a55 taper number size of this particular taper.56 '''57 raise ValueError("Abstract base class")58class Morse(Taper):59 def __init__(self):60 self.name = "Morse"61 self.super = super(Morse, self)62 self.super.__init__(set(range(8)))63 # Dimensions in inches; see MH, 19th ed., pg 1679. The symbols64 # are: tpf is the taper in inches per foot, D is the small65 # diameter of the plug, H is the depth of the hole, and X is the66 # additional length of the socket such that P = H - X = plug depth.67 self.data = {68 # tpf D H X69 0 : [0.62460, 0.252, 2+1/32, 1/32],70 1 : [0.59858, 0.369, 2+5/32, 1/16],71 2 : [0.59941, 0.572, 2+39/64, 1/16],72 3 : [0.60235, 0.778, 3+1/4, 1/16],73 4 : [0.62326, 1.020, 4+1/8, 1/16],74 5 : [0.63151, 1.475, 5+1/4, 1/16],75 6 : [0.62565, 2.116, 7+21/64, 1/16],76 7 : [0.62400, 2.750, 10+5/64, 1/16],77 }78 self.data = {79 # tpf = taper in inches per foot80 # A = large diameter81 # H = hole depth82 # tpf A H83 0 : [0.62460, 0.3561, 2+1/32],84 1 : [0.59858, 0.475 , 2+5/32],85 2 : [0.59941, 0.700 , 2+39/64],86 3 : [0.60235, 0.938 , 3+1/4],87 4 : [0.62326, 1.231 , 4+1/8],88 5 : [0.63151, 1.748 , 5+1/4],89 6 : [0.62565, 2.494 , 7+21/64],90 7 : [0.62400, 3.270 , 10+5/64],91 }92 def __call__(self, n):93 '''Return the tuple (D, d, L) where the dimensions are in inches.94 D is the large diameter, d is the small diameter, and L is the95 length of the Morse taper socket. n is the taper number.96 '''97 if n not in self.sizes:98 raise ValueError(self.errmsg(n))99 X = 1/16 if n else 1/32100 tpf, D, L = self.data[n]101 tpi = tpf/12 # Taper per inch in inch/inch102 d = D - (L - X)*tpi103 n = 4104 return (round(D, n), round(d, n), round(L, n))105class Jarno(Taper):106 def __init__(self):107 self.name = "Jarno"108 self.super = super(Jarno, self)109 self.super.__init__(set(range(2, 21)))110 def __call__(self, n):111 '''Return the tuple (D, d, L) where the dimensions are in inches.112 D is the large diameter, d is the small diameter, and L is the113 length of the socket. n is the taper number.114 115 See MH, 19th ed., pg 1683. If n is the taper number, then116 (dimensions in inches)117 D = n/8118 d = n/10119 L = n/2120 '''121 if n not in self.sizes:122 raise ValueError(self.errmsg(n))123 return (round(n/8, 3), round(n/10, 3), round(n/2, 3))124class BrownAndSharpe(Taper):125 def __init__(self):126 self.name = "Brown & Sharpe"127 self.super = super(BrownAndSharpe, self)128 self.super.__init__(set(range(1, 19)))129 self.data = {130 # Reference MH, 19th ed., pg 1682.131 # [ tpf(inch), minor_dia, length]132 1 : [0.50200, 0.20000, 15/16],133 2 : [0.50200, 0.25000, 1+3/16],134 3 : [0.50200, 0.31250, 1+1/2],135 4 : [0.50240, 0.35000, 1+11/16],136 5 : [0.50160, 0.45000, 2+1/8],137 6 : [0.50329, 0.50000, 2+3/8],138 7 : [0.50147, 0.60000, 2+7/8],139 8 : [0.50100, 0.75000, 3+9/16],140 9 : [0.50085, 0.90010, 4+1/4],141 10 : [0.51612, 1.04465, 5],142 11 : [0.50100, 1.24995, 5+15/16],143 12 : [0.49973, 1.50010, 7+1/8],144 13 : [0.50020, 1.75005, 7+3/4],145 14 : [0.50000, 2.00000, 8+1/4],146 15 : [0.50000, 2.25000, 8+3/4],147 16 : [0.50000, 2.50000, 9+1/4],148 17 : [0.50000, 2.75000, 9+3/4],149 18 : [0.50000, 3.00000, 10+1/4],150 }151 def __call__(self, n):152 '''Return the tuple (D, d, L) where the dimensions are in inches.153 D is the large diameter, d is the small diameter, and L is the154 length of the socket. n is the taper number.155 '''156 if n not in self.sizes:157 raise ValueError(self.errmsg(n))158 # Symbols are from page 1682 of MH, 19th ed. tpf = taper per foot,159 # d = diameter of small end of plug, P = plug depth.160 tpf, d, P = self.data[n]161 tpi = tpf/12162 D = d + P*tpi163 return (round(D, 4), round(d, 5), round(P, 4))164class Jacobs(Taper):165 def __init__(self):166 self.name = "Jacobs"167 self.super = super(Jacobs, self)168 sizes = set(range(7))169 sizes.add(33)170 self.super.__init__(sizes)171 self.data = {172 # Reference MH, 19th ed., pg 1690.173 0 : [0.2500, 0.22844, 0.43750],174 1 : [0.3840, 0.33341, 0.65625],175 2 : [0.5590, 0.48764, 0.87500],176 3 : [0.8110, 0.74610, 1.21875],177 4 : [1.1240, 1.03720, 1.65630],178 5 : [1.4130, 1.31610, 1.87500],179 6 : [0.6760, 0.62410, 1.00000],180 33 : [0.6240, 0.56050, 1.00000],181 }182 def __call__(self, n):183 '''Return the tuple (D, d, L) where the dimensions are in inches.184 D is the large diameter, d is the small diameter, and L is the185 length of the socket. n is the taper number.186 '''187 if n not in self.sizes:188 raise ValueError(self.errmsg(n))189 return self.data[n]190class Sellers(Taper):191 '''Defined on page 791 and 795 of Colvin & Stanley, "American192 Machinist's Handbook", 8th ed., 1945. Also see page 1687 of MH, 19th193 ed.194 '''195 def __init__(self):196 self.name = "Sellers"197 self.super = super(Sellers, self)198 sizes = set((200, 250, 300, 350, 400, 450, 500, 600, 800, 1000, 1200))199 self.super.__init__(sizes)200 self.tpf = 1 + 3/4201 self.Bprime = { # Length from gauge line202 200 : 5+1/8,203 250 : 5+7/8,204 300 : 6+5/8,205 350 : 7+7/16,206 400 : 8+3/16,207 450 : 9,208 500 : 9+3/4,209 600 : 11+5/16,210 800 : 14+3/8,211 1000 : 17+7/16,212 1200 : 20+1/2,213 }214 def __call__(self, n):215 '''Return the tuple (D, d, L) where the dimensions are in inches.216 D is the large diameter, d is the small diameter, and L is the217 length of the socket. n is the taper number.218 '''219 if n not in self.sizes:220 raise ValueError(self.errmsg(n))221 D = n/100222 L = self.Bprime[n]223 tpi = self.tpf/12224 d = D - L*tpi225 return (D, d, L)226class NMTB(Taper):227 '''Defined on page 1691 of MH, 19th ed.228 '''229 def __init__(self):230 self.name = "NMTB"231 self.super = super(NMTB, self)232 sizes = set((30, 40, 50, 60))233 self.super.__init__(sizes)234 self.tpi = 3.5/12235 self.data = {236 # A = large diameter of taper237 # C = small diameter of taper238 # A C239 30 : (1+1/4, 0.6885),240 40 : (1+3/4, 1.001),241 50 : (2+3/4, 1.5635),242 60 : (4+1/4, 2.376),243 }244 def __call__(self, n):245 '''Return the tuple (D, d, L) where the dimensions are in inches.246 D is the large diameter, d is the small diameter, and L is the247 length of the socket. n is the taper number.248 '''249 if n not in self.sizes:250 raise ValueError(self.errmsg(n))251 D, d = self.data[n]252 L = (D - d)/self.tpi253 return (D, d, L)254def Error(msg, status=1):255 print(msg, file=sys.stderr)256 exit(status)257def Introduction():258 if dbg:259 return260 names = [" " + i for i in taper_names]261 print(dedent(f'''262 This script will print a table of step-boring dimensions for a tapered263 hole. You'll be prompted for the following information:264 - Standard taper name and size number265 or266 - Taper large and small diameters and length267 - Clearance between the step corners and the taper (this determines the268 amount of material that would need to be reamed out after step boring269 was finished).270 - Longitudinal step size271 - Units to display the output report in272 273 The default units are inches; you can use other common length units and274 metric prefixes as desired.275 276 The allowed standard taper names are:277 {nl.join(names)}278 '''))279def RTZ(s):280 '''Replace trailing 0 characters in s with spaces but don't change the281 length of s.282 '''283 t, i, n = list(reversed(list(s))), 1, len(s)284 if t[0] == "0":285 t[0] = " "286 while t[i - 1] == " " and t[i] == "0" and i < len(t):287 t[i] = " "288 i += 1289 t = ''.join(reversed(t))290 # Remove "." if it's the last non-space character291 u = t.rstrip()292 if u[-1] == ".":293 u = u[:-1] + " "294 u += " "*(n - len(u))295 return u296def Report(opts):297 print(f"{time.asctime():^78s}")298 if opts["taper_type"] != "dimensioned":299 print(opts["taper_type"], "#" + str(opts["taper_number"]),300 "standard taper")301 print()302 D = opts["D"] # inches303 d = opts["d"] # inches304 L = opts["L"] # inches305 diff = sig(D - d)306 tpi = (D - d)/L307 tpi_ = sig(tpi)308 tpf_ = sig(tpi*12)309 tps = tpi*opts["step_size"]310 tps_ = sig(tps)311 # Fill locals with desired strings to be printed312 D_ = RTZ(sig(opts["D"]))313 d_ = RTZ(sig(opts["d"]))314 L_ = RTZ(sig(opts["L"]))315 clearance = RTZ(sig(opts["clearance"]))316 step_size = RTZ(sig(opts["step_size"]))317 print(dedent(f'''318 Taper dimensions in inches:319 D = large diameter = {D_}320 d = small diameter = {d_}321 Diameter difference = {diff}322 L = length = {L_}323 Clearance = {clearance}324 Step size = {step_size}325 Taper = {tpi_} inch/inch = {tpf_} inch/foot326 Taper per step = {tps_} inch327 '''))328 # Generate report329 print(dedent(f'''330 331 The following cutting schedule starts at the deepest part of the tapered332 bore (x = 0). First bore a hole to the small diameter above less the333 clearance (the entry under Diameter for x = 0), then move the cutting tool334 right one step and then move the cross slide out by the indicated step dy.335 Repeat until the large diameter has been cut.336 Total337 x dy Diameter x338 ------- ------ -------- -------'''))339 ss = opts["step_size"]340 m = 0 # Number of dial indicator ranges in x so far341 clr = opts["clearance"]342 for i, x in enumerate(frange(0, L + 0.9*ss, ss)):343 m_new, remainder = divmod(x, indicator_size)344 if m_new > m and remainder:345 print("Reset dial indicator")346 m = m_new347 X = x - m*indicator_size348 a = RTZ("{:10.3f}".format(X))349 b = RTZ("{:10.4f}".format(tps)) if i else " "*10350 c = RTZ("{:12.3f}".format(d - clr + i*tps))351 e = RTZ("{:10.3f}".format(x))352 print("{} {} {} {}".format(a, b, c, e))353def GetInfo(opts):354 '''Information needed:355 Standard taper or specify by dimensions?356 Standard: Morse, Jarno, B&S357 Dimensions: large dia, small dia, length358 Clearance from step to actual taper359 Radial step360 Longitudinal step361 Output dimensions [inch]362 '''363 if dbg:364 opts["taper_type"] = "Morse"365 opts["taper_number"] = 3366 opts["clearance"] = 0.002367 opts["clearance_input"] = ""368 opts["step_size"] = 0.1369 opts["step_size_input"] = ""370 T = Morse()371 D, d, L = T(opts["taper_number"])372 opts["D"] = D373 opts["D_input"] = str(D) + " in"374 opts["d"] = d375 opts["d_input"] = str(d) + " in"376 opts["L"] = L377 opts["L_input"] = str(L) + " in"378 return379 p = "Standard taper (1) or specified by dimensions (2)? "380 taper = GetNumber(p, numtype=int, default=1, low=1, high=2)381 opts["taper_type"] = "standard" if taper == 1 else "dimensioned"382 if 1:383 # Get taper type or dimensions384 if opts["taper_type"] == "standard":385 # Morse, Jarno, etc.386 print("Choose a taper type:")387 bd = bidict()388 for i, name in enumerate(taper_names):389 print(" {}) {}".format(i + 1, name))390 bd[i] = name391 morse = bd("Morse") + 1392 ok = False393 while not ok:394 try:395 choice = GetNumber("?", default=morse, numtype=int,396 low=1, high=len(taper_names))397 choice -= 1398 ok = True399 except ValueError:400 print("You must select one of the numbers.")401 opts["taper_type"] = taper_name = taper_names[choice]402 # Instantiate a taper object403 T = taper_objects[choice]()404 # Get taper number405 tapers = sorted(T.sizes)406 t = ' '.join([str(i) for i in tapers])407 ok, number = False, -1408 while number not in tapers:409 print('''Select a {} taper number from the following list:410 {}'''.format(taper_name, t))411 choice = input("? ")412 if choice.lower() == "q":413 exit(0)414 try:415 number = int(choice)416 except ValueError:417 print("'{}' is not a valid number".format(choice))418 opts["taper_number"] = number419 # Convert to dimensions D, d, and L in inches420 D, d, L = T(number)421 else:422 # Dimensioned423 # Get D in inches424 p = "What is large diameter? "425 value, unit = GetNumber(p, low=0, low_open=True, use_unit=True)426 unit = unit if unit else "in"427 D = value*u(unit)/u("inch")428 opts["D_input"] = (sig(value) + " " + unit).strip()429 # Get d in inches430 p = "What is small diameter? "431 while True:432 print(p, end="")433 answer = input()434 if answer.strip().lower() == "q":435 exit(0)436 value, unit = ParseUnit(answer)437 # Note value is a string438 opts["d_input"] = (value + " " + unit).strip()439 d = float(value)*u(unit)/u("inch")440 if d <= 0:441 print("Diameter must be > 0")442 elif d >= D:443 print("Diameter must be < {}".format(opts["D input"]))444 else:445 break446 # Get L in inches447 p = "What is length? "448 value, unit = GetNumber(p, low=0, low_open=True, use_unit=True)449 unit = unit if unit else "in"450 L = value*u(unit)/u("inch")451 opts["L_input"] = (sig(value) + " " + unit).strip()452 opts["D"] = D453 opts["d"] = d454 opts["L"] = L455 # Get clearance from step corner to taper456 p = "What is clearance from step corner to taper? "457 value, unit = GetNumber(p, low=0, use_unit=True, default=0.005)458 unit = unit if unit else "in"459 opts["clearance"] = value*u(unit)/u("inch")460 opts["clearance_input"] = (sig(value) + " " + unit).strip()461 # Get (longitudinal) step size462 p = "What is longitudinal step size? "463 value, unit = GetNumber(p, low=0, low_open=True, use_unit=True,464 default=0.1)465 unit = unit if unit else "in"466 opts["step_size"] = value*u(unit)/u("inch")467 opts["step_size_input"] = (sig(value) + " " + unit).strip()468 print()469if __name__ == "__main__":470 taper_names = ("Brown & Sharpe", "Jacobs", "Jarno", "Morse", "Sellers")471 taper_objects = (BrownAndSharpe, Jacobs, Jarno, Morse, Sellers)472 opts = {} # Options & data473 sig.digits = 4474 sig.rtz = True475 Introduction()476 GetInfo(opts)...

Full Screen

Full Screen

wigner_transform.py

Source:wigner_transform.py Github

copy

Full Screen

...127 This is to generalize in case user doesnot want to compute C_ell at every ell.128 Also apply tapering if needed.129 """130 if taper:131 self.taper_f=self.taper(l=l_cl,**kwargs)132 taper_f=self.taper_f['taper_f']133 cl=cl*taper_f134 print('taper:',taper_f)135 if np.all(wig_l==l_cl):136 return cl137 cl_int=interp1d(l_cl,cl,bounds_error=False,fill_value=0,138 kind='linear')139 if wig_l is None:140 wig_l=self.l141 cl2=cl_int(wig_l)142 return cl2143 def cl_cov_grid(self,l_cl=[],cl_cov=[],taper=False,**kwargs):144 """145 Interpolate a given C_ell covariance onto the grid of ells for which WT is intialized. 146 This is to generalize in case user doesnot want to compute C_ell at every ell.147 Also apply tapering if needed.148 """149 if taper:#FIXME there is no check on change in taper_kwargs150 if self.taper_f2 is None or not np.all(np.isclose(self.taper_f['l'],cl)):151 self.taper_f=self.taper(l=l,**kwargs)152 taper_f2=np.outer(self.taper_f['taper_f'],self.taper_f['taper_f'])153 self.taper_f2={'l':l,'taper_f2':taper_f2}154 cl=cl*self.taper_f2['taper_f2']155 if l_cl==[]:#In this case pass a function that takes k with kwargs and outputs cl156 cl2=cl_cov(l=self.l,**kwargs)157 else:158 cl_int=RectBivariateSpline(l_cl,l_cl,cl_cov,)#bounds_error=False,fill_value=0,159 #kind='linear')160 #interp2d is slow. Make sure l_cl is on regular grid.161 cl2=cl_int(self.l,self.l)162 return cl2163 def projected_correlation(self,l_cl=[],cl=[],s1_s2=[],wig_l=None,taper=False,wig_d=None,wig_norm=None,**kwargs):164 """165 Get the projected correlation function from given c_ell.166 """167 if wig_d is None: #when using default wigner matrices, interpolate to ensure grids match.168 wig_d=self.wig_d[s1_s2]169 wig_l=self.l170 wig_norm=self.wig_norm171 cl2=self.cl_grid(l_cl=l_cl,cl=cl,taper=taper,wig_l=wig_l,**kwargs)172 w=np.dot(wig_d*wig_norm,cl2)173 return self.theta[s1_s2],w174 175 def inv_projected_correlation(self,theta_xi=[],xi=[],s1_s2=[],wig_theta=None,taper=False,wig_d=None,wig_norm=None,**kwargs):176 """177 Get the projected power spectra (c_ell) from given xi.178 """179 if wig_d is None: #when using default wigner matrices, interpolate to ensure grids match.180 wig_d=self.wig_d[s1_s2].T181 wig_theta=self.theta[s1_s2]182 wig_norm=self.inv_wig_norm183 if wig_theta is None:184 wig_theta=self.theta[s1_s2]185 xi2=self.cl_grid(l_cl=theta_xi,cl=xi,taper=taper,wig_l=wig_theta,**kwargs)186 cl=np.dot(wig_d*wig_norm,xi2)187 return self.l,cl188 def projected_covariance(self,l_cl=[],cl_cov=[],s1_s2=[],s1_s2_cross=None,189 wig_d1=None,wig_d2=None,wig_norm=None,wig_l=None,190 grad_l=None,taper=False,**kwargs):191 """192 Turn the power spectra covariance into correlation function covariance. 193 In this function, cl_cov is assumed to be a 1-d vector (the diagonal of the194 power spectra covariance). See projected_covariance2 for the case when 195 cl_cov is a two-dimensional matrix.196 """197 if s1_s2_cross is None:198 s1_s2_cross=s1_s2199 if wig_d1 is None:200 wig_d1=self.wig_d[s1_s2]201 wig_d2=self.wig_d[s1_s2_cross]202 wig_l=self.l203 wig_norm=self.wig_norm204 205 #return self.theta[s1_s2],wig_d1@np.diag(cl_cov)@wig_d2.T206 #when cl_cov can be written as vector, eg. gaussian covariance207 cl2=self.cl_grid(l_cl=l_cl,cl=cl_cov,taper=taper,wig_l=wig_l,**kwargs)208 if grad_l is None:209 grad_l=np.gradient(wig_l)210 cov=(wig_d1*np.sqrt(wig_norm))@np.diag(cl2*grad_l)@(wig_d2*(np.sqrt(wig_norm))).T211# cov=np.einsum('rk,k,sk->rs',self.wig_d[s1_s2]*np.sqrt(self.norm),cl2*self.grad_l,212# self.wig_d[s1_s2_cross]*np.sqrt(self.norm),optimize=True)213 #FIXME: Check normalization214 #FIXME: need to allow user to input wigner matrices.215 return self.theta[s1_s2],cov216 def projected_covariance2(self,l_cl=[],cl_cov=[],s1_s2=[],s1_s2_cross=None,217 wig_d1=None,wig_d2=None,218 taper=False,**kwargs):219 if wig_d1 is not None:220 #print(wig_d1.shape,cl_cov.shape)221 return self.theta[s1_s2],wig_d1@cl_cov@wig_d2.T222 #when cl_cov is a 2-d matrix223 if s1_s2_cross is None:224 s1_s2_cross=s1_s2225 cl_cov2=cl_cov #self.cl_cov_grid(l_cl=l_cl,cl_cov=cl_cov,s1_s2=s1_s2,taper=taper,**kwargs)226 cov=np.einsum('rk,kk,sk->rs',self.wig_d[s1_s2]*np.sqrt(self.norm)*self.grad_l,cl_cov2,227 self.wig_d[s1_s2_cross]*np.sqrt(self.norm),optimize=True)228# cov=np.dot(self.wig_d[s1_s2]*self.grad_l*np.sqrt(self.norm),np.dot(self.wig_d[s1_s2_cross]*np.sqrt(self.norm),cl_cov2).T)229 # cov*=self.norm230 #FIXME: Check normalization231 return self.theta[s1_s2],cov232 def taper(self,l=[],large_l_lower=1000,large_l_upper=1500,low_l_lower=10,low_l_upper=50):233 #FIXME there is no check on change in taper_kwargs234 if self.taper_f is None or not np.all(np.isclose(self.taper_f['l'],l)):235 taper_f=np.zeros_like(l,dtype='float64')236 x=l>large_l_lower237 taper_f[x]=np.cos((l[x]-large_l_lower)/(large_l_upper-large_l_lower)*np.pi/2.)238 x=np.logical_and(l<=large_l_lower , l>=low_l_upper)239 taper_f[x]=1240 x=l<low_l_upper241 taper_f[x]=np.cos((l[x]-low_l_upper)/(low_l_upper-low_l_lower)*np.pi/2.)242 243 x=np.logical_or(l<=low_l_lower , l>=large_l_upper)244 taper_f[x]=0245 self.taper_f={'taper_f':taper_f,'l':l}246 return self.taper_f...

Full Screen

Full Screen

bevel_curve.py

Source:bevel_curve.py Github

copy

Full Screen

1# This file is part of project Sverchok. It's copyrighted by the contributors2# recorded in the version control history of the file, available from3# its original location https://github.com/nortikin/sverchok/commit/master4# 5# SPDX-License-Identifier: GPL36# License-Filename: LICENSE7import numpy as np8from math import pi, cos, sin9from collections import defaultdict10from mathutils import Matrix, Vector11from sverchok.utils.math import (12 ZERO, FRENET, HOUSEHOLDER, TRACK, DIFF, TRACK_NORMAL,13 to_cylindrical_np, to_cylindrical,14 from_cylindrical_np15 )16from sverchok.utils.geom import LineEquation, rotate_vector_around_vector_np, autorotate_householder17from sverchok.utils.math import np_vectors_angle, np_signed_angle18from sverchok.utils.curve.core import UnsupportedCurveTypeException19from sverchok.utils.curve.primitives import SvCircle20from sverchok.utils.curve import knotvector as sv_knotvector21from sverchok.utils.curve.algorithms import (22 SvNormalTrack, curve_frame_on_surface_array,23 MathutilsRotationCalculator, DifferentialRotationCalculator,24 SvCurveFrameCalculator,25 SvCurveLengthSolver,26 reparametrize_curve27 )28from sverchok.utils.curve.nurbs_algorithms import refine_curve29from sverchok.utils.surface.core import SvSurface30from sverchok.utils.surface.nurbs import SvNurbsSurface31from sverchok.utils.surface.data import *32from sverchok.utils.surface.gordon import gordon_surface33from sverchok.utils.surface.algorithms import SvDeformedByFieldSurface, SvTaperSweepSurface34from sverchok.utils.field.vector import SvBendAlongCurveField35def bend_curve(field, curve):36 control_points = np.copy(curve.get_control_points())37 cpt_xs = control_points[:,0]38 cpt_ys = control_points[:,1]39 cpt_zs = control_points[:,2]40 cpt_dxs, cpt_dys, cpt_dzs = field.evaluate_grid(cpt_xs, cpt_ys, cpt_zs)41 xs = cpt_xs + cpt_dxs42 ys = cpt_ys + cpt_dys43 zs = cpt_zs + cpt_dzs44 control_points = np.stack((xs, ys, zs)).T45 return curve.copy(control_points = control_points)46def bend_surface(field, surface):47 control_points = np.copy(surface.get_control_points())48 m, n, _ = control_points.shape49 control_points = control_points.reshape((m*n, 3))50 cpt_xs = control_points[:,0]51 cpt_ys = control_points[:,1]52 cpt_zs = control_points[:,2]53 cpt_dxs, cpt_dys, cpt_dzs = field.evaluate_grid(cpt_xs, cpt_ys, cpt_zs)54 xs = cpt_xs + cpt_dxs55 ys = cpt_ys + cpt_dys56 zs = cpt_zs + cpt_dzs57 control_points = np.stack((xs, ys, zs)).T58 control_points = control_points.reshape((m,n,3))59 return surface.copy(control_points = control_points)60def place_profile_z(curve, z, scale):61 control_points = np.copy(curve.get_control_points())62 control_points[:,0] *= scale63 control_points[:,1] *= scale64 control_points[:,2] += z65 return curve.copy(control_points = control_points)66def place_profile(control_points, origin, scale):67 control_points = origin + control_points * scale68 return control_points69def rotate_curve_z(curve, angle, scale):70 control_points = np.copy(curve.get_control_points())71 control_points = control_points[:,0], control_points[:,1], control_points[:,2]72 rhos, phis, zs = to_cylindrical_np(control_points, mode='radians')73 xs, ys, zs = from_cylindrical_np(rhos*scale, phis+angle, zs, mode='radians')74 control_points = np.stack((xs, ys, zs)).T75 return curve.copy(control_points = control_points)76def rotate_curve(curve, axis, angle, scale):77 control_points = np.copy(curve.get_control_points())78 control_points = rotate_vector_around_vector_np(control_points, axis, angle)79 rotation_m = np.array(autorotate_householder(Vector(axis), Vector((0.0, 0.0, 1.0))).to_3x3())80 rotation_inv_m = np.linalg.inv(rotation_m)81 scale_m = np.eye(3)82 scale_m[0][0] = scale83 scale_m[1][1] = -scale84 #print("Scale", scale_m)85 #print("Rot", rotation_m)86 nonuniform_scale_m = np.linalg.inv(rotation_m) @ scale_m @ rotation_m87 control_points = [nonuniform_scale_m @ pt for pt in control_points]88 control_points = np.array(control_points)89 return curve.copy(control_points = control_points)90def nurbs_taper_sweep(profile, taper,91 point, direction, scale_base = SvTaperSweepSurface.UNIT):92 axis = LineEquation.from_direction_and_point(direction, point)93 taper_cpts = taper.get_control_points()94 taper_weights = taper.get_weights()95 taper_projections = axis.projection_of_points(taper_cpts)96 control_points = []97 weights = []98 if scale_base == SvTaperSweepSurface.TAPER:99 profile_t_min, profile_t_max = profile.get_u_bounds()100 profile_start = profile.evaluate(profile_t_min)101 profile_start_projection = axis.projection_of_point(profile_start)102 divisor = np.linalg.norm(profile_start - profile_start_projection)103 elif scale_base == SvTaperSweepSurface.PROFILE:104 taper_t_min, taper_t_max = taper.get_u_bounds()105 taper_start = taper.evaluate(taper_t_min)106 taper_start_projection = np.array(axis.projection_of_point(taper_start))107 divisor = np.linalg.norm(taper_start_projection - taper_start)108 else:109 divisor = 1.0110 profile_cpts = profile.get_control_points()111 n = len(profile_cpts)112 profile_knotvector = profile.get_knotvector()113 profile_weights = profile.get_weights()114 for taper_control_point, taper_projection, taper_weight in zip(taper_cpts, taper_projections, taper_weights):115 radius = np.linalg.norm(taper_control_point - taper_projection)116 if radius < 1e-8:117 parallel_points = np.empty((n,3))118 parallel_points[:] = taper_projection119 else:120 parallel_points = place_profile(profile_cpts, taper_projection, radius / divisor)121 parallel_weights = profile_weights * taper_weight122 control_points.append(parallel_points)123 weights.append(parallel_weights)124 control_points = np.array(control_points)125 control_points -= point126 weights = np.array(weights)127 degree_u = taper.get_degree()128 degree_v = profile.get_degree()129 return SvNurbsSurface.build(taper.get_nurbs_implementation(),130 degree_u, degree_v,131 taper.get_knotvector(), profile_knotvector,132 control_points, weights)133def nurbs_bevel_curve_simple(path, profile, taper,134 algorithm=SvBendAlongCurveField.HOUSEHOLDER,135 scale_all=False, path_axis=2,136 path_length_mode = 'T',137 path_length_resolution = 50,138 up_axis=None):139 taper_t_min, taper_t_max = taper.get_u_bounds()140 profile_t_min, profile_t_max = profile.get_u_bounds()141 taper_start = taper.evaluate(taper_t_min)142 taper_end = taper.evaluate(taper_t_max)143 z_min = taper_start[path_axis]144 z_max = taper_end[path_axis]145 field = SvBendAlongCurveField(path, algorithm, scale_all=scale_all, axis=path_axis, t_min=z_min, t_max=z_max, length_mode=path_length_mode, resolution=path_length_resolution, up_axis=up_axis)146 origin = np.zeros((3,), dtype=np.float64)147 direction = np.zeros((3,), dtype=np.float64)148 direction[path_axis] = 1.0149 sweeped = nurbs_taper_sweep(profile, taper, origin, direction, scale_base = SvTaperSweepSurface.TAPER)150 return bend_surface(field, sweeped).swap_uv()151def nurbs_bevel_curve_refined(path, profile, taper,152 algorithm=SvBendAlongCurveField.HOUSEHOLDER,153 scale_all=False, path_axis=2,154 path_length_mode = 'T',155 path_length_resolution = 50,156 up_axis=None,157 taper_refine=20):158 if path_length_mode == 'L':159 solver = SvCurveLengthSolver(taper)160 solver.prepare('SPL', path_length_resolution)161 else:162 solver = None163 taper = refine_curve(taper, taper_refine, solver=solver)164 return nurbs_bevel_curve_simple(path, profile, taper,165 algorithm = algorithm,166 scale_all = scale_all, path_axis = path_axis,167 path_length_mode = path_length_mode,168 path_length_resolution = path_length_resolution,169 up_axis = up_axis)170def nurbs_bevel_curve_gordon(path, profile, taper,171 algorithm=SvBendAlongCurveField.HOUSEHOLDER,172 scale_all=False, path_axis=2,173 path_length_mode = 'T',174 path_length_resolution = 50,175 up_axis=None,176 taper_samples=10, taper_refine=20, profile_samples=10):177 if profile.is_rational():178 raise Exception("Rational profile curves are not supported by Gordon algorithm")179 if taper.is_rational():180 raise Exception("Rational taper curves are not supported by Gordon algorithm")181 taper_t_min, taper_t_max = taper.get_u_bounds()182 profile_t_min, profile_t_max = profile.get_u_bounds()183 taper_start = taper.evaluate(taper_t_min)184 taper_end = taper.evaluate(taper_t_max)185 z_min = taper_start[path_axis]186 z_max = taper_end[path_axis]187 field = SvBendAlongCurveField(path, algorithm, scale_all=scale_all, axis=path_axis, t_min=z_min, t_max=z_max, length_mode=path_length_mode, resolution=path_length_resolution, up_axis=up_axis)188 if path_length_mode == 'T':189 taper_ts = np.linspace(taper_t_min, taper_t_max, num=taper_samples)190 else:191 solver = SvCurveLengthSolver(taper)192 solver.prepare('SPL', path_length_resolution)193 total_length = solver.get_total_length()194 input_lengths = np.linspace(0.0, total_length, num=taper_samples)195 taper_ts = solver.solve(input_lengths)196 taper_pts = taper.evaluate_array(taper_ts)197 taper_pts = taper_pts[:,0], taper_pts[:,1], taper_pts[:,2]198 taper_rhos, _, taper_zs = to_cylindrical_np(taper_pts)199 profile_start_rho = to_cylindrical(profile.evaluate(profile_t_min))[0]200 taper_start_rho, taper_start_angle, _ = to_cylindrical(taper.evaluate(taper_t_min))201 profiles = [place_profile_z(profile, z, scale) for z, scale in zip(taper_zs, taper_rhos / profile_start_rho)]202 profiles = [bend_curve(field, profile) for profile in profiles]203 profiles = [profile.reverse() for profile in profiles]204 profile_ts = np.linspace(profile_t_min, profile_t_max, num=profile_samples, endpoint=True)205 profile_pts = profile.evaluate_array(profile_ts)206 profile_pts = profile_pts[:,0], profile_pts[:,1], profile_pts[:,2]207 profile_rhos, profile_angles, _ = to_cylindrical_np(profile_pts, mode='radians')208 if path_length_mode == 'L':209 solver = SvCurveLengthSolver(taper)210 solver.prepare('SPL', path_length_resolution)211 else:212 solver = None213 taper = refine_curve(taper, taper_refine, solver=solver)214 tapers = [rotate_curve_z(taper, angle-taper_start_angle, scale) for angle, scale in zip(profile_angles, profile_rhos / profile_start_rho)]215 tapers = [bend_curve(field, taper) for taper in tapers]216 #intersections = [[taper.evaluate(t) for t in taper_ts] for taper in tapers]217 intersections = [[taper.evaluate(t) for taper in tapers] for t in taper_ts]218 return gordon_surface(tapers, profiles, intersections)[-1]219BEVEL_SIMPLE = 'SIMPLE'220BEVEL_REFINE = 'REFINE'221BEVEL_GORDON = 'GORDON'222def nurbs_bevel_curve(path, profile, taper,223 algorithm=SvBendAlongCurveField.HOUSEHOLDER,224 scale_all=False, path_axis=2,225 path_length_mode = 'T',226 path_length_resolution = 50,227 up_axis=None,228 precision_method = BEVEL_GORDON,229 taper_samples=10, taper_refine=20, profile_samples=10):230 231 if precision_method == BEVEL_GORDON:232 return nurbs_bevel_curve_gordon(path, profile, taper,233 algorithm = algorithm,234 scale_all = scale_all, path_axis = path_axis,235 path_length_mode = path_length_mode,236 path_length_resolution = path_length_resolution,237 up_axis = up_axis,238 taper_samples = taper_samples, taper_refine = taper_refine,239 profile_samples = profile_samples)240 elif precision_method == BEVEL_REFINE:241 return nurbs_bevel_curve_refined(path, profile, taper,242 algorithm = algorithm,243 scale_all = scale_all, path_axis = path_axis,244 path_length_mode = path_length_mode,245 path_length_resolution = path_length_resolution,246 up_axis = up_axis,247 taper_refine = taper_refine)248 elif precision_method == BEVEL_SIMPLE:249 return nurbs_bevel_curve_simple(path, profile, taper,250 algorithm = algorithm,251 scale_all = scale_all, path_axis = path_axis,252 path_length_mode = path_length_mode,253 path_length_resolution = path_length_resolution,254 up_axis = up_axis)255 else:256 raise Exception("Unknown method")257def generic_bevel_curve(path, profile, taper,258 algorithm=SvBendAlongCurveField.HOUSEHOLDER,259 scale_all=False, path_axis=2,260 path_length_mode = 'T',261 path_length_resolution = 50,262 up_axis=None,263 scale_base = SvTaperSweepSurface.PROFILE):264 taper_t_min, taper_t_max = taper.get_u_bounds()265 profile_t_min, profile_t_max = profile.get_u_bounds()266 taper_start = taper.evaluate(taper_t_min)267 taper_end = taper.evaluate(taper_t_max)268 z_min = taper_start[path_axis]269 z_max = taper_end[path_axis]270 origin = np.array([0.0, 0.0, 0.0])271 direction = np.eye(3)[path_axis]272 sweep_surface = SvTaperSweepSurface(profile, taper,273 origin, direction,274 scale_base = scale_base)275 bend_field = SvBendAlongCurveField(path, algorithm, scale_all=scale_all, axis=path_axis, t_min=z_min, t_max=z_max, length_mode=path_length_mode, resolution=path_length_resolution, up_axis=up_axis)...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run SeleniumBase automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful