def remesh(self, edgelen=None): """Remesh a TriSurface. edgelen is the suggested edge length """ if edgelen is None: self.getElemEdges() E = Mesh(self.coords, self.edges, eltype='line2') edgelen = E.lengths().mean() tmp = utils.tempFile(suffix='.stl').name tmp1 = utils.tempFile(suffix='.stl').name pf.message("Writing temp file %s" % tmp) self.write(tmp, 'stl') pf.message("Remeshing using VMTK (edge length = %s)" % edgelen) cmd = "vmtk vmtksurfaceremeshing -ifile %s -ofile %s -edgelength %s" % ( tmp, tmp1, edgelen) sta, out = utils.runCommand(cmd) os.remove(tmp) if sta: pf.message("An error occurred during the remeshing.") pf.message(out) return None S = TriSurface.read(tmp1) os.remove(tmp1) return S
def run(): reset() smooth() lights(True) S = TriSurface.read(getcfg('datadir')+'/horse.off') SA = draw(S) res = askItems([ ('direction',[1.,0.,0.]), ('number of sections',20), ('color','red'), ('ontop',False), ('remove surface',False), ]) if not res: return d = res['direction'] n = res['number of sections'] c = res['color'] slices = S.slice(dir=d,nplanes=n) linewidth(2) draw(slices,color=c,view=None,bbox='last',nolight=True,ontop=res['ontop']) export({'_HorseSlice_slices':slices}) if res['remove surface']: undraw(SA) zoomAll()
def run(): reset() smooth() lights(True) S = TriSurface.read(getcfg('datadir') + '/horse.off') SA = draw(S) bb = S.bbox() bb1 = [1.1 * bb[0] - 0.1 * bb[1], 1.1 * bb[1] - 0.1 * bb[0]] print(bb) print(bb1) res = askItems([ _I('Resolution', 100), ]) if not res: return nmax = res['Resolution'] sz = bb1[1] - bb1[0] step = sz.max() / (nmax - 1) n = (sz / step).astype(Int) print(n) P = Formex(simple.regularGrid(bb1[0], bb1[0] + n * step, n).reshape(-1, 3)) draw(P, marksize=1, color='black') #drawNumbers(P) zoomAll() ind = S.inside(P) vox = zeros(n + 1, dtype=uint8) print(vox.shape) vox1 = vox.reshape(-1) print(vox1.shape, ind.max()) vox1[ind] = 1 print(vox.max()) P.setProp(vox1) draw(P, marksize=8) dirname = askDirname() chdir(dirname) # Create output file if not checkWorkdir(): print("Could not open a directory for writing. I have to stop here") return fs = utils.NameSequence('horse', '.png') clear() flat() A = None for frame in vox: B = showGreyImage(frame) saveBinaryImage(frame * 255, fs.next()) undraw(A) A = B
def run(): reset() smooth() lights(True) S = TriSurface.read(getcfg('datadir')+'/horse.off') SA = draw(S) bb = S.bbox() bb1 = [ 1.1*bb[0]-0.1*bb[1], 1.1*bb[1]-0.1*bb[0]] print(bb) print(bb1) res = askItems([ _I('Resolution',100), ]) if not res: return nmax = res['Resolution'] sz = bb1[1]-bb1[0] step = sz.max() / (nmax-1) n = (sz / step).astype(Int) print(n) P = Formex(simple.regularGrid(bb1[0],bb1[0]+n*step,n).reshape(-1,3)) draw(P, marksize=1, color='black') #drawNumbers(P) zoomAll() ind = S.inside(P) vox = zeros(n+1,dtype=uint8) print(vox.shape) vox1 = vox.reshape(-1) print(vox1.shape,ind.max()) vox1[ind] = 1 print(vox.max()) P.setProp(vox1) draw(P, marksize=8) dirname = askDirname() chdir(dirname) # Create output file if not checkWorkdir(): print("Could not open a directory for writing. I have to stop here") return fs = utils.NameSequence('horse','.png') clear() flat() A = None for frame in vox: B = showGreyImage(frame) saveBinaryImage(frame*255,fs.next()) undraw(A) A = B
def run(): reset() smooth() lights(True) transparent(False) setView('horse', [20, 20, 0]) S = TriSurface.read(getcfg('datadir') + '/horse.off') bb = S.bbox() t = -0.3 bb[0] = (1.0 - t) * bb[0] + t * bb[1] draw(S, bbox=bb, view='front') try: P, n, t = askSlices(S.bbox()) except: return a = t / len(P) F = S.toFormex() G = [] old = seterr(all='ignore') setDrawOptions({'bbox': None}) clear() A = None for i, p in enumerate(P): F1, F = F.cutWithPlane(p, -n) if F1.nelems() > 0: F1.setProp(i) G = [g.rot(a, around=p) for g in G] G.append(F1) #clear() B = draw([F, G]) if A: undraw(A) A = B seterr(**old) x = pf.canvas.width() / 2 y = pf.canvas.height() - 40 T = drawText("No animals got hurt during the making of this movie!", x, y, size=18, gravity='C') for i in range(10): sleep(0.3) undecorate(T) sleep(0.3) decorate(T)
def run(): reset() smooth() lights(True) transparent(False) setView('horse',[20,20,0]) S = TriSurface.read(getcfg('datadir')+'/horse.off') bb = S.bbox() t = -0.3 bb[0] = (1.0-t)*bb[0] + t*bb[1] draw(S,bbox=bb,view='front') try: P,n,t = askSlices(S.bbox()) except: return a = t/len(P) F = S.toFormex() G = [] old = seterr(all='ignore') setDrawOptions({'bbox':None}) clear() A = None for i,p in enumerate(P): F1,F = F.cutWithPlane(p,-n) if F1.nelems() > 0: F1.setProp(i) G = [ g.rot(a,around=p) for g in G ] G.append(F1) #clear() B = draw([F,G]) if A: undraw(A) A = B seterr(**old) x = pf.canvas.width()/2 y = pf.canvas.height() - 40 T = drawText("No animals got hurt during the making of this movie!",x,y,size=18,gravity='C') for i in range(10): sleep(0.3) undecorate(T) sleep(0.3) decorate(T)
def gtsset(self, surf, op, filt='', ext='.tmp', curve=False, check=False, verbose=False): """_Perform the boolean/intersection methods. See the boolean/intersection methods for more info. Parameters not explained there: - filt: a filter command to be executed on the gtsset output - ext: extension of the result file - curve: if True, an intersection curve is computed, else the surface. Returns the name of the (temporary) results file. """ op = {'+': 'union', '-': 'diff', '*': 'inter'}[op] options = '' if curve: options += '-i' if check: options += ' -s' if not verbose: options += ' -v' tmp = utils.tempFile(suffix='.gts').name tmp1 = utils.tempFile(suffix='.gts').name tmp2 = utils.tempFile(suffix=ext).name pf.message("Writing temp file %s" % tmp) self.write(tmp, 'gts') pf.message("Writing temp file %s" % tmp1) surf.write(tmp1, 'gts') pf.message("Performing boolean operation") cmd = "gtsset %s %s %s %s %s > %s" % (options, op, tmp, tmp1, filt, tmp2) sta, out = utils.runCommand(cmd) os.remove(tmp) os.remove(tmp1) if sta or verbose: pf.message(out) pf.message("Reading result from %s" % tmp2) if curve: res = read_gts_intersectioncurve(tmp2) else: res = TriSurface.read(tmp2) os.remove(tmp2) return res
def gtsset(self,surf,op,filt='',ext='.tmp',curve=False,check=False,verbose=False): """_Perform the boolean/intersection methods. See the boolean/intersection methods for more info. Parameters not explained there: - filt: a filter command to be executed on the gtsset output - ext: extension of the result file - curve: if True, an intersection curve is computed, else the surface. Returns the name of the (temporary) results file. """ op = {'+':'union', '-':'diff', '*':'inter'}[op] options = '' if curve: options += '-i' if check: options += ' -s' if not verbose: options += ' -v' tmp = utils.tempFile(suffix='.gts').name tmp1 = utils.tempFile(suffix='.gts').name tmp2 = utils.tempFile(suffix=ext).name pf.message("Writing temp file %s" % tmp) self.write(tmp,'gts') pf.message("Writing temp file %s" % tmp1) surf.write(tmp1,'gts') pf.message("Performing boolean operation") cmd = "gtsset %s %s %s %s %s > %s" % (options,op,tmp,tmp1,filt,tmp2) sta,out = utils.runCommand(cmd) os.remove(tmp) os.remove(tmp1) if sta or verbose: pf.message(out) pf.message("Reading result from %s" % tmp2) if curve: res = read_gts_intersectioncurve(tmp2) else: res = TriSurface.read(tmp2) os.remove(tmp2) return res
def remesh(self,edgelen=None): """Remesh a TriSurface. edgelen is the suggested edge length """ if edgelen is None: self.getElemEdges() E = Mesh(self.coords,self.edges,eltype='line2') edgelen = E.lengths().mean() tmp = utils.tempFile(suffix='.stl').name tmp1 = utils.tempFile(suffix='.stl').name pf.message("Writing temp file %s" % tmp) self.write(tmp,'stl') pf.message("Remeshing using VMTK (edge length = %s)" % edgelen) cmd = "vmtk vmtksurfaceremeshing -ifile %s -ofile %s -edgelength %s" % (tmp,tmp1,edgelen) sta,out = utils.runCommand(cmd) os.remove(tmp) if sta: pf.message("An error occurred during the remeshing.") pf.message(out) return None S = TriSurface.read(tmp1) os.remove(tmp1) return S
def run(): reset() smooth() lights(True) S = TriSurface.read(getcfg('datadir') + '/horse.off') SA = draw(S) res = askItems([ ('direction', [1., 0., 0.]), ('number of sections', 20), ('color', 'red'), ('ontop', False), ('remove surface', False), ]) if not res: return d = res['direction'] n = res['number of sections'] c = res['color'] slices = S.slice(dir=d, nplanes=n) linewidth(2) draw(slices, color=c, view=None, bbox='last', nolight=True, ontop=res['ontop']) export({'_HorseSlice_slices': slices}) if res['remove surface']: undraw(SA) zoomAll()
def run(): global wviewer,pcolor,px,py clear() smooth() lights(True) transparent(False) view('iso') image = None scaled_image = None # read the teapot surface T = TriSurface.read(getcfg('datadir')+'/teapot.off') xmin,xmax = T.bbox() T= T.trl(-T.center()).scale(4./(xmax[0]-xmin[0])).setProp(2) draw(T) # default image file dfilename = getcfg('datadir')+'/benedict_6.jpg' wviewer = ImageView(dfilename,maxheight=200) res = askItems([ _I('filename',dfilename,text='Image file',itemtype='button',func=selectImage), wviewer, _I('px',4,text='Number of patches in x-direction'), _I('py',6,text='Number of patches in y-direction'), _I('kx',30,text='Width of a patch in pixels'), _I('ky',30,text='Height of a patch in pixels'), _I('scale',1.0,text='Scale factor'), _I('trl',[-0.4,-0.1,2.],itemtype='point',text='Translation'), _I('method',choices=['projection','intersection']), ]) if not res: return globals().update(res) nx,ny = px*kx,py*ky # pixels print('The image is reconstructed with %d x %d pixels'%(nx, ny)) F = Formex('4:0123').replic2(nx,ny).centered() if image is None: print("Loading image") image = loadImage(filename) wpic,hpic = image.width(),image.height() print("Image size is %sx%s" % (wpic,hpic)) if image is None: return # Create the colors color,colortable = image2glcolor(image.scaled(nx,ny)) # Reorder by patch pcolor = color.reshape((py,ky,px,kx,3)).swapaxes(1,2).reshape(-1,kx*ky,3) print("Shape of the colors array: %s" % str(pcolor.shape)) mH = makeGrid(px,py,'Quad8') try: ratioYX = float(hpic)/wpic mH = mH.scale(ratioYX,1) # Keep original aspect ratio except: pass mH0 = mH.scale(scale).translate(trl) dg0 = draw(mH0,mode='wireframe') zoomAll() zoom(0.5) print("Create %s x %s patches" % (px,py)) # Create the transforms base = makeGrid(1,1,'Quad8').coords[0] patch = makeGrid(kx,ky,'Quad4').toMesh() d0 = drawImage(mH0,base,patch) if method == 'projection': pts = mH0.coords.projectOnSurface(T,[0.,0.,1.],'-f') dg1 = d1 = [] # to allow dummy undraw else: mH1 = mH.rotate(-30.,0).scale(0.5).translate([0.,-.7,-2.]) dg1 = draw(mH1,mode='wireframe') d1 = drawImage(mH1,base,patch) x = connect([mH0.asPoints(),mH1.asPoints()]) dx = draw(x) print("Creating intersection with surface") pts, il, it, mil=intersectSurfaceWithSegments2(T, x, max1xperline=True) if len(x) != len(pts): print("Some of the lines do not intersect the surface:") print(" %d lines, %d intersections %d missing" % (len(x),len(pts),len(mil))) return dp = draw(pts, marksize=6, color='white') #print pts.shape mH2 = Formex(pts.reshape(-1,8,3)) if method == 'projection': x = connect([mH0.points(),mH2.points()]) dx = draw(x) print("Create projection mapping using the grid points") d2 = drawImage(mH2.trl([0.,0.,0.01]),base,patch) # small translation to make sure the image is above the surface, not cutting it print("Finally show the finished image") undraw(dp); undraw(dx); undraw(d0); undraw(d1); undraw(dg0); undraw(dg1); view('front') zoomAll() sleep(1) transparent()
totalrot = res['total rot'] xmin,xmax = bb[:,axis] dx = (xmax-xmin) / nslices x = arange(nslices+1) * dx N = unitVector(axis) P = [ bb[0]+N*s for s in x ] return P,N,totalrot else: return None reset() smooth() lights(True) transparent(False) setView('horse',[20,20,0]) S = TriSurface.read(getcfg('datadir')+'/horse.off') bb = S.bbox() t = -0.3 bb[0] = (1.0-t)*bb[0] + t*bb[1] draw(S,bbox=bb,view='front') try: P,n,t = askSlices(S.bbox()) except: exit() a = t/len(P) F = S.toFormex() G = []
sw=sp[w] return px[sw], w, itx[sw], delete( arange(len(segm)), w) else:return px, ilx, itx clear() smooth() lights(True) transparent(False) view('iso') image = None scaled_image = None # read the teapot surface T = TriSurface.read(getcfg('datadir')+'/teapot.off') xmin,xmax = T.bbox() T= T.trl(-T.center()).scale(4./(xmax[0]-xmin[0])).setProp(2) draw(T) # default image file filename = getcfg('datadir')+'/benedict_6.jpg' viewer = ImageView(filename) px,py = 5,5 #control points for projection of patches kx,ky = 60,50 #number of cells in each patch scale = 0.8 method='projection' res = askItems([ I('filename',filename,text='Image file',itemtype='button',func=selectImage),
## """HorseTorse level = 'advanced' topics = ['geometry','surface','mesh'] techniques = ['intersection'] """ from plugins.trisurface import TriSurface from mesh import Mesh reset() smooth() lights(True) S = TriSurface.read(getcfg("datadir") + "/horse.off") SA = draw(S) res = askItems([("direction", [1.0, 0.0, 0.0]), ("number of sections", 20), ("color", "red"), ("ontop", False)]) if not res: exit() d = res["direction"] n = res["number of sections"] c = res["color"] slices = S.slice(dir=d, nplanes=n) linewidth(2) draw(slices, color=c, view=None, bbox="last", nolight=True, ontop=res["ontop"]) draw(slices[0])