Skip to content

Commit 6174c12

Browse files
committed
Pushed 4.0.0
1 parent 7ece29e commit 6174c12

File tree

10 files changed

+343
-30
lines changed

10 files changed

+343
-30
lines changed

ArmaToolbox/ArmaTools.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,3 +987,71 @@ def setFaceFlags(self, context, flags, mask):
987987
fl = face[fflayer] & ~mask
988988
face[fflayer] = fl | flags
989989

990+
def matchAllConfigs(context, mainObject, testObject):
991+
mainArma = mainObject.armaObjProps
992+
testArma = testObject.armaObjProps
993+
994+
if not testArma.isArmaObject:
995+
return False
996+
997+
## Generate the list of configs to check against
998+
## On always export, use the list of all configs
999+
mainConfigs = mainArma.exportConfigs.keys()
1000+
if mainArma.alwaysExport:
1001+
mainConfigs = context.scene.armaExportConfigs.exportConfigs.keys()
1002+
testConfigs = testArma.exportConfigs.keys()
1003+
if testArma.alwaysExport:
1004+
testConfigs = context.scene.armaExportConfigs.exportConfigs.keys()
1005+
configs = context.scene.armaExportConfigs.exportConfigs.keys()
1006+
1007+
for c in configs:
1008+
if c in mainConfigs and c not in testConfigs:
1009+
return False
1010+
if c not in mainConfigs and c in testConfigs:
1011+
return False
1012+
1013+
return True
1014+
1015+
def matchAnyConfigs(context, mainObject, testObject):
1016+
mainArma = mainObject.armaObjProps
1017+
testArma = testObject.armaObjProps
1018+
1019+
if not testArma.isArmaObject:
1020+
return False
1021+
1022+
## Generate the list of configs to check against
1023+
## On always export, use the list of all configs
1024+
mainConfigs = mainArma.exportConfigs.keys()
1025+
if mainArma.alwaysExport:
1026+
mainConfigs = context.scene.armaExportConfigs.exportConfigs.keys()
1027+
testConfigs = testArma.exportConfigs.keys()
1028+
if testArma.alwaysExport:
1029+
testConfigs = context.scene.armaExportConfigs.exportConfigs.keys()
1030+
1031+
for c in mainConfigs:
1032+
if c in testConfigs:
1033+
return True
1034+
1035+
return False
1036+
1037+
def matchAtLeastConfigs(context, mainObject, testObject):
1038+
mainArma = mainObject.armaObjProps
1039+
testArma = testObject.armaObjProps
1040+
1041+
if not testArma.isArmaObject:
1042+
return False
1043+
1044+
## Generate the list of configs to check against
1045+
## On always export, use the list of all configs
1046+
mainConfigs = mainArma.exportConfigs.keys()
1047+
if mainArma.alwaysExport:
1048+
mainConfigs = context.scene.armaExportConfigs.exportConfigs.keys()
1049+
testConfigs = testArma.exportConfigs.keys()
1050+
if testArma.alwaysExport:
1051+
testConfigs = context.scene.armaExportConfigs.exportConfigs.keys()
1052+
1053+
for c in mainConfigs:
1054+
if c not in testConfigs:
1055+
return False
1056+
1057+
return True

ArmaToolbox/MDLImporter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,8 @@ def loadLOD(context, filePtr, objectName, materialData, layerFlag, lodnr):
525525
# be discarded. Don't want that
526526
#mymesh.validate()
527527
print("Normal calculation")
528-
mymesh.calc_normals()
528+
if (4,0,0) < bpy.app.version:
529+
mymesh.calc_normals()
529530
for poly in mymesh.polygons:
530531
poly.use_smooth = True
531532

ArmaToolbox/MDLexporter.py

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,14 @@ def lodKey(obj):
106106

107107
def convertWeight(weight):
108108
if weight > 1:
109-
weight = 1;
109+
weight = 1
110+
if weight < 0:
111+
weight = 0
110112
value = round(255 - 254 * weight)
111113

112114
if value == 255:
113115
value = 0
114-
115-
#print("weight = ", weight, " value=",value)
116+
116117
return value
117118

118119
def writeByte(filePtr, value):
@@ -578,7 +579,7 @@ def sameLod(objects, index):
578579
print(obj.name_full, "is same LOD as ", obj2.name_full, "(no resolution)")
579580
return False
580581

581-
def duplicateObject(obj):
582+
def duplicateObject(obj, applyModifier = True):
582583
print("duplicateObject: ", obj.name_full)
583584
newObj = obj.copy()
584585
newObj.data = obj.data.copy()
@@ -596,11 +597,38 @@ def duplicateObject(obj):
596597
# copy those properties
597598
for prop in properties:
598599
setattr(mDst, prop, getattr(mSrc, prop))
600+
599601

600602
bpy.context.scene.collection.objects.link(newObj)
603+
instantiateMeshCollector(newObj)
601604

602605
return newObj
603606

607+
# Here is how instantiating a mesh collector works
608+
# We get a copy of the original object
609+
# a. we copy each and every collected object
610+
# b. we apply the collected object's modifiers
611+
# c. we join the object into our object.
612+
# TODO: d. if desired, delete specified vertex groups.
613+
def instantiateMeshCollector(master, applyModifiers = True):
614+
objs = [x.object for x in master.armaObjProps.collectedMeshes]
615+
616+
instances = []
617+
618+
for o in objs:
619+
copied = duplicateObject(o)
620+
if applyModifiers:
621+
applyModifiersOnObject(copied)
622+
instances.append(copied)
623+
624+
bpy.ops.object.select_all(action='DESELECT')
625+
for x in instances:
626+
x.select_set(True)
627+
628+
master.select_set(True)
629+
bpy.context.view_layer.objects.active = master
630+
ArmaTools.joinObjectToObject(bpy.context)
631+
604632

605633
def exportLodLevelWithModifiers(myself, filePtr, obj, wm, idx, applyModifiers, renumberComponents, applyTransforms, originObject):
606634
print("Exporting lod " , lodKey(obj), "of object", obj.name)
@@ -690,7 +718,7 @@ def exportMDL(myself, filePtr, selectedOnly, applyModifiers, mergeSameLOD, renum
690718

691719
def exportObjectListAsMDL(myself, filePtr, applyModifiers, mergeSameLOD, objects, renumberComponents, applyTransforms, originObject):
692720

693-
print("originObject =", originObject)
721+
print("exportObjectListAsMDL: originObject =", originObject)
694722

695723
objects = sorted(objects, key=lodKey)
696724

@@ -721,14 +749,20 @@ def exportObjectListAsMDL(myself, filePtr, applyModifiers, mergeSameLOD, objects
721749

722750

723751
else:
724-
752+
753+
hasMeshCollector = False
754+
for ob in objects:
755+
if ob.armaObjProps.isMeshCollector:
756+
hasMeshCollector = True
757+
758+
print("has mesh collector: ", hasMeshCollector)
725759

726760
idx = 0
727761
while idx < len(objects):
728762
obj = objects[idx]
729763
realIndex = idx
730764
print ("Considering object ", objects[idx].name)
731-
if sameLod(objects, idx):
765+
if sameLod(objects, idx) or hasMeshCollector:
732766
print ("There are objects to merge")
733767
# Copy this object and merge all subsequent objects of the same LOD
734768
newTmpObj = duplicateObject(obj)

ArmaToolbox/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"name": "Arma: Toolbox",
33
"description": "Collection of tools for editing RV Engine content",
44
"author": "Hans-Joerg \"Alwarren\" Frieden.",
5-
"version": (3, 1, 1),
6-
"blender": (2, 80, 0),
5+
"version": (4, 0, 0),
6+
"blender": (3, 0, 0),
77
"location": "View3D > Panels",
88
"warning": '',
99
"wiki_url": "https://github.com/AlwarrenSidh/ArmAToolbox/wiki",

ArmaToolbox/lists.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,25 @@ def draw_item(self, context, layout, data, item, icon, active_data, active_propn
174174
#def invoke(self, context, event):
175175
# print ("Invoke called")
176176

177+
class ATBX_UL_collected_meshes_list(bpy.types.UIList):
178+
# The draw_item function is called for each item of the collection that is visible in the list.
179+
# data is the RNA object containing the collection,
180+
# item is the current drawn item of the collection,
181+
# icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
182+
# have custom icons ID, which are not available as enum items).
183+
# active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
184+
# active item of the collection).
185+
# active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
186+
# index is index of the current item in the collection.
187+
188+
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
189+
190+
if self.layout_type in {'DEFAULT', 'COMPACT'}:
191+
o = item.object
192+
layout.prop(o, property="name", text="", emboss=False, icon="OBJECT_DATA")
193+
elif self.layout_type == 'GRID':
194+
layout.alignment = 'CENTER'
195+
layout.label(text="", icon="GROUP_VERTEX")
177196

178197
list_classes = (
179198
ATBX_UL_named_prop_list,
@@ -184,6 +203,7 @@ def draw_item(self, context, layout, data, item, icon, active_data, active_propn
184203
ATBX_UL_export_config_list,
185204
ATBX_UL_export_config_object_list,
186205
ATBX_UL_named_selections_list,
206+
ATBX_UL_collected_meshes_list,
187207
)
188208

189209
def safeAddTime(frame, prop):

ArmaToolbox/menus.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,20 @@ def draw(self, context):
2020
layout = self.layout
2121
layout.operator("armatoolbox.clear_props", text="Clear all", icon='CANCEL')
2222

23+
class ATBX_MT_mesh_collector_menu(Menu):
24+
bl_label = "Mesh Collector"
25+
26+
def draw(self, context):
27+
layout = self.layout
28+
layout.operator("armatoolbox.clear_mesh_collector", text="Clear Mesh List", icon='CANCEL')
29+
layout.operator("armatoolbox.add_same_config_mesh_collector", text="Add all meshes with the exact same config", icon='ADD')
30+
layout.operator("armatoolbox.add_any_config_mesh_collector", text="Add all meshes with one common config", icon='ADD')
31+
layout.operator("armatoolbox.add_atleast_config_mesh_collector", text="Add all meshes with at least all common config", icon='ADD')
2332

2433
menu_classes = (
2534
#ATBX_MT_named_selection_menu,
2635
ATBX_MT_named_properties_menu,
36+
ATBX_MT_mesh_collector_menu
2737
)
2838

2939

ArmaToolbox/operators.py

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,132 @@ def execute(self, context):
12981298

12991299
return {'FINISHED'}
13001300

1301+
class ATBX_OT_add_selected_meshes(bpy.types.Operator):
1302+
bl_idname = "armatoolbox.add_selected_meshes"
1303+
bl_label = "Add selected meshes to active mesh capture list"
1304+
bl_description ="Add selected meshes to active mesh capture list"
1305+
1306+
@classmethod
1307+
def poll(cls, context):
1308+
l = len(context.selected_objects)
1309+
return l>=2 and context.active_object.armaObjProps.isMeshCollector
1310+
1311+
def execute(self, context):
1312+
objs = context.selected_objects
1313+
arma = context.active_object.armaObjProps
1314+
for o in objs:
1315+
if o != context.active_object and o.type == 'MESH':
1316+
if o not in [x.object for x in arma.collectedMeshes]:
1317+
item = context.active_object.armaObjProps.collectedMeshes.add()
1318+
print(item)
1319+
item.object = o
1320+
1321+
return {'FINISHED'}
1322+
1323+
class ATBX_OT_rem_selected_meshes(bpy.types.Operator):
1324+
bl_idname = "armatoolbox.rem_selected_meshes"
1325+
bl_label = "Remove Active meshes from active mesh capture list"
1326+
bl_description ="Remove Active meshes from active mesh capture list"
1327+
1328+
@classmethod
1329+
def poll(cls, context):
1330+
return context.active_object.armaObjProps.collectedMeshesIndex != -1
1331+
1332+
def execute(self, context):
1333+
obj = context.active_object
1334+
arma = obj.armaObjProps
1335+
if arma.collectedMeshesIndex != -1:
1336+
arma.collectedMeshes.remove(arma.collectedMeshesIndex)
1337+
1338+
return {'FINISHED'}
1339+
1340+
class ATBX_MT_clear_mesh_collector(bpy.types.Operator):
1341+
bl_idname = "armatoolbox.clear_mesh_collector"
1342+
bl_label = "Remove all meshes from the list"
1343+
bl_description = "Remove all meshes from the list"
1344+
1345+
def execute(self,context):
1346+
obj = context.active_object
1347+
arma = obj.armaObjProps
1348+
arma.collectedMeshes.clear()
1349+
1350+
return {'FINISHED'}
1351+
1352+
class ATBX_MT_add_same_config_mesh_collector(bpy.types.Operator):
1353+
bl_idname = "armatoolbox.add_same_config_mesh_collector"
1354+
bl_label = "Add all objects with the same config combo"
1355+
bl_description = "Add all objects to this collector that have the exact same combination of configs"
1356+
1357+
def execute(self, context):
1358+
arma = context.active_object.armaObjProps
1359+
if len(context.selected_objects)>1:
1360+
cobjs = context.selected_objects
1361+
else:
1362+
cobjs = context.view_layer.objects
1363+
1364+
objs = [obj for obj in cobjs
1365+
if obj.type == 'MESH'
1366+
and obj.armaObjProps.isArmaObject
1367+
and obj != context.active_object
1368+
and ArmaTools.matchAllConfigs(context, context.active_object, obj)]
1369+
1370+
for o in objs:
1371+
if o != context.active_object and o.type == 'MESH':
1372+
if o not in [x.object for x in arma.collectedMeshes]:
1373+
item = context.active_object.armaObjProps.collectedMeshes.add()
1374+
item.object = o
1375+
1376+
return {'FINISHED'}
1377+
1378+
class ATBX_MT_add_any_config_mesh_collector(bpy.types.Operator):
1379+
bl_idname = "armatoolbox.add_any_config_mesh_collector"
1380+
bl_label = "Add all objects with the at least one common config"
1381+
bl_description = "Add all objects to this collector that have the one or more of the objects configs"
1382+
1383+
def execute(self, context):
1384+
arma = context.active_object.armaObjProps
1385+
if len(context.selected_objects)>1:
1386+
cobjs = context.selected_objects
1387+
else:
1388+
cobjs = context.view_layer.objects
1389+
1390+
objs = [obj for obj in cobjs
1391+
if obj.type == 'MESH'
1392+
and obj.armaObjProps.isArmaObject
1393+
and obj != context.active_object
1394+
and ArmaTools.matchAnyConfigs(context, context.active_object, obj)]
1395+
for o in objs:
1396+
if o != context.active_object and o.type == 'MESH':
1397+
if o not in [x.object for x in arma.collectedMeshes]:
1398+
item = context.active_object.armaObjProps.collectedMeshes.add()
1399+
item.object = o
1400+
1401+
return {'FINISHED'}
1402+
1403+
class ATBX_MT_add_atleast_config_mesh_collector(bpy.types.Operator):
1404+
bl_idname = "armatoolbox.add_atleast_config_mesh_collector"
1405+
bl_label = "Add all objects with the at least one common config"
1406+
bl_description = "Add all objects to this collector that have the one or more of the objects configs"
1407+
1408+
def execute(self, context):
1409+
arma = context.active_object.armaObjProps
1410+
if len(context.selected_objects)>1:
1411+
cobjs = context.selected_objects
1412+
else:
1413+
cobjs = context.view_layer.objects
1414+
1415+
objs = [obj for obj in cobjs
1416+
if obj.type == 'MESH'
1417+
and obj.armaObjProps.isArmaObject
1418+
and obj != context.active_object
1419+
and ArmaTools.matchAtLeastConfigs(context, context.active_object, obj)]
1420+
for o in objs:
1421+
if o != context.active_object and o.type == 'MESH':
1422+
if o not in [x.object for x in arma.collectedMeshes]:
1423+
item = context.active_object.armaObjProps.collectedMeshes.add()
1424+
item.object = o
1425+
1426+
return {'FINISHED'}
13011427

13021428
op_classes = (
13031429
ATBX_OT_add_frame_range,
@@ -1360,7 +1486,13 @@ def execute(self, context):
13601486
ATBX_OT_set_zbias,
13611487
ATBX_OT_select_zbiased,
13621488
ATBX_OT_batch_rename_vgrp,
1363-
ATBX_OT_match_vgrp
1489+
ATBX_OT_match_vgrp,
1490+
ATBX_OT_add_selected_meshes,
1491+
ATBX_OT_rem_selected_meshes,
1492+
ATBX_MT_clear_mesh_collector,
1493+
ATBX_MT_add_same_config_mesh_collector,
1494+
ATBX_MT_add_any_config_mesh_collector,
1495+
ATBX_MT_add_atleast_config_mesh_collector
13641496
)
13651497

13661498

0 commit comments

Comments
 (0)