def sliceIt(): """Slice a surface using the provided slicing data """ S, cp = getData('surface', 'central_point') try: hl = named('control_lines') cl = named('center_lines') except: centerlines() hl = named('control_lines') cl = named('center_lines') nslice = sliceData('nslice') pf.GUI.setBusy(True) h = [ sliceBranch(S, cp, hl[2 * i], hl[2 * i + 1], cl[i], nslice[i]) for i in range(3) ] ##corrections of some points of the cross-PolyLines because sometimes, due to the cutting, different pts appear at the connections between semi-branches (0,1) and branches (at center-splines top and bottom) ##merge the points between half branches for ibr in [0, 1, 2]: pfl0 = array([hi.coords[[0, -1]] for hi in h[ibr][0] ]) #point first and last of each half cross section pfl1 = array([hi.coords[[0, -1]] for hi in h[ibr][1]]) temp = (pfl0 + pfl1) * 0.5 for i in range(len(temp)): h[ibr][0][i].coords[[0, -1]] = h[ibr][1][i].coords[[0, -1]] = temp[i] ##mergethe 3 points on the top and the 3 points on the bottom (at the bif center) t0 = array([ h[ibr][sbr][0].coords[0] for ibr in [0, 1, 2] for sbr in [0, 1] ]).mean(axis=0) t1 = array([ h[ibr][sbr][0].coords[-1] for ibr in [0, 1, 2] for sbr in [0, 1] ]).mean(axis=0) for ibr in [0, 1, 2]: for sbr in [0, 1]: h[ibr][sbr][0].coords[0] = t0 h[ibr][sbr][0].coords[-1] = t1 export({'cross_sections': olist.flatten(h)}) export({ 'cross_sections_backup': olist.flatten(h) }) #to recover from overwriting when creating the outer cross sections clear() drawCenterLines() drawCrossSections() pf.GUI.setBusy(False)
def drawCrossSections(): cs = named('cross_sections') #draw(cs[0:6:2],color='red') #draw(cs[1:6:2],color='blue') draw(Mesh.concatenate([i.toMesh() for i in olist.flatten(cs[0:6:2])]), color='red', flat=True, alpha=1, linewidth=3) draw(Mesh.concatenate([i.toMesh() for i in olist.flatten(cs[1:6:2])]), color='blue', flat=True, alpha=1, linewidth=3)
def cutPart(M, x0, x1): """Cut part of section at plane thru x0 and return part between x0 and x1""" M = M.clipAtPlane(x1, x0 - x1, nodes='all') meshlist = M.splitProp() meshlist = [meshToPolyLine2(m) for m in meshlist] #meshlist = [ p.cutWithPlane(x0,x1-x0,side='+') for p in meshlist ] draw(meshlist, flat=True, alpha=1, linewidth=3) #print erf meshlist = olist.flatten(meshlist) if len(meshlist) == 1: pl = meshlist[0] elif len(meshlist) == 2: p1, p0 = meshlist pl = PolyLine(Coords.concatenate([p0.coords, p1.coords])) else: print([p.nelems() for p in meshlist]) [ draw(p, color=c) for p, c in zip(meshlist, pf.canvas.settings.colormap) ] pl = longestItem(meshlist) return pl
def spliner(): """Slice the surface to a sequence of cross sections.""" import olist from plugins.curve import BezierSpline S = selection.check(single=True) if not S: return res = askItems([_I('Direction',[1.,0.,0.]), _I('# slices',20), _I('remove_invalid',False), ],caption = 'Define the slicing planes') if res: axis = res['Direction'] nslices = res['# slices'] remove_cruft = res['remove_invalid'] pf.GUI.setBusy(True) slices = S.slice(dir=axis,nplanes=nslices) pf.GUI.setBusy(False) print([ s.nelems() for s in slices ]) split = [ s.splitProp() for s in slices if s.nelems() > 0 ] split = olist.flatten(split) hasnan = [ isnan(s.coords).any() for s in split ] print(hasnan) print(sum(hasnan)) #print [s.closed for s in split] export({'%s/split' % selection[0]:split}) draw(split,color='blue',bbox='last',view=None) splines = [ BezierSpline(s.coords[s.elems[:,0]],closed=True) for s in split ] draw(splines,color='red',bbox='last',view=None) export({'%s/splines' % selection[0]:splines})
def knotVector(nctrl,degree,blended=True,closed=False): """Compute sensible knot vector for a Nurbs curve. A knot vector is a sequence of non-decreasing parametric values. These values define the `knots`, i.e. the points where the analytical expression of the Nurbs curve may change. The knot values are only meaningful upon a multiplicative constant, and they are usually normalized to the range [0.0..1.0]. A Nurbs curve with ``nctrl`` points and of given ``degree`` needs a knot vector with ``nknots = nctrl+degree+1`` values. A ``degree`` curve needs at least ``nctrl = degree+1`` control points, and thus at least ``nknots = 2*(degree+1)`` knot values. To make an open curve start and end in its end points, it needs knots with multiplicity ``degree+1`` at its ends. Thus, for an open blended curve, the default policy is to set the knot values at the ends to 0.0, resp. 1.0, both with multiplicity ``degree+1``, and to spread the remaining ``nctrl - degree - 1`` values equally over the interval. For a closed (blended) curve, the knots are equally spread over the interval, all having a multiplicity 1 for maximum continuity of the curve. For an open unblended curve, all internal knots get multiplicity ``degree``. This results in a curve that is only one time continuously derivable at the knots, thus the curve is smooth, but the curvature may be discontinuous. There is an extra requirement in this case: ``nctrl`` sohuld be a multiple of ``degree`` plus 1. Example: >>> print knotVector(7,3) [ 0. 0. 0. 0. 0.25 0.5 0.75 1. 1. 1. 1. ] >>> print knotVector(7,3,closed=True) [ 0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ] >>> print knotVector(7,3,blended=False) [ 0. 0. 0. 0. 1. 1. 1. 2. 2. 2. 2.] """ nknots = nctrl+degree+1 if closed: knots = uniformParamValues(nknots-1) else: if blended: npts = nknots - 2*degree knots = [0.]*degree + uniformParamValues(npts-1).tolist() + [1.]*degree else: nparts = (nctrl-1) / degree if nparts*degree+1 != nctrl: raise ValueError,"Discrete knot vectors can only be used if the number of control points is a multiple of the degree, plus one." knots = [0.] + [ [float(i)]*degree for i in range(nparts+1) ] + [float(nparts)] knots = olist.flatten(knots) return asarray(knots)
def sliceIt(): """Slice a surface using the provided slicing data """ S,cp = getData('surface','central_point') try: hl = named('control_lines') cl = named('center_lines') except: centerlines() hl = named('control_lines') cl = named('center_lines') nslice = sliceData('nslice') pf.GUI.setBusy(True) h = [sliceBranch(S,cp,hl[2*i],hl[2*i+1],cl[i],nslice[i]) for i in range(3) ] ##corrections of some points of the cross-PolyLines because sometimes, due to the cutting, different pts appear at the connections between semi-branches (0,1) and branches (at center-splines top and bottom) ##merge the points between half branches for ibr in [0, 1, 2]: pfl0=array([hi.coords[[0, -1]] for hi in h[ibr][0]])#point first and last of each half cross section pfl1=array([hi.coords[[0, -1]] for hi in h[ibr][1]]) temp=(pfl0+ pfl1)*0.5 for i in range(len(temp)):h[ibr][0][i].coords[[0, -1]]=h[ibr][1][i].coords[[0, -1]]=temp[i] ##mergethe 3 points on the top and the 3 points on the bottom (at the bif center) t0= array([ h[ibr][sbr][0].coords[0] for ibr in [0, 1, 2] for sbr in [0, 1]]).mean(axis=0) t1= array([ h[ibr][sbr][0].coords[-1] for ibr in [0, 1, 2] for sbr in [0, 1]]).mean(axis=0) for ibr in [0, 1, 2]: for sbr in [0, 1]: h[ibr][sbr][0].coords[0]=t0 h[ibr][sbr][0].coords[-1]=t1 export({'cross_sections':olist.flatten(h)}) export({'cross_sections_backup':olist.flatten(h)})#to recover from overwriting when creating the outer cross sections clear() drawCenterLines() drawCrossSections() pf.GUI.setBusy(False)
def cutPart(M,x0,x1): """Cut part of section at plane thru x0 and return part between x0 and x1""" M = M.clipAtPlane(x1,x0-x1, nodes='all') meshlist = M.splitProp() meshlist = [ meshToPolyLine2(m) for m in meshlist ] #meshlist = [ p.cutWithPlane(x0,x1-x0,side='+') for p in meshlist ] draw(meshlist, flat=True, alpha=1, linewidth=3) #print erf meshlist = olist.flatten(meshlist) if len(meshlist) == 1: pl = meshlist[0] elif len(meshlist) == 2: p1,p0 = meshlist pl = PolyLine(Coords.concatenate([p0.coords,p1.coords])) else: print([ p.nelems() for p in meshlist]) [ draw(p,color=c) for p,c in zip(meshlist,pf.canvas.settings.colormap) ] pl = longestItem(meshlist) return pl
from plugins.curve import BezierSpline S = selection.check(single=True) if not S: return res = askItems([['Direction',[1.,0.,0.]], ['# slices',20], ],caption = 'Define the slicing planes') if res: axis = res['Direction'] nslices = res['# slices'] GD.GUI.setBusy(True) slices = S.slice(dir=axis,nplanes=nslices,ignoreErrors=True) GD.GUI.setBusy(False) print [ s.nelems() for s in slices ] split = [ s.splitProp().values() for s in slices if s.nelems() > 0 ] split = olist.flatten(split) export({'%s/split' % selection[0]:split}) draw(split,color='blue',bbox='last',view=None) splines = [ BezierSpline(s.coords[s.elems[:,0]],closed=True) for s in split ] draw(splines,color='red',bbox='last',view=None) export({'%s/splines' % selection[0]:splines}) ################## Smooth the selected surface ############################# def smoothLowPass(): """Smooth the selected surface using a low-pass filter.""" S = selection.check(single=True) if S: res = askItems([('lambda_value',0.5), ('n_iterations',2),('neighbourhood',1)],'Low-pass filter')
def drawCrossSections(): cs = named('cross_sections') #draw(cs[0:6:2],color='red') #draw(cs[1:6:2],color='blue') draw(Mesh.concatenate([i.toMesh() for i in olist.flatten(cs[0:6:2]) ]),color='red',flat=True, alpha=1, linewidth=3) draw(Mesh.concatenate([i.toMesh() for i in olist.flatten(cs[1:6:2]) ]),color='blue',flat=True, alpha=1, linewidth=3)