Skip to content

Commit 7cfec1e

Browse files
committed
Fixed an issue when objects were selected without being part of any element group
Additionally, support for advanced math functions for use in breaking threshold expressions was added.
1 parent 693a5be commit 7cfec1e

File tree

8 files changed

+289
-466
lines changed

8 files changed

+289
-466
lines changed

kk_bullet_constraints_builder.zip

-1.57 KB
Binary file not shown.

kk_bullet_constraints_builder/builder.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,7 @@ def build():
8888
if props.minimumElementSize: connectsPair, connectsPairParent = deleteConnectionsWithTooSmallElementsAndParentThemInstead(objs, connectsPair, connectsPairDist)
8989
else: connectsPairParent = []
9090
###### Calculate contact area for all connections
91-
### For now this is not used anymore as it is less safe than to derive an accurate contact area indirectly by using: volume /length
92-
if props.useAccurateArea:
93-
#connectsGeo, connectsLoc = calculateContactAreaBasedOnBooleansForAll(objs, objsEGrp, connectsPair)
94-
connectsGeo, connectsLoc = calculateContactAreaBasedOnBoundaryBoxesForAll(objs, objsEGrp, connectsPair, qAccurate=1)
95-
else:
96-
connectsGeo, connectsLoc = calculateContactAreaBasedOnBoundaryBoxesForAll(objs, objsEGrp, connectsPair, qAccurate=0)
91+
connectsGeo, connectsLoc = calculateContactAreaBasedOnBoundaryBoxesForAll(objs, objsEGrp, connectsPair, qAccurate=props.useAccurateArea)
9792
###### Delete connections with zero contact area
9893
connectsPair, connectsGeo, connectsLoc = deleteConnectionsWithZeroContactArea(objs, objsEGrp, connectsPair, connectsGeo, connectsLoc)
9994
###### Delete connections with references from predefined constraints

kk_bullet_constraints_builder/builder_prep.py

Lines changed: 235 additions & 428 deletions
Large diffs are not rendered by default.

kk_bullet_constraints_builder/builder_setc.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import bpy, mathutils, math, sys, copy, random
3434
from mathutils import Vector
35+
from math import *
3536
import global_vars
3637

3738
### Import submodules
@@ -197,8 +198,10 @@ def setConstraintSettings(objs, objsEGrp, emptyObjs, objsID, connectsPair, conne
197198

198199
objA = objs[pair[0]]
199200
objB = objs[pair[1]]
200-
# If objects are missing fill in empty data and skip rest
201-
if objA == None or objB == None or len(consts) == 0:
201+
elemGrpA = objsEGrp[objsDict[objA]]
202+
elemGrpB = objsEGrp[objsDict[objB]]
203+
# If objects are missing or connection not used then fill in empty data and skip rest
204+
if objA == None or objB == None or len(consts) == 0 or elemGrpA == -1 or elemGrpB == -1:
202205
cData = {}; cDatb = []
203206
for cIdx in consts:
204207
setConstParams(cData,cDatb,cDef)
@@ -216,8 +219,6 @@ def setConstraintSettings(objs, objsEGrp, emptyObjs, objsID, connectsPair, conne
216219
geoContactArea *= min(corFacA, corFacB)
217220

218221
### Prepare connection data
219-
elemGrpA = objsEGrp[objsDict[objA]]
220-
elemGrpB = objsEGrp[objsDict[objB]]
221222
elemGrps_elemGrpA = elemGrps[elemGrpA]
222223
elemGrps_elemGrpB = elemGrps[elemGrpB]
223224
CT_A = elemGrps_elemGrpA[EGSidxCTyp]
@@ -675,6 +676,7 @@ def setConstraintSettings(objs, objsEGrp, emptyObjs, objsID, connectsPair, conne
675676
if damageMul < 1:
676677
damage = (1 -damageMul) *100
677678
for idx in consts: emptyObjs[idx]['Damage %'] = damage
679+
objConst0['Element Group'] = elemGrp
678680
else:
679681
qUpdateComplete = 1
680682

@@ -1607,7 +1609,9 @@ def setConstraintSettings(objs, objsEGrp, emptyObjs, objsID, connectsPair, conne
16071609
bpy.context.window_manager.progress_update(k /len(connectsPair))
16081610

16091611
obj = objs[k]
1610-
elemGrp = objsEGrp[objsDict[obj]]
1612+
elemGrp = objsEGrp[objsDict[obj]]
1613+
if elemGrp == -1: continue
1614+
16111615
elemGrps_elemGrp = elemGrps[elemGrp]
16121616
dims = obj.dimensions /2
16131617
# Compensate BCB rescaling

kk_bullet_constraints_builder/formula_props.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import bpy
3434
import global_vars
35+
from math import *
3536

3637
### Import submodules
3738
from global_vars import * # Contains global variables

kk_bullet_constraints_builder/gui.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
################################################################################
3232

3333
import bpy, sys
34+
from math import *
3435
import global_vars
3536

3637
### Import submodules

kk_bullet_constraints_builder/monitor.py

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,12 @@ def monitor_initBuffers(scene):
428428

429429
objA = objs[pair[0]]
430430
objB = objs[pair[1]]
431-
if objA != None and objB != None:
431+
elemGrpA = objsEGrp[pair[0]]
432+
elemGrpB = objsEGrp[pair[1]]
433+
if objA != None and objB != None and elemGrpA != -1 and elemGrpB != -1:
432434
tol = next(connectsTol_iter)
433435
geo = next(connectsGeo_iter)
434436
geoContactArea = geo[0]
435-
elemGrpA = objsEGrp[pair[0]]
436-
elemGrpB = objsEGrp[pair[1]]
437437
elemGrps_elemGrpA = elemGrps[elemGrpA]
438438
elemGrps_elemGrpB = elemGrps[elemGrpB]
439439
Prio_A = elemGrps_elemGrpA[EGSidxPrio]
@@ -498,7 +498,8 @@ def monitor_checkForChange(scene):
498498

499499
props = bpy.context.window_manager.bcb
500500
connects = bpy.app.driver_namespace["bcb_monitor"]
501-
progrWeakVar = 1 -bpy.app.driver_namespace["bcb_progrWeakTmp"]
501+
try: progrWeakVar = 1 -bpy.app.driver_namespace["bcb_progrWeakTmp"]
502+
except: progrWeakVar = 1
502503
rbw_steps_per_second = scene.rigidbody_world.steps_per_second
503504
rbw_time_scale = scene.rigidbody_world.time_scale
504505

@@ -679,7 +680,7 @@ def monitor_checkForChange(scene):
679680
cntB += 1
680681

681682
# Progressive Weakening
682-
if qProgrWeak:
683+
if qProgrWeak and progrWeakVar != 1:
683684
for const in consts:
684685
const.rigid_body_constraint.breaking_threshold *= progrWeakVar
685686

@@ -766,11 +767,11 @@ def monitor_initBuffers_fm(scene):
766767

767768
objA = objs[pair[0]]
768769
objB = objs[pair[1]]
769-
if objA != None and objB != None:
770+
elemGrpA = objsEGrp[pair[0]]
771+
elemGrpB = objsEGrp[pair[1]]
772+
if objA != None and objB != None and elemGrpA != -1 and elemGrpB != -1:
770773
geo = next(connectsGeo_iter)
771774
geoContactArea = geo[0]
772-
elemGrpA = objsEGrp[pair[0]]
773-
elemGrpB = objsEGrp[pair[1]]
774775
elemGrps_elemGrpA = elemGrps[elemGrpA]
775776
elemGrps_elemGrpB = elemGrps[elemGrpB]
776777
Prio_A = elemGrps_elemGrpA[EGSidxPrio]
@@ -821,7 +822,8 @@ def monitor_checkForChange_fm(scene):
821822
props = bpy.context.window_manager.bcb
822823
elemGrps = global_vars.elemGrps
823824
connects = bpy.app.driver_namespace["bcb_monitor"]
824-
progrWeakVar = 1 -bpy.app.driver_namespace["bcb_progrWeakTmp"]
825+
try: progrWeakVar = 1 -bpy.app.driver_namespace["bcb_progrWeakTmp"]
826+
except: progrWeakVar = 1
825827
rbw_steps_per_second = scene.rigidbody_world.steps_per_second
826828
rbw_time_scale = scene.rigidbody_world.time_scale
827829

@@ -938,7 +940,7 @@ def monitor_checkForChange_fm(scene):
938940
con.breaking_threshold = constsBrkThres[i] +(brkThresInc *rbw_time_scale /rbw_steps_per_second)
939941

940942
# Progressive Weakening
941-
if qProgrWeak:
943+
if qProgrWeak and progrWeakVar != 1:
942944
for const in consts:
943945
const.breaking_threshold *= progrWeakVar
944946

@@ -1010,8 +1012,10 @@ def monitor_initTriggers(scene):
10101012
grpName = elemGrp[EGSidxName]
10111013
grpObjs = []
10121014
for obj in objs:
1013-
if elemGrp == elemGrps[objsEGrp[objsDict[obj]]]:
1014-
grpObjs.append(obj)
1015+
elemGrpIdx = objsEGrp[objsDict[obj]]
1016+
if elemGrpIdx != -1:
1017+
if elemGrp == elemGrps[elemGrpIdx]:
1018+
grpObjs.append(obj)
10151019
grpsObjs[grpName] = grpObjs
10161020

10171021
### Get trigger data from text file
@@ -1278,8 +1282,10 @@ def monitor_dampingRegion(scene):
12781282
grpName = elemGrp[EGSidxName]
12791283
grpObjs = []
12801284
for obj in objs:
1281-
if elemGrp == elemGrps[objsEGrp[objsDict[obj]]]:
1282-
grpObjs.append(obj)
1285+
elemGrpIdx = objsEGrp[objsDict[obj]]
1286+
if elemGrpIdx != -1:
1287+
if elemGrp == elemGrps[elemGrpIdx]:
1288+
grpObjs.append(obj)
12831289
grpsObjs[grpName] = grpObjs
12841290

12851291
### On start frame backup data
@@ -1387,8 +1393,10 @@ def monitor_dampingRegion_fm(scene):
13871393
grpName = elemGrp[EGSidxName]
13881394
grpObjs = []
13891395
for obj in objs:
1390-
if elemGrp == elemGrps[objsEGrp[objsDict[obj]]]:
1391-
grpObjs.append(obj)
1396+
elemGrpIdx = objsEGrp[objsDict[obj]]
1397+
if elemGrpIdx != -1:
1398+
if elemGrp == elemGrps[elemGrpIdx]:
1399+
grpObjs.append(obj)
13921400
grpsObjs[grpName] = grpObjs
13931401

13941402
### On start frame backup data
@@ -1482,8 +1490,10 @@ def monitor_displCorrectDiffExport(scene):
14821490
grpName = elemGrp[EGSidxName]
14831491
grpObjs = []
14841492
for obj in objs:
1485-
if elemGrp == elemGrps[objsEGrp[objsDict[obj]]]:
1486-
grpObjs.append(obj)
1493+
elemGrpIdx = objsEGrp[objsDict[obj]]
1494+
if elemGrpIdx != -1:
1495+
if elemGrp == elemGrps[elemGrpIdx]:
1496+
grpObjs.append(obj)
14871497
grpsObjs[grpName] = grpObjs
14881498

14891499
if "bcb_vLocs" not in bpy.app.driver_namespace:
@@ -1555,8 +1565,10 @@ def monitor_freeBuffers(scene):
15551565
grpName = elemGrp[EGSidxName]
15561566
grpObjs = []
15571567
for obj in objs:
1558-
if elemGrp == elemGrps[objsEGrp[objsDict[obj]]]:
1559-
grpObjs.append(obj)
1568+
elemGrpIdx = objsEGrp[objsDict[obj]]
1569+
if elemGrpIdx != -1:
1570+
if elemGrp == elemGrps[elemGrpIdx]:
1571+
grpObjs.append(obj)
15601572
grpsObjs[grpName] = grpObjs
15611573

15621574
if connects != None:
@@ -1644,8 +1656,10 @@ def monitor_freeBuffers_fm(scene):
16441656
grpName = elemGrp[EGSidxName]
16451657
grpObjs = []
16461658
for obj in objs:
1647-
if elemGrp == elemGrps[objsEGrp[objsDict[obj]]]:
1648-
grpObjs.append(obj)
1659+
elemGrpIdx = objsEGrp[objsDict[obj]]
1660+
if elemGrpIdx != -1:
1661+
if elemGrp == elemGrps[elemGrpIdx]:
1662+
grpObjs.append(obj)
16491663
grpsObjs[grpName] = grpObjs
16501664

16511665
if connects != None:

kk_bullet_constraints_builder/tools.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,11 +2083,12 @@ def tool_forcesVisualization_eventHandler(scene):
20832083
if qFoundation:
20842084
elemGrpA = objsEGrp[pair[0]]
20852085
elemGrpB = objsEGrp[pair[1]]
2086-
CT_A = elemGrps[elemGrpA][EGSidxCTyp]
2087-
CT_B = elemGrps[elemGrpB][EGSidxCTyp]
2088-
if CT_A != 0 and CT_B == 0: pass # Only A is active and B is passive group
2089-
elif CT_A == 0 and CT_B != 0: pass # Only B is active and A is passive group
2090-
else: qUse = 0
2086+
if elemGrpA != -1 and elemGrpB != -1:
2087+
CT_A = elemGrps[elemGrpA][EGSidxCTyp]
2088+
CT_B = elemGrps[elemGrpB][EGSidxCTyp]
2089+
if CT_A != 0 and CT_B == 0: pass # Only A is active and B is passive group
2090+
elif CT_A == 0 and CT_B != 0: pass # Only B is active and A is passive group
2091+
else: qUse = 0
20912092
# Fallback in case no foundation group is available, then check for passive objects instead
20922093
else:
20932094
if not qFM and (objA.rigid_body.type == 'ACTIVE' and objB.rigid_body.type == 'ACTIVE'): qUse = 0

0 commit comments

Comments
 (0)