/usr/lib/python2.7/dist-packages/yade/bodiesHandling.py is in python-yade 1.12.0-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | # encoding: utf-8
"""
Miscellaneous functions, which are useful for handling bodies.
"""
from yade.wrapper import *
import utils,math,numpy
try:
from minieigen import *
except ImportError:
from miniEigen import *
#spheresPackDimensions==================================================
def spheresPackDimensions(idSpheres=[],mask=-1):
"""The function accepts the list of spheres id's or list of bodies and calculates max and min dimensions, geometrical center.
:param list idSpheres: list of spheres
:param int mask: :yref:`Body.mask` for the checked bodies
:return: dictionary with keys ``min`` (minimal dimension, Vector3), ``max`` (maximal dimension, Vector3), ``minId`` (minimal dimension sphere Id, Vector3), ``maxId`` (maximal dimension sphere Id, Vector3), ``center`` (central point of bounding box, Vector3), ``extends`` (sizes of bounding box, Vector3), ``volume`` (volume of spheres, Real), ``mass`` (mass of spheres, Real), ``number`` (number of spheres, int),
"""
idSpheresIter=[]
if (len(idSpheres)<1):
#check mask
ifSpherMask=[]
if (mask>-1): #The case, when only the mask was given, without list of ids
for i in O.bodies:
if ((i.mask&mask)<>0):
ifSpherMask.append(i.id)
if (len(ifSpherMask)<2):
raise RuntimeWarning("Not enough bodies to analyze with given mask")
else:
idSpheresIter=ifSpherMask
else:
raise RuntimeWarning("Only a list of particles with length > 1 can be analyzed")
else:
idSpheresIter=idSpheres
minVal = Vector3.Zero
maxVal = Vector3.Zero
minId = Vector3.Zero
maxId = Vector3.Zero
counter = 0
volume = 0.0
mass = 0.0
for i in idSpheresIter:
if (type(i).__name__=='int'):
b = O.bodies[i] #We have received a list of ID's
elif (type(i).__name__=='Body'):
b = i #We have recevied a list of bodies
else:
raise TypeError("Unknow type of data, should be list of int's or bodies's")
if (b):
spherePosition=b.state.pos #skip non-existent spheres
try:
sphereRadius=b.shape.radius #skip non-spheres
except AttributeError: continue
if (mask>-1) and ((mask&b.mask)==0): continue #skip bodies with wrong mask
sphereRadiusVec3 = Vector3(sphereRadius,sphereRadius,sphereRadius)
sphereMax = spherePosition + sphereRadiusVec3
sphereMin = spherePosition - sphereRadiusVec3
for dim in range(0,3):
if ((sphereMax[dim]>maxVal[dim]) or (counter==0)):
maxVal[dim]=sphereMax[dim]
maxId[dim] = b.id
if ((sphereMin[dim]<minVal[dim]) or (counter==0)):
minVal[dim]=sphereMin[dim]
minId[dim] = b.id
volume += 4.0/3.0*math.pi*sphereRadius*sphereRadius*sphereRadius
mass += b.state.mass
counter += 1
center = (maxVal-minVal)/2.0+minVal
extends = maxVal-minVal
dimensions = {'max':maxVal,'min':minVal,'maxId':maxId,'minId':minId,'center':center,
'extends':extends, 'volume':volume, 'mass':mass, 'number':counter}
return dimensions
#facetsDimensions==================================================
def facetsDimensions(idFacets=[],mask=-1):
"""The function accepts the list of facet id's or list of facets and calculates max and min dimensions, geometrical center.
:param list idFacets: list of spheres
:param int mask: :yref:`Body.mask` for the checked bodies
:return: dictionary with keys ``min`` (minimal dimension, Vector3), ``max`` (maximal dimension, Vector3), ``minId`` (minimal dimension facet Id, Vector3), ``maxId`` (maximal dimension facet Id, Vector3), ``center`` (central point of bounding box, Vector3), ``extends`` (sizes of bounding box, Vector3), ``number`` (number of facets, int),
"""
idFacetsIter=[]
if (len(idFacets)<1):
#check mask
ifFacetMask=[]
if (mask>-1): #The case, when only the mask was given, without list of ids
for i in O.bodies:
if ((i.mask&mask)<>0):
ifFacetMask.append(i.id)
if (len(ifFacetMask)<2):
raise RuntimeWarning("Not enough bodies to analyze with given mask")
else:
idFacetsIter=ifFacetMask
else:
raise RuntimeWarning("Only a list of particles with length > 1 can be analyzed")
else:
idFacetsIter=idFacets
minVal = Vector3.Zero
maxVal = Vector3.Zero
minId = Vector3.Zero
maxId = Vector3.Zero
counter = 0
for i in idFacetsIter:
if (type(i).__name__=='int'):
b = O.bodies[i] #We have received a list of ID's
elif (type(i).__name__=='Body'):
b = i #We have recevied a list of bodies
else:
raise TypeError("Unknow type of data, should be list of int's or bodies's")
if (b):
p = b.state.pos
o = b.state.ori
s = b.shape
pt1 = p + o*s.vertices[0]
pt2 = p + o*s.vertices[1]
pt3 = p + o*s.vertices[2]
if (mask>-1) and ((mask&b.mask)==0): continue #skip bodies with wrong mask
facetMax = Vector3(max(pt1[0], pt2[0], pt3[0]), max(pt1[1], pt2[1], pt3[1]), max(pt1[2], pt2[2], pt3[2]))
facetMin = Vector3(min(pt1[0], pt2[0], pt3[0]), min(pt1[1], pt2[1], pt3[1]), min(pt1[2], pt2[2], pt3[2]))
for dim in range(0,3):
if ((facetMax[dim]>maxVal[dim]) or (counter==0)):
maxVal[dim]=facetMax[dim]
maxId[dim] = b.id
if ((facetMin[dim]<minVal[dim]) or (counter==0)):
minVal[dim]=facetMin[dim]
minId[dim] = b.id
counter += 1
center = (maxVal-minVal)/2.0+minVal
extends = maxVal-minVal
dimensions = {'max':maxVal,'min':minVal,'maxId':maxId,'minId':minId,'center':center,
'extends':extends, 'number':counter}
return dimensions
#spheresPackDimensions==================================================
def spheresModify(idSpheres=[],mask=-1,shift=Vector3.Zero,scale=1.0,orientation=Quaternion((0,1,0),0.0),copy=False):
"""The function accepts the list of spheres id's or list of bodies and modifies them: rotating, scaling, shifting.
if copy=True copies bodies and modifies them.
Also the mask can be given. If idSpheres not empty, the function affects only bodies, where the mask passes.
If idSpheres is empty, the function search for bodies, where the mask passes.
:param Vector3 shift: Vector3(X,Y,Z) parameter moves spheres.
:param float scale: factor scales given spheres.
:param Quaternion orientation: orientation of spheres
:param int mask: :yref:`Body.mask` for the checked bodies
:returns: list of bodies if copy=True, and Boolean value if copy=False
"""
idSpheresIter=[]
if (len(idSpheres)==0):
#check mask
ifSpherMask=[]
if (mask>-1): #The case, when only the mask was given, without list of ids
for i in O.bodies:
if ((i.mask&mask)<>0):
ifSpherMask.append(i.id)
if (len(ifSpherMask)==0):
raise RuntimeWarning("No bodies to modify with given mask")
else:
idSpheresIter=ifSpherMask
else:
raise RuntimeWarning("No bodies to modify")
else:
idSpheresIter=idSpheres
dims = spheresPackDimensions(idSpheresIter)
ret=[]
for i in idSpheresIter:
if (type(i).__name__=='int'):
b = O.bodies[i] #We have received a list of ID's
elif (type(i).__name__=='Body'):
b = i #We have recevied a list of bodies
else:
raise TypeError("Unknown type of data, should be list of int's or bodies")
try:
sphereRadius=b.shape.radius #skip non-spheres
except AttributeError: continue
if (mask>-1) and ((mask&b.mask)==0): continue #skip bodies with wrong mask
if (copy): b=sphereDuplicate(b)
b.state.pos=orientation*(b.state.pos-dims['center'])+dims['center']
b.shape.radius*=scale
b.state.pos=(b.state.pos-dims['center'])*scale + dims['center']
b.state.pos+=shift
if (copy): ret.append(b)
if (copy):
return ret
else:
return True
#spheresDublicate=======================================================
def sphereDuplicate(idSphere):
"""The functions makes a copy of sphere"""
i=idSphere
if (type(i).__name__=='int'):
b = O.bodies[i] #We have received a list of ID's
elif (type(i).__name__=='Body'):
b = i #We have recevied a list of bodies
else:
raise TypeError("Unknown type of data, should be list of int's or bodies")
try:
sphereRadius=b.shape.radius #skip non-spheres
except AttributeError:
return False
addedBody = utils.sphere(center=b.state.pos,radius=b.shape.radius,fixed=not(b.dynamic),wire=b.shape.wire,color=b.shape.color,highlight=b.shape.highlight,material=b.material,mask=b.mask)
return addedBody
|