77import bpy
88import bmesh
99from . import (
10- ArmaProxy
10+ ArmaProxy ,
11+ MDLImporter
1112)
1213import tempfile
1314from subprocess import call
@@ -1103,4 +1104,216 @@ def collectionMeshListValid(context, object):
11031104 if collectorMeshValid (context , name ) is False :
11041105 return False
11051106
1106- return True
1107+ return True
1108+
1109+ # from https://blenderartists.org/t/show-hide-collection-blender-beta-2-80/1141768
1110+ # modified for later blender versions
1111+ def get_viewport_ordered_collections (context ):
1112+ def fn (c , out , addme ):
1113+ if addme :
1114+ out .append (c )
1115+ for c1 in c .children :
1116+ out .append (c1 )
1117+ for c1 in c .children :
1118+ fn (c1 , out , False )
1119+ collections = []
1120+ fn (context .scene .collection , collections , True )
1121+ return collections
1122+
1123+ def get_area_from_context (context , area_type ):
1124+ area = None
1125+ for a in context .screen .areas :
1126+ if a .type == area_type :
1127+ area = a
1128+ break
1129+ return area
1130+
1131+ def set_collection_viewport_visibility (context , collection_name , visibility = True ):
1132+ collections = get_viewport_ordered_collections (context )
1133+
1134+ collection = None
1135+ index = 0
1136+ for c in collections :
1137+ if c .name == collection_name :
1138+ collection = c
1139+ break
1140+ index += 1
1141+
1142+ if collection is None :
1143+ return
1144+
1145+ first_object = None
1146+ if len (collection .objects ) > 0 :
1147+ first_object = collection .objects [0 ]
1148+
1149+ try :
1150+ bpy .ops .object .hide_collection (context , collection_index = index , toggle = True )
1151+
1152+ if first_object .visible_get () != visibility :
1153+ bpy .ops .object .hide_collection (context , collection_index = index , toggle = True )
1154+ except :
1155+ context_override = context .copy ()
1156+ context_override ['area' ] = get_area_from_context (context , 'VIEW_3D' )
1157+
1158+ with bpy .context .temp_override (window = context_override ['window' ], area = context_override ['area' ]):
1159+ bpy .ops .object .hide_collection (collection_index = index , toggle = True )
1160+
1161+ if first_object .visible_get () != visibility :
1162+ with bpy .context .temp_override (window = context_override ['window' ], area = context_override ['area' ]):
1163+ bpy .ops .object .hide_collection (collection_index = index , toggle = True )
1164+
1165+ return collection
1166+
1167+ def allButOneCollection (context ):
1168+ colls = context .collection .children_recursive
1169+ first_name = colls [0 ].name
1170+
1171+ for c in colls :
1172+ set_collection_viewport_visibility (context , c .name , False )
1173+
1174+ set_collection_viewport_visibility (context , first_name , True )
1175+
1176+ def getSelectedObjects (context ):
1177+ # Find the Outliner area
1178+ override = None
1179+ for area in bpy .context .screen .areas :
1180+ if area .type == 'OUTLINER' :
1181+ for region in area .regions :
1182+ if region .type == 'WINDOW' :
1183+ override = {'area' : area , 'region' : region }
1184+ break
1185+ break
1186+
1187+ # Get selected objects (including hidden ones) if Outliner exists
1188+ if override :
1189+ with bpy .context .temp_override (** override ):
1190+ selected_objects = [o for o in bpy .context .selected_ids if isinstance (o , bpy .types .Object )]
1191+ return (selected_objects )
1192+ else :
1193+ print ("No Outliner area found!" )
1194+
1195+
1196+ def find_or_create_collection (collection_name ):
1197+ """
1198+ Find a collection by name or create a new one if it doesn't exist.
1199+
1200+ Args:
1201+ collection_name (str): The name of the collection to find or create.
1202+
1203+ Returns:
1204+ bpy.types.Collection: The found or created collection.
1205+ """
1206+ # Check if the collection already exists
1207+ collection = bpy .data .collections .get (collection_name )
1208+
1209+ # If the collection does not exist, create a new one
1210+ if collection is None :
1211+ collection = bpy .data .collections .new (collection_name )
1212+ bpy .context .scene .collection .children .link (collection )
1213+
1214+ return collection
1215+
1216+ def resolutionName (lod , lodDistance ):
1217+
1218+ if (lod == '-1.0' ):
1219+ return "LOD_" + str (lodDistance )
1220+
1221+ values = {
1222+ '1.000e+3' :'View Gunner' ,
1223+ '1.100e+3' :'View Pilot' ,
1224+ '1.200e+3' :'View Cargo' ,
1225+ '1.000e+4' :'Stencil Shadow' ,
1226+ '2.000e+4' :'Edit' ,
1227+ #1.001e+4:'Stencil Shadow 2',
1228+ '1.100e+4' :'Shadow Volume' ,
1229+ #1.101e+4:'Shadow Volume 2',
1230+ '1.000e+13' :'Geometry' ,
1231+ '1.000e+15' :'Memory' ,
1232+ '2.000e+15' :'Land Contact' ,
1233+ '3.000e+15' :'Roadway' ,
1234+ '4.000e+15' :'Paths' ,
1235+ '5.000e+15' :'Hit Points' ,
1236+ '6.000e+15' :'View Geometry' ,
1237+ '7.000e+15' :'Fire Geometry' ,
1238+ '8.000e+15' :'View Cargo Geometry' ,
1239+ '9.000e+15' :'View Cargo Fire Geometry' ,
1240+ '1.000e+16' :'View Commander' ,
1241+ '1.100e+16' :'View Commander Geometry' ,
1242+ '1.200e+16' :'View Commander Fire Geometry' ,
1243+ '1.300e+16' :'View Pilot Geometry' ,
1244+ '1.400e+16' :'View Pilot Fire Geometry' ,
1245+ '1.500e+16' :'View Gunner Geometry' ,
1246+ '1.600e+16' :'View Gunner Fire Geometry' ,
1247+ '1.700e+16' :'Sub Parts' ,
1248+ '1.800e+16' :'Cargo View shadow volume' ,
1249+ '1.900e+16' :'Pilot View shadow volume' ,
1250+ '2.000e+16' :'Gunner View shadow volume' ,
1251+ '2.100e+16' :'Wreckage' ,
1252+ '2.000e+13' :'Geometry Buoyancy' ,
1253+ '4.000e+13' :'Geometry PhysX'
1254+ }
1255+
1256+ for n in values :
1257+ if n == lod :
1258+ if (NeedsResolution (lod )):
1259+ return values [n ] + "_" + str (lodDistance )
1260+ else :
1261+ return values [n ]
1262+
1263+ def createEmptyObject (context , name , collection ):
1264+ verts = []
1265+ faces = []
1266+ mesh_data = bpy .data .meshes .new ("name" )
1267+ mesh_data .from_pydata (verts , [], faces )
1268+ mesh_data .update ()
1269+
1270+ obj = bpy .data .objects .new (name , mesh_data )
1271+
1272+ if collection is not None :
1273+ collection .objects .link (obj )
1274+
1275+ obj .select_set (True )
1276+ bpy .context .view_layer .objects .active = obj
1277+ return obj
1278+
1279+ def meshCollectify (context , obj , mcify_lod , mcify_lodDistance , mcify_colectionName , mcify_addDecimate , mciy_decimateRatio , mcify_deleteGroup ):
1280+ print (
1281+ "obj " , obj .name ,
1282+ "lod " , mcify_lod ,
1283+ "lodDistance " , mcify_lodDistance ,
1284+ "colectionName " , mcify_colectionName
1285+ )
1286+
1287+ if mcify_colectionName != "" :
1288+ collection = find_or_create_collection (mcify_colectionName )
1289+ else :
1290+ collection = context .collection
1291+
1292+ resName = resolutionName (mcify_lod , mcify_lodDistance )
1293+
1294+ nobj = createEmptyObject (context , obj .name + " " + resName + "Mesh Collector" , collection )
1295+ nobj .armaObjProps .isArmaObject = True
1296+ nobj .armaObjProps .lod = mcify_lod
1297+ nobj .armaObjProps .lodDistance = mcify_lodDistance
1298+ nobj .armaObjProps .isMeshCollector = True
1299+
1300+ # Enter the mesh into the mesh collector
1301+ item = nobj .armaObjProps .collectedMeshes .add ()
1302+ item .object = obj
1303+
1304+ # Copy the export configs
1305+ for c in context .scene .armaExportConfigs .exportConfigs :
1306+ nobj .armaObjProps .exportConfigs .add ().name = c .name
1307+
1308+ if mcify_deleteGroup != "" :
1309+ if "," not in mcify_deleteGroup :
1310+ nobj .armaObjProps .collectedMeshesDelete .add ().vname = mcify_deleteGroup
1311+ else :
1312+ grps = mcify_deleteGroup .split ("," )
1313+ for g in grps :
1314+ nobj .armaObjProps .collectedMeshesDelete .add ().vname = g
1315+
1316+ if mcify_addDecimate :
1317+ # Add Decimate modifier
1318+ mod = nobj .modifiers .new (name = "Decimate" , type = 'DECIMATE' )
1319+ mod .ratio = mciy_decimateRatio
0 commit comments