def gtsPFacet(meshfile,shift=Vector3.Zero,scale=1.0, radius=1,wire=True,fixed=True,materialNodes=-1,material=-1,color=None): """ Imports mesh geometry from .gts file and automatically creates connected :yref:`PFacet3<PFacet>` elements. For an example see :ysrc:`examples/pfacet/gts-pfacet.py`. :param string filename: .gts file to read. :param [float,float,float] shift: [X,Y,Z] parameter shifts the mesh. :param float scale: factor scales the mesh. :param float radius: radius used to create the :yref:`PFacets<PFacet>`. :param materialNodes: specify :yref:`Body.material` of :yref:`GridNodes<GridNode>`. This material is used to make the internal connections. :param material: specify :yref:`Body.material` of :yref:`PFacets<PFacet>`. This material is used for interactions with external bodies. See documentation of :yref:`yade.utils.sphere` for meaning of other parameters. :returns: lists of :yref:`GridNode<GridNode>` ids `nodesIds`, :yref:`GridConnection<GridConnection>` ids `cylIds`, and :yref:`PFacet<PFacet>` ids `pfIds` """ import gts,yade.pack surf=gts.read(open(meshfile)) surf.scale(scale,scale,scale) surf.translate(shift[0],shift[1],shift[2]) nodesIds=[]; cylIds=[]; pfIds=[] for face in surf.faces(): a=face.vertices()[0].coords() b=face.vertices()[1].coords() c=face.vertices()[2].coords() pfacetCreator1([a,b,c],radius=radius,nodesIds=nodesIds,cylIds=cylIds,pfIds=pfIds,wire=wire,fixed=fixed,materialNodes=materialNodes,material=material,color=color) #print a,b,c return nodesIds,cylIds,pfIds
def gts(meshfile, shift=Vector3.Zero, scale=1.0, **kw): """ Read given meshfile in gts format. :Parameters: `meshfile`: string name of the input file. `shift`: [float,float,float] [X,Y,Z] parameter moves the specimen. `scale`: float factor scales the given data. `**kw`: (unused keyword arguments) is passed to :yref:`yade.utils.facet` :Returns: list of facets. """ import gts, yade.pack surf = gts.read(open(meshfile)) surf.scale(scale, scale, scale) surf.translate(shift[0], shift[1], shift[2]) yade.pack.gtsSurface2Facets(surf, **kw)
def gts(meshfile,shift=Vector3.Zero,scale=1.0,**kw): """ Read given meshfile in gts format. :Parameters: `meshfile`: string name of the input file. `shift`: [float,float,float] [X,Y,Z] parameter moves the specimen. `scale`: float factor scales the given data. `**kw`: (unused keyword arguments) is passed to :yref:`yade.utils.facet` :Returns: list of facets. """ import gts,yade.pack surf=gts.read(open(meshfile)) surf.scale(scale,scale,scale) surf.translate(shift[0],shift[1],shift[2]) yade.pack.gtsSurface2Facets(surf,**kw)
# -*- coding: utf-8 -*- from yade import pack, export, ymport import gts, os.path, locale #### controling parameters mesh = 'parallellepiped' #name of gts mesh sizeRatio = 10. # defines discretisation (sizeRatio=meshLength/particleDiameter) #### import mesh locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' ) #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally surface = gts.read(open(mesh + '.gts')) print 'closed? ', surface.is_closed() #### generate packing if surface.is_closed(): pred = pack.inGtsSurface(surface) # get characteristic dimensions aabb = pred.aabb() dim = pred.dim() center = pred.center() minDim = min(dim[0], dim[1], dim[2]) # define discretisation radius = minDim / (2 * sizeRatio) print center, dim, ' | minDim=', minDim, ' | diameter=', 2 * radius ### regular packing #O.bodies.append(pack.regularHexa(pred,radius=radius,gap=0.,color=(0.9,0.8,0.6))) #O.bodies.append(pack.regularOrtho(pred,radius=radius,gap=0.,color=(0.9,0.8,0.6)))
from yade import pack import gts, os.path, locale locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally ''' if you get "Error: unsupported locale setting" -> type as root: "dpkg-reconfigure locales" -> choose "en_US.UTF-8" (press space to choose) ''' # coarsen the original horse if we have it # do nothing if we have the coarsened horse already if not os.path.exists('horse.coarse.gts'): if os.path.exists('horse.gts'): surf=gts.read(open('horse.gts')); surf.coarsen(1000); surf.write(open('horse.coarse.gts','w')) else: print """horse.gts not found, you need to download input data: wget http://gts.sourceforge.net/samples/horse.gts.gz gunzip horse.gts.gz """ quit() surf=gts.read(open('horse.coarse.gts')) if surf.is_closed(): pred=pack.inGtsSurface(surf) aabb=pred.aabb() dim0=aabb[1][0]-aabb[0][0]; radius=dim0/40. # get some characteristic dimension, use it for radius O.bodies.append(pack.regularHexa(pred,radius=radius,gap=radius/4.))
def buildsectionsurface(cls, s): import gts from morphforge.core import LocMgr from os.path import join as Join print 'Building Mesh' working_dir = LocMgr.ensure_dir_exists('/tmp/mf/mesh/') fTemp1 = Join(working_dir, 'pts.txt') fTemp2 = Join(working_dir, 'pts.off') fTemp3 = Join(working_dir, 'pts.stl') fTemp2b = Join(working_dir, 'pts_postSub.off') fTemp4 = Join(working_dir, 'pts.gts') nstep = 5 print 'Building Spheres' distal_offset = np.array((0.05, 0.05, 0.05)) ptsP = GeomTools.produce_sphere(centre=s.get_proximal_npa3(), radius=s.p_r, n_steps=nstep) ptsD = GeomTools.produce_sphere(centre=s.get_distal_npa3() + distal_offset, radius=s.d_r, n_steps=nstep) print 'Removing Close Points' pts = cls.only_pts_at_min_dist(ptsP + ptsD, min_dist=0.01) print 'Writing:', fTemp2 with open(fTemp1, 'w') as f: f.write('3 %d\n' % len(pts)) np.savetxt(f, np.array(pts)) if os.path.exists(fTemp2): os.unlink(fTemp2) os.system('qhull T1 QJ o < %s > %s' % (fTemp1, fTemp2)) # Don't do the subdivision, just copy the files: os.system('cp %s %s' % (fTemp2, fTemp2b)) # fTemp2 = fTemp2b f = open(fTemp2b).read().split() (nVertex, nFace, nEdge) = [int(i) for i in f[1:4]] assert nVertex > 5 vertices = np.array([float(t) for t in f[4:4 + nVertex * 3]]).reshape(nVertex, 3) triangles = np.array([int(t) for t in f[4 + nVertex * 3:]]) triangles = triangles.reshape((nFace, 4)) triangles = triangles[:, (1, 2, 3)] print 'Writing STL' with open(fTemp3, 'w') as fSTL: fSTL.write('solid name\n') for i in range(triangles.shape[0]): (a, b, c) = triangles[i, :] fSTL.write('facet normal 0 0 0\n') fSTL.write('outer loop \n') fSTL.write('vertex %f %f %f\n' % (vertices[a, 0], vertices[a, 1], vertices[a, 2])) fSTL.write('vertex %f %f %f\n' % (vertices[b, 0], vertices[b, 1], vertices[b, 2])) fSTL.write('vertex %f %f %f\n' % (vertices[c, 0], vertices[c, 1], vertices[c, 2])) fSTL.write('endloop \n') fSTL.write('endfacet\n') fSTL.write('solid end') print 'Running stl2gts...' if os.path.exists(fTemp4): os.unlink(fTemp4) os.system('stl2gts < %s > %s' % (fTemp3, fTemp4)) assert os.path.exists(fTemp4) import gts f = open(fTemp4) s = gts.Surface() s = gts.read(f) s.cleanup() assert s.is_closed() assert s.is_orientable() # s.tessellate() return s
import gts, os.path, locale locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' ) #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally ''' if you get "Error: unsupported locale setting" -> type as root: "dpkg-reconfigure locales" -> choose "en_US.UTF-8" (press space to choose) ''' # coarsen the original horse if we have it # do nothing if we have the coarsened horse already if not os.path.exists('horse.coarse.gts'): if os.path.exists('horse.gts'): surf = gts.read(open('horse.gts')) surf.coarsen(1000) surf.write(open('horse.coarse.gts', 'w')) else: print """horse.gts not found, you need to download input data: wget http://gts.sourceforge.net/samples/horse.gts.gz gunzip horse.gts.gz """ quit() surf = gts.read(open('horse.coarse.gts')) if surf.is_closed(): pred = pack.inGtsSurface(surf) aabb = pred.aabb()
def buildsectionsurface(cls, s): import gts from morphforge.core import LocMgr from os.path import join as Join print 'Building Mesh' working_dir = LocMgr.ensure_dir_exists('/tmp/mf/mesh/') fTemp1 = Join(working_dir, 'pts.txt') fTemp2 = Join(working_dir, 'pts.off') fTemp3 = Join(working_dir, 'pts.stl') fTemp2b = Join(working_dir, 'pts_postSub.off') fTemp4 = Join(working_dir, 'pts.gts') nstep = 5 print 'Building Spheres' distal_offset = np.array((0.05, 0.05, 0.05)) ptsP = GeomTools.produce_sphere(centre=s.get_proximal_npa3(), radius=s.p_r, n_steps=nstep) ptsD = GeomTools.produce_sphere(centre=s.get_distal_npa3() + distal_offset, radius=s.d_r, n_steps=nstep) print 'Removing Close Points' pts = cls.only_pts_at_min_dist(ptsP + ptsD, min_dist=0.01) print 'Writing:', fTemp2 with open(fTemp1, 'w') as f: f.write('3 %d\n' % len(pts)) np.savetxt(f, np.array(pts)) if os.path.exists(fTemp2): os.unlink(fTemp2) os.system('qhull T1 QJ o < %s > %s' % (fTemp1, fTemp2)) # Don't do the subdivision, just copy the files: os.system('cp %s %s' % (fTemp2, fTemp2b)) # fTemp2 = fTemp2b f = open(fTemp2b).read().split() (nVertex, nFace, nEdge) = [int(i) for i in f[1:4]] assert nVertex > 5 vertices = np.array([float(t) for t in f[4:4 + nVertex * 3] ]).reshape(nVertex, 3) triangles = np.array([int(t) for t in f[4 + nVertex * 3:]]) triangles = triangles.reshape((nFace, 4)) triangles = triangles[:, (1, 2, 3)] print 'Writing STL' with open(fTemp3, 'w') as fSTL: fSTL.write('solid name\n') for i in range(triangles.shape[0]): (a, b, c) = triangles[i, :] fSTL.write('facet normal 0 0 0\n') fSTL.write('outer loop \n') fSTL.write('vertex %f %f %f\n' % (vertices[a, 0], vertices[a, 1], vertices[a, 2])) fSTL.write('vertex %f %f %f\n' % (vertices[b, 0], vertices[b, 1], vertices[b, 2])) fSTL.write('vertex %f %f %f\n' % (vertices[c, 0], vertices[c, 1], vertices[c, 2])) fSTL.write('endloop \n') fSTL.write('endfacet\n') fSTL.write('solid end') print 'Running stl2gts...' if os.path.exists(fTemp4): os.unlink(fTemp4) os.system('stl2gts < %s > %s' % (fTemp3, fTemp4)) assert os.path.exists(fTemp4) import gts f = open(fTemp4) s = gts.Surface() s = gts.read(f) s.cleanup() assert s.is_closed() assert s.is_orientable() # s.tessellate() return s
# -*- coding: utf-8 -*- from yade import pack, export, ymport import gts, os.path, locale #### controling parameters mesh='parallellepiped' #name of gts mesh sizeRatio=10. # defines discretisation (sizeRatio=meshLength/particleDiameter) #### import mesh locale.setlocale(locale.LC_ALL,'en_US.UTF-8') #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally surface=gts.read(open(mesh+'.gts')) print 'closed? ', surface.is_closed() #### generate packing if surface.is_closed(): pred=pack.inGtsSurface(surface) # get characteristic dimensions aabb=pred.aabb() dim=pred.dim() center=pred.center() minDim=min(dim[0],dim[1],dim[2]) # define discretisation radius=minDim/(2*sizeRatio) print center, dim, ' | minDim=', minDim, ' | diameter=', 2*radius ### regular packing #O.bodies.append(pack.regularHexa(pred,radius=radius,gap=0.,color=(0.9,0.8,0.6))) #O.bodies.append(pack.regularOrtho(pred,radius=radius,gap=0.,color=(0.9,0.8,0.6))) sp=SpherePack() # random packing
#!/usr/bin/python # -*- coding: utf-8 -*- # © 2009 Václav Šmilauer <*****@*****.**> # © 2013 Anton Gladky <*****@*****.**> from yade import pack import gts, os.path, locale surf = gts.read(open('cone.gts')) if surf.is_closed(): pred = pack.inGtsSurface(surf) aabb = pred.aabb() dim0 = aabb[1][0] - aabb[0][0] radius = dim0 / 70. # get some characteristic dimension, use it for radius O.bodies.appendClumped( pack.regularHexa(pred, radius=radius, gap=radius / 4.)) surf.translate( 0, -(aabb[1][1] - aabb[0][1]) / 2.0, -(aabb[1][2] - aabb[0][2]) ) # move surface down so that facets are underneath the falling spheres O.bodies.append(pack.gtsSurface2Facets(surf, wire=True)) O.engines = [ ForceResetter(), InsertionSortCollider( [Bo1_Sphere_Aabb(), Bo1_Facet_Aabb()], label='collider'), InteractionLoop( [Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()], [Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_ScGeom_FrictPhys_CundallStrack()],
# pts=pack.revolutionSurfaceMeridians([[(pt[0],pt[1]+2e-3*theta) for pt in poly] for theta in thetas],thetas # pts=pack.revolutionSurfaceMeridians([[(pt[0],pt[1]+1e-2*theta) for pt in poly] for theta in thetas],thetas,origin=Vector3(0,-.05,.1),orientation=Quaternion((1,1,0),pi/4)) # connect meridians to make surfaces # caps will close it at the beginning and the end # threshold will merge points closer than 1e-4; this is important: we want it to be closed for filling surf=pack.sweptPolylines2gtsSurface(pts,capStart=True,capEnd=True,threshold=1e-4) # add the surface as facets to the simulation, to make it visible O.bodies.append(pack.gtsSurface2Facets(surf,color=(1,0,1))) # now fill the inGtsSurface predicate constructed form the same surface with sphere packing generated by TriaxialTest # with given radius and standard deviation (see documentation of pack.randomDensePack) # # The memoizeDb will save resulting packing into given file and next time, if you run with the same # parameters (or parameters that can be scaled to the same one), # it will load the packing instead of running the triaxial compaction again. # Try running for the second time to see the speed difference! memoizeDb='/tmp/gts-triax-packings.sqlite' O.bodies.append(pack.randomDensePack(pack.inGtsSurface(surf),radius=5e-3,rRelFuzz=1e-4,memoizeDb=memoizeDb)) # We could also fill the horse with triaxial packing, but have nice approximation, the triaxial would run terribly long, # since horse discard most volume of its bounding box # Here, we would use a very crude one, however if 1: import gts horse=gts.read(open('horse.coarse.gts')) #; horse.scale(.25,.25,.25) O.bodies.append(pack.gtsSurface2Facets(horse)) O.bodies.append(pack.randomDensePack(pack.inGtsSurface(horse),radius=5e-3,memoizeDb=memoizeDb)) horse.translate(.07,0,0) O.bodies.append(pack.gtsSurface2Facets(horse)) # specifying spheresInCell makes the packing periodic, with the given number of spheres, proportions being equal to that of the predicate O.bodies.append(pack.randomDensePack(pack.inGtsSurface(horse),radius=1e-3,spheresInCell=2000,memoizeDb=memoizeDb))
create union of surfaces using GTS calls first and use a single isGtsSurface as predicate with the united surface. The disadvantage of the predicate union | is that each sphere must fit whole in one surface or another: with padding, several points on the sphere are tested. Therefore, areas near both surfaces' boundary will not be filled at all. Note that GTS only moves references to surfaces around, therefore e.g. translating surface that is part of the union will move also the part of the united surface. Therefore, we use the copy() method for deep copy here. """ from __future__ import print_function from woo import pack, qt import gts s1 = gts.read(open("horse.coarse.gts")) s2 = gts.Surface() s2.copy(s1) s2.translate(0.04, 0, 0) O.bodies.append(pack.gtsSurface2Facets(s1, color=(0, 1, 0)) + pack.gtsSurface2Facets(s2, color=(1, 0, 0))) s12 = gts.Surface() s12.copy(s1.union(s2)) s12.translate(0, 0, 0.1) radius = 0.002 O.bodies.append(pack.gtsSurface2Facets(s12, color=(0, 0, 1))) qt.View() from time import time t0 = time()
# # The memoizeDb will save resulting packing into given file and next time, if you run with the same # parameters (or parameters that can be scaled to the same one), # it will load the packing instead of running the triaxial compaction again. # Try running for the second time to see the speed difference! memoizeDb = '/tmp/gts-triax-packings.sqlite' O.bodies.append( pack.randomDensePack(pack.inGtsSurface(surf), radius=5e-3, rRelFuzz=1e-4, memoizeDb=memoizeDb)) # We could also fill the horse with triaxial packing, but have nice approximation, the triaxial would run terribly long, # since horse discard most volume of its bounding box # Here, we would use a very crude one, however if 1: import gts horse = gts.read(open('horse.coarse.gts')) #; horse.scale(.25,.25,.25) O.bodies.append(pack.gtsSurface2Facets(horse)) O.bodies.append( pack.randomDensePack(pack.inGtsSurface(horse), radius=5e-3, memoizeDb=memoizeDb)) horse.translate(.07, 0, 0) O.bodies.append(pack.gtsSurface2Facets(horse)) # specifying spheresInCell makes the packing periodic, with the given number of spheres, proportions being equal to that of the predicate O.bodies.append( pack.randomDensePack(pack.inGtsSurface(horse), radius=1e-3, spheresInCell=2000, memoizeDb=memoizeDb))
#!/usr/bin/python # -*- coding: utf-8 -*- # © 2009 Václav Šmilauer <*****@*****.**> # © 2013 Anton Gladky <*****@*****.**> from yade import pack import gts, os.path, locale surf=gts.read(open('cone.gts')) if surf.is_closed(): pred=pack.inGtsSurface(surf) aabb=pred.aabb() dim0=aabb[1][0]-aabb[0][0]; radius=dim0/70. # get some characteristic dimension, use it for radius O.bodies.appendClumped(pack.regularHexa(pred,radius=radius,gap=radius/4.)) surf.translate(0,-(aabb[1][1]-aabb[0][1])/2.0,-(aabb[1][2]-aabb[0][2])) # move surface down so that facets are underneath the falling spheres O.bodies.append(pack.gtsSurface2Facets(surf,wire=True)) O.engines=[ ForceResetter(), InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()],label='collider'), InteractionLoop( [Ig2_Sphere_Sphere_L3Geom(),Ig2_Facet_Sphere_L3Geom()], [Ip2_FrictMat_FrictMat_FrictPhys()], [Law2_L3Geom_FrictPhys_ElPerfPl()], ), NewtonIntegrator(damping=.1,gravity=[0,0,-500.0]), PyRunner(iterPeriod=1000,command='timing.stats(); O.pause();'), PyRunner(iterPeriod=10,command='addPlotData()') ] O.dt=.7*PWaveTimeStep()
surface that is part of the union will move also the part of the united surface. Therefore, we use the copy() method for deep copy here. """ from yade import pack,qt import gts, locale locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally ''' if you get "Error: unsupported locale setting" -> type as root: "dpkg-reconfigure locales" -> choose "en_US.UTF-8" (press space to choose) ''' s1=gts.read(open('horse.coarse.gts')) s2=gts.Surface(); s2.copy(s1); s2.translate(0.04,0,0) O.bodies.append(pack.gtsSurface2Facets(s1,color=(0,1,0))+pack.gtsSurface2Facets(s2,color=(1,0,0))) s12=gts.Surface(); s12.copy(s1.union(s2)); s12.translate(0,0,.1) radius=0.002 O.bodies.append(pack.gtsSurface2Facets(s12,color=(0,0,1))) qt.View() from time import time t0=time() O.bodies.append(pack.regularHexa(pack.inGtsSurface(s1) | pack.inGtsSurface(s2),radius,gap=0,color=(0,1,0))) t1=time() print 'Using predicate union: %gs'%(t1-t0) O.bodies.append(pack.regularHexa(pack.inGtsSurface(s12),radius,gap=0.,color=(1,0,0))) t2=time()
You can either use union of 2 inGtsSurface predicates or create union of surfaces using GTS calls first and use a single isGtsSurface as predicate with the united surface. The disadvantage of the predicate union | is that each sphere must fit whole in one surface or another: with padding, several points on the sphere are tested. Therefore, areas near both surfaces' boundary will not be filled at all. Note that GTS only moves references to surfaces around, therefore e.g. translating surface that is part of the union will move also the part of the united surface. Therefore, we use the copy() method for deep copy here. """ from woo import pack, qt import gts s1 = gts.read(open('horse.coarse.gts')) s2 = gts.Surface() s2.copy(s1) s2.translate(0.04, 0, 0) O.bodies.append( pack.gtsSurface2Facets(s1, color=(0, 1, 0)) + pack.gtsSurface2Facets(s2, color=(1, 0, 0))) s12 = gts.Surface() s12.copy(s1.union(s2)) s12.translate(0, 0, .1) radius = 0.002 O.bodies.append(pack.gtsSurface2Facets(s12, color=(0, 0, 1))) qt.View() from time import time
from yade import pack import gts, os.path, locale locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') #gts is locale-dependend. If, for example, german locale is used, gts.read()-function does not import floats normally ''' if you get "Error: unsupported locale setting" -> type as root: "dpkg-reconfigure locales" -> choose "en_US.UTF-8" (press space to choose) ''' # coarsen the original horse if we have it # do nothing if we have the coarsened horse already if not os.path.exists('horse.coarse.gts'): if os.path.exists('horse.gts'): surf=gts.read(open('horse.gts')); surf.coarsen(1000); surf.write(open('horse.coarse.gts','w')) else: print("""horse.gts not found, you need to download input data: wget http://gts.sourceforge.net/samples/horse.gts.gz gunzip horse.gts.gz """) quit() surf=gts.read(open('horse.coarse.gts')) if surf.is_closed(): pred=pack.inGtsSurface(surf) aabb=pred.aabb() dim0=aabb[1][0]-aabb[0][0]; radius=dim0/40. # get some characteristic dimension, use it for radius O.bodies.append(pack.regularHexa(pred,radius=radius,gap=radius/4.))