Example #1
0
def gridNode(center,
             radius,
             dynamic=None,
             fixed=False,
             wire=False,
             color=None,
             highlight=False,
             material=-1):
    """
	Create a :yref:`GridNode` which is needed to set up :yref:`GridConnections<GridConnection>`.

	See documentation of :yref:`yade.utils.sphere` for meaning of parameters.

	:return: Body object with the :yref:`gridNode` :yref:`shape<Body.shape>`.
	"""
    b = Body()
    b.shape = GridNode(radius=radius,
                       color=color if color else utils.randomColor(),
                       wire=wire,
                       highlight=highlight)
    #V=(4./3)*math.pi*radius**3	# will be overwritten by the connection
    V = 0.
    geomInert = (2. /
                 5.) * V * radius**2  # will be overwritten by the connection
    utils._commonBodySetup(b,
                           V,
                           Vector3(geomInert, geomInert, geomInert),
                           material,
                           pos=center,
                           dynamic=dynamic,
                           fixed=fixed)
    b.aspherical = False
    b.bounded = False
    b.mask = 0  # avoid contact detection with the nodes. Manual interaction will be set for them in "gridConnection" below.
    return b
Example #2
0
def stl(file,
        dynamic=None,
        fixed=True,
        wire=True,
        color=None,
        highlight=False,
        noBound=False,
        material=-1):
    """ Import geometry from stl file, return list of created facets."""
    imp = STLImporter()
    facets = imp.ymport(file)
    for b in facets:
        b.shape.color = color if color else utils.randomColor()
        b.shape.wire = wire
        b.shape.highlight = highlight
        pos = b.state.pos
        utils._commonBodySetup(b,
                               0,
                               Vector3(0, 0, 0),
                               material=material,
                               pos=pos,
                               noBound=noBound,
                               dynamic=dynamic,
                               fixed=fixed)
        b.aspherical = False
    return facets
Example #3
0
def polyhedra(material,
              size=Vector3(1, 1, 1),
              seed=None,
              v=[],
              mask=1,
              fixed=False,
              color=[-1, -1, -1]):
    """create polyhedra, one can specify vertices directly, or leave it empty for random shape.
	
	:param Material material: material of new body
	:param Vector3 size: size of new body (see Polyhedra docs)
	:param float seed: seed for random operations
	:param [Vector3] v: list of body vertices (see Polyhedra docs)
	"""
    b = Body()
    random.seed(seed)
    b.aspherical = True
    if len(v) > 0:
        b.shape = Polyhedra(v=v)
    else:
        b.shape = Polyhedra(size=size, seed=random.randint(0, 1E6))
    if color[0] == -1:
        b.shape.color = randomColor(seed=random.randint(0, 1E6))
    else:
        b.shape.color = color
    b.mat = material
    b.state.mass = b.mat.density * b.shape.GetVolume()
    b.state.inertia = b.shape.GetInertia() * b.mat.density
    b.state.ori = b.shape.GetOri()
    b.state.pos = b.shape.GetCentroid()
    b.mask = mask
    if fixed:
        b.state.blockedDOFs = 'xyzXYZ'
    return b
Example #4
0
def chainedCylinder(begin=Vector3(0, 0, 0),
                    end=Vector3(1., 0., 0.),
                    radius=0.2,
                    dynamic=None,
                    fixed=False,
                    wire=False,
                    color=None,
                    highlight=False,
                    material=-1,
                    mask=1):
    """
	Create and connect a chainedCylinder with given parameters. The shape generated by repeted calls of this function is the Minkowski sum of polyline and sphere.

	:param Real radius: radius of sphere in the Minkowski sum.
	:param Vector3 begin: first point positioning the line in the Minkowski sum
	:param Vector3 last: last point positioning the line in the Minkowski sum

	In order to build a correct chain, last point of element of rank N must correspond to first point of element of rank N+1 in the same chain (with some tolerance, since bounding boxes will be used to create connections.

	:return: Body object with the :yref:`ChainedCylinder` :yref:`shape<Body.shape>`.

	.. note:: :yref:`ChainedCylinder` is deprecated and will be removed in the future, use :yref:`GridConnection` instead. See :yref:`yade.gridpfacet.cylinder` and :yref:`yade.gridpfacet.cylinderConnection`.
	"""

    import warnings
    warnings.warn(
        '\033[1;31mchainedCylinder is deprecated and will be removed in the future, use GridConnection instead. See examples/grids/CohesiveGridConnectionSphere.py.\033[1;0m',
        category=UserWarning)

    segment = end - begin
    b = Body()
    b.shape = ChainedCylinder(radius=radius,
                              length=segment.norm(),
                              color=color if color else utils.randomColor(),
                              wire=wire,
                              highlight=highlight)
    b.shape.segment = segment
    V = 2 * (4. / 3) * math.pi * radius**3
    geomInert = (2. /
                 5.) * V * radius**2 + b.shape.length * b.shape.length * 2 * (
                     4. / 3) * math.pi * radius**3
    b.state = ChainedState()
    b.state.addToChain(O.bodies.append(b))
    utils._commonBodySetup(b,
                           V,
                           Vector3(geomInert, geomInert, geomInert),
                           material,
                           pos=begin,
                           resetState=False,
                           dynamic=dynamic,
                           fixed=fixed)
    b.mask = mask
    b.bound = Aabb(color=[0, 1, 0])
    b.state.ori.setFromTwoVectors(Vector3(0., 0., 1.), segment)
    if (end == begin): b.state.ori = Quaternion((1, 0, 0), 0)
    return b
def interaction_element(material,nodepairs,elementshape,radius=0.0015,dynamic=None,fixed=True,wire=False,color=Vector3(1,0,0),highlight=False,mask=1):
	
	# triangles for drawing(node indices)
	#faces=[Vector3(0,1,3),Vector3(1,2,3),Vector3(2,0,3),Vector3(0,1,2)]
	faces=[];
	shape=elementshape()
	shape.color=color if color else randomColor();
	[body_,nodes_]=finite_element(material,shape,nodepairs,faces,radius,interface=True)

	return [body_,nodes_]
def tetrahedral_element(material,nodes,elementshape,radius=0.0015,dynamic=None,fixed=True,wire=False,color=Vector3(1,0,0),highlight=False,mask=1):
	
	# triangles for drawing(node indices)
	#faces are in the format [face_vertex0,face_vertex1,face_vertex2,opposite_vertex]
	faces=[Vector3(1,2,0),Vector3(2,1,3),Vector3(2,0,3),Vector3(3,1,0)]

	shape=elementshape()
	shape.color=color if color else randomColor();
	[body_,nodes_]=finite_element(material,shape,nodes,faces,radius)

	return [body_,nodes_]
Example #7
0
def stl(file, dynamic=None,fixed=True,wire=True,color=None,highlight=False,noBound=False,material=-1):
	""" Import geometry from stl file, return list of created facets."""
	imp = STLImporter()
	facets=imp.ymport(file)
	for b in facets:
		b.shape.color=color if color else utils.randomColor()
		b.shape.wire=wire
		b.shape.highlight=highlight
		pos=b.state.pos
		utils._commonBodySetup(b,0,Vector3(0,0,0),material=material,pos=pos,noBound=noBound,dynamic=dynamic,fixed=fixed)
		b.aspherical=False
	return facets
Example #8
0
def chainedCylinder(
    begin=Vector3(0, 0, 0),
    end=Vector3(1.0, 0.0, 0.0),
    radius=0.2,
    dynamic=None,
    fixed=False,
    wire=False,
    color=None,
    highlight=False,
    material=-1,
    mask=1,
):
    """
	Create and connect a chainedCylinder with given parameters. The shape generated by repeted calls of this function is the Minkowski sum of polyline and sphere.

	:param Real radius: radius of sphere in the Minkowski sum.
	:param Vector3 begin: first point positioning the line in the Minkowski sum
	:param Vector3 last: last point positioning the line in the Minkowski sum

	In order to build a correct chain, last point of element of rank N must correspond to first point of element of rank N+1 in the same chain (with some tolerance, since bounding boxes will be used to create connections.

	:return: Body object with the :yref:`ChainedCylinder` :yref:`shape<Body.shape>`.
	"""
    segment = end - begin
    b = Body()
    b.shape = ChainedCylinder(
        radius=radius,
        length=segment.norm(),
        color=color if color else utils.randomColor(),
        wire=wire,
        highlight=highlight,
    )
    b.shape.segment = segment
    V = 2 * (4.0 / 3) * math.pi * radius ** 3
    geomInert = (2.0 / 5.0) * V * radius ** 2 + b.shape.length * b.shape.length * 2 * (4.0 / 3) * math.pi * radius ** 3
    b.state = ChainedState()
    b.state.addToChain(O.bodies.append(b))
    utils._commonBodySetup(
        b,
        V,
        Vector3(geomInert, geomInert, geomInert),
        material,
        pos=begin,
        resetState=False,
        dynamic=dynamic,
        fixed=fixed,
    )
    b.mask = mask
    b.bound = Aabb(color=[0, 1, 0])
    b.state.ori.setFromTwoVectors(Vector3(0.0, 0.0, 1.0), segment)
    if end == begin:
        b.state.ori = Quaternion((1, 0, 0), 0)
    return b
Example #9
0
def gridConnection(id1,id2,radius,wire=False,color=None,highlight=False,material=-1,mask=1,cellDist=None):
	"""
	Create a :yref:`GridConnection` by connecting two :yref:`GridNodes<GridNode>`.

	:param id1,id2: the two :yref:`GridNodes<GridNode>` forming the cylinder. 
	:param float radius: radius of the cylinder. Note that the radius needs to be the same as the one for the :yref:`GridNodes<GridNode>`.
	:param Vector3 cellDist: for periodic boundary conditions, see :yref:`Interaction.cellDist`. Note: periodic boundary conditions for gridConnections are not yet implemented! 

	See documentation of :yref:`yade.utils.sphere` for meaning of other parameters.

	:return: Body object with the :yref:`GridConnection` :yref:`shape<Body.shape>`.

	.. note:: The material of the :yref:`GridNodes<GridNode>` will be used to set the constitutive behaviour of the internal connection, i.e., the constitutive behaviour of the cylinder. The material of the :yref:`GridConnection` is used for interactions with other (external) bodies.
	"""
	b=Body()
	b.shape=GridConnection(radius=radius,color=color if color else utils.randomColor(),wire=wire,highlight=highlight)
	sph1=O.bodies[id1] ; sph2=O.bodies[id2]
	i=createInteraction(id1,id2)
	nodeMat=sph1.material
	b.shape.node1=sph1 ; b.shape.node2=sph2
	sph1.shape.addConnection(b) ; sph2.shape.addConnection(b)
	if(O.periodic):
		if(cellDist!=None):
			i.cellDist=cellDist
		segt=sph2.state.pos + O.cell.hSize*i.cellDist - sph1.state.pos
	else: segt=sph2.state.pos - sph1.state.pos
	L=segt.norm()
	V=0.5*L*math.pi*radius**2
	geomInert=(2./5.)*V*radius**2
	utils._commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=sph1.state.pos,dynamic=False,fixed=True)
	sph1.state.mass = sph1.state.mass + V*nodeMat.density
	sph2.state.mass = sph2.state.mass + V*nodeMat.density
	for k in [0,1,2]:
		sph1.state.inertia[k] = sph1.state.inertia[k] + geomInert*nodeMat.density
		sph2.state.inertia[k] = sph2.state.inertia[k] + geomInert*nodeMat.density
	b.aspherical=False
	if O.periodic:
		i.phys.unp= -(sph2.state.pos + O.cell.hSize*i.cellDist - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius
		b.shape.periodic=True
		b.shape.cellDist=i.cellDist
	else:
		i.phys.unp= -(sph2.state.pos - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius	
	i.geom.connectionBody=b
	I=math.pi*(2.*radius)**4/64.
	E=nodeMat.young
	i.phys.kn=E*math.pi*(radius**2)/L
	i.phys.kr=E*I/L
	i.phys.ks=12.*E*I/(L**3)
	G=E/(2.*(1+nodeMat.poisson))
	i.phys.ktw=2.*I*G/L
	b.mask=mask
	return b
Example #10
0
def gridConnection(id1,id2,radius,wire=False,color=None,highlight=False,material=-1,mask=1,cellDist=None):
	"""
	Create a :yref:`GridConnection` by connecting two :yref:`GridNodes<GridNode>`.

	:param id1,id2: the two :yref:`GridNodes<GridNode>` forming the cylinder. 
	:param float radius: radius of the cylinder. Note that the radius needs to be the same as the one for the :yref:`GridNodes<GridNode>`.
	:param Vector3 cellDist: for periodic boundary conditions, see :yref:`Interaction.cellDist`. Note: periodic boundary conditions for gridConnections are not yet implemented! 

	See documentation of :yref:`yade.utils.sphere` for meaning of other parameters.

	:return: Body object with the :yref:`GridConnection` :yref:`shape<Body.shape>`.

	.. note:: The material of the :yref:`GridNodes<GridNode>` will be used to set the constitutive behaviour of the internal connection, i.e., the constitutive behaviour of the cylinder. The material of the :yref:`GridConnection` is used for interactions with other (external) bodies.
	"""
	b=Body()
	b.shape=GridConnection(radius=radius,color=color if color else utils.randomColor(),wire=wire,highlight=highlight)
	sph1=O.bodies[id1] ; sph2=O.bodies[id2]
	i=createInteraction(id1,id2)
	nodeMat=sph1.material
	b.shape.node1=sph1 ; b.shape.node2=sph2
	sph1.shape.addConnection(b) ; sph2.shape.addConnection(b)
	if(O.periodic):
		if(cellDist!=None):
			i.cellDist=cellDist
		segt=sph2.state.pos + O.cell.hSize*i.cellDist - sph1.state.pos
	else: segt=sph2.state.pos - sph1.state.pos
	L=segt.norm()
	V=0.5*L*math.pi*radius**2
	geomInert=(2./5.)*V*radius**2
	utils._commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=sph1.state.pos,dynamic=False,fixed=True)
	sph1.state.mass = sph1.state.mass + V*nodeMat.density
	sph2.state.mass = sph2.state.mass + V*nodeMat.density
	for k in [0,1,2]:
		sph1.state.inertia[k] = sph1.state.inertia[k] + geomInert*nodeMat.density
		sph2.state.inertia[k] = sph2.state.inertia[k] + geomInert*nodeMat.density
	b.aspherical=False
	if O.periodic:
		i.phys.unp= -(sph2.state.pos + O.cell.hSize*i.cellDist - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius
		b.shape.periodic=True
		b.shape.cellDist=i.cellDist
	else:
		i.phys.unp= -(sph2.state.pos - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius	
	i.geom.connectionBody=b
	I=math.pi*(2.*radius)**4/64.
	E=nodeMat.young
	i.phys.kn=E*math.pi*(radius**2)/L
	i.phys.kr=E*I/L
	i.phys.ks=12.*E*I/(L**3)
	G=E/(2.*(1+nodeMat.poisson))
	i.phys.ktw=2.*I*G/L
	b.mask=mask
	return b
Example #11
0
def gridNode(center,radius,dynamic=None,fixed=False,wire=False,color=None,highlight=False,material=-1):
	"""
	Create a :yref:`GridNode` which is needed to set up :yref:`GridConnections<GridConnection>`.

	See documentation of :yref:`yade.utils.sphere` for meaning of parameters.

	:return: Body object with the :yref:`gridNode` :yref:`shape<Body.shape>`.
	"""
	b=Body()
	b.shape=GridNode(radius=radius,color=color if color else utils.randomColor(),wire=wire,highlight=highlight)
	#V=(4./3)*math.pi*radius**3	# will be overwritten by the connection
	V=0.
	geomInert=(2./5.)*V*radius**2	# will be overwritten by the connection
	utils._commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=center,dynamic=dynamic,fixed=fixed)
	b.aspherical=False
	b.bounded=False
	b.mask=0	# avoid contact detection with the nodes. Manual interaction will be set for them in "gridConnection" below.
	return b
Example #12
0
           poisson=poisson,
           density=4800,
           sigmaT=sigmaT,
           crackOpening=crackOpening,
           epsCrackOnset=epsCrackOnset,
           poisson=poisson,
           isoPrestress=isoPrestress))
sphDict = pickle.load(open(packingFile))
from yade import pack
sp = pack.SpherePack()
sp.fromList(sphDict['spheres'])
sp.cellSize = sphDict['cell']

import numpy
avgRadius = numpy.average([r for c, r in sp])
O.bodies.append([utils.sphere(c, r, color=utils.randomColor()) for c, r in sp])
O.periodic = True
#O.cell.setBox=sp.cellSize	#doesnt work correctly, periodic cell is too big!!!!
O.cell.refSize = sp.cellSize
axis = 2
ax1 = (axis + 1) % 3
ax2 = (axis + 2) % 3
O.dt = dtSafety * utils.PWaveTimeStep()

import yade.plot as yp

O.engines = [
    ForceResetter(),
    InsertionSortCollider([
        Bo1_Sphere_Aabb(aabbEnlargeFactor=intRadius, label='is2aabb'),
    ]),
Example #13
0
	import cPickle as pickle
	pickle.dump(dd,open(packingFile,'w'))
#
# load the packing (again);
#
import cPickle as pickle
concreteId=O.materials.append(CpmMat(young=young, frictionAngle=frictionAngle, poisson=poisson, density=4800, sigmaT=sigmaT, crackOpening=crackOpening, epsCrackOnset=epsCrackOnset, poisson=poisson, isoPrestress=isoPrestress))
sphDict=pickle.load(open(packingFile))
from yade import pack
sp=pack.SpherePack()
sp.fromList(sphDict['spheres'])
sp.cellSize=sphDict['cell']

import numpy
avgRadius=numpy.average([r for c,r in sp])
O.bodies.append([utils.sphere(c,r,color=utils.randomColor()) for c,r in sp])
O.periodic=True
#O.cell.setBox=sp.cellSize	#doesnt work correctly, periodic cell is too big!!!!
O.cell.refSize=sp.cellSize
axis=2
ax1=(axis+1)%3
ax2=(axis+2)%3
O.dt=dtSafety*utils.PWaveTimeStep()

import yade.plot as yp

O.engines=[
	ForceResetter(),
	InsertionSortCollider([Bo1_Sphere_Aabb(aabbEnlargeFactor=intRadius,label='is2aabb'),]),
	#,sweepLength=.05*avgRadius,nBins=5,binCoeff=5),
	InteractionLoop(
Example #14
0
def chainedCylinder(begin=Vector3(0,0,0),end=Vector3(1.,0.,0.),radius=0.2,dynamic=None,fixed=False,wire=False,color=None,highlight=False,material=-1,mask=1):
	"""
	Create and connect a chainedCylinder with given parameters. The shape generated by repeted calls of this function is the Minkowski sum of polyline and sphere.

	:param Real radius: radius of sphere in the Minkowski sum.
	:param Vector3 begin: first point positioning the line in the Minkowski sum
	:param Vector3 last: last point positioning the line in the Minkowski sum

	In order to build a correct chain, last point of element of rank N must correspond to first point of element of rank N+1 in the same chain (with some tolerance, since bounding boxes will be used to create connections.

	:return: Body object with the :yref:`ChainedCylinder` :yref:`shape<Body.shape>`.

	.. note:: :yref:`ChainedCylinder` is deprecated and will be removed in the future, use :yref:`GridConnection` instead. See :yref:`yade.gridpfacet.cylinder` and :yref:`yade.gridpfacet.cylinderConnection`.
	"""

	import warnings
	warnings.warn('\033[1;31mchainedCylinder is deprecated and will be removed in the future, use GridConnection instead. See examples/grids/CohesiveGridConnectionSphere.py.\033[1;0m',category=UserWarning)

	segment=end-begin
	b=Body()
	b.shape=ChainedCylinder(radius=radius,length=segment.norm(),color=color if color else utils.randomColor(),wire=wire,highlight=highlight)
	b.shape.segment=segment
	V=2*(4./3)*math.pi*radius**3
	geomInert=(2./5.)*V*radius**2+b.shape.length*b.shape.length*2*(4./3)*math.pi*radius**3
	b.state=ChainedState()
	b.state.addToChain(O.bodies.append(b))
	utils._commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=begin,resetState=False,dynamic=dynamic,fixed=fixed)
	b.mask=mask
	b.bound=Aabb(color=[0,1,0])
	b.state.ori.setFromTwoVectors(Vector3(0.,0.,1.),segment)
	if (end == begin): b.state.ori = Quaternion((1,0,0),0)
	return b
Example #15
0
def gridConnection(id1, id2, radius, wire=False, color=None, highlight=False, material=-1, mask=1, cellDist=None):
    """
	Create a :yref:`GridConnection` by connecting two :yref:`GridNodes<GridNode>`.

	:param id1,id2: already with :yref:`GridConnections<GridConnection>` connected :yref:`GridNodes<GridNode>`
	:param bool wire: if ``True``, top and bottom facet are shown as skeleton; otherwise facets are filled.
	:param Vector3-or-None color: color of the PFacet; random color will be assigned if ``None``.
	:param Vector3 cellDist: for periodic boundary conditions, see :yref:`Interaction.cellDist`. Note: periodic boundary conditions are not yet implemented! 

	See documentation of :yref:`yade.utils.sphere` for meaning of other parameters.

	:return: Body object with the :yref:`PFacet<PFacet>` :yref:`shape<Body.shape>`.

	.. note:: :yref:`GridNodes<GridNode>` and :yref:`GridConnections<GridConnection>` need to have the same radius. This is also the radius used to create the :yref:`PFacet<PFacet>`

	"""
    b = Body()
    b.shape = GridConnection(
        radius=radius, color=color if color else utils.randomColor(), wire=wire, highlight=highlight
    )
    sph1 = O.bodies[id1]
    sph2 = O.bodies[id2]
    i = createInteraction(id1, id2)
    nodeMat = sph1.material
    b.shape.node1 = sph1
    b.shape.node2 = sph2
    sph1.shape.addConnection(b)
    sph2.shape.addConnection(b)
    if O.periodic:
        if cellDist != None:
            i.cellDist = cellDist
        segt = sph2.state.pos + O.cell.hSize * i.cellDist - sph1.state.pos
    else:
        segt = sph2.state.pos - sph1.state.pos
    L = segt.norm()
    V = 0.5 * L * math.pi * radius ** 2
    geomInert = (2.0 / 5.0) * V * radius ** 2
    utils._commonBodySetup(
        b, V, Vector3(geomInert, geomInert, geomInert), material, pos=sph1.state.pos, dynamic=False, fixed=True
    )
    sph1.state.mass = sph1.state.mass + V * nodeMat.density
    sph2.state.mass = sph2.state.mass + V * nodeMat.density
    for k in [0, 1, 2]:
        sph1.state.inertia[k] = sph1.state.inertia[k] + geomInert * nodeMat.density
        sph2.state.inertia[k] = sph2.state.inertia[k] + geomInert * nodeMat.density
    b.aspherical = False
    if O.periodic:
        i.phys.unp = (
            -(sph2.state.pos + O.cell.hSize * i.cellDist - sph1.state.pos).norm()
            + sph1.shape.radius
            + sph2.shape.radius
        )
        b.shape.periodic = True
        b.shape.cellDist = i.cellDist
    else:
        i.phys.unp = -(sph2.state.pos - sph1.state.pos).norm() + sph1.shape.radius + sph2.shape.radius
    i.geom.connectionBody = b
    I = math.pi * (2.0 * radius) ** 4 / 64.0
    E = nodeMat.young
    i.phys.kn = E * math.pi * (radius ** 2) / L
    i.phys.kr = E * I / L
    i.phys.ks = 12.0 * E * I / (L ** 3)
    G = E / (2.0 * (1 + nodeMat.poisson))
    i.phys.ktw = 2.0 * I * G / L
    b.mask = mask
    return b
Example #16
0
def node(center,radius,dynamic=None,fixed=True,wire=False,color=None,highlight=False,material=-1,mask=1):
	"""Create sphere with given parameters; mass and inertia computed automatically.

	Last assigned material is used by default (*material* = -1), and utils.defaultMaterial() will be used if no material is defined at all.

	:param Vector3 center: center
	:param float radius: radius
	:param float dynamic: deprecated, see "fixed"
	:param float fixed: generate the body with all DOFs blocked?
	:param material:
		specify :yref:`Body.material`; different types are accepted:
			* int: O.materials[material] will be used; as a special case, if material==-1 and there is no shared materials defined, utils.defaultMaterial() will be assigned to O.materials[0]
			* string: label of an existing material that will be used
			* :yref:`Material` instance: this instance will be used
			* callable: will be called without arguments; returned Material value will be used (Material factory object, if you like)
	:param int mask: :yref:`Body.mask` for the body
	:param wire: display as wire sphere?
	:param highlight: highlight this body in the viewer?
	:param Vector3-or-None: body's color, as normalized RGB; random color will be assigned if ``None``.
	
	:return:
		A Body instance with desired characteristics.


	Creating default shared material if none exists neither is given::

		>>> O.reset()
		>>> from yade import utils
		>>> len(O.materials)
		0
		>>> s0=utils.sphere([2,0,0],1)
		>>> len(O.materials)
		1

	Instance of material can be given::

		>>> s1=utils.sphere([0,0,0],1,wire=False,color=(0,1,0),material=ElastMat(young=30e9,density=2e3))
		>>> s1.shape.wire
		False
		>>> s1.shape.color
		Vector3(0,1,0)
		>>> s1.mat.density
		2000.0

	Material can be given by label::

		>>> O.materials.append(FrictMat(young=10e9,poisson=.11,label='myMaterial'))
		1
		>>> s2=utils.sphere([0,0,2],1,material='myMaterial')
		>>> s2.mat.label
		'myMaterial'
		>>> s2.mat.poisson
		0.11

	Finally, material can be a callable object (taking no arguments), which returns a Material instance.
	Use this if you don't call this function directly (for instance, through yade.pack.randomDensePack), passing
	only 1 *material* parameter, but you don't want material to be shared.

	For instance, randomized material properties can be created like this:

		>>> import random
		>>> def matFactory(): return ElastMat(young=1e10*random.random(),density=1e3+1e3*random.random())
		...
		>>> s3=utils.sphere([0,2,0],1,material=matFactory)
		>>> s4=utils.sphere([1,2,0],1,material=matFactory)

	"""
	b=Body()
	b.shape=Node(radius=radius,color=color if color else randomColor(),wire=wire,highlight=highlight)
	V=(4./3)*math.pi*radius**3
	geomInert=(2./5.)*V*radius**2
	_commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert),material,pos=center,dynamic=dynamic,fixed=fixed,blockedDOFs='XYZ')
	b.aspherical=False
	b.mask=mask
	b.bounded=True
	return b