Skip to content

Commit 822af0b

Browse files
committed
Ambiguous cases of mass calculation for surface objects have been more clearly defined
1 parent 7cfec1e commit 822af0b

File tree

3 files changed

+53
-63
lines changed

3 files changed

+53
-63
lines changed

kk_bullet_constraints_builder.zip

-40 Bytes
Binary file not shown.

kk_bullet_constraints_builder/builder_prep.py

Lines changed: 48 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,32 +1899,21 @@ def calculateMass(scene, objs, objsEGrp, childObjs):
18991899

19001900
### Calculating and applying material masses based on surface area * thickness
19011901
if (props.surfaceForced and props.surfaceThickness) or (props.surfaceThickness and len(objsNonMan)):
1902-
# Find out density of the element group
1903-
if not materialDensity:
1904-
materialPreset = elemGrp[EGSidxMatP]
1905-
if materialPreset != "":
1906-
try: materialDensity = materialPresets[materialPreset]
1907-
except:
1908-
print("Warning: Density of 0 set and material preset not found for '%s', a density of 1000 kg/m^3 is used." %elemGrp[EGSidxName])
1909-
materialDensity = 1000
1910-
else:
1911-
print("Warning: Density of 0 set and no material preset defined for '%s', a density of 1000 kg/m^3 is used." %elemGrp[EGSidxName])
1912-
materialDensity = 1000
1913-
1914-
if props.surfaceForced: objsNonMan = objs
1915-
1916-
objsNonManSelected = []
1917-
for n in range(len(objsNonMan)):
1918-
obj = objsNonMan[n]
1919-
k = objsIndex[obj.name]
1920-
if objsEGrp[k] == j: # If object is in current element group
1921-
# Calculate object surface area and volume
1922-
me = obj.data
1923-
area = sum(f.area for f in me.polygons)
1924-
volume = area *props.surfaceThickness
1925-
# Calculate mass
1926-
obj.rigid_body.mass = volume *materialDensity
1927-
objsNonManSelected.append(obj)
1902+
if materialDensity:
1903+
if props.surfaceForced: objsNonMan = objs
1904+
1905+
objsNonManSelected = []
1906+
for n in range(len(objsNonMan)):
1907+
obj = objsNonMan[n]
1908+
k = objsIndex[obj.name]
1909+
if objsEGrp[k] == j: # If object is in current element group
1910+
# Calculate object surface area and volume
1911+
me = obj.data
1912+
area = sum(f.area for f in me.polygons)
1913+
volume = area *props.surfaceThickness
1914+
# Calculate mass
1915+
obj.rigid_body.mass = volume *materialDensity
1916+
objsNonManSelected.append(obj)
19281917

19291918
### Adding live load to masses
19301919
liveLoad = elemGrp[EGSidxLoad]
@@ -2034,51 +2023,50 @@ def correctContactAreaByVolume(objs, objsEGrp, connectsPair, connectsGeo):
20342023
try: materialDensity = materialPresets[materialPreset]
20352024
except:
20362025
print("Warning: Density of 0 set and material preset not found for '%s', can't compute mass and leaving it as is." %elemGrp[EGSidxName])
2037-
materialDensity = 1
20382026
else:
20392027
print("Warning: Density of 0 set and no material preset defined for '%s', can't compute mass and leaving it as is." %elemGrp[EGSidxName])
2040-
materialDensity = 1
20412028

20422029
### Calculate volumes from densities and derive correctional factors for contact areas
2043-
for k in range(len(objs)):
2044-
if objsEGrp[k] == j: # If object is in current element group
2045-
obj = objs[k]
2030+
if materialDensity:
2031+
for k in range(len(objs)):
2032+
if objsEGrp[k] == j: # If object is in current element group
2033+
obj = objs[k]
20462034

2047-
mass = obj.rigid_body.mass
2035+
mass = obj.rigid_body.mass
20482036

2049-
### Remove live load from mass if present
2050-
if liveLoad > 0:
2051-
dims = obj.dimensions
2052-
floorArea = dims[0] *dims[1] # Simple approximation by assuming rectangular floor area (x *y) for live load
2053-
mass -= floorArea *liveLoad
2037+
### Remove live load from mass if present
2038+
if liveLoad > 0:
2039+
dims = obj.dimensions
2040+
floorArea = dims[0] *dims[1] # Simple approximation by assuming rectangular floor area (x *y) for live load
2041+
mass -= floorArea *liveLoad
20542042

2055-
volume = mass /materialDensity
2056-
2057-
### Find out element thickness to be used for bending threshold calculation
2058-
dim = obj.dimensions; dimAxis = [1, 2, 3]
2059-
dim, dimAxis = zip(*sorted(zip(dim, dimAxis)))
2060-
dimHeight = dim[0]; dimWidth = dim[1]; dimLength = dim[2]
2043+
volume = mass /materialDensity
2044+
2045+
### Find out element thickness to be used for bending threshold calculation
2046+
dim = obj.dimensions; dimAxis = [1, 2, 3]
2047+
dim, dimAxis = zip(*sorted(zip(dim, dimAxis)))
2048+
dimHeight = dim[0]; dimWidth = dim[1]; dimLength = dim[2]
20612049

2062-
# Derive contact area correction factor from geometry section area divided by bbox section area
2063-
if dimLength != 0: sectionArea = volume /dimLength # Full geometry section area of element
2064-
else: sectionArea = volume**.5 # Assume cube as fallback if length is zero
2050+
# Derive contact area correction factor from geometry section area divided by bbox section area
2051+
if dimLength != 0: sectionArea = volume /dimLength # Full geometry section area of element
2052+
else: sectionArea = volume**.5 # Assume cube as fallback if length is zero
20652053

2066-
### Compensate section area for rescaling
2067-
try: scale = elemGrp[EGSidxScal] # Try in case elemGrps is from an old BCB version
2068-
except: pass
2069-
else:
2070-
if obj != None and scale != 0 and scale != 1:
2071-
sectionArea *= scale**3 # Cubic instead of square because dimLength is included as well
2054+
### Compensate section area for rescaling
2055+
try: scale = elemGrp[EGSidxScal] # Try in case elemGrps is from an old BCB version
2056+
except: pass
2057+
else:
2058+
if obj != None and scale != 0 and scale != 1:
2059+
sectionArea *= scale**3 # Cubic instead of square because dimLength is included as well
20722060

2073-
### Determine contact area correction factor
2074-
if dimHeight *dimWidth != 0 and mass != materialDensity: # Special case: mass = materialDensity only for foundation elements
2075-
corFac = sectionArea / (dimHeight *dimWidth)
2076-
else: corFac = 1
2061+
### Determine contact area correction factor
2062+
if dimHeight *dimWidth != 0 and mass != materialDensity: # Special case: mass = materialDensity only for foundation elements
2063+
corFac = sectionArea / (dimHeight *dimWidth)
2064+
else: corFac = 1
20772065

2078-
obj["CA Corr.Fac."] = corFac
2079-
obj["Density"] = materialDensity
2080-
obj["Volume"] = volume
2081-
2066+
obj["CA Corr.Fac."] = corFac
2067+
obj["Density"] = materialDensity
2068+
obj["Volume"] = volume
2069+
20822070
################################################################################
20832071

20842072
def generateDetonator(objs, connectsPair, objsEGrp):

kk_bullet_constraints_builder/builder_setc.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,11 @@ def setConstraintSettings(objs, objsEGrp, emptyObjs, objsID, connectsPair, conne
213213
### Apply corrections to geometry lists
214214
qVolCorrect = geo[6]
215215

216-
if qVolCorrect: # No correction needed in valid polygon based contact area cases
217-
corFacA = objA["CA Corr.Fac."]
218-
corFacB = objB["CA Corr.Fac."]
216+
if qVolCorrect: # No correction needed in valid polygon based contact area cases
217+
try: corFacA = objA["CA Corr.Fac."]
218+
except: corFacA = 1
219+
try: corFacB = objB["CA Corr.Fac."]
220+
except: corFacB = 1
219221
geoContactArea *= min(corFacA, corFacB)
220222

221223
### Prepare connection data

0 commit comments

Comments
 (0)