Skip to content

Commit 929b6ec

Browse files
committed
Added new feature Balance Masses
The new setting is a factor to balance the masses of elements within the element group. A value of 1 assigns the same mass to each element, regardless of size, while maintaining the total mass of the group. This can be useful for force fields that require uniform element masses. A value of 0 (default) calculates masses proportionally based on the elements´ volume.
1 parent b8a187a commit 929b6ec

File tree

5 files changed

+39
-24
lines changed

5 files changed

+39
-24
lines changed

kk_bullet_constraints_builder.zip

404 Bytes
Binary file not shown.

kk_bullet_constraints_builder/builder_prep.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2117,11 +2117,21 @@ def calculateMass(scene, objs, objsEGrp, childObjs):
21172117
if liveLoad > 0: obj.rigid_body.mass += floorArea *liveLoad
21182118
obj["Floor Area"] = floorArea # Only needed for the diagnostic prints below
21192119

2120+
### Balance masses
2121+
balanceFac = elemGrp[EGSidxBlnc]
2122+
if balanceFac > 0 and len(objsSelected):
2123+
massGrp = 0
2124+
for obj in objsSelected:
2125+
massGrp += obj.rigid_body.mass
2126+
massGrp /= len(objsSelected)
2127+
for obj in objsSelected:
2128+
obj.rigid_body.mass = ((1 -balanceFac) *obj.rigid_body.mass) +(balanceFac *massGrp)
2129+
21202130
### Setting friction if we are at it already (could be separate function but not because of 3 lines)
21212131
friction = elemGrp[EGSidxFric]
21222132
for obj in objsSelected:
21232133
obj.rigid_body.friction = friction
2124-
2134+
21252135
# Deselect all objects
21262136
bpy.ops.object.select_all(action='DESELECT')
21272137

kk_bullet_constraints_builder/global_props.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ class bcb_props(bpy.types.PropertyGroup):
230230
exec("elemGrp_%d_EGSidxTl2R" %i +" = float_(name='2nd Rot. Tol.', default=presets[j][EGSidxTl2R], min=-1.0, max=pi, update=updGlob, description='Second deformation tolerance limit for angular change in radian for connection removal. The Formula Assistant might set this to 0 which means that this tolerance will be calculated later during the constraint building phase individually for each connection using Formula Assistant settings, there is no need to change it back then')")
231231
exec("elemGrp_%d_EGSidxPrio" %i +" = int_(name='Connection Priority', default=presets[j][EGSidxPrio], min=1, max=9, update=updGlob, description='Changes the connection priority for this element group which will override that the weaker breaking threshold of two elements is preferred for an connection. Lower Strength Priority has similar functionality but works on all groups, however, it is ignored if the priority here is different for a particular connection')")
232232
exec("elemGrp_%d_EGSidxFric" %i +" = float_(name='Friction', default=presets[j][EGSidxFric], min=0.0, max=100000, update=updGlob, description='Coefficient of friction for the given material (dimensionless)')")
233-
exec("elemGrp_%d_EGSidxSDFl" %i +" = bool_(name='Search Distance Fallback', default=presets[j][EGSidxSDFl], update=updGlob, description='In case no geometry could be detected within mesh search distance while the neighbor element´s boundary box is still within range this enables a fallback using the intersection of the boundary boxes as contact area instead of the mesh surface. If disabled contact area will remain zero and no connection will be created in that case')")
233+
exec("elemGrp_%d_EGSidxBlnc" %i +" = float_(name='Balance Masses', default=presets[j][EGSidxBlnc], min=0.0, max=1.0, update=updGlob, description='Factor to balance the masses of elements within this group. A value of 1 assigns the same mass to each element, regardless of size, while maintaining the total mass of the group. This can be useful for force fields that require uniform element masses. A value of 0 (default) calculates masses proportionally based on the elements´ volume')")
234+
exec("elemGrp_%d_EGSidxSDFl" %i +" = bool_(name='Search Dist. Fallback', default=presets[j][EGSidxSDFl], update=updGlob, description='In case no geometry could be detected within mesh search distance while the neighbor element´s boundary box is still within range this enables a fallback using the intersection of the boundary boxes as contact area instead of the mesh surface. If disabled contact area will remain zero and no connection will be created in that case')")
234235
exec("elemGrp_%d_EGSidxMCTh" %i +" = bool_(name='Mohr-Coulomb Theory', default=presets[j][EGSidxMCTh], update=updGlob, description='Enables the calculation of shear and bending strength using the Mohr-Coulomb theory and makes it stress-related. This method is recommended for masonry structures in earthquake scenarios. Note that the Multiplier setting is also applied to the strength increase')")
235236
exec("elemGrp_%d_EGSidxScal" %i +" = float_(name='Rescale Factor', default=presets[j][EGSidxScal], min=0.0, max=10.0, update=updGlob, description='Applies scaling factor on elements to avoid `Jenga´ effect (undesired stability increase caused by incompressible rigid bodies). This has no influence on breaking threshold and mass calculations')")
236237
exec("elemGrp_%d_EGSidxNoHo" %i +" = bool_(name='No Horizontal Connections', default=presets[j][EGSidxNoHo], update=updGlob, description='Removes horizontal connections between elements of different element groups. This can be useful for masonry walls touching a framing structure without a particular fixation')")
@@ -284,6 +285,7 @@ def props_update_menu(self):
284285
exec("self.elemGrp_%d_EGSidxTl2R" %i +" = elemGrps[i][EGSidxTl2R]")
285286
exec("self.elemGrp_%d_EGSidxPrio" %i +" = elemGrps[i][EGSidxPrio]")
286287
exec("self.elemGrp_%d_EGSidxFric" %i +" = elemGrps[i][EGSidxFric]")
288+
exec("self.elemGrp_%d_EGSidxBlnc" %i +" = elemGrps[i][EGSidxBlnc]")
287289
exec("self.elemGrp_%d_EGSidxSDFl" %i +" = elemGrps[i][EGSidxSDFl]")
288290
exec("self.elemGrp_%d_EGSidxMCTh" %i +" = elemGrps[i][EGSidxMCTh]")
289291
exec("self.elemGrp_%d_EGSidxScal" %i +" = elemGrps[i][EGSidxScal]")
@@ -354,6 +356,7 @@ def props_update_globals(self):
354356
elemGrps[i][EGSidxTl2R] = eval("self.elemGrp_%d_EGSidxTl2R" %i)
355357
elemGrps[i][EGSidxPrio] = eval("self.elemGrp_%d_EGSidxPrio" %i)
356358
elemGrps[i][EGSidxFric] = eval("self.elemGrp_%d_EGSidxFric" %i)
359+
elemGrps[i][EGSidxBlnc] = eval("self.elemGrp_%d_EGSidxBlnc" %i)
357360
elemGrps[i][EGSidxSDFl] = eval("self.elemGrp_%d_EGSidxSDFl" %i)
358361
lastValue = elemGrps[i][EGSidxMCTh]
359362
elemGrps[i][EGSidxMCTh] = eval("self.elemGrp_%d_EGSidxMCTh" %i)

kk_bullet_constraints_builder/global_vars.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,28 @@
3535
################################################################################
3636

3737
### Vars:
38-
bcb_version = (3, 5, 8)
38+
bcb_version = (3, 5, 9)
3939

4040
### Customizable element group presets
4141
presets = [
42-
# 0 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
43-
# Name RVP Mat.preset Density CT BTC BTT BTS BTS90 BTB BTB90 BTP T1D T1R T2D T2R Bev. Scale Facing F.Assist.+Data Cyl PLen BTX Prio Load NoHo Fric NoCo Iter DClP BLC BLT BLS BLS9 BLB BLB9 BTI DCor MCTh SDFl
44-
[ "", 1, "Uncategorized", 2400, 15, "35", "5.2", "155", "", "1.0", "", "1.3", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
45-
[ "Base", 1, "Uncategorized", 2000, 0, "0", "0", "0", "", "0", "", "0", 0, 0, 0, 0, 0, .95, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
46-
[ "Victims", 1, "Uncategorized", 1060, 20, "13", "15", "7", "", "0.2", "", "15", .1, .2, .6, 3.14, 0, 1.0, 0, "None", 0, .001, 1, 5, 0, 0, .5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
47-
[ "Concrete", 1, "Concrete", 2400, 15, "35", "3.5", "0.9", "", "1.0", "", "0", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
48-
[ "RC Columns", 1, "Concrete", 2400, 15, "35", "5.2", "155", "", "1.0", "", "1.3", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
49-
[ "RC Walls", 1, "Concrete", 2400, 15, "35", "5.2", "0.9", "", "1.0", "", "1.3", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
50-
[ "RC Slabs", 1, "Concrete", 2400, 15, "35", "5.2", "0.9", "", "1.0", "", "1.3", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
51-
[ "Masonry Walls", 1, "Masonry", 1800, 15, "10", "0.2", "0.5", "", "0.1", "", "0.1", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 ],
52-
[ "Timber Spruce", 1, "Timber", 470, 15, "40", "80", "7.5", "", "68", "", "80", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
53-
[ "Timber Larch", 1, "Timber", 590, 15, "48", "105", "9", "", "93", "", "105", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
54-
[ "Timber Ash", 1, "Timber", 690, 15, "50", "130", "13", "", "105", "", "130", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
55-
[ "I-Beams #1 Screwed", 1, "Steel", 7800, 22, "250", "61.84","37.1", "", "6.18", "", "123.7",.1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
56-
[ "I-Beams #1 Welded", 1, "Steel", 7800, 22, "250", "250", "150", "", "16.67","", "500", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
57-
[ "I-Beams #2 Screwed", 1, "Steel", 7800, 22, "350", "94.5", "56.7", "", "45.15","", "135", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
58-
[ "I-Beams #2 Welded", 1, "Steel", 7800, 22, "350", "350", "210", "", "71.11","", "500", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
59-
[ "HSS-Beams Welded", 1, "Steel", 7800, 22, "250", "250", "150", "", "29.17","", "500", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ]
42+
# 0 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
43+
# Name RVP Mat.preset Density CT BTC BTT BTS BTS90 BTB BTB90 BTP T1D T1R T2D T2R Bev. Scale Facing F.Assist.+Data Cyl PLen BTX Prio Load NoHo Fric NoCo Iter DClP BLC BLT BLS BLS9 BLB BLB9 BTI DCor MCTh SDFl Blnc
44+
[ "", 1, "Uncategorized", 2400, 15, "35", "5.2", "155", "", "1.0", "", "1.3", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
45+
[ "Base", 1, "Uncategorized", 2000, 0, "0", "0", "0", "", "0", "", "0", 0, 0, 0, 0, 0, .95, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
46+
[ "Victims", 1, "Uncategorized", 1060, 20, "13", "15", "7", "", "0.2", "", "15", .1, .2, .6, 3.14, 0, 1.0, 0, "None", 0, .001, 1, 5, 0, 0, .5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
47+
[ "Concrete", 1, "Concrete", 2400, 15, "35", "3.5", "0.9", "", "1.0", "", "0", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
48+
[ "RC Columns", 1, "Concrete", 2400, 15, "35", "5.2", "155", "", "1.0", "", "1.3", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
49+
[ "RC Walls", 1, "Concrete", 2400, 15, "35", "5.2", "0.9", "", "1.0", "", "1.3", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
50+
[ "RC Slabs", 1, "Concrete", 2400, 15, "35", "5.2", "0.9", "", "1.0", "", "1.3", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
51+
[ "Masonry Walls", 1, "Masonry", 1800, 15, "10", "0.2", "0.5", "", "0.1", "", "0.1", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0 ],
52+
[ "Timber Spruce", 1, "Timber", 470, 15, "40", "80", "7.5", "", "68", "", "80", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
53+
[ "Timber Larch", 1, "Timber", 590, 15, "48", "105", "9", "", "93", "", "105", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
54+
[ "Timber Ash", 1, "Timber", 690, 15, "50", "130", "13", "", "105", "", "130", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
55+
[ "I-Beams #1 Screwed", 1, "Steel", 7800, 22, "250", "61.84","37.1", "", "6.18", "", "123.7",.1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
56+
[ "I-Beams #1 Welded", 1, "Steel", 7800, 22, "250", "250", "150", "", "16.67","", "500", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
57+
[ "I-Beams #2 Screwed", 1, "Steel", 7800, 22, "350", "94.5", "56.7", "", "45.15","", "135", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
58+
[ "I-Beams #2 Welded", 1, "Steel", 7800, 22, "350", "350", "210", "", "71.11","", "500", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
59+
[ "HSS-Beams Welded", 1, "Steel", 7800, 22, "250", "250", "150", "", "29.17","", "500", .1, .2, .2, .8, 0, 1.0, 0, "None", 0, 0, 1, 5, 0, 0, .8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ]
6060
] # Empty name means this group is to be used when element is not part of any element group
6161

6262
# Actual element group list (for elements of different conflicting groups the weaker thresholds is used, also the type is changed accordingly)
@@ -94,6 +94,8 @@
9494
EGSidxTl2R = 15 # Tolerance 2nd Def.Rot. | For baking: Second deformation tolerance limit for angular change in radian for connection removal
9595
EGSidxPrio = 23 # Connection Priority | Changes the connection priority for this element group which will override that the weaker breaking threshold of two elements is preferred for an connection. Lower Strength Priority has similar functionality but works on all groups, however, it is ignored if the priority here is different for a particular connection.
9696
EGSidxFric = 26 # Friction | Coefficient of friction for the given material (dimensionless).
97+
EGSidxBlnc = 40 # Balance Masses | Factor to balance the masses of elements within this group. A value of 1 assigns the same mass to each element, regardless of size, while maintaining the total mass of the group. This can be useful for force fields that require uniform element masses. A value of 0 (default) calculates masses proportionally based on the elements' volume.
98+
EGSidxIter = 28 # Const. Solver Iterations | Overrides the Constraint Solver Iterations value of the scene for constraints of this element group if set to a value greater 0. Higher numbers can help to reduce solver induced deformation on elements bearing extreme loads.
9799
EGSidxSDFl = 39 # Search Distance Fallback | In case no geometry could be detected within mesh search distance while the neighbor element's boundary box is still within range this enables a fallback using the intersection of the boundary boxes as contact area instead of the mesh surface. If disabled contact area will remain zero and no connection will be created in that case.
98100
EGSidxMCTh = 38 # Mohr-Coulomb Theory | Enables the calculation of shear and bending strength using the Mohr-Coulomb theory and makes it stress-related. This method is recommended for masonry structures in earthquake scenarios.
99101
EGSidxScal = 17 # Scale | Apply scaling factor on elements to avoid `Jenga
@@ -105,8 +107,7 @@
105107
EGSidxCyln = 20 # Cylindrical Shape | Interpret connection area as round instead of rectangular (ar = a *pi/4). This can be useful when you have to deal with cylindrical columns.
106108
EGSidxDCor = 37 # Displacement Correction | Enables the correction of initial displacements. This can compensate for sagging structures such as bridges that would otherwise require a very high solver step count to be straight. To do this, the simulation must be run twice. On the first run, the displacements are saved into an external file when the warm-up period ends. In the second run (rebuilding required), the differences are integrated into the mesh. Delete the external file to reset.
107109
EGSidxDClP = 29 # Dis. Col. Permanently | Disables collisions between initially connected elements of this element group permanently (overrides global setting).
108-
EGSidxIter = 28 # Const. Solver Iterations | Overrides the Constraint Solver Iterations value of the scene for constraints of this element group if set to a value greater 0. Higher numbers can help to reduce solver induced deformation on elements bearing extreme loads.
109-
# !!! Last ID: 39 !!! (Can be different from above line because list is not in order!)
110+
# !!! Last ID: 40 !!! (Can be different from above line because list is not in order!)
110111
# To add further element group variables add them here but also above in the presets at the correct index.
111112
# Aside from creating a corresponding UI property in global_props.py and gui.py no extra storage handling is needed like for global settings.
112113

kk_bullet_constraints_builder/gui.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,10 +920,11 @@ def draw(self, context):
920920
row = col.row(align=1)
921921
if props.menu_gotData: row.enabled = 0
922922
row.prop(props, "elemGrp_%d_EGSidxFric" %i)
923-
row.prop(props, "elemGrp_%d_EGSidxIter" %i)
923+
row.prop(props, "elemGrp_%d_EGSidxBlnc" %i)
924924

925925
row = col.row(align=1)
926926
if props.menu_gotData: row.enabled = 0
927+
row.prop(props, "elemGrp_%d_EGSidxIter" %i)
927928
row.prop(props, "elemGrp_%d_EGSidxSDFl" %i)
928929

929930
row = col.row(align=1)

0 commit comments

Comments
 (0)