From fa04c0e0f926fdb8eb545300523711eee8dcb907 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sun, 28 Aug 2022 00:35:44 +0200 Subject: [PATCH 01/47] 2.8+ working importb3d --- src/.gitignore | 1 + src/2.79/export_tch/__init__.py | 128 +- src/2.79/importb3d/__init__.py | 24 +- src/2.79/importb3d/importb3d.py | 544 +++--- src/2.79/way_tools/__init__.py | 508 +++--- src/2.80/addons/b3d_tools/__init__.py | 2039 +++++++++++++++++++++++ src/2.80/addons/b3d_tools/common.py | 148 ++ src/2.80/addons/export_tch/__init__.py | 298 ++++ src/2.80/addons/importb3d/__init__.py | 194 +++ src/2.80/addons/importb3d/common.py | 171 ++ src/2.80/addons/importb3d/exportb3d.py | 1837 ++++++++++++++++++++ src/2.80/addons/importb3d/imghelp.py | 224 +++ src/2.80/addons/importb3d/importb3d.py | 1888 +++++++++++++++++++++ src/2.80/addons/way_tools/__init__.py | 1158 +++++++++++++ src/2.80/addons/way_tools/import_way.py | 221 +++ 15 files changed, 8781 insertions(+), 602 deletions(-) create mode 100644 src/.gitignore create mode 100644 src/2.80/addons/b3d_tools/__init__.py create mode 100644 src/2.80/addons/b3d_tools/common.py create mode 100644 src/2.80/addons/export_tch/__init__.py create mode 100644 src/2.80/addons/importb3d/__init__.py create mode 100644 src/2.80/addons/importb3d/common.py create mode 100644 src/2.80/addons/importb3d/exportb3d.py create mode 100644 src/2.80/addons/importb3d/imghelp.py create mode 100644 src/2.80/addons/importb3d/importb3d.py create mode 100644 src/2.80/addons/way_tools/__init__.py create mode 100644 src/2.80/addons/way_tools/import_way.py diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..67314ae --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +/*.py \ No newline at end of file diff --git a/src/2.79/export_tch/__init__.py b/src/2.79/export_tch/__init__.py index 227b02c..b143490 100644 --- a/src/2.79/export_tch/__init__.py +++ b/src/2.79/export_tch/__init__.py @@ -25,186 +25,186 @@ def read_tch(context, filepath, use_some_setting): print("running read_tch...") #file = open(filepath, 'r', encoding='utf-8') #data = f.read() - - + + file = open(filepath, 'r') - + CollisionPlane = [] - + CPlanes_num = 0 - + field_ind = "" field_x = "" field_y = "" field_z = "" field_offset = "" - + for line in file: ColPlane_line = "" if "CollisionPlane" in line: CollisionPlane.append(line) #CPlanes_num += 1 file.close() - + #print(str(CollisionPlane)) ColPlane_vector = [] - - + + for i in range(len(CollisionPlane)):#(CPlanes_num): if i < 10: ColPlane_vector.append((CollisionPlane[i])[16:].split(" ")) else: ColPlane_vector.append((CollisionPlane[i])[17:].split(" ")) #print(str(i)) - + print(str(ColPlane_vector)) # would normally load the data here #print(data) return {'FINISHED'} - + def export_tch(context, filepath): print("exporting tch...") file = open(filepath, 'w') - + global global_matrix global_matrix = axis_conversion(to_forward="-Z", to_up="Y", ).to_4x4() * Matrix.Scale(1, 4) - + global CollisionPlane_num CollisionPlane_num = 0 - + forChild(bpy.data.objects['tch'],True, file, CollisionPlane_num) - + return {'FINISHED'} - + def forChild(object, root, file, CollisionPlane_num): if (not root): if object.name == "Corner_Mark": verticesL = [] uvs = [] faces = [] - + bm = bmesh.new() bm.from_mesh(object.data) bm.verts.ensure_lookup_table() bm.faces.ensure_lookup_table() - + bm.transform(global_matrix * object.matrix_world) - + bm.to_mesh(object.data) - - + + for v in bm.verts: verticesL.append((v.co)) - + meshdata = object.data - + for i, polygon in enumerate(meshdata.polygons): for i1, loopindex in enumerate(polygon.loop_indices): meshloop = meshdata.loops[loopindex] faces.append(meshloop.vertex_index) - + vLen = len(verticesL) - + #for i,vert in enumerate(verticesL): #file.write("CornerMark_" + str(i) + "=" + str(vert[0][0]) + " " + str(-vert[0][2]) + " " + str(vert[0][1])) #file.write(str(object.data.vert[i][0][0])) - - v_num = 0 - + + v_num = 0 + for vert in object.data.vertices: v_num += 1 file.write("Corner_Mark_" + str(v_num) + "=" + str(round(vert.co.x, 6)) + " " + str(round(-vert.co.z, 6)) + " " + str(round(vert.co.y, 6)) + "\n") #file.write(struct.pack(" " + material_textures[k]) - + return material_textures - + def read(file, context, op, filepath, search_tex_names, textures_format, color_format, tex_path): if file.read(3) == b'b3d': print ("correct file"); else: print ("b3d error") - + file.seek(21,1); Imgs = [] math = [] #texr = [] - + if (search_tex_names == True): colors_list = parse_plm(file.name[:-3] + "plm", color_format) material_textures = parse_pro(file.name[:-3] + "pro", colors_list) #print(material_textures) - + for i in range(struct.unpack('23281193): # break - + ex = openclose(file) if ex == 0: #print('-') @@ -386,7 +386,7 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f #print((objString)) #print('eob') #continue - elif ex == 1: + elif ex == 1: print(str(cnt)) file.close() break @@ -404,7 +404,7 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f qu = quat(file).v objString.append(os.path.basename(op.properties.filepath)) ff = file.seek(28,1) - + elif (type == 1): cnt+=1 #b3dObj.append( @@ -413,7 +413,7 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - #b3dObj.hide = True + #b3dObj.hide = True b3dObj['2 name'] = file.read(32).decode("cp1251").rstrip('\0') b3dObj['3 name'] = file.read(32).decode("cp1251").rstrip('\0') @@ -428,8 +428,8 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - #b3dObj.hide = True - + #b3dObj.hide = True + qu = quat(file).v struct.unpack("<4fi",file.read(20)) elif (type == 3): # @@ -441,8 +441,8 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - #b3dObj.hide = True - + #b3dObj.hide = True + qu = quat(file).v struct.unpack("0: pass #printwrite(writefile,tab1+'0d Coords: '+str(coords)) - - elif (type == 14): #sell_ ? - + + elif (type == 14): #sell_ ? + #cnt+=1 #b3dObj = bpy.data.objects.new(objName, None) #b3dObj['block_type'] = 14 @@ -707,19 +707,19 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f #b3dObj.parent = context.scene.objects[objString[-1]] #context.scene.objects.link(b3dObj) #objString.append(context.scene.objects[0].name) - #b3dObj.hide = True + #b3dObj.hide = True - #qu = quat(file).v + #qu = quat(file).v #file.seek(24, 1) #var = struct.unpack(" 15): skip_len = 20 - + elif (11 < len(name) < 15 or len(name) == 15): skip_len = 16 - + elif (7 < len(name) < 11 or len(name) == 11): skip_len = 12 - + elif (3 < len(name) < 7 or len(name) == 7): skip_len = 8 - + elif (len(name) < 3 or len(name) == 3): skip_len = 4 - + file.seek(skip_len, 1) - - + + elif (type == 16): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) @@ -780,7 +780,7 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - #b3dObj.hide = True + #b3dObj.hide = True qu = quat(file).v struct.unpack("11f",file.read(44)) @@ -792,14 +792,14 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - #b3dObj.hide = True + #b3dObj.hide = True qu = quat(file).v struct.unpack("11f",file.read(44)) - + elif (type == 18): #контейнер "применить к" qu = quat(file).v - + cnt+=1 b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = 18 @@ -809,8 +809,8 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - - + + elif (type == 19): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) @@ -819,13 +819,13 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - #b3dObj.hide = True - + #b3dObj.hide = True + num = [] num.append(struct.unpack("i",file.read(4))[0]) #printwrite(writefile,tab1+str(num)) - + elif (type == 20): cnt+=1 #b3dObj = bpy.data.objects.new(objName, None) @@ -835,7 +835,7 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f #objString.append(context.scene.objects[0].name) qu = quat(file).v - + verts_count = struct.unpack("i",file.read(4))[0] struct.unpack("f",file.read(4)) struct.unpack("f",file.read(4)) @@ -851,7 +851,7 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f #for i in range (title[3]): # coords1.append(struct.unpack("f",file.read(4))[0]) curveData = bpy.data.curves.new('curve', type='CURVE') - + curveData.dimensions = '3D' curveData.resolution_u = 2 @@ -870,8 +870,8 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f #scn = bpy.context.scene #scn.objects.link(curveOB) #scn.objects.active = curveOB - - + + b3dObj.location = (0,0,0) b3dObj['block_type'] = 20 b3dObj['pos'] = str(file.tell()) @@ -879,13 +879,13 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - - #bpy.context.scene.objects.link(object) - - elif (type == 21): #testkey??? + #bpy.context.scene.objects.link(object) + + + elif (type == 21): #testkey??? qu = quat(file).v - + cnt+=1 b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = 21 @@ -893,13 +893,13 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.parent = context.scene.objects[objString[-1]] context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - #b3dObj.hide = True + #b3dObj.hide = True object = type15(file) - + elif (type == 23): #colision mesh - + cnt+=1 b3dMesh = (bpy.data.meshes.new(objName)) b3dObj = bpy.data.objects.new(objName, b3dMesh) @@ -909,8 +909,8 @@ def read(file, context, op, filepath, search_tex_names, textures_format, color_f b3dObj.hide = True context.scene.objects.link(b3dObj) objString.append(context.scene.objects[0].name) - - + + #qu = quat(file).v var1 = struct.unpack(" 15): text_len = 20 - + elif (11 < len(str(object['str'])) < 15 or len(str(object['str'])) == 15): text_len = 16 - + elif (7 < len(str(object['str'])) < 11 or len(str(object['str'])) == 11): text_len = 12 - + elif (3 < len(str(object['str'])) < 7 or len(str(object['str'])) == 7): text_len = 8 - + elif (len(str(object['str'])) < 3 or len(str(object['str'])) == 3): text_len = 4 - + bytes_len = 8 + text_len - + object['bytes_len'] = bytes_len object['c_bytes_len'] = 0 - + elif object.name[0:4] == 'RNOD': bytes_len = 8 object['bytes_len'] = bytes_len object['c_bytes_len'] = 0 - + elif object.name[0:4] == 'NNAM': text_len = 0 - + if (len(str(object['str'])) > 15): text_len = 20 - + elif (11 < len(str(object['str'])) < 15 or len(str(object['str'])) == 15): text_len = 16 - + elif (7 < len(str(object['str'])) < 11 or len(str(object['str'])) == 11): text_len = 12 - + elif (3 < len(str(object['str'])) < 7 or len(str(object['str'])) == 7): text_len = 8 - + elif (len(str(object['str'])) < 3 or len(str(object['str'])) == 3): text_len = 4 - + bytes_len = 8 + text_len object['bytes_len'] = bytes_len object['c_bytes_len'] = 0 - + elif object.name[0:4] == 'GROM': bytes_len = 8 object['bytes_len'] = bytes_len object['c_bytes_len'] = 0 - + elif object.name[0:4] == 'GDAT': bytes_len = 8 object['bytes_len'] = bytes_len object['c_bytes_len'] = 0 - + elif object.name[0:4] == 'MNAM': text_len = 0 - + if (len(str(object['str'])) > 15): text_len = 20 - + elif (11 < len(str(object['str'])) < 15 or len(str(object['str'])) == 15): text_len = 16 - + elif (7 < len(str(object['str'])) < 11 or len(str(object['str'])) == 11): text_len = 12 - + elif (3 < len(str(object['str'])) < 7 or len(str(object['str'])) == 7): text_len = 8 - + elif (len(str(object['str'])) < 3 or len(str(object['str'])) == 3): text_len = 4 - + bytes_len = 8 + text_len object['bytes_len'] = bytes_len object['c_bytes_len'] = 0 - + elif object.name[0:4] == 'WTWR': bytes_len = 8 object['bytes_len'] = bytes_len object['c_bytes_len'] = 0 - + elif object.name[0:4] == 'FLAG': bytes_len = 12 object['bytes_len'] = bytes_len object['c_bytes_len'] = 0 #object['flag'] = 1 - + for child in object.children: SetBytesLength(child,False) - + def SetCBytesLength(object, root): varCB = 0 if (not root): if object.name[0:4] == 'RSEG': bytes_len = 8 - + elif object.name[0:4] == 'RNOD': for x in range (len(object.children)): varCB += object.children[x]['bytes_len'] - + object['c_bytes_len'] = varCB - + for child in object.children: - SetCBytesLength(child,False) + SetCBytesLength(child,False) -def SetRS(object, root): +def SetRS(object, root): varRS = 0 if (not root): if object.name[0:4] == 'RSEG': for r in range (len(object.children)): varRS += object.children[r]['bytes_len'] + object.children[r]['c_bytes_len'] - + object['c_bytes_len'] = varRS - + for child in object.children: - SetRS(child, False) - + SetRS(child, False) + def SetGR(object, root): varGR = 0 if (not root): if object.name[0:4] == 'GROM': for j in range (len(object.children)): varGR += object.children[j]['bytes_len'] + object.children[j]['c_bytes_len'] - + object['c_bytes_len'] = varGR - + for child in object.children: SetGR(child, False) - + def SetGD(object, root): variable = 0 if (not root): if object.name[0:4] == 'GDAT': for n in range (len(object.children)): variable += object.children[n]['bytes_len'] + object.children[n]['c_bytes_len'] - + object['c_bytes_len'] = variable - + for child in object.children: SetGD(child, False) - + def SetMN(object, root): varMN = 0 if (not root): if object.name[0:4] == 'MNAM': for i in range (len(object.children)): varMN = object.children[i]['bytes_len'] + object.children[i]['c_bytes_len'] - + object['c_bytes_len'] = varMN - + for child in object.children: SetMN(child, False) - + def SetWT(object, root): varWT = 0 if (not root): if object.name[0:4] == 'WTWR': for i in range (len(object.children)): varWT = object.children[i]['bytes_len'] + object.children[i]['c_bytes_len'] - + object['c_bytes_len'] = varWT - + for child in object.children: SetWT(child, False) - - + + def GetCBytesLength(object, root): var1 = 0 if (not root): @@ -769,26 +769,26 @@ def GetCBytesLength(object, root): if (object.children): for i in range (len(object.children)): var1 = object.children[i]['bytes_len'] + object['bytes_len'] - #object['c_bytes_len'] = var1 + #object['c_bytes_len'] = var1 object['c_bytes_len'] = var1 + object['c_bytes_len'] print(str(var1)) - + for child in object.children: GetCBytesLength(child,False) - -def SetRSEGBytes(object, root): + +def SetRSEGBytes(object, root): if (not root): if object['type'] == 'rseg': for subcurve in object.data.splines: object['bytes_len'] = 68 + len(subcurve.points) * 24 - + room = object.parent room['c_bytes_len'] += object['bytes_len'] - + for child in object.children: - SetRSEGBytes(child, False) - -def SetNodeBytes(object, root): + SetRSEGBytes(child, False) + +def SetNodeBytes(object, root): var_node = 0 print("SetNodeBytes") try: @@ -797,24 +797,24 @@ def SetNodeBytes(object, root): text_len1 = 0 if (len(str(object_name)) > 15): text_len1 = 20 - + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): text_len1 = 16 - + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): text_len1 = 12 - + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): text_len1 = 8 - + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): text_len1 = 4 - + var_node = text_len1 + 16 + 32 + 12 if object['type'] == "ortn": var_node += 104 object['bytes_len'] = var_node - + #object.parent['c_bytes_len'] += var_node room = object.parent room['c_bytes_len'] += var_node @@ -823,38 +823,38 @@ def SetNodeBytes(object, root): SetNodeBytes(child, False) except: pass - -def SetRoomBytes(object, root): + +def SetRoomBytes(object, root): var_r = 0 if object['type'] == 'room': object_name = object.name.split(".")[0] text_len1 = 0 if (len(str(object_name)) > 15): text_len1 = 20 - + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): text_len1 = 16 - + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): text_len1 = 12 - + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): text_len1 = 8 - + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): text_len1 = 4 - + var_r = text_len1 + 16 - + object['bytes_len'] = var_r #+ 8 - + #way = object.parent #way['c_bytes_len'] += object['bytes_len'] for child in object.children: SetRoomBytes(child, False) - -def SetWayBytes(object, root): + +def SetWayBytes(object, root): if object['type'] == 'room': way = object.parent print(object['bytes_len']) @@ -862,37 +862,37 @@ def SetWayBytes(object, root): for child in object.children: SetWayBytes(child, False) - -def SetWayBytes1(object, root): + +def SetWayBytes1(object, root): if object['type'] == 'way': object['bytes_len'] = 20 + object['c_bytes_len'] for child in object.children: SetWayBytes1(child, False) - -def ClearBytes(object, root): + +def ClearBytes(object, root): if object['type'] == 'room': object['bytes_len'] = 0 object['c_bytes_len'] = 0 - + if object['type'] == 'way': object['bytes_len'] = 0 object['c_bytes_len'] = 0 for child in object.children: ClearBytes(child, False) - + def writeWTWR(object, file): file.write(str.encode('WTWR')) file.write(struct.pack(" 15): text_len1 = 20 - + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): text_len1 = 16 - + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): text_len1 = 12 - + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): text_len1 = 8 - + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): text_len1 = 4 - + object['c_bytes_len'] = text_len1 + 8 + 32 + 12 - + if object['type'] == "ortn": object['c_bytes_len'] += 104 - + file.write(struct.pack(" 15): file.write(str.encode(object_name)+bytearray(b'\x00'*(20-len(str(object_name))))) text_len = 20 - + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): file.write(str.encode(object_name)+bytearray(b'\x00'*(16-len(str(object_name))))) text_len = 16 - + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): file.write(str.encode(object_name)+bytearray(b'\x00'*(12-len(str(object_name))))) text_len = 12 - + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): file.write(str.encode(object_name)+bytearray(b'\x00'*(8-len(str(object_name))))) text_len = 8 - + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): file.write(str.encode(object_name)+bytearray(b'\x00'*(4-len(str(object_name))))) text_len = 4 - + #bytes_len = 8 + text_len - + file.write(str.encode('POSN')) file.write(struct.pack(" 15): text_len1 = 20 - + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): text_len1 = 16 - + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): text_len1 = 12 - + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): text_len1 = 8 - + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): text_len1 = 4 - + object['bytes_len'] = 8 + text_len1 + object['c_bytes_len'] object['c_bytes_len'] = object['c_bytes_len'] + 20 - + file.write(struct.pack(" 15): file.write(str.encode(object_name)+bytearray(b'\x00'*(20-len(str(object_name))))) text_len = 20 - + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): file.write(str.encode(object_name)+bytearray(b'\x00'*(16-len(str(object_name))))) text_len = 16 - + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): file.write(str.encode(object_name)+bytearray(b'\x00'*(12-len(str(object_name))))) text_len = 12 - + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): file.write(str.encode(object_name)+bytearray(b'\x00'*(8-len(str(object_name))))) text_len = 8 - + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): file.write(str.encode(object_name)+bytearray(b'\x00'*(4-len(str(object_name))))) text_len = 4 @@ -1125,28 +1125,28 @@ def execute(self, context): # Only needed if you want to add into a dynamic menu def menu_func_export(self, context): self.layout.operator(ExportSomeData.bl_idname, text="Export KOTR *.way") - + def menu_func_import(self, context): self.layout.operator(ImportSomeData.bl_idname, text="Import KOTR *.way") def register(): bpy.utils.register_class(ExportSomeData) - bpy.types.INFO_MT_file_export.append(menu_func_export) - + bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + bpy.utils.register_class(ImportSomeData) - bpy.types.INFO_MT_file_import.append(menu_func_import) - + bpy.types.TOPBAR_MT_file_import.append(menu_func_import) + bpy.utils.register_module(__name__) bpy.types.Scene.way_tool = PointerProperty(type=PanelSettings1) def unregister(): bpy.utils.unregister_class(ExportSomeData) - bpy.types.INFO_MT_file_export.remove(menu_func_export) - + bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) + bpy.utils.unregister_class(ImportSomeData) - bpy.types.INFO_MT_file_import.remove(menu_func_import) - + bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) + bpy.utils.unregister_module(__name__) del bpy.types.Scene.way_tool diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py new file mode 100644 index 0000000..8698170 --- /dev/null +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -0,0 +1,2039 @@ +bl_info = { + "name": "King of The Road Tools Panel for b3d exporter", + "description": "", + "author": "Andrey Prozhoga", + "version": (1, 0, 0), + "blender": (2, 80, 0), + "location": "3D View > Tools", + "warning": "", + "wiki_url": "", + "tracker_url": "vk.com/rnr_mods", + "category": "Development" +} + +if "bpy" in locals(): + print("Reimporting modules!!!") + import importlib + importlib.reload(common) + # importlib.reload(exportb3d) +else: + import bpy + from . import ( + common + ) + +# https://blenderartists.org/t/solved-adding-a-tab-in-blender-2-8/1133119/3 +def getRegion(): + if bpy.app.version < (2,80,0): + return "TOOLS" + else: + return "UI" + +import bpy +from .common import applyRemoveTransforms, applyTransforms, showHideObjByType, showHideObjTreeByType + +from bpy.props import (StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + EnumProperty, + PointerProperty, + ) + +from bpy.types import (Panel, + Operator, + PropertyGroup, + ) + +import bmesh + + +# ------------------------------------------------------------------------ +# store properties in the active scene +# ------------------------------------------------------------------------ + +class PanelSettings(bpy.types.PropertyGroup): + + #my_bool = bpy.props.BoolProperty( + # name="Enable or Disable", + # description="A bool property", + # default = False + # ) + + #my_int : bpy.props.IntProperty( + # name = "Int Value", + # description="A integer property", + # default = 23, + # min = 10, + # max = 100 + # ) + + #my_float : bpy.props.FloatProperty( + # name = "Float Value", + # description = "A float property", + # default = 23.7, + # min = 0.01, + # max = 30.0 + # ) + + BlockName_string : bpy.props.StringProperty( + name="Имя блока", + default="", + maxlen=30, + ) + + addBlockType_enum : bpy.props.EnumProperty( + name="Тип блока", + items=[ ('6566754', "b3d", "b3d"), + ('00', "00", "2D фон"), + ('01', "01", "Камера"), + ('03', "03", "Контейнер"), + ('04', "04", "Контейнер с возможностью привязки к нему других блоков"), + ('05', "05", "Контейнер с возможностью привязки к нему другого блока"), + ('10', "10", "LOD"), + ('12', "12", "Плоскость коллизии"), + ('13', "13", "Триггер (загрузчик карты)"), + ('14', "14", "Блок, связанный с автомобилями"), + ('18', "18", "Связка локатора и 3D-модели, например: FiatWheel0Space и Single0Wheel14"), + ('19', "19", "Контейнер, в отличие от блока типа 05, не имеет возможности привязки"), + ('20', "20", "Плоская коллизия"), + ('21', "21", "Контейнер с обработкой событий"), + #('22', "22", "Блок-локатор"), + #('23', "23", "Объёмная коллизия"), + ('24', "24", "Локатор"), + ('25', "25", "Звуковой объект"), + ('28', "28", "3D-спрайт"), + #('25', "25", "Блок-локатор"), + #('26', "26", "Блок-локатор"), + #('27', "27", "Блок-локатор"), + #('29', "29", "Блок-локатор"), + ('30', "30", "Триггер для загрузки участков карты"), + #('31', "31", "Блок-локатор"), + #('32', "32", "Блок-локатор"), + ('33', "33", "Источник света"), + #('34', "34", "Блок-локатор"), + #('35', "35", "Трисы модели"), + #('36', "36", "Блок-локатор"), + #('37', "37", "Вершины модели"), + #('38', "38", "Блок-локатор"), + #('39', "39", "Блок-локатор"), + ('40', "40", "Генератор объектов"), + ('444', "Разделитель", "Разделитель"), + ] + ) + + addBlockType_enum1 : bpy.props.EnumProperty( + name="Тип блока", + items=[ ('05', "05", "Контейнер с возможностью привязки к нему другого блока"), + ('07', "07", "Меш (ДБ1)"), + ('10', "10", "LOD"), + ('12', "12", "Плоскость коллизии"), + ('14', "14", "Блок, связанный с автомобилями"), + ('18', "18", "Связка локатора и 3D-модели, например: FiatWheel0Space и Single0Wheel14"), + ('19', "19", "Контейнер, в отличие от блока типа 05, не имеет возможности привязки"), + ('20', "20", "Плоская коллизия"), + ('21', "21", "Контейнер с обработкой событий"), + ('23', "23", "Объёмная коллизия"), + ('24', "24", "Локатор"), + ('28', "28", "3D-спрайт"), + ('33', "33", "Источник света"), + ('37', "37", "Меш"), + ('40', "40", "Генератор объектов"), + ] + ) + + CollisionType_enum : bpy.props.EnumProperty( + name="Тип коллизии", + items=(('0', "стандарт", ""), + ('1', "асфальт", ""), + ('2', "земля", ""), + ('3', "вязкое болото", ""), + ('4', "легкопроходимое болото", ""), + ('5', "мокрый асфальт", ""), + ('7', "лёд", ""), + ('8', "вода (уничтожает автомобиль)", ""), + ('10', "песок", ""), + ('11', "пустыня", ""), + ('13', "шипы", ""), + ('16', "лёд (следы от шин не остаются)", ""), + ), + ) + + Radius : bpy.props.FloatProperty( + name = "Радиус блока", + description = "Дальность прорисовки блока", + default = 1.0, + ) + + Radius1 : bpy.props.FloatProperty( + name = "Радиус блока", + description = "Дальность прорисовки блока", + default = 1.0, + ) + + LOD_Distance : bpy.props.FloatProperty( + name = "Дальность отображения LOD", + description = "Маскимальная дальность отображения LOD", + default = 10.0, + ) + + LOD_Distance1 : bpy.props.FloatProperty( + name = "Дальность отображения LOD", + description = "Маскимальная дальность отображения LOD", + default = 10.0, + ) + + Intensity : bpy.props.FloatProperty( + name = "Интенсивность освещения", + description = "Яркость источника света", + default = 1.0, + min = 0.0, + ) + + Intensity1 : bpy.props.FloatProperty( + name = "Интенсивность освещения", + description = "Яркость источника света", + default = 1.0, + min = 0.0, + ) + + R : bpy.props.FloatProperty( + name = "R", + description = "", + default = 255, + min = 0.0, + max = 255, + ) + + G : bpy.props.FloatProperty( + name = "G", + description = "", + default = 255, + min = 0.0, + max = 255, + ) + + B : bpy.props.FloatProperty( + name = "B", + description = "", + default = 255, + min = 0.0, + max = 255, + ) + + R1 : bpy.props.FloatProperty( + name = "R", + description = "", + default = 255, + min = 0.0, + max = 255, + ) + + G1 : bpy.props.FloatProperty( + name = "G", + description = "", + default = 255, + min = 0.0, + max = 255, + ) + + B1 : bpy.props.FloatProperty( + name = "B", + description = "", + default = 255, + min = 0.0, + max = 255, + ) + + RadiusLight : bpy.props.FloatProperty( + name = "Радиус освещения", + description = "", + default = 1, + min = 0.0, + ) + + RadiusLight1 : bpy.props.FloatProperty( + name = "Радиус освещения", + description = "", + default = 1, + min = 0.0, + ) + + LType_enum : bpy.props.EnumProperty( + name="Тип источника света", + items=(('0', 'Тип 0', ""), + ('1', 'Тип 1', ""), + ('2', 'Тип 2', ""), + ('3', 'Тип 3', ""), + ), + ) + + SType_enum : bpy.props.EnumProperty( + name="Тип записи вершин", + items=(#('1', "Тип 1, координаты + UV + нормали", ""), + ('2', "Тип 2, координаты + UV + нормали", "Данный тип используется на обычных моделях"), + ('3', "Тип 3, координаты + UV", "Данный тип используется на моделях света фар"), + ('258', "Тип 258, координаты + UV + нормали + 2 float", "Данный тип используется для моделей асфальтированных дорог"), + ('514', "Тип 514, координаты + UV + нормали + 4 float", "Данный тип используется на моделях поверхности воды"), + ('515', "Тип 515, координаты + UV + нормали + 2 float", "Тоже самое, что и 258. Данный тип используется для моделей асфальтированных дорог"), + ), + ) + + MType_enum : bpy.props.EnumProperty( + name="Тип записи полигонов (35)", + items=(('1', "Тип 1, с разрывной UV", "Каждый трис модели записывается вместе со собственной UV."), + ('3', "Тип 3, без разрывной UV", "Этот тип можно использовать для моделей, которые используют текстуру отражений."), + ), + ) + + texNum_int : bpy.props.IntProperty( + name = "Номер текстуры", + description="Номер используемой текстуры.", + ) + + addBlockName_string : bpy.props.StringProperty( + name="Присоединённый блок", + description="Имя блока, который будет приписан к текущему блоку, например: hit_BmwM5 приписан к BmwM5 (05)", + default="", + maxlen=30, + ) + + addBlockName1_string : bpy.props.StringProperty( + name="Присоединённый блок", + description="Имя блока, который будет приписан к текущему блоку, например: hit_BmwM5 приписан к BmwM5 (05)", + default="", + maxlen=30, + ) + + addSpaceName_string : bpy.props.StringProperty( + name="Используемый локатор", + description="Имя блока, который будет использоваться в качестве локатора для привязанного блока, например: AirportSpace и Airport", + default="", + maxlen=30, + ) + + addSpaceName1_string : bpy.props.StringProperty( + name="Используемый локатор", + description="Имя блока, который будет использоваться в качестве локатора для привязанного блока, например: AirportSpace и Airport", + default="", + maxlen=30, + ) + + add24Flag_enum : bpy.props.EnumProperty( + name="Флаг", + items=[ ('0', "0", "Присоединённый объект не будет отображаться"), + ('1', "1", "Присоединённый объект будет отображаться"), + ] + ) + + add24Flag_enum1 : bpy.props.EnumProperty( + name="Флаг", + items=[ ('0', "0", "Присоединённый объект не будет отображаться"), + ('1', "1", "Присоединённый объект будет отображаться"), + ] + ) + + TGType_int : bpy.props.IntProperty( + name = "Тип модели дерева", + description="", + ) + + Scale : bpy.props.FloatProperty( + name = "Масштаб генератора", + description="", + min=0.0, + default=9.5, + ) + + generatorType_enum : bpy.props.EnumProperty( + name="Тип генератора", + items=[ ('$SeaGenerator', "$SeaGenerator", ""), + ('$$TreeGenerator1', "$$TreeGenerator1", ""), + ('$$TreeGenerator', "$$TreeGenerator", ""), + ('$$CollisionOfTerrain', "$$CollisionOfTerrain", ""), + ('$$GeneratorOfTerrain', "$$GeneratorOfTerrain", ""), + ('$$People', "$$People", ""), + ('$$WeldingSparkles', "$$WeldingSparkles", ""), + ('$$DynamicGlow', "$$DynamicGlow", ""), + ('$$StaticGlow', "$$StaticGlow", ""), + ] + ) + + groupsNum_int : bpy.props.IntProperty( + name = "Количество групп", + description="Количество переключаемых групп.", + ) + + groupsNum1_int : bpy.props.IntProperty( + name = "Количество групп", + description="Количество переключаемых групп.", + ) + + Refer_bool = bpy.props.BoolProperty( + name="refer", + description="", + default = False + ) + + Type21_enum : bpy.props.EnumProperty( + name="Имя 21 блока", + items=[ ('GeometryKey', "GeometryKey", ""), + ('CollisionKey', "CollisionKey", ""), + ('GlassKey', "GlassKey", ""), + ('RD_LampKey', "RD_LampKey", ""), + ('RD_Key', "RD_Key", ""), + ('RedSvetKey', "RedSvetKey", ""), + ('GreenSvetKey', "GreenSvetKey", ""), + ('TrafficLightKey0', "TrafficLightKey0", ""), + ('TrafficLightKey1', "TrafficLightKey1", ""), + ('ILLUM_LEVEL_00', "ILLUM_LEVEL_00", ""), + ('ILLUM_LEVEL_01', "ILLUM_LEVEL_01", ""), + ('ILLUM_LEVEL_02', "ILLUM_LEVEL_02", ""), + ('ILLUM_LEVEL_03', "ILLUM_LEVEL_03", ""), + ('ILLUM_LEVEL_04', "ILLUM_LEVEL_04", ""), + ('ILLUM_LEVEL_05', "ILLUM_LEVEL_05", ""), + ('ILLUM_LEVEL_06', "ILLUM_LEVEL_06", ""), + ('ILLUM_LEVEL_07', "ILLUM_LEVEL_07", ""), + ('ILLUM_LEVEL_08', "ILLUM_LEVEL_08", ""), + ('ILLUM_LEVEL_09', "ILLUM_LEVEL_09", ""), + ('ILLUM_LEVEL_10', "ILLUM_LEVEL_10", ""), + ('ILLUM_LEVEL_11', "ILLUM_LEVEL_11", ""), + ('ILLUM_LEVEL_12', "ILLUM_LEVEL_12", ""), + ('ILLUM_LEVEL_13', "ILLUM_LEVEL_13", ""), + ('ILLUM_LEVEL_14', "ILLUM_LEVEL_14", ""), + ('ILLUM_LEVEL_15', "ILLUM_LEVEL_15", ""), + ('Damage1Key', "Damage1Key", ""), + ('DamageFRKey', "DamageFRKey", ""), + ('DamageFCKey', "DamageFCKey", ""), + ('DamageFLKey', "DamageFLKey", ""), + ('DamageRKey', "DamageRKey", ""), + ('DamageLKey', "DamageLKey", ""), + ('DamageBRKey', "DamageBRKey", ""), + ('DamageBCKey', "DamageBCKey", ""), + ('DamageBLKey', "DamageBLKey", ""), + ('DamageWheel0Key', "DamageWheel0Key", ""), + ('DamageWheel1Key', "DamageWheel1Key", ""), + ('DamageWheel2Key', "DamageWheel2Key", ""), + ('DamageWheel3Key', "DamageWheel3Key", ""), + ('DamageWheel4Key', "DamageWheel4Key", ""), + ('DamageWheel5Key', "DamageWheel5Key", ""), + ('DamageWheel6Key', "DamageWheel6Key", ""), + ('DamageWheel7Key', "DamageWheel7Key", ""), + ('HeadLightKey', "HeadLightKey", ""), + ('BackFaraKeyR', "BackFaraKeyR", ""), + ('StopFaraKeyR', "StopFaraKeyR", ""), + ('BackFaraKeyL', "BackFaraKeyL", ""), + ('StopFaraKeyL', "StopFaraKeyL", ""), + ('IconKey', "IconKey", ""), + ('SizeLightKey', "SizeLightKey", ""), + ('HornKey', "HornKey", ""), + ('SupportKey', "SupportKey", ""), + ('CopSirenKey', "CopSirenKey", ""), + ('CopLightKey', "CopLightKey", ""), + ('GunRightKey', "GunRightKey", ""), + ('GunLeftKey', "GunLeftKey", ""), + ('StaticLightKey', "StaticLightKey", ""), + ('BlinkLightKey', "BlinkLightKey", ""), + ('SearchLightKey', "SearchLightKey", ""), + ] + ) + + addGroupName_string : bpy.props.StringProperty( + name="Имя группы", + description="Имя переключаемой группы", + default="", + maxlen=30, + ) + + T14_enum : bpy.props.EnumProperty( + name="Преднастройки", + items=[ ('car', "Для транспорта", ""), + ('trl', "Для полуприцепа", ""), + ('trl_cyc', "Для полуприцепа-цистерны", ""), + ('clk', "Для коллизии", ""), + ] + ) + + T28_radius : bpy.props.FloatProperty( + name = "Радиус спрайта", + description = "Радиус плоскости спрайта", + default = 1.0, + min = 0.01, + ) + + T28_radius1 : bpy.props.FloatProperty( + name = "Радиус спрайта", + description = "Радиус плоскости спрайта", + default = 1.0, + min = 0.01, + ) + + CH : bpy.props.FloatProperty( + name = "Высота коллизии", + description = "Высота плоскости коллизии", + ) + + CH1 : bpy.props.FloatProperty( + name = "Высота коллизии", + description = "Высота плоскости коллизии", + ) + + RSound : bpy.props.FloatProperty( + name = "Радиус звука", + description = "Радиус звука", + default = 10.0, + min = 0.0, + ) + + RSound1 : bpy.props.FloatProperty( + name = "Радиус звука", + description = "Радиус звука", + default = 10.0, + min = 0.0, + ) + + addSoundName_string : bpy.props.StringProperty( + name="Присоединённый звуковой файл", + description="Имя звукового файла, который будет использоваться данным блоком", + default="", + maxlen=30, + ) + + addSoundName1_string : bpy.props.StringProperty( + name="Присоединённый звуковой файл", + description="Имя звукового файла, который будет использоваться данным блоком", + default="", + maxlen=30, + ) + + SLevel : bpy.props.FloatProperty( + name = "Уровень громкости звука", + description = "Уровень громкости звука", + default = 1.0, + min = 0.0, + max = 1.0, + ) + + SLevel1 : bpy.props.FloatProperty( + name = "Уровень громкости звука", + description = "Уровень громкости звука", + default = 1.0, + min = 0.0, + max = 1.0, + ) + + addRoomName_string : bpy.props.StringProperty( + name="Присоединённая комната", + description="Имя комнаты, которая будет загружена", + default="", + maxlen=30, + ) + + FType_enum : bpy.props.EnumProperty( + name="Тип записи полигонов (08)", + items=(('0', "Тип 0", "С нормалями"), + ('1', "Тип 1", "Без нормалей"), + ('2', "Тип 2", "С нормалями, UV разрывная"), + ('128', "Тип 128", ""), + ('144', "Тип 144", ""), + ), + ) + + Faces_enum : bpy.props.EnumProperty( + name="Тип блока полигонов", + items=(('8', "8", ""), + ('35', "35", ""), + ), + ) + + addBlockMeshType_enum : bpy.props.EnumProperty( + name="Тип записи модели", + items=[ ('auto', "Автоматический", "Экспортер сам определит, какой блок использовать (8, 35 или оба)"), + ('manual', "Ручной", "Будет записан блок, который выбран в настройках"), + ] + ) + + addMeshType_enum : bpy.props.EnumProperty( + name="Тип записи полигонов", + items=[ ('uv0', "Обычный", ""), + ('uv1', "С разрывной UV", ""), + ] + ) + + materialName_string : bpy.props.StringProperty( + name="Имя материала", + description="Имя материала, который будет использоваться генератором", + default="", + maxlen=10, + ) + + routeName_string : bpy.props.StringProperty( + name="Имя участка карты", + description="Имя участка карты, который будет загружен", + default="", + maxlen=2, + ) + + triggerType_enum : bpy.props.EnumProperty( + name="Тип триггера", + items=(('loader', "Загрузчик", "Загрузчик участков карты"), + ('radar0', "Радар 0", "Event 0"), + ('radar1', "Радар 1", "Event 1"), + ), + ) + + addBlockName4_string : bpy.props.StringProperty( + name="Родительский блок", + description="", + default="", + maxlen=30, + ) + + speed_limit : bpy.props.FloatProperty( + name = "Ограничение скорости", + description = "", + default = 60.0, + min = 0.0, + ) + + addBlocks_enum : bpy.props.EnumProperty( + name="Тип сборки", + items=[ ('room', "Комната", "Комната с коллизией"), + #('07', "07", "Меш (ДБ1)"), + #('10', "10", "LOD"), + #('12', "12", "Плоскость коллизии"), + #('14', "14", "Блок, связанный с автомобилями"), + #('18', "18", "Связка локатора и 3D-модели, например: FiatWheel0Space и Single0Wheel14"), + #('19', "19", "Контейнер, в отличие от блока типа 05, не имеет возможности привязки"), + #('20', "20", "Плоская коллизия"), + #('21', "21", "Контейнер с обработкой событий"), + #('23', "23", "Объёмная коллизия"), + #('24', "24", "Локатор"), + #('28', "28", "3D-спрайт"), + #('33', "33", "Источник света"), + #('37', "37", "Меш"), + #('40', "40", "Генератор объектов"), + ] + ) + + addRoomNameIndex_string : bpy.props.StringProperty( + name="Имя комнаты", + description="", + default="aa_000", + maxlen=30, + ) + + mirrorType_enum : bpy.props.EnumProperty( + name="Тип блока", + items=[ ('x', "x", ""), + ('y', "y", ""), + ('z', "z", ""), + ] + ) + +# ------------------------------------------------------------------------ +# operators +# ------------------------------------------------------------------------ + +class AddOperator(bpy.types.Operator): + bl_idname = "wm.add_operator" + bl_label = "Добавить блок на сцену" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + global block_type + + block_type = int(mytool.addBlockType_enum) + + global cursor_pos + cursor_pos = bpy.context.scene.cursor_location + + if block_type == 6566754: + object_name = "b3d" + object = bpy.data.objects.new(object_name, None) + object.location=(0.0,0.0,0.0) + bpy.context.scene.objects.link(object) + + if block_type == 0: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos + object['add_space'] = mytool.addSpaceName_string + bpy.context.scene.objects.link(object) + + if block_type == 1: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos + object['add_space'] = mytool.addSpaceName_string + object['route_name'] = mytool.routeName_string + bpy.context.scene.objects.link(object) + + if block_type == 3: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos + object['node_radius'] = mytool.Radius + bpy.context.scene.objects.link(object) + + if block_type == 4: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos #(0.0,0.0,0.0) + object['node_radius'] = mytool.Radius + object['add_name'] = mytool.addBlockName4_string + object['add_name1'] = mytool.addBlockName_string + bpy.context.scene.objects.link(object) + + if block_type == 5: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos #(0.0,0.0,0.0) + object['node_radius'] = mytool.Radius + object['add_name'] = mytool.addBlockName_string + bpy.context.scene.objects.link(object) + + if block_type == 10: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos + object['node_radius'] = mytool.Radius + object['lod_distance'] = mytool.LOD_Distance + bpy.context.scene.objects.link(object) + + if block_type == 12: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object.location=cursor_pos + object['block_type'] = block_type + object['pos'] = 1 + object['height'] = mytool.CH + object['CType'] = int(mytool.CollisionType_enum) + bpy.context.scene.objects.link(object) + + if block_type == 13: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object.location=cursor_pos + object['block_type'] = block_type + if mytool.triggerType_enum == "loader": + object['type'] = "loader" + object['route_name'] = mytool.routeName_string + if mytool.triggerType_enum == "radar0": + object['type'] = "radar0" + object['var0'] = 30 + object['var1'] = 3005 + object['var2'] = 4 + object['speed_limit'] = mytool.speed_limit + if mytool.triggerType_enum == "radar1": + object['type'] = "radar1" + object['var0'] = 30 + object['var1'] = -1 + object['var2'] = 4 + object['speed_limit'] = mytool.speed_limit + bpy.context.scene.objects.link(object) + + if block_type == 14: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos + if mytool.T14_enum == "car": + object['var0'] = 0 + object['var1'] = mytool.Radius + object['var2'] = mytool.Radius/2 + object['var3'] = 10 + object['var4'] = 18 + elif mytool.T14_enum == "trl": + object['var0'] = 0 + object['var1'] = mytool.Radius + object['var2'] = mytool.Radius/2 + object['var3'] = 16 + object['var4'] = 25 + + elif mytool.T14_enum == "trl_cyc": + object['var0'] = 0 + object['var1'] = mytool.Radius + object['var2'] = mytool.Radius/2 + object['var3'] = 18 + object['var4'] = 25 + + elif mytool.T14_enum == "clk": + object['var0'] = 0 + object['var1'] = mytool.Radius * 0.08 + object['var2'] = mytool.Radius * 0.51 + object['var3'] = mytool.Radius + object['var4'] = 0 + bpy.context.scene.objects.link(object) + + if block_type == 18: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos + object['node_radius'] = mytool.Radius + object['add_name'] = mytool.addBlockName_string + object['space_name'] = mytool.addSpaceName_string + bpy.context.scene.objects.link(object) + + if block_type == 19: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object.location=cursor_pos + bpy.context.scene.objects.link(object) + + if block_type == 20: + points = [(0,0,0), (0,1,0)] + curveData = bpy.data.curves.new('curve', type='CURVE') + + curveData.dimensions = '3D' + curveData.resolution_u = 2 + + polyline = curveData.splines.new('POLY') + polyline.points.add(len(points)-1) + for i, coord in enumerate(points): + x,y,z = coord + polyline.points[i].co = (x, y, z, 1) + + object = bpy.data.objects.new("VDAT", curveData) + curveData.bevel_depth = 0.01 + + object.location = (0,0,0) + #object = bpy.context.selected_objects[0] + context.scene.objects.link(object) + object.name = mytool.BlockName_string + object['block_type'] = block_type + + if block_type == 21: + if mytool.Refer_bool is False: + object_name = mytool.Type21_enum + else: + object_name = 'refer_' + mytool.Type21_enum + object = bpy.data.objects.new(object_name, None) + object['block_type'] = block_type + object['node_radius'] = mytool.Radius + object['groups_num'] = mytool.groupsNum_int + object.location=cursor_pos + bpy.context.scene.objects.link(object) + for i in range(mytool.groupsNum_int): + group = bpy.data.objects.new((mytool.addGroupName_string + str(i)), None) + group['block_type'] = 5 + group['node_radius'] = mytool.Radius + group['add_name'] = "" + bpy.context.scene.objects.link(group) + group.parent = object + if (i < mytool.groupsNum_int - 1): + separator = bpy.data.objects.new((mytool.addGroupName_string + str(i) + "_444"), None) + separator['block_type'] = 444 + bpy.context.scene.objects.link(separator) + separator.parent = object + + + if block_type == 24: + object = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) + object = bpy.context.selected_objects[0] + object['block_type'] = block_type + object['flag'] = int(mytool.add24Flag_enum) + object.name = mytool.BlockName_string + object.location=cursor_pos + + if block_type == 25: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object.location=cursor_pos + object['block_type'] = block_type + object['sound_name'] = mytool.addSoundName_string + object['RSound'] = mytool.RSound + object['SLevel'] = mytool.SLevel + bpy.context.scene.objects.link(object) + + if block_type == 28: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object.location=cursor_pos + object['block_type'] = block_type + object['node_radius'] = mytool.Radius + object['sprite_radius'] = mytool.T28_radius + object['texNum'] = mytool.texNum_int + object_name = mytool.BlockName_string + bpy.context.scene.objects.link(object) + + if block_type == 30: + object_name = mytool.BlockName_string + + myvertex = [] + myfaces = [] + + mypoint = [(0, -20, 0)] + myvertex.extend(mypoint) + + mypoint = [(0, -20, 100)] + myvertex.extend(mypoint) + + mypoint = [(0, 20, 100)] + myvertex.extend(mypoint) + + mypoint = [(0, 20, 0)] + myvertex.extend(mypoint) + + myface = [(0, 1, 2, 3)] + myfaces.extend(myface) + + + mymesh = bpy.data.meshes.new(object_name) + + object = bpy.data.objects.new(object_name, mymesh) + + bpy.context.scene.objects.link(object) + + mymesh.from_pydata(myvertex, [], myfaces) + + mymesh.update(calc_edges=True) + + object.location = cursor_pos + + object['block_type'] = block_type + object.location=cursor_pos + object['radius'] = mytool.Radius + object['room_name'] = mytool.addRoomName_string + #bpy.context.scene.objects.link(object) + + if block_type == 33: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object.location=cursor_pos + object['block_type'] = block_type + object['node_radius'] = mytool.Radius + object['light_radius'] = mytool.RadiusLight + object['light_type'] = int(mytool.LType_enum) + object['intensity'] = mytool.Intensity + object['R'] = mytool.R / 255 + object['G'] = mytool.G / 255 + object['B'] = mytool.B / 255 + object_name = mytool.BlockName_string + bpy.context.scene.objects.link(object) + + if block_type == 40: + if mytool.generatorType_enum == "$$TreeGenerator1": + point = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, enter_editmode=True, location=(0.0,0.0,0.0)) + mesh0 = bpy.ops.mesh.primitive_cone_add(vertices=12, radius1=0.5, radius2=0.0, depth=1.0, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 1.0)) + mesh1 = bpy.ops.mesh.primitive_cone_add(vertices=12, radius1=0.3, radius2=0.0, depth=0.6, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 1.4)) + tree = bpy.ops.mesh.primitive_cylinder_add(vertices=12, radius=0.05, depth=0.5, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 0.25)) + object = bpy.context.selected_objects[0] + object['block_type'] = block_type + object['scale'] = mytool.Scale + object['TGType'] = mytool.TGType_int + object['GType'] = mytool.generatorType_enum + object.name = mytool.BlockName_string + bpy.ops.object.mode_set(mode = 'OBJECT') + object.location = bpy.context.scene.cursor_location + + if mytool.generatorType_enum == "$$DynamicGlow": + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object.location=cursor_pos + + object['block_type'] = block_type + object['node_radius'] = mytool.Radius + object['scale'] = mytool.Scale + object['mat_name'] = mytool.materialName_string + object['GType'] = mytool.generatorType_enum + object.name = mytool.BlockName_string + bpy.context.scene.objects.link(object) + + if block_type == 444: + object_name = mytool.BlockName_string + object = bpy.data.objects.new(object_name, None) + object['block_type'] = 444 + object.location=(0.0,0.0,0.0) + bpy.context.scene.objects.link(object) + return {'FINISHED'} + +# ------------------------------------------------------------------------ +# menus +# ------------------------------------------------------------------------ + +class BasicMenu(bpy.types.Menu): + bl_idname = "OBJECT_MT_select_test" + bl_label = "Select" + + def draw(self, context): + layout = self.layout + + # built-in example operators + layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE' + layout.operator("object.select_all", text="Inverse").action = 'INVERT' + layout.operator("object.select_random", text="Random") + +# ------------------------------------------------------------------------ +# my tool in objectmode +# ------------------------------------------------------------------------ + +class OBJECT_PT_b3d_add_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_add_panel" + bl_label = "Настройки" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + mytool = scene.my_tool + +class OBJECT_PT_b3d_add_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_add_panel" + bl_label = "Добавление блоков" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + mytool = scene.my_tool + # print(type(mytool)) + # print(bpy.types.Scene.my_tool) + # print(dir(bpy.types.Scene.my_tool)) + # print(dir(context.scene.my_tool)) + global block_type + block_type = int(mytool.addBlockType_enum) + + if block_type == 6566754: + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + + if block_type == 0: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "addSpaceName_string") + + + if block_type == 1: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "addSpaceName_string") + layout.prop(mytool, "routeName_string") + + if block_type == 3: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "Radius") + + if block_type == 4: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "Radius") + layout.prop(mytool, "addBlockName4_string") + layout.prop(mytool, "addBlockName_string") + + if block_type == 5: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "addBlockName_string") + layout.prop(mytool, "Radius") + + elif block_type == 10: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "Radius") + layout.prop(mytool, "LOD_Distance") + + elif block_type == 12: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "CH") + layout.prop(mytool, "CollisionType_enum") + + elif block_type == 13: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "triggerType_enum", text="") + if mytool.triggerType_enum == "loader": + layout.prop(mytool, "routeName_string") + elif mytool.triggerType_enum == "radar0" or "radar1": + layout.prop(mytool, "speed_limit") + + elif block_type == 14: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + self.layout.label(text="Вариант преднастроек:") + layout.prop(mytool, "T14_enum", text="") + layout.prop(mytool, "Radius") + + elif block_type == 18: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "Radius") + layout.prop(mytool, "addBlockName_string") + layout.prop(mytool, "addSpaceName_string") + + elif block_type == 19: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + + elif block_type == 20: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + + elif block_type == 21: + self.layout.label(text="Имя блока:") + layout.prop(mytool, "Type21_enum", text="") + layout.prop(mytool, "Refer_bool") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "Radius") + layout.prop(mytool, "groupsNum_int") + layout.prop(mytool, "addGroupName_string") + + elif block_type == 24: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + self.layout.label(text="Флаг:") + layout.prop(mytool, "add24Flag_enum", text="") + + elif block_type == 25: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "addSoundName_string") + layout.prop(mytool, "RSound") + layout.prop(mytool, "SLevel") + + elif block_type == 28: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "Radius") + layout.prop(mytool, "T28_radius") + layout.prop(mytool, "texNum_int") + + elif block_type == 30: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "Radius") + layout.prop(mytool, "addRoomName_string") + + elif block_type == 33: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + layout.prop(mytool, "LType_enum") + layout.prop(mytool, "Radius") + layout.prop(mytool, "RadiusLight") + layout.prop(mytool, "Intensity") + layout.prop(mytool, "R") + layout.prop(mytool, "G") + layout.prop(mytool, "B") + + elif block_type == 40: + layout.prop(mytool, "BlockName_string") + layout.prop(mytool, "Radius") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + self.layout.label(text="Тип генератора:") + layout.prop(mytool, "generatorType_enum", text="") + if mytool.generatorType_enum == "$$TreeGenerator1": + layout.prop(mytool, "TGType_int") + layout.prop(mytool, "Scale") + if mytool.generatorType_enum == "$$DynamicGlow": + layout.prop(mytool, "materialName_string") + layout.prop(mytool, "Scale") + else: + self.layout.label(text="Данный тип генератора не поддерживается.") + + elif block_type == 444: + layout.prop(mytool, "BlockName_string") + self.layout.label(text="Тип блока:") + layout.prop(mytool, "addBlockType_enum", text="") + + layout.operator("wm.add_operator") + + #layout.prop(mytool, "my_bool") + #layout.prop(mytool, "my_int") + #layout.prop(mytool, "my_float") + #layout.menu("OBJECT_MT_select_test", text="Presets", icon="SCENE") + +class GetValuesOperator(bpy.types.Operator): + bl_idname = "wm.get_values_operator" + bl_label = "Получить настройки блока" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + global block_type + global lenStr + object = bpy.context.selected_objects[0] + block_type = object['block_type'] + + if block_type == 5: + mytool.addBlockName1_string = object['add_name'] + mytool.Radius1 = object['node_radius'] + + elif block_type == 7: + if 'BType' in object: + mytool.Faces_enum = str(object['BType']) + else: + mytool.Faces_enum = str(35) + object['BType'] = 35 + if "type1" in object: + mytool.addBlockMeshType_enum = str(object['type1']) + else: + object['type1'] = "manual" + mytool.addBlockMeshType_enum = str(object['type1']) + mytool.MType_enum = str(object['MType']) + mytool.FType_enum = str(object['FType']) + mytool.texNum_int = object['texNum'] + + elif block_type == 10: + mytool.Radius1 = object['node_radius'] + mytool.LOD_Distance1 = object['lod_distance'] + + elif block_type == 12: + mytool.CH1 = object['height'] + mytool.CollisionType_enum = object['CType'] + + elif block_type == 18: + mytool.Radius1 = object['node_radius'] + mytool.addBlockName1_string = object['add_name'] + mytool.addSpaceName1_string = object['space_name'] + + elif block_type == 21: + mytool.groupsNum1_int = object['groups_num'] + mytool.Radius1 = object['node_radius'] + + elif block_type == 23: + mytool.CollisionType_enum = str(object['CType']) + + elif block_type == 24: + mytool.add24Flag_enum1 = str(object['flag']) + + elif block_type == 25: + mytool.RSound1 = (object['RSound']) + mytool.addSoundName1_string = object['sound_name'] + mytool.SLevel1 = (object['SLevel']) + + elif block_type == 28: + mytool.texNum_int = object['texNum'] + mytool.T28_radius1 = object['sprite_radius'] + + elif block_type == 33: + mytool.Radius1 = object['node_radius'] + mytool.LType_enum = str(object['light_type']) + mytool.RadiusLight1 = object['light_radius'] + mytool.Intensity1 = object['intensity'] + mytool.R1 = object['R'] * 255 + mytool.G1 = object['G'] * 255 + mytool.B1 = object['B'] * 255 + + elif block_type == 37: + if 'BType' in object: + mytool.Faces_enum = str(object['BType']) + else: + mytool.Faces_enum = str(35) + object['BType'] = 35 + if "type1" in object: + mytool.addBlockMeshType_enum = str(object['type1']) + else: + object['type1'] = "manual" + mytool.addBlockMeshType_enum = str(object['type1']) + #mytool.addMeshType_enum = str(object['type2']) + mytool.SType_enum = str(object['SType']) + mytool.MType_enum = str(object['MType']) + mytool.FType_enum = str(object['FType']) + mytool.texNum_int = object['texNum'] + + return {'FINISHED'} + +class SetValuesOperator(bpy.types.Operator): + bl_idname = "wm.set_values_operator" + bl_label = "Сохранить настройки блока" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + global block_type + global lenStr + #object = bpy.context.selected_objects[0] + + for i in range(len(bpy.context.selected_objects)): + + object = bpy.context.selected_objects[i] + + if 'block_type' in object: + block_type = object['block_type'] + else: + block_type = int(mytool.addBlockType_enum1) + + object['block_type'] = block_type + + if block_type == 5: + object['add_name'] = mytool.addBlockName1_string + object['node_radius'] = mytool.Radius1 + + elif block_type == 7: + object['type1'] = str(mytool.addBlockMeshType_enum) + object['BType'] = int(mytool.Faces_enum) + object['FType'] = int(mytool.FType_enum) + object['MType'] = int(mytool.MType_enum) + object['texNum'] = int(mytool.texNum_int) + + elif block_type == 10: + object['node_radius'] = mytool.Radius1 + object['lod_distance'] = mytool.LOD_Distance1 + + elif block_type == 12: + object['height'] = mytool.CH1 + object['CType'] = int(mytool.CollisionType_enum) + + elif block_type == 18: + object['node_radius'] = mytool.Radius1 + object['add_name'] = mytool.addBlockName1_string + object['space_name'] = mytool.addSpaceName1_string + + elif block_type == 21: + object['groups_num'] = mytool.groupsNum1_int + object['node_radius'] = mytool.Radius1 + + elif block_type == 23: + object['CType'] = int(mytool.CollisionType_enum) + + elif block_type == 24: + object['flag'] = int(mytool.add24Flag_enum1) + + elif block_type == 25: + object['RSound'] = mytool.RSound1 + object['sound_name'] = mytool.addSoundName1_string + object['SLevel'] = mytool.SLevel1 + + elif block_type == 28: + object['texNum'] = mytool.texNum_int + object['node_radius'] = mytool.Radius1 + object['sprite_radius'] = mytool.T28_radius1 + + elif block_type == 33: + object['node_radius'] = mytool.Radius1 + object['light_type'] = int(mytool.LType_enum) + object['light_radius'] = mytool.RadiusLight1 + object['intensity'] = mytool.Intensity1 + object['R'] = mytool.R1 / 255 + object['G'] = mytool.G1 / 255 + object['B'] = mytool.B1 / 255 + + elif block_type == 37: + object['type1'] = str(mytool.addBlockMeshType_enum) + #object['type2'] = str(mytool.addMeshType_enum) + object['BType'] = int(mytool.Faces_enum) + object['SType'] = int(mytool.SType_enum) + object['MType'] = int(mytool.MType_enum) + object['FType'] = int(mytool.FType_enum) + object['texNum'] = int(mytool.texNum_int) + + return {'FINISHED'} + +class DelValuesOperator(bpy.types.Operator): + bl_idname = "wm.del_values_operator" + bl_label = "Удалить настройки блока" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + global block_type + global lenStr + #object = bpy.context.selected_objects[0] + + for i in range(len(bpy.context.selected_objects)): + + object = bpy.context.selected_objects[i] + + if 'block_type' in object: + del object['block_type'] + + return {'FINISHED'} + +class FixUVOperator(bpy.types.Operator): + bl_idname = "wm.fix_uv_operator" + bl_label = "Исправить UV для экспорта" + + def execute(self, context): + + for i in range(len(bpy.context.selected_objects)): + + object = bpy.context.selected_objects[i] + + bpy.ops.object.mode_set(mode = 'EDIT') + + context = bpy.context + obj = context.edit_object + me = obj.data + bm = bmesh.from_edit_mesh(me) + # old seams + old_seams = [e for e in bm.edges if e.seam] + # unmark + for e in old_seams: + e.seam = False + # mark seams from uv islands + bpy.ops.uv.seams_from_islands() + seams = [e for e in bm.edges if e.seam] + # split on seams + print(seams) + print("salo 111") + bmesh.ops.split_edges(bm, edges=seams) + # re instate old seams.. could clear new seams. + for e in old_seams: + e.seam = True + bmesh.update_edit_mesh(me) + + boundary_seams = [e for e in bm.edges if e.seam and e.is_boundary] + + bpy.ops.object.mode_set(mode = 'OBJECT') + + return {'FINISHED'} + +class FixVertsOperator(bpy.types.Operator): + bl_idname = "wm.fix_verts_operator" + bl_label = "Исправить меш для экспорта" + + def execute(self, context): + + for i in range(len(bpy.context.selected_objects)): + + object = bpy.context.selected_objects[i] + + bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.mesh.select_mode(type="FACE") + bpy.ops.mesh.select_all(action='DESELECT') + bpy.ops.mesh.select_all(action='INVERT') + bpy.ops.mesh.select_mode(type="VERT") + bpy.ops.mesh.select_all(action='INVERT') + bpy.ops.mesh.delete(type='VERT') + + bpy.ops.object.mode_set(mode = 'OBJECT') + + return {'FINISHED'} + +from mathutils import Vector, Matrix +from math import radians, degrees + +class MirrorAndFlipObjectsOperator(bpy.types.Operator): + bl_idname = "wm.mirror_objects_operator" + bl_label = "Отзеркалить объекты" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + x = False + y = False + z = False + + if (mytool.mirrorType_enum) == "x": + x = True + else: + x = False + + if (mytool.mirrorType_enum) == "y": + y = True + else: + y = False + + if (mytool.mirrorType_enum) == "z": + z = True + else: + z = False + + for object in context.selected_objects: + if object.type == 'MESH': + #object = bpy.context.selected_objects[i] + bpy.ops.transform.mirror(constraint_axis=(x, y, z), constraint_orientation='GLOBAL') + bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) + + #if object.type == 'MESH': + bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.mesh.select_mode(type="FACE") + bpy.ops.mesh.select_all(action='DESELECT') + bpy.ops.mesh.select_all(action='INVERT') + bpy.ops.mesh.flip_normals() + bpy.ops.mesh.select_all(action='DESELECT') + bpy.ops.object.mode_set(mode = 'OBJECT') + + + + + #bpy.ops.object.mode_set(mode = 'OBJECT') + + return {'FINISHED'} + +class ApplyTransformsOperator(bpy.types.Operator): + bl_idname = "wm.apply_transforms_operator" + bl_label = "Расположить/Убрать обьекты" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + applyRemoveTransforms() + + return {'FINISHED'} + +class ShowHideCollisionsOperator(bpy.types.Operator): + bl_idname = "wm.show_hide_collisions_operator" + bl_label = "Отобразить/Скрыть коллизии" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + showHideObjByType(23) + + return {'FINISHED'} + +class ShowHideRoomBordersOperator(bpy.types.Operator): + bl_idname = "wm.show_hide_room_borders_operator" + bl_label = "Отобразить/Скрыть границы комнат" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + showHideObjByType(30) + + return {'FINISHED'} + +class ShowHideLODOperator(bpy.types.Operator): + bl_idname = "wm.show_hide_lod_operator" + bl_label = "Отобразить/Скрыть LOD модели" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + showHideObjTreeByType(10) + + return {'FINISHED'} + +class ShowHideGeneratorsOperator(bpy.types.Operator): + bl_idname = "wm.show_hide_generator_operator" + bl_label = "Отобразить/Скрыть генераторы обьектов" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + showHideObjByType(40) + + return {'FINISHED'} + +class OBJECT_PT_b3d_edit_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_edit_panel" + bl_label = "Редактирование блоков" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + mytool = context.scene.my_tool + + type(context) + #for i in range(len(bpy.context.selected_objects)): + + if len(bpy.context.selected_objects): + for i in range(1): + + object = bpy.context.selected_objects[i] + + if 'block_type' in object: + block_type = object['block_type'] + else: + block_type = None + + lenStr = str(len(object.children)) + + if block_type == 0: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 1: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 2: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 3: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 4: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 5: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + if 'add_name' in object: + layout.prop(mytool, "addBlockName1_string") + layout.prop(mytool, "Radius1") + else: + self.layout.label(text="Имя присоединённого блока не указано. Сохраните настройки,") + self.layout.label(text="а затем попробуйте выделить блок заново.") + + elif block_type == 6: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 7: + self.layout.label(text="Тип блока: " + str(block_type)) + if 'texNum' in object: + layout.prop(mytool, "addBlockMeshType_enum") + + if (mytool.addBlockMeshType_enum) == "auto": + layout.prop(mytool, "FType_enum") + layout.prop(mytool, "MType_enum") + else: + layout.prop(mytool, "Faces_enum") + if int(mytool.Faces_enum) == 35: + layout.prop(mytool, "MType_enum") + else: + layout.prop(mytool, "FType_enum") + + layout.prop(mytool, "texNum_int") + else: + self.layout.label(text="Указаны не все атрибуты объекта.") + self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") + + elif block_type == 8: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 9: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 10: + self.layout.label(text="Тип блока: " + str(block_type)) + if 'node_radius' in object: + layout.prop(mytool, "Radius1") + layout.prop(mytool, "LOD_Distance1") + else: + self.layout.label(text="Указаны не все атрибуты объекта.") + self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") + self.layout.label(text="Количество вложенных блоков: " + str(len(object.children) - 1)) + + elif block_type == 11: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 12: + self.layout.label(text="Тип блока: " + str(block_type)) + if 'CType' in object: + self.layout.label(text="Тип коллизии:") + layout.prop(mytool, "CollisionType_enum", text="") + layout.prop(mytool, "CH1") + else: + self.layout.label(text="Тип коллизии не указан. Сохраните настройки,") + self.layout.label(text="а затем попробуйте выделить блок заново.") + + elif block_type == 13: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 14: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 15: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 16: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 17: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 18: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + if 'add_name' in object: + layout.prop(mytool, "Radius1") + layout.prop(mytool, "addBlockName1_string") + layout.prop(mytool, "addSpaceName1_string") + else: + self.layout.label(text="Указаны не все атрибуты объекта.") + self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") + + elif block_type == 19: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 20: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 21: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + str(len(object.children)-object['groups_num']+1)) + if 'groups_num' in object: + layout.prop(mytool, "groupsNum1_int") + layout.prop(mytool, "Radius1") + else: + self.layout.label(text="Количество групп не указано. Сохраните настройки,") + self.layout.label(text="а затем попробуйте выделить блок заново.") + + elif block_type == 23: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + if 'CType' in object: + self.layout.label(text="Тип коллизии:") + layout.prop(mytool, "CollisionType_enum", text="") + else: + self.layout.label(text="Тип коллизии не указан. Сохраните настройки,") + self.layout.label(text="а затем попробуйте выделить блок заново.") + + elif block_type == 24: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + if 'flag' in object: + layout.prop(mytool, "add24Flag_enum1", text="") + else: + self.layout.label(text="Флаг блока не указан. Сохраните настройки,") + self.layout.label(text="а затем попробуйте выделить блок заново.") + + elif block_type == 25: + self.layout.label(text="Тип блока: " + str(block_type)) + if 'RSound' in object: + layout.prop(mytool, "addSoundName1_string") + layout.prop(mytool, "RSound1") + layout.prop(mytool, "SLevel1") + else: + self.layout.label(text="Указаны не все атрибуты объекта.") + self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") + + elif block_type == 26: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 27: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 28: + self.layout.label(text="Тип блока: " + str(block_type)) + if 'sprite_radius' in object: + layout.prop(mytool, "Radius1") + layout.prop(mytool, "T28_radius1") + layout.prop(mytool, "texNum_int") + else: + self.layout.label(text="Указаны не все атрибуты объекта.") + self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") + + elif block_type == 29: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 30: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 31: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 32: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 33: + self.layout.label(text="Тип блока: " + str(block_type)) + layout.prop(mytool, "Radius1") + layout.prop(mytool, "LType_enum") + layout.prop(mytool, "RadiusLight1") + layout.prop(mytool, "Intensity1") + layout.prop(mytool, "R1") + layout.prop(mytool, "G1") + layout.prop(mytool, "B1") + + elif block_type == 34: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 35: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 36: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 37: + self.layout.label(text="Тип блока: " + str(block_type)) + #self.layout.label(text="Количество вложенных блоков: " + lenStr) + if 'texNum' in object: + layout.prop(mytool, "addBlockMeshType_enum") + + if (mytool.addBlockMeshType_enum) == "auto": + layout.prop(mytool, "SType_enum") + #layout.prop(mytool, "FType_enum") + #layout.prop(mytool, "addMeshType_enum") + layout.prop(mytool, "FType_enum") + layout.prop(mytool, "MType_enum") + else: + layout.prop(mytool, "Faces_enum") + if int(mytool.Faces_enum) == 35: + layout.prop(mytool, "MType_enum") + layout.prop(mytool, "SType_enum") + else: + layout.prop(mytool, "SType_enum") + layout.prop(mytool, "FType_enum") + + layout.prop(mytool, "texNum_int") + else: + self.layout.label(text="Указаны не все атрибуты объекта.") + self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") + + elif block_type == 38: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 39: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Количество вложенных блоков: " + lenStr) + + elif block_type == 40: + self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Тип генератора: " + object['GType']) + + elif block_type == 444: + self.layout.label(text="Тип объекта - разделитель") + + else: + self.layout.label(text="Выбранный объект не имеет типа.") + self.layout.label(text="Чтобы указать его, нажмите на кнопку сохранения настроек.") + layout.prop(mytool, "addBlockType_enum1") + + layout.operator("wm.get_values_operator") + layout.operator("wm.set_values_operator") + layout.operator("wm.del_values_operator") + layout.operator("wm.fix_uv_operator") + layout.operator("wm.fix_verts_operator") + +class AddBlocksOperator(bpy.types.Operator): + bl_idname = "wm.add1_operator" + bl_label = "Добавить сборку блоков на сцену" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + global type + + type = mytool.addBlocks_enum + + global cursor_pos + cursor_pos = bpy.context.scene.cursor_location + + def type05(name, radius, add_name): + object_name = name + object = bpy.data.objects.new(object_name, None) + object['block_type'] = 5 + object.location=cursor_pos + object['node_radius'] = radius + object['add_name'] = add_name + bpy.context.scene.objects.link(object) + object.select = True + + def type19(name): + object_name = name + object = bpy.data.objects.new(object_name, None) + object['block_type'] = 19 + object.location=cursor_pos + bpy.context.scene.objects.link(object) + object.select = True + + if type == "room": + type19("room_" + mytool.addRoomNameIndex_string) + room = bpy.context.selected_objects[0] + + type05(("road_" + mytool.addRoomNameIndex_string), mytool.Radius, ("hit_road_" + mytool.addRoomNameIndex_string)) + road = bpy.context.selected_objects[0] + + type05(("obj_" + mytool.addRoomNameIndex_string), mytool.Radius, ("hit_obj_" + mytool.addRoomNameIndex_string)) + obj = bpy.context.selected_objects[0] + + hit_road = type05(("hit_road_" + mytool.addRoomNameIndex_string), 0, "") + hit_obj = type05(("hit_obj_" + mytool.addRoomNameIndex_string), 0, "") + + bpy.ops.object.select_all(action='DESELECT') + + room.select = True + road.select = True + obj.select = True + + bpy.context.scene.objects.active = room + + bpy.ops.object.parent_set() + + bpy.ops.object.select_all(action='DESELECT') + + return {'FINISHED'} + +class OBJECT_PT_b3d_blocks_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_blocks_panel" + bl_label = "Сборки блоков" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + # print(dir(context)) + mytool = context.scene.my_tool + + type = mytool.addBlocks_enum + + # print(dir(mytool)) + + layout.prop(mytool, "addBlocks_enum") + + if type == "room": + layout.prop(mytool, "addRoomNameIndex_string") + layout.prop(mytool, "Radius") + + layout.operator("wm.add1_operator") + +class OBJECT_PT_b3d_func_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_func_panel" + bl_label = "Дополнительные функции" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + mytool = scene.my_tool + + + layout.prop(mytool, "mirrorType_enum") + + layout.operator("wm.mirror_objects_operator") + layout.operator("wm.apply_transforms_operator") + layout.operator("wm.show_hide_collisions_operator") + layout.operator("wm.show_hide_room_borders_operator") + layout.operator("wm.show_hide_lod_operator") + layout.operator("wm.show_hide_generator_operator") + +class OBJECT_PT_b3d_misc_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_misc_panel" + bl_label = "О плагине" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + mytool = scene.my_tool + + self.layout.label(text="Автор плагина: aleko2144") + self.layout.label(text="vk.com/rnr_mods") +# ------------------------------------------------------------------------ +# register and unregister +# ------------------------------------------------------------------------ + +classes = ( + PanelSettings, + AddOperator, + BasicMenu, + OBJECT_PT_b3d_add_panel, + GetValuesOperator, + SetValuesOperator, + DelValuesOperator, + FixUVOperator, + FixVertsOperator, + MirrorAndFlipObjectsOperator, + ApplyTransformsOperator, + ShowHideCollisionsOperator, + ShowHideRoomBordersOperator, + ShowHideLODOperator, + ShowHideGeneratorsOperator, + OBJECT_PT_b3d_edit_panel, + AddBlocksOperator, + OBJECT_PT_b3d_blocks_panel, + OBJECT_PT_b3d_func_panel, + OBJECT_PT_b3d_misc_panel, +) + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=PanelSettings) + +def unregister(): + del bpy.types.Scene.my_tool + for cls in classes: + bpy.utils.unregister_class(cls) + +if __name__ == "__main__": + register() diff --git a/src/2.80/addons/b3d_tools/common.py b/src/2.80/addons/b3d_tools/common.py new file mode 100644 index 0000000..2ab5d58 --- /dev/null +++ b/src/2.80/addons/b3d_tools/common.py @@ -0,0 +1,148 @@ +import bpy +import logging +import sys +import re + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +log = logging.getLogger("common") + +def getAllChildren(obj): + allChildren = [] + currentObjs = [obj] + while(1): + nextChildren = [] + if len(currentObjs) > 0: + for obj in currentObjs: + nextChildren.extend(obj.children) + currentObjs = nextChildren + allChildren.extend(currentObjs) + else: + break + return allChildren + + +def applyTransform(block_18): + + spaceName = block_18["space_name"] + objName = block_18["add_name"] + log.debug("Applying transform {} to object {}".format(spaceName, objName)) + + spaceObj = bpy.data.objects.get(spaceName) + destObj = bpy.data.objects.get(objName) + + if(spaceObj == None): + log.warn("Transformation object not found in "+block_18.name) + return + + if(destObj == None): + log.warn("Destination object not found in "+block_18.name) + return + + + linkObj = None + if bpy.data.objects.get(spaceObj.name + "_b3dSpaceCopy"): + linkObj = bpy.data.objects[spaceObj.name + "_b3dSpaceCopy"] + else: + linkObj = spaceObj.copy() + linkObj.parent = spaceObj.parent + linkObj.rotation_euler[0] = spaceObj.rotation_euler[0] + linkObj.rotation_euler[1] = spaceObj.rotation_euler[1] + linkObj.rotation_euler[2] = spaceObj.rotation_euler[2] + linkObj.location = spaceObj.location + linkObj.name = spaceObj.name + "_b3dSpaceCopy" + bpy.context.collection.objects.link(linkObj) + + reIsCopy = re.compile(r'.*b3dcopy.*') + + allChildren = [obj for obj in getAllChildren(destObj)] + + subTransforms = [obj for obj in allChildren if obj["block_type"] == 18] + + meshes = [obj for obj in allChildren if obj.type=="MESH" and not reIsCopy.search(obj.name)] + + newmeshes = [] + + for trans in subTransforms: + subSpaceObj = bpy.data.objects.get(trans["space_name"]+"_b3dSpaceCopy") + if subSpaceObj: + subSpaceObj.parent = linkObj + + log.info("Copying meshes") + for mesh in meshes: + newmesh = mesh.copy() + # newmesh.data = mesh.data.copy() # for NOT linked copy + newmesh.parent = linkObj + newmesh.name = "{}_b3dcopy".format(mesh.name) + # newmesh.rotation_euler[0] = spaceObj.rotation_euler[0] + # newmesh.rotation_euler[1] = spaceObj.rotation_euler[1] + # newmesh.rotation_euler[2] = spaceObj.rotation_euler[2] + # newmesh.location = spaceObj.location + newmeshes.append(newmesh) + + log.info("Linking meshes") + for newmesh in newmeshes: + bpy.context.collection.objects.link(newmesh) + + # destObj.rotation_euler[0] = spaceObj.rotation_euler[0] + # destObj.rotation_euler[1] = spaceObj.rotation_euler[1] + # destObj.rotation_euler[2] = spaceObj.rotation_euler[2] + # destObj.location = spaceObj.location + + +reb3dSpace = re.compile(r'.*b3dSpaceCopy.*') +reb3dMesh = re.compile(r'.*b3dcopy.*') + +def applyRemoveTransforms(): + toRemove = False + for obj in (bpy.data.objects): + if reb3dSpace.search(obj.name): + toRemove = True + break + if toRemove: + removeTransforms() + else: + applyTransforms() + + +def removeTransforms(): + spaces = [cn for cn in bpy.data.objects if reb3dSpace.search(cn.name)] + meshes = [cn for cn in bpy.data.objects if reb3dMesh.search(cn.name)] + + for mesh in meshes: + mesh.select_set(True) + bpy.ops.object.delete() + + for space in spaces: + space.select_set(True) + bpy.ops.object.delete() + +def applyTransforms(): + objs = [cn for cn in bpy.data.objects if cn["block_type"]==18] + for obj in objs: + applyTransform(obj) + +def showHideObjByType(type): + objs = [cn for cn in bpy.data.objects if cn["block_type"]==type] + hiddenObj = [cn for cn in bpy.data.objects if cn["block_type"]==type and cn.hide_get()] + if objs == hiddenObj: + for obj in objs: + obj.hide_set(False) + else: + for obj in objs: + obj.hide_set(True) + +def showHideObjTreeByType(type): + objs = [cn for cn in bpy.data.objects if cn["block_type"]==type] + hiddenObj = [cn for cn in bpy.data.objects if cn["block_type"]==type and cn.hide_get()] + if objs == hiddenObj: + for obj in objs: + children = getAllChildren(obj) + for child in children: + child.hide_set(False) + obj.hide_set(False) + else: + for obj in objs: + children = getAllChildren(obj) + for child in children: + child.hide_set(True) + obj.hide_set(True) \ No newline at end of file diff --git a/src/2.80/addons/export_tch/__init__.py b/src/2.80/addons/export_tch/__init__.py new file mode 100644 index 0000000..4b37cac --- /dev/null +++ b/src/2.80/addons/export_tch/__init__.py @@ -0,0 +1,298 @@ +bl_info = { + "name": "King of The Road *.tch exporter", + "description": "", + "author": "Andrey Prozhoga", + "version": (0, 0, 1), + "blender": (3, 0, 0), + "location": "3D View > Tools", + "warning": "", + "wiki_url": "", + "tracker_url": "vk.com/rnr_mods", + "category": "Development" +} + +import bpy +from mathutils import Matrix +from math import radians + +from mathutils import Vector +from math import sqrt + +import bmesh + + +def read_tch(context, filepath, use_some_setting): + print("running read_tch...") + #file = open(filepath, 'r', encoding='utf-8') + #data = f.read() + + + file = open(filepath, 'r') + + CollisionPlane = [] + + CPlanes_num = 0 + + field_ind = "" + field_x = "" + field_y = "" + field_z = "" + field_offset = "" + + for line in file: + ColPlane_line = "" + if "CollisionPlane" in line: + CollisionPlane.append(line) + #CPlanes_num += 1 + file.close() + + #print(str(CollisionPlane)) + ColPlane_vector = [] + + + for i in range(len(CollisionPlane)):#(CPlanes_num): + if i < 10: + ColPlane_vector.append((CollisionPlane[i])[16:].split(" ")) + else: + ColPlane_vector.append((CollisionPlane[i])[17:].split(" ")) + #print(str(i)) + + + print(str(ColPlane_vector)) + # would normally load the data here + #print(data) + + return {'FINISHED'} + +def export_tch(context, filepath): + print("exporting tch...") + file = open(filepath, 'w') + + global global_matrix + global_matrix = axis_conversion(to_forward="-Z", + to_up="Y", + ).to_4x4() * Matrix.Scale(1, 4) + + global CollisionPlane_num + CollisionPlane_num = 0 + + forChild(bpy.data.objects['tch'],True, file, CollisionPlane_num) + + return {'FINISHED'} + + + +def forChild(object, root, file, CollisionPlane_num): + if (not root): + if object.name == "Corner_Mark": + verticesL = [] + uvs = [] + faces = [] + + bm = bmesh.new() + bm.from_mesh(object.data) + bm.verts.ensure_lookup_table() + bm.faces.ensure_lookup_table() + + bm.transform(global_matrix * object.matrix_world) + + bm.to_mesh(object.data) + + + for v in bm.verts: + verticesL.append((v.co)) + + meshdata = object.data + + for i, polygon in enumerate(meshdata.polygons): + for i1, loopindex in enumerate(polygon.loop_indices): + meshloop = meshdata.loops[loopindex] + faces.append(meshloop.vertex_index) + + vLen = len(verticesL) + + #for i,vert in enumerate(verticesL): + #file.write("CornerMark_" + str(i) + "=" + str(vert[0][0]) + " " + str(-vert[0][2]) + " " + str(vert[0][1])) + #file.write(str(object.data.vert[i][0][0])) + + v_num = 0 + + for vert in object.data.vertices: + v_num += 1 + file.write("Corner_Mark_" + str(v_num) + "=" + str(round(vert.co.x, 6)) + " " + str(round(-vert.co.z, 6)) + " " + str(round(vert.co.y, 6)) + "\n") + #file.write(struct.pack(" + +bl_info = { + 'name': 'King of the Road B3D importer/exporter', + 'author': 'Yuriy Gladishenko, Andrey Prozhoga', + 'version': (0, 1, 17), + 'blender': (2, 80, 0), + 'api': 34893, + 'description': 'This script imports and exports the King of the Road b3d', + 'warning': '', + 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/'\ + 'Import-Export/M3_Import', + 'tracker_url': 'vk.com/rnr_mods', + 'category': 'Import-Export'} + +# To support reload properly, try to access a package var, if it's there, +# reload everything +if "bpy" in locals(): + print("Reimporting modules!!!") + import importlib + importlib.reload(common) + importlib.reload(importb3d) + # importlib.reload(exportb3d) + importlib.reload(imghelp) +else: + import bpy + from . import ( + common, + importb3d, + # exportb3d, + imghelp, + ) + +import time +import datetime +import bpy +from bpy.props import StringProperty, BoolProperty +from bpy_extras.io_utils import ImportHelper, ExportHelper +# from . import common, exportb3d, imghelp, importb3d + + +class HTImportPreferences(bpy.types.AddonPreferences): + bl_idname = __package__ + + COMMON_RES_Path: bpy.props.StringProperty( + name="Common.res path", + default="", + subtype='FILE_PATH') + + def draw(self, context): + layout = self.layout + row = layout.row() + row.prop(self, 'COMMON_RES_Path', expand=True) + + +class ImportB3D(bpy.types.Operator, ImportHelper): + '''Import from B3D file format (.b3d)''' + bl_idname = 'import_scene.kotr_b3d' + bl_label = 'Import B3D' + + filename_ext = '.b3d' + filter_glob : StringProperty(default='*.b3d', options={'HIDDEN'}) + + to_unpack_res : BoolProperty(name='Unpack .res archive', + description='Unpack associated with .b3d fie .res archive. \n'\ + 'NOTE: .res archive must be located in the same folder as .b3d file', default=False) + + to_import_textures : BoolProperty(name='Import Textures', + description='Import textures from unpacked .res archive. \n'\ + 'NOTE: if importing for the first time select previous option too', default=False) + + + textures_format : StringProperty( + name="Images format", + description="Loaded images format", + default="tga", + ) + + def execute(self, context): + from . import importb3d + print('Importing file', self.filepath) + t = time.mktime(datetime.datetime.now().timetuple()) + with open(self.filepath, 'rb') as file: + importb3d.read(file, context, self, self.filepath) + t = time.mktime(datetime.datetime.now().timetuple()) - t + print('Finished importing in', t, 'seconds') + return {'FINISHED'} + +class ImportWayTxt(bpy.types.Operator, ImportHelper): + '''Import from txt file format (.txt)''' + bl_idname = 'import_scene.kotr_way_txt' + bl_label = 'Import way_txt' + + filename_ext = '.txt' + filter_glob = StringProperty(default='*.txt', options={'HIDDEN'}) + + use_image_search = BoolProperty(name='Image Search', + description='Search subdirectories for any associated'\ + 'images', default=True) + + def execute(self, context): + from . import importb3d + print('Importing file', self.filepath) + t = time.mktime(datetime.datetime.now().timetuple()) + with open(self.filepath, 'r') as file: + importb3d.readWayTxt(file, context, self, self.filepath) + t = time.mktime(datetime.datetime.now().timetuple()) - t + print('Finished importing in', t, 'seconds') + return {'FINISHED'} + + +class ExportB3D(bpy.types.Operator, ImportHelper): + '''Export to B3D file format (.b3d)''' + bl_idname = 'export_scene.kotr_b3d' + bl_label = 'Export B3D' + + filename_ext = '.b3d' + filter_glob = StringProperty(default='*.b3d', options={'HIDDEN'}) + + generate_pro_file = BoolProperty(name='Generate .pro file', + description='Generate .pro file, which can used'\ + 'to assembly the resources file', default=False) + + textures_path = StringProperty( + name="Textures directory", + default="txr\\", + ) + + def execute(self, context): + from . import exportb3d + print('Exporting file', self.filepath) + t = time.mktime(datetime.datetime.now().timetuple()) + exportb3d.write(self.filepath+'.b3d', context, self, self.filepath, self.generate_pro_file, self.textures_path) + t = time.mktime(datetime.datetime.now().timetuple()) - t + print('Finished exporting in', t, 'seconds') + return {'FINISHED'} + + +def menu_func_import(self, context): + self.layout.operator(ImportB3D.bl_idname, text='KOTR B3D (.b3d)') + self.layout.operator(ImportWayTxt.bl_idname, text='KOTR WAY (.txt)') + + +def menu_func_export(self, context): + self.layout.operator(ExportB3D.bl_idname, text='KOTR B3D (.b3d)') + +classes = ( + HTImportPreferences, + ImportB3D, + ImportWayTxt, + ExportB3D +) + + + +def register(): + print("registering addon") + # import importlib + # for cls in classes: + # importlib.reload(cls) + for cls in classes: + bpy.utils.register_class(cls) + bpy.types.TOPBAR_MT_file_import.append(menu_func_import) + bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + + +def unregister(): + print("unregistering addon") + bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) + bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) + for cls in classes: + bpy.utils.unregister_class(cls) + + +if __name__ == "__main__": + register() diff --git a/src/2.80/addons/importb3d/common.py b/src/2.80/addons/importb3d/common.py new file mode 100644 index 0000000..50a9827 --- /dev/null +++ b/src/2.80/addons/importb3d/common.py @@ -0,0 +1,171 @@ +from asyncio.windows_events import NULL +import os +import struct +import bpy +import logging +import sys + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +log = logging.getLogger("common") +log.setLevel(logging.DEBUG) + +def ShowMessageBox(message = "", title = "Message Box", icon = 'INFO'): + + def draw(self, context): + self.layout.label(text=message) + + bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) + + +def unmaskShort(num): + bits = [int(digit) for digit in bin(num)[2:]] + lzeros = 0 + rzeros = 0 + ones = 0 + if num == 0: + return [0, 0, 0] + for bit in bits: + if bit: + ones+=1 + else: + rzeros+=1 + lzeros = 16 - len(bits) + return [lzeros, ones, rzeros] + + +def readCString(file): + try: + chrs = [] + i = 0 + chrs.append(file.read(1).decode("utf-8")) + while ord(chrs[i]) != 0: + chrs.append(file.read(1).decode("utf-8")) + i += 1 + return "".join(chrs[:-1]) + except TypeError as e: + log.error("Error in readCString. Nothing to read") + return "" + + +class HTMaterial(): + + def __init__(self): + self.prefix = "" + self.path = "" + self.reflect = 0.0 #HT1 + self.specular = 0.0 #HT1 + self.col = 0 + self.transp = 1.0 + self.tex = 0 + self.ttx = 0 + self.rot = 0.0 + self.rotPoint = [0, 0] + self.power = 0.0 + self.noz = False + self.nof = False + self.notile = False + self.move = None + self.att = 0 + self.itx = 0 + self.coord = 2 + self.env = [0, 0] #scale x,y + self.notilev = False + self.notileu = False + self.bumpcoord = 0 + self.alphamirr = 0 + +class Vector3F(): + + def __init__(self, file=NULL, tuple=NULL): + if file != NULL: + tpl = struct.unpack("<3f", file.read(12)) + self.x = tpl[0] + self.y = tpl[1] + self.z = tpl[2] + elif tuple != NULL: + self.x = tuple[0] + self.y = tuple[1] + self.z = tuple[2] + else: + self.x = 0 + self.y = 0 + self.z = 0 + + + +class RESUnpack(): + + def __init__(self): + self.prefix = "" + self.textures = [] + self.maskfiles = [] + self.materials = [] + self.materialParams = [] + self.colors = [] + + def getPrefixedMaterial(self, ind): + return "{}_{}".format(self.prefix, self.materials[ind]) + +def parseMaterial(matString, prefix): + params = matString.split(" ") + i = 1 + mat = HTMaterial() + mat.prefix = prefix + mat.path = params[0] + while i < len(params): + if params[i] == "col": + i+=1 + mat.col = int(params[i]) + elif params[i] == "tex": + i+=1 + mat.tex = int(params[i]) + elif params[i] == "ttx": + i+=1 + mat.ttx = int(params[i]) + elif params[i] == "itx": + i+=1 + mat.itx = int(params[i]) + i+=1 + return mat + + +def parseMaterials(filepath, prefix): + content = "" + with open(filepath, "rb") as matFile: + content = matFile.read().decode("UTF-8") + + matStrings = content.split("\n") + materials = [] + for matStr in matStrings: + material = parseMaterial(matStr, prefix) + materials.append(material) + return materials + +#https://blender.stackexchange.com/questions/118646/add-a-texture-to-an-object-using-python-and-blender-2-8 +def createMaterial(palette, texturelist, texturepath, mat, imageFormat): + newMat = bpy.data.materials.new(name="{}_{}".format(mat.prefix, mat.path)) + newMat.use_nodes = True + bsdf = newMat.node_tree.nodes["Principled BSDF"] + if int(mat.col) > 0: + R = palette[mat.col-1][0] + G = palette[mat.col-1][1] + B = palette[mat.col-1][2] + texColor = newMat.node_tree.nodes.new("ShaderNodeRGB") + texColor.outputs[0].default_value = hex_to_rgb(R,G,B) + newMat.node_tree.links.new(bsdf.inputs['Base Color'], texColor.outputs['Color']) + if int(mat.tex) > 0 or int(mat.ttx) > 0 or int(mat.itx) > 0: + texidx = mat.tex | mat.ttx | mat.itx + path = texturelist[texidx-1][:-4] + texImage = newMat.node_tree.nodes.new("ShaderNodeTexImage") + texImage.image = bpy.data.images.load(os.path.join(texturepath, "{}.{}".format(path, imageFormat))) + newMat.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color']) + +#https://blender.stackexchange.com/questions/158896/how-set-hex-in-rgb-node-python +def srgb_to_linearrgb(c): + if c < 0: return 0 + elif c < 0.04045: return c/12.92 + else: return ((c+0.055)/1.055)**2.4 + +def hex_to_rgb(r,g,b,alpha=1): + return tuple([srgb_to_linearrgb(c/0xff) for c in (r,g,b)] + [alpha]) + diff --git a/src/2.80/addons/importb3d/exportb3d.py b/src/2.80/addons/importb3d/exportb3d.py new file mode 100644 index 0000000..60ac708 --- /dev/null +++ b/src/2.80/addons/importb3d/exportb3d.py @@ -0,0 +1,1837 @@ +import struct +import sys +import timeit +import threading +import pdb +import time + +import bmesh +import bpy +import mathutils +import os.path +from bpy.props import * +from mathutils import Matrix +from math import radians + +from math import cos +from math import sin + +import bpy_extras.mesh_utils + +from bpy_extras.io_utils import ( + ImportHelper, + ExportHelper, + #orientation_helper_factory, + path_reference_mode, + axis_conversion, + ) + +from bpy.props import (StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + EnumProperty, + PointerProperty, + ) +from bpy.types import (Panel, + Operator, + AddonPreferences, + PropertyGroup, + ) + +from bpy_extras.image_utils import load_image +from mathutils import Vector +from bpy import context + +scene = bpy.context.scene +RoMesh = True + +def openclose(file): + oc = file.read(4) + if (oc == (b'\x4D\x01\x00\x00')): + return 2 + elif oc == (b'\x2B\x02\x00\x00'): + # print('}') + return 0 + elif oc == (b'\xbc\x01\x00\x00'): + #print('BC01') + return 3 + elif oc == (b'\xde\x00\00\00'): + print ('EOF') + return 1 + else: + print(str(file.tell())) + print (str(oc)) + print('brackets error') + sys.exit() + +def uv_from_vert_first(uv_layer, v): + for l in v.link_loops: + uv_data = l[uv_layer] + return uv_data.uv + return None + +def uv_from_vert_average(uv_layer, v): + uv_average = Vector((0.0, 0.0)) + total = 0.0 + for loop in v.link_loops: + uv_average += loop[uv_layer].uv + total += 1.0 + + if total != 0.0: + return uv_average * (1.0 / total) + else: + return None + +def write(file, context, op, filepath, generate_pro_file, textures_path): + + global myFile_pro + myFile_pro = filepath + if generate_pro_file == True: + export_pro(myFile_pro, textures_path) + + global myFile + myFile = filepath + export(myFile, generate_pro_file) + +def MsgBox(label = "", title = "Error", icon = 'ERROR'): + + def draw(self, context): + self.layout.label(label) + + bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) + +def export_pro(file, textures_path): + file = open(myFile_pro+'.pro','w') + + #file.write('TEXTUREFILES ' + str(len(bpy.data.materials)) + '\n') + + #imgs = [] + #for img in bpy.data.images: + # imgs.append(img.name) + + #for material in bpy.data.materials: + # file.write('txr\\' + material.active_texture.name + '.txr' + '\n') + + #file.write('\n') + + file.write('MATERIALS ' + str(len(bpy.data.materials)) + '\n') + + materials = [] + num_tex = 0 + + for material in bpy.data.materials: + materials.append(material.name) + + for i in range(len(materials)): + num_tex = i#imgs.index[i] + #print(str(imgs[i])) + file.write(materials[i] + ' tex ' + str(num_tex + 1) + '\n') + + file.write('TEXTUREFILES ' + str(len(bpy.data.materials)) + '\n') + + imgs = [] + for img in bpy.data.images: + imgs.append(img.name) + + for material in bpy.data.materials: + try: + file.write(textures_path + material.texture_slots[0].texture.image.name[:-3] + 'txr' + '\n') + except: + file.write(textures_path + "error" + '.txr' + '\n') + + file.write('\n') + +def clone_node(): + b3d_node = bpy.data.objects['b3d'] + bpy.context.scene.objects.active = b3d_node + bpy.ops.object.select_grouped(type='CHILDREN_RECURSIVE') + b3d_node.select = True + bpy.ops.object.duplicate(linked=False, mode='TRANSLATION') + bpy.context.scene.objects.active.name = "b3d_temporary" + +def delete_clone(): + b3d_node = bpy.data.objects['b3d_temporary'] + bpy.context.scene.objects.active = b3d_node + bpy.ops.object.select_grouped(type='CHILDREN_RECURSIVE') + b3d_node.select = True + bpy.ops.object.delete() + + +def export(file, generate_pro_file): + file = open(myFile+'.b3d','wb') + + global global_matrix + global_matrix = axis_conversion(to_forward="-Z", + to_up="Y", + ).to_4x4() * Matrix.Scale(1, 4) + + global generatePro + generatePro = generate_pro_file + + global verNums + verNums = [] + + file.write(b'B3D\x00')#struct.pack("4c",b'B',b'3',b'D',b'\x00')) + #ba = bytearray(b'\x00' * 20) + + #file.write(ba) + + file.write(struct.pack(' 0: + mesh_blocks += 1 + + if len(flat_faces) > 0: + mesh_blocks += 1 + + file.write(struct.pack(" 0: + file.write(struct.pack(" 0: + file.write(struct.pack(" 180): + object.rotation_euler[0] = (360-(object.rotation_euler[0] * 180/PI)) * PI/180 + + if ((object.rotation_euler[1] * 180/PI) < -180): + object.rotation_euler[1] = (360+(object.rotation_euler[1] * 180/PI)) * PI/180 + elif ((object.rotation_euler[1] * 180/PI) > 180): + object.rotation_euler[1] = (360-(object.rotation_euler[1] * 180/PI)) * PI/180 + + if ((object.rotation_euler[2] * 180/PI) < -180): + object.rotation_euler[2] = (360+(object.rotation_euler[2] * 180/PI)) * PI/180 + elif ((object.rotation_euler[2] * 180/PI) > 180): + object.rotation_euler[2] = (360-(object.rotation_euler[2] * 180/PI)) * PI/180 + """ + + #file.write(struct.pack(" 0: + mesh_blocks += 1 + + if len(flat_faces) > 0: + mesh_blocks += 1 + + file.write(struct.pack(" 0: + file.write(struct.pack(" 0: + file.write(struct.pack(" 0: + mesh_blocks += 1 + + if len(flat_faces) > 0: + mesh_blocks += 1 + + file.write(struct.pack(" 0: + file.write(struct.pack(" 0: + file.write(struct.pack(" 0: + A = 0b11111111 + else: + A = 0 + colors.extend([B, G, R, A]) + return colors + + +def MSKtoTGA32(filepath): + outpath = os.path.splitext(filepath)[0] + ".tga" + log.info("Converting " + outpath) + indexes = [] + colorsAfter = [] + with open(filepath, "rb") as mskFile: + magic = struct.unpack("<4s", mskFile.read(4)) + width = struct.unpack(" 127): + for i in range(curBit-128): + indexes.append(0) + else: + indexes.extend(list(struct.unpack("<"+str(curBit)+"B", mskFile.read(curBit)))) + curBit = mskFile.read(1) + colorsAfter = paletteToColors(palette, indexes) + header = [None]*12 + header[0] = 0 #IDLength + header[1] = 0 #ColorMapType + header[2] = 2 #ImageType + header[3] = 0 #FirstIndexEntry + header[4] = 0 #ColorMapLength + header[5] = 32 #ColorMapEntrySize + header[6] = 0 #XOrigin + header[7] = 0 #YOrigin + header[8] = width #Width + header[9] = height #Height + header[10] = 32 #PixelDepth + header[11] = 32 #ImageDescriptor + + with open(outpath, "wb") as tgaFile: + headerPack = struct.pack("<3b2hb4h2b", *header) + colorsPack = struct.pack("<"+str(colorsSize*4)+"B", *colorsAfter) + tgaFile.write(headerPack) + tgaFile.write(colorsPack) + + +def TXR565toTGA8888(filepath): + + outpath = os.path.splitext(filepath)[0] + ".tga" + with open(filepath, "rb") as txrFile: + colorsAfter = [] + header = list(struct.unpack("<3b2hb4h2b"+"4s2i", txrFile.read(30))) + header[5] = 32 #ColorMapEntrySize + header[10] = 32 #PixelDepth + width = header[8] + height = header[9] + colorsSize = height*width + colorsBefore = list(struct.unpack("<"+str(colorsSize)+"H", txrFile.read(colorsSize*2))) + + footerIdentifier = txrFile.read(4) + footerSize = struct.unpack("> Runmask[2]) << (8-Runmask[1]) + G = ((color & Gmsk) >> Gunmask[2]) << (8-Gunmask[1]) + B = ((color & Bmsk) >> Bunmask[2]) << (8-Bunmask[1]) + A = ((color & Amsk) >> Aunmask[2]) << (8-Aunmask[1]) + colorsAfter.extend([B, G, R, A]) + else: + for color in colorsBefore: + R = ((color & Rmsk) >> Runmask[2]) << (8-Runmask[1]) + G = ((color & Gmsk) >> Gunmask[2]) << (8-Gunmask[1]) + B = ((color & Bmsk) >> Bunmask[2]) << (8-Bunmask[1]) + if (R | B | G) > 0: + A = 0b11111111 + else: + A = 0 + colorsAfter.extend([B, G, R, A]) + footer[0] = 0xFF000000 + footer[1] = 0x00FF0000 + footer[2] = 0x0000FF00 + footer[3] = 0x000000FF + with open(outpath, "wb") as tgaFile: + headerPack = struct.pack("<3b2hb4h2b"+"4s2i", *header) + colorsPack = struct.pack("<"+str(colorsSize*4)+"B", *colorsAfter) + footerPack = struct.pack("<4I"+str(footerSize-16)+"B", *footer) + tgaFile.write(headerPack) + tgaFile.write(colorsPack) + tgaFile.write(footerIdentifier) + tgaFile.write(struct.pack(" 0: + A = 0b11111111 + else: + A = 0 + colorsAfter.extend([B, G, R, A]) + + with open(outpath, "wb") as tgaFile: + headerPack = struct.pack("<3b2hb4h2b", *header) + colorsPack = struct.pack("<"+str(colorsSize*4)+"B", *colorsAfter) + tgaFile.write(headerPack) + tgaFile.write(colorsPack) + + return + +def TXRtoTGA32(filepath): + outpath = os.path.splitext(filepath)[0] + ".tga" + log.info("Converting " + outpath) + imageType = "" + with open(filepath, "rb") as txrFile: + txrFile.seek(2, 0) + imageType = struct.unpack("> 3) << 11) | ((G >> 2) << 5) | (B >> 3) + colorsAfter.append(color) + footer = tgaFile.read() + with open(outpath, "wb") as tgaFile: + headerPack = struct.pack("<3b2hb4h2b"+"4s2i", *header) + colorsPack = struct.pack("<"+str(colorsSize)+"H", *colorsAfter) + tgaFile.write(headerPack) + tgaFile.write(colorsPack) + tgaFile.write(footer) + + return \ No newline at end of file diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py new file mode 100644 index 0000000..17b6107 --- /dev/null +++ b/src/2.80/addons/importb3d/importb3d.py @@ -0,0 +1,1888 @@ +import enum +from hashlib import new +import struct +import sys +import timeit +import threading +import pdb +import logging +from pathlib import Path +from .imghelp import TXRtoTGA32 +from .imghelp import parsePLM +from .common import ShowMessageBox, Vector3F, createMaterial, parseMaterials, readCString, RESUnpack + +import bpy +import mathutils +import os.path +import os +from bpy.props import * +from bpy_extras.image_utils import load_image +from ast import literal_eval as make_tuple + +from math import sqrt +from math import atan2 + +import re + +import bmesh + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +log = logging.getLogger("importb3d") +log.setLevel(logging.DEBUG) + +class ChunkType(enum.Enum): + END_CHUNK = 0 + END_CHUNKS = 1 + BEGIN_CHUNK = 2 + GROUP_CHUNK = 3 + +def openclose(file): + oc = file.read(4) + if (oc == (b'\x4D\x01\x00\x00')): # Begin_Chunk(111) + return ChunkType.BEGIN_CHUNK + elif oc == (b'\x2B\x02\x00\x00'): # End_Chunk(555) + return ChunkType.END_CHUNK + elif oc == (b'\xbc\x01\x00\x00'): # Group_Chunk(444) + return ChunkType.GROUP_CHUNK + elif oc == (b'\xde\x00\00\00'): # End_Chunks(222) + return ChunkType.END_CHUNKS + else: + raise Exception() + +def onebyte(file): + return (file.read(1)) + +def readName(file): + objName = file.read(32) + if (objName[0] == 0): + objName = "empty name" + #objname = "Untitled_0x" + str(hex(file.tell()-36)) + else: + objName = (objName.decode("cp1251").rstrip('\0')) + return objName + + +def Triangulate(faces): + faces_new = [] + for t in range(len(faces)-2): + faces_new.extend([faces[t],faces[t+1],faces[t+2]]) + # if t%2 ==0: + # faces_new.extend([faces[t],faces[t+1],faces[t+2]]) + # else: + # faces_new.extend([faces[t+2],faces[t+1],faces[t]]) + + + # if ((format == 0) or (format == 16) or (format == 1)): + # faces_new.extend([faces[t+2],faces[t+1],faces[0]]) + # else: + # faces_new.extend([faces[t+2],faces[t+1],faces[t]]) + return faces_new + + +def MakePolyOk(faces): + faces1 = [] + face = [] + for j in range(len(faces)): + if (j%2 == 0): + faces1.append(faces[j]) + else: + face.append(faces[j]) + + faces = face + faces1.reverse() + faces.extend(faces1) + return faces + +def parse_plm(input_file, color_format): + with open (input_file,'r+b') as file: + struct.unpack(' 10 + material_colors.append(str(colors_list[colNum])) + else: + material_colors.append("[]") + + + ##### Параметры материалов (tex %d) ##### + material_textures = [] + + for i in range(materials_num): + texNum_str = str(re.findall(r't\wx\s+\d+', materials[i])) # t\wx - так как помимо tex, ещё бывает ttx + texNum = 0 + if (texNum_str != "[]"): + texNum_final = str(re.findall(r'\d+', texNum_str[2:-2]))[2:-2] + texNum = int(texNum_final) #[5:-2] нужно чтобы убрать ['tex и '], например: ['tex 10'] -> 10 + material_textures.append(texturefiles[texNum-1]) + else: + material_textures.append(material_colors[i]) + + #for k in range(materials_num): + + return material_textures + + + +def read(file, context, op, filepath): + if file.read(3) == b'b3d': + log.info("correct file") + else: + log.error("b3d error") + + commonResPath = bpy.context.preferences.addons['importb3d'].preferences.COMMON_RES_Path + + + #skip to materials list + file.seek(21,1) + Imgs = [] + math = [] + commonPalette = [] + materials = [] + + noextPath, ext = os.path.splitext(filepath) + basepath = os.path.dirname(filepath) + basename = os.path.basename(filepath)[:-4] #cut extension + #Пути + resPath = os.path.join(noextPath + ".res") + # commonPath = os.path.join(bpy.context.preferences.addons['importb3d'].preferences.COMMON_RES_Path, r"COMMON") + + RESUnpacked = None + if op.to_unpack_res: + RESUnpacked = unpackRES(resPath, basename, True) + else: + RESUnpacked = unpackRES(resPath, basename, False) + + if op.to_import_textures and not os.path.exists(commonResPath): + ShowMessageBox("Common.res path is wrong or is not set. Textures weren't imported! Please, set path to Common.res in addon preferences.", + "COMMON.res wrong path", + "ERROR") + op.to_import_textures = False + + if op.to_import_textures and os.path.exists(commonResPath): + # commonPath = os.path.join(r"D:\_PROJECTS\DB2\Hard Truck 2", r"COMMON") + # commonResPath = os.path.join(commonPath, r"COMMON.RES") + commonPath = os.path.join(os.path.dirname(commonResPath)) + palettePath = os.path.join(commonPath, r"COMMON_unpack/PALETTEFILES/common.plm") + unpackPath = os.path.join(basepath, basename + r"_unpack") + materialsPath = os.path.join(unpackPath, r"MATERIALS", "MATERIALS.txt") + colorsPath = os.path.join(unpackPath, r"COLORS", "COLORS.txt") + texturePath = os.path.join(unpackPath, r"TEXTUREFILES") + maskfiles = os.path.join(unpackPath, r"MASKFILES") + + #1. Получить общую для большинства палитру Common.plm + if os.path.exists(commonResPath): + unpackRES(commonResPath, "common") + commonPalette = parsePLM(palettePath) + else: + log.warning("Failed to unpack COMMON.RES") + + # RESUnpacked = unpackRES(resPath, basename) + + #2. Распаковка .RES и конвертация .txr и .msk в .tga 32bit + txrFolder = os.path.join(texturePath, "txr") + folder_content = os.listdir(txrFolder) + reTXR = re.compile(r'\.txr') + for path in folder_content: + fullpath = os.path.join(txrFolder, path) + if reTXR.search(path): + TXRtoTGA32(fullpath) + + #3. Парсинг и добавление материалов + materials = parseMaterials(materialsPath, basename) + for material in materials: + createMaterial(commonPalette, RESUnpacked.textures, texturePath, material, op.textures_format) + + # Parsing b3d + material_textures = [] + materials_count = struct.unpack('> 8 #ah + triangulateOffset = format & 0b10000000 + + if format & 0b10: + coordsPerVertex += 1 + + uunknown = struct.unpack(" 1: + for texnum in texnums: + mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] + b3dMesh.materials.append(mat) + lastIndex = len(b3dMesh.materials)-1 + + for vertArr in texnums[texnum]: + assignMaterialByVertices(b3dObj, vertArr, lastIndex) + else: + for texnum in texnums: + mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] + b3dMesh.materials.append(mat) + + objString.append(b3dObj.name) + + + elif (type == 9 or type == 22): + cnt+=1 + b3dObj = bpy.data.objects.new(objName, None) + b3dObj['block_type'] = type + b3dObj['pos'] = str(file.tell()) + + b3dObj.parent = context.scene.objects[objString[-1]] + context.collection.objects.link(b3dObj) + objString.append(b3dObj.name) + + bounding_sphere = struct.unpack("<4f",file.read(16)) + unknown_sphere = struct.unpack("<4f",file.read(16)) + childCnt = struct.unpack("0: + pass + + elif (type == 14): #sell_ ? + + b3dObj = bpy.data.objects.new(objName, None) + b3dObj['block_type'] = type + b3dObj['pos'] = str(file.tell()) + + b3dObj.parent = context.scene.objects[objString[-1]] + context.collection.objects.link(b3dObj) + objString.append(b3dObj.name) + + bounding_sphere = struct.unpack("<4f",file.read(16)) + unknown_sphere = struct.unpack("<4f",file.read(16)) + + some_var = struct.unpack("0: + pass + + elif (type == 16): + cnt+=1 + b3dObj = bpy.data.objects.new(objName, None) + b3dObj['block_type'] = type + b3dObj['pos'] = str(file.tell()) + + b3dObj.parent = context.scene.objects[objString[-1]] + context.collection.objects.link(b3dObj) + objString.append(b3dObj.name) + + bounding_sphere = struct.unpack("<4f",file.read(16)) + vector1 = struct.unpack("<3f",file.read(12)) + vector2 = struct.unpack("<3f",file.read(12)) + unk1 = struct.unpack(" 16*sys.float_info.epsilon): + z_d = atan2(m12, m22) + x_d = atan2(- m32, var_cy) + y_d = atan2(m31, m33) + else: + z_d = atan2(- m21, m11) + x_d = atan2(- m32, var_cy) + y_d = 0 + + rot_x = ((x_d * 180) / PI) + rot_y = ((y_d * 180) / PI) + rot_z = ((z_d * 180) / PI) + + + + #bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=sp_pos) + b3dObj = bpy.data.objects.new(objName, None) + #b3dObj = bpy.context.selected_objects[0] + #b3dObj.name = objName + b3dObj['block_type'] = type + b3dObj.rotation_euler[0] = x_d + b3dObj.rotation_euler[1] = y_d + b3dObj.rotation_euler[2] = z_d + b3dObj.location = sp_pos + + #b3dObj['rotation_euler0'] = rot_x + #b3dObj['rotation_euler1'] = rot_y + #b3dObj['rotation_euler2'] = rot_z + + #bpy.ops.object.select_all(action='DESELECT') + flag = struct.unpack("> 8 #ah + file.seek(4,1) + + unknown3 = struct.unpack("1): + # for i in range(coords[4]): + # coords.extend(struct.unpack("<4f",file.read(16))) + # else: + # coords.extend(struct.unpack("<8f",file.read(32))) + + # elif num ==2: + # coords.extend(struct.unpack("if3i",file.read(20))) + # for i in range(num*2): + # coords.extend(struct.unpack("<7f",file.read(28))) + # coords.extend(struct.unpack(" 0: + f = struct.unpack("<"+num0+"f",file.read(4*num0)) + + childCnt = struct.unpack("> 8) & 0xF0 #ah + triangulateOffset = format & 0b10000000 + + if format & 0b10: + coordsPerVertex += 1 + + uunknown = struct.unpack("> 8 + format = formatRaw & 0xFF + + vertexCount = struct.unpack("> 8 + format = formatRaw & 0xFF + + + vertexCount = struct.unpack(" 0: + + if format == 0: + objString.append(objString[-1]) + pass + else: + for i in range(vertexCount): + vertexes.append(struct.unpack("<3f",file.read(12))) + uv.append(struct.unpack("<2f",file.read(8))) + for j in range(uvCount): + u = struct.unpack("1): + del objString[-1] + type = grom + elif(line[0:4] == 'MNAM'): + mnam_c = int(line[5]) + type = mnam + + + + + + + + +def assignMaterialByVertices(obj, vertIndexes, matIndex): + bpy.context.view_layer.objects.active = obj + bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.mesh.select_mode(type= 'VERT') + bpy.ops.mesh.select_all(action = 'DESELECT') + bpy.ops.object.mode_set(mode = 'OBJECT') + for idx in vertIndexes: + obj.data.vertices[idx].select = True + selectedPolygons = getPolygonsBySelectedVertices() + for poly in selectedPolygons: + poly.material_index = matIndex + +def getPolygonsBySelectedVertices(): + data = bpy.context.object.data + selectedPolygons = [] + for f in data.polygons: + s = True + for v in f.vertices: + if not data.vertices[v].select: + s = False + if s: + selectedPolygons.append(f) + return selectedPolygons + +def getRESFolder(filepath): + basename = os.path.basename(filepath) + basepath = os.path.dirname(filepath) + return os.path.join(basepath, "{}_unpack".format(basename[:-4])) + +def unpackRES(filepath, prefix, saveOnDisk = True): + log.info("Unpacking {}:".format(filepath)) + # filename, resExtension = os.path.splitext(filepath) + # basename = os.path.basename(filepath)[:-4] + # basepath = os.path.dirname(filepath) + resdir = getRESFolder(filepath) + curfolder = resdir + if not os.path.exists(resdir): + os.mkdir(resdir) + + unpacked = RESUnpack() + unpacked.prefix = prefix + + with open(filepath, "rb") as resFile: + while 1: + category = readCString(resFile) + if(len(category) > 0): + log.info(category) + resSplit = category.split(" ") + id = resSplit[0] + cnt = int(resSplit[1]) + log.info("Reading category {}".format(id)) + log.info("Element count in category is {}.".format(cnt)) + binfilePath = None + if cnt > 0: + elements = [] + log.info("Start processing...") + curfolder = os.path.join(resdir,id) + if id == "COLORS" or id == "MATERIALS" or id == "SOUNDS": + if saveOnDisk: + binfilePath = os.path.join(curfolder, "{}.txt".format(id)) + binfileBase = os.path.dirname(binfilePath) + binfileBase = Path(binfileBase) + binfileBase.mkdir(exist_ok=True, parents=True) + names = [] + for i in range(cnt): + name = readCString(resFile) + names.append(name) + if id == "MATERIALS": + if saveOnDisk: + with open(binfilePath, "wb") as outFile: + for n in names: + nameSplit = n.split(" ") + name = nameSplit[0] + params = " ".join(nameSplit[1:]) + unpacked.materials.append(name) + unpacked.materialParams.append(params) + outFile.write((n+"\n").encode("UTF-8")) + else: + for n in names: + nameSplit = n.split(" ") + name = nameSplit[0] + params = " ".join(nameSplit[1:]) + unpacked.materials.append(name) + unpacked.materialParams.append(params) + elif id == "COLORS": + if saveOnDisk: + with open(binfilePath, "wb") as outFile: + for name in names: + unpacked.colors.append(name) + outFile.write((name+"\n").encode("UTF-8")) + else: + for name in names: + unpacked.colors.append(name) + else: + if saveOnDisk: + with open(binfilePath, "wb") as outFile: + for name in names: + outFile.write((name+"\n").encode("UTF-8")) + else: + names = [] + for i in range(cnt): + name = readCString(resFile).split(" ")[0] + names.append(name) + sectionSize = struct.unpack(" Tools", + "warning": "", + "wiki_url": "", + "tracker_url": "vk.com/rnr_mods", + "category": "Development" +} + +import bpy + +from bpy.props import (StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + EnumProperty, + PointerProperty, + ) + +from bpy.types import (Panel, + Operator, + PropertyGroup, + ) + +import struct + +bytes_len = 0 + +# panel + +class PanelSettings1(PropertyGroup): + + #my_bool = BoolProperty( + # name="Enable or Disable", + # description="A bool property", + # default = False + # ) + + #my_int = IntProperty( + # name = "Int Value", + # description="A integer property", + # default = 23, + # min = 10, + # max = 100 + # ) + + #my_float = FloatProperty( + # name = "Float Value", + # description = "A float property", + # default = 23.7, + # min = 0.01, + # max = 30.0 + # ) + + addWBlockType_enum = EnumProperty( + name="Тип блока", + items=[ ('VDAT', "VDAT", ""), # + ('WDTH', "WDTH", ""), # + ('RTEN', "RTEN", ""), + ('ATTR', "ATTR", ""), # + ('FLAG', "FLAG", ""), # + ('ORTN', "ORTN", ""), + ('POSN', "POSN", ""), + ('NNAM', "NNAM", ""), + ('RNOD', "RNOD", ""), + ('RNAM', "RNAM", ""), + ('GROM', "GROM", ""), + ('GDAT', "GDAT", ""), + ('MNAM', "MNAM", ""), + ('WTWR', "WTWR", ""), + ] + ) + + addWDBlockType_enum = EnumProperty( + name="Тип блока", + items=[ ('way', "Way", ""), + ('room', "Room", ""), + ('rseg', "Road segment", ""), + ('rnod', "Node", ""), + ('ortn', "Node with orientation block", ""), + ] + ) + + attr_int_0 = IntProperty( + name = "Параметр 1", + description="Тип дороги", + default = 1, + min = 0 + ) + + attr_dbl_0 = FloatProperty( + name = "Граница дороги", + description="A integer property", + default = 0, + min = 0 + ) + + attr_int_1 = IntProperty( + name = "Параметр 3", + description="-", + default = 1, + min = 0 + ) + + wdth_dbl_0 = FloatProperty( + name = "Параметр 1", + description="", + min = 0 + ) + + wdth_dbl_1 = FloatProperty( + name = "Параметр 2", + description="", + min = 0 + ) + + flag_int = IntProperty( + name = "Флаг", + description="", + min = 0, + ) + + name_string = StringProperty( + name="Имя объекта", + default="", + maxlen=20, + ) +########################################## + mnam_string = StringProperty( + name="Имя карты", + default="aa", + maxlen=2, + ) + + rnam_string = StringProperty( + name="Имя комнаты", + default="room_aa_000", + maxlen=20, + ) + + nnam_string = StringProperty( + name="Node name", + default="pos_parking_00", + maxlen=20, + ) + + wdth_val = FloatProperty( + name = "Ширина дороги", + description="", + default=14, + min = 0, + ) + + attr_1 = IntProperty( + name = "Тип дороги", + description="", + default = 1, + min = 0 + ) + + attr_2 = FloatProperty( + name = "Граница дороги", + description="", + default = 0.1, + min = 0 + ) + + attr_3 = IntProperty( + name = "Параметр 3", + description="", + default = 1, + min = 0 + ) + + flag_val = IntProperty( + name = "Флаг", + description="", + min = 0, + ) + +class AddOperator1(bpy.types.Operator): + bl_idname = "wm.add_operator1" + bl_label = "Добавить блок на сцену" + + def execute(self, context): + scene = context.scene + waytool = scene.way_tool + + global blockW_type + + blockW_type = waytool.addWBlockType_enum + + global cursor_pos1 + cursor_pos1 = bpy.context.scene.cursor_location + + + if blockW_type == "WDTH": + object_name = waytool.addWBlockType_enum + object = bpy.data.objects.new(object_name, None) + object.location=(0,0,0) + object['var1'] = waytool.wdth_dbl_0 + object['var2'] = waytool.wdth_dbl_1 + bpy.context.scene.objects.link(object) + + if blockW_type == "ATTR": + object_name = waytool.addWBlockType_enum + object = bpy.data.objects.new(object_name, None) + object.location=(0,0,0) + object['var1'] = waytool.attr_int_0 + object['var2'] = waytool.attr_dbl_0 + object['var3'] = waytool.attr_int_1 + bpy.context.scene.objects.link(object) + + if blockW_type == "FLAG": + object_name = waytool.addWBlockType_enum + object = bpy.data.objects.new(object_name, None) + object.location=(0,0,0) + object['flag'] = waytool.flag_int + bpy.context.scene.objects.link(object) + + if blockW_type == "MNAM": + object_name = waytool.addWBlockType_enum + object = bpy.data.objects.new(object_name, None) + object.location=(0,0,0) + object['str'] = waytool.name_string + bpy.context.scene.objects.link(object) + + if blockW_type == "RNAM": + object_name = waytool.addWBlockType_enum + object = bpy.data.objects.new(object_name, None) + object.location=(0,0,0) + object['str'] = waytool.name_string + bpy.context.scene.objects.link(object) + + if blockW_type == "NNAM": + object_name = waytool.addWBlockType_enum + object = bpy.data.objects.new(object_name, None) + object.location=(0,0,0) + object['str'] = waytool.name_string + bpy.context.scene.objects.link(object) + + if blockW_type == "ORTN": + object = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) + object = bpy.context.selected_objects[0] + object.name = waytool.addWBlockType_enum + object.location=cursor_pos1 + + if blockW_type == "POSN": + object = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) + object = bpy.context.selected_objects[0] + object.name =waytool.addWBlockType_enum + object.location=cursor_pos1 + + return {'FINISHED'} + +class SetValuesOperator1(bpy.types.Operator): + bl_idname = "wm.set_values_operator1" + bl_label = "Сохранить настройки блока" + + def execute(self, context): + scene = context.scene + waytool = scene.way_tool + + object = bpy.context.selected_objects[0] + + if object.name[0:4] == 'ATTR': + object['var1'] = waytool.attr_int_0 + object['var2'] = waytool.attr_dbl_0 + object['var3'] = waytool.attr_int_1 + + elif object.name[0:4] == 'WDTH': + object['var1'] = waytool.wdth_dbl_0 + object['var2'] = waytool.wdth_dbl_1 + + return {'FINISHED'} + +class AddOperator11(bpy.types.Operator): + bl_idname = "wm.add_operator11" + bl_label = "Добавить объект на сцену" + + def execute(self, context): + scene = context.scene + waytool = scene.way_tool + + global blockWD_type + + blockWD_type = waytool.addWDBlockType_enum + + global cursor_pos1 + cursor_pos1 = bpy.context.scene.cursor_location + + if blockWD_type == "way": + way = bpy.data.objects.new("way", None) + way.location=(0,0,0) + way['type'] = "way" + way['mnam'] = waytool.mnam_string + bpy.context.scene.objects.link(way) + + + if blockWD_type == "room": + object_name = waytool.rnam_string + object = bpy.data.objects.new(object_name, None) + object.location=(0,0,0) + object['type'] = "room" + bpy.context.scene.objects.link(object) + + if blockWD_type == "rseg": + + points = [(0,0,0), (0,1,0)] + + curveData = bpy.data.curves.new('curve', type='CURVE') + + curveData.dimensions = '3D' + curveData.resolution_u = 2 + + polyline = curveData.splines.new('POLY') + polyline.points.add(len(points)-1) + for i, coord in enumerate(points): + x,y,z = coord + polyline.points[i].co = (x, y, z, 1) + + object = bpy.data.objects.new("RSEG", curveData) + curveData.bevel_depth = 0.01 + + object.location = (0,0,0) + + object.name = "RSEG" + object['type'] = "rseg" + object['attr1'] = waytool.attr_1 + object['attr2'] = waytool.attr_2 + object['attr3'] = waytool.attr_3 + object['wdth'] = waytool.wdth_val + context.scene.objects.link(object) + + if blockWD_type == "rnod" or blockWD_type == "ortn": + object = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) + object = bpy.context.selected_objects[0] + object.name = waytool.nnam_string + object.location=cursor_pos1 + object['type'] = waytool.addWDBlockType_enum + object['flag'] = waytool.flag_val + + return {'FINISHED'} + +class OBJECT_PT_way_add_panel(Panel): + bl_idname = "OBJECT_PT_way_add_panel" + bl_label = "Добавление блоков" + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + bl_category = "way Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + waytool = scene.way_tool + global blockW_type + blockW_type = waytool.addWBlockType_enum + + self.layout.label("Тип блока:") + layout.prop(waytool, "addWBlockType_enum", text="") + + if blockW_type == "ATTR": + layout.prop(waytool, "attr_int_0") + layout.prop(waytool, "attr_dbl_0") + layout.prop(waytool, "attr_int_1") + + if blockW_type == "WDTH": + layout.prop(waytool, "wdth_dbl_0") + layout.prop(waytool, "wdth_dbl_1") + + if blockW_type == "FLAG": + layout.prop(waytool, "flag_int") + + if blockW_type == "MNAM": + layout.prop(waytool, "name_string") + + if blockW_type == "RNAM": + layout.prop(waytool, "name_string") + + if blockW_type == "NNAM": + layout.prop(waytool, "name_string") + + layout.operator("wm.add_operator1") + +class GetValuesOperator1(bpy.types.Operator): + bl_idname = "wm.get_values_operator1" + bl_label = "Получить настройки блока" + + def execute(self, context): + scene = context.scene + waytool = scene.way_tool + + object = bpy.context.selected_objects[0] + + if object.name[0:4] == 'ATTR': + waytool.attr_int_0 = object['var1'] + waytool.attr_dbl_0 = object['var2'] + waytool.attr_int_1 = object['var3'] + + elif object.name[0:4] == 'WDTH': + waytool.wdth_dbl_0 = object['var1'] + waytool.wdth_dbl_1 = object['var2'] + + elif object.name[0:4] == 'FLAG': + waytool.flag_int = object['flag'] + + elif object.name[0:4] == 'MNAM': + waytool.name_string = object['str'] + + elif object.name[0:4] == 'RNAM': + waytool.name_string = object['str'] + + elif object.name[0:4] == 'NNAM': + waytool.name_string = object['str'] + + return {'FINISHED'} + +class OBJECT_PT_way_edit_panel(Panel): + bl_idname = "OBJECT_PT_way_edit_panel" + bl_label = "Редактирование блоков" + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + bl_category = "way Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + waytool = scene.way_tool + + object = bpy.context.selected_objects[0] + + if object.name[0:4] == "ATTR": + layout.prop(waytool, "attr_int_0") + layout.prop(waytool, "attr_dbl_0") + layout.prop(waytool, "attr_int_1") + + if object.name[0:4] == "WDTH": + layout.prop(waytool, "wdth_dbl_0") + layout.prop(waytool, "wdth_dbl_1") + + if object.name[0:4] == "FLAG": + layout.prop(waytool, "flag_int") + + if object.name[0:4] == "MNAM": + layout.prop(waytool, "name_string") + + if object.name[0:4] == "RNAM": + layout.prop(waytool, "name_string") + + if object.name[0:4] == "NNAM": + layout.prop(waytool, "name_string") + + layout.operator("wm.get_values_operator1") + layout.operator("wm.set_values_operator1") + +class OBJECT_PT_way_misc_panel(Panel): + bl_idname = "OBJECT_PT_way_misc_panel" + bl_label = "О плагине" + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + bl_category = "way Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + waytool = scene.way_tool + + self.layout.label("Автор плагина: aleko2144") + self.layout.label("vk.com/rnr_mods") + +class OBJECT_PT_blocks_panel(Panel): + bl_idname = "OBJECT_PT_blocks_panel" + bl_label = "Создание блоков" + bl_space_type = "VIEW_3D" + bl_region_type = "TOOLS" + bl_category = "way Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + waytool = scene.way_tool + + layout.prop(waytool, "addWDBlockType_enum") + + if waytool.addWDBlockType_enum == "way": + layout.prop(waytool, "mnam_string") + + if waytool.addWDBlockType_enum == "room": + layout.prop(waytool, "rnam_string") + + if waytool.addWDBlockType_enum == "rseg": + layout.prop(waytool, "attr_1") + layout.prop(waytool, "attr_2") + layout.prop(waytool, "attr_3") + layout.prop(waytool, "wdth_val") + + if waytool.addWDBlockType_enum == "rnod" or waytool.addWDBlockType_enum == "ortn": + layout.prop(waytool, "nnam_string") + layout.prop(waytool, "flag_val") + + layout.operator("wm.add_operator11") + +# exporter + +def MsgBox(label = "", title = "Error", icon = 'ERROR'): + + def draw(self, context): + self.layout.label(label) + + bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) + +def export(context, filepath, use_some_setting): + file = open(filepath, 'wb') + #SetBytesLength(bpy.data.objects['way'], True) + #SetCBytesLength(bpy.data.objects['way'], True) + #SetRS(bpy.data.objects['way'], True) + #SetGR(bpy.data.objects['way'], True) + #SetGD(bpy.data.objects['way'], True) + #SetMN(bpy.data.objects['way'], True) + #SetWT(bpy.data.objects['way'], True) + ClearBytes(bpy.data.objects['way'], True) + SetNodeBytes(bpy.data.objects['way'], True) + SetRSEGBytes(bpy.data.objects['way'], True) + SetRoomBytes(bpy.data.objects['way'], True) + SetWayBytes(bpy.data.objects['way'], True) + SetWayBytes1(bpy.data.objects['way'], True) + writeWTWR(bpy.data.objects['way'], file) + forChild(bpy.data.objects['way'],True, file) + + file.close() + + return {'FINISHED'} + +def SetBytesLength(object, root): + if (not root): + if object.name[0:4] == 'VDAT': + for subcurve in object.data.splines: + bytes_len = (len(subcurve.points) * 24) + 4 + 4 + 4 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + if object.name[0:4] == 'ATTR': + bytes_len = 24 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'WDTH': + bytes_len = 24 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'ORTN': + bytes_len = 96 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'POSN': + bytes_len = 32 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'RSEG': + bytes_len = 8 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'RNAM': + + text_len = 0 + + if (len(str(object['str'])) > 15): + text_len = 20 + + elif (11 < len(str(object['str'])) < 15 or len(str(object['str'])) == 15): + text_len = 16 + + elif (7 < len(str(object['str'])) < 11 or len(str(object['str'])) == 11): + text_len = 12 + + elif (3 < len(str(object['str'])) < 7 or len(str(object['str'])) == 7): + text_len = 8 + + elif (len(str(object['str'])) < 3 or len(str(object['str'])) == 3): + text_len = 4 + + bytes_len = 8 + text_len + + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'RNOD': + bytes_len = 8 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'NNAM': + text_len = 0 + + if (len(str(object['str'])) > 15): + text_len = 20 + + elif (11 < len(str(object['str'])) < 15 or len(str(object['str'])) == 15): + text_len = 16 + + elif (7 < len(str(object['str'])) < 11 or len(str(object['str'])) == 11): + text_len = 12 + + elif (3 < len(str(object['str'])) < 7 or len(str(object['str'])) == 7): + text_len = 8 + + elif (len(str(object['str'])) < 3 or len(str(object['str'])) == 3): + text_len = 4 + + bytes_len = 8 + text_len + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'GROM': + bytes_len = 8 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'GDAT': + bytes_len = 8 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'MNAM': + text_len = 0 + + if (len(str(object['str'])) > 15): + text_len = 20 + + elif (11 < len(str(object['str'])) < 15 or len(str(object['str'])) == 15): + text_len = 16 + + elif (7 < len(str(object['str'])) < 11 or len(str(object['str'])) == 11): + text_len = 12 + + elif (3 < len(str(object['str'])) < 7 or len(str(object['str'])) == 7): + text_len = 8 + + elif (len(str(object['str'])) < 3 or len(str(object['str'])) == 3): + text_len = 4 + + bytes_len = 8 + text_len + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'WTWR': + bytes_len = 8 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + + elif object.name[0:4] == 'FLAG': + bytes_len = 12 + object['bytes_len'] = bytes_len + object['c_bytes_len'] = 0 + #object['flag'] = 1 + + for child in object.children: + SetBytesLength(child,False) + + +def SetCBytesLength(object, root): + varCB = 0 + if (not root): + if object.name[0:4] == 'RSEG': + bytes_len = 8 + + elif object.name[0:4] == 'RNOD': + for x in range (len(object.children)): + varCB += object.children[x]['bytes_len'] + + object['c_bytes_len'] = varCB + + for child in object.children: + SetCBytesLength(child,False) + +def SetRS(object, root): + varRS = 0 + if (not root): + if object.name[0:4] == 'RSEG': + for r in range (len(object.children)): + varRS += object.children[r]['bytes_len'] + object.children[r]['c_bytes_len'] + + object['c_bytes_len'] = varRS + + for child in object.children: + SetRS(child, False) + +def SetGR(object, root): + varGR = 0 + if (not root): + if object.name[0:4] == 'GROM': + for j in range (len(object.children)): + varGR += object.children[j]['bytes_len'] + object.children[j]['c_bytes_len'] + + object['c_bytes_len'] = varGR + + for child in object.children: + SetGR(child, False) + +def SetGD(object, root): + variable = 0 + if (not root): + if object.name[0:4] == 'GDAT': + for n in range (len(object.children)): + variable += object.children[n]['bytes_len'] + object.children[n]['c_bytes_len'] + + object['c_bytes_len'] = variable + + for child in object.children: + SetGD(child, False) + +def SetMN(object, root): + varMN = 0 + if (not root): + if object.name[0:4] == 'MNAM': + for i in range (len(object.children)): + varMN = object.children[i]['bytes_len'] + object.children[i]['c_bytes_len'] + + object['c_bytes_len'] = varMN + + for child in object.children: + SetMN(child, False) + +def SetWT(object, root): + varWT = 0 + if (not root): + if object.name[0:4] == 'WTWR': + for i in range (len(object.children)): + varWT = object.children[i]['bytes_len'] + object.children[i]['c_bytes_len'] + + object['c_bytes_len'] = varWT + + for child in object.children: + SetWT(child, False) + + +def GetCBytesLength(object, root): + var1 = 0 + if (not root): + #for object in bpy.data.objects: + if (object.children): + for i in range (len(object.children)): + var1 = object.children[i]['bytes_len'] + object['bytes_len'] + #object['c_bytes_len'] = var1 + object['c_bytes_len'] = var1 + object['c_bytes_len'] + print(str(var1)) + + for child in object.children: + GetCBytesLength(child,False) + +def SetRSEGBytes(object, root): + if (not root): + if object['type'] == 'rseg': + for subcurve in object.data.splines: + object['bytes_len'] = 68 + len(subcurve.points) * 24 + + room = object.parent + room['c_bytes_len'] += object['bytes_len'] + + for child in object.children: + SetRSEGBytes(child, False) + +def SetNodeBytes(object, root): + var_node = 0 + print("SetNodeBytes") + try: + if object['type'] == 'rnod' or object['type'] == 'ortn': + object_name = object.name.split(".")[0] + text_len1 = 0 + if (len(str(object_name)) > 15): + text_len1 = 20 + + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): + text_len1 = 16 + + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): + text_len1 = 12 + + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): + text_len1 = 8 + + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): + text_len1 = 4 + + var_node = text_len1 + 16 + 32 + 12 + if object['type'] == "ortn": + var_node += 104 + object['bytes_len'] = var_node + + #object.parent['c_bytes_len'] += var_node + room = object.parent + room['c_bytes_len'] += var_node + + for child in object.children: + SetNodeBytes(child, False) + except: + pass + +def SetRoomBytes(object, root): + var_r = 0 + if object['type'] == 'room': + object_name = object.name.split(".")[0] + text_len1 = 0 + if (len(str(object_name)) > 15): + text_len1 = 20 + + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): + text_len1 = 16 + + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): + text_len1 = 12 + + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): + text_len1 = 8 + + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): + text_len1 = 4 + + var_r = text_len1 + 16 + + object['bytes_len'] = var_r #+ 8 + + #way = object.parent + #way['c_bytes_len'] += object['bytes_len'] + + for child in object.children: + SetRoomBytes(child, False) + +def SetWayBytes(object, root): + if object['type'] == 'room': + way = object.parent + print(object['bytes_len']) + way['c_bytes_len'] = way['c_bytes_len'] + object['c_bytes_len'] + object['bytes_len'] + + for child in object.children: + SetWayBytes(child, False) + +def SetWayBytes1(object, root): + if object['type'] == 'way': + object['bytes_len'] = 20 + object['c_bytes_len'] + + for child in object.children: + SetWayBytes1(child, False) + +def ClearBytes(object, root): + if object['type'] == 'room': + object['bytes_len'] = 0 + object['c_bytes_len'] = 0 + + if object['type'] == 'way': + object['bytes_len'] = 0 + object['c_bytes_len'] = 0 + + for child in object.children: + ClearBytes(child, False) + +def writeWTWR(object, file): + file.write(str.encode('WTWR')) + file.write(struct.pack(" 15): + text_len1 = 20 + + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): + text_len1 = 16 + + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): + text_len1 = 12 + + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): + text_len1 = 8 + + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): + text_len1 = 4 + + object['c_bytes_len'] = text_len1 + 8 + 32 + 12 + + if object['type'] == "ortn": + object['c_bytes_len'] += 104 + + file.write(struct.pack(" 15): + file.write(str.encode(object_name)+bytearray(b'\x00'*(20-len(str(object_name))))) + text_len = 20 + + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): + file.write(str.encode(object_name)+bytearray(b'\x00'*(16-len(str(object_name))))) + text_len = 16 + + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): + file.write(str.encode(object_name)+bytearray(b'\x00'*(12-len(str(object_name))))) + text_len = 12 + + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): + file.write(str.encode(object_name)+bytearray(b'\x00'*(8-len(str(object_name))))) + text_len = 8 + + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): + file.write(str.encode(object_name)+bytearray(b'\x00'*(4-len(str(object_name))))) + text_len = 4 + + #bytes_len = 8 + text_len + + file.write(str.encode('POSN')) + file.write(struct.pack(" 15): + text_len1 = 20 + + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): + text_len1 = 16 + + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): + text_len1 = 12 + + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): + text_len1 = 8 + + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): + text_len1 = 4 + + object['bytes_len'] = 8 + text_len1 + object['c_bytes_len'] + object['c_bytes_len'] = object['c_bytes_len'] + 20 + + file.write(struct.pack(" 15): + file.write(str.encode(object_name)+bytearray(b'\x00'*(20-len(str(object_name))))) + text_len = 20 + + elif (11 < len(str(object_name)) < 15 or len(str(object_name)) == 15): + file.write(str.encode(object_name)+bytearray(b'\x00'*(16-len(str(object_name))))) + text_len = 16 + + elif (7 < len(str(object_name)) < 11 or len(str(object_name)) == 11): + file.write(str.encode(object_name)+bytearray(b'\x00'*(12-len(str(object_name))))) + text_len = 12 + + elif (3 < len(str(object_name)) < 7 or len(str(object_name)) == 7): + file.write(str.encode(object_name)+bytearray(b'\x00'*(8-len(str(object_name))))) + text_len = 8 + + elif (len(str(object_name)) < 3 or len(str(object_name)) == 3): + file.write(str.encode(object_name)+bytearray(b'\x00'*(4-len(str(object_name))))) + text_len = 4 + + for child in object.children: + forChild(child,False,file) + +# ExportHelper is a helper class, defines filename and +# invoke() function which calls the file selector. +from bpy_extras.io_utils import ExportHelper +from bpy.props import StringProperty, BoolProperty, EnumProperty +from bpy.types import Operator + +class ImportSomeData(Operator, ExportHelper): + """This appears in the tooltip of the operator and in the generated docs""" + bl_idname = "import_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed + bl_label = "Import *.way" + + # ExportHelper mixin class uses this + filename_ext = ".way" + + filter_glob = StringProperty( + default="*.way", + options={'HIDDEN'}, + maxlen=255, # Max internal buffer length, longer would be clamped. + ) + + def execute(self, context): + from . import import_way + with open(self.filepath, 'r') as file: + import_way.read(self.filepath, context) + return {'FINISHED'} + +class ExportSomeData(Operator, ExportHelper): + """This appears in the tooltip of the operator and in the generated docs""" + bl_idname = "export_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed + bl_label = "Export *.way" + + # ExportHelper mixin class uses this + filename_ext = ".way" + + filter_glob = StringProperty( + default="*.way", + options={'HIDDEN'}, + maxlen=255, # Max internal buffer length, longer would be clamped. + ) + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + use_setting = BoolProperty( + name="Example Boolean", + description="Example Tooltip", + default=True, + ) + + type = EnumProperty( + name="Example Enum", + description="Choose between two items", + items=(('OPT_A', "First Option", "Description one"), + ('OPT_B', "Second Option", "Description two")), + default='OPT_A', + ) + + def execute(self, context): + return export(context, self.filepath, self.use_setting) + + +# Only needed if you want to add into a dynamic menu +def menu_func_export(self, context): + self.layout.operator(ExportSomeData.bl_idname, text="Export KOTR *.way") + +def menu_func_import(self, context): + self.layout.operator(ImportSomeData.bl_idname, text="Import KOTR *.way") + +def register(): + bpy.utils.register_class(ExportSomeData) + bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + + bpy.utils.register_class(ImportSomeData) + bpy.types.TOPBAR_MT_file_import.append(menu_func_import) + + bpy.utils.register_module(__name__) + bpy.types.Scene.way_tool = PointerProperty(type=PanelSettings1) + + +def unregister(): + bpy.utils.unregister_class(ExportSomeData) + bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) + + bpy.utils.unregister_class(ImportSomeData) + bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) + + bpy.utils.unregister_module(__name__) + del bpy.types.Scene.way_tool + + +if __name__ == "__main__": + register() + + # test call + bpy.ops.export_test.some_data('INVOKE_DEFAULT') diff --git a/src/2.80/addons/way_tools/import_way.py b/src/2.80/addons/way_tools/import_way.py new file mode 100644 index 0000000..d0a25ee --- /dev/null +++ b/src/2.80/addons/way_tools/import_way.py @@ -0,0 +1,221 @@ +import bpy +import struct +import os +import sys + +def readName(file): + text_len = 0 + str_len = 0 + + text_len = struct.unpack(" 15): + str_len = 20 + + elif (11 < text_len < 15 or text_len == 15): + str_len = 16 + + elif (7 < text_len < 11 or text_len == 11): + str_len = 12 + + elif (3 < text_len < 7 or text_len == 7): + str_len = 8 + + elif (text_len < 3 or text_len == 3): + str_len = 4 + + string = file.read(str_len).decode("utf-8") + return string + +def openclose(file, path): + if file.tell() == os.path.getsize(path): + print ('EOF') + return 1 + else: + return 2 + print(str(os.path.getsize(path))) + +def read(file, context): + file_path = file + file = open(file, 'rb') + + ex = 0 + while ex!=1: + ex = openclose(file, file_path) + if ex == 1: + file.close() + break + + elif ex == 2: + type = file.read(4).decode("cp1251") + + global r + + if type == "WTWR": #WTWR + object_name = "way" + object = bpy.data.objects.new(object_name, None) + object.location=(0,0,0) + object['c_bytes_len'] = struct.unpack(" Date: Sun, 28 Aug 2022 13:18:18 +0200 Subject: [PATCH 02/47] block 28 fix --- src/2.80/addons/importb3d/importb3d.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index 17b6107..5c63f29 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -1065,7 +1065,7 @@ def read(file, context, op, filepath): formatRaw = struct.unpack("> 8 #ah + unknown2 = ((formatRaw & 0xFF00) >> 8) + 1 #ah file.seek(4,1) unknown3 = struct.unpack(" Date: Sun, 28 Aug 2022 13:28:25 +0200 Subject: [PATCH 03/47] README --- README.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 12ce87f..40b87c2 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ # Blender-VWI -Плагины для форматов файлов игрового движка Virtual World Inventor. +Плагины для форматов файлов игрового движка Virtual World Inventor. ##### Текущие планы -* Доработка экспорта. -* Переход на Blender 2.9. -* Поддержка импорта и экспорта игровых ресурсов. +* Доработка экспорта b3d. ## Поддерживаемые игры | Название игры | Название игры (международное) | Год выхода | @@ -12,32 +10,35 @@ | Дальнобойщики - 2 | Hard Truck 2 (King of the Road) | 2000 (2003) ## Поддерживаемые форматы файлов -| Расширение | Описание | Импорт | Экспорт | +| Расширение | Описание | Импорт | Экспорт | |-----------|-----------------------|:----------:|:----------:| -| .b3d | Модели, логика, различные объекты | Да | Да | -| .way | Пути транспорта для ИИ | Да | Да | -| .tch/.tech | Параметры транспорта и динамических объектов | | Да | -| .res/.rmp | Архив игровых ресурсов | | в работе | -| .pro | Архив игровых ресурсов | | в работе | +| .b3d + .res | Модели, логика, различные объекты | Да | Нет | +| .way | Пути транспорта для ИИ | Нет | Нет | +| .tch/.tech | Параметры транспорта и динамических объектов | | Да | ## Файлы в проекте -#### Папка **src/2.79** +#### Папка **src/2.79** Плагины для версии 2.79. -#### Папка **scenes** +#### Папка **src/2.80** + +Плагины для версии 2.80+. +#### Папка **scenes** Готовые сцены для экспорта в игру: **ht2-way.blend** - пути транспорта, **ht2-vehicle-export.blend** - транспорт, **ht2-env-module.blend** - карта -## Как установить плагины +## Как установить плагины 1. Распаковать архив. -2. Поместить содержимое в папку Blender/2.79/scripts/addons/. +2. Поместить содержимое в папку Blender/2.79/scripts/addons/. 3. Открыть настройки в Blender (нажать LCtrl + Alt + U ), перейти во вкладку Addons. 4. Найти аддоны (b3d) и активировать их (галка на названии). ## Авторы Юрий Гладышенко и Андрей Прожога. +Обновление: Иван Карцев + ## Ссылки [Сообщество VK](https://vk.com/rnr_mods) @@ -49,21 +50,20 @@ Hard Truck classic games (VWI engine) import/export plugins for Blender. #### Roadmap -* Blender 2.9 support -* Add support for game resource files (.res/.rmp) +* Export support ## Supported games and formats 1. Hard Truck: Road to Victory (1998) -| Расширение | Описание | Import | +| Расширение | Описание | Import | |-----------|-----------------------|:----------:| -| .b3d | Models, game logic, various objects | Yes | +| .b3d | Models, game logic, various objects | Yes | 2. Hard Truck: King Of The Road (2003) -| Расширение | Описание | Import | Export | +| Расширение | Описание | Import | Export | |-----------|-----------------------|:----------:|:----------:| -| .b3d | Models, game logic, various objects | Yes | Yes | -| .way | AI paths | Yes | Yes | -| .tch/.tech | Transport parameters | | Yes | \ No newline at end of file +| .b3d | Models, game logic, various objects | Yes | No | +| .way | AI paths | No | No | +| .tch/.tech | Transport parameters | | Yes | \ No newline at end of file From cbd6b516368823bd95979e4d7fa0c2457e53a7d7 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sun, 28 Aug 2022 23:39:08 +0200 Subject: [PATCH 04/47] import .way --- README.md | 4 +- src/2.80/addons/b3d_tools/common.py | 12 +- src/2.80/addons/way_tools/__init__.py | 115 ++++++--- src/2.80/addons/way_tools/import_way.py | 327 ++++++++++++------------ 4 files changed, 256 insertions(+), 202 deletions(-) diff --git a/README.md b/README.md index 40b87c2..b6ba4e0 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ | Расширение | Описание | Импорт | Экспорт | |-----------|-----------------------|:----------:|:----------:| | .b3d + .res | Модели, логика, различные объекты | Да | Нет | -| .way | Пути транспорта для ИИ | Нет | Нет | +| .way | Пути транспорта для ИИ | Да | Нет | | .tch/.tech | Параметры транспорта и динамических объектов | | Да | ## Файлы в проекте @@ -65,5 +65,5 @@ Hard Truck classic games (VWI engine) import/export plugins for Blender. | Расширение | Описание | Import | Export | |-----------|-----------------------|:----------:|:----------:| | .b3d | Models, game logic, various objects | Yes | No | -| .way | AI paths | No | No | +| .way | AI paths | Yes | No | | .tch/.tech | Transport parameters | | Yes | \ No newline at end of file diff --git a/src/2.80/addons/b3d_tools/common.py b/src/2.80/addons/b3d_tools/common.py index 2ab5d58..027d5e0 100644 --- a/src/2.80/addons/b3d_tools/common.py +++ b/src/2.80/addons/b3d_tools/common.py @@ -56,7 +56,7 @@ def applyTransform(block_18): allChildren = [obj for obj in getAllChildren(destObj)] - subTransforms = [obj for obj in allChildren if obj["block_type"] == 18] + subTransforms = [obj for obj in allChildren if obj.get("block_type") is not None and obj["block_type"] == 18] meshes = [obj for obj in allChildren if obj.type=="MESH" and not reIsCopy.search(obj.name)] @@ -117,13 +117,13 @@ def removeTransforms(): bpy.ops.object.delete() def applyTransforms(): - objs = [cn for cn in bpy.data.objects if cn["block_type"]==18] + objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==18] for obj in objs: applyTransform(obj) def showHideObjByType(type): - objs = [cn for cn in bpy.data.objects if cn["block_type"]==type] - hiddenObj = [cn for cn in bpy.data.objects if cn["block_type"]==type and cn.hide_get()] + objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] + hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] if objs == hiddenObj: for obj in objs: obj.hide_set(False) @@ -132,8 +132,8 @@ def showHideObjByType(type): obj.hide_set(True) def showHideObjTreeByType(type): - objs = [cn for cn in bpy.data.objects if cn["block_type"]==type] - hiddenObj = [cn for cn in bpy.data.objects if cn["block_type"]==type and cn.hide_get()] + objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] + hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] if objs == hiddenObj: for obj in objs: children = getAllChildren(obj) diff --git a/src/2.80/addons/way_tools/__init__.py b/src/2.80/addons/way_tools/__init__.py index e07be36..ac5e783 100644 --- a/src/2.80/addons/way_tools/__init__.py +++ b/src/2.80/addons/way_tools/__init__.py @@ -11,6 +11,18 @@ "category": "Development" } +# To support reload properly, try to access a package var, if it's there, +# reload everything +if "bpy" in locals(): + print("Reimporting modules!!!") + import importlib + importlib.reload(import_way) +else: + import bpy + from . import ( + import_way + ) + import bpy from bpy.props import (StringProperty, @@ -30,6 +42,14 @@ bytes_len = 0 + +# https://blenderartists.org/t/solved-adding-a-tab-in-blender-2-8/1133119/3 +def getRegion(): + if bpy.app.version < (2,80,0): + return "TOOLS" + else: + return "UI" + # panel class PanelSettings1(PropertyGroup): @@ -350,7 +370,7 @@ class OBJECT_PT_way_add_panel(Panel): bl_idname = "OBJECT_PT_way_add_panel" bl_label = "Добавление блоков" bl_space_type = "VIEW_3D" - bl_region_type = "TOOLS" + bl_region_type = getRegion() bl_category = "way Tools" #bl_context = "objectmode" @@ -365,7 +385,7 @@ def draw(self, context): global blockW_type blockW_type = waytool.addWBlockType_enum - self.layout.label("Тип блока:") + self.layout.label(text="Тип блока:") layout.prop(waytool, "addWBlockType_enum", text="") if blockW_type == "ATTR": @@ -428,7 +448,7 @@ class OBJECT_PT_way_edit_panel(Panel): bl_idname = "OBJECT_PT_way_edit_panel" bl_label = "Редактирование блоков" bl_space_type = "VIEW_3D" - bl_region_type = "TOOLS" + bl_region_type = getRegion() bl_category = "way Tools" #bl_context = "objectmode" @@ -471,7 +491,7 @@ class OBJECT_PT_way_misc_panel(Panel): bl_idname = "OBJECT_PT_way_misc_panel" bl_label = "О плагине" bl_space_type = "VIEW_3D" - bl_region_type = "TOOLS" + bl_region_type = getRegion() bl_category = "way Tools" #bl_context = "objectmode" @@ -484,14 +504,14 @@ def draw(self, context): scene = context.scene waytool = scene.way_tool - self.layout.label("Автор плагина: aleko2144") - self.layout.label("vk.com/rnr_mods") + self.layout.label(text="Автор плагина: aleko2144") + self.layout.label(text="vk.com/rnr_mods") class OBJECT_PT_blocks_panel(Panel): bl_idname = "OBJECT_PT_blocks_panel" bl_label = "Создание блоков" bl_space_type = "VIEW_3D" - bl_region_type = "TOOLS" + bl_region_type = getRegion() bl_category = "way Tools" #bl_context = "objectmode" @@ -529,7 +549,7 @@ def draw(self, context): def MsgBox(label = "", title = "Error", icon = 'ERROR'): def draw(self, context): - self.layout.label(label) + self.layout.label(text=label) bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) @@ -1071,21 +1091,17 @@ def forChild(object, root, file): class ImportSomeData(Operator, ExportHelper): """This appears in the tooltip of the operator and in the generated docs""" bl_idname = "import_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed - bl_label = "Import *.way" + bl_label = "Import WAY" # ExportHelper mixin class uses this - filename_ext = ".way" + filename_ext = '.way' - filter_glob = StringProperty( - default="*.way", - options={'HIDDEN'}, - maxlen=255, # Max internal buffer length, longer would be clamped. - ) + filter_glob : StringProperty(default='*.way',options={'HIDDEN'}) # Max internal buffer length, longer would be clamped. def execute(self, context): from . import import_way - with open(self.filepath, 'r') as file: - import_way.read(self.filepath, context) + with open(self.filepath, 'rb') as file: + import_way.read(file, context, self.filepath) return {'FINISHED'} class ExportSomeData(Operator, ExportHelper): @@ -1094,13 +1110,9 @@ class ExportSomeData(Operator, ExportHelper): bl_label = "Export *.way" # ExportHelper mixin class uses this - filename_ext = ".way" + filename_ext = '.way' - filter_glob = StringProperty( - default="*.way", - options={'HIDDEN'}, - maxlen=255, # Max internal buffer length, longer would be clamped. - ) + filter_glob : StringProperty(default='*.way', options={'HIDDEN'}) # Max internal buffer length, longer would be clamped. # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -1124,31 +1136,60 @@ def execute(self, context): # Only needed if you want to add into a dynamic menu def menu_func_export(self, context): - self.layout.operator(ExportSomeData.bl_idname, text="Export KOTR *.way") + self.layout.operator(ExportSomeData.bl_idname, text="KOTR WAY (.way") def menu_func_import(self, context): - self.layout.operator(ImportSomeData.bl_idname, text="Import KOTR *.way") + self.layout.operator(ImportSomeData.bl_idname, text="KOTR WAY (.way)") + +classes = ( + PanelSettings1, + AddOperator1, + SetValuesOperator1, + AddOperator11, + OBJECT_PT_way_add_panel, + GetValuesOperator1, + OBJECT_PT_way_edit_panel, + OBJECT_PT_way_misc_panel, + OBJECT_PT_blocks_panel, + ImportSomeData, + ExportSomeData +) + def register(): - bpy.utils.register_class(ExportSomeData) + for cls in classes: + bpy.utils.register_class(cls) bpy.types.TOPBAR_MT_file_export.append(menu_func_export) - - bpy.utils.register_class(ImportSomeData) bpy.types.TOPBAR_MT_file_import.append(menu_func_import) - - bpy.utils.register_module(__name__) - bpy.types.Scene.way_tool = PointerProperty(type=PanelSettings1) - + bpy.types.Scene.way_tool = bpy.props.PointerProperty(type=PanelSettings1) def unregister(): - bpy.utils.unregister_class(ExportSomeData) + del bpy.types.Scene.way_tool bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) - - bpy.utils.unregister_class(ImportSomeData) bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) + for cls in classes: + bpy.utils.unregister_class(cls) - bpy.utils.unregister_module(__name__) - del bpy.types.Scene.way_tool +# def register(): +# bpy.utils.register_class(ExportSomeData) +# bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + +# bpy.utils.register_class(ImportSomeData) +# bpy.types.TOPBAR_MT_file_import.append(menu_func_import) + +# bpy.utils.register_module(__name__) +# bpy.types.Scene.way_tool = PointerProperty(type=PanelSettings1) + + +# def unregister(): +# bpy.utils.unregister_class(ExportSomeData) +# bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) + +# bpy.utils.unregister_class(ImportSomeData) +# bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) + +# bpy.utils.unregister_module(__name__) +# del bpy.types.Scene.way_tool if __name__ == "__main__": diff --git a/src/2.80/addons/way_tools/import_way.py b/src/2.80/addons/way_tools/import_way.py index d0a25ee..cd9fe26 100644 --- a/src/2.80/addons/way_tools/import_way.py +++ b/src/2.80/addons/way_tools/import_way.py @@ -3,28 +3,33 @@ import os import sys -def readName(file): - text_len = 0 +def readName(file, text_len): + # text_len = 0 str_len = 0 - - text_len = struct.unpack(" 15): - str_len = 20 - - elif (11 < text_len < 15 or text_len == 15): - str_len = 16 - - elif (7 < text_len < 11 or text_len == 11): - str_len = 12 - - elif (3 < text_len < 7 or text_len == 7): - str_len = 8 - - elif (text_len < 3 or text_len == 3): - str_len = 4 - - string = file.read(str_len).decode("utf-8") + + rem = text_len % 4 + fill_len = (text_len + 4 - rem if rem else text_len) - text_len + + # if (text_len > 15): + # str_len = 20 + + # elif (11 < text_len < 15 or text_len == 15): + # str_len = 16 + + # elif (7 < text_len < 11 or text_len == 11): + # str_len = 12 + + # elif (3 < text_len < 7 or text_len == 7): + # str_len = 8 + + # elif (text_len < 3 or text_len == 3): + # str_len = 4 + + # string = file.read(str_len).decode("utf-8") + + string = file.read(text_len).decode("cp1251") + if fill_len > 0: + file.seek(fill_len, 1) return string def openclose(file, path): @@ -34,187 +39,195 @@ def openclose(file, path): else: return 2 print(str(os.path.getsize(path))) - -def read(file, context): - file_path = file - file = open(file, 'rb') - + +def read(file, context, filepath): + # file_path = file + # file = open(file, 'rb') + ex = 0 + rootName = os.path.basename(filepath) + rootObject = bpy.data.objects.new(rootName, None) + rootObject.location=(0,0,0) + context.collection.objects.link(rootObject) + while ex!=1: - ex = openclose(file, file_path) - if ex == 1: + ex = openclose(file, filepath) + if ex == 1: file.close() break elif ex == 2: type = file.read(4).decode("cp1251") - + global r - + if type == "WTWR": #WTWR - object_name = "way" - object = bpy.data.objects.new(object_name, None) - object.location=(0,0,0) - object['c_bytes_len'] = struct.unpack(" 0: + subtype = file.read(4).decode("cp1251") + subtypeSize = struct.unpack(" 0: + subtype = file.read(4).decode("cp1251") + subtypeSize = struct.unpack(" 0: + + cur_pos = object_matrix[3] + object = bpy.ops.mesh.primitive_ico_sphere_add(radius=0.2, calc_uvs=True, location=cur_pos) + object = bpy.context.selected_objects[0] + object.parent = r else: print("Unknown type: " + type + " on position " + str(file.tell())) #sys.exit() #except: #print(str(file.tell())) #print('error') - + return {'FINISHED'} - + def bak(): if type == "FLAG": object_name = type - object = bpy.data.objects.new(object_name, None) + object = bpy.data.objects.new(object_name, None) object.location=(0,0,0) object['flag'] = waytool.flag_int - bpy.context.scene.objects.link(object) - + bpy.context.collection.objects.link(object) + if type == "RNAM": object_name = type - object = bpy.data.objects.new(object_name, None) + object = bpy.data.objects.new(object_name, None) object.location=(0,0,0) object['str'] = waytool.name_string - bpy.context.scene.objects.link(object) - + bpy.context.collection.objects.link(object) + if type == "NNAM": object_name = type - object = bpy.data.objects.new(object_name, None) + object = bpy.data.objects.new(object_name, None) object.location=(0,0,0) object['str'] = waytool.name_string - bpy.context.scene.objects.link(object) - + bpy.context.collection.objects.link(object) + if type == "ORTN": - object = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) + object = bpy.ops.mesh.primitive_ico_sphere_add(radius=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) object = bpy.context.selected_objects[0] object.name = type object.location=cursor_pos1 - + if type == "POSN": - object = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) + object = bpy.ops.mesh.primitive_ico_sphere_add(radius=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) object = bpy.context.selected_objects[0] object.name =type object.location=cursor_pos1 From a6e751dfb96ad9d286cd35392392e124443949e8 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 17 Sep 2022 22:03:51 +0200 Subject: [PATCH 05/47] 8 block performance improved (bpy.ops) --- src/2.80/addons/importb3d/importb3d.py | 65 +++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index 5c63f29..0bf6413 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -2,6 +2,7 @@ from hashlib import new import struct import sys +import time import timeit import threading import pdb @@ -390,7 +391,8 @@ def read(file, context, op, filepath): type = struct.unpack(" 1: for texnum in texnums: @@ -631,7 +643,6 @@ def read(file, context, op, filepath): objString.append(b3dObj.name) - elif (type == 9 or type == 22): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) @@ -640,6 +651,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -654,6 +666,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -668,6 +681,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -682,6 +696,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -700,6 +715,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) @@ -722,6 +738,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -742,6 +759,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) @@ -764,6 +782,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -786,6 +805,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -812,6 +832,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) @@ -822,6 +843,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) childCnt = struct.unpack("i",file.read(4))[0] @@ -862,6 +884,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) elif (type == 21): #testkey??? @@ -873,6 +896,7 @@ def read(file, context, op, filepath): b3dObj.parent = context.scene.objects[objString[-1]] context.collection.objects.link(b3dObj) + realName = b3dObj.name objString.append(b3dObj.name) unknown1 = struct.unpack(" Date: Sun, 25 Sep 2022 18:24:24 +0200 Subject: [PATCH 06/47] improved 8 block + LOD detection --- src/2.80/addons/b3d_tools/__init__.py | 51 ++++++- src/2.80/addons/b3d_tools/common.py | 38 +++++- src/2.80/addons/importb3d/common.py | 29 ++++ src/2.80/addons/importb3d/importb3d.py | 182 ++++++++++--------------- 4 files changed, 186 insertions(+), 114 deletions(-) diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py index 8698170..c0dfcbd 100644 --- a/src/2.80/addons/b3d_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -30,7 +30,7 @@ def getRegion(): return "UI" import bpy -from .common import applyRemoveTransforms, applyTransforms, showHideObjByType, showHideObjTreeByType +from .common import applyRemoveTransforms, applyTransforms, showHideLOD, showHideObjByType, showHideObjTreeByType from bpy.props import (StringProperty, BoolProperty, @@ -1544,7 +1544,7 @@ def execute(self, context): scene = context.scene mytool = scene.my_tool - showHideObjTreeByType(10) + showHideLOD() return {'FINISHED'} @@ -1584,36 +1584,49 @@ def draw(self, context): object = bpy.context.selected_objects[i] + level_group = None + if 'block_type' in object: block_type = object['block_type'] else: block_type = None + if 'level_group' in object: + level_group = object['level_group'] + else: + level_group = None + lenStr = str(len(object.children)) if block_type == 0: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 1: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 2: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 3: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 4: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 5: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) if 'add_name' in object: layout.prop(mytool, "addBlockName1_string") layout.prop(mytool, "Radius1") @@ -1624,9 +1637,11 @@ def draw(self, context): elif block_type == 6: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 7: self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Группа блока: " + str(level_group)) if 'texNum' in object: layout.prop(mytool, "addBlockMeshType_enum") @@ -1648,13 +1663,16 @@ def draw(self, context): elif block_type == 8: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 9: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 10: self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Группа блока: " + str(level_group)) if 'node_radius' in object: layout.prop(mytool, "Radius1") layout.prop(mytool, "LOD_Distance1") @@ -1666,9 +1684,11 @@ def draw(self, context): elif block_type == 11: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 12: self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Группа блока: " + str(level_group)) if 'CType' in object: self.layout.label(text="Тип коллизии:") layout.prop(mytool, "CollisionType_enum", text="") @@ -1680,26 +1700,32 @@ def draw(self, context): elif block_type == 13: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 14: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 15: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 16: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 17: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 18: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) if 'add_name' in object: layout.prop(mytool, "Radius1") layout.prop(mytool, "addBlockName1_string") @@ -1711,14 +1737,17 @@ def draw(self, context): elif block_type == 19: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 20: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 21: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + str(len(object.children)-object['groups_num']+1)) + self.layout.label(text="Группа блока: " + str(level_group)) if 'groups_num' in object: layout.prop(mytool, "groupsNum1_int") layout.prop(mytool, "Radius1") @@ -1729,6 +1758,7 @@ def draw(self, context): elif block_type == 23: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) if 'CType' in object: self.layout.label(text="Тип коллизии:") layout.prop(mytool, "CollisionType_enum", text="") @@ -1739,6 +1769,7 @@ def draw(self, context): elif block_type == 24: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) if 'flag' in object: layout.prop(mytool, "add24Flag_enum1", text="") else: @@ -1747,6 +1778,7 @@ def draw(self, context): elif block_type == 25: self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Группа блока: " + str(level_group)) if 'RSound' in object: layout.prop(mytool, "addSoundName1_string") layout.prop(mytool, "RSound1") @@ -1758,13 +1790,16 @@ def draw(self, context): elif block_type == 26: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 27: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 28: self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Группа блока: " + str(level_group)) if 'sprite_radius' in object: layout.prop(mytool, "Radius1") layout.prop(mytool, "T28_radius1") @@ -1776,21 +1811,26 @@ def draw(self, context): elif block_type == 29: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 30: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 31: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 32: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 33: self.layout.label(text="Тип блока: " + str(block_type)) + self.layout.label(text="Группа блока: " + str(level_group)) layout.prop(mytool, "Radius1") layout.prop(mytool, "LType_enum") layout.prop(mytool, "RadiusLight1") @@ -1802,18 +1842,22 @@ def draw(self, context): elif block_type == 34: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 35: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 36: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 37: self.layout.label(text="Тип блока: " + str(block_type)) #self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) if 'texNum' in object: layout.prop(mytool, "addBlockMeshType_enum") @@ -1840,14 +1884,17 @@ def draw(self, context): elif block_type == 38: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 39: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Количество вложенных блоков: " + lenStr) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 40: self.layout.label(text="Тип блока: " + str(block_type)) self.layout.label(text="Тип генератора: " + object['GType']) + self.layout.label(text="Группа блока: " + str(level_group)) elif block_type == 444: self.layout.label(text="Тип объекта - разделитель") diff --git a/src/2.80/addons/b3d_tools/common.py b/src/2.80/addons/b3d_tools/common.py index 027d5e0..3bb509a 100644 --- a/src/2.80/addons/b3d_tools/common.py +++ b/src/2.80/addons/b3d_tools/common.py @@ -1,3 +1,4 @@ +import math import bpy import logging import sys @@ -20,6 +21,15 @@ def getAllChildren(obj): break return allChildren +def getLODObjects(obj): + vertObjs = [cn for cn in obj.children if (cn.get("block_type") is not None and (cn["block_type"]==6 or cn["block_type"]==7 or cn["block_type"]==36 or cn["block_type"]==37)) and (cn.get("level_group") is not None and (cn["level_group"]==1))] + if len(vertObjs) == 0: + vertObjs = [cn for cn in obj.children if (cn.get("block_type") is not None and (cn["block_type"]==8 or cn["block_type"]==35)) and (cn.get("level_group") is not None and (cn["level_group"]==1))] + # vertObjs.sort(key=lambda x: x.name, reverse=True) + # lodCnt = math.floor(len(vertObjs) / 2) + # return vertObjs[0:lodCnt] + return vertObjs + def applyTransform(block_18): @@ -124,7 +134,7 @@ def applyTransforms(): def showHideObjByType(type): objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] - if objs == hiddenObj: + if len(objs) == len(hiddenObj): for obj in objs: obj.hide_set(False) else: @@ -134,7 +144,7 @@ def showHideObjByType(type): def showHideObjTreeByType(type): objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] - if objs == hiddenObj: + if len(objs) == len(hiddenObj): for obj in objs: children = getAllChildren(obj) for child in children: @@ -145,4 +155,26 @@ def showHideObjTreeByType(type): children = getAllChildren(obj) for child in children: child.hide_set(True) - obj.hide_set(True) \ No newline at end of file + obj.hide_set(True) + +def showHideLOD(): + lodRoots = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==10] + hiddenLodRoots = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==10 and cn.hide_get()] + if len(hiddenLodRoots) > 0: #show + for lodRoot in lodRoots: + lods = getLODObjects(lodRoot) + if len(lods) > 0: + lodRoot.hide_set(False) + for lod in lods: + lod.hide_set(False) + for obj in getAllChildren(lod): + obj.hide_set(False) + else: #hide + for lodRoot in lodRoots: + lods = getLODObjects(lodRoot) + if len(lods) > 0: + lodRoot.hide_set(True) + for lod in lods: + lod.hide_set(True) + for obj in getAllChildren(lod): + obj.hide_set(True) \ No newline at end of file diff --git a/src/2.80/addons/importb3d/common.py b/src/2.80/addons/importb3d/common.py index 50a9827..5471eca 100644 --- a/src/2.80/addons/importb3d/common.py +++ b/src/2.80/addons/importb3d/common.py @@ -169,3 +169,32 @@ def srgb_to_linearrgb(c): def hex_to_rgb(r,g,b,alpha=1): return tuple([srgb_to_linearrgb(c/0xff) for c in (r,g,b)] + [alpha]) + +def getUsedVerticesAndTransform(vertices, faces): + indices = set() + idxTransf = {} + newVertexes = [] + newFaces = [] + for face in faces: + for idx in face: + indices.add(idx) + indices = sorted(indices) + for idx in indices: + idxTransf[idx] = len(newVertexes) + newVertexes.append(vertices[idx]) + newFaces = getUsedFaces(faces, idxTransf) + + return [newVertexes, newFaces, idxTransf] + +def getUsedFaces(faces, idxTransf): + newFaces = [] + for face in faces: + newFace = getUsedFace(face, idxTransf) + newFaces.append(tuple(newFace)) + return newFaces + +def getUsedFace(face, idxTransf): + newFace = [] + for idx in face: + newFace.append(idxTransf[idx]) + return newFace \ No newline at end of file diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index 0bf6413..bff2f8e 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -10,7 +10,7 @@ from pathlib import Path from .imghelp import TXRtoTGA32 from .imghelp import parsePLM -from .common import ShowMessageBox, Vector3F, createMaterial, parseMaterials, readCString, RESUnpack +from .common import ShowMessageBox, Vector3F, createMaterial, getUsedFaces, getUsedFace, getUsedVerticesAndTransform, parseMaterials, readCString, RESUnpack import bpy import mathutils @@ -268,11 +268,11 @@ def read(file, context, op, filepath): # RESUnpacked = unpackRES(resPath, basename) #2. Распаковка .RES и конвертация .txr и .msk в .tga 32bit - txrFolder = os.path.join(texturePath, "txr") - folder_content = os.listdir(txrFolder) + # txrFolder = os.path.join(texturePath, "txr") + folder_content = os.listdir(texturePath) reTXR = re.compile(r'\.txr') for path in folder_content: - fullpath = os.path.join(txrFolder, path) + fullpath = os.path.join(texturePath, path) if reTXR.search(path): TXRtoTGA32(fullpath) @@ -357,6 +357,7 @@ def read(file, context, op, filepath): i = 0 lvl = 0 cnt = 0 + levelGroups = [] coords25 = [] coords23 = [] vertexes = [] @@ -379,14 +380,24 @@ def read(file, context, op, filepath): ex = openclose(file) if ex == ChunkType.END_CHUNK: del objString[-1] + levelGroups[lvl] = 0 lvl-=1 elif ex == ChunkType.END_CHUNKS: file.close() break elif ex == ChunkType.GROUP_CHUNK: + if len(levelGroups) <= lvl: + for i in range(lvl+1-len(levelGroups)): + levelGroups.append(0) + levelGroups[lvl] +=1 continue elif ex == ChunkType.BEGIN_CHUNK: lvl+=1 + if len(levelGroups) <= lvl: + for i in range(lvl+1-len(levelGroups)): + levelGroups.append(0) + + t1 = time.perf_counter() onlyName = readName(file) type = struct.unpack(" 1: for texnum in texnums: @@ -635,7 +656,8 @@ def read(file, context, op, filepath): lastIndex = len(b3dMesh.materials)-1 for vertArr in texnums[texnum]: - assignMaterialByVertices(b3dObj, vertArr, lastIndex) + newVertArr = getUsedFace(vertArr, idxTransf) + assignMaterialByVertices(b3dObj, newVertArr, lastIndex) else: for texnum in texnums: mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] @@ -647,6 +669,7 @@ def read(file, context, op, filepath): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -662,6 +685,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -677,6 +701,7 @@ def read(file, context, op, filepath): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -692,6 +717,7 @@ def read(file, context, op, filepath): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -711,6 +737,7 @@ def read(file, context, op, filepath): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -734,6 +761,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -755,6 +783,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -778,6 +807,7 @@ def read(file, context, op, filepath): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -801,6 +831,7 @@ def read(file, context, op, filepath): cnt+=1 b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -826,6 +857,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj['space_name'] = file.read(32).decode("utf-8").rstrip('\0') b3dObj['add_name'] = file.read(32).decode("utf-8").rstrip('\0') @@ -839,6 +871,7 @@ def read(file, context, op, filepath): elif (type == 19): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -880,6 +913,7 @@ def read(file, context, op, filepath): b3dObj.location = (0,0,0) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -892,6 +926,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -910,6 +945,7 @@ def read(file, context, op, filepath): b3dMesh = (bpy.data.meshes.new(objName)) b3dObj = bpy.data.objects.new(objName, b3dMesh) b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(file.tell()) b3dObj.parent = context.scene.objects[objString[-1]] @@ -927,7 +963,7 @@ def read(file, context, op, filepath): vertsBlockNum = struct.unpack(" 0: - f = struct.unpack("<"+num0+"f",file.read(4*num0)) + f = struct.unpack("<"+str(num0)+"f",file.read(4*num0)) childCnt = struct.unpack(" Date: Mon, 26 Sep 2022 05:48:55 +0200 Subject: [PATCH 07/47] Multiple b3d import --- src/2.80/addons/importb3d/__init__.py | 77 +++++++++++++++++++++++--- src/2.80/addons/importb3d/common.py | 7 +-- src/2.80/addons/importb3d/importb3d.py | 19 ++++--- 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/src/2.80/addons/importb3d/__init__.py b/src/2.80/addons/importb3d/__init__.py index 711b425..16a577c 100644 --- a/src/2.80/addons/importb3d/__init__.py +++ b/src/2.80/addons/importb3d/__init__.py @@ -49,13 +49,25 @@ imghelp, ) +from threading import Lock, Thread import time import datetime +import os import bpy -from bpy.props import StringProperty, BoolProperty +from bpy.props import StringProperty, BoolProperty, CollectionProperty from bpy_extras.io_utils import ImportHelper, ExportHelper # from . import common, exportb3d, imghelp, importb3d +def thread_import_b3d(self, files, context): + for b3dfile in files: + filepath = os.path.join(self.directory, b3dfile.name) + + print('Importing file', filepath) + t = time.mktime(datetime.datetime.now().timetuple()) + with open(filepath, 'rb') as file: + importb3d.read(file, context, self, filepath) + t = time.mktime(datetime.datetime.now().timetuple()) - t + print('Finished importing in', t, 'seconds') class HTImportPreferences(bpy.types.AddonPreferences): bl_idname = __package__ @@ -77,6 +89,14 @@ class ImportB3D(bpy.types.Operator, ImportHelper): bl_label = 'Import B3D' filename_ext = '.b3d' + + files: CollectionProperty( + type=bpy.types.OperatorFileListElement, + options={'HIDDEN', 'SKIP_SAVE'}, + ) + + directory: StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'}) + filter_glob : StringProperty(default='*.b3d', options={'HIDDEN'}) to_unpack_res : BoolProperty(name='Unpack .res archive', @@ -94,16 +114,57 @@ class ImportB3D(bpy.types.Operator, ImportHelper): default="tga", ) + def thread_import_b3d(self, files, context): + for b3dfile in files: + filepath = os.path.join(self.directory, b3dfile.name) + + print('Importing file', filepath) + t = time.mktime(datetime.datetime.now().timetuple()) + with open(filepath, 'rb') as file: + importb3d.read(file, context, self, filepath) + t = time.mktime(datetime.datetime.now().timetuple()) - t + print('Finished importing in', t, 'seconds') + + lock = Lock() + def execute(self, context): - from . import importb3d - print('Importing file', self.filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - with open(self.filepath, 'rb') as file: - importb3d.read(file, context, self, self.filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - t - print('Finished importing in', t, 'seconds') + # from . import importb3d + # t1 = None + # t2 = None + + evens = [cn for i,cn in enumerate(self.files) if i%2==0] + odds = [cn for i,cn in enumerate(self.files) if i%2==1] + + + t1 = Thread(target=thread_import_b3d, args=(self, evens, context)) + t2 = Thread(target=thread_import_b3d, args=(self, odds, context)) + + tt = time.mktime(datetime.datetime.now().timetuple()) + + t1.start() + t2.start() + + t1.join() + t2.join() + + # for b3dfile in self.files: + # filepath = os.path.join(self.directory, b3dfile.name) + + # print('Importing file', filepath) + # t = time.mktime(datetime.datetime.now().timetuple()) + # with open(filepath, 'rb') as file: + # importb3d.read(file, context, self, filepath) + # t = time.mktime(datetime.datetime.now().timetuple()) - t + # print('Finished importing in', t, 'seconds') + + + tt = time.mktime(datetime.datetime.now().timetuple()) - tt + print('All imported in', tt, 'seconds') + return {'FINISHED'} + + class ImportWayTxt(bpy.types.Operator, ImportHelper): '''Import from txt file format (.txt)''' bl_idname = 'import_scene.kotr_way_txt' diff --git a/src/2.80/addons/importb3d/common.py b/src/2.80/addons/importb3d/common.py index 5471eca..82d94ec 100644 --- a/src/2.80/addons/importb3d/common.py +++ b/src/2.80/addons/importb3d/common.py @@ -1,4 +1,3 @@ -from asyncio.windows_events import NULL import os import struct import bpy @@ -76,13 +75,13 @@ def __init__(self): class Vector3F(): - def __init__(self, file=NULL, tuple=NULL): - if file != NULL: + def __init__(self, file=None, tuple=None): + if file != None: tpl = struct.unpack("<3f", file.read(12)) self.x = tpl[0] self.y = tpl[1] self.z = tpl[2] - elif tuple != NULL: + elif tuple != None: self.x = tuple[0] self.y = tuple[1] self.z = tuple[2] diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index bff2f8e..63928a5 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -16,6 +16,7 @@ import mathutils import os.path import os +from threading import Lock from bpy.props import * from bpy_extras.image_utils import load_image from ast import literal_eval as make_tuple @@ -242,9 +243,9 @@ def read(file, context, op, filepath): RESUnpacked = unpackRES(resPath, basename, False) if op.to_import_textures and not os.path.exists(commonResPath): - ShowMessageBox("Common.res path is wrong or is not set. Textures weren't imported! Please, set path to Common.res in addon preferences.", - "COMMON.res wrong path", - "ERROR") + # ShowMessageBox("Common.res path is wrong or is not set. Textures weren't imported! Please, set path to Common.res in addon preferences.", + # "COMMON.res wrong path", + # "ERROR") op.to_import_textures = False if op.to_import_textures and os.path.exists(commonResPath): @@ -367,7 +368,7 @@ def read(file, context, op, filepath): b3dObj = 0 uv = [] - b3dName = os.path.basename(op.properties.filepath) + b3dName = os.path.basename(filepath) b3dObj = bpy.data.objects.new(b3dName,None) b3dObj['block_type'] = 0 @@ -657,7 +658,9 @@ def read(file, context, op, filepath): for vertArr in texnums[texnum]: newVertArr = getUsedFace(vertArr, idxTransf) + # op.lock.acquire() assignMaterialByVertices(b3dObj, newVertArr, lastIndex) + # op.lock.release() else: for texnum in texnums: mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] @@ -1772,9 +1775,9 @@ def assignMaterialByVertices(obj, vertIndexes, matIndex): # bpy.ops.mesh.select_mode(type= 'VERT') # bpy.ops.mesh.select_all(action = 'DESELECT') # bpy.ops.object.mode_set(mode = 'OBJECT') - vert = bpy.context.object.data.vertices - face = bpy.context.object.data.polygons - edge = bpy.context.object.data.edges + vert = obj.data.vertices + face = obj.data.polygons + edge = obj.data.edges for i in face: i.select=False for i in edge: @@ -1789,7 +1792,7 @@ def assignMaterialByVertices(obj, vertIndexes, matIndex): poly.material_index = matIndex def getPolygonsBySelectedVertices(): - data = bpy.context.object.data + data = bpy.context.view_layer.objects.active.data selectedPolygons = [] for f in data.polygons: s = True From 38f3a3960191de2dc72f31f779effb94a50e74bf Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Tue, 27 Sep 2022 00:04:51 +0200 Subject: [PATCH 08/47] fixed triangulation --- src/2.80/addons/importb3d/common.py | 24 +++++- src/2.80/addons/importb3d/importb3d.py | 109 +++++++++++++++++++------ 2 files changed, 103 insertions(+), 30 deletions(-) diff --git a/src/2.80/addons/importb3d/common.py b/src/2.80/addons/importb3d/common.py index 82d94ec..ac05f6b 100644 --- a/src/2.80/addons/importb3d/common.py +++ b/src/2.80/addons/importb3d/common.py @@ -171,7 +171,8 @@ def hex_to_rgb(r,g,b,alpha=1): def getUsedVerticesAndTransform(vertices, faces): indices = set() - idxTransf = {} + oldNewTransf = {} + newOldTransf = {} newVertexes = [] newFaces = [] for face in faces: @@ -179,11 +180,18 @@ def getUsedVerticesAndTransform(vertices, faces): indices.add(idx) indices = sorted(indices) for idx in indices: - idxTransf[idx] = len(newVertexes) + oldNewTransf[idx] = len(newVertexes) + newOldTransf[len(newVertexes)] = idx newVertexes.append(vertices[idx]) - newFaces = getUsedFaces(faces, idxTransf) + newFaces = getUsedFaces(faces, oldNewTransf) - return [newVertexes, newFaces, idxTransf] + return [newVertexes, newFaces, indices, oldNewTransf, newOldTransf] + +def transformVertices(vertices, idxTransf): + newVertices = [] + for idx in vertices: + newVertices.append(idxTransf[idx]) + return newVertices def getUsedFaces(faces, idxTransf): newFaces = [] @@ -192,6 +200,14 @@ def getUsedFaces(faces, idxTransf): newFaces.append(tuple(newFace)) return newFaces +def getUserVertices(faces): + indices = set() + for face in faces: + for idx in face: + indices.add(idx) + return list(indices) + + def getUsedFace(face, idxTransf): newFace = [] for idx in face: diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index 63928a5..11e49b3 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -10,7 +10,7 @@ from pathlib import Path from .imghelp import TXRtoTGA32 from .imghelp import parsePLM -from .common import ShowMessageBox, Vector3F, createMaterial, getUsedFaces, getUsedFace, getUsedVerticesAndTransform, parseMaterials, readCString, RESUnpack +from .common import ShowMessageBox, Vector3F, createMaterial, getUsedFaces, getUsedFace, getUsedVerticesAndTransform, getUserVertices, parseMaterials, readCString, RESUnpack, transformVertices import bpy import mathutils @@ -363,6 +363,7 @@ def read(file, context, op, filepath): coords23 = [] vertexes = [] normals = [] + formats = [] format = 0 # b3dObj = 0 @@ -525,6 +526,7 @@ def read(file, context, op, filepath): format = 0 coords25 = [] vertexes = [] + normals = [] uv = [] cnt+=1 b3dObj = bpy.data.objects.new(objName, None) @@ -551,6 +553,8 @@ def read(file, context, op, filepath): faces = [] faces_all = [] uvs = [] + # normals = [] + intencities = [] texnums = {} cnt+=1 b3dObj @@ -588,9 +592,14 @@ def read(file, context, op, filepath): if format & 0b10000: if format & 0b1: if format & 0b100000: - normals1 = struct.unpack("<3f",file.read(12)) + intens = struct.unpack("<3f",file.read(12)) + intencities.append(intens) elif format & 0b100000: - intencity = struct.unpack(" 0: + b3dMesh.use_auto_smooth = True + normalList = [] + for i,vert in enumerate(b3dMesh.vertices): + normalList.append(normals[newOldTransf[i]]) + # b3dMesh.vertices[idx].normal = normals[idx] + log.debug(normalList) + b3dMesh.normals_split_custom_set_from_vertices(normalList) + #Setup UV customUV = b3dMesh.uv_layers.new() customUV.name = "UVmap" @@ -657,7 +684,7 @@ def read(file, context, op, filepath): lastIndex = len(b3dMesh.materials)-1 for vertArr in texnums[texnum]: - newVertArr = getUsedFace(vertArr, idxTransf) + newVertArr = getUsedFace(vertArr, oldNewTransf) # op.lock.acquire() assignMaterialByVertices(b3dObj, newVertArr, lastIndex) # op.lock.release() @@ -974,7 +1001,8 @@ def read(file, context, op, filepath): faces.append([num+1,num+2,num+0]) num+=3 elif(vertsInBlock ==4): - faces.append([num+1,num+2,num+0,num+2,num+3,num+1]) + # faces.append([num+1,num+2,num+0,num+2,num+3,num+1]) + faces.append([num+0,num+1,num+2,num+3]) num+=4 for j in range(vertsInBlock): @@ -1388,18 +1416,19 @@ def read(file, context, op, filepath): # qu = quat(file).v faces_all = [] faces = [] - - # todo: 444 razdelitelj HIGHRES ot LOWRES + formats = [] mType = struct.unpack("> 8) & 0xF0 #ah triangulateOffset = format & 0b10000000 @@ -1420,14 +1449,19 @@ def read(file, context, op, filepath): if format & 0b10000: if format & 0b1: if format & 0b100000: - normals1 = struct.unpack("<3f",file.read(12)) + intens = struct.unpack("<3f",file.read(12)) + intencities.append(intens) elif format & 0b100000: - intencity = struct.unpack(" 0: + b3dMesh.use_auto_smooth = True + normalList = [] + for i,vert in enumerate(b3dMesh.vertices): + normalList.append(normals[newOldTransf[i]]) + # b3dMesh.vertices[idx].normal = normals[idx] + # log.debug(normalList) + b3dMesh.normals_split_custom_set_from_vertices(normalList) + + # if len(normals) > 0: + # for i,idx in enumerate(newIndices): + # b3dMesh.vertices[idx].normal = normals[idx] customUV = b3dMesh.uv_layers.new() customUV.name = "UVmap" @@ -1503,15 +1553,19 @@ def read(file, context, op, filepath): pass else: for i in range(vertexCount): - vertexes.append(struct.unpack("<3f",file.read(12))) - uv.append(struct.unpack("<2f",file.read(8))) - for j in range(uvCount): - u = struct.unpack(" Date: Wed, 28 Sep 2022 20:57:21 +0200 Subject: [PATCH 09/47] .raw import --- src/2.80/addons/importb3d/__init__.py | 30 ++++++++++++ src/2.80/addons/importb3d/imghelp.py | 2 - src/2.80/addons/importb3d/importb3d.py | 64 +++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/2.80/addons/importb3d/__init__.py b/src/2.80/addons/importb3d/__init__.py index 16a577c..23a5758 100644 --- a/src/2.80/addons/importb3d/__init__.py +++ b/src/2.80/addons/importb3d/__init__.py @@ -82,6 +82,34 @@ def draw(self, context): row = layout.row() row.prop(self, 'COMMON_RES_Path', expand=True) +class ImportRAW(bpy.types.Operator, ImportHelper): + '''Import from RAW file format (.raw)''' + bl_idname = 'import_scene.kotr_raw' + bl_label = 'Import RAW' + + filename_ext = '.raw' + + files: CollectionProperty( + type=bpy.types.OperatorFileListElement, + options={'HIDDEN', 'SKIP_SAVE'}, + ) + filter_glob : StringProperty(default='*.raw', options={'HIDDEN'}) + + directory: StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'}) + + def execute(self, context): + for rawfile in self.files: + filepath = os.path.join(self.directory, rawfile.name) + + print('Importing file', filepath) + t = time.mktime(datetime.datetime.now().timetuple()) + with open(filepath, 'rb') as file: + importb3d.parseRAW(file, context, self, filepath) + t = time.mktime(datetime.datetime.now().timetuple()) - t + print('Finished importing in', t, 'seconds') + + return {'FINISHED'} + class ImportB3D(bpy.types.Operator, ImportHelper): '''Import from B3D file format (.b3d)''' @@ -216,6 +244,7 @@ def execute(self, context): def menu_func_import(self, context): + self.layout.operator(ImportRAW.bl_idname, text='KOTR RAW (.raw)') self.layout.operator(ImportB3D.bl_idname, text='KOTR B3D (.b3d)') self.layout.operator(ImportWayTxt.bl_idname, text='KOTR WAY (.txt)') @@ -226,6 +255,7 @@ def menu_func_export(self, context): classes = ( HTImportPreferences, ImportB3D, + ImportRAW, ImportWayTxt, ExportB3D ) diff --git a/src/2.80/addons/importb3d/imghelp.py b/src/2.80/addons/importb3d/imghelp.py index 5a7de9a..dbc93b5 100644 --- a/src/2.80/addons/importb3d/imghelp.py +++ b/src/2.80/addons/importb3d/imghelp.py @@ -95,13 +95,11 @@ def TXR565toTGA8888(filepath): footerIdentifier = txrFile.read(4) footerSize = struct.unpack(" Date: Fri, 7 Oct 2022 19:25:18 +0200 Subject: [PATCH 10/47] block_to_import select --- src/2.80/addons/importb3d/__init__.py | 73 ++- src/2.80/addons/importb3d/importb3d.py | 793 +++++++++++-------------- 2 files changed, 421 insertions(+), 445 deletions(-) diff --git a/src/2.80/addons/importb3d/__init__.py b/src/2.80/addons/importb3d/__init__.py index 23a5758..4ce3c8a 100644 --- a/src/2.80/addons/importb3d/__init__.py +++ b/src/2.80/addons/importb3d/__init__.py @@ -49,12 +49,13 @@ imghelp, ) +import math from threading import Lock, Thread import time import datetime import os import bpy -from bpy.props import StringProperty, BoolProperty, CollectionProperty +from bpy.props import StringProperty, EnumProperty, BoolProperty, CollectionProperty from bpy_extras.io_utils import ImportHelper, ExportHelper # from . import common, exportb3d, imghelp, importb3d @@ -110,6 +111,18 @@ def execute(self, context): return {'FINISHED'} +class ActiveBlock(bpy.types.PropertyGroup): + name: StringProperty() + state : BoolProperty() + +# def initBlocksArray(): + # blocks = [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] + # result = CollectionProperty(type=ActiveBlock) + # for i, block in enumerate(blocks): + # item = result.add() + # item.index = str(block) + # item.active = False +# return result class ImportB3D(bpy.types.Operator, ImportHelper): '''Import from B3D file format (.b3d)''' @@ -142,6 +155,28 @@ class ImportB3D(bpy.types.Operator, ImportHelper): default="tga", ) + + blocks_to_import: CollectionProperty(type=ActiveBlock) + + def invoke(self, context, event): + wm = context.window_manager + + self.blocks_to_import.clear() + + blocks = [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] + for i, block in enumerate(blocks): + item = self.blocks_to_import.add() + item.name = str(block) + item.state = False + + wm.fileselect_add(self) + return {"RUNNING_MODAL"} + + def thread_import_b3d(self, files, context): for b3dfile in files: filepath = os.path.join(self.directory, b3dfile.name) @@ -153,13 +188,34 @@ def thread_import_b3d(self, files, context): t = time.mktime(datetime.datetime.now().timetuple()) - t print('Finished importing in', t, 'seconds') - lock = Lock() + def draw_import_config(self, context): + # --- Import Options --- # + layout = self.layout - def execute(self, context): - # from . import importb3d - # t1 = None - # t2 = None + layout.label(text="Main settings:") + box1 = layout.box() + row = box1.row() + row.prop(self, 'to_unpack_res') + row = box1.row() + row.prop(self, 'to_import_textures') + row = box1.row() + row.prop(self, 'textures_format') + + layout.label(text="Blocks to import:") + box1 = layout.box() + i = 0 + perRow = 8 + rowcnt = math.floor(len(self.blocks_to_import)/perRow) + for j in range(rowcnt): + row = box1.row() + for block in self.blocks_to_import[i:i+perRow]: + row.prop(block, 'state', text=block['name'], toggle=True) + i+=perRow + row = box1.row() + for block in self.blocks_to_import[i:]: + row.prop(block, 'state', text=block['name'], toggle=True) + def execute(self, context): evens = [cn for i,cn in enumerate(self.files) if i%2==0] odds = [cn for i,cn in enumerate(self.files) if i%2==1] @@ -191,6 +247,9 @@ def execute(self, context): return {'FINISHED'} + def draw(self, context): + self.draw_import_config(context) + class ImportWayTxt(bpy.types.Operator, ImportHelper): @@ -267,6 +326,7 @@ def register(): # import importlib # for cls in classes: # importlib.reload(cls) + bpy.utils.register_class(ActiveBlock) for cls in classes: bpy.utils.register_class(cls) bpy.types.TOPBAR_MT_file_import.append(menu_func_import) @@ -279,6 +339,7 @@ def unregister(): bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) for cls in classes: bpy.utils.unregister_class(cls) + bpy.utils.unregister_class(ActiveBlock) if __name__ == "__main__": diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index 08e1003..61028f2 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -58,7 +58,7 @@ def readName(file): objName = file.read(32) if (objName[0] == 0): objName = "empty name" - #objname = "Untitled_0x" + str(hex(file.tell()-36)) + #objname = "Untitled_0x" + str(hex(pos-36)) else: objName = (objName.decode("cp1251").rstrip('\0')) return objName @@ -299,6 +299,12 @@ def read(file, context, op, filepath): resPath = os.path.join(noextPath + ".res") # commonPath = os.path.join(bpy.context.preferences.addons['importb3d'].preferences.COMMON_RES_Path, r"COMMON") + blocksToImport = op.blocks_to_import + + usedBlocks = {} + for block in blocksToImport: + usedBlocks[block.name] = block.state + RESUnpacked = None if op.to_unpack_res: RESUnpacked = unpackRES(resPath, basename, True) @@ -355,64 +361,6 @@ def read(file, context, op, filepath): SNImg = file.read(32).decode("utf-8").rstrip('\0') #читаю имя material_list.append(SNImg) - # if (search_tex_names == True): - # if (material_textures[i][0] == "("): - # PImg = (material_textures[i]) - # elif (material_textures[i][0] == "["): - # PImg = ("(255, 255, 255)") - # else: - # PImg = (filepath.rsplit('\\',1)[0] + "\\" + material_textures[i] + "." + textures_format) - # else: - # PImg = (filepath.rsplit('\\',1)[0] +'\\txr\\' +SNImg + "." + textures_format) - - - # if (search_tex_names == True): - # if os.path.isfile(PImg): - # img = bpy.data.images.load(PImg) - # else: - # img = bpy.data.images.new(SNImg,1,1) - # if (material_textures[i][0] == "("): - # PImg = (material_textures[i]) - # R = (float((PImg[1:-1].split(", "))[0])) / 255 - # G = (float((PImg[1:-1].split(", "))[1])) / 255 - # B = (float((PImg[1:-1].split(", "))[2])) / 255 - # img.pixels = (B, G, R, 1.0) - # img.filepath_raw = (filepath.rsplit('\\',1)[0] + tex_path + "\\" + SNImg + "." + textures_format) - # img.file_format = textures_format.upper() - # img.save() - # else: - # if os.path.isfile(PImg): - # img = bpy.data.images.load(PImg) - # else: - # PImg = (filepath.rsplit('\\',1)[0] +'\\txr\\' +SNImg[4:]+'.tga') #полный путь - # if os.path.isfile(PImg): - # img = bpy.data.images.load(PImg) - # else: - # img = bpy.data.images.new(SNImg,1,1) - - #if (search_tex_names == False): - # PImg = (filepath.rsplit('\\',1)[0] +'\\txr\\' +SNImg+'.tga') #полный путь ##################################################################### - #PImg = (filepath.rsplit('\\',1)[0] +'\\txr\\' +SNImg[4:]+'.tga') - #? - #if os.path.isfile(PImg): - # img = bpy.data.images.load(PImg) - #else: - # img = bpy.data.images.new(SNImg,1,1)#bpy.data.images.new(SNImg,1,1) - # Imgs.append(img) - - - # tex = bpy.data.textures.new(SNImg,'IMAGE') - # tex.use_preview_alpha = True - # tex.image = img #bpy.data.images[i] - # # todo: replace with solution: - # # https://blender.stackexchange.com/questions/118646/add-a-texture-to-an-object-using-python-and-blender-2-8 - # # mat = bpy.data.materials.new(SNImg) - # # mat.texture_slots.add() - # # mat.texture_slots[0].uv_layer = 'UVmap' - # # mat.texture_slots[0].texture = tex - # # mat.texture_slots[0].use_map_alpha = True - # # math.append(mat) - file.seek(4,1) #Skip Begin_Chunks(111) # Processing vertices @@ -429,7 +377,6 @@ def read(file, context, op, filepath): formats = [] format = 0 # - b3dObj = 0 uv = [] b3dName = os.path.basename(filepath) @@ -463,117 +410,116 @@ def read(file, context, op, filepath): levelGroups.append(0) t1 = time.perf_counter() + objString.append(objString[-1]) onlyName = readName(file) type = struct.unpack("0: pass - elif (type == 14): #sell_ ? + if not usedBlocks[str(type)]: + continue b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] - b3dObj['pos'] = str(file.tell()) + b3dObj['pos'] = str(pos) - b3dObj.parent = context.scene.objects[objString[-1]] + b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name - objString.append(b3dObj.name) + objString[len(objString)-1] = b3dObj.name + elif (type == 14): #sell_ ? bounding_sphere = struct.unpack("<4f",file.read(16)) unknown_sphere = struct.unpack("<4f",file.read(16)) @@ -871,17 +837,21 @@ def read(file, context, op, filepath): for i in range(cnt): coords.append(struct.unpack("f",file.read(4))[0]) - elif (type == 15): + if not usedBlocks[str(type)]: + continue b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] - b3dObj['pos'] = str(file.tell()) + b3dObj['pos'] = str(pos) - b3dObj.parent = context.scene.objects[objString[-1]] + b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name - objString.append(b3dObj.name) + objString[len(objString)-1] = b3dObj.name + + elif (type == 15): + bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -895,17 +865,20 @@ def read(file, context, op, filepath): if cnt>0: pass - elif (type == 16): - cnt+=1 + if not usedBlocks[str(type)]: + continue + b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] - b3dObj['pos'] = str(file.tell()) + b3dObj['pos'] = str(pos) - b3dObj.parent = context.scene.objects[objString[-1]] + b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name - objString.append(b3dObj.name) + objString[len(objString)-1] = b3dObj.name + + elif (type == 16): bounding_sphere = struct.unpack("<4f",file.read(16)) vector1 = struct.unpack("<3f",file.read(12)) @@ -919,17 +892,21 @@ def read(file, context, op, filepath): for i in range(cnt): coords.append(struct.unpack("f",file.read(4))[0]) - elif (type == 17): - cnt+=1 + if not usedBlocks[str(type)]: + continue + b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] - b3dObj['pos'] = str(file.tell()) + b3dObj['pos'] = str(pos) - b3dObj.parent = context.scene.objects[objString[-1]] + b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name - objString.append(b3dObj.name) + objString[len(objString)-1] = b3dObj.name + + elif (type == 17): + bounding_sphere = struct.unpack("<4f",file.read(16)) vector1 = struct.unpack("<3f",file.read(12)) @@ -943,35 +920,60 @@ def read(file, context, op, filepath): for i in range(cnt): coords.append(struct.unpack("f",file.read(4))[0]) + if not usedBlocks[str(type)]: + continue + + b3dObj = bpy.data.objects.new(objName, None) + b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['pos'] = str(pos) + + b3dObj.parent = context.scene.objects[objString[-2]] + context.collection.objects.link(b3dObj) + realName = b3dObj.name + objString[len(objString)-1] = b3dObj.name + elif (type == 18): #контейнер "применить к" bounding_sphere = struct.unpack("<4f",file.read(16)) + space_name = readName(file) + add_name = readName(file) + # b3dObj['space_name'] = file.read(32).decode("utf-8").rstrip('\0') + # b3dObj['add_name'] = file.read(32).decode("utf-8").rstrip('\0') + + if not usedBlocks[str(type)]: + continue b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] - b3dObj['pos'] = str(file.tell()) - b3dObj['space_name'] = file.read(32).decode("utf-8").rstrip('\0') - b3dObj['add_name'] = file.read(32).decode("utf-8").rstrip('\0') + b3dObj['pos'] = str(pos) + b3dObj['add_name'] = add_name + b3dObj['space_name'] = space_name - b3dObj.parent = context.scene.objects[objString[-1]] + b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name - objString.append(b3dObj.name) + objString[len(objString)-1] = b3dObj.name elif (type == 19): + + childCnt = struct.unpack("i",file.read(4))[0] + + if not usedBlocks[str(type)]: + continue + b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] - b3dObj['pos'] = str(file.tell()) + b3dObj['pos'] = str(pos) - b3dObj.parent = context.scene.objects[objString[-1]] + b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name - objString.append(b3dObj.name) + objString[len(objString)-1] = b3dObj.name - childCnt = struct.unpack("i",file.read(4))[0] elif (type == 20): bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -999,52 +1001,47 @@ def read(file, context, op, filepath): x,y,z = coord polyline.points[i].co = (x, y, z, 1) - # create Object - b3dObj = bpy.data.objects.new(objName, curveData) curveData.bevel_depth = 0.01 + # create Object + if not usedBlocks[str(type)]: + continue + + b3dObj = bpy.data.objects.new(objName, curveData) b3dObj.location = (0,0,0) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] - b3dObj['pos'] = str(file.tell()) + b3dObj['pos'] = str(pos) - b3dObj.parent = context.scene.objects[objString[-1]] + b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name - objString.append(b3dObj.name) + objString[len(objString)-1] = b3dObj.name elif (type == 21): #testkey??? bounding_sphere = struct.unpack("<4f",file.read(16)) - b3dObj = bpy.data.objects.new(objName, None) - b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] - b3dObj['pos'] = str(file.tell()) - - b3dObj.parent = context.scene.objects[objString[-1]] - context.collection.objects.link(b3dObj) - realName = b3dObj.name - objString.append(b3dObj.name) unknown1 = struct.unpack("1): - # for i in range(coords[4]): - # coords.extend(struct.unpack("<4f",file.read(16))) - # else: - # coords.extend(struct.unpack("<8f",file.read(32))) - - # elif num ==2: - # coords.extend(struct.unpack("if3i",file.read(20))) - # for i in range(num*2): - # coords.extend(struct.unpack("<7f",file.read(28))) - # coords.extend(struct.unpack(" 0: if format == 0: - objString.append(objString[-1]) + objString[len(objString)-1] = objString[-2] pass else: for i in range(vertexCount): @@ -1686,19 +1609,20 @@ def read(file, context, op, filepath): childCnt = struct.unpack(" Date: Sat, 8 Oct 2022 14:15:41 +0200 Subject: [PATCH 11/47] 40 blok fix --- src/2.80/addons/importb3d/importb3d.py | 64 ++++++++++++++------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index 61028f2..ced6afe 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -412,7 +412,7 @@ def read(file, context, op, filepath): t1 = time.perf_counter() objString.append(objString[-1]) onlyName = readName(file) - type = struct.unpack("> 8 format = formatRaw & 0xFF - vertexCount = struct.unpack(" 0: if format == 0: - objString[len(objString)-1] = objString[-2] + # objString[len(objString)-1] = objString[-2] pass else: for i in range(vertexCount): @@ -1622,6 +1627,7 @@ def read(file, context, op, filepath): context.collection.objects.link(b3dObj) realName = b3dObj.name objString[len(objString)-1] = b3dObj.name + elif (type == 39): bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -1651,7 +1657,6 @@ def read(file, context, op, filepath): bounding_sphere = struct.unpack("<4f",file.read(16)) - name1 = readName(file) name2 = readName(file) @@ -1661,14 +1666,13 @@ def read(file, context, op, filepath): for i in range(num): data1.append(struct.unpack("f", file.read(4))[0]) - if not usedBlocks[str(type)]: continue + b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) - b3dObj = bpy.data.objects.new(objName, None) b3dObj.location = bounding_sphere[:3] context.collection.objects.link(b3dObj) realName = b3dObj.name From d9830b6defd9e249e0b9ff4473205f587349f107 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Mon, 10 Oct 2022 23:00:57 +0200 Subject: [PATCH 12/47] uv override --- src/2.80/addons/importb3d/__init__.py | 92 ++++++++++++++------------ src/2.80/addons/importb3d/importb3d.py | 47 ++++++------- 2 files changed, 72 insertions(+), 67 deletions(-) diff --git a/src/2.80/addons/importb3d/__init__.py b/src/2.80/addons/importb3d/__init__.py index 4ce3c8a..10d74c3 100644 --- a/src/2.80/addons/importb3d/__init__.py +++ b/src/2.80/addons/importb3d/__init__.py @@ -70,6 +70,11 @@ def thread_import_b3d(self, files, context): t = time.mktime(datetime.datetime.now().timetuple()) - t print('Finished importing in', t, 'seconds') + +class ActiveBlock(bpy.types.PropertyGroup): + name: StringProperty() + state : BoolProperty() + class HTImportPreferences(bpy.types.AddonPreferences): bl_idname = __package__ @@ -111,19 +116,6 @@ def execute(self, context): return {'FINISHED'} -class ActiveBlock(bpy.types.PropertyGroup): - name: StringProperty() - state : BoolProperty() - -# def initBlocksArray(): - # blocks = [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] - # result = CollectionProperty(type=ActiveBlock) - # for i, block in enumerate(blocks): - # item = result.add() - # item.index = str(block) - # item.active = False -# return result - class ImportB3D(bpy.types.Operator, ImportHelper): '''Import from B3D file format (.b3d)''' bl_idname = 'import_scene.kotr_b3d' @@ -155,6 +147,14 @@ class ImportB3D(bpy.types.Operator, ImportHelper): default="tga", ) + show_all_blocks : EnumProperty( + name="Block", + items=[ + ('0', 'Custom select', 'Custom select'), + ('1', 'Select all', 'Select all'), + ('2', 'Select none', 'Select none'), + ] + ) blocks_to_import: CollectionProperty(type=ActiveBlock) @@ -168,6 +168,7 @@ def invoke(self, context, event): 33,34,35,36,37, # 38, 39,40] + for i, block in enumerate(blocks): item = self.blocks_to_import.add() item.name = str(block) @@ -188,33 +189,6 @@ def thread_import_b3d(self, files, context): t = time.mktime(datetime.datetime.now().timetuple()) - t print('Finished importing in', t, 'seconds') - def draw_import_config(self, context): - # --- Import Options --- # - layout = self.layout - - layout.label(text="Main settings:") - box1 = layout.box() - row = box1.row() - row.prop(self, 'to_unpack_res') - row = box1.row() - row.prop(self, 'to_import_textures') - row = box1.row() - row.prop(self, 'textures_format') - - layout.label(text="Blocks to import:") - box1 = layout.box() - i = 0 - perRow = 8 - rowcnt = math.floor(len(self.blocks_to_import)/perRow) - for j in range(rowcnt): - row = box1.row() - for block in self.blocks_to_import[i:i+perRow]: - row.prop(block, 'state', text=block['name'], toggle=True) - i+=perRow - row = box1.row() - for block in self.blocks_to_import[i:]: - row.prop(block, 'state', text=block['name'], toggle=True) - def execute(self, context): evens = [cn for i,cn in enumerate(self.files) if i%2==0] odds = [cn for i,cn in enumerate(self.files) if i%2==1] @@ -248,9 +222,45 @@ def execute(self, context): return {'FINISHED'} def draw(self, context): - self.draw_import_config(context) + layout = self.layout + + layout.label(text="Main settings:") + box1 = layout.box() + row = box1.row() + row.prop(self, 'to_unpack_res') + row = box1.row() + row.prop(self, 'to_import_textures') + row = box1.row() + row.prop(self, 'textures_format') + + layout.label(text="Blocks to import:") + box1 = layout.box() + row = box1.row() + row.prop(self, 'show_all_blocks') + # props = row.operator(SelectAllBlocksBtn.bl_idname) + # props.blocks_to_import = self.blocks_to_import + # props.test = PointerProperty(type=self.blocks_to_import) + row = box1.row() + if self.show_all_blocks == '1': + for block in self.blocks_to_import: + block.state = True + elif self.show_all_blocks == '2': + for block in self.blocks_to_import: + block.state = False + + i = 0 + perRow = 8 + rowcnt = math.floor(len(self.blocks_to_import)/perRow) + for j in range(rowcnt): + row = box1.row() + for block in self.blocks_to_import[i:i+perRow]: + row.prop(block, 'state', text=block['name'], toggle=True) + i+=perRow + row = box1.row() + for block in self.blocks_to_import[i:]: + row.prop(block, 'state', text=block['name'], toggle=True) class ImportWayTxt(bpy.types.Operator, ImportHelper): '''Import from txt file format (.txt)''' diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index ced6afe..797496f 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -370,8 +370,6 @@ def read(file, context, op, filepath): lvl = 0 cnt = 0 levelGroups = [] - coords25 = [] - coords23 = [] vertexes = [] normals = [] formats = [] @@ -554,7 +552,7 @@ def read(file, context, op, filepath): uv = [] bounding_sphere = struct.unpack("<4f",file.read(16)) - groupName = str(file.read(32)) #0-0 + groupName = readName(file) #0-0 vertexCount = struct.unpack(" 0: + l_uv[face] = vert_uvs[len(vert_uvs)-1] if format & 0b10000: if format & 0b1: if format & 0b100000: @@ -638,6 +640,7 @@ def read(file, context, op, filepath): # uv_new = uv_new + (uv[faces[t]],) # uvs.append(uv_new) # faces_all.append(faces) + #Triangulating faces for t in range(len(faces)-2): if not triangulateOffset: @@ -651,7 +654,7 @@ def read(file, context, op, filepath): else: faces_new.append([faces[t],faces[t+2],faces[t+1]]) - uvs.append((uv[faces_new[t][0]],uv[faces_new[t][1]],uv[faces_new[t][2]])) + uvs.append((l_uv[faces_new[t][0]],l_uv[faces_new[t][1]],l_uv[faces_new[t][2]])) faces_all.extend(faces_new) @@ -666,10 +669,6 @@ def read(file, context, op, filepath): Ev.set() Tr.join() - # log.debug(len(normals)) - # log.debug(list(b3dMesh.vertices)) - # log.debug(list(indices)) - # newIndices = getUserVertices(curFaces) if len(normals) > 0: @@ -686,7 +685,7 @@ def read(file, context, op, filepath): for k, texpoly in enumerate(b3dMesh.polygons): for j,loop in enumerate(texpoly.loop_indices): - uvsMesh = [uvs[k][j][0],1 - uvs[k][j][1]] + uvsMesh = (uvs[k][j][0], 1-uvs[k][j][1]) customUV.data[loop].uv = uvsMesh #Create Object @@ -1406,10 +1405,7 @@ def read(file, context, op, filepath): elif (type == 35): #mesh - #b3dObj.hide_viewport = True - bounding_sphere = struct.unpack("<4f",file.read(16)) - # qu = quat(file).v faces_all = [] faces = [] formats = [] @@ -1419,6 +1415,8 @@ def read(file, context, op, filepath): polygonCount = struct.unpack(" 0: + l_uv[face] = vert_uvs[len(vert_uvs)-1] if format & 0b10000: if format & 0b1: if format & 0b100000: @@ -1455,7 +1456,7 @@ def read(file, context, op, filepath): intencities.append(intens) faces_all.append(faces) - uvs.append((uv[faces[0]],uv[faces[1]],uv[faces[2]])) + uvs.append((l_uv[faces[0]],l_uv[faces[1]],l_uv[faces[2]])) if not usedBlocks[str(type)]: continue @@ -1469,12 +1470,6 @@ def read(file, context, op, filepath): Ev.set() Tr.join() - # log.debug(formats) - # log.debug(normals) - # log.debug(len(b3dMesh.vertices)) - # log.debug(len(indices)) - # log.debug(indices) - # newIndices = getUserVertices(curFaces) if len(normals) > 0: From 746cd3a9375ee1d4ec8aeaf2fe8bdb000f28011c Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 15 Oct 2022 16:20:52 +0200 Subject: [PATCH 13/47] hideLOD fix --- src/2.80/addons/b3d_tools/common.py | 19 +++++++++++--- src/2.80/addons/importb3d/importb3d.py | 35 ++++++++++++++------------ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/2.80/addons/b3d_tools/common.py b/src/2.80/addons/b3d_tools/common.py index 3bb509a..afe0896 100644 --- a/src/2.80/addons/b3d_tools/common.py +++ b/src/2.80/addons/b3d_tools/common.py @@ -22,9 +22,22 @@ def getAllChildren(obj): return allChildren def getLODObjects(obj): - vertObjs = [cn for cn in obj.children if (cn.get("block_type") is not None and (cn["block_type"]==6 or cn["block_type"]==7 or cn["block_type"]==36 or cn["block_type"]==37)) and (cn.get("level_group") is not None and (cn["level_group"]==1))] - if len(vertObjs) == 0: - vertObjs = [cn for cn in obj.children if (cn.get("block_type") is not None and (cn["block_type"]==8 or cn["block_type"]==35)) and (cn.get("level_group") is not None and (cn["level_group"]==1))] + vertObjs = None + if obj["level_group"] == 0: + vertObjs = [cn for cn in obj.children if ( \ + cn.get("block_type") is not None + and (cn["block_type"]==6 or cn["block_type"]==7 \ + or cn["block_type"]==36 or cn["block_type"]==37 \ + or cn["block_type"]==8 or cn["block_type"]==35)) \ + and (cn.get("level_group") is not None and (cn["level_group"]==1))] + else: # == 1 + vertObjs = [cn for cn in obj.children if ( \ + cn.get("block_type") is not None + and (cn["block_type"]==6 or cn["block_type"]==7 \ + or cn["block_type"]==36 or cn["block_type"]==37 \ + or cn["block_type"]==8 or cn["block_type"]==35))] + # if len(vertObjs) == 0: + # vertObjs = [cn for cn in obj.children if (cn.get("block_type") is not None and (cn["block_type"]==8 or cn["block_type"]==35)) and (cn.get("level_group") is not None and (cn["level_group"]==1))] # vertObjs.sort(key=lambda x: x.name, reverse=True) # lodCnt = math.floor(len(vertObjs) / 2) # return vertObjs[0:lodCnt] diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/importb3d/importb3d.py index 797496f..2cda2c9 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/importb3d/importb3d.py @@ -306,10 +306,11 @@ def read(file, context, op, filepath): usedBlocks[block.name] = block.state RESUnpacked = None - if op.to_unpack_res: - RESUnpacked = unpackRES(resPath, basename, True) - else: - RESUnpacked = unpackRES(resPath, basename, False) + if op.to_import_textures: + if op.to_unpack_res: + RESUnpacked = unpackRES(resPath, basename, True) + else: + RESUnpacked = unpackRES(resPath, basename, False) if op.to_import_textures and not os.path.exists(commonResPath): # ShowMessageBox("Common.res path is wrong or is not set. Textures weren't imported! Please, set path to Common.res in addon preferences.", @@ -1513,8 +1514,8 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] realName = b3dObj.name - for face in b3dMesh.polygons: - face.use_smooth = True + # for face in b3dMesh.polygons: + # face.use_smooth = True context.collection.objects.link(b3dObj) #добавляем в сцену обьект objString[len(objString)-1] = b3dObj.name @@ -1547,11 +1548,12 @@ def read(file, context, op, filepath): if format == 1 or format == 2: #Vertex with normals normals.append(struct.unpack("<3f",file.read(12))) elif format == 3: #отличается от шаблона 010Editor - normal = struct.unpack(" Date: Mon, 17 Oct 2022 20:15:49 +0200 Subject: [PATCH 14/47] visible object copy --- src/2.80/addons/b3d_tools/common.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/2.80/addons/b3d_tools/common.py b/src/2.80/addons/b3d_tools/common.py index afe0896..b54144f 100644 --- a/src/2.80/addons/b3d_tools/common.py +++ b/src/2.80/addons/b3d_tools/common.py @@ -61,6 +61,7 @@ def applyTransform(block_18): log.warn("Destination object not found in "+block_18.name) return + # if not destObj.hide_get(): #hidden objects not coopied linkObj = None if bpy.data.objects.get(spaceObj.name + "_b3dSpaceCopy"): @@ -77,11 +78,11 @@ def applyTransform(block_18): reIsCopy = re.compile(r'.*b3dcopy.*') - allChildren = [obj for obj in getAllChildren(destObj)] + allVisibleChildren = [obj for obj in getAllChildren(destObj) if not obj.hide_get()] - subTransforms = [obj for obj in allChildren if obj.get("block_type") is not None and obj["block_type"] == 18] + subTransforms = [obj for obj in allVisibleChildren if obj.get("block_type") is not None and obj["block_type"] == 18] - meshes = [obj for obj in allChildren if obj.type=="MESH" and not reIsCopy.search(obj.name)] + meshes = [obj for obj in allVisibleChildren if obj.type=="MESH" and not reIsCopy.search(obj.name)] newmeshes = [] @@ -96,21 +97,12 @@ def applyTransform(block_18): # newmesh.data = mesh.data.copy() # for NOT linked copy newmesh.parent = linkObj newmesh.name = "{}_b3dcopy".format(mesh.name) - # newmesh.rotation_euler[0] = spaceObj.rotation_euler[0] - # newmesh.rotation_euler[1] = spaceObj.rotation_euler[1] - # newmesh.rotation_euler[2] = spaceObj.rotation_euler[2] - # newmesh.location = spaceObj.location newmeshes.append(newmesh) log.info("Linking meshes") for newmesh in newmeshes: bpy.context.collection.objects.link(newmesh) - # destObj.rotation_euler[0] = spaceObj.rotation_euler[0] - # destObj.rotation_euler[1] = spaceObj.rotation_euler[1] - # destObj.rotation_euler[2] = spaceObj.rotation_euler[2] - # destObj.location = spaceObj.location - reb3dSpace = re.compile(r'.*b3dSpaceCopy.*') reb3dMesh = re.compile(r'.*b3dcopy.*') From 2c6b7cf87ab34fa319cfef12a6ba547eca0fe058 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Thu, 10 Nov 2022 20:37:00 +0200 Subject: [PATCH 15/47] single add-on --- src/2.80/addons/b3d_tools/__init__.py | 2137 +------------ .../{importb3d => b3d_tools/b3d}/__init__.py | 65 +- src/2.80/addons/b3d_tools/b3d/classes.py | 1501 ++++++++++ .../{importb3d => b3d_tools/b3d}/common.py | 24 +- .../{importb3d => b3d_tools/b3d}/exportb3d.py | 0 .../{importb3d => b3d_tools/b3d}/imghelp.py | 9 +- .../{importb3d => b3d_tools/b3d}/importb3d.py | 731 ++++- .../addons/b3d_tools/b3d/panel/__init__.py | 2648 +++++++++++++++++ src/2.80/addons/b3d_tools/b3d/panel/common.py | 435 +++ src/2.80/addons/b3d_tools/common.py | 187 +- .../{export_tch => b3d_tools/tch}/__init__.py | 18 +- .../{way_tools => b3d_tools/way}/__init__.py | 40 +- .../way}/import_way.py | 0 13 files changed, 5334 insertions(+), 2461 deletions(-) rename src/2.80/addons/{importb3d => b3d_tools/b3d}/__init__.py (87%) create mode 100644 src/2.80/addons/b3d_tools/b3d/classes.py rename src/2.80/addons/{importb3d => b3d_tools/b3d}/common.py (89%) rename src/2.80/addons/{importb3d => b3d_tools/b3d}/exportb3d.py (100%) rename src/2.80/addons/{importb3d => b3d_tools/b3d}/imghelp.py (98%) rename src/2.80/addons/{importb3d => b3d_tools/b3d}/importb3d.py (71%) create mode 100644 src/2.80/addons/b3d_tools/b3d/panel/__init__.py create mode 100644 src/2.80/addons/b3d_tools/b3d/panel/common.py rename src/2.80/addons/{export_tch => b3d_tools/tch}/__init__.py (95%) rename src/2.80/addons/{way_tools => b3d_tools/way}/__init__.py (97%) rename src/2.80/addons/{way_tools => b3d_tools/way}/import_way.py (100%) diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py index c0dfcbd..fa1895c 100644 --- a/src/2.80/addons/b3d_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -1,8 +1,74 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +if "bpy" in locals(): + print("Reimporting modules!!!") + import importlib + importlib.reload(common) + importlib.reload(way) + importlib.reload(tch) + importlib.reload(b3d) + # importlib.reload(exportb3d) +else: + import bpy + from . import ( + common, + way, + tch, + b3d + ) + + + + +# from .b3d import b3d_register, b3d_unregister +from .b3d import b3d_register, b3d_unregister +from .tch import tch_unregister, tch_register +from .b3d.panel import b3dpanel_register, b3dpanel_unregister +from .way import way_register, way_unregister + +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# + bl_info = { - "name": "King of The Road Tools Panel for b3d exporter", + "name": "King of The Road Tools", "description": "", "author": "Andrey Prozhoga", - "version": (1, 0, 0), + "version": (1, 2, 2), "blender": (2, 80, 0), "location": "3D View > Tools", "warning": "", @@ -11,2076 +77,21 @@ "category": "Development" } -if "bpy" in locals(): - print("Reimporting modules!!!") - import importlib - importlib.reload(common) - # importlib.reload(exportb3d) -else: - import bpy - from . import ( - common - ) - -# https://blenderartists.org/t/solved-adding-a-tab-in-blender-2-8/1133119/3 -def getRegion(): - if bpy.app.version < (2,80,0): - return "TOOLS" - else: - return "UI" - -import bpy -from .common import applyRemoveTransforms, applyTransforms, showHideLOD, showHideObjByType, showHideObjTreeByType - -from bpy.props import (StringProperty, - BoolProperty, - IntProperty, - FloatProperty, - EnumProperty, - PointerProperty, - ) - -from bpy.types import (Panel, - Operator, - PropertyGroup, - ) - -import bmesh - - -# ------------------------------------------------------------------------ -# store properties in the active scene -# ------------------------------------------------------------------------ - -class PanelSettings(bpy.types.PropertyGroup): - - #my_bool = bpy.props.BoolProperty( - # name="Enable or Disable", - # description="A bool property", - # default = False - # ) - - #my_int : bpy.props.IntProperty( - # name = "Int Value", - # description="A integer property", - # default = 23, - # min = 10, - # max = 100 - # ) - - #my_float : bpy.props.FloatProperty( - # name = "Float Value", - # description = "A float property", - # default = 23.7, - # min = 0.01, - # max = 30.0 - # ) - - BlockName_string : bpy.props.StringProperty( - name="Имя блока", - default="", - maxlen=30, - ) - - addBlockType_enum : bpy.props.EnumProperty( - name="Тип блока", - items=[ ('6566754', "b3d", "b3d"), - ('00', "00", "2D фон"), - ('01', "01", "Камера"), - ('03', "03", "Контейнер"), - ('04', "04", "Контейнер с возможностью привязки к нему других блоков"), - ('05', "05", "Контейнер с возможностью привязки к нему другого блока"), - ('10', "10", "LOD"), - ('12', "12", "Плоскость коллизии"), - ('13', "13", "Триггер (загрузчик карты)"), - ('14', "14", "Блок, связанный с автомобилями"), - ('18', "18", "Связка локатора и 3D-модели, например: FiatWheel0Space и Single0Wheel14"), - ('19', "19", "Контейнер, в отличие от блока типа 05, не имеет возможности привязки"), - ('20', "20", "Плоская коллизия"), - ('21', "21", "Контейнер с обработкой событий"), - #('22', "22", "Блок-локатор"), - #('23', "23", "Объёмная коллизия"), - ('24', "24", "Локатор"), - ('25', "25", "Звуковой объект"), - ('28', "28", "3D-спрайт"), - #('25', "25", "Блок-локатор"), - #('26', "26", "Блок-локатор"), - #('27', "27", "Блок-локатор"), - #('29', "29", "Блок-локатор"), - ('30', "30", "Триггер для загрузки участков карты"), - #('31', "31", "Блок-локатор"), - #('32', "32", "Блок-локатор"), - ('33', "33", "Источник света"), - #('34', "34", "Блок-локатор"), - #('35', "35", "Трисы модели"), - #('36', "36", "Блок-локатор"), - #('37', "37", "Вершины модели"), - #('38', "38", "Блок-локатор"), - #('39', "39", "Блок-локатор"), - ('40', "40", "Генератор объектов"), - ('444', "Разделитель", "Разделитель"), - ] - ) - - addBlockType_enum1 : bpy.props.EnumProperty( - name="Тип блока", - items=[ ('05', "05", "Контейнер с возможностью привязки к нему другого блока"), - ('07', "07", "Меш (ДБ1)"), - ('10', "10", "LOD"), - ('12', "12", "Плоскость коллизии"), - ('14', "14", "Блок, связанный с автомобилями"), - ('18', "18", "Связка локатора и 3D-модели, например: FiatWheel0Space и Single0Wheel14"), - ('19', "19", "Контейнер, в отличие от блока типа 05, не имеет возможности привязки"), - ('20', "20", "Плоская коллизия"), - ('21', "21", "Контейнер с обработкой событий"), - ('23', "23", "Объёмная коллизия"), - ('24', "24", "Локатор"), - ('28', "28", "3D-спрайт"), - ('33', "33", "Источник света"), - ('37', "37", "Меш"), - ('40', "40", "Генератор объектов"), - ] - ) - - CollisionType_enum : bpy.props.EnumProperty( - name="Тип коллизии", - items=(('0', "стандарт", ""), - ('1', "асфальт", ""), - ('2', "земля", ""), - ('3', "вязкое болото", ""), - ('4', "легкопроходимое болото", ""), - ('5', "мокрый асфальт", ""), - ('7', "лёд", ""), - ('8', "вода (уничтожает автомобиль)", ""), - ('10', "песок", ""), - ('11', "пустыня", ""), - ('13', "шипы", ""), - ('16', "лёд (следы от шин не остаются)", ""), - ), - ) - - Radius : bpy.props.FloatProperty( - name = "Радиус блока", - description = "Дальность прорисовки блока", - default = 1.0, - ) - - Radius1 : bpy.props.FloatProperty( - name = "Радиус блока", - description = "Дальность прорисовки блока", - default = 1.0, - ) - - LOD_Distance : bpy.props.FloatProperty( - name = "Дальность отображения LOD", - description = "Маскимальная дальность отображения LOD", - default = 10.0, - ) - - LOD_Distance1 : bpy.props.FloatProperty( - name = "Дальность отображения LOD", - description = "Маскимальная дальность отображения LOD", - default = 10.0, - ) - - Intensity : bpy.props.FloatProperty( - name = "Интенсивность освещения", - description = "Яркость источника света", - default = 1.0, - min = 0.0, - ) - - Intensity1 : bpy.props.FloatProperty( - name = "Интенсивность освещения", - description = "Яркость источника света", - default = 1.0, - min = 0.0, - ) - - R : bpy.props.FloatProperty( - name = "R", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - G : bpy.props.FloatProperty( - name = "G", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - B : bpy.props.FloatProperty( - name = "B", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - R1 : bpy.props.FloatProperty( - name = "R", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - G1 : bpy.props.FloatProperty( - name = "G", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - B1 : bpy.props.FloatProperty( - name = "B", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - RadiusLight : bpy.props.FloatProperty( - name = "Радиус освещения", - description = "", - default = 1, - min = 0.0, - ) - - RadiusLight1 : bpy.props.FloatProperty( - name = "Радиус освещения", - description = "", - default = 1, - min = 0.0, - ) - - LType_enum : bpy.props.EnumProperty( - name="Тип источника света", - items=(('0', 'Тип 0', ""), - ('1', 'Тип 1', ""), - ('2', 'Тип 2', ""), - ('3', 'Тип 3', ""), - ), - ) - - SType_enum : bpy.props.EnumProperty( - name="Тип записи вершин", - items=(#('1', "Тип 1, координаты + UV + нормали", ""), - ('2', "Тип 2, координаты + UV + нормали", "Данный тип используется на обычных моделях"), - ('3', "Тип 3, координаты + UV", "Данный тип используется на моделях света фар"), - ('258', "Тип 258, координаты + UV + нормали + 2 float", "Данный тип используется для моделей асфальтированных дорог"), - ('514', "Тип 514, координаты + UV + нормали + 4 float", "Данный тип используется на моделях поверхности воды"), - ('515', "Тип 515, координаты + UV + нормали + 2 float", "Тоже самое, что и 258. Данный тип используется для моделей асфальтированных дорог"), - ), - ) - - MType_enum : bpy.props.EnumProperty( - name="Тип записи полигонов (35)", - items=(('1', "Тип 1, с разрывной UV", "Каждый трис модели записывается вместе со собственной UV."), - ('3', "Тип 3, без разрывной UV", "Этот тип можно использовать для моделей, которые используют текстуру отражений."), - ), - ) - - texNum_int : bpy.props.IntProperty( - name = "Номер текстуры", - description="Номер используемой текстуры.", - ) - - addBlockName_string : bpy.props.StringProperty( - name="Присоединённый блок", - description="Имя блока, который будет приписан к текущему блоку, например: hit_BmwM5 приписан к BmwM5 (05)", - default="", - maxlen=30, - ) - - addBlockName1_string : bpy.props.StringProperty( - name="Присоединённый блок", - description="Имя блока, который будет приписан к текущему блоку, например: hit_BmwM5 приписан к BmwM5 (05)", - default="", - maxlen=30, - ) - - addSpaceName_string : bpy.props.StringProperty( - name="Используемый локатор", - description="Имя блока, который будет использоваться в качестве локатора для привязанного блока, например: AirportSpace и Airport", - default="", - maxlen=30, - ) - - addSpaceName1_string : bpy.props.StringProperty( - name="Используемый локатор", - description="Имя блока, который будет использоваться в качестве локатора для привязанного блока, например: AirportSpace и Airport", - default="", - maxlen=30, - ) - - add24Flag_enum : bpy.props.EnumProperty( - name="Флаг", - items=[ ('0', "0", "Присоединённый объект не будет отображаться"), - ('1', "1", "Присоединённый объект будет отображаться"), - ] - ) - - add24Flag_enum1 : bpy.props.EnumProperty( - name="Флаг", - items=[ ('0', "0", "Присоединённый объект не будет отображаться"), - ('1', "1", "Присоединённый объект будет отображаться"), - ] - ) - - TGType_int : bpy.props.IntProperty( - name = "Тип модели дерева", - description="", - ) - - Scale : bpy.props.FloatProperty( - name = "Масштаб генератора", - description="", - min=0.0, - default=9.5, - ) - - generatorType_enum : bpy.props.EnumProperty( - name="Тип генератора", - items=[ ('$SeaGenerator', "$SeaGenerator", ""), - ('$$TreeGenerator1', "$$TreeGenerator1", ""), - ('$$TreeGenerator', "$$TreeGenerator", ""), - ('$$CollisionOfTerrain', "$$CollisionOfTerrain", ""), - ('$$GeneratorOfTerrain', "$$GeneratorOfTerrain", ""), - ('$$People', "$$People", ""), - ('$$WeldingSparkles', "$$WeldingSparkles", ""), - ('$$DynamicGlow', "$$DynamicGlow", ""), - ('$$StaticGlow', "$$StaticGlow", ""), - ] - ) - - groupsNum_int : bpy.props.IntProperty( - name = "Количество групп", - description="Количество переключаемых групп.", - ) - - groupsNum1_int : bpy.props.IntProperty( - name = "Количество групп", - description="Количество переключаемых групп.", - ) - - Refer_bool = bpy.props.BoolProperty( - name="refer", - description="", - default = False - ) - - Type21_enum : bpy.props.EnumProperty( - name="Имя 21 блока", - items=[ ('GeometryKey', "GeometryKey", ""), - ('CollisionKey', "CollisionKey", ""), - ('GlassKey', "GlassKey", ""), - ('RD_LampKey', "RD_LampKey", ""), - ('RD_Key', "RD_Key", ""), - ('RedSvetKey', "RedSvetKey", ""), - ('GreenSvetKey', "GreenSvetKey", ""), - ('TrafficLightKey0', "TrafficLightKey0", ""), - ('TrafficLightKey1', "TrafficLightKey1", ""), - ('ILLUM_LEVEL_00', "ILLUM_LEVEL_00", ""), - ('ILLUM_LEVEL_01', "ILLUM_LEVEL_01", ""), - ('ILLUM_LEVEL_02', "ILLUM_LEVEL_02", ""), - ('ILLUM_LEVEL_03', "ILLUM_LEVEL_03", ""), - ('ILLUM_LEVEL_04', "ILLUM_LEVEL_04", ""), - ('ILLUM_LEVEL_05', "ILLUM_LEVEL_05", ""), - ('ILLUM_LEVEL_06', "ILLUM_LEVEL_06", ""), - ('ILLUM_LEVEL_07', "ILLUM_LEVEL_07", ""), - ('ILLUM_LEVEL_08', "ILLUM_LEVEL_08", ""), - ('ILLUM_LEVEL_09', "ILLUM_LEVEL_09", ""), - ('ILLUM_LEVEL_10', "ILLUM_LEVEL_10", ""), - ('ILLUM_LEVEL_11', "ILLUM_LEVEL_11", ""), - ('ILLUM_LEVEL_12', "ILLUM_LEVEL_12", ""), - ('ILLUM_LEVEL_13', "ILLUM_LEVEL_13", ""), - ('ILLUM_LEVEL_14', "ILLUM_LEVEL_14", ""), - ('ILLUM_LEVEL_15', "ILLUM_LEVEL_15", ""), - ('Damage1Key', "Damage1Key", ""), - ('DamageFRKey', "DamageFRKey", ""), - ('DamageFCKey', "DamageFCKey", ""), - ('DamageFLKey', "DamageFLKey", ""), - ('DamageRKey', "DamageRKey", ""), - ('DamageLKey', "DamageLKey", ""), - ('DamageBRKey', "DamageBRKey", ""), - ('DamageBCKey', "DamageBCKey", ""), - ('DamageBLKey', "DamageBLKey", ""), - ('DamageWheel0Key', "DamageWheel0Key", ""), - ('DamageWheel1Key', "DamageWheel1Key", ""), - ('DamageWheel2Key', "DamageWheel2Key", ""), - ('DamageWheel3Key', "DamageWheel3Key", ""), - ('DamageWheel4Key', "DamageWheel4Key", ""), - ('DamageWheel5Key', "DamageWheel5Key", ""), - ('DamageWheel6Key', "DamageWheel6Key", ""), - ('DamageWheel7Key', "DamageWheel7Key", ""), - ('HeadLightKey', "HeadLightKey", ""), - ('BackFaraKeyR', "BackFaraKeyR", ""), - ('StopFaraKeyR', "StopFaraKeyR", ""), - ('BackFaraKeyL', "BackFaraKeyL", ""), - ('StopFaraKeyL', "StopFaraKeyL", ""), - ('IconKey', "IconKey", ""), - ('SizeLightKey', "SizeLightKey", ""), - ('HornKey', "HornKey", ""), - ('SupportKey', "SupportKey", ""), - ('CopSirenKey', "CopSirenKey", ""), - ('CopLightKey', "CopLightKey", ""), - ('GunRightKey', "GunRightKey", ""), - ('GunLeftKey', "GunLeftKey", ""), - ('StaticLightKey', "StaticLightKey", ""), - ('BlinkLightKey', "BlinkLightKey", ""), - ('SearchLightKey', "SearchLightKey", ""), - ] - ) - - addGroupName_string : bpy.props.StringProperty( - name="Имя группы", - description="Имя переключаемой группы", - default="", - maxlen=30, - ) - - T14_enum : bpy.props.EnumProperty( - name="Преднастройки", - items=[ ('car', "Для транспорта", ""), - ('trl', "Для полуприцепа", ""), - ('trl_cyc', "Для полуприцепа-цистерны", ""), - ('clk', "Для коллизии", ""), - ] - ) - - T28_radius : bpy.props.FloatProperty( - name = "Радиус спрайта", - description = "Радиус плоскости спрайта", - default = 1.0, - min = 0.01, - ) - - T28_radius1 : bpy.props.FloatProperty( - name = "Радиус спрайта", - description = "Радиус плоскости спрайта", - default = 1.0, - min = 0.01, - ) - - CH : bpy.props.FloatProperty( - name = "Высота коллизии", - description = "Высота плоскости коллизии", - ) - - CH1 : bpy.props.FloatProperty( - name = "Высота коллизии", - description = "Высота плоскости коллизии", - ) - - RSound : bpy.props.FloatProperty( - name = "Радиус звука", - description = "Радиус звука", - default = 10.0, - min = 0.0, - ) - - RSound1 : bpy.props.FloatProperty( - name = "Радиус звука", - description = "Радиус звука", - default = 10.0, - min = 0.0, - ) - - addSoundName_string : bpy.props.StringProperty( - name="Присоединённый звуковой файл", - description="Имя звукового файла, который будет использоваться данным блоком", - default="", - maxlen=30, - ) - - addSoundName1_string : bpy.props.StringProperty( - name="Присоединённый звуковой файл", - description="Имя звукового файла, который будет использоваться данным блоком", - default="", - maxlen=30, - ) - - SLevel : bpy.props.FloatProperty( - name = "Уровень громкости звука", - description = "Уровень громкости звука", - default = 1.0, - min = 0.0, - max = 1.0, - ) - - SLevel1 : bpy.props.FloatProperty( - name = "Уровень громкости звука", - description = "Уровень громкости звука", - default = 1.0, - min = 0.0, - max = 1.0, - ) - - addRoomName_string : bpy.props.StringProperty( - name="Присоединённая комната", - description="Имя комнаты, которая будет загружена", - default="", - maxlen=30, - ) - - FType_enum : bpy.props.EnumProperty( - name="Тип записи полигонов (08)", - items=(('0', "Тип 0", "С нормалями"), - ('1', "Тип 1", "Без нормалей"), - ('2', "Тип 2", "С нормалями, UV разрывная"), - ('128', "Тип 128", ""), - ('144', "Тип 144", ""), - ), - ) - - Faces_enum : bpy.props.EnumProperty( - name="Тип блока полигонов", - items=(('8', "8", ""), - ('35', "35", ""), - ), - ) - - addBlockMeshType_enum : bpy.props.EnumProperty( - name="Тип записи модели", - items=[ ('auto', "Автоматический", "Экспортер сам определит, какой блок использовать (8, 35 или оба)"), - ('manual', "Ручной", "Будет записан блок, который выбран в настройках"), - ] - ) - - addMeshType_enum : bpy.props.EnumProperty( - name="Тип записи полигонов", - items=[ ('uv0', "Обычный", ""), - ('uv1', "С разрывной UV", ""), - ] - ) - - materialName_string : bpy.props.StringProperty( - name="Имя материала", - description="Имя материала, который будет использоваться генератором", - default="", - maxlen=10, - ) - - routeName_string : bpy.props.StringProperty( - name="Имя участка карты", - description="Имя участка карты, который будет загружен", - default="", - maxlen=2, - ) - - triggerType_enum : bpy.props.EnumProperty( - name="Тип триггера", - items=(('loader', "Загрузчик", "Загрузчик участков карты"), - ('radar0', "Радар 0", "Event 0"), - ('radar1', "Радар 1", "Event 1"), - ), - ) - - addBlockName4_string : bpy.props.StringProperty( - name="Родительский блок", - description="", - default="", - maxlen=30, - ) - - speed_limit : bpy.props.FloatProperty( - name = "Ограничение скорости", - description = "", - default = 60.0, - min = 0.0, - ) - - addBlocks_enum : bpy.props.EnumProperty( - name="Тип сборки", - items=[ ('room', "Комната", "Комната с коллизией"), - #('07', "07", "Меш (ДБ1)"), - #('10', "10", "LOD"), - #('12', "12", "Плоскость коллизии"), - #('14', "14", "Блок, связанный с автомобилями"), - #('18', "18", "Связка локатора и 3D-модели, например: FiatWheel0Space и Single0Wheel14"), - #('19', "19", "Контейнер, в отличие от блока типа 05, не имеет возможности привязки"), - #('20', "20", "Плоская коллизия"), - #('21', "21", "Контейнер с обработкой событий"), - #('23', "23", "Объёмная коллизия"), - #('24', "24", "Локатор"), - #('28', "28", "3D-спрайт"), - #('33', "33", "Источник света"), - #('37', "37", "Меш"), - #('40', "40", "Генератор объектов"), - ] - ) - - addRoomNameIndex_string : bpy.props.StringProperty( - name="Имя комнаты", - description="", - default="aa_000", - maxlen=30, - ) - - mirrorType_enum : bpy.props.EnumProperty( - name="Тип блока", - items=[ ('x', "x", ""), - ('y', "y", ""), - ('z', "z", ""), - ] - ) - -# ------------------------------------------------------------------------ -# operators -# ------------------------------------------------------------------------ - -class AddOperator(bpy.types.Operator): - bl_idname = "wm.add_operator" - bl_label = "Добавить блок на сцену" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - global block_type - - block_type = int(mytool.addBlockType_enum) - - global cursor_pos - cursor_pos = bpy.context.scene.cursor_location - - if block_type == 6566754: - object_name = "b3d" - object = bpy.data.objects.new(object_name, None) - object.location=(0.0,0.0,0.0) - bpy.context.scene.objects.link(object) - - if block_type == 0: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos - object['add_space'] = mytool.addSpaceName_string - bpy.context.scene.objects.link(object) - - if block_type == 1: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos - object['add_space'] = mytool.addSpaceName_string - object['route_name'] = mytool.routeName_string - bpy.context.scene.objects.link(object) - - if block_type == 3: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos - object['node_radius'] = mytool.Radius - bpy.context.scene.objects.link(object) - - if block_type == 4: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos #(0.0,0.0,0.0) - object['node_radius'] = mytool.Radius - object['add_name'] = mytool.addBlockName4_string - object['add_name1'] = mytool.addBlockName_string - bpy.context.scene.objects.link(object) - - if block_type == 5: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos #(0.0,0.0,0.0) - object['node_radius'] = mytool.Radius - object['add_name'] = mytool.addBlockName_string - bpy.context.scene.objects.link(object) - - if block_type == 10: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos - object['node_radius'] = mytool.Radius - object['lod_distance'] = mytool.LOD_Distance - bpy.context.scene.objects.link(object) - - if block_type == 12: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object.location=cursor_pos - object['block_type'] = block_type - object['pos'] = 1 - object['height'] = mytool.CH - object['CType'] = int(mytool.CollisionType_enum) - bpy.context.scene.objects.link(object) - - if block_type == 13: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object.location=cursor_pos - object['block_type'] = block_type - if mytool.triggerType_enum == "loader": - object['type'] = "loader" - object['route_name'] = mytool.routeName_string - if mytool.triggerType_enum == "radar0": - object['type'] = "radar0" - object['var0'] = 30 - object['var1'] = 3005 - object['var2'] = 4 - object['speed_limit'] = mytool.speed_limit - if mytool.triggerType_enum == "radar1": - object['type'] = "radar1" - object['var0'] = 30 - object['var1'] = -1 - object['var2'] = 4 - object['speed_limit'] = mytool.speed_limit - bpy.context.scene.objects.link(object) - - if block_type == 14: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos - if mytool.T14_enum == "car": - object['var0'] = 0 - object['var1'] = mytool.Radius - object['var2'] = mytool.Radius/2 - object['var3'] = 10 - object['var4'] = 18 - elif mytool.T14_enum == "trl": - object['var0'] = 0 - object['var1'] = mytool.Radius - object['var2'] = mytool.Radius/2 - object['var3'] = 16 - object['var4'] = 25 - - elif mytool.T14_enum == "trl_cyc": - object['var0'] = 0 - object['var1'] = mytool.Radius - object['var2'] = mytool.Radius/2 - object['var3'] = 18 - object['var4'] = 25 - - elif mytool.T14_enum == "clk": - object['var0'] = 0 - object['var1'] = mytool.Radius * 0.08 - object['var2'] = mytool.Radius * 0.51 - object['var3'] = mytool.Radius - object['var4'] = 0 - bpy.context.scene.objects.link(object) - - if block_type == 18: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos - object['node_radius'] = mytool.Radius - object['add_name'] = mytool.addBlockName_string - object['space_name'] = mytool.addSpaceName_string - bpy.context.scene.objects.link(object) - - if block_type == 19: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object.location=cursor_pos - bpy.context.scene.objects.link(object) - - if block_type == 20: - points = [(0,0,0), (0,1,0)] - curveData = bpy.data.curves.new('curve', type='CURVE') - - curveData.dimensions = '3D' - curveData.resolution_u = 2 - - polyline = curveData.splines.new('POLY') - polyline.points.add(len(points)-1) - for i, coord in enumerate(points): - x,y,z = coord - polyline.points[i].co = (x, y, z, 1) - - object = bpy.data.objects.new("VDAT", curveData) - curveData.bevel_depth = 0.01 - - object.location = (0,0,0) - #object = bpy.context.selected_objects[0] - context.scene.objects.link(object) - object.name = mytool.BlockName_string - object['block_type'] = block_type - - if block_type == 21: - if mytool.Refer_bool is False: - object_name = mytool.Type21_enum - else: - object_name = 'refer_' + mytool.Type21_enum - object = bpy.data.objects.new(object_name, None) - object['block_type'] = block_type - object['node_radius'] = mytool.Radius - object['groups_num'] = mytool.groupsNum_int - object.location=cursor_pos - bpy.context.scene.objects.link(object) - for i in range(mytool.groupsNum_int): - group = bpy.data.objects.new((mytool.addGroupName_string + str(i)), None) - group['block_type'] = 5 - group['node_radius'] = mytool.Radius - group['add_name'] = "" - bpy.context.scene.objects.link(group) - group.parent = object - if (i < mytool.groupsNum_int - 1): - separator = bpy.data.objects.new((mytool.addGroupName_string + str(i) + "_444"), None) - separator['block_type'] = 444 - bpy.context.scene.objects.link(separator) - separator.parent = object - - - if block_type == 24: - object = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) - object = bpy.context.selected_objects[0] - object['block_type'] = block_type - object['flag'] = int(mytool.add24Flag_enum) - object.name = mytool.BlockName_string - object.location=cursor_pos - - if block_type == 25: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object.location=cursor_pos - object['block_type'] = block_type - object['sound_name'] = mytool.addSoundName_string - object['RSound'] = mytool.RSound - object['SLevel'] = mytool.SLevel - bpy.context.scene.objects.link(object) - - if block_type == 28: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object.location=cursor_pos - object['block_type'] = block_type - object['node_radius'] = mytool.Radius - object['sprite_radius'] = mytool.T28_radius - object['texNum'] = mytool.texNum_int - object_name = mytool.BlockName_string - bpy.context.scene.objects.link(object) - - if block_type == 30: - object_name = mytool.BlockName_string - - myvertex = [] - myfaces = [] - - mypoint = [(0, -20, 0)] - myvertex.extend(mypoint) - - mypoint = [(0, -20, 100)] - myvertex.extend(mypoint) - - mypoint = [(0, 20, 100)] - myvertex.extend(mypoint) - - mypoint = [(0, 20, 0)] - myvertex.extend(mypoint) - - myface = [(0, 1, 2, 3)] - myfaces.extend(myface) - - - mymesh = bpy.data.meshes.new(object_name) - - object = bpy.data.objects.new(object_name, mymesh) - - bpy.context.scene.objects.link(object) - - mymesh.from_pydata(myvertex, [], myfaces) - - mymesh.update(calc_edges=True) - - object.location = cursor_pos - - object['block_type'] = block_type - object.location=cursor_pos - object['radius'] = mytool.Radius - object['room_name'] = mytool.addRoomName_string - #bpy.context.scene.objects.link(object) - - if block_type == 33: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object.location=cursor_pos - object['block_type'] = block_type - object['node_radius'] = mytool.Radius - object['light_radius'] = mytool.RadiusLight - object['light_type'] = int(mytool.LType_enum) - object['intensity'] = mytool.Intensity - object['R'] = mytool.R / 255 - object['G'] = mytool.G / 255 - object['B'] = mytool.B / 255 - object_name = mytool.BlockName_string - bpy.context.scene.objects.link(object) - - if block_type == 40: - if mytool.generatorType_enum == "$$TreeGenerator1": - point = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, enter_editmode=True, location=(0.0,0.0,0.0)) - mesh0 = bpy.ops.mesh.primitive_cone_add(vertices=12, radius1=0.5, radius2=0.0, depth=1.0, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 1.0)) - mesh1 = bpy.ops.mesh.primitive_cone_add(vertices=12, radius1=0.3, radius2=0.0, depth=0.6, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 1.4)) - tree = bpy.ops.mesh.primitive_cylinder_add(vertices=12, radius=0.05, depth=0.5, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 0.25)) - object = bpy.context.selected_objects[0] - object['block_type'] = block_type - object['scale'] = mytool.Scale - object['TGType'] = mytool.TGType_int - object['GType'] = mytool.generatorType_enum - object.name = mytool.BlockName_string - bpy.ops.object.mode_set(mode = 'OBJECT') - object.location = bpy.context.scene.cursor_location - - if mytool.generatorType_enum == "$$DynamicGlow": - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object.location=cursor_pos - - object['block_type'] = block_type - object['node_radius'] = mytool.Radius - object['scale'] = mytool.Scale - object['mat_name'] = mytool.materialName_string - object['GType'] = mytool.generatorType_enum - object.name = mytool.BlockName_string - bpy.context.scene.objects.link(object) - - if block_type == 444: - object_name = mytool.BlockName_string - object = bpy.data.objects.new(object_name, None) - object['block_type'] = 444 - object.location=(0.0,0.0,0.0) - bpy.context.scene.objects.link(object) - return {'FINISHED'} - -# ------------------------------------------------------------------------ -# menus -# ------------------------------------------------------------------------ - -class BasicMenu(bpy.types.Menu): - bl_idname = "OBJECT_MT_select_test" - bl_label = "Select" - - def draw(self, context): - layout = self.layout - - # built-in example operators - layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE' - layout.operator("object.select_all", text="Inverse").action = 'INVERT' - layout.operator("object.select_random", text="Random") - -# ------------------------------------------------------------------------ -# my tool in objectmode -# ------------------------------------------------------------------------ - -class OBJECT_PT_b3d_add_panel(bpy.types.Panel): - bl_idname = "OBJECT_PT_b3d_add_panel" - bl_label = "Настройки" - bl_space_type = "VIEW_3D" - bl_region_type = getRegion() - bl_category = "b3d Tools" - #bl_context = "objectmode" - - @classmethod - def poll(self,context): - return context.object is not None - - def draw(self, context): - layout = self.layout - scene = context.scene - mytool = scene.my_tool - -class OBJECT_PT_b3d_add_panel(bpy.types.Panel): - bl_idname = "OBJECT_PT_b3d_add_panel" - bl_label = "Добавление блоков" - bl_space_type = "VIEW_3D" - bl_region_type = getRegion() - bl_category = "b3d Tools" - #bl_context = "objectmode" - - @classmethod - def poll(self,context): - return context.object is not None - - def draw(self, context): - layout = self.layout - scene = context.scene - mytool = scene.my_tool - # print(type(mytool)) - # print(bpy.types.Scene.my_tool) - # print(dir(bpy.types.Scene.my_tool)) - # print(dir(context.scene.my_tool)) - global block_type - block_type = int(mytool.addBlockType_enum) - - if block_type == 6566754: - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - - if block_type == 0: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "addSpaceName_string") - - - if block_type == 1: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "addSpaceName_string") - layout.prop(mytool, "routeName_string") - - if block_type == 3: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "Radius") - - if block_type == 4: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "Radius") - layout.prop(mytool, "addBlockName4_string") - layout.prop(mytool, "addBlockName_string") - - if block_type == 5: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "addBlockName_string") - layout.prop(mytool, "Radius") - - elif block_type == 10: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "Radius") - layout.prop(mytool, "LOD_Distance") - - elif block_type == 12: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "CH") - layout.prop(mytool, "CollisionType_enum") - - elif block_type == 13: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "triggerType_enum", text="") - if mytool.triggerType_enum == "loader": - layout.prop(mytool, "routeName_string") - elif mytool.triggerType_enum == "radar0" or "radar1": - layout.prop(mytool, "speed_limit") - - elif block_type == 14: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - self.layout.label(text="Вариант преднастроек:") - layout.prop(mytool, "T14_enum", text="") - layout.prop(mytool, "Radius") - - elif block_type == 18: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "Radius") - layout.prop(mytool, "addBlockName_string") - layout.prop(mytool, "addSpaceName_string") - - elif block_type == 19: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - - elif block_type == 20: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - - elif block_type == 21: - self.layout.label(text="Имя блока:") - layout.prop(mytool, "Type21_enum", text="") - layout.prop(mytool, "Refer_bool") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "Radius") - layout.prop(mytool, "groupsNum_int") - layout.prop(mytool, "addGroupName_string") - - elif block_type == 24: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - self.layout.label(text="Флаг:") - layout.prop(mytool, "add24Flag_enum", text="") - - elif block_type == 25: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "addSoundName_string") - layout.prop(mytool, "RSound") - layout.prop(mytool, "SLevel") - - elif block_type == 28: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "Radius") - layout.prop(mytool, "T28_radius") - layout.prop(mytool, "texNum_int") - - elif block_type == 30: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "Radius") - layout.prop(mytool, "addRoomName_string") - - elif block_type == 33: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - layout.prop(mytool, "LType_enum") - layout.prop(mytool, "Radius") - layout.prop(mytool, "RadiusLight") - layout.prop(mytool, "Intensity") - layout.prop(mytool, "R") - layout.prop(mytool, "G") - layout.prop(mytool, "B") - - elif block_type == 40: - layout.prop(mytool, "BlockName_string") - layout.prop(mytool, "Radius") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - self.layout.label(text="Тип генератора:") - layout.prop(mytool, "generatorType_enum", text="") - if mytool.generatorType_enum == "$$TreeGenerator1": - layout.prop(mytool, "TGType_int") - layout.prop(mytool, "Scale") - if mytool.generatorType_enum == "$$DynamicGlow": - layout.prop(mytool, "materialName_string") - layout.prop(mytool, "Scale") - else: - self.layout.label(text="Данный тип генератора не поддерживается.") - - elif block_type == 444: - layout.prop(mytool, "BlockName_string") - self.layout.label(text="Тип блока:") - layout.prop(mytool, "addBlockType_enum", text="") - - layout.operator("wm.add_operator") - - #layout.prop(mytool, "my_bool") - #layout.prop(mytool, "my_int") - #layout.prop(mytool, "my_float") - #layout.menu("OBJECT_MT_select_test", text="Presets", icon="SCENE") - -class GetValuesOperator(bpy.types.Operator): - bl_idname = "wm.get_values_operator" - bl_label = "Получить настройки блока" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - global block_type - global lenStr - object = bpy.context.selected_objects[0] - block_type = object['block_type'] - - if block_type == 5: - mytool.addBlockName1_string = object['add_name'] - mytool.Radius1 = object['node_radius'] - - elif block_type == 7: - if 'BType' in object: - mytool.Faces_enum = str(object['BType']) - else: - mytool.Faces_enum = str(35) - object['BType'] = 35 - if "type1" in object: - mytool.addBlockMeshType_enum = str(object['type1']) - else: - object['type1'] = "manual" - mytool.addBlockMeshType_enum = str(object['type1']) - mytool.MType_enum = str(object['MType']) - mytool.FType_enum = str(object['FType']) - mytool.texNum_int = object['texNum'] - - elif block_type == 10: - mytool.Radius1 = object['node_radius'] - mytool.LOD_Distance1 = object['lod_distance'] - - elif block_type == 12: - mytool.CH1 = object['height'] - mytool.CollisionType_enum = object['CType'] - - elif block_type == 18: - mytool.Radius1 = object['node_radius'] - mytool.addBlockName1_string = object['add_name'] - mytool.addSpaceName1_string = object['space_name'] - - elif block_type == 21: - mytool.groupsNum1_int = object['groups_num'] - mytool.Radius1 = object['node_radius'] - - elif block_type == 23: - mytool.CollisionType_enum = str(object['CType']) - - elif block_type == 24: - mytool.add24Flag_enum1 = str(object['flag']) - - elif block_type == 25: - mytool.RSound1 = (object['RSound']) - mytool.addSoundName1_string = object['sound_name'] - mytool.SLevel1 = (object['SLevel']) - - elif block_type == 28: - mytool.texNum_int = object['texNum'] - mytool.T28_radius1 = object['sprite_radius'] - - elif block_type == 33: - mytool.Radius1 = object['node_radius'] - mytool.LType_enum = str(object['light_type']) - mytool.RadiusLight1 = object['light_radius'] - mytool.Intensity1 = object['intensity'] - mytool.R1 = object['R'] * 255 - mytool.G1 = object['G'] * 255 - mytool.B1 = object['B'] * 255 - - elif block_type == 37: - if 'BType' in object: - mytool.Faces_enum = str(object['BType']) - else: - mytool.Faces_enum = str(35) - object['BType'] = 35 - if "type1" in object: - mytool.addBlockMeshType_enum = str(object['type1']) - else: - object['type1'] = "manual" - mytool.addBlockMeshType_enum = str(object['type1']) - #mytool.addMeshType_enum = str(object['type2']) - mytool.SType_enum = str(object['SType']) - mytool.MType_enum = str(object['MType']) - mytool.FType_enum = str(object['FType']) - mytool.texNum_int = object['texNum'] - - return {'FINISHED'} - -class SetValuesOperator(bpy.types.Operator): - bl_idname = "wm.set_values_operator" - bl_label = "Сохранить настройки блока" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - global block_type - global lenStr - #object = bpy.context.selected_objects[0] - - for i in range(len(bpy.context.selected_objects)): - - object = bpy.context.selected_objects[i] - - if 'block_type' in object: - block_type = object['block_type'] - else: - block_type = int(mytool.addBlockType_enum1) - - object['block_type'] = block_type - - if block_type == 5: - object['add_name'] = mytool.addBlockName1_string - object['node_radius'] = mytool.Radius1 - - elif block_type == 7: - object['type1'] = str(mytool.addBlockMeshType_enum) - object['BType'] = int(mytool.Faces_enum) - object['FType'] = int(mytool.FType_enum) - object['MType'] = int(mytool.MType_enum) - object['texNum'] = int(mytool.texNum_int) - - elif block_type == 10: - object['node_radius'] = mytool.Radius1 - object['lod_distance'] = mytool.LOD_Distance1 - - elif block_type == 12: - object['height'] = mytool.CH1 - object['CType'] = int(mytool.CollisionType_enum) - - elif block_type == 18: - object['node_radius'] = mytool.Radius1 - object['add_name'] = mytool.addBlockName1_string - object['space_name'] = mytool.addSpaceName1_string - - elif block_type == 21: - object['groups_num'] = mytool.groupsNum1_int - object['node_radius'] = mytool.Radius1 - - elif block_type == 23: - object['CType'] = int(mytool.CollisionType_enum) - - elif block_type == 24: - object['flag'] = int(mytool.add24Flag_enum1) - - elif block_type == 25: - object['RSound'] = mytool.RSound1 - object['sound_name'] = mytool.addSoundName1_string - object['SLevel'] = mytool.SLevel1 - - elif block_type == 28: - object['texNum'] = mytool.texNum_int - object['node_radius'] = mytool.Radius1 - object['sprite_radius'] = mytool.T28_radius1 - - elif block_type == 33: - object['node_radius'] = mytool.Radius1 - object['light_type'] = int(mytool.LType_enum) - object['light_radius'] = mytool.RadiusLight1 - object['intensity'] = mytool.Intensity1 - object['R'] = mytool.R1 / 255 - object['G'] = mytool.G1 / 255 - object['B'] = mytool.B1 / 255 - - elif block_type == 37: - object['type1'] = str(mytool.addBlockMeshType_enum) - #object['type2'] = str(mytool.addMeshType_enum) - object['BType'] = int(mytool.Faces_enum) - object['SType'] = int(mytool.SType_enum) - object['MType'] = int(mytool.MType_enum) - object['FType'] = int(mytool.FType_enum) - object['texNum'] = int(mytool.texNum_int) - - return {'FINISHED'} - -class DelValuesOperator(bpy.types.Operator): - bl_idname = "wm.del_values_operator" - bl_label = "Удалить настройки блока" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - global block_type - global lenStr - #object = bpy.context.selected_objects[0] - - for i in range(len(bpy.context.selected_objects)): - - object = bpy.context.selected_objects[i] - - if 'block_type' in object: - del object['block_type'] - - return {'FINISHED'} - -class FixUVOperator(bpy.types.Operator): - bl_idname = "wm.fix_uv_operator" - bl_label = "Исправить UV для экспорта" - - def execute(self, context): - - for i in range(len(bpy.context.selected_objects)): - - object = bpy.context.selected_objects[i] - - bpy.ops.object.mode_set(mode = 'EDIT') - - context = bpy.context - obj = context.edit_object - me = obj.data - bm = bmesh.from_edit_mesh(me) - # old seams - old_seams = [e for e in bm.edges if e.seam] - # unmark - for e in old_seams: - e.seam = False - # mark seams from uv islands - bpy.ops.uv.seams_from_islands() - seams = [e for e in bm.edges if e.seam] - # split on seams - print(seams) - print("salo 111") - bmesh.ops.split_edges(bm, edges=seams) - # re instate old seams.. could clear new seams. - for e in old_seams: - e.seam = True - bmesh.update_edit_mesh(me) - - boundary_seams = [e for e in bm.edges if e.seam and e.is_boundary] - - bpy.ops.object.mode_set(mode = 'OBJECT') - - return {'FINISHED'} - -class FixVertsOperator(bpy.types.Operator): - bl_idname = "wm.fix_verts_operator" - bl_label = "Исправить меш для экспорта" - - def execute(self, context): - - for i in range(len(bpy.context.selected_objects)): - - object = bpy.context.selected_objects[i] - - bpy.ops.object.mode_set(mode = 'EDIT') - bpy.ops.mesh.select_mode(type="FACE") - bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.mesh.select_all(action='INVERT') - bpy.ops.mesh.select_mode(type="VERT") - bpy.ops.mesh.select_all(action='INVERT') - bpy.ops.mesh.delete(type='VERT') - - bpy.ops.object.mode_set(mode = 'OBJECT') - - return {'FINISHED'} - -from mathutils import Vector, Matrix -from math import radians, degrees - -class MirrorAndFlipObjectsOperator(bpy.types.Operator): - bl_idname = "wm.mirror_objects_operator" - bl_label = "Отзеркалить объекты" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - x = False - y = False - z = False - - if (mytool.mirrorType_enum) == "x": - x = True - else: - x = False - - if (mytool.mirrorType_enum) == "y": - y = True - else: - y = False - - if (mytool.mirrorType_enum) == "z": - z = True - else: - z = False - - for object in context.selected_objects: - if object.type == 'MESH': - #object = bpy.context.selected_objects[i] - bpy.ops.transform.mirror(constraint_axis=(x, y, z), constraint_orientation='GLOBAL') - bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) - - #if object.type == 'MESH': - bpy.ops.object.mode_set(mode = 'EDIT') - bpy.ops.mesh.select_mode(type="FACE") - bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.mesh.select_all(action='INVERT') - bpy.ops.mesh.flip_normals() - bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.object.mode_set(mode = 'OBJECT') - - - - - #bpy.ops.object.mode_set(mode = 'OBJECT') - - return {'FINISHED'} - -class ApplyTransformsOperator(bpy.types.Operator): - bl_idname = "wm.apply_transforms_operator" - bl_label = "Расположить/Убрать обьекты" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - applyRemoveTransforms() - - return {'FINISHED'} - -class ShowHideCollisionsOperator(bpy.types.Operator): - bl_idname = "wm.show_hide_collisions_operator" - bl_label = "Отобразить/Скрыть коллизии" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - showHideObjByType(23) - - return {'FINISHED'} - -class ShowHideRoomBordersOperator(bpy.types.Operator): - bl_idname = "wm.show_hide_room_borders_operator" - bl_label = "Отобразить/Скрыть границы комнат" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - showHideObjByType(30) - - return {'FINISHED'} - -class ShowHideLODOperator(bpy.types.Operator): - bl_idname = "wm.show_hide_lod_operator" - bl_label = "Отобразить/Скрыть LOD модели" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - showHideLOD() - - return {'FINISHED'} - -class ShowHideGeneratorsOperator(bpy.types.Operator): - bl_idname = "wm.show_hide_generator_operator" - bl_label = "Отобразить/Скрыть генераторы обьектов" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - showHideObjByType(40) - - return {'FINISHED'} - -class OBJECT_PT_b3d_edit_panel(bpy.types.Panel): - bl_idname = "OBJECT_PT_b3d_edit_panel" - bl_label = "Редактирование блоков" - bl_space_type = "VIEW_3D" - bl_region_type = getRegion() - bl_category = "b3d Tools" - #bl_context = "objectmode" - - @classmethod - def poll(self,context): - return context.object is not None - - def draw(self, context): - layout = self.layout - mytool = context.scene.my_tool - - type(context) - #for i in range(len(bpy.context.selected_objects)): - - if len(bpy.context.selected_objects): - for i in range(1): - - object = bpy.context.selected_objects[i] - - level_group = None - - if 'block_type' in object: - block_type = object['block_type'] - else: - block_type = None - - if 'level_group' in object: - level_group = object['level_group'] - else: - level_group = None - - lenStr = str(len(object.children)) - - if block_type == 0: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 1: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 2: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 3: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 4: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 5: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'add_name' in object: - layout.prop(mytool, "addBlockName1_string") - layout.prop(mytool, "Radius1") - else: - self.layout.label(text="Имя присоединённого блока не указано. Сохраните настройки,") - self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 6: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 7: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'texNum' in object: - layout.prop(mytool, "addBlockMeshType_enum") - - if (mytool.addBlockMeshType_enum) == "auto": - layout.prop(mytool, "FType_enum") - layout.prop(mytool, "MType_enum") - else: - layout.prop(mytool, "Faces_enum") - if int(mytool.Faces_enum) == 35: - layout.prop(mytool, "MType_enum") - else: - layout.prop(mytool, "FType_enum") - - layout.prop(mytool, "texNum_int") - else: - self.layout.label(text="Указаны не все атрибуты объекта.") - self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 8: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 9: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 10: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'node_radius' in object: - layout.prop(mytool, "Radius1") - layout.prop(mytool, "LOD_Distance1") - else: - self.layout.label(text="Указаны не все атрибуты объекта.") - self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - self.layout.label(text="Количество вложенных блоков: " + str(len(object.children) - 1)) - - elif block_type == 11: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 12: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'CType' in object: - self.layout.label(text="Тип коллизии:") - layout.prop(mytool, "CollisionType_enum", text="") - layout.prop(mytool, "CH1") - else: - self.layout.label(text="Тип коллизии не указан. Сохраните настройки,") - self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 13: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 14: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 15: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 16: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 17: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 18: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'add_name' in object: - layout.prop(mytool, "Radius1") - layout.prop(mytool, "addBlockName1_string") - layout.prop(mytool, "addSpaceName1_string") - else: - self.layout.label(text="Указаны не все атрибуты объекта.") - self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 19: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 20: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 21: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + str(len(object.children)-object['groups_num']+1)) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'groups_num' in object: - layout.prop(mytool, "groupsNum1_int") - layout.prop(mytool, "Radius1") - else: - self.layout.label(text="Количество групп не указано. Сохраните настройки,") - self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 23: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'CType' in object: - self.layout.label(text="Тип коллизии:") - layout.prop(mytool, "CollisionType_enum", text="") - else: - self.layout.label(text="Тип коллизии не указан. Сохраните настройки,") - self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 24: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'flag' in object: - layout.prop(mytool, "add24Flag_enum1", text="") - else: - self.layout.label(text="Флаг блока не указан. Сохраните настройки,") - self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 25: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'RSound' in object: - layout.prop(mytool, "addSoundName1_string") - layout.prop(mytool, "RSound1") - layout.prop(mytool, "SLevel1") - else: - self.layout.label(text="Указаны не все атрибуты объекта.") - self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 26: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 27: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 28: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'sprite_radius' in object: - layout.prop(mytool, "Radius1") - layout.prop(mytool, "T28_radius1") - layout.prop(mytool, "texNum_int") - else: - self.layout.label(text="Указаны не все атрибуты объекта.") - self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 29: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 30: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 31: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 32: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 33: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Группа блока: " + str(level_group)) - layout.prop(mytool, "Radius1") - layout.prop(mytool, "LType_enum") - layout.prop(mytool, "RadiusLight1") - layout.prop(mytool, "Intensity1") - layout.prop(mytool, "R1") - layout.prop(mytool, "G1") - layout.prop(mytool, "B1") - - elif block_type == 34: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 35: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 36: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 37: - self.layout.label(text="Тип блока: " + str(block_type)) - #self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - if 'texNum' in object: - layout.prop(mytool, "addBlockMeshType_enum") - - if (mytool.addBlockMeshType_enum) == "auto": - layout.prop(mytool, "SType_enum") - #layout.prop(mytool, "FType_enum") - #layout.prop(mytool, "addMeshType_enum") - layout.prop(mytool, "FType_enum") - layout.prop(mytool, "MType_enum") - else: - layout.prop(mytool, "Faces_enum") - if int(mytool.Faces_enum) == 35: - layout.prop(mytool, "MType_enum") - layout.prop(mytool, "SType_enum") - else: - layout.prop(mytool, "SType_enum") - layout.prop(mytool, "FType_enum") - - layout.prop(mytool, "texNum_int") - else: - self.layout.label(text="Указаны не все атрибуты объекта.") - self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 38: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 39: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Количество вложенных блоков: " + lenStr) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 40: - self.layout.label(text="Тип блока: " + str(block_type)) - self.layout.label(text="Тип генератора: " + object['GType']) - self.layout.label(text="Группа блока: " + str(level_group)) - - elif block_type == 444: - self.layout.label(text="Тип объекта - разделитель") - - else: - self.layout.label(text="Выбранный объект не имеет типа.") - self.layout.label(text="Чтобы указать его, нажмите на кнопку сохранения настроек.") - layout.prop(mytool, "addBlockType_enum1") - - layout.operator("wm.get_values_operator") - layout.operator("wm.set_values_operator") - layout.operator("wm.del_values_operator") - layout.operator("wm.fix_uv_operator") - layout.operator("wm.fix_verts_operator") - -class AddBlocksOperator(bpy.types.Operator): - bl_idname = "wm.add1_operator" - bl_label = "Добавить сборку блоков на сцену" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - global type - - type = mytool.addBlocks_enum - - global cursor_pos - cursor_pos = bpy.context.scene.cursor_location - - def type05(name, radius, add_name): - object_name = name - object = bpy.data.objects.new(object_name, None) - object['block_type'] = 5 - object.location=cursor_pos - object['node_radius'] = radius - object['add_name'] = add_name - bpy.context.scene.objects.link(object) - object.select = True - - def type19(name): - object_name = name - object = bpy.data.objects.new(object_name, None) - object['block_type'] = 19 - object.location=cursor_pos - bpy.context.scene.objects.link(object) - object.select = True - - if type == "room": - type19("room_" + mytool.addRoomNameIndex_string) - room = bpy.context.selected_objects[0] - - type05(("road_" + mytool.addRoomNameIndex_string), mytool.Radius, ("hit_road_" + mytool.addRoomNameIndex_string)) - road = bpy.context.selected_objects[0] - - type05(("obj_" + mytool.addRoomNameIndex_string), mytool.Radius, ("hit_obj_" + mytool.addRoomNameIndex_string)) - obj = bpy.context.selected_objects[0] - - hit_road = type05(("hit_road_" + mytool.addRoomNameIndex_string), 0, "") - hit_obj = type05(("hit_obj_" + mytool.addRoomNameIndex_string), 0, "") - - bpy.ops.object.select_all(action='DESELECT') - - room.select = True - road.select = True - obj.select = True - - bpy.context.scene.objects.active = room - - bpy.ops.object.parent_set() - - bpy.ops.object.select_all(action='DESELECT') - - return {'FINISHED'} - -class OBJECT_PT_b3d_blocks_panel(bpy.types.Panel): - bl_idname = "OBJECT_PT_b3d_blocks_panel" - bl_label = "Сборки блоков" - bl_space_type = "VIEW_3D" - bl_region_type = getRegion() - bl_category = "b3d Tools" - #bl_context = "objectmode" - - @classmethod - def poll(self,context): - return context.object is not None - - def draw(self, context): - layout = self.layout - # print(dir(context)) - mytool = context.scene.my_tool - - type = mytool.addBlocks_enum - - # print(dir(mytool)) - - layout.prop(mytool, "addBlocks_enum") - - if type == "room": - layout.prop(mytool, "addRoomNameIndex_string") - layout.prop(mytool, "Radius") - - layout.operator("wm.add1_operator") - -class OBJECT_PT_b3d_func_panel(bpy.types.Panel): - bl_idname = "OBJECT_PT_b3d_func_panel" - bl_label = "Дополнительные функции" - bl_space_type = "VIEW_3D" - bl_region_type = getRegion() - bl_category = "b3d Tools" - #bl_context = "objectmode" - - @classmethod - def poll(self,context): - return context.object is not None - - def draw(self, context): - layout = self.layout - scene = context.scene - mytool = scene.my_tool - - - layout.prop(mytool, "mirrorType_enum") - - layout.operator("wm.mirror_objects_operator") - layout.operator("wm.apply_transforms_operator") - layout.operator("wm.show_hide_collisions_operator") - layout.operator("wm.show_hide_room_borders_operator") - layout.operator("wm.show_hide_lod_operator") - layout.operator("wm.show_hide_generator_operator") - -class OBJECT_PT_b3d_misc_panel(bpy.types.Panel): - bl_idname = "OBJECT_PT_b3d_misc_panel" - bl_label = "О плагине" - bl_space_type = "VIEW_3D" - bl_region_type = getRegion() - bl_category = "b3d Tools" - #bl_context = "objectmode" - - @classmethod - def poll(self,context): - return context.object is not None - - def draw(self, context): - layout = self.layout - scene = context.scene - mytool = scene.my_tool - self.layout.label(text="Автор плагина: aleko2144") - self.layout.label(text="vk.com/rnr_mods") # ------------------------------------------------------------------------ # register and unregister # ------------------------------------------------------------------------ -classes = ( - PanelSettings, - AddOperator, - BasicMenu, - OBJECT_PT_b3d_add_panel, - GetValuesOperator, - SetValuesOperator, - DelValuesOperator, - FixUVOperator, - FixVertsOperator, - MirrorAndFlipObjectsOperator, - ApplyTransformsOperator, - ShowHideCollisionsOperator, - ShowHideRoomBordersOperator, - ShowHideLODOperator, - ShowHideGeneratorsOperator, - OBJECT_PT_b3d_edit_panel, - AddBlocksOperator, - OBJECT_PT_b3d_blocks_panel, - OBJECT_PT_b3d_func_panel, - OBJECT_PT_b3d_misc_panel, -) def register(): - for cls in classes: - bpy.utils.register_class(cls) - bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=PanelSettings) + b3d_register() + # tch_register() + b3dpanel_register() def unregister(): - del bpy.types.Scene.my_tool - for cls in classes: - bpy.utils.unregister_class(cls) + b3dpanel_unregister() + # tch_unregister() + b3d_unregister() if __name__ == "__main__": register() diff --git a/src/2.80/addons/importb3d/__init__.py b/src/2.80/addons/b3d_tools/b3d/__init__.py similarity index 87% rename from src/2.80/addons/importb3d/__init__.py rename to src/2.80/addons/b3d_tools/b3d/__init__.py index 10d74c3..ef58827 100644 --- a/src/2.80/addons/importb3d/__init__.py +++ b/src/2.80/addons/b3d_tools/b3d/__init__.py @@ -1,52 +1,26 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -# - -bl_info = { - 'name': 'King of the Road B3D importer/exporter', - 'author': 'Yuriy Gladishenko, Andrey Prozhoga', - 'version': (0, 1, 17), - 'blender': (2, 80, 0), - 'api': 34893, - 'description': 'This script imports and exports the King of the Road b3d', - 'warning': '', - 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/'\ - 'Import-Export/M3_Import', - 'tracker_url': 'vk.com/rnr_mods', - 'category': 'Import-Export'} + # To support reload properly, try to access a package var, if it's there, # reload everything if "bpy" in locals(): print("Reimporting modules!!!") import importlib + importlib.reload(common) + importlib.reload(classes) importlib.reload(importb3d) # importlib.reload(exportb3d) importlib.reload(imghelp) + importlib.reload(panel) else: import bpy from . import ( common, + classes, importb3d, # exportb3d, imghelp, + panel ) import math @@ -55,7 +29,7 @@ import datetime import os import bpy -from bpy.props import StringProperty, EnumProperty, BoolProperty, CollectionProperty +from bpy.props import StringProperty, EnumProperty, BoolProperty, CollectionProperty, FloatProperty from bpy_extras.io_utils import ImportHelper, ExportHelper # from . import common, exportb3d, imghelp, importb3d @@ -75,8 +49,9 @@ class ActiveBlock(bpy.types.PropertyGroup): name: StringProperty() state : BoolProperty() + class HTImportPreferences(bpy.types.AddonPreferences): - bl_idname = __package__ + bl_idname = "b3d_tools" COMMON_RES_Path: bpy.props.StringProperty( name="Common.res path", @@ -136,6 +111,9 @@ class ImportB3D(bpy.types.Operator, ImportHelper): description='Unpack associated with .b3d fie .res archive. \n'\ 'NOTE: .res archive must be located in the same folder as .b3d file', default=False) + to_convert_txr : BoolProperty(name='Convert .txr to .tga', + description='Convert .txr from unpacked .res to .tga', default=False) + to_import_textures : BoolProperty(name='Import Textures', description='Import textures from unpacked .res archive. \n'\ 'NOTE: if importing for the first time select previous option too', default=False) @@ -230,6 +208,8 @@ def draw(self, context): row = box1.row() row.prop(self, 'to_unpack_res') row = box1.row() + row.prop(self, 'to_convert_txr') + row = box1.row() row.prop(self, 'to_import_textures') row = box1.row() row.prop(self, 'textures_format') @@ -321,7 +301,8 @@ def menu_func_import(self, context): def menu_func_export(self, context): self.layout.operator(ExportB3D.bl_idname, text='KOTR B3D (.b3d)') -classes = ( +_classes = ( + common.SCENE_UL_list, HTImportPreferences, ImportB3D, ImportRAW, @@ -331,26 +312,24 @@ def menu_func_export(self, context): -def register(): +def b3d_register(): print("registering addon") # import importlib # for cls in classes: # importlib.reload(cls) bpy.utils.register_class(ActiveBlock) - for cls in classes: + bpy.utils.register_class(common.FloatBlock) + for cls in _classes: bpy.utils.register_class(cls) bpy.types.TOPBAR_MT_file_import.append(menu_func_import) bpy.types.TOPBAR_MT_file_export.append(menu_func_export) -def unregister(): +def b3d_unregister(): print("unregistering addon") bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) - for cls in classes: + for cls in _classes: bpy.utils.unregister_class(cls) + bpy.utils.unregister_class(common.FloatBlock) bpy.utils.unregister_class(ActiveBlock) - - -if __name__ == "__main__": - register() diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py new file mode 100644 index 0000000..74b818e --- /dev/null +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -0,0 +1,1501 @@ +from email.policy import default +import bpy +import enum + +from bpy.props import (StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + EnumProperty, + PointerProperty, + FloatVectorProperty, + CollectionProperty + ) + +from bpy.types import (Panel, + Operator, + PropertyGroup, + ) + +from b3d_tools.common import log +from b3d_tools.b3d.common import FloatBlock + + +class fieldType(enum.Enum): + STRING = 1 + COORD = 2 + RAD = 3 + INT = 4 + FLOAT = 5 + ENUM = 6 + LIST = 7 + + + +def createTypeClass(zclass): + attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + attributes = { + '__annotations__' : { + + } + } + for attr in attrs: + obj = zclass.__dict__[attr] + propName = obj['prop'] + prop = None + + prop = BoolProperty( + name = "Вкл./Выкл.", + description = "Включить/выключить параметр для редактирования", + default = True + ) + attributes['__annotations__']["show_"+propName] = prop + + if obj['type'] == fieldType.STRING: + prop = StringProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'], + maxlen = 30 + ) + elif obj['type'] == fieldType.COORD: + prop = FloatVectorProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'] + ) + elif obj['type'] == fieldType.RAD or obj['type'] == fieldType.FLOAT: + prop = FloatProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'] + ) + elif obj['type'] == fieldType.INT: + prop = IntProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'] + ) + elif obj['type'] == fieldType.ENUM: + prop = EnumProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'], + items = obj['items'] + ) + elif obj['type'] == fieldType.LIST: + prop = CollectionProperty( + name = obj['name'], + description = obj['description'], + type = FloatBlock + ) + attributes['__annotations__'][propName] = prop + newclass = type("{}_gen".format(zclass.__name__), (bpy.types.PropertyGroup,), attributes) + return newclass + +class b_common(): + LevelGroup = { + 'prop': 'level_group', + 'type': fieldType.INT, + 'name': 'Группа блока', + 'description': '', + 'default': 0 + } + +class b_1(): + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Неизв. название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Неизв. название 2', + 'description': '', + 'default': '' + } + +class b_2(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_3(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + +class b_4(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Название 2', + 'description': '', + 'default': '' + } + +class b_5(): + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Имя блока', + 'description': '', + 'default': '' + } + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + +# block_5 = type("block_5", (bpy.types.PropertyGroup,), { +# '__annotations__': { +# 'name': StringProperty( +# name="Имя блока", +# default="", +# maxlen=30, +# ), +# 'XYZ': FloatVectorProperty( +# name='Координаты блока', +# description='', +# default=(0.0, 0.0, 0.0) +# ), +# 'R': FloatProperty( +# name = "Радиус", +# description = "", + +# ) +# } +# }) + +class b_6(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Название 2', + 'description': '', + 'default': '' + } + +class b_7(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название группы', + 'description': '', + 'default': '' + } + +class b_8(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + +class b_9(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_10(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + LOD_XYZ = { + 'prop': 'LOD_XYZ', + 'type': fieldType.COORD, + 'name': 'Центр LOD', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + LOD_R = { + 'prop': 'LOD_R', + 'type': fieldType.RAD, + 'name': 'Радиус LOD', + 'description': '', + 'default': 0.0 + } + +class b_11(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_12(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_13(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_14(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_15(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_16(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Float2 = { + 'prop': 'float2', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 3', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 4', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_17(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Float2 = { + 'prop': 'float2', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 3', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 4', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_18(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Space_Name = { + 'prop': 'space_name', + 'type': fieldType.STRING, + 'name': 'Название трансформации (24)', + 'description': '', + 'default': '' + } + Add_Name = { + 'prop': 'add_name', + 'type': fieldType.STRING, + 'name': 'Название переносимого блока', + 'description': '', + 'default': '' + } + +class b_20(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_21(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + +class b_22(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_23(): + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Surface = { + 'prop': 'CType', + 'type': fieldType.INT, + 'name': 'Тип поверхности', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_24(): + Flag = { + 'prop': 'flag', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + +class b_25(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Name = { + 'prop': 'name', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Float2 = { + 'prop': 'float2', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0.0 + } + Unk_Float3 = { + 'prop': 'float3', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 3', + 'description': '', + 'default': 0.0 + } + Unk_Float4 = { + 'prop': 'float4', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 4', + 'description': '', + 'default': 0.0 + } + Unk_Float5 = { + 'prop': 'float5', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 5', + 'description': '', + 'default': 0.0 + } + +class b_26(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ3 = { + 'prop': 'unk_XYZ3', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 3', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + +class b_27(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Flag = { + 'prop': 'flag', + 'type': fieldType.INT, + 'name': 'Флаг', + 'description': '', + 'default': 0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Material = { + 'prop': 'material', + 'type': fieldType.INT, + 'name': 'Материал', + 'description': '', + 'default': 0 + } + +class b_28(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + #todo: check + +class b_29(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_30(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name = { + 'prop': 'name', + 'type': fieldType.STRING, + 'name': 'Название комнаты', + 'description': '', + 'default': '' + } + XYZ1 = { + 'prop': 'XYZ1', + 'type': fieldType.COORD, + 'name': 'Координаты 1. точки', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + XYZ2 = { + 'prop': 'XYZ2', + 'type': fieldType.COORD, + 'name': 'Координаты 2. точки', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + +class b_31(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + #todo: check + +class b_33(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Use_Lights = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Исп. свет', + 'description': '', + 'default': 0 + } + Light_Type = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Тип света', + 'description': '', + 'default': 0 + } + Flag = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Флаг', + 'description': '', + 'default': 0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизв. 1', + 'description': '', + 'default': 0.0 + } + Unk_Float2 = { + 'prop': 'float2', + 'type': fieldType.FLOAT, + 'name': 'Неизв. 2', + 'description': '', + 'default': 0.0 + } + Light_R = { + 'prop': 'light_radius', + 'type': fieldType.FLOAT, + 'name': 'Радиус света', + 'description': '', + 'default': 0.0 + } + Intens = { + 'prop': 'intensity', + 'type': fieldType.FLOAT, + 'name': 'Интенсивность', + 'description': '', + 'default': 0.0 + } + Unk_Float3 = { + 'prop': 'float3', + 'type': fieldType.FLOAT, + 'name': 'Неизв. 3', + 'description': '', + 'default': 0.0 + } + Unk_Float4 = { + 'prop': 'float4', + 'type': fieldType.FLOAT, + 'name': 'Неизв. 4', + 'description': '', + 'default': 0.0 + } + RGB = { + 'prop': 'rgb', + 'type': fieldType.COORD, + 'name': 'RGB', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + + +class b_34(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + #todo check + +class b_35(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + MType = { + 'prop': 'mType', + 'type': fieldType.INT, + 'name': 'Переменная 1', + 'description': '', + 'default': 0 + } + TexNum = { + 'prop': 'texnum', + 'type': fieldType.INT, + 'name': 'Номер текстуры', + 'description': '', + 'default': 0 + } + +class b_36(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Название 2', + 'description': '', + 'default': '' + } + MType = { + 'prop': 'MType', + 'type': fieldType.INT, + 'name': 'Переменная 1', + 'description': '', + 'default': 0 + } + +class b_37(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + SType = { + 'prop': 'SType', + 'type': fieldType.INT, + 'name': 'Переменная 1', + 'description': '', + 'default': 0 + } + +class b_39(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Color_R = { + 'prop': 'color_r', + 'type': fieldType.INT, + 'name': 'Радиус цвета', + 'description': '', + 'default': 0 + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Fog_Start = { + 'prop': 'fog_start', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 3', + 'description': '', + 'default': 0.0 + } + Fog_End = { + 'prop': 'fog_end', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 4', + 'description': '', + 'default': 0.0 + } + Color_Id = { + 'prop': 'color_id', + 'type': fieldType.INT, + 'name': 'ID цвета', + 'description': '', + 'default': 0 + } + +class b_40(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Название 2', + 'description': '', + 'default': '' + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + #todo check + + +block_common = createTypeClass(b_common) +block_1 = createTypeClass(b_1) +block_2 = createTypeClass(b_2) +block_3 = createTypeClass(b_3) +block_4 = createTypeClass(b_4) +block_5 = createTypeClass(b_5) +block_6 = createTypeClass(b_6) +block_7 = createTypeClass(b_7) +block_8 = createTypeClass(b_8) +block_9 = createTypeClass(b_9) +block_10 = createTypeClass(b_10) +block_11 = createTypeClass(b_11) +block_12 = createTypeClass(b_12) +block_13 = createTypeClass(b_13) +block_14 = createTypeClass(b_14) +block_15 = createTypeClass(b_15) +block_16 = createTypeClass(b_16) +block_17 = createTypeClass(b_17) +block_18 = createTypeClass(b_18) +block_20 = createTypeClass(b_20) +block_21 = createTypeClass(b_21) +block_22 = createTypeClass(b_22) +block_23 = createTypeClass(b_23) +block_24 = createTypeClass(b_24) +block_25 = createTypeClass(b_25) +block_26 = createTypeClass(b_26) +block_27 = createTypeClass(b_27) +block_28 = createTypeClass(b_28) +block_29 = createTypeClass(b_29) +block_30 = createTypeClass(b_30) +block_31 = createTypeClass(b_31) +block_33 = createTypeClass(b_33) +block_34 = createTypeClass(b_34) +block_35 = createTypeClass(b_35) +block_36 = createTypeClass(b_36) +block_37 = createTypeClass(b_37) +block_39 = createTypeClass(b_39) +block_40 = createTypeClass(b_40) diff --git a/src/2.80/addons/importb3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py similarity index 89% rename from src/2.80/addons/importb3d/common.py rename to src/2.80/addons/b3d_tools/b3d/common.py index ac05f6b..288e567 100644 --- a/src/2.80/addons/importb3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -4,9 +4,27 @@ import logging import sys -logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) -log = logging.getLogger("common") -log.setLevel(logging.DEBUG) +from b3d_tools.common import log + +from bpy.props import FloatProperty, IntProperty +from bpy.types import UIList + +# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +# log = logging.getLogger("common") +# log.setLevel(logging.DEBUG) + +class SCENE_UL_list(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + + if self.layout_type in {'DEFAULT', 'COMPACT'}: + layout.prop(item, "value", text="") + elif self.layout_type in {'GRID'}: + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) + +class FloatBlock(bpy.types.PropertyGroup): + index: IntProperty() + value: FloatProperty() def ShowMessageBox(message = "", title = "Message Box", icon = 'INFO'): diff --git a/src/2.80/addons/importb3d/exportb3d.py b/src/2.80/addons/b3d_tools/b3d/exportb3d.py similarity index 100% rename from src/2.80/addons/importb3d/exportb3d.py rename to src/2.80/addons/b3d_tools/b3d/exportb3d.py diff --git a/src/2.80/addons/importb3d/imghelp.py b/src/2.80/addons/b3d_tools/b3d/imghelp.py similarity index 98% rename from src/2.80/addons/importb3d/imghelp.py rename to src/2.80/addons/b3d_tools/b3d/imghelp.py index dbc93b5..2c11f24 100644 --- a/src/2.80/addons/importb3d/imghelp.py +++ b/src/2.80/addons/b3d_tools/b3d/imghelp.py @@ -4,9 +4,12 @@ import logging import sys -logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) -log = logging.getLogger("imghelp") -log.setLevel(logging.DEBUG) + +from b3d_tools.common import log + +# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +# log = logging.getLogger("imghelp") +# log.setLevel(logging.DEBUG) def parsePLM(filepath): colors = [] diff --git a/src/2.80/addons/importb3d/importb3d.py b/src/2.80/addons/b3d_tools/b3d/importb3d.py similarity index 71% rename from src/2.80/addons/importb3d/importb3d.py rename to src/2.80/addons/b3d_tools/b3d/importb3d.py index 2cda2c9..0bddd2a 100644 --- a/src/2.80/addons/importb3d/importb3d.py +++ b/src/2.80/addons/b3d_tools/b3d/importb3d.py @@ -8,6 +8,52 @@ import pdb import logging from pathlib import Path + +from .classes import ( + b_1, + b_2, + b_3, + b_4, + b_5, + b_6, + b_7, + b_8, + b_9, + b_10, + b_11, + b_12, + b_13, + b_14, + b_15, + b_16, + b_17, + b_18, + b_20, + b_21, + b_22, + b_23, + b_24, + b_25, + b_26, + b_27, + b_28, + b_29, + b_30, + b_31, + b_33, + b_34, + b_35, + b_36, + b_37, + b_39, + b_40 +) + +from .panel.common import ( + prop +) + + from .imghelp import TXRtoTGA32 from .imghelp import parsePLM from .common import ShowMessageBox, Vector3F, createMaterial, getUsedFaces, getUsedFace, getUsedVerticesAndTransform, getUserVertices, parseMaterials, readCString, RESUnpack, transformVertices @@ -28,9 +74,15 @@ import bmesh -logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) -log = logging.getLogger("importb3d") -log.setLevel(logging.DEBUG) +from b3d_tools.common import log + +# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +# log = logging.getLogger("importb3d") +# log.setLevel(logging.DEBUG) + + + + class ChunkType(enum.Enum): END_CHUNK = 0 @@ -240,8 +292,6 @@ def parseRAW(file, context, op, filepath): # log.debug('Quad') faces1.append((counter, counter+1, counter+width+1, counter+width)) - log.debug(faces1) - for i in range(width-1): for j in range(i,width-1): counter = j*width+i @@ -282,8 +332,9 @@ def read(file, context, op, filepath): else: log.error("b3d error") - commonResPath = bpy.context.preferences.addons['importb3d'].preferences.COMMON_RES_Path + commonResPath = bpy.context.preferences.addons['b3d_tools'].preferences.COMMON_RES_Path + scene = context.scene #skip to materials list file.seek(21,1) @@ -340,12 +391,13 @@ def read(file, context, op, filepath): #2. Распаковка .RES и конвертация .txr и .msk в .tga 32bit # txrFolder = os.path.join(texturePath, "txr") - folder_content = os.listdir(texturePath) - reTXR = re.compile(r'\.txr') - for path in folder_content: - fullpath = os.path.join(texturePath, path) - if reTXR.search(path): - TXRtoTGA32(fullpath) + if op.to_convert_txr: + folder_content = os.listdir(texturePath) + reTXR = re.compile(r'\.txr') + for path in folder_content: + fullpath = os.path.join(texturePath, path) + if reTXR.search(path): + TXRtoTGA32(fullpath) #3. Парсинг и добавление материалов materials = parseMaterials(materialsPath, basename) @@ -376,11 +428,22 @@ def read(file, context, op, filepath): formats = [] format = 0 # + vertex_block_uvs = [] + poly_block_uvs = [] + uv = [] + # b_1 = block_1() + # b_2_9_11_22 = block_2_9_11_22() + # b_3 = block_3() + # b_4 = block_4() + # b_5 = block_5() + + # log.debug(block_5.XYZ) + b3dName = os.path.basename(filepath) - b3dObj = bpy.data.objects.new(b3dName,None) + b3dObj = bpy.data.objects.new(b3dName, None) b3dObj['block_type'] = 0 context.collection.objects.link(b3dObj) # root object @@ -419,11 +482,21 @@ def read(file, context, op, filepath): # log.info("Importing block #{}: {}".format(type, objName)) # log.info("type: {}, active: {}".format(type, usedBlocks[str(type)])) if (type == 0): # Empty Block - bounding_sphere = struct.unpack("<4f",file.read(16)) - ff = file.seek(28,1) + + # bounding_sphere = struct.unpack("<4f",file.read(16)) + ff = file.seek(44,1) if not usedBlocks[str(type)]: continue + + b3dObj = bpy.data.objects.new(objName, None) + b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['pos'] = str(pos) + + b3dObj.parent = context.scene.objects[objString[-2]] + context.collection.objects.link(b3dObj) + realName = b3dObj.name objString[len(objString)-1] = b3dName elif (type == 1): @@ -437,6 +510,8 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_1.Name1)] = name1 + b3dObj[prop(b_1.Name2)] = name2 b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -456,6 +531,10 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_2.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_2.R)] = bounding_sphere[3] + b3dObj[prop(b_2.Unk_XYZ)] = unknown_sphere[0:3] + b3dObj[prop(b_2.Unk_R)] = unknown_sphere[3] b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -474,6 +553,8 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_3.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_3.R)] = bounding_sphere[3] b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -494,14 +575,19 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_4.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_4.R)] = bounding_sphere[3] + b3dObj[prop(b_4.Name1)] = name1 + b3dObj[prop(b_4.Name2)] = name2 b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name objString[len(objString)-1] = b3dObj.name - elif (type==5): #общий контейнер + elif (type == 5): #общий контейнер + # bounding_sphere bounding_sphere = struct.unpack("<4f",file.read(16)) name = readName(file) childCnt = struct.unpack("> 8 #ah + uvCount = (format & 0xFF00) >> 8 #ah triangulateOffset = format & 0b10000000 if format & 0b10: - coordsPerVertex += 1 + uvCount += 1 + + poly_block_uvs = [{}] + + poly_block_len = len(poly_block_uvs) + + for i in range(uvCount - poly_block_len): + poly_block_uvs.append({}) uunknown = struct.unpack(" 0: - l_uv[face] = vert_uvs[len(vert_uvs)-1] - if format & 0b10000: + for k in range(uvCount): + poly_block_uvs[k][face] = struct.unpack("<2f",file.read(8)) + else: + poly_block_uvs[0][face] = vertex_block_uvs[0][face] + if format & 0b100000 and format & 0b10000: if format & 0b1: - if format & 0b100000: - intens = struct.unpack("<3f",file.read(12)) - intencities.append(intens) - elif format & 0b100000: + intens = struct.unpack("<3f",file.read(12)) + intencities.append(intens) + else: intencity = struct.unpack(" len(overriden_uvs): + for i in range(len(poly_block_uvs)-len(overriden_uvs)): + overriden_uvs.append([]) + #Triangulating faces for t in range(len(faces)-2): if not triangulateOffset: @@ -655,7 +766,10 @@ def read(file, context, op, filepath): else: faces_new.append([faces[t],faces[t+2],faces[t+1]]) - uvs.append((l_uv[faces_new[t][0]],l_uv[faces_new[t][1]],l_uv[faces_new[t][2]])) + for u, over_uv in enumerate(poly_block_uvs): + overriden_uvs[u].append((over_uv[faces_new[t][0]], over_uv[faces_new[t][1]], over_uv[faces_new[t][2]])) + + uv_indexes.append(faces_new[t]) faces_all.extend(faces_new) @@ -681,13 +795,36 @@ def read(file, context, op, filepath): b3dMesh.normals_split_custom_set_from_vertices(normalList) #Setup UV - customUV = b3dMesh.uv_layers.new() - customUV.name = "UVmap" + # customUV = b3dMesh.uv_layers.new() + # customUV.name = "UVmap" - for k, texpoly in enumerate(b3dMesh.polygons): - for j,loop in enumerate(texpoly.loop_indices): - uvsMesh = (uvs[k][j][0], 1-uvs[k][j][1]) - customUV.data[loop].uv = uvsMesh + # for k, texpoly in enumerate(b3dMesh.polygons): + # for j,loop in enumerate(texpoly.loop_indices): + # uvsMesh = (uvs[k][j][0], 1-uvs[k][j][1]) + # customUV.data[loop].uv = uvsMesh + + + for u, uvMap in enumerate(vertex_block_uvs): + + customUV = b3dMesh.uv_layers.new() + customUV.name = "UVmapVert{}".format(u) + uvsMesh = [] + + for i, texpoly in enumerate(b3dMesh.polygons): + for j,loop in enumerate(texpoly.loop_indices): + uvsMesh = (uvMap[uv_indexes[i][j]][0],1 - uvMap[uv_indexes[i][j]][1]) + customUV.data[loop].uv = uvsMesh + + for u, uvOver in enumerate(overriden_uvs): + + customUV = b3dMesh.uv_layers.new() + customUV.name = "UVmapPoly{}".format(u) + uvsMesh = [] + + for i, texpoly in enumerate(b3dMesh.polygons): + for j,loop in enumerate(texpoly.loop_indices): + uvsMesh = [uvOver[i][j][0],1 - uvOver[i][j][1]] + customUV.data[loop].uv = uvsMesh #Create Object @@ -695,6 +832,8 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = pos + b3dObj[prop(b_8.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_8.R)] = bounding_sphere[3] b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) realName = b3dObj.name @@ -735,6 +874,10 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_9.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_9.R)] = bounding_sphere[3] + b3dObj[prop(b_9.Unk_XYZ)] = unknown_sphere[0:3] + b3dObj[prop(b_9.Unk_R)] = unknown_sphere[3] b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -754,6 +897,10 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_10.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_10.R)] = bounding_sphere[3] + b3dObj[prop(b_10.LOD_XYZ)] = unknown_sphere[0:3] + b3dObj[prop(b_10.LOD_R)] = unknown_sphere[3] b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -773,6 +920,10 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_11.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_11.R)] = bounding_sphere[3] + b3dObj[prop(b_11.Unk_XYZ)] = unknown_sphere[0:3] + b3dObj[prop(b_11.Unk_R)] = unknown_sphere[3] b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -796,6 +947,13 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_12.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_12.R)] = bounding_sphere[3] + b3dObj[prop(b_12.Unk_XYZ)] = unknown_sphere[0:3] + b3dObj[prop(b_12.Unk_R)] = unknown_sphere[3] + b3dObj[prop(b_12.Unk_Int1)] = unknown1 + b3dObj[prop(b_12.Unk_Int2)] = unknown2 + b3dObj[prop(b_12.Unk_List)] = coords b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -812,8 +970,6 @@ def read(file, context, op, filepath): cnt = struct.unpack("0: - pass if not usedBlocks[str(type)]: continue @@ -822,6 +978,11 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_13.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_13.R)] = bounding_sphere[3] + b3dObj[prop(b_13.Unk_Int1)] = unknown1 + b3dObj[prop(b_13.Unk_Int2)] = unknown2 + b3dObj[prop(b_13.Unk_List)] = coords b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -830,11 +991,13 @@ def read(file, context, op, filepath): elif (type == 14): #sell_ ? + coords = [] + bounding_sphere = struct.unpack("<4f",file.read(16)) unknown_sphere = struct.unpack("<4f",file.read(16)) - some_var = struct.unpack("0: - pass if not usedBlocks[str(type)]: continue @@ -873,6 +1041,11 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_15.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_15.R)] = bounding_sphere[3] + b3dObj[prop(b_15.Unk_Int1)] = unknown1 + b3dObj[prop(b_15.Unk_Int2)] = unknown2 + b3dObj[prop(b_15.Unk_List)] = coords b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -881,6 +1054,8 @@ def read(file, context, op, filepath): elif (type == 16): + coords = [] + bounding_sphere = struct.unpack("<4f",file.read(16)) vector1 = struct.unpack("<3f",file.read(12)) vector2 = struct.unpack("<3f",file.read(12)) @@ -900,6 +1075,16 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_16.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_16.R)] = bounding_sphere[3] + b3dObj[prop(b_16.Unk_XYZ1)] = vector1 + b3dObj[prop(b_16.Unk_XYZ2)] = vector2 + b3dObj[prop(b_16.Unk_Float1)] = unk1 + b3dObj[prop(b_16.Unk_Float2)] = unk2 + b3dObj[prop(b_16.Unk_Int1)] = unknown1 + b3dObj[prop(b_16.Unk_Int2)] = unknown2 + b3dObj[prop(b_13.Unk_List)] = coords + b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -908,6 +1093,8 @@ def read(file, context, op, filepath): elif (type == 17): + coords = [] + bounding_sphere = struct.unpack("<4f",file.read(16)) vector1 = struct.unpack("<3f",file.read(12)) vector2 = struct.unpack("<3f",file.read(12)) @@ -927,6 +1114,15 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_17.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_17.R)] = bounding_sphere[3] + b3dObj[prop(b_17.Unk_XYZ1)] = vector1 + b3dObj[prop(b_17.Unk_XYZ2)] = vector2 + b3dObj[prop(b_17.Unk_Float1)] = unk1 + b3dObj[prop(b_17.Unk_Float2)] = unk2 + b3dObj[prop(b_17.Unk_Int1)] = unknown1 + b3dObj[prop(b_17.Unk_Int2)] = unknown2 + b3dObj[prop(b_17.Unk_List)] = coords b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -948,8 +1144,10 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) - b3dObj['add_name'] = add_name - b3dObj['space_name'] = space_name + b3dObj[prop(b_18.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_18.R)] = bounding_sphere[3] + b3dObj[prop(b_18.Add_Name)] = add_name + b3dObj[prop(b_18.Space_Name)] = space_name b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -983,11 +1181,13 @@ def read(file, context, op, filepath): unknown1 = struct.unpack("> 8) + 1 #ah - file.seek(4,1) + format = formatRaw & 0xFFFF + uvCount = ((formatRaw & 0xFF00) >> 8) + 1 #ah + triangulateOffset = format & 0b10000000 - unknown3 = struct.unpack(" len(overriden_uvs): + for i in range(len(poly_block_uvs)-len(overriden_uvs)): + overriden_uvs.append([]) + + log.debug(poly_block_uvs) + + #Triangulating faces + for t in range(len(l_faces)-2): + if not triangulateOffset: + if t%2 == 0: + faces_new.append([l_faces[t-1],l_faces[t],l_faces[t+1]]) + else: + faces_new.append([l_faces[t],l_faces[t+1],l_faces[t+2]]) + else: + if t%2 == 0: + faces_new.append([l_faces[t],l_faces[t+1],l_faces[t+2]]) + else: + faces_new.append([l_faces[t],l_faces[t+2],l_faces[t+1]]) + + for u, over_uv in enumerate(poly_block_uvs): + if over_uv: #not empty + overriden_uvs[u].append((over_uv[faces_new[t][0]], over_uv[faces_new[t][1]], over_uv[faces_new[t][2]])) + + log.debug(faces_new) + # store face indexes for setting uv coords later + uv_indexes.append(faces_new[t]) + + l_faces_all.extend(faces_new) + if not usedBlocks[str(type)]: continue b3dMesh = (bpy.data.meshes.new(objName)) + + Ev = threading.Event() + Tr = threading.Thread(target=b3dMesh.from_pydata, args = (l_vertexes,[],l_faces_all)) + Tr.start() + Ev.set() + Tr.join() + + for u, uvMap in enumerate(vertex_block_uvs): + if len(uvMap): + customUV = b3dMesh.uv_layers.new() + customUV.name = "UVmapVert{}".format(u) + uvsMesh = [] + + for i, texpoly in enumerate(b3dMesh.polygons): + for j,loop in enumerate(texpoly.loop_indices): + uvsMesh = (uvMap[uv_indexes[i][j]][0],1 - uvMap[uv_indexes[i][j]][1]) + customUV.data[loop].uv = uvsMesh + + for u, uvOver in enumerate(overriden_uvs): + if len(uvOver): + customUV = b3dMesh.uv_layers.new() + customUV.name = "UVmapPoly{}".format(u) + uvsMesh = [] + + for i, texpoly in enumerate(b3dMesh.polygons): + for j,loop in enumerate(texpoly.loop_indices): + uvsMesh = [uvOver[i][j][0],1 - uvOver[i][j][1]] + customUV.data[loop].uv = uvsMesh + + if op.to_import_textures: + #For assignMaterialByVertices just-in-case + # bpy.ops.object.mode_set(mode = 'OBJECT') + #Set appropriate meaterials + if len(texnums.keys()) > 1: + for texnum in texnums: + mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] + b3dMesh.materials.append(mat) + lastIndex = len(b3dMesh.materials)-1 + + for vertArr in texnums[texnum]: + # op.lock.acquire() + assignMaterialByVertices(b3dObj, vertArr, lastIndex) + # op.lock.release() + else: + for texnum in texnums: + mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] + b3dMesh.materials.append(mat) + b3dObj = bpy.data.objects.new(objName, b3dMesh) b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_28.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_28.R)] = bounding_sphere[3] + b3dObj[prop(b_28.Unk_XYZ)] = sprite_center b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) #добавляем в сцену обьект @@ -1274,6 +1617,12 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_29.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_29.R)] = bounding_sphere[3] + b3dObj[prop(b_29.Unk_Int1)] = num0 + b3dObj[prop(b_29.Unk_Int2)] = num1 + b3dObj[prop(b_29.Unk_XYZ)] = unknown_sphere[0:3] + b3dObj[prop(b_29.Unk_R)] = unknown_sphere[3] b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -1288,17 +1637,21 @@ def read(file, context, op, filepath): connectedRoomName = readName(file) - p1 = Vector3F(file) - p2 = Vector3F(file) + p1 = struct.unpack("<3f",file.read(12)) + p2 = struct.unpack("<3f",file.read(12)) if not usedBlocks[str(type)]: continue + #0-x + #1-y + #2-z + l_vertexes = [ - (p1.x, p1.y, p1.z), - (p1.x, p1.y, p2.z), - (p2.x, p2.y, p2.z), - (p2.x, p2.y, p1.z), + (p1[0], p1[1], p1[2]), + (p1[0], p1[1], p2[2]), + (p2[0], p2[1], p2[2]), + (p2[0], p2[1], p1[2]), ] l_faces = [ @@ -1317,6 +1670,11 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = pos + b3dObj[prop(b_30.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_30.R)] = bounding_sphere[3] + b3dObj[prop(b_30.Name)] = connectedRoomName + b3dObj[prop(b_30.XYZ1)] = p1 + b3dObj[prop(b_30.XYZ2)] = p2 b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -1341,6 +1699,13 @@ def read(file, context, op, filepath): b3dObj['block_type'] = type b3dObj['level_group'] = levelGroups[lvl-1] b3dObj['pos'] = str(pos) + b3dObj[prop(b_31.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_31.R)] = bounding_sphere[3] + b3dObj[prop(b_31.Unk_Int1)] = num + b3dObj[prop(b_31.Unk_XYZ1)] = unknown_sphere[0:3] + b3dObj[prop(b_31.Unk_R)] = unknown_sphere[3] + b3dObj[prop(b_31.Unk_Int2)] = num2 + b3dObj[prop(b_31.Unk_XYZ2)] = unknown b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -1352,20 +1717,19 @@ def read(file, context, op, filepath): bounding_sphere = struct.unpack("<4f",file.read(16)) useLights = struct.unpack("> 8) & 0xF0 #ah + uvCount = (format >> 8) & 0xF0 #ah triangulateOffset = format & 0b10000000 if format & 0b10: - coordsPerVertex += 1 + uvCount += 1 - uunknown = struct.unpack(" 0: - l_uv[face] = vert_uvs[len(vert_uvs)-1] - if format & 0b10000: + for k in range(uvCount): + poly_block_uvs[k][face] = struct.unpack("<2f",file.read(8)) + else: + poly_block_uvs[0][face] = vertex_block_uvs[0][face] + if format & 0b100000 and format & 0b10000: + log.debug("intencities") if format & 0b1: - if format & 0b100000: - intens = struct.unpack("<3f",file.read(12)) - intencities.append(intens) - elif format & 0b100000: + intens = struct.unpack("<3f",file.read(12)) + intencities.append(intens) + else: intencity = struct.unpack(" len(overriden_uvs): + for i in range(len(poly_block_uvs)-len(overriden_uvs)): + overriden_uvs.append([]) + + for u, over_uv in enumerate(poly_block_uvs): + overriden_uvs[u].append((over_uv[faces[0]], over_uv[faces[1]], over_uv[faces[2]])) + + # store face indexes for setting uv coords later + uv_indexes.append((faces[0], faces[1], faces[2])) + + #https://docs.blender.org/api/current/bpy.types.bpy_prop_collection.html#bpy.types.bpy_prop_collection + #seq must be uni-dimensional + # normals_set.extend([normals[faces[0]], normals[faces[1]], normals[faces[2]]]) + # normals_set.extend(list(normals[faces[0]])) + # normals_set.extend(list(normals[faces[1]])) + # normals_set.extend(list(normals[faces[2]])) + # intens_set.extend(list(intencities[faces[0]])) + # intens_set.extend(list(intencities[faces[1]])) + # intens_set.extend(list(intencities[faces[2]])) + # intens_set.extend([intencities[faces[0]], intencities[faces[1]], intencities[faces[2]]]) if not usedBlocks[str(type)]: continue @@ -1473,6 +1885,8 @@ def read(file, context, op, filepath): # newIndices = getUserVertices(curFaces) + # blender generates his own normals, so imported vertex normals doesn't affect + # them too much. if len(normals) > 0: b3dMesh.use_auto_smooth = True normalList = [] @@ -1486,15 +1900,54 @@ def read(file, context, op, filepath): # for i,idx in enumerate(newIndices): # b3dMesh.vertices[idx].normal = normals[idx] - customUV = b3dMesh.uv_layers.new() - customUV.name = "UVmap" - uvsMesh = [] + + + for u, uvMap in enumerate(vertex_block_uvs): + + customUV = b3dMesh.uv_layers.new() + customUV.name = "UVmapVert{}".format(u) + uvsMesh = [] + + for i, texpoly in enumerate(b3dMesh.polygons): + for j,loop in enumerate(texpoly.loop_indices): + uvsMesh = (uvMap[uv_indexes[i][j]][0],1 - uvMap[uv_indexes[i][j]][1]) + customUV.data[loop].uv = uvsMesh + + for u, uvOver in enumerate(overriden_uvs): + + customUV = b3dMesh.uv_layers.new() + customUV.name = "UVmapPoly{}".format(u) + uvsMesh = [] + + for i, texpoly in enumerate(b3dMesh.polygons): + for j,loop in enumerate(texpoly.loop_indices): + uvsMesh = [uvOver[i][j][0],1 - uvOver[i][j][1]] + customUV.data[loop].uv = uvsMesh + + # log.debug(normals_set) + + + # log.debug(len(b3dMesh.attributes["my_normal"].data)) + # log.debug(len(normals_set)) + + # b3dMesh.attributes["my_normal"].data.foreach_set("vector", normals_set) + b3dMesh.attributes.new(name="my_normal", type="FLOAT_VECTOR", domain="POINT") + attr = b3dMesh.attributes["my_normal"].data + for i in range(len(attr)): + setattr(attr[i], "vector", list(normals[newOldTransf[i]])) + + b3dMesh.attributes.new(name="my_intens", type="FLOAT_VECTOR", domain="POINT") + attr = b3dMesh.attributes["my_intens"].data + # b3dMesh.attributes["my_intens"].data.foreach_set("vector", intens_set) + for i in range(len(attr)): + setattr(attr[i], "vector", list(intencities[i])) for i, texpoly in enumerate(b3dMesh.polygons): for j,loop in enumerate(texpoly.loop_indices): - uvsMesh = [uvs[i][j][0],1 - uvs[i][j][1]] + uvsMesh = (uvMap[uv_indexes[i][j]][0],1 - uvMap[uv_indexes[i][j]][1]) customUV.data[loop].uv = uvsMesh + if op.to_import_textures: mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(texNum)] b3dMesh.materials.append(mat) @@ -1502,17 +1955,19 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, b3dMesh) b3dObj.parent = context.scene.objects[objString[-2]] - b3dObj['MType'] = mType - b3dObj['texNum'] = texNum + b3dObj['block_type'] = type + b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['pos'] = str(pos) + b3dObj[prop(b_35.XYZ)] = bounding_sphere[0:3] + b3dObj[prop(b_35.R)] = bounding_sphere[3] + b3dObj[prop(b_35.MType)] = mType + b3dObj[prop(b_35.TexNum)] = texNum b3dObj['FType'] = 0 try: b3dObj['SType'] = b3dObj.parent['SType'] except: b3dObj['SType'] = 2 b3dObj['BType'] = 35 - b3dObj['pos'] = str(pos) - b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] realName = b3dObj.name # for face in b3dMesh.polygons: # face.use_smooth = True @@ -1521,10 +1976,10 @@ def read(file, context, op, filepath): elif (type == 36): - coords25 = [] vertexes = [] normals =[] uv = [] + vertex_block_uvs = [] bounding_sphere = struct.unpack("<4f",file.read(16)) name1 = readName(file) @@ -1534,17 +1989,20 @@ def read(file, context, op, filepath): uvCount = formatRaw >> 8 format = formatRaw & 0xFF + vertex_block_uvs.append([]) + for i in range(uvCount): + vertex_block_uvs.append([]) + vertexCount = struct.unpack("> 8 format = formatRaw & 0xFF + vertex_block_uvs.append([]) + for i in range(uvCount): + vertex_block_uvs.append([]) + + vertexCount = struct.unpack(" 0: @@ -1596,10 +2065,9 @@ def read(file, context, op, filepath): else: for i in range(vertexCount): vertexes.append(struct.unpack("<3f",file.read(12))) - uv.append(struct.unpack("<2f",file.read(8))) + vertex_block_uvs[0].append(struct.unpack("<2f",file.read(8))) for j in range(uvCount): - u = struct.unpack(" 0: + for obj in currentObjs: + nextChildren.extend(obj.children) + currentObjs = nextChildren + allChildren.extend(currentObjs) + else: + break + return allChildren + +def getLODObjects(obj): + vertObjs = None + if obj["level_group"] == 0: + vertObjs = [cn for cn in obj.children if ( \ + cn.get("block_type") is not None + and (cn["block_type"]==6 or cn["block_type"]==7 \ + or cn["block_type"]==36 or cn["block_type"]==37 \ + or cn["block_type"]==8 or cn["block_type"]==35\ + or cn["block_type"]==28)) \ + and (cn.get("level_group") is not None and (cn["level_group"]==1))] + else: # == 1 + vertObjs = [cn for cn in obj.children if ( \ + cn.get("block_type") is not None + and (cn["block_type"]==6 or cn["block_type"]==7 \ + or cn["block_type"]==36 or cn["block_type"]==37 \ + or cn["block_type"]==8 or cn["block_type"]==35 \ + or cn["block_type"]==28))] + # if len(vertObjs) == 0: + # vertObjs = [cn for cn in obj.children if (cn.get("block_type") is not None and (cn["block_type"]==8 or cn["block_type"]==35)) and (cn.get("level_group") is not None and (cn["level_group"]==1))] + # vertObjs.sort(key=lambda x: x.name, reverse=True) + # lodCnt = math.floor(len(vertObjs) / 2) + # return vertObjs[0:lodCnt] + return vertObjs + +def getCondObjects(obj, group): + vertObjs = None + if group != -1: + vertObjs = [cn for cn in obj.children if \ + (cn.get("level_group") is not None and (cn["level_group"]==group))] + else: + vertObjs = [cn for cn in obj.children] + return vertObjs + +def applyTransform(block_18): + + spaceName = block_18["space_name"] + objName = block_18["add_name"] + log.debug("Applying transform {} to object {}".format(spaceName, objName)) + + spaceObj = bpy.data.objects.get(spaceName) + destObj = bpy.data.objects.get(objName) + + if(spaceObj == None): + log.warn("Transformation object not found in "+block_18.name) + return + + if(destObj == None): + log.warn("Destination object not found in "+block_18.name) + return + + # if not destObj.hide_get(): #hidden objects not coopied + + linkObj = None + if bpy.data.objects.get(spaceObj.name + "_b3dSpaceCopy"): + linkObj = bpy.data.objects[spaceObj.name + "_b3dSpaceCopy"] + else: + linkObj = spaceObj.copy() + linkObj.parent = spaceObj.parent + linkObj.rotation_euler[0] = spaceObj.rotation_euler[0] + linkObj.rotation_euler[1] = spaceObj.rotation_euler[1] + linkObj.rotation_euler[2] = spaceObj.rotation_euler[2] + linkObj.location = spaceObj.location + linkObj.name = spaceObj.name + "_b3dSpaceCopy" + bpy.context.collection.objects.link(linkObj) + + reIsCopy = re.compile(r'.*b3dcopy.*') + + allVisibleChildren = [obj for obj in getAllChildren(destObj) if not obj.hide_get()] + + subTransforms = [obj for obj in allVisibleChildren if obj.get("block_type") is not None and obj["block_type"] == 18] + + meshes = [obj for obj in allVisibleChildren if obj.type=="MESH" and not reIsCopy.search(obj.name)] + + newmeshes = [] + + for trans in subTransforms: + subSpaceObj = bpy.data.objects.get(trans["space_name"]+"_b3dSpaceCopy") + if subSpaceObj: + subSpaceObj.parent = linkObj + + log.info("Copying meshes") + for mesh in meshes: + newmesh = mesh.copy() + # newmesh.data = mesh.data.copy() # for NOT linked copy + newmesh.parent = linkObj + newmesh.name = "{}_b3dcopy".format(mesh.name) + newmeshes.append(newmesh) + + log.info("Linking meshes") + for newmesh in newmeshes: + log.info("Linking {}".format(newmesh.name)) + bpy.context.collection.objects.link(newmesh) + + +reb3dSpace = re.compile(r'.*b3dSpaceCopy.*') +reb3dMesh = re.compile(r'.*b3dcopy.*') + +def applyRemoveTransforms(): + toRemove = False + for obj in (bpy.data.objects): + if reb3dSpace.search(obj.name): + toRemove = True + break + if toRemove: + removeTransforms() + else: + applyTransforms() + + +def removeTransforms(): + spaces = [cn for cn in bpy.data.objects if reb3dSpace.search(cn.name)] + meshes = [cn for cn in bpy.data.objects if reb3dMesh.search(cn.name)] + + for mesh in meshes: + mesh.select_set(True) + bpy.ops.object.delete() + + for space in spaces: + space.select_set(True) + bpy.ops.object.delete() + +def applyTransforms(): + objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==18 and not cn.hide_get()] + for obj in objs: + applyTransform(obj) + +def showHideObjByType(type): + objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] + hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] + if len(objs) == len(hiddenObj): + for obj in objs: + obj.hide_set(False) + else: + for obj in objs: + obj.hide_set(True) + +def showHideObjTreeByType(type): + objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] + hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] + if len(objs) == len(hiddenObj): + for obj in objs: + children = getAllChildren(obj) + for child in children: + child.hide_set(False) + obj.hide_set(False) + else: + for obj in objs: + children = getAllChildren(obj) + for child in children: + child.hide_set(True) + obj.hide_set(True) + +def getNBlockHierarchy(root, block_type, rootnum=0, curlevel=0, arr=[]): + for obj in root.children: + if obj['block_type'] == block_type: + arr.append([rootnum, curlevel, obj]) + getNBlockHierarchy(obj, block_type, rootnum, curlevel+1, arr) + rootnum+=1 + getNBlockHierarchy(obj, block_type, rootnum, curlevel, arr) + +def processLOD(root, state): + arr = [] + rootnum = 0 + curlevel = 0 + if root['block_type'] == 10: + arr.append([rootnum, curlevel, root]) + curlevel +=1 + getNBlockHierarchy(root, 10, rootnum, curlevel, arr) + LODRoots = [cn[2] for cn in arr if cn[1]==0] + for LODRoot in LODRoots: + print(LODRoot.name) + lods = [cn for cn in LODRoot.children if (cn.get("level_group") is not None and (cn["level_group"]==1))] + print(len(lods)) + for lod in lods: + if isMeshBlock(lod): + lod.hide_set(state) + else: + for obj in [cn for cn in getAllChildren(lod) if isMeshBlock(cn)]: + obj.hide_set(state) + +def showLOD(root): + processLOD(root, False) + +def hideLOD(root): + processLOD(root, True) + +# def showHideLOD(): +# lodRoots = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==10] +# hiddenLodRoots = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==10 and cn.hide_get()] +# if len(hiddenLodRoots) > 0: #show +# for lodRoot in lodRoots: +# lods = getLODObjects(lodRoot) +# if len(lods) > 0: +# lodRoot.hide_set(False) +# for lod in lods: +# lod.hide_set(False) +# for obj in getAllChildren(lod): +# obj.hide_set(False) +# else: #hide +# for lodRoot in lodRoots: +# lods = getLODObjects(lodRoot) +# if len(lods) > 0: +# lodRoot.hide_set(True) +# for lod in lods: +# lod.hide_set(True) +# for obj in getAllChildren(lod): +# obj.hide_set(True) + +# def get21blocks(root, rootnum=0, curlevel=0, arr=[]): +# for obj in root.children: +# if obj['block_type'] == 21: +# arr.append([rootnum, curlevel, obj]) +# get21blocks(obj, rootnum, curlevel+1, arr) +# rootnum+=1 +# get21blocks(obj, rootnum, curlevel, arr) + +def isMeshBlock(obj): + # 18 - for correct transform apply + return obj.get("block_type") is not None \ + and (obj["block_type"]==8 or obj["block_type"]==35\ + or obj["block_type"]==28 or obj["block_type"]==18) + + +def processCond(root, group, state): + arr = [] + rootnum = 0 + curlevel = 0 + if root['block_type'] == 21: + arr.append([rootnum, curlevel, root]) + curlevel +=1 + getNBlockHierarchy(root, 21, rootnum, curlevel, arr) + condRoots = sorted(arr, key=lambda arr: arr[1], reverse=True) + for condRootArr in condRoots: + condRoot = condRootArr[2] + groupMax = sorted([cn['level_group'] for cn in condRoot.children], reverse=True)[0] + if group > groupMax: + group = groupMax + print(condRoot.name) + conds = getCondObjects(condRoot, group) + print(len(conds)) + for cond in conds: + if isMeshBlock(cond): + cond.hide_set(state) + else: + for obj in [cn for cn in getAllChildren(cond) if isMeshBlock(cn)]: + obj.hide_set(state) + +def showConditionals(root, group): + processCond(root, group, False) + + +def hideConditionals(root, group): + processCond(root, group, True) + + + +def drawCommon(l_self, obj): + block_type = None + level_group = None + if 'block_type' in obj: + block_type = obj['block_type'] + + if 'level_group' in obj: + level_group = obj['level_group'] + + lenStr = str(len(obj.children)) + + box = l_self.layout.box() + box.label(text="Тип блока: " + str(block_type)) + box.label(text="Кол-во вложенных блоков: " + lenStr) + box.label(text="Группа блока: " + str(level_group)) + +def drawAllFieldsByType(l_self, context, zclass): + drawFieldsByType(l_self, context, b_common) + drawFieldsByType(l_self, context, zclass) + +def drawFieldsByType(l_self, context, zclass): + btype = zclass.__name__.split('_')[1] + bname = "block{}".format(btype) + + attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + for attr in attrs: + obj = zclass.__dict__[attr] + drawFieldByType(l_self, context, obj, bname) + +def drawFieldByType(l_self, context, obj, bname): + ftype = obj['type'] + pname = obj['prop'] + mytool = context.scene.my_tool + box = l_self.layout.box() + box.prop(getattr(mytool, bname), "show_"+pname) + + col = box.column() + if ftype == fieldType.STRING: + col.prop(getattr(mytool, bname), pname) + + elif ftype == fieldType.COORD: + col.prop(getattr(mytool, bname), pname) + + elif ftype == fieldType.RAD: + col.prop(getattr(mytool, bname), pname) + + elif ftype == fieldType.INT: + col.prop(getattr(mytool, bname), pname) + + elif ftype == fieldType.FLOAT: + col.prop(getattr(mytool, bname), pname) + + elif ftype == fieldType.ENUM: + col.prop(getattr(mytool, bname), pname) + + elif ftype == fieldType.LIST: + collect = getattr(mytool, bname) + # col.prop(getattr(mytool, bname), pname) + col.template_list("SCENE_UL_list", "", collect, pname, mytool, "list_index") + # collect = getattr(getattr(mytool, bname), pname) + # print(dir(collect)) + # for item in collect.items(): + # print(item) + # col.prop(item, "value") + + if getattr(getattr(mytool, bname), "show_"+pname): + col.enabled = True + else: + col.enabled = False + +def getAllObjsByType(context, object, zclass): + getObjsByType(context, object, b_common) + getObjsByType(context, object, zclass) + +def getObjsByType(context, object, zclass): + attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + btype = zclass.__name__.split('_')[1] + bname = "block{}".format(btype) + mytool = context.scene.my_tool + for property in attrs: + obj = zclass.__dict__[property] + + # print(dir(getattr(mytool, bname))) + + if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + and getattr(getattr(mytool, bname), "show_"+obj['prop']): + + if obj['type'] == fieldType.FLOAT or obj['type'] == fieldType.RAD: + getattr(mytool, bname)[obj['prop']] = float(object[obj['prop']]) + + elif obj['type'] == fieldType.INT: + getattr(mytool, bname)[obj['prop']] = int(object[obj['prop']]) + + elif obj['type'] == fieldType.STRING: + getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) + + elif obj['type'] == fieldType.LIST: + + col = getattr(getattr(mytool, bname), obj['prop']) + + col.clear() + for i, obj in enumerate(object[obj['prop']]): + item = col.add() + item.index = i + item.value = obj + # getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) + + else: + getattr(mytool, bname)[obj['prop']] = object[obj['prop']] + +def setAllObjsByType(context, object, zclass): + setObjsByType(context, object, b_common) + setObjsByType(context, object, zclass) + + +def setObjsByType(context, object, zclass): + attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + btype = zclass.__name__.split('_')[1] + bname = "block{}".format(btype) + mytool = context.scene.my_tool + for property in attrs: + obj = zclass.__dict__[property] + if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + and getattr(getattr(mytool, bname), "show_"+obj['prop']): + + if obj['type'] == fieldType.FLOAT or obj['type'] == fieldType.RAD: + object[obj['prop']] = float(getattr(mytool, bname)[obj['prop']]) + + elif obj['type'] == fieldType.INT: + object[obj['prop']] = int(getattr(mytool, bname)[obj['prop']]) + + elif obj['type'] == fieldType.STRING: + object[obj['prop']] = str(getattr(mytool, bname)[obj['prop']]) + + elif obj['type'] == fieldType.COORD: + xyz = getattr(mytool, bname)[obj['prop']] + object[obj['prop']] = (xyz[0],xyz[1],xyz[2]) + + elif obj['type'] == fieldType.LIST: + collect = getattr(getattr(mytool, bname), obj['prop']) + + arr = [] + for item in list(collect): + arr.append(item.value) + + object[obj['prop']] = arr + + else: + object[obj['prop']] = getattr(mytool, bname)[obj['prop']] diff --git a/src/2.80/addons/b3d_tools/common.py b/src/2.80/addons/b3d_tools/common.py index b54144f..dba8261 100644 --- a/src/2.80/addons/b3d_tools/common.py +++ b/src/2.80/addons/b3d_tools/common.py @@ -1,185 +1,16 @@ -import math import bpy + import logging import sys -import re - -logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) -log = logging.getLogger("common") - -def getAllChildren(obj): - allChildren = [] - currentObjs = [obj] - while(1): - nextChildren = [] - if len(currentObjs) > 0: - for obj in currentObjs: - nextChildren.extend(obj.children) - currentObjs = nextChildren - allChildren.extend(currentObjs) - else: - break - return allChildren - -def getLODObjects(obj): - vertObjs = None - if obj["level_group"] == 0: - vertObjs = [cn for cn in obj.children if ( \ - cn.get("block_type") is not None - and (cn["block_type"]==6 or cn["block_type"]==7 \ - or cn["block_type"]==36 or cn["block_type"]==37 \ - or cn["block_type"]==8 or cn["block_type"]==35)) \ - and (cn.get("level_group") is not None and (cn["level_group"]==1))] - else: # == 1 - vertObjs = [cn for cn in obj.children if ( \ - cn.get("block_type") is not None - and (cn["block_type"]==6 or cn["block_type"]==7 \ - or cn["block_type"]==36 or cn["block_type"]==37 \ - or cn["block_type"]==8 or cn["block_type"]==35))] - # if len(vertObjs) == 0: - # vertObjs = [cn for cn in obj.children if (cn.get("block_type") is not None and (cn["block_type"]==8 or cn["block_type"]==35)) and (cn.get("level_group") is not None and (cn["level_group"]==1))] - # vertObjs.sort(key=lambda x: x.name, reverse=True) - # lodCnt = math.floor(len(vertObjs) / 2) - # return vertObjs[0:lodCnt] - return vertObjs - - -def applyTransform(block_18): - - spaceName = block_18["space_name"] - objName = block_18["add_name"] - log.debug("Applying transform {} to object {}".format(spaceName, objName)) - - spaceObj = bpy.data.objects.get(spaceName) - destObj = bpy.data.objects.get(objName) - - if(spaceObj == None): - log.warn("Transformation object not found in "+block_18.name) - return - - if(destObj == None): - log.warn("Destination object not found in "+block_18.name) - return - - # if not destObj.hide_get(): #hidden objects not coopied - - linkObj = None - if bpy.data.objects.get(spaceObj.name + "_b3dSpaceCopy"): - linkObj = bpy.data.objects[spaceObj.name + "_b3dSpaceCopy"] - else: - linkObj = spaceObj.copy() - linkObj.parent = spaceObj.parent - linkObj.rotation_euler[0] = spaceObj.rotation_euler[0] - linkObj.rotation_euler[1] = spaceObj.rotation_euler[1] - linkObj.rotation_euler[2] = spaceObj.rotation_euler[2] - linkObj.location = spaceObj.location - linkObj.name = spaceObj.name + "_b3dSpaceCopy" - bpy.context.collection.objects.link(linkObj) - - reIsCopy = re.compile(r'.*b3dcopy.*') - - allVisibleChildren = [obj for obj in getAllChildren(destObj) if not obj.hide_get()] - subTransforms = [obj for obj in allVisibleChildren if obj.get("block_type") is not None and obj["block_type"] == 18] - meshes = [obj for obj in allVisibleChildren if obj.type=="MESH" and not reIsCopy.search(obj.name)] +# https://blenderartists.org/t/solved-adding-a-tab-in-blender-2-8/1133119/3 +def getRegion(): + if bpy.app.version < (2,80,0): + return "TOOLS" + else: + return "UI" - newmeshes = [] - for trans in subTransforms: - subSpaceObj = bpy.data.objects.get(trans["space_name"]+"_b3dSpaceCopy") - if subSpaceObj: - subSpaceObj.parent = linkObj - - log.info("Copying meshes") - for mesh in meshes: - newmesh = mesh.copy() - # newmesh.data = mesh.data.copy() # for NOT linked copy - newmesh.parent = linkObj - newmesh.name = "{}_b3dcopy".format(mesh.name) - newmeshes.append(newmesh) - - log.info("Linking meshes") - for newmesh in newmeshes: - bpy.context.collection.objects.link(newmesh) - - -reb3dSpace = re.compile(r'.*b3dSpaceCopy.*') -reb3dMesh = re.compile(r'.*b3dcopy.*') - -def applyRemoveTransforms(): - toRemove = False - for obj in (bpy.data.objects): - if reb3dSpace.search(obj.name): - toRemove = True - break - if toRemove: - removeTransforms() - else: - applyTransforms() - - -def removeTransforms(): - spaces = [cn for cn in bpy.data.objects if reb3dSpace.search(cn.name)] - meshes = [cn for cn in bpy.data.objects if reb3dMesh.search(cn.name)] - - for mesh in meshes: - mesh.select_set(True) - bpy.ops.object.delete() - - for space in spaces: - space.select_set(True) - bpy.ops.object.delete() - -def applyTransforms(): - objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==18] - for obj in objs: - applyTransform(obj) - -def showHideObjByType(type): - objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] - hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] - if len(objs) == len(hiddenObj): - for obj in objs: - obj.hide_set(False) - else: - for obj in objs: - obj.hide_set(True) - -def showHideObjTreeByType(type): - objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] - hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] - if len(objs) == len(hiddenObj): - for obj in objs: - children = getAllChildren(obj) - for child in children: - child.hide_set(False) - obj.hide_set(False) - else: - for obj in objs: - children = getAllChildren(obj) - for child in children: - child.hide_set(True) - obj.hide_set(True) - -def showHideLOD(): - lodRoots = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==10] - hiddenLodRoots = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==10 and cn.hide_get()] - if len(hiddenLodRoots) > 0: #show - for lodRoot in lodRoots: - lods = getLODObjects(lodRoot) - if len(lods) > 0: - lodRoot.hide_set(False) - for lod in lods: - lod.hide_set(False) - for obj in getAllChildren(lod): - obj.hide_set(False) - else: #hide - for lodRoot in lodRoots: - lods = getLODObjects(lodRoot) - if len(lods) > 0: - lodRoot.hide_set(True) - for lod in lods: - lod.hide_set(True) - for obj in getAllChildren(lod): - obj.hide_set(True) \ No newline at end of file +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +log = logging.getLogger("common") \ No newline at end of file diff --git a/src/2.80/addons/export_tch/__init__.py b/src/2.80/addons/b3d_tools/tch/__init__.py similarity index 95% rename from src/2.80/addons/export_tch/__init__.py rename to src/2.80/addons/b3d_tools/tch/__init__.py index 4b37cac..e3964a9 100644 --- a/src/2.80/addons/export_tch/__init__.py +++ b/src/2.80/addons/b3d_tools/tch/__init__.py @@ -1,16 +1,3 @@ -bl_info = { - "name": "King of The Road *.tch exporter", - "description": "", - "author": "Andrey Prozhoga", - "version": (0, 0, 1), - "blender": (3, 0, 0), - "location": "3D View > Tools", - "warning": "", - "wiki_url": "", - "tracker_url": "vk.com/rnr_mods", - "category": "Development" -} - import bpy from mathutils import Matrix from math import radians @@ -213,7 +200,6 @@ def forChild(object, root, file, CollisionPlane_num): from bpy_extras.io_utils import ( ImportHelper, ExportHelper, - orientation_helper_factory, path_reference_mode, axis_conversion, ) @@ -277,14 +263,14 @@ def menu_func_export(self, context): self.layout.operator(ExportTch.bl_idname, text="Export KOTR tch") -def register(): +def tch_register(): bpy.utils.register_class(ImportTch) bpy.types.TOPBAR_MT_file_import.append(menu_func_import) bpy.utils.register_class(ExportTch) bpy.types.TOPBAR_MT_file_export.append(menu_func_export) -def unregister(): +def tch_unregister(): bpy.utils.unregister_class(ImportTch) bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) bpy.utils.unregister_class(ExportTch) diff --git a/src/2.80/addons/way_tools/__init__.py b/src/2.80/addons/b3d_tools/way/__init__.py similarity index 97% rename from src/2.80/addons/way_tools/__init__.py rename to src/2.80/addons/b3d_tools/way/__init__.py index ac5e783..9c2f08c 100644 --- a/src/2.80/addons/way_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/way/__init__.py @@ -1,16 +1,3 @@ -bl_info = { - "name": "King of The Road *.way exporter", - "description": "", - "author": "Andrey Prozhoga", - "version": (0, 0, 1), - "blender": (3, 0, 0), - "location": "3D View > Tools", - "warning": "", - "wiki_url": "", - "tracker_url": "vk.com/rnr_mods", - "category": "Development" -} - # To support reload properly, try to access a package var, if it's there, # reload everything if "bpy" in locals(): @@ -38,18 +25,11 @@ PropertyGroup, ) +from b3d_tools.common import getRegion + import struct bytes_len = 0 - - -# https://blenderartists.org/t/solved-adding-a-tab-in-blender-2-8/1133119/3 -def getRegion(): - if bpy.app.version < (2,80,0): - return "TOOLS" - else: - return "UI" - # panel class PanelSettings1(PropertyGroup): @@ -1141,7 +1121,7 @@ def menu_func_export(self, context): def menu_func_import(self, context): self.layout.operator(ImportSomeData.bl_idname, text="KOTR WAY (.way)") -classes = ( +_classes = ( PanelSettings1, AddOperator1, SetValuesOperator1, @@ -1156,18 +1136,18 @@ def menu_func_import(self, context): ) -def register(): - for cls in classes: +def way_register(): + for cls in _classes: bpy.utils.register_class(cls) bpy.types.TOPBAR_MT_file_export.append(menu_func_export) bpy.types.TOPBAR_MT_file_import.append(menu_func_import) bpy.types.Scene.way_tool = bpy.props.PointerProperty(type=PanelSettings1) -def unregister(): +def way_unregister(): del bpy.types.Scene.way_tool bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) - for cls in classes: + for cls in _classes: bpy.utils.unregister_class(cls) # def register(): @@ -1191,9 +1171,3 @@ def unregister(): # bpy.utils.unregister_module(__name__) # del bpy.types.Scene.way_tool - -if __name__ == "__main__": - register() - - # test call - bpy.ops.export_test.some_data('INVOKE_DEFAULT') diff --git a/src/2.80/addons/way_tools/import_way.py b/src/2.80/addons/b3d_tools/way/import_way.py similarity index 100% rename from src/2.80/addons/way_tools/import_way.py rename to src/2.80/addons/b3d_tools/way/import_way.py From 6ec40c33d8369ab50ec8fa3fb3eff73c3a14a98d Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Wed, 23 Nov 2022 00:02:50 +0200 Subject: [PATCH 16/47] vertices/faces edit --- src/2.80/addons/b3d_tools/b3d/__init__.py | 12 +- src/2.80/addons/b3d_tools/b3d/classes.py | 234 ++++- src/2.80/addons/b3d_tools/b3d/common.py | 27 +- src/2.80/addons/b3d_tools/b3d/importb3d.py | 254 ++++-- .../addons/b3d_tools/b3d/panel/__init__.py | 863 ++++++++++-------- src/2.80/addons/b3d_tools/b3d/panel/common.py | 824 ++++++++++++----- 6 files changed, 1497 insertions(+), 717 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/__init__.py b/src/2.80/addons/b3d_tools/b3d/__init__.py index ef58827..c3268e3 100644 --- a/src/2.80/addons/b3d_tools/b3d/__init__.py +++ b/src/2.80/addons/b3d_tools/b3d/__init__.py @@ -118,13 +118,18 @@ class ImportB3D(bpy.types.Operator, ImportHelper): description='Import textures from unpacked .res archive. \n'\ 'NOTE: if importing for the first time select previous option too', default=False) - textures_format : StringProperty( name="Images format", description="Loaded images format", default="tga", ) + res_location : StringProperty( + name=".res path", + description="Path to .res file location. Default: .res file with name and location of imported .b3d", + default="" + ) + show_all_blocks : EnumProperty( name="Block", items=[ @@ -214,6 +219,11 @@ def draw(self, context): row = box1.row() row.prop(self, 'textures_format') + layout.label(text="Optional settings:") + box1 = layout.box() + row = box1.row() + row.prop(self, 'res_location') + layout.label(text="Blocks to import:") box1 = layout.box() row = box1.row() diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 74b818e..58c0283 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -29,6 +29,7 @@ class fieldType(enum.Enum): FLOAT = 5 ENUM = 6 LIST = 7 + V_FORMAT = 8 @@ -44,55 +45,199 @@ def createTypeClass(zclass): propName = obj['prop'] prop = None - prop = BoolProperty( + lockProp = BoolProperty( name = "Вкл./Выкл.", description = "Включить/выключить параметр для редактирования", default = True ) - attributes['__annotations__']["show_"+propName] = prop - - if obj['type'] == fieldType.STRING: - prop = StringProperty( - name = obj['name'], - description = obj['description'], - default = obj['default'], - maxlen = 30 - ) - elif obj['type'] == fieldType.COORD: - prop = FloatVectorProperty( - name = obj['name'], - description = obj['description'], - default = obj['default'] - ) - elif obj['type'] == fieldType.RAD or obj['type'] == fieldType.FLOAT: - prop = FloatProperty( - name = obj['name'], - description = obj['description'], - default = obj['default'] + + if obj['type'] == fieldType.STRING \ + or obj['type'] == fieldType.COORD \ + or obj['type'] == fieldType.RAD \ + or obj['type'] == fieldType.FLOAT \ + or obj['type'] == fieldType.INT \ + or obj['type'] == fieldType.ENUM \ + or obj['type'] == fieldType.LIST: + + + attributes['__annotations__']["show_"+propName] = lockProp + + if obj['type'] == fieldType.STRING: + prop = StringProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'], + maxlen = 30 + ) + + elif obj['type'] == fieldType.COORD: + prop = FloatVectorProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'] + ) + + elif obj['type'] == fieldType.RAD or obj['type'] == fieldType.FLOAT: + prop = FloatProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'] + ) + + elif obj['type'] == fieldType.INT: + prop = IntProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'] + ) + + elif obj['type'] == fieldType.ENUM: + prop = EnumProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'], + items = obj['items'] + ) + + elif obj['type'] == fieldType.LIST: + prop = CollectionProperty( + name = obj['name'], + description = obj['description'], + type = FloatBlock + ) + + attributes['__annotations__'][propName] = prop + + elif obj['type'] == fieldType.V_FORMAT: + + attributes['__annotations__']["show_{}".format(propName)] = lockProp + + prop1 = BoolProperty( + name = 'Смещенная триангуляция', + description = 'Порядок в котором считываются вертексы, зависит от этой переменной', + default = True ) - elif obj['type'] == fieldType.INT: - prop = IntProperty( - name = obj['name'], - description = obj['description'], - default = obj['default'] + attributes['__annotations__']['{}_{}'.format(propName, 'triang_offset')] = prop1 + + prop2 = BoolProperty( + name = 'Использовать UV', + description = 'Когда активен, при экспорте записывает UV.', + default = True ) - elif obj['type'] == fieldType.ENUM: - prop = EnumProperty( - name = obj['name'], - description = obj['description'], - default = obj['default'], - items = obj['items'] + attributes['__annotations__']['{}_{}'.format(propName, 'use_uvs')] = prop2 + + prop3 = BoolProperty( + name = 'Использовать нормали', + description = 'Когда активен, при экспорте записывает нормали.', + default = True ) - elif obj['type'] == fieldType.LIST: - prop = CollectionProperty( - name = obj['name'], - description = obj['description'], - type = FloatBlock + attributes['__annotations__']['{}_{}'.format(propName, 'use_normals')] = prop3 + + prop4 = BoolProperty( + name = 'Выключатель нормалей', + description = 'Когда активен, использует float для вкл./выкл. нормалей. Когда неактивен использует float vector для обычных нормалей. Игнорируется если пункт "Использовать нормали" неактивен', + default = True ) - attributes['__annotations__'][propName] = prop + attributes['__annotations__']['{}_{}'.format(propName, 'normal_flag')] = prop4 + newclass = type("{}_gen".format(zclass.__name__), (bpy.types.PropertyGroup,), attributes) return newclass +class pvb_8(): + Normal_Switch = { + 'prop': 'normal_switch', + 'type': fieldType.FLOAT, + 'name': 'Выключатель нормали', + 'description': '', + 'default': 0.0 + } + Custom_Normal = { + 'prop': 'custom_normal', + 'type': fieldType.COORD, + 'name': 'Кастомная нормаль', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + + +class pvb_35(): + Normal_Switch = { + 'prop': 'normal_switch', + 'type': fieldType.FLOAT, + 'name': 'Выключатель нормали', + 'description': '', + 'default': 0.0 + } + Custom_Normal = { + 'prop': 'custom_normal', + 'type': fieldType.COORD, + 'name': 'Кастомная нормаль', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + +class pfb_8(): + Format_Flags = { + 'prop': 'format_flags', + 'type': fieldType.V_FORMAT, + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + +class pfb_28(): + Format_Flags = { + 'prop': 'format_flags', + 'type': fieldType.V_FORMAT, + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + + +class pfb_35(): + Format_Flags = { + 'prop': 'format_flags', + 'type': fieldType.V_FORMAT, + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + + class b_common(): LevelGroup = { 'prop': 'level_group', @@ -777,10 +922,10 @@ class b_21(): 'description': '', 'default': 0.0 } - Unk_Int1 = { - 'prop': 'int1', + GroupCnt = { + 'prop': 'group_cnt', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Количество групп', 'description': '', 'default': 0 } @@ -1461,6 +1606,13 @@ class b_40(): #todo check +perFaceBlock_8 = createTypeClass(pfb_8) +perFaceBlock_28 = createTypeClass(pfb_28) +perFaceBlock_35 = createTypeClass(pfb_35) + +perVertBlock_8 = createTypeClass(pvb_8) +perVertBlock_35 = createTypeClass(pvb_35) + block_common = createTypeClass(b_common) block_1 = createTypeClass(b_1) block_2 = createTypeClass(b_2) diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 288e567..8519a47 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -230,4 +230,29 @@ def getUsedFace(face, idxTransf): newFace = [] for idx in face: newFace.append(idxTransf[idx]) - return newFace \ No newline at end of file + return newFace + + +def getPolygonsBySelectedVertices(obj): + data = obj.data + # data = bpy.context.object.data + selectedPolygons = [] + for f in data.polygons: + s = True + for v in f.vertices: + if not data.vertices[v].select: + s = False + break + if s: + selectedPolygons.append(f) + return selectedPolygons + +def getSelectedVertices(obj): + data = obj.data + # data = bpy.context.object.data + selectedVertices = [] + for v in data.vertices: + if v.select: + selectedVertices.append(v) + + return selectedVertices \ No newline at end of file diff --git a/src/2.80/addons/b3d_tools/b3d/importb3d.py b/src/2.80/addons/b3d_tools/b3d/importb3d.py index 0bddd2a..0e4a9d2 100644 --- a/src/2.80/addons/b3d_tools/b3d/importb3d.py +++ b/src/2.80/addons/b3d_tools/b3d/importb3d.py @@ -46,17 +46,36 @@ b_36, b_37, b_39, - b_40 + b_40, + pfb_8, + pfb_28, + pfb_35, + pvb_8, + pvb_35 ) from .panel.common import ( - prop + prop, + createCustomAttribute ) from .imghelp import TXRtoTGA32 from .imghelp import parsePLM -from .common import ShowMessageBox, Vector3F, createMaterial, getUsedFaces, getUsedFace, getUsedVerticesAndTransform, getUserVertices, parseMaterials, readCString, RESUnpack, transformVertices +from .common import ( + ShowMessageBox, + Vector3F, + createMaterial, + getUsedFaces, + getUsedFace, + getUsedVerticesAndTransform, + getUserVertices, + parseMaterials, + readCString, + RESUnpack, + transformVertices, + getPolygonsBySelectedVertices +) import bpy import mathutils @@ -286,20 +305,16 @@ def parseRAW(file, context, op, filepath): for j in range(i,width-1): counter = i*width+j if i == j: - # log.debug('Triangle') faces1.append((counter, counter+1, counter+width+1)) else: - # log.debug('Quad') faces1.append((counter, counter+1, counter+width+1, counter+width)) for i in range(width-1): for j in range(i,width-1): counter = j*width+i if i == j: - # log.debug('Triangle') faces2.append((counter, counter+width, counter+width+1)) else: - # log.debug('Quad') faces2.append((counter, counter+1, counter+width+1, counter+width)) @@ -346,8 +361,18 @@ def read(file, context, op, filepath): noextPath, ext = os.path.splitext(filepath) basepath = os.path.dirname(filepath) basename = os.path.basename(filepath)[:-4] #cut extension + + #Пути - resPath = os.path.join(noextPath + ".res") + resPath = '' + if len(op.res_location) > 0 and os.path.exists(op.res_location): + resPath = op.res_location + else: + resPath = os.path.join(noextPath + ".res") + + res_basepath = os.path.dirname(resPath) + res_basename = os.path.basename(resPath)[:-4] #cut extension + # commonPath = os.path.join(bpy.context.preferences.addons['importb3d'].preferences.COMMON_RES_Path, r"COMMON") blocksToImport = op.blocks_to_import @@ -359,9 +384,9 @@ def read(file, context, op, filepath): RESUnpacked = None if op.to_import_textures: if op.to_unpack_res: - RESUnpacked = unpackRES(resPath, basename, True) + RESUnpacked = unpackRES(resPath, res_basename, True) else: - RESUnpacked = unpackRES(resPath, basename, False) + RESUnpacked = unpackRES(resPath, res_basename, False) if op.to_import_textures and not os.path.exists(commonResPath): # ShowMessageBox("Common.res path is wrong or is not set. Textures weren't imported! Please, set path to Common.res in addon preferences.", @@ -374,7 +399,7 @@ def read(file, context, op, filepath): # commonResPath = os.path.join(commonPath, r"COMMON.RES") commonPath = os.path.join(os.path.dirname(commonResPath)) palettePath = os.path.join(commonPath, r"COMMON_unpack/PALETTEFILES/common.plm") - unpackPath = os.path.join(basepath, basename + r"_unpack") + unpackPath = os.path.join(res_basepath, res_basename + r"_unpack") materialsPath = os.path.join(unpackPath, r"MATERIALS", "MATERIALS.txt") colorsPath = os.path.join(unpackPath, r"COLORS", "COLORS.txt") texturePath = os.path.join(unpackPath, r"TEXTUREFILES") @@ -400,7 +425,7 @@ def read(file, context, op, filepath): TXRtoTGA32(fullpath) #3. Парсинг и добавление материалов - materials = parseMaterials(materialsPath, basename) + materials = parseMaterials(materialsPath, res_basename) for material in materials: createMaterial(commonPalette, RESUnpacked.textures, texturePath, material, op.textures_format) @@ -433,14 +458,6 @@ def read(file, context, op, filepath): uv = [] - # b_1 = block_1() - # b_2_9_11_22 = block_2_9_11_22() - # b_3 = block_3() - # b_4 = block_4() - # b_5 = block_5() - - # log.debug(block_5.XYZ) - b3dName = os.path.basename(filepath) b3dObj = bpy.data.objects.new(b3dName, None) @@ -610,6 +627,8 @@ def read(file, context, op, filepath): elif (type == 6): vertexes = [] uv = [] + normals = [] + normals_off = [] bounding_sphere = struct.unpack("<4f",file.read(16)) name1 = readName(file) @@ -619,6 +638,7 @@ def read(file, context, op, filepath): vertexes.append(struct.unpack("<3f",file.read(12))) uv.append(struct.unpack("<2f",file.read(8))) normals.append((0.0, 0.0, 0.0)) + normals_off.append(1.0) childCnt = struct.unpack("> 8) + 1 #ah triangulateOffset = format & 0b10000000 - unknown3 = struct.unpack("> 8) & 0xF0 #ah + uvCount = (format & 0xFF00) >> 8 #ah triangulateOffset = format & 0b10000000 if format & 0b10: uvCount += 1 + if format & 0b100000 and format & 0b10000: + if format & 0b1: + log.debug("intencities 3f") + else: + log.debug("intencities f") + poly_block_uvs = [{}] poly_block_len = len(poly_block_uvs) @@ -1820,7 +1884,7 @@ def read(file, context, op, filepath): unkF = struct.unpack(" len(overriden_uvs): for i in range(len(poly_block_uvs)-len(overriden_uvs)): @@ -1877,6 +1938,12 @@ def read(file, context, op, filepath): b3dMesh = (bpy.data.meshes.new(objName)) curVertexes, curFaces, indices, oldNewTransf, newOldTransf = getUsedVerticesAndTransform(vertexes, faces_all) + curNormals = [] + curNormalsOff = [] + for i in range(len(curVertexes)): + curNormals.append(l_normals[newOldTransf[i]]) + curNormalsOff.append(l_normals_off[newOldTransf[i]]) + Ev = threading.Event() Tr = threading.Thread(target=b3dMesh.from_pydata, args = (curVertexes,[],curFaces)) Tr.start() @@ -1924,23 +1991,15 @@ def read(file, context, op, filepath): uvsMesh = [uvOver[i][j][0],1 - uvOver[i][j][1]] customUV.data[loop].uv = uvsMesh - # log.debug(normals_set) - - - # log.debug(len(b3dMesh.attributes["my_normal"].data)) - # log.debug(len(normals_set)) # b3dMesh.attributes["my_normal"].data.foreach_set("vector", normals_set) - b3dMesh.attributes.new(name="my_normal", type="FLOAT_VECTOR", domain="POINT") - attr = b3dMesh.attributes["my_normal"].data - for i in range(len(attr)): - setattr(attr[i], "vector", list(normals[newOldTransf[i]])) - b3dMesh.attributes.new(name="my_intens", type="FLOAT_VECTOR", domain="POINT") - attr = b3dMesh.attributes["my_intens"].data - # b3dMesh.attributes["my_intens"].data.foreach_set("vector", intens_set) - for i in range(len(attr)): - setattr(attr[i], "vector", list(intencities[i])) + createCustomAttribute(b3dMesh, formats, pfb_35, pfb_35.Format_Flags) + createCustomAttribute(b3dMesh, unkFs, pfb_35, pfb_35.Unk_Float1) + createCustomAttribute(b3dMesh, unkInts, pfb_35, pfb_35.Unk_Int2) + + createCustomAttribute(b3dMesh, curNormalsOff, pvb_35, pvb_35.Normal_Switch) + createCustomAttribute(b3dMesh, curNormals, pvb_35, pvb_35.Custom_Normal) for i, texpoly in enumerate(b3dMesh.polygons): for j,loop in enumerate(texpoly.loop_indices): @@ -1977,7 +2036,8 @@ def read(file, context, op, filepath): elif (type == 36): vertexes = [] - normals =[] + normals = [] + normals_off = [] uv = [] vertex_block_uvs = [] @@ -1989,6 +2049,11 @@ def read(file, context, op, filepath): uvCount = formatRaw >> 8 format = formatRaw & 0xFF + if format == 1 or format == 2: + log.debug("normals 3f") + elif format == 3: + log.debug("normals f") + vertex_block_uvs.append([]) for i in range(uvCount): vertex_block_uvs.append([]) @@ -2005,15 +2070,13 @@ def read(file, context, op, filepath): vertex_block_uvs[j+1].append(struct.unpack("<2f",file.read(8))) if format == 1 or format == 2: #Vertex with normals normals.append(struct.unpack("<3f",file.read(12))) + normals_off.append(1.0) elif format == 3: #отличается от шаблона 010Editor - normal = struct.unpack("> 8 format = formatRaw & 0xFF + if format == 1 or format == 2: + log.debug("normals 3f") + elif format == 3: + log.debug("normals f") + vertex_block_uvs.append([]) for i in range(uvCount): vertex_block_uvs.append([]) @@ -2070,15 +2139,13 @@ def read(file, context, op, filepath): vertex_block_uvs[j+1].append(struct.unpack("<2f",file.read(8))) if format == 1 or format == 2: #Vertex with normals normals.append(struct.unpack("<3f",file.read(12))) + normals_off.append(1.0) elif format == 3: #отличается от шаблона 010Editor - normal = struct.unpack(" 0: #show -# for lodRoot in lodRoots: -# lods = getLODObjects(lodRoot) -# if len(lods) > 0: -# lodRoot.hide_set(False) -# for lod in lods: -# lod.hide_set(False) -# for obj in getAllChildren(lod): -# obj.hide_set(False) -# else: #hide -# for lodRoot in lodRoots: -# lods = getLODObjects(lodRoot) -# if len(lods) > 0: -# lodRoot.hide_set(True) -# for lod in lods: -# lod.hide_set(True) -# for obj in getAllChildren(lod): -# obj.hide_set(True) - -# def get21blocks(root, rootnum=0, curlevel=0, arr=[]): + roots = [cn for cn in visited.keys() if (visited[cn]["in"] == 0) and (visited[cn]["out"] > 0)] + + res = other + res.extend(roots) + + return res + + +# def getNBlockHierarchy(root, block_type, rootnum=0, curlevel=0, arr=[]): # for obj in root.children: -# if obj['block_type'] == 21: +# if obj['block_type'] == block_type: +# print("block_type block") # arr.append([rootnum, curlevel, obj]) -# get21blocks(obj, rootnum, curlevel+1, arr) +# getNBlockHierarchy(obj, block_type, rootnum, curlevel+1, arr) # rootnum+=1 -# get21blocks(obj, rootnum, curlevel, arr) +# elif obj['block_type'] == 18: +# print("ref block") +# refObj = bpy.data.objects[obj[prop(b_18.Add_Name)]] +# arr.append([rootnum, curlevel, refObj]) +# getNBlockHierarchy(refObj, block_type, rootnum, curlevel+1, arr) +# rootnum+=1 +# getNBlockHierarchy(obj, block_type, rootnum, curlevel, arr) def isMeshBlock(obj): # 18 - for correct transform apply return obj.get("block_type") is not None \ and (obj["block_type"]==8 or obj["block_type"]==35\ - or obj["block_type"]==28 or obj["block_type"]==18) + or obj["block_type"]==28 \ + # or obj["block_type"]==18 + ) + +def isRefBlock(obj): + return obj.get("block_type") is not None and obj["block_type"]==18 + + +def processLOD(root, state, explevel = 0, curlevel = -1): + + stack = [[root, curlevel, False]] + + while stack: + block, clevel, isActive = stack.pop() + + if block['block_type'] == 18: + refObj = bpy.data.objects.get(block['add_name']) + if refObj is not None: + stack.append([refObj, clevel, isActive]) + if isActive: + block.hide_set(state) + + if block['block_type'] == 10: + clevel += 1 + + if isActive and isMeshBlock(block): + block.hide_set(state) + + + for directChild in block.children: + log.debug("Processing {}".format(directChild.name)) + if clevel == explevel: + if directChild['level_group'] == 1: + stack.append([directChild, clevel, True]) + else: + stack.append([directChild, -1, isActive]) + elif clevel > explevel: + stack.append([directChild, clevel, True]) + else: + stack.append([directChild, clevel, isActive]) + + +def showLOD(root): + if root.parent is None: + hroots = getHierarchyRoots(root) + for hroot in hroots: + obj = bpy.data.objects.get(hroot) + if obj is not None: + processLOD(obj, False, 0, -1) + else: + processLOD(root, False, 0, -1) + +def hideLOD(root): + if root.parent is None: + hroots = getHierarchyRoots(root) + for hroot in hroots: + obj = bpy.data.objects.get(hroot) + if obj is not None: + processLOD(obj, True, 0, -1) + else: + processLOD(root, True, 0, -1) def processCond(root, group, state): - arr = [] - rootnum = 0 + curlevel = 0 - if root['block_type'] == 21: - arr.append([rootnum, curlevel, root]) - curlevel +=1 - getNBlockHierarchy(root, 21, rootnum, curlevel, arr) - condRoots = sorted(arr, key=lambda arr: arr[1], reverse=True) - for condRootArr in condRoots: - condRoot = condRootArr[2] - groupMax = sorted([cn['level_group'] for cn in condRoot.children], reverse=True)[0] - if group > groupMax: - group = groupMax - print(condRoot.name) - conds = getCondObjects(condRoot, group) - print(len(conds)) - for cond in conds: - if isMeshBlock(cond): - cond.hide_set(state) + globlevel = 0 + + stack = [[root, curlevel, globlevel, 0, False]] + + while stack: + block, clevel, glevel, groupMax, isActive = stack.pop() + + l_group = group + + if block['block_type'] == 18: + refObj = bpy.data.objects.get(block['add_name']) + if refObj is not None: + stack.append([refObj, clevel+1, glevel, groupMax, isActive]) + if isActive: + block.hide_set(state) + + if block['block_type'] == 21: + glevel += 1 + clevel = 1 + groupMax = block[prop(b_21.GroupCnt)] + if l_group > groupMax-1: + l_group = groupMax-1 + + if isActive and isMeshBlock(block): + block.hide_set(state) + + for directChild in block.children: + log.debug("Processing {}".format(directChild.name)) + nextState = False + if glevel == 1: + nextState = True + elif glevel > 1: + nextState = isActive and True + if clevel == 1: + if directChild['level_group'] == l_group or l_group == -1: + stack.append([directChild, clevel+1, glevel, groupMax, nextState]) + else: + stack.append([directChild, clevel+1, glevel, groupMax, False]) + elif clevel > 1: + stack.append([directChild, clevel+1, glevel, groupMax, isActive]) else: - for obj in [cn for cn in getAllChildren(cond) if isMeshBlock(cn)]: - obj.hide_set(state) + stack.append([directChild, clevel+1, glevel, groupMax, False]) def showConditionals(root, group): - processCond(root, group, False) + + if root.parent is None: + hroots = getHierarchyRoots(root) + for hroot in hroots: + obj = bpy.data.objects.get(hroot) + if obj is not None: + processCond(obj, group, False) + else: + processCond(root, group, False) def hideConditionals(root, group): - processCond(root, group, True) + + if root.parent is None: + hroots = getHierarchyRoots(root) + for hroot in hroots: + obj = bpy.data.objects.get(hroot) + if obj is not None: + processCond(obj, group, True) + else: + processCond(root, group, True) @@ -301,58 +472,93 @@ def drawCommon(l_self, obj): box.label(text="Группа блока: " + str(level_group)) def drawAllFieldsByType(l_self, context, zclass): - drawFieldsByType(l_self, context, b_common) - drawFieldsByType(l_self, context, zclass) + if zclass.__name__.split('_')[0] == 'b': + drawFieldsByType(l_self, context, b_common) + drawFieldsByType(l_self, context, zclass) + else: + drawFieldsByType(l_self, context, zclass) def drawFieldsByType(l_self, context, zclass): - btype = zclass.__name__.split('_')[1] - bname = "block{}".format(btype) + # btype = zclass.__name__.split('_')[1] + # bname = "block{}".format(btype) attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] for attr in attrs: obj = zclass.__dict__[attr] - drawFieldByType(l_self, context, obj, bname) + drawFieldByType(l_self, context, obj, zclass) + +def drawFieldByType(l_self, context, obj, zclass): + + bname = '' + btype, bnum = zclass.__name__.split('_') + if btype == 'b': + bname = 'block{}'.format(bnum) + elif btype == 'pfb': + bname = 'perFaceBlock{}'.format(bnum) + elif btype == 'pvb': + bname = 'perVertBlock{}'.format(bnum) -def drawFieldByType(l_self, context, obj, bname): ftype = obj['type'] pname = obj['prop'] mytool = context.scene.my_tool - box = l_self.layout.box() - box.prop(getattr(mytool, bname), "show_"+pname) - col = box.column() - if ftype == fieldType.STRING: - col.prop(getattr(mytool, bname), pname) + if ftype == fieldType.STRING \ + or ftype == fieldType.COORD \ + or ftype == fieldType.RAD \ + or ftype == fieldType.INT \ + or ftype == fieldType.FLOAT \ + or ftype == fieldType.ENUM \ + or ftype == fieldType.LIST: - elif ftype == fieldType.COORD: - col.prop(getattr(mytool, bname), pname) + box = l_self.layout.box() + box.prop(getattr(mytool, bname), "show_"+pname) - elif ftype == fieldType.RAD: - col.prop(getattr(mytool, bname), pname) + col = box.column() + if ftype == fieldType.STRING: + col.prop(getattr(mytool, bname), pname) - elif ftype == fieldType.INT: - col.prop(getattr(mytool, bname), pname) + elif ftype == fieldType.COORD: + col.prop(getattr(mytool, bname), pname) - elif ftype == fieldType.FLOAT: - col.prop(getattr(mytool, bname), pname) + elif ftype == fieldType.RAD: + col.prop(getattr(mytool, bname), pname) - elif ftype == fieldType.ENUM: - col.prop(getattr(mytool, bname), pname) + elif ftype == fieldType.INT: + col.prop(getattr(mytool, bname), pname) - elif ftype == fieldType.LIST: - collect = getattr(mytool, bname) - # col.prop(getattr(mytool, bname), pname) - col.template_list("SCENE_UL_list", "", collect, pname, mytool, "list_index") - # collect = getattr(getattr(mytool, bname), pname) - # print(dir(collect)) - # for item in collect.items(): - # print(item) - # col.prop(item, "value") + elif ftype == fieldType.FLOAT: + col.prop(getattr(mytool, bname), pname) - if getattr(getattr(mytool, bname), "show_"+pname): - col.enabled = True - else: - col.enabled = False + elif ftype == fieldType.ENUM: + col.prop(getattr(mytool, bname), pname) + + elif ftype == fieldType.LIST: + collect = getattr(mytool, bname) + # col.prop(getattr(mytool, bname), pname) + col.template_list("SCENE_UL_list", "", collect, pname, mytool, "list_index") + # collect = getattr(getattr(mytool, bname), pname) + # print(dir(collect)) + # for item in collect.items(): + # print(item) + # col.prop(item, "value") + + if getattr(getattr(mytool, bname), "show_"+pname): + col.enabled = True + else: + col.enabled = False + elif ftype == fieldType.V_FORMAT: + box = l_self.layout.box() + box.prop(getattr(mytool, bname), "show_{}".format(pname)) + col1 = box.column() + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'triang_offset')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_uvs')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_normals')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'normal_flag')) + + if getattr(getattr(mytool, bname), "show_"+pname): + col1.enabled = True + else: + col1.enabled = False def getAllObjsByType(context, object, zclass): getObjsByType(context, object, b_common) @@ -398,7 +604,6 @@ def setAllObjsByType(context, object, zclass): setObjsByType(context, object, b_common) setObjsByType(context, object, zclass) - def setObjsByType(context, object, zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] btype = zclass.__name__.split('_')[1] @@ -433,3 +638,188 @@ def setObjsByType(context, object, zclass): else: object[obj['prop']] = getattr(mytool, bname)[obj['prop']] + +def getFromAttributes(context, obj, attrs, bname, index): + + mytool = context.scene.my_tool + + + if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + and getattr(getattr(mytool, bname), "show_"+obj['prop']): + + if obj['type'] == fieldType.FLOAT: + getattr(mytool, bname)[obj['prop']] = float(getattr(attrs[index], "value")) + + elif obj['type'] == fieldType.COORD: + getattr(mytool, bname)[obj['prop']] = getattr(attrs[index], "vector") + + elif obj['type'] == fieldType.INT: + getattr(mytool, bname)[obj['prop']] = int(getattr(attrs[index], "value")) + + elif obj['type'] == fieldType.V_FORMAT: + format = getattr(attrs[index], "value") ^ 1 + triangOffset = format & 0b10000000 + useUV = format & 0b10 + useNormals = format & 0b10000 and format & 0b100000 + normalFlag = format & 1 + + getattr(mytool, bname)["{}_{}".format(obj['prop'],'triang_offset')] = triangOffset + getattr(mytool, bname)["{}_{}".format(obj['prop'],'use_uvs')] = useUV + getattr(mytool, bname)["{}_{}".format(obj['prop'],'use_normals')] = useNormals + getattr(mytool, bname)["{}_{}".format(obj['prop'],'normal_flag')] = normalFlag + +def setFromAttributes(context, obj, attrs, bname, index): + + mytool = context.scene.my_tool + + if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + and getattr(getattr(mytool, bname), "show_"+obj['prop']): + + if obj['type'] == fieldType.FLOAT: + attrs[index].value = getattr(mytool, bname)[obj['prop']] + + elif obj['type'] == fieldType.INT: + attrs[index].value = getattr(mytool, bname)[obj['prop']] + + elif obj['type'] == fieldType.COORD: + attrs[index].vector = getattr(mytool, bname)[obj['prop']] + + elif obj['type'] == fieldType.V_FORMAT: + value = 0 + triangOffset = getattr(mytool, bname)['{}_{}'.format(obj['prop'], 'triang_offset')] + useUV = getattr(mytool, bname)['{}_{}'.format(obj['prop'], 'use_uvs')] + useNormals = getattr(mytool, bname)['{}_{}'.format(obj['prop'], 'use_normals')] + normalFlag = getattr(mytool, bname)['{}_{}'.format(obj['prop'], 'normal_flag')] + + if triangOffset: + value = value ^ 0b10000000 + if useUV: + value = value ^ 0b10 + if useNormals: + value = value ^ 0b110000 + if normalFlag: + value = value ^ 0b1 + + value = value ^ 1 + + attrs[index].value = value + +def getPerFaceByType(context, object, zclass): + zattrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + btype = zclass.__name__.split('_')[1] + bname = "perFaceBlock{}".format(btype) + mesh = object.data + bpy.ops.object.mode_set(mode = 'OBJECT') + polygons = getPolygonsBySelectedVertices(object) + indexes = [cn.index for cn in polygons] + + if len(indexes) > 0: + index = indexes[0] + for property in zattrs: + obj = zclass.__dict__[property] + attrs = mesh.attributes[obj['prop']].data + getFromAttributes(context, obj, attrs, bname, index) + + bpy.ops.object.mode_set(mode = 'EDIT') + +def getPerVertexByType(context, object, zclass): + zattrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + btype = zclass.__name__.split('_')[1] + bname = "perVertBlock{}".format(btype) + mesh = object.data + bpy.ops.object.mode_set(mode = 'OBJECT') + vertices = getSelectedVertices(object) + # log.debug(vertices) + indexes = [cn.index for cn in vertices] + + if len(indexes) > 0: + index = indexes[0] + for property in zattrs: + obj = zclass.__dict__[property] + attrs = mesh.attributes[obj['prop']].data + getFromAttributes(context, obj, attrs, bname, index) + + bpy.ops.object.mode_set(mode = 'EDIT') + +def setPerVertexByType(context, object, zclass): + zattrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + btype = zclass.__name__.split('_')[1] + bname = "perVertBlock{}".format(btype) + mesh = object.data + + bpy.ops.object.mode_set(mode = 'OBJECT') + vertices = getSelectedVertices(object) + indexes = [cn.index for cn in vertices] + + for index in indexes: + for property in zattrs: + obj = zclass.__dict__[property] + attrs = mesh.attributes[obj['prop']].data + setFromAttributes(context, obj, attrs, bname, index) + + bpy.ops.object.mode_set(mode = 'EDIT') + +def setPerFaceByType(context, object, zclass): + zattrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + btype = zclass.__name__.split('_')[1] + bname = "perFaceBlock{}".format(btype) + mesh = object.data + + bpy.ops.object.mode_set(mode = 'OBJECT') + polygons = getPolygonsBySelectedVertices(object) + indexes = [cn.index for cn in polygons] + + for index in indexes: + for property in zattrs: + obj = zclass.__dict__[property] + attrs = mesh.attributes[obj['prop']].data + setFromAttributes(context, obj, attrs, bname, index) + + bpy.ops.object.mode_set(mode = 'EDIT') + +def createCustomAttribute(mesh, values, zclass, zobj): + # attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + ctype, btype = zclass.__name__.split('_') + domain = '' + if ctype == 'pvb': + domain = 'POINT' + elif ctype == 'pfb': + domain = 'FACE' + + # log.debug(domain) + # log.debug(zobj['type']) + if zobj['type'] == fieldType.FLOAT: + ztype = 'FLOAT' + mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) + attr = mesh.attributes[zobj['prop']].data + # log.debug(len(attr)) + # log.debug(len(values)) + for i in range(len(attr)): + setattr(attr[i], "value", values[i]) + + elif zobj['type'] == fieldType.COORD: + ztype = 'FLOAT_VECTOR' + mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) + attr = mesh.attributes[zobj['prop']].data + # log.debug(len(attr)) + # log.debug(len(values)) + for i in range(len(attr)): + setattr(attr[i], "vector", values[i]) + + elif zobj['type'] == fieldType.INT: + ztype = 'INT' + mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) + attr = mesh.attributes[zobj['prop']].data + # log.debug(len(attr)) + # log.debug(len(values)) + for i in range(len(attr)): + setattr(attr[i], "value", values[i]) + + elif zobj['type'] == fieldType.V_FORMAT: + ztype = 'INT' + mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) + attr = mesh.attributes[zobj['prop']].data + # log.debug(len(attr)) + # log.debug(len(values)) + for i in range(len(attr)): + setattr(attr[i], "value", values[i]) \ No newline at end of file From 53211642e3fd7a1fc365a92bcc8d44556afcfe9c Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Wed, 23 Nov 2022 00:07:17 +0200 Subject: [PATCH 17/47] b3dsplit --- README.md | 6 + utils/b3dsplit.py | 704 ++++++++++++++++++++++++++++++++++++++++++++++ utils/split.txt | 23 ++ 3 files changed, 733 insertions(+) create mode 100644 utils/b3dsplit.py create mode 100644 utils/split.txt diff --git a/README.md b/README.md index b6ba4e0..8e1d256 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,12 @@ Готовые сцены для экспорта в игру: **ht2-way.blend** - пути транспорта, **ht2-vehicle-export.blend** - транспорт, **ht2-env-module.blend** - карта +#### Папка **utils** + +Прочие полезные скрипты: +b3dsplit - извлечение из b3d-файла прочих моделей в отдельные файлы для импорта. +Пример: python b3dsplit.py ./TRUCKS.b3d ./split.txt + ## Как установить плагины 1. Распаковать архив. 2. Поместить содержимое в папку Blender/2.79/scripts/addons/. diff --git a/utils/b3dsplit.py b/utils/b3dsplit.py new file mode 100644 index 0000000..4ea4b0d --- /dev/null +++ b/utils/b3dsplit.py @@ -0,0 +1,704 @@ +import logging +import struct +import sys +import enum +import json +import os + +filename = '' +outdir = '' + +args = sys.argv + +rootsFile = None +rootsFromFile = False + +if len(args) == 2: + filename = args[1] + outdir = os.path.dirname(filename) +elif len(args) == 3: + rootsFromFile = True + rootsFile = args[2] +else: + print("Wrong number of parameters") + print("") + print('Usage: python b3dsplit.py ') + print(' - (obligatory) Path to .b3d file to export meshes') + print(' - (optional) Path to .txt file with mesh root names. 1 line = 1 name') + print('if not defined or file is empty, script search for roots automatically') + print('Tested with Python v.3.9.13') + sys.exit() + +blocksToExtract = [] + +if rootsFromFile: + if os.path.exists(rootsFile): + with open(rootsFile) as f: + for line in f: + l = line.rstrip() + if len(l) > 0: + blocksToExtract.append(l) + + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +log = logging.getLogger("splitb3d") +log.setLevel(logging.DEBUG) + +def getHierarchyRoots(refObjs): + + graph = {} + + for key in refObjs.keys(): + graph[key] = [cn['add_name'] for cn in refObjs[key]] + + zgraph = Graph(graph) + + visited = zgraph.DFS() + + roots = [cn for cn in visited.keys() if (visited[cn]["in"] == 0) and (visited[cn]["out"] > 0)] + + return roots + +def readName(file): + objName = file.read(32) + if (objName[0] == 0): + objName = "empty name" + #objname = "Untitled_0x" + str(hex(pos-36)) + else: + objName = (objName.decode("cp1251").rstrip('\0')) + return objName + +class ChunkType(enum.Enum): + END_CHUNK = 0 + END_CHUNKS = 1 + BEGIN_CHUNK = 2 + GROUP_CHUNK = 3 + +def openclose(file): + oc = file.read(4) + if (oc == (b'\x4D\x01\x00\x00')): # Begin_Chunk(111) + return ChunkType.BEGIN_CHUNK + elif oc == (b'\x2B\x02\x00\x00'): # End_Chunk(555) + return ChunkType.END_CHUNK + elif oc == (b'\xbc\x01\x00\x00'): # Group_Chunk(444) + return ChunkType.GROUP_CHUNK + elif oc == (b'\xde\x00\00\00'): # End_Chunks(222) + return ChunkType.END_CHUNKS + else: + # log.debug(file.tell()) + raise Exception() + +class Graph: + + def __init__(self, graph): + self.graph = graph + + def DFSUtil(self, val, visited): + + visited[val]["in"] += 1 + for v in self.graph[val]: + if self.graph.get(v) is not None: + visited[val]["out"] += 1 + self.DFSUtil(v, visited) + + def DFS(self, start=None): + V = len(self.graph) #total vertices + + visited = {} + for val in self.graph.keys(): + visited[val] = { + "in": 0, + "out": 0 + } + + searchIn = [] + if start is not None: + searchIn.append(start.name) + else: + searchIn = self.graph.keys() + + for val in searchIn: + for v in self.graph[val]: + if self.graph.get(v) is not None: + visited[val]["out"] += 1 + self.DFSUtil(v, visited) + + return visited + +def read(file): + if file.read(3) == b'b3d': + log.info("correct file") + else: + log.error("b3d error") + + file.seek(1,1) + filesize = struct.unpack("> 8 #ah + + if format & 0b10: + uvCount += 1 + + unkF = struct.unpack("> 8) + 1 #ah + unknown3 = struct.unpack(" 0: + f = struct.unpack("<"+str(num0)+"f",file.read(4*num0)) + + childCnt = struct.unpack("> 8 #ah + + if format & 0b10: + uvCount += 1 + + unkF = struct.unpack("> 8 + format = formatRaw & 0xFF + + vertexCount = struct.unpack("> 8 + format = formatRaw & 0xFF + vertexCount = struct.unpack(" 0: + if format == 0: + # objString[len(objString)-1] = objString[-2] + pass + else: + for i in range(vertexCount): + vertex = struct.unpack("<3f",file.read(12)) + uv = struct.unpack("<2f",file.read(8)) + for j in range(uvCount): + uv = struct.unpack("<2f",file.read(8)) + if format == 1 or format == 2: + normal = struct.unpack("<3f",file.read(12)) + elif format == 3: + normal_off = struct.unpack(" 0: + for add in curLevel: + for block in blocks18[add]: + # log.debug(block) + g_spaces.add(block['space_name']) + g_objs.add(block['add_name']) + objs.add(block['add_name']) + curLevel = list(objs) + objs = set() + + spaces = [cn for cn in list(g_spaces) if cn != 'empty name'] + objs = list(g_objs) + + spaces.sort() + objs.sort(reverse=True) + + + outfilename = os.path.join(outdir, '{}.b3d'.format(extBlock)) + with open(outfilename, 'wb') as outFile: + outFile.write(b'b3d\x00') + outFile.write(struct.pack(" Date: Sun, 25 Dec 2022 00:59:01 +0200 Subject: [PATCH 18/47] b3d refactor --- src/2.80/addons/b3d_tools/__init__.py | 24 +- src/2.80/addons/b3d_tools/b3d/__init__.py | 336 +-------- src/2.80/addons/b3d_tools/b3d/classes.py | 147 +++- src/2.80/addons/b3d_tools/b3d/common.py | 144 ++-- .../b3d/{exportb3d.py => export_b3d.py} | 672 +++++++++++++++++- src/2.80/addons/b3d_tools/b3d/imghelp.py | 2 +- .../b3d/{importb3d.py => import_b3d.py} | 399 +++++++---- src/2.80/addons/b3d_tools/b3d/menus.py | 292 ++++++++ .../b3d/{panel/__init__.py => panel.py} | 324 ++------- .../b3d/{panel/common.py => scripts.py} | 66 +- src/2.80/addons/b3d_tools/consts.py | 156 ++++ src/2.80/addons/b3d_tools/custom_UIList.py | 439 ++++++++++++ src/2.80/addons/b3d_tools/way/__init__.py | 12 +- src/2.80/addons/b3d_tools/way/menus.py | 78 ++ 14 files changed, 2227 insertions(+), 864 deletions(-) rename src/2.80/addons/b3d_tools/b3d/{exportb3d.py => export_b3d.py} (76%) rename src/2.80/addons/b3d_tools/b3d/{importb3d.py => import_b3d.py} (88%) create mode 100644 src/2.80/addons/b3d_tools/b3d/menus.py rename src/2.80/addons/b3d_tools/b3d/{panel/__init__.py => panel.py} (88%) rename src/2.80/addons/b3d_tools/b3d/{panel/common.py => scripts.py} (93%) create mode 100644 src/2.80/addons/b3d_tools/consts.py create mode 100644 src/2.80/addons/b3d_tools/custom_UIList.py create mode 100644 src/2.80/addons/b3d_tools/way/menus.py diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py index fa1895c..e8f44cf 100644 --- a/src/2.80/addons/b3d_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -21,14 +21,19 @@ if "bpy" in locals(): print("Reimporting modules!!!") import importlib + # importlib.reload(object_UIList) + # importlib.reload(material_UIList) + importlib.reload(custom_UIList) importlib.reload(common) importlib.reload(way) importlib.reload(tch) importlib.reload(b3d) - # importlib.reload(exportb3d) else: import bpy from . import ( + # object_UIList, + # material_UIList, + custom_UIList, common, way, tch, @@ -38,11 +43,8 @@ -# from .b3d import b3d_register, b3d_unregister -from .b3d import b3d_register, b3d_unregister from .tch import tch_unregister, tch_register -from .b3d.panel import b3dpanel_register, b3dpanel_unregister -from .way import way_register, way_unregister + # ##### BEGIN GPL LICENSE BLOCK ##### # @@ -84,14 +86,18 @@ def register(): - b3d_register() + # material_UIList.register() + # object_UIList.register() + custom_UIList.register() + b3d.register() # tch_register() - b3dpanel_register() def unregister(): - b3dpanel_unregister() + # material_UIList.unregister() + # object_UIList.unregister() + b3d.unregister() + custom_UIList.unregister() # tch_unregister() - b3d_unregister() if __name__ == "__main__": register() diff --git a/src/2.80/addons/b3d_tools/b3d/__init__.py b/src/2.80/addons/b3d_tools/b3d/__init__.py index c3268e3..b0bea9f 100644 --- a/src/2.80/addons/b3d_tools/b3d/__init__.py +++ b/src/2.80/addons/b3d_tools/b3d/__init__.py @@ -8,338 +8,32 @@ importlib.reload(common) importlib.reload(classes) - importlib.reload(importb3d) - # importlib.reload(exportb3d) + importlib.reload(import_b3d) + importlib.reload(export_b3d) importlib.reload(imghelp) importlib.reload(panel) + importlib.reload(menus) else: import bpy from . import ( common, classes, - importb3d, - # exportb3d, + import_b3d, + export_b3d, imghelp, - panel + panel, + menus ) -import math -from threading import Lock, Thread -import time -import datetime -import os -import bpy -from bpy.props import StringProperty, EnumProperty, BoolProperty, CollectionProperty, FloatProperty -from bpy_extras.io_utils import ImportHelper, ExportHelper -# from . import common, exportb3d, imghelp, importb3d - -def thread_import_b3d(self, files, context): - for b3dfile in files: - filepath = os.path.join(self.directory, b3dfile.name) - - print('Importing file', filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - with open(filepath, 'rb') as file: - importb3d.read(file, context, self, filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - t - print('Finished importing in', t, 'seconds') - - -class ActiveBlock(bpy.types.PropertyGroup): - name: StringProperty() - state : BoolProperty() - - -class HTImportPreferences(bpy.types.AddonPreferences): - bl_idname = "b3d_tools" - - COMMON_RES_Path: bpy.props.StringProperty( - name="Common.res path", - default="", - subtype='FILE_PATH') - - def draw(self, context): - layout = self.layout - row = layout.row() - row.prop(self, 'COMMON_RES_Path', expand=True) - -class ImportRAW(bpy.types.Operator, ImportHelper): - '''Import from RAW file format (.raw)''' - bl_idname = 'import_scene.kotr_raw' - bl_label = 'Import RAW' - - filename_ext = '.raw' - - files: CollectionProperty( - type=bpy.types.OperatorFileListElement, - options={'HIDDEN', 'SKIP_SAVE'}, - ) - filter_glob : StringProperty(default='*.raw', options={'HIDDEN'}) - - directory: StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'}) - - def execute(self, context): - for rawfile in self.files: - filepath = os.path.join(self.directory, rawfile.name) - - print('Importing file', filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - with open(filepath, 'rb') as file: - importb3d.parseRAW(file, context, self, filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - t - print('Finished importing in', t, 'seconds') - - return {'FINISHED'} - -class ImportB3D(bpy.types.Operator, ImportHelper): - '''Import from B3D file format (.b3d)''' - bl_idname = 'import_scene.kotr_b3d' - bl_label = 'Import B3D' - - filename_ext = '.b3d' - - files: CollectionProperty( - type=bpy.types.OperatorFileListElement, - options={'HIDDEN', 'SKIP_SAVE'}, - ) - - directory: StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'}) - - filter_glob : StringProperty(default='*.b3d', options={'HIDDEN'}) - - to_unpack_res : BoolProperty(name='Unpack .res archive', - description='Unpack associated with .b3d fie .res archive. \n'\ - 'NOTE: .res archive must be located in the same folder as .b3d file', default=False) - - to_convert_txr : BoolProperty(name='Convert .txr to .tga', - description='Convert .txr from unpacked .res to .tga', default=False) - - to_import_textures : BoolProperty(name='Import Textures', - description='Import textures from unpacked .res archive. \n'\ - 'NOTE: if importing for the first time select previous option too', default=False) - - textures_format : StringProperty( - name="Images format", - description="Loaded images format", - default="tga", - ) - - res_location : StringProperty( - name=".res path", - description="Path to .res file location. Default: .res file with name and location of imported .b3d", - default="" - ) - - show_all_blocks : EnumProperty( - name="Block", - items=[ - ('0', 'Custom select', 'Custom select'), - ('1', 'Select all', 'Select all'), - ('2', 'Select none', 'Select none'), - ] - ) - - blocks_to_import: CollectionProperty(type=ActiveBlock) - - def invoke(self, context, event): - wm = context.window_manager - - self.blocks_to_import.clear() - - blocks = [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] - - for i, block in enumerate(blocks): - item = self.blocks_to_import.add() - item.name = str(block) - item.state = False - - wm.fileselect_add(self) - return {"RUNNING_MODAL"} - - - def thread_import_b3d(self, files, context): - for b3dfile in files: - filepath = os.path.join(self.directory, b3dfile.name) - - print('Importing file', filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - with open(filepath, 'rb') as file: - importb3d.read(file, context, self, filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - t - print('Finished importing in', t, 'seconds') - - def execute(self, context): - evens = [cn for i,cn in enumerate(self.files) if i%2==0] - odds = [cn for i,cn in enumerate(self.files) if i%2==1] - - - t1 = Thread(target=thread_import_b3d, args=(self, evens, context)) - t2 = Thread(target=thread_import_b3d, args=(self, odds, context)) - - tt = time.mktime(datetime.datetime.now().timetuple()) - - t1.start() - t2.start() - - t1.join() - t2.join() - - # for b3dfile in self.files: - # filepath = os.path.join(self.directory, b3dfile.name) - - # print('Importing file', filepath) - # t = time.mktime(datetime.datetime.now().timetuple()) - # with open(filepath, 'rb') as file: - # importb3d.read(file, context, self, filepath) - # t = time.mktime(datetime.datetime.now().timetuple()) - t - # print('Finished importing in', t, 'seconds') - - - tt = time.mktime(datetime.datetime.now().timetuple()) - tt - print('All imported in', tt, 'seconds') - - return {'FINISHED'} - - def draw(self, context): - - layout = self.layout - - layout.label(text="Main settings:") - box1 = layout.box() - row = box1.row() - row.prop(self, 'to_unpack_res') - row = box1.row() - row.prop(self, 'to_convert_txr') - row = box1.row() - row.prop(self, 'to_import_textures') - row = box1.row() - row.prop(self, 'textures_format') - - layout.label(text="Optional settings:") - box1 = layout.box() - row = box1.row() - row.prop(self, 'res_location') - - layout.label(text="Blocks to import:") - box1 = layout.box() - row = box1.row() - row.prop(self, 'show_all_blocks') - # props = row.operator(SelectAllBlocksBtn.bl_idname) - # props.blocks_to_import = self.blocks_to_import - # props.test = PointerProperty(type=self.blocks_to_import) - row = box1.row() - - if self.show_all_blocks == '1': - for block in self.blocks_to_import: - block.state = True - elif self.show_all_blocks == '2': - for block in self.blocks_to_import: - block.state = False - - i = 0 - perRow = 8 - rowcnt = math.floor(len(self.blocks_to_import)/perRow) - for j in range(rowcnt): - row = box1.row() - for block in self.blocks_to_import[i:i+perRow]: - row.prop(block, 'state', text=block['name'], toggle=True) - i+=perRow - row = box1.row() - for block in self.blocks_to_import[i:]: - row.prop(block, 'state', text=block['name'], toggle=True) - -class ImportWayTxt(bpy.types.Operator, ImportHelper): - '''Import from txt file format (.txt)''' - bl_idname = 'import_scene.kotr_way_txt' - bl_label = 'Import way_txt' - - filename_ext = '.txt' - filter_glob = StringProperty(default='*.txt', options={'HIDDEN'}) - - use_image_search = BoolProperty(name='Image Search', - description='Search subdirectories for any associated'\ - 'images', default=True) - - def execute(self, context): - from . import importb3d - print('Importing file', self.filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - with open(self.filepath, 'r') as file: - importb3d.readWayTxt(file, context, self, self.filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - t - print('Finished importing in', t, 'seconds') - return {'FINISHED'} - - -class ExportB3D(bpy.types.Operator, ImportHelper): - '''Export to B3D file format (.b3d)''' - bl_idname = 'export_scene.kotr_b3d' - bl_label = 'Export B3D' - - filename_ext = '.b3d' - filter_glob = StringProperty(default='*.b3d', options={'HIDDEN'}) - - generate_pro_file = BoolProperty(name='Generate .pro file', - description='Generate .pro file, which can used'\ - 'to assembly the resources file', default=False) - - textures_path = StringProperty( - name="Textures directory", - default="txr\\", - ) - - def execute(self, context): - from . import exportb3d - print('Exporting file', self.filepath) - t = time.mktime(datetime.datetime.now().timetuple()) - exportb3d.write(self.filepath+'.b3d', context, self, self.filepath, self.generate_pro_file, self.textures_path) - t = time.mktime(datetime.datetime.now().timetuple()) - t - print('Finished exporting in', t, 'seconds') - return {'FINISHED'} - - -def menu_func_import(self, context): - self.layout.operator(ImportRAW.bl_idname, text='KOTR RAW (.raw)') - self.layout.operator(ImportB3D.bl_idname, text='KOTR B3D (.b3d)') - self.layout.operator(ImportWayTxt.bl_idname, text='KOTR WAY (.txt)') - - -def menu_func_export(self, context): - self.layout.operator(ExportB3D.bl_idname, text='KOTR B3D (.b3d)') - -_classes = ( - common.SCENE_UL_list, - HTImportPreferences, - ImportB3D, - ImportRAW, - ImportWayTxt, - ExportB3D -) - - - -def b3d_register(): +def register(): print("registering addon") - # import importlib - # for cls in classes: - # importlib.reload(cls) - bpy.utils.register_class(ActiveBlock) - bpy.utils.register_class(common.FloatBlock) - for cls in _classes: - bpy.utils.register_class(cls) - bpy.types.TOPBAR_MT_file_import.append(menu_func_import) - bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + classes.register() + menus.register() + panel.register() -def b3d_unregister(): +def unregister(): print("unregistering addon") - bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) - bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) - for cls in _classes: - bpy.utils.unregister_class(cls) - bpy.utils.unregister_class(common.FloatBlock) - bpy.utils.unregister_class(ActiveBlock) + panel.unregister() + menus.unregister() + classes.unregister() diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 58c0283..d9c0f4e 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -17,8 +17,7 @@ PropertyGroup, ) -from b3d_tools.common import log -from b3d_tools.b3d.common import FloatBlock +from ..common import log class fieldType(enum.Enum): @@ -32,6 +31,90 @@ class fieldType(enum.Enum): V_FORMAT = 8 +class ActiveBlock(bpy.types.PropertyGroup): + name: StringProperty() + state : BoolProperty() + +class FloatBlock(bpy.types.PropertyGroup): + value: FloatProperty() + +class MaskfileBlock(bpy.types.PropertyGroup): + name: StringProperty() + + is_noload: BoolProperty(default=False) + is_someint: BoolProperty(default=False) + someint: IntProperty(default=0) + +class TextureBlock(bpy.types.PropertyGroup): + name: StringProperty() + + is_memfix: BoolProperty(default=False) + is_noload: BoolProperty(default=False) + is_bumpcoord: BoolProperty(default=False) + is_someint: BoolProperty(default=False) + someint: IntProperty() + +class MaterialBlock(bpy.types.PropertyGroup): + name: StringProperty() + + is_reflect: BoolProperty(default=False) + reflect: FloatProperty(default=0.0) + + is_specular: BoolProperty(default=False) + specular: FloatProperty(default=0.0) + + is_transp: BoolProperty(default=False) + transp: FloatProperty(default=0.0) + + is_rot: BoolProperty(default=False) + rot: FloatProperty(default=0.0) + + is_col: BoolProperty(default=False) + col: IntProperty(default=0) + + is_tex: BoolProperty(default=False) + tex: IntProperty(default=0) + ttx: IntProperty(default=0) + itx: IntProperty(default=0) + + is_att: BoolProperty(default=False) + att: IntProperty(default=0) + + is_msk: BoolProperty(default=False) + msk: IntProperty(default=0) + + is_power: BoolProperty(default=False) + power: IntProperty(default=0) + + is_coord: BoolProperty(default=False) + coord: IntProperty(default=0) + + is_env: BoolProperty(default=False) + envId: IntProperty(default=0) + env: FloatVectorProperty(default=(0.0, 0.0), size=2) + + is_rotPoint: BoolProperty(default=False) + rotPoint: FloatVectorProperty(default=(0.0, 0.0), size=2) + + is_move: BoolProperty(default=False) + move: FloatVectorProperty(default=(0.0, 0.0), size=2) + + is_noz: BoolProperty(default=False) + is_nof: BoolProperty(default=False) + is_notile: BoolProperty(default=False) + is_notileu: BoolProperty(default=False) + is_notilev: BoolProperty(default=False) + is_alphamirr: BoolProperty(default=False) + is_bumpcoord: BoolProperty(default=False) + is_usecol: BoolProperty(default=False) + is_wave: BoolProperty(default=False) + +class ResBlock(bpy.types.PropertyGroup): + name: StringProperty() + textures: CollectionProperty(type=TextureBlock) + materials: CollectionProperty(type=MaterialBlock) + maskfiles: CollectionProperty(type=MaskfileBlock) + def createTypeClass(zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] @@ -1651,3 +1734,63 @@ class b_40(): block_37 = createTypeClass(b_37) block_39 = createTypeClass(b_39) block_40 = createTypeClass(b_40) + +_classes = ( + ActiveBlock, + FloatBlock, + TextureBlock, + MaskfileBlock, + MaterialBlock, + ResBlock, + block_1, + block_2, + block_3, + block_4, + block_5, + block_6, + block_7, + block_8, + block_9, + block_10, + block_11, + block_12, + block_13, + block_14, + block_15, + block_16, + block_17, + block_18, + block_20, + block_21, + block_22, + block_23, + block_24, + block_25, + block_26, + block_27, + block_28, + block_29, + block_30, + block_31, + block_33, + block_34, + block_35, + block_36, + block_37, + block_39, + block_40, + block_common, + perFaceBlock_8, + perFaceBlock_28, + perFaceBlock_35, + perVertBlock_8, + perVertBlock_35 +) + +def register(): + for cls in _classes: + bpy.utils.register_class(cls) + +def unregister(): + for cls in _classes[::-1]: #reversed + bpy.utils.unregister_class(cls) diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 8519a47..b442146 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -3,28 +3,32 @@ import bpy import logging import sys - -from b3d_tools.common import log - -from bpy.props import FloatProperty, IntProperty +import re + +from ..common import log + +from bpy.props import ( + FloatProperty, + IntProperty, + FloatVectorProperty, + BoolProperty, + StringProperty, + PointerProperty +) from bpy.types import UIList # logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) # log = logging.getLogger("common") # log.setLevel(logging.DEBUG) -class SCENE_UL_list(UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname): - if self.layout_type in {'DEFAULT', 'COMPACT'}: - layout.prop(item, "value", text="") - elif self.layout_type in {'GRID'}: - layout.alignment = 'CENTER' - layout.label(text="", icon_value=icon) +def isRootObj(obj): + return obj.parent is None and obj.name[-4:] == '.b3d' + -class FloatBlock(bpy.types.PropertyGroup): - index: IntProperty() - value: FloatProperty() +def isEmptyName(name): + reIsEmpty = re.compile(r'.*empty name.*') + return reIsEmpty.search(name) def ShowMessageBox(message = "", title = "Message Box", icon = 'INFO'): @@ -69,27 +73,31 @@ class HTMaterial(): def __init__(self): self.prefix = "" self.path = "" - self.reflect = 0.0 #HT1 - self.specular = 0.0 #HT1 - self.col = 0 - self.transp = 1.0 - self.tex = 0 - self.ttx = 0 - self.rot = 0.0 - self.rotPoint = [0, 0] - self.power = 0.0 - self.noz = False - self.nof = False - self.notile = False - self.move = None - self.att = 0 - self.itx = 0 - self.coord = 2 - self.env = [0, 0] #scale x,y - self.notilev = False - self.notileu = False - self.bumpcoord = 0 - self.alphamirr = 0 + self.reflect = None #HT1 float + self.specular = None #HT1 float + self.transp = None # float + self.rot = None # float + self.col = None # int + self.tex = None # int + self.ttx = None # int + self.itx = None # int + self.att = None # int + self.msk = None # int + self.power = None # int + self.coord = None # int + self.envId = None # int + self.env = None #scale x,y 2 floats + self.rotPoint = None # 2 floats + self.move = None # 2 floats + self.noz = False # bool + self.nof = False # bool + self.notile = False # bool + self.notileu = False # bool + self.notilev = False # bool + self.alphamirr = False # bool + self.bumpcoord = False # bool + self.usecol = False # bool + self.wave = False # bool class Vector3F(): @@ -110,73 +118,37 @@ def __init__(self, file=None, tuple=None): -class RESUnpack(): +def createMaterials(resModule, palette, texturePath, imageFormat): + materialList = resModule.materials - def __init__(self): - self.prefix = "" - self.textures = [] - self.maskfiles = [] - self.materials = [] - self.materialParams = [] - self.colors = [] - - def getPrefixedMaterial(self, ind): - return "{}_{}".format(self.prefix, self.materials[ind]) - -def parseMaterial(matString, prefix): - params = matString.split(" ") - i = 1 - mat = HTMaterial() - mat.prefix = prefix - mat.path = params[0] - while i < len(params): - if params[i] == "col": - i+=1 - mat.col = int(params[i]) - elif params[i] == "tex": - i+=1 - mat.tex = int(params[i]) - elif params[i] == "ttx": - i+=1 - mat.ttx = int(params[i]) - elif params[i] == "itx": - i+=1 - mat.itx = int(params[i]) - i+=1 - return mat - - -def parseMaterials(filepath, prefix): - content = "" - with open(filepath, "rb") as matFile: - content = matFile.read().decode("UTF-8") - - matStrings = content.split("\n") - materials = [] - for matStr in matStrings: - material = parseMaterial(matStr, prefix) - materials.append(material) - return materials + for material in materialList: + createMaterial(resModule, palette, texturePath, material, imageFormat) #https://blender.stackexchange.com/questions/118646/add-a-texture-to-an-object-using-python-and-blender-2-8 -def createMaterial(palette, texturelist, texturepath, mat, imageFormat): - newMat = bpy.data.materials.new(name="{}_{}".format(mat.prefix, mat.path)) +def createMaterial(resModule, palette, texturepath, mat, imageFormat): + + textureList = resModule.textures + + newMat = bpy.data.materials.new(name="{}_{}".format(resModule.name, mat.name)) newMat.use_nodes = True bsdf = newMat.node_tree.nodes["Principled BSDF"] - if int(mat.col) > 0: + + if mat.is_col and int(mat.col) > 0: R = palette[mat.col-1][0] G = palette[mat.col-1][1] B = palette[mat.col-1][2] texColor = newMat.node_tree.nodes.new("ShaderNodeRGB") texColor.outputs[0].default_value = hex_to_rgb(R,G,B) newMat.node_tree.links.new(bsdf.inputs['Base Color'], texColor.outputs['Color']) - if int(mat.tex) > 0 or int(mat.ttx) > 0 or int(mat.itx) > 0: + + if (mat.is_tex and (int(mat.tex) > 0 or int(mat.ttx) > 0 or int(mat.itx) > 0)): texidx = mat.tex | mat.ttx | mat.itx - path = texturelist[texidx-1][:-4] + path = textureList[texidx-1].name texImage = newMat.node_tree.nodes.new("ShaderNodeTexImage") texImage.image = bpy.data.images.load(os.path.join(texturepath, "{}.{}".format(path, imageFormat))) newMat.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color']) + #https://blender.stackexchange.com/questions/158896/how-set-hex-in-rgb-node-python def srgb_to_linearrgb(c): if c < 0: return 0 diff --git a/src/2.80/addons/b3d_tools/b3d/exportb3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py similarity index 76% rename from src/2.80/addons/b3d_tools/b3d/exportb3d.py rename to src/2.80/addons/b3d_tools/b3d/export_b3d.py index 60ac708..a864655 100644 --- a/src/2.80/addons/b3d_tools/b3d/exportb3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -18,6 +18,65 @@ import bpy_extras.mesh_utils + +from .classes import ( + b_1, + b_2, + b_3, + b_4, + b_5, + b_6, + b_7, + b_8, + b_9, + b_10, + b_11, + b_12, + b_13, + b_14, + b_15, + b_16, + b_17, + b_18, + b_20, + b_21, + b_22, + b_23, + b_24, + b_25, + b_26, + b_27, + b_28, + b_29, + b_30, + b_31, + b_33, + b_34, + b_35, + b_36, + b_37, + b_39, + b_40, + pfb_8, + pfb_28, + pfb_35, + pvb_8, + pvb_35 +) + +from .scripts import ( + prop +) + +from ..common import ( + log +) + +from .common import ( + isRootObj, + isEmptyName +) + from bpy_extras.io_utils import ( ImportHelper, ExportHelper, @@ -44,20 +103,19 @@ from mathutils import Vector from bpy import context -scene = bpy.context.scene RoMesh = True def openclose(file): oc = file.read(4) - if (oc == (b'\x4D\x01\x00\x00')): + if (oc == (b'\x4D\x01\x00\x00')): #Begin Chunk return 2 - elif oc == (b'\x2B\x02\x00\x00'): + elif oc == (b'\x2B\x02\x00\x00'): #End Chunk # print('}') return 0 - elif oc == (b'\xbc\x01\x00\x00'): + elif oc == (b'\xbc\x01\x00\x00'): #Group Chunk #print('BC01') return 3 - elif oc == (b'\xde\x00\00\00'): + elif oc == (b'\xde\x00\00\00'): #End Chunks print ('EOF') return 1 else: @@ -143,6 +201,16 @@ def export_pro(file, textures_path): file.write('\n') +def writeName(name, file): + objName = '' + if not isEmptyName(name): + objName = name + nameLen = len(objName) + if nameLen <= 32: + file.write(objName.encode("cp1251")) + file.write(bytearray(b'\00'*(32-nameLen))) + return + def clone_node(): b3d_node = bpy.data.objects['b3d'] bpy.context.scene.objects.active = b3d_node @@ -160,7 +228,7 @@ def delete_clone(): def export(file, generate_pro_file): - file = open(myFile+'.b3d','wb') + file = open(myFile,'wb') global global_matrix global_matrix = axis_conversion(to_forward="-Z", @@ -173,38 +241,72 @@ def export(file, generate_pro_file): global verNums verNums = [] - file.write(b'B3D\x00')#struct.pack("4c",b'B',b'3',b'D',b'\x00')) #ba = bytearray(b'\x00' * 20) #file.write(ba) - file.write(struct.pack(' curGroups[curLevel]: + log.debug('group ended') + file.write(struct.pack(" 0): + for i, ch in enumerate(blChildren[:-1]): + + if len(passToMesh): + l_extra = passToMesh[i] + exportBlock(ch, False, curLevel+1, curMaxCnt, curGroups, l_extra, file) + + if len(passToMesh): + l_extra = passToMesh[-1] + exportBlock(blChildren[-1], True, curLevel+1, curMaxCnt, curGroups, l_extra, file) + + + log.debug("{}_{}".format(curGroups, block.name)) + + if isLast: + log.info("{}_{}".format(maxGroups, curGroups[curLevel])) + for i in range(maxGroups-1 - curGroups[curLevel]): + log.debug('not enough in group') + file.write(struct.pack(" 0: + levelGroups[lvl] +=1 continue elif ex == ChunkType.BEGIN_CHUNK: lvl+=1 @@ -496,6 +506,9 @@ def read(file, context, op, filepath): # objName = "{}_{}".format(str(type).zfill(2), onlyName) objName = onlyName realName = onlyName + + # log.debug("{}_{}".format(type, objName)) + # log.debug("{}_{}".format(lvl - 1, levelGroups)) # log.info("Importing block #{}: {}".format(type, objName)) # log.info("type: {}, active: {}".format(type, usedBlocks[str(type)])) if (type == 0): # Empty Block @@ -508,7 +521,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj.parent = context.scene.objects[objString[-2]] @@ -525,7 +538,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_1.Name1)] = name1 b3dObj[prop(b_1.Name2)] = name2 @@ -546,7 +559,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_2.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_2.R)] = bounding_sphere[3] @@ -568,7 +581,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_3.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_3.R)] = bounding_sphere[3] @@ -590,7 +603,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_4.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_4.R)] = bounding_sphere[3] @@ -613,7 +626,7 @@ def read(file, context, op, filepath): continue b3dObj = bpy.data.objects.new(objName, None) #create empty b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = pos b3dObj[prop(b_5.XYZ)] = (bounding_sphere[0:3]) b3dObj[prop(b_5.R)] = (bounding_sphere[3]) @@ -647,7 +660,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_6.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_6.R)] = bounding_sphere[3] @@ -688,7 +701,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = pos b3dObj[prop(b_7.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_7.R)] = bounding_sphere[3] @@ -721,7 +734,7 @@ def read(file, context, op, filepath): formatRaw = struct.unpack("> 8 #ah + uvCount = ((format & 0xFF00) >> 8) #ah triangulateOffset = format & 0b10000000 if format & 0b10: @@ -742,9 +755,7 @@ def read(file, context, op, filepath): unkF = struct.unpack(" 1: for texnum in texnums: - mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] + mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texnum)].name)] b3dMesh.materials.append(mat) lastIndex = len(b3dMesh.materials)-1 @@ -906,7 +917,7 @@ def read(file, context, op, filepath): # op.lock.release() else: for texnum in texnums: - mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] + mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texnum)].name)] b3dMesh.materials.append(mat) @@ -922,7 +933,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_9.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_9.R)] = bounding_sphere[3] @@ -945,7 +956,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_10.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_10.R)] = bounding_sphere[3] @@ -968,7 +979,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_11.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_11.R)] = bounding_sphere[3] @@ -982,20 +993,21 @@ def read(file, context, op, filepath): elif (type == 12): + l_params = [] bounding_sphere = struct.unpack("<4f",file.read(16)) unknown_sphere = struct.unpack("<4f",file.read(16)) unknown1 = struct.unpack(" 1: for texnum in texnums: - mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] + mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texnum)].name)] b3dMesh.materials.append(mat) lastIndex = len(b3dMesh.materials)-1 @@ -1634,7 +1645,7 @@ def read(file, context, op, filepath): # op.lock.release() else: for texnum in texnums: - mat = bpy.data.materials[RESUnpacked.getPrefixedMaterial(int(texnum))] + mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texnum)].name)] b3dMesh.materials.append(mat) createCustomAttribute(b3dMesh, formats, pfb_28, pfb_28.Format_Flags) @@ -1643,7 +1654,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, b3dMesh) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_28.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_28.R)] = bounding_sphere[3] @@ -1672,7 +1683,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_29.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_29.R)] = bounding_sphere[3] @@ -1723,7 +1734,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, b3dMesh) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = pos b3dObj[prop(b_30.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_30.R)] = bounding_sphere[3] @@ -1752,7 +1763,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_31.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_31.R)] = bounding_sphere[3] @@ -1792,7 +1803,7 @@ def read(file, context, op, filepath): b3dObj = bpy.data.objects.new(objName, None) b3dObj['block_type'] = type - b3dObj['level_group'] = levelGroups[lvl-1] + b3dObj['level_group'] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) b3dObj[prop(b_33.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_33.R)] = bounding_sphere[3] @@ -1821,16 +1832,31 @@ def read(file, context, op, filepath): bounding_sphere = struct.unpack("<4f",file.read(16)) file.read(4) #skipped Int num = struct.unpack("> 8 #ah + uvCount = ((format & 0xFF00) >> 8) #ah triangulateOffset = format & 0b10000000 if format & 0b10: @@ -1892,6 +1918,7 @@ def read(file, context, op, filepath): face = struct.unpack(" 0: + setattr(material, "envId", int(envid)) + i+=1 + +def saveMaskfile(resModule, maskfileStr): + nameSplit = maskfileStr.split(" ") + rawName = nameSplit[0] + params = nameSplit[1:] + + name = rawName.split("\\")[-1][:-4] + + maskfile = resModule.maskfiles.add() + maskfile.name = name + i = 0 + while i < len(params): + paramName = params[i].replace('"', '') + if paramName == "noload": + setattr(maskfile, "is_noload", True) + else: + someInt = None + try: + someInt = int(someInt) + except: + pass + if someInt: + setattr(maskfile, "is_someint", True) + setattr(maskfile, "someint", someInt) + i+=1 + +def saveTexture(resModule, textueStr): + nameSplit = textueStr.split(" ") + rawName = nameSplit[0] + params = nameSplit[1:] + + name = rawName.split("\\")[-1][:-4] + log.debug(name) + + texture = resModule.textures.add() + texture.name = name + i = 0 + while i < len(params): + paramName = params[i].replace('"', '') + if paramName in ["noload", "bumpcoord", "memfix"]: + setattr(texture, "is_" + paramName, True) + else: + someInt = None + try: + someInt = int(someInt) + except: + pass + if someInt: + setattr(texture, "is_someint", True) + setattr(texture, "someint", someInt) + i+=1 + + +def unpackRES(resModule, filepath, saveOnDisk = True): log.info("Unpacking {}:".format(filepath)) + # filename, resExtension = os.path.splitext(filepath) # basename = os.path.basename(filepath)[:-4] # basepath = os.path.dirname(filepath) @@ -2396,9 +2516,6 @@ def unpackRES(filepath, prefix, saveOnDisk = True): if not os.path.exists(resdir): os.mkdir(resdir) - unpacked = RESUnpack() - unpacked.prefix = prefix - with open(filepath, "rb") as resFile: while 1: category = readCString(resFile) @@ -2420,48 +2537,54 @@ def unpackRES(filepath, prefix, saveOnDisk = True): binfileBase = os.path.dirname(binfilePath) binfileBase = Path(binfileBase) binfileBase.mkdir(exist_ok=True, parents=True) - names = [] + rawStrings = [] for i in range(cnt): - name = readCString(resFile) - names.append(name) + rawString = readCString(resFile) + rawStrings.append(rawString) if id == "MATERIALS": if saveOnDisk: with open(binfilePath, "wb") as outFile: - for n in names: - nameSplit = n.split(" ") - name = nameSplit[0] - params = " ".join(nameSplit[1:]) - unpacked.materials.append(name) - unpacked.materialParams.append(params) - outFile.write((n+"\n").encode("UTF-8")) + for rawString in rawStrings: + saveMaterial(resModule, rawString) + # nameSplit = rawString.split(" ") + # name = nameSplit[0] + # params = " ".join(nameSplit[1:]) + # unpacked.materials.append(name) + # unpacked.materialParams.append(params) + outFile.write((rawString+"\n").encode("UTF-8")) else: - for n in names: - nameSplit = n.split(" ") - name = nameSplit[0] - params = " ".join(nameSplit[1:]) - unpacked.materials.append(name) - unpacked.materialParams.append(params) + for rawString in rawStrings: + saveMaterial(resModule, rawString) + # nameSplit = rawString.split(" ") + # name = nameSplit[0] + # params = " ".join(nameSplit[1:]) + # unpacked.materials.append(name) + # unpacked.materialParams.append(params) elif id == "COLORS": if saveOnDisk: with open(binfilePath, "wb") as outFile: - for name in names: - unpacked.colors.append(name) - outFile.write((name+"\n").encode("UTF-8")) + for rawString in rawStrings: + # unpacked.colors.append(rawString) + outFile.write((rawString+"\n").encode("UTF-8")) else: - for name in names: - unpacked.colors.append(name) + for rawString in rawStrings: + pass + # unpacked.colors.append(rawString) else: if saveOnDisk: with open(binfilePath, "wb") as outFile: - for name in names: - outFile.write((name+"\n").encode("UTF-8")) - else: - names = [] + for rawString in rawStrings: + outFile.write((rawString+"\n").encode("UTF-8")) + else: #TEXTUREFILES and MASKFILES + rawStrings = [] for i in range(cnt): - fullname = readCString(resFile).split(" ")[0] + rawString = readCString(resFile) + rawStrings.append(rawString) + + nameSplit = rawString.split(" ") + fullname = nameSplit[0] lastpath = fullname.split("\\") name = "\\".join(lastpath[len(lastpath)-1:]) - names.append(name) sectionSize = struct.unpack("= 1: + item_prev = param[idx-1].name + param.move(idx, idx-1) + scn.custom_index -= 1 + info = 'Item "%s" moved to position %d' % (item.name, scn.custom_index + 1) + self.report({'INFO'}, info) + + elif self.action == 'REMOVE': + info = 'Item "%s" removed from list' % (param[idx].name) + scn.custom_index -= 1 + param.remove(idx) + self.report({'INFO'}, info) + + if self.action == 'ADD': + if context.object: + item = param.add() + # item.name = context.object.name + # item.obj = context.object + item['value'] = 0.0 + scn.custom_index = len(param)-1 + # info = '"%s" added to list' % (item.name) + # self.report({'INFO'}, info) + else: + pass + # self.report({'INFO'}, "Nothing selected in the Viewport") + return {"FINISHED"} + + +class CUSTOM_OT_addViewportSelection(Operator): + """Add all items currently selected in the viewport""" + bl_idname = "custom.add_viewport_selection" + bl_label = "Add Viewport Selection to List" + bl_description = "Add all items currently selected in the viewport" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + scn = context.scene + selected_objs = context.selected_objects + if selected_objs: + new_objs = [] + for i in selected_objs: + item = scn.custom.add() + item.name = i.name + item.obj = i + new_objs.append(item.name) + info = ', '.join(map(str, new_objs)) + self.report({'INFO'}, 'Added: "%s"' % (info)) + else: + self.report({'INFO'}, "Nothing selected in the Viewport") + return{'FINISHED'} + + +class CUSTOM_OT_printItems(Operator): + """Print all items and their properties to the console""" + bl_idname = "custom.print_items" + bl_label = "Print Items to Console" + bl_description = "Print all items and their properties to the console" + bl_options = {'REGISTER', 'UNDO'} + + reverse_order: BoolProperty( + default=False, + name="Reverse Order") + + @classmethod + def poll(cls, context): + return bool(context.scene.custom) + + def execute(self, context): + scn = context.scene + if self.reverse_order: + for i in range(scn.custom_index, -1, -1): + ob = scn.custom[i].obj + print ("Object:", ob,"-",ob.name, ob.type) + else: + for item in scn.custom: + ob = item.obj + print ("Object:", ob,"-",ob.name, ob.type) + return{'FINISHED'} + + +class CUSTOM_OT_clearList(Operator): + """Clear all items of the list""" + bl_idname = "custom.clear_list" + bl_label = "Clear List" + bl_description = "Clear all items of the list" + bl_options = {'INTERNAL'} + + @classmethod + def poll(cls, context): + return bool(context.scene.custom) + + def invoke(self, context, event): + return context.window_manager.invoke_confirm(self, event) + + def execute(self, context): + if bool(context.scene.custom): + context.scene.custom.clear() + self.report({'INFO'}, "All items removed") + else: + self.report({'INFO'}, "Nothing to remove") + return{'FINISHED'} + + +class CUSTOM_OT_removeDuplicates(Operator): + """Remove all duplicates""" + bl_idname = "custom.remove_duplicates" + bl_label = "Remove Duplicates" + bl_description = "Remove all duplicates" + bl_options = {'INTERNAL'} + + def find_duplicates(self, context): + """find all duplicates by name""" + name_lookup = {} + for c, i in enumerate(context.scene.custom): + name_lookup.setdefault(i.obj.name, []).append(c) + duplicates = set() + for name, indices in name_lookup.items(): + for i in indices[1:]: + duplicates.add(i) + return sorted(list(duplicates)) + + @classmethod + def poll(cls, context): + return bool(context.scene.custom) + + def execute(self, context): + scn = context.scene + removed_items = [] + # Reverse the list before removing the items + for i in self.find_duplicates(context)[::-1]: + scn.custom.remove(i) + removed_items.append(i) + if removed_items: + scn.custom_index = len(scn.custom)-1 + info = ', '.join(map(str, removed_items)) + self.report({'INFO'}, "Removed indices: %s" % (info)) + else: + self.report({'INFO'}, "No duplicates") + return{'FINISHED'} + + def invoke(self, context, event): + return context.window_manager.invoke_confirm(self, event) + + +class CUSTOM_OT_selectItems(Operator): + """Select Items in the Viewport""" + bl_idname = "custom.select_items" + bl_label = "Select Item(s) in Viewport" + bl_description = "Select Items in the Viewport" + bl_options = {'REGISTER', 'UNDO'} + + select_all = BoolProperty( + default=False, + name="Select all Items of List", + options={'SKIP_SAVE'}) + + @classmethod + def poll(cls, context): + return bool(context.scene.custom) + + def execute(self, context): + scn = context.scene + idx = scn.custom_index + + try: + item = scn.custom[idx] + except IndexError: + self.report({'INFO'}, "Nothing selected in the list") + return{'CANCELLED'} + + obj_error = False + bpy.ops.object.select_all(action='DESELECT') + if not self.select_all: + name = scn.custom[idx].obj.name + obj = scn.objects.get(name, None) + if not obj: + obj_error = True + else: + obj.select_set(True) + info = '"%s" selected in Vieport' % (obj.name) + else: + selected_items = [] + unique_objs = set([i.obj.name for i in scn.custom]) + for i in unique_objs: + obj = scn.objects.get(i, None) + if obj: + obj.select_set(True) + selected_items.append(obj.name) + + if not selected_items: + obj_error = True + else: + missing_items = unique_objs.difference(selected_items) + if not missing_items: + info = '"%s" selected in Viewport' \ + % (', '.join(map(str, selected_items))) + else: + info = 'Missing items: "%s"' \ + % (', '.join(map(str, missing_items))) + if obj_error: + info = "Nothing to select, object removed from scene" + self.report({'INFO'}, info) + return{'FINISHED'} + + +class CUSTOM_OT_deleteObject(Operator): + """Delete object from scene""" + bl_idname = "custom.delete_object" + bl_label = "Remove Object from Scene" + bl_description = "Remove object from scene" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return bool(context.scene.custom) + + def invoke(self, context, event): + return context.window_manager.invoke_confirm(self, event) + + def execute(self, context): + scn = context.scene + selected_objs = context.selected_objects + idx = scn.custom_index + try: + item = scn.custom[idx] + except IndexError: + pass + else: + ob = scn.objects.get(item.obj.name) + if not ob: + self.report({'INFO'}, "No object of that name found in scene") + return {"CANCELLED"} + else: + bpy.ops.object.select_all(action='DESELECT') + ob.select_set(True) + bpy.ops.object.delete() + + info = ' Item "%s" removed from Scene' % (len(selected_objs)) + scn.custom_index -= 1 + scn.custom.remove(idx) + self.report({'INFO'}, info) + return{'FINISHED'} + + +# ------------------------------------------------------------------- +# Drawing +# ------------------------------------------------------------------- + +class CUSTOM_UL_items(UIList): + + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + # obj = item.obj + # custom_icon = "OUTLINER_OB_%s" % obj.type + split = layout.split(factor=0.3) + split.label(text="Index: %d" % (index)) + split.prop(item, "value", text="", emboss=False, translate=False) + # split.prop(obj, "name", text="", emboss=False, translate=False, icon=custom_icon) + + def invoke(self, context, event): + pass + +class CUSTOM_PT_objectList(Panel): + """Adds a custom panel to the TEXT_EDITOR""" + bl_idname = 'TEXT_PT_my_panel' + bl_space_type = "TEXT_EDITOR" + bl_region_type = "UI" + bl_label = "Custom Object List Demo" + + def draw(self, context): + layout = self.layout + scn = bpy.context.scene + + rows = 2 + row = layout.row() + row.template_list("CUSTOM_UL_items", "", scn, "custom", scn, "custom_index", rows=rows) + + col = row.column(align=True) + col.operator("custom.list_action", icon='ADD', text="").action = 'ADD' + col.operator("custom.list_action", icon='REMOVE', text="").action = 'REMOVE' + col.separator() + col.operator("custom.list_action", icon='TRIA_UP', text="").action = 'UP' + col.operator("custom.list_action", icon='TRIA_DOWN', text="").action = 'DOWN' + + # row = layout.row() + # col = row.column(align=True) + # row = col.row(align=True) + # row.operator("custom.print_items", icon="LINENUMBERS_ON") + # row = col.row(align=True) + # row.operator("custom.clear_list", icon="X") + # row.operator("custom.remove_duplicates", icon="GHOST_ENABLED") + + # row = layout.row() + # col = row.column(align=True) + # row = col.row(align=True) + # row.operator("custom.add_viewport_selection", icon="HAND") #LINENUMBERS_OFF, ANIM + # row = col.row(align=True) + # row.operator("custom.select_items", icon="VIEW3D", text="Select Item in 3D View") + # row.operator("custom.select_items", icon="GROUP", text="Select All Items in 3D View").select_all = True + # row = col.row(align=True) + # row.operator("custom.delete_object", icon="X") + + +# ------------------------------------------------------------------- +# Collection +# ------------------------------------------------------------------- + +class CUSTOM_PG_objectCollection(PropertyGroup): + #name: StringProperty() -> Instantiated by default + obj: PointerProperty( + name="Object", + type=bpy.types.Object) + + +# ------------------------------------------------------------------- +# Register & Unregister +# ------------------------------------------------------------------- + +classes = ( + CUSTOM_OT_actions, + CUSTOM_OT_addViewportSelection, + CUSTOM_OT_printItems, + CUSTOM_OT_clearList, + CUSTOM_OT_removeDuplicates, + CUSTOM_OT_selectItems, + CUSTOM_OT_deleteObject, + CUSTOM_UL_items, + CUSTOM_PT_objectList, + CUSTOM_PG_objectCollection, +) + +def register(): + from bpy.utils import register_class + for cls in classes: + register_class(cls) + + # Custom scene properties + bpy.types.Scene.custom = CollectionProperty(type=CUSTOM_PG_objectCollection) + bpy.types.Scene.custom_index = IntProperty() + + +def unregister(): + from bpy.utils import unregister_class + for cls in classes[::-1]: + unregister_class(cls) + + del bpy.types.Scene.custom + del bpy.types.Scene.custom_index + + +if __name__ == "__main__": + register() \ No newline at end of file diff --git a/src/2.80/addons/b3d_tools/way/__init__.py b/src/2.80/addons/b3d_tools/way/__init__.py index 9c2f08c..6285807 100644 --- a/src/2.80/addons/b3d_tools/way/__init__.py +++ b/src/2.80/addons/b3d_tools/way/__init__.py @@ -4,10 +4,12 @@ print("Reimporting modules!!!") import importlib importlib.reload(import_way) + importlib.reload(menus) else: import bpy from . import ( - import_way + import_way, + menus ) import bpy @@ -25,7 +27,7 @@ PropertyGroup, ) -from b3d_tools.common import getRegion +from ..common import getRegion import struct @@ -1136,19 +1138,21 @@ def menu_func_import(self, context): ) -def way_register(): +def register(): + menus.register() for cls in _classes: bpy.utils.register_class(cls) bpy.types.TOPBAR_MT_file_export.append(menu_func_export) bpy.types.TOPBAR_MT_file_import.append(menu_func_import) bpy.types.Scene.way_tool = bpy.props.PointerProperty(type=PanelSettings1) -def way_unregister(): +def unregister(): del bpy.types.Scene.way_tool bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) for cls in _classes: bpy.utils.unregister_class(cls) + menus.unregister() # def register(): # bpy.utils.register_class(ExportSomeData) diff --git a/src/2.80/addons/b3d_tools/way/menus.py b/src/2.80/addons/b3d_tools/way/menus.py new file mode 100644 index 0000000..45e0dad --- /dev/null +++ b/src/2.80/addons/b3d_tools/way/menus.py @@ -0,0 +1,78 @@ + +import time +import datetime +from threading import Lock, Thread +import os +import math +import bpy + +from bpy.props import ( + StringProperty, + EnumProperty, + BoolProperty, + CollectionProperty, + FloatProperty +) +from bpy_extras.io_utils import ( + ImportHelper, + ExportHelper +) +from bpy.types import ( + OperatorFileListElement, + Operator, + AddonPreferences +) + + + + +class ImportWayTxt(Operator, ImportHelper): + '''Import from txt file format (.txt)''' + bl_idname = 'import_scene.kotr_way_txt' + bl_label = 'Import way_txt' + + filename_ext = '.txt' + filter_glob = StringProperty(default='*.txt', options={'HIDDEN'}) + + use_image_search = BoolProperty(name='Image Search', + description='Search subdirectories for any associated'\ + 'images', default=True) + + def execute(self, context): + from . import import_b3d + print('Importing file', self.filepath) + t = time.mktime(datetime.datetime.now().timetuple()) + with open(self.filepath, 'r') as file: + import_b3d.readWayTxt(file, context, self, self.filepath) + t = time.mktime(datetime.datetime.now().timetuple()) - t + print('Finished importing in', t, 'seconds') + return {'FINISHED'} + + +def menu_func_import(self, context): + self.layout.operator(ImportWayTxt.bl_idname, text='KOTR WAY (.txt)') + + +def menu_func_export(self, context): + pass + + +_classes = ( + ImportWayTxt +) + + +def register(): + print("registering addon") + for cls in _classes: + bpy.utils.register_class(cls) + bpy.types.TOPBAR_MT_file_import.append(menu_func_import) + bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + + +def unregister(): + print("unregistering addon") + bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) + bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) + for cls in _classes[::-1]: #reversed + bpy.utils.unregister_class(cls) \ No newline at end of file From 8896fca0eba8e77f4c924c716d8e2b237d0a805e Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Mon, 26 Dec 2022 12:19:37 +0200 Subject: [PATCH 19/47] .res edit panel --- src/2.80/addons/b3d_tools/b3d/classes.py | 12 +- src/2.80/addons/b3d_tools/b3d/common.py | 30 +- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 131 ++++--- src/2.80/addons/b3d_tools/b3d/panel.py | 358 +++++++++++++++++++- src/2.80/addons/b3d_tools/b3d/scripts.py | 4 + src/2.80/addons/b3d_tools/custom_UIList.py | 150 ++++---- 6 files changed, 566 insertions(+), 119 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index d9c0f4e..f78caf9 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -39,14 +39,14 @@ class FloatBlock(bpy.types.PropertyGroup): value: FloatProperty() class MaskfileBlock(bpy.types.PropertyGroup): - name: StringProperty() + value: StringProperty() is_noload: BoolProperty(default=False) is_someint: BoolProperty(default=False) someint: IntProperty(default=0) class TextureBlock(bpy.types.PropertyGroup): - name: StringProperty() + value: StringProperty() is_memfix: BoolProperty(default=False) is_noload: BoolProperty(default=False) @@ -55,7 +55,7 @@ class TextureBlock(bpy.types.PropertyGroup): someint: IntProperty() class MaterialBlock(bpy.types.PropertyGroup): - name: StringProperty() + value: StringProperty() is_reflect: BoolProperty(default=False) reflect: FloatProperty(default=0.0) @@ -74,7 +74,11 @@ class MaterialBlock(bpy.types.PropertyGroup): is_tex: BoolProperty(default=False) tex: IntProperty(default=0) + + is_ttx: BoolProperty(default=False) ttx: IntProperty(default=0) + + is_itx: BoolProperty(default=False) itx: IntProperty(default=0) is_att: BoolProperty(default=False) @@ -110,7 +114,7 @@ class MaterialBlock(bpy.types.PropertyGroup): is_wave: BoolProperty(default=False) class ResBlock(bpy.types.PropertyGroup): - name: StringProperty() + value: StringProperty() textures: CollectionProperty(type=TextureBlock) materials: CollectionProperty(type=MaterialBlock) maskfiles: CollectionProperty(type=MaskfileBlock) diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index b442146..12c97bf 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -117,6 +117,28 @@ def __init__(self, file=None, tuple=None): self.z = 0 +def getColPropertyByName(colProperty, value): + result = None + for item in colProperty: + if item.value == value: + result = item + break + return result + +def getColPropertyIndexByName(colProperty, value): + result = -1 + for idx, item in enumerate(colProperty): + if item.value == value: + result = idx + break + return result + + +def existsColPropertyByName(colProperty, value): + for item in colProperty: + if item.value == value: + return True + return False def createMaterials(resModule, palette, texturePath, imageFormat): materialList = resModule.materials @@ -129,7 +151,7 @@ def createMaterial(resModule, palette, texturepath, mat, imageFormat): textureList = resModule.textures - newMat = bpy.data.materials.new(name="{}_{}".format(resModule.name, mat.name)) + newMat = bpy.data.materials.new(name="{}_{}".format(resModule.value, mat.value)) newMat.use_nodes = True bsdf = newMat.node_tree.nodes["Principled BSDF"] @@ -141,9 +163,11 @@ def createMaterial(resModule, palette, texturepath, mat, imageFormat): texColor.outputs[0].default_value = hex_to_rgb(R,G,B) newMat.node_tree.links.new(bsdf.inputs['Base Color'], texColor.outputs['Color']) - if (mat.is_tex and (int(mat.tex) > 0 or int(mat.ttx) > 0 or int(mat.itx) > 0)): + if (mat.is_tex and int(mat.tex) > 0) \ + or (mat.is_ttx and int(mat.ttx) > 0) \ + or (mat.is_itx and int(mat.itx) > 0): texidx = mat.tex | mat.ttx | mat.itx - path = textureList[texidx-1].name + path = textureList[texidx-1].value texImage = newMat.node_tree.nodes.new("ShaderNodeTexImage") texImage.image = bpy.data.images.load(os.path.join(texturepath, "{}.{}".format(path, imageFormat))) newMat.node_tree.links.new(bsdf.inputs['Base Color'], texImage.outputs['Color']) diff --git a/src/2.80/addons/b3d_tools/b3d/import_b3d.py b/src/2.80/addons/b3d_tools/b3d/import_b3d.py index e5ec985..9ab2137 100644 --- a/src/2.80/addons/b3d_tools/b3d/import_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/import_b3d.py @@ -67,6 +67,8 @@ ShowMessageBox, Vector3F, createMaterials, + getColPropertyByName, + getColPropertyIndexByName, getUsedFaces, getUsedFace, getUsedVerticesAndTransform, @@ -346,31 +348,12 @@ def parseRAW(file, context, op, filepath): b3dObj2 = bpy.data.objects.new(basename2, b3dMesh2) context.collection.objects.link(b3dObj2) +def importTextures(filepath, resModules, op): -def read(file, context, op, filepath): - if file.read(3) == b'b3d': - log.info("correct file") - else: - log.error("b3d error") - - commonResPath = bpy.context.preferences.addons['b3d_tools'].preferences.COMMON_RES_Path - - scene = context.scene - mytool = scene.my_tool - - #skip to materials list - file.seek(21,1) - Imgs = [] - math = [] commonPalette = [] - materials = [] noextPath, ext = os.path.splitext(filepath) - basepath = os.path.dirname(filepath) - basename = os.path.basename(filepath)[:-4] #cut extension - - #Пути resPath = '' if len(op.res_location) > 0 and os.path.exists(op.res_location): resPath = op.res_location @@ -380,17 +363,27 @@ def read(file, context, op, filepath): res_basepath = os.path.dirname(resPath) res_basename = os.path.basename(resPath)[:-4] #cut extension - # commonPath = os.path.join(bpy.context.preferences.addons['import_b3d'].preferences.COMMON_RES_Path, r"COMMON") + commonResPath = bpy.context.preferences.addons['b3d_tools'].preferences.COMMON_RES_Path - blocksToImport = op.blocks_to_import + resIndex = getColPropertyIndexByName(resModules, res_basename) + resModule = None + print(resIndex) + if resIndex >= 0: + resModule = resModules[resIndex] + if resModule: + #delete old materials + for m in [cn.value for cn in resModule.materials]: + mat = bpy.data.materials["{}_{}".format(res_basename, m)] + if mat: + bpy.data.materials.remove(mat) + #delete RES module + print("Removing resModule " + str(resIndex)) + resModules.remove(resIndex) + commonResIndex = getColPropertyIndexByName(resModules, "common") + resModules.remove(commonResIndex) - resModules = getattr(mytool, "resModules") resModule = resModules.add() - resModule.name = res_basename - - usedBlocks = {} - for block in blocksToImport: - usedBlocks[block.name] = block.state + resModule.value = res_basename if op.to_import_textures: if op.to_unpack_res: @@ -417,10 +410,12 @@ def read(file, context, op, filepath): #1. Получить общую для большинства палитру Common.plm if os.path.exists(commonResPath): - commonResModule = resModules.add() - commonResModule.name = "common" - unpackRES(commonResModule, commonResPath) - commonPalette = parsePLM(palettePath) + commonResModule = getColPropertyByName(resModules, "common") + if not commonResModule: + commonResModule = resModules.add() + commonResModule.value = "common" + unpackRES(commonResModule, commonResPath) + commonPalette = parsePLM(palettePath) else: log.warning("Failed to unpack COMMON.RES") @@ -434,10 +429,56 @@ def read(file, context, op, filepath): if reTXR.search(path): TXRtoTGA32(fullpath) - #3. Парсинг и добавление материалов createMaterials(resModule, commonPalette, texturePath, op.textures_format) +def read(file, context, op, filepath): + if file.read(3) == b'b3d': + log.info("correct file") + else: + log.error("b3d error") + + commonResPath = bpy.context.preferences.addons['b3d_tools'].preferences.COMMON_RES_Path + + scene = context.scene + mytool = scene.my_tool + + #skip to materials list + file.seek(21,1) + Imgs = [] + math = [] + materials = [] + + resModules = getattr(mytool, "resModules") + + importTextures(filepath, resModules, op) + + + noextPath, ext = os.path.splitext(filepath) + basepath = os.path.dirname(filepath) + basename = os.path.basename(filepath)[:-4] #cut extension + + + #Пути + resPath = '' + if len(op.res_location) > 0 and os.path.exists(op.res_location): + resPath = op.res_location + else: + resPath = os.path.join(noextPath + ".res") + + res_basepath = os.path.dirname(resPath) + res_basename = os.path.basename(resPath)[:-4] #cut extension + + resModule = getColPropertyByName(resModules, res_basename) + + # commonPath = os.path.join(bpy.context.preferences.addons['import_b3d'].preferences.COMMON_RES_Path, r"COMMON") + + blocksToImport = op.blocks_to_import + + usedBlocks = {} + for block in blocksToImport: + usedBlocks[block.name] = block.state + # Parsing b3d material_textures = [] materials_count = struct.unpack(' 1: for texnum in texnums: - mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texnum)].name)] + mat = bpy.data.materials["{}_{}".format(resModule.value, resModule.materials[int(texnum)].value)] b3dMesh.materials.append(mat) lastIndex = len(b3dMesh.materials)-1 @@ -917,7 +958,7 @@ def read(file, context, op, filepath): # op.lock.release() else: for texnum in texnums: - mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texnum)].name)] + mat = bpy.data.materials["{}_{}".format(resModule.value, resModule.materials[int(texnum)].value)] b3dMesh.materials.append(mat) @@ -1635,7 +1676,7 @@ def read(file, context, op, filepath): #Set appropriate meaterials if len(texnums.keys()) > 1: for texnum in texnums: - mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texnum)].name)] + mat = bpy.data.materials["{}_{}".format(resModule.value, resModule.materials[int(texnum)].value)] b3dMesh.materials.append(mat) lastIndex = len(b3dMesh.materials)-1 @@ -1645,7 +1686,7 @@ def read(file, context, op, filepath): # op.lock.release() else: for texnum in texnums: - mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texnum)].name)] + mat = bpy.data.materials["{}_{}".format(resModule.value, resModule.materials[int(texnum)].value)] b3dMesh.materials.append(mat) createCustomAttribute(b3dMesh, formats, pfb_28, pfb_28.Format_Flags) @@ -2033,7 +2074,7 @@ def read(file, context, op, filepath): createCustomAttribute(b3dMesh, curNormals, pvb_35, pvb_35.Custom_Normal) if op.to_import_textures: - mat = bpy.data.materials["{}_{}".format(resModule.name, resModule.materials[int(texNum)].name)] + mat = bpy.data.materials["{}_{}".format(resModule.value, resModule.materials[int(texNum)].value)] b3dMesh.materials.append(mat) @@ -2421,15 +2462,11 @@ def saveMaterial(resModule, materialStr): params = nameSplit[1:] material = resModule.materials.add() - material.name = name + material.value = name i = 0 while i < len(params): paramName = params[i].replace('"', '') - if paramName in ["tex", "ttx", "itx"]: - setattr(material, "is_tex", True) - setattr(material, paramName, int(params[i+1])) - i+=1 - elif paramName in ["col", "att", "msk", "power", "coord"]: + if paramName in ["col", "att", "msk", "power", "coord", "tex", "ttx", "itx"]: setattr(material, "is_" + paramName, True) setattr(material, paramName, int(params[i+1])) i+=1 @@ -2461,7 +2498,7 @@ def saveMaskfile(resModule, maskfileStr): name = rawName.split("\\")[-1][:-4] maskfile = resModule.maskfiles.add() - maskfile.name = name + maskfile.value = name i = 0 while i < len(params): paramName = params[i].replace('"', '') @@ -2487,7 +2524,7 @@ def saveTexture(resModule, textueStr): log.debug(name) texture = resModule.textures.add() - texture.name = name + texture.value = name i = 0 while i < len(params): paramName = params[i].replace('"', '') @@ -2505,7 +2542,7 @@ def saveTexture(resModule, textueStr): i+=1 -def unpackRES(resModule, filepath, saveOnDisk = True): +def unpackRES(resModule, filepath, saveOnDisk = True, ): log.info("Unpacking {}:".format(filepath)) # filename, resExtension = os.path.splitext(filepath) diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index 1b45d7d..ae0f179 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -83,6 +83,16 @@ # store properties in the active scene # ------------------------------------------------------------------------ +def resModuleCallback(scene, context): + + mytool = context.scene.my_tool + resModules = mytool.resModules + + enumProperties = [(str(i), cn.value, "") for i, cn in enumerate(resModules)] + + return enumProperties + + class PanelSettings(bpy.types.PropertyGroup): block1: PointerProperty(type=block_1) @@ -132,6 +142,12 @@ class PanelSettings(bpy.types.PropertyGroup): resModules: CollectionProperty(type=ResBlock) + selectedResModule: EnumProperty( + name="RES модуль", + description="Выбранный RES модуль", + items=resModuleCallback + ) + conditionGroup : bpy.props.IntProperty( name='Номер условия', description='Номер условия(группа обьекта), который надо скрыть/отобразить. Если -1, то берутся все доступные номера. При слишком большом числе берётся ближайшее подходящее.', @@ -1751,8 +1767,6 @@ def execute(self, context): if not len(objs): objs = [cn for cn in bpy.data.objects if isRootObj(cn)] - print(objs) - for obj in objs: hideConditionals(obj, self.group) @@ -2522,6 +2536,342 @@ def draw(self, context): oper = box.operator("wm.hide_conditional_operator") oper.group = getattr(mytool, 'conditionGroup') + +class OBJECT_PT_b3d_res_module_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_res_module_panel" + bl_label = "Игровые ресурсы" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + mytool = scene.my_tool + + layout.prop(mytool, "selectedResModule") + +class OBJECT_PT_b3d_maskfiles_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_maskfiles_panel" + bl_label = "MSK-файлы" + bl_parent_id = "OBJECT_PT_b3d_res_module_panel" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + mytool = scene.my_tool + + currentRes = int(mytool.selectedResModule) + curResModule = mytool.resModules[currentRes] + + box = self.layout.box() + + rows = 2 + row = box.row() + row.template_list("CUSTOM_UL_items", "maskfiles_list", curResModule, "maskfiles", scene, "maskfiles_index", rows=rows) + + col = row.column(align=True) + + props = col.operator("custom.list_action_arrbname", icon='ADD', text="") + props.action = 'ADD' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "maskfiles" + props.customindex = "maskfiles_index" + + props = col.operator("custom.list_action_arrbname", icon='REMOVE', text="") + props.action = 'REMOVE' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "maskfiles" + props.customindex = "maskfiles_index" + + col.separator() + + props = col.operator("custom.list_action_arrbname", icon='TRIA_UP', text="") + props.action = 'UP' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "maskfiles" + props.customindex = "maskfiles_index" + + props = col.operator("custom.list_action_arrbname", icon='TRIA_DOWN', text="") + props.action = 'DOWN' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "maskfiles" + props.customindex = "maskfiles_index" + + #Maskfile edit + box = self.layout.box() + + maskfiles_index = scene.maskfiles_index + curMaskfile = curResModule.maskfiles[maskfiles_index] + + box.prop(curMaskfile, "is_noload", text="Noload") + + split = box.split(factor=0.3) + split.prop(curMaskfile, "is_someint", text="?Someint?") + col = split.column() + col.prop(curMaskfile, "someint") + + col.enabled = curMaskfile.is_someint + + +class OBJECT_PT_b3d_textures_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_textures_panel" + bl_label = "Текстуры" + bl_parent_id = "OBJECT_PT_b3d_res_module_panel" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + mytool = scene.my_tool + + currentRes = int(mytool.selectedResModule) + curResModule = mytool.resModules[currentRes] + + box = self.layout.box() + + rows = 2 + row = box.row() + row.template_list("CUSTOM_UL_items", "textures_list", curResModule, "textures", scene, "textures_index", rows=rows) + + col = row.column(align=True) + + props = col.operator("custom.list_action_arrbname", icon='ADD', text="") + props.action = 'ADD' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "textures" + props.customindex = "textures_index" + + props = col.operator("custom.list_action_arrbname", icon='REMOVE', text="") + props.action = 'REMOVE' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "textures" + props.customindex = "textures_index" + + col.separator() + + props = col.operator("custom.list_action_arrbname", icon='TRIA_UP', text="") + props.action = 'UP' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "textures" + props.customindex = "textures_index" + + props = col.operator("custom.list_action_arrbname", icon='TRIA_DOWN', text="") + props.action = 'DOWN' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "textures" + props.customindex = "textures_index" + + #Texture edit + box = self.layout.box() + + textureIndex = scene.textures_index + curTexture = curResModule.textures[textureIndex] + + box.prop(curTexture, "is_memfix", text="Memfix") + box.prop(curTexture, "is_noload", text="Noload") + box.prop(curTexture, "is_bumpcoord", text="Bympcoord") + + split = box.split(factor=0.3) + split.prop(curTexture, "is_someint", text="?Someint?") + col = split.column() + col.prop(curTexture, "someint") + + col.enabled = curTexture.is_someint + +class OBJECT_PT_b3d_materials_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_materials_panel" + bl_label = "Материалы" + bl_parent_id = "OBJECT_PT_b3d_res_module_panel" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + scene = context.scene + mytool = scene.my_tool + + currentRes = int(mytool.selectedResModule) + curResModule = mytool.resModules[currentRes] + + box = self.layout.box() + + rows = 2 + row = box.row() + row.template_list("CUSTOM_UL_items", "materials_list", curResModule, "materials", scene, "materials_index", rows=rows) + + col = row.column(align=True) + + props = col.operator("custom.list_action_arrbname", icon='ADD', text="") + props.action = 'ADD' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "materials" + props.customindex = "materials_index" + + props = col.operator("custom.list_action_arrbname", icon='REMOVE', text="") + props.action = 'REMOVE' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "materials" + props.customindex = "materials_index" + + col.separator() + + props = col.operator("custom.list_action_arrbname", icon='TRIA_UP', text="") + props.action = 'UP' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "materials" + props.customindex = "materials_index" + + props = col.operator("custom.list_action_arrbname", icon='TRIA_DOWN', text="") + props.action = 'DOWN' + props.bname = "resModules" + props.bindex = currentRes + props.pname = "materials" + props.customindex = "materials_index" + + #Material edit + box = self.layout.box() + + textureIndex = scene.materials_index + curMaterial = curResModule.materials[textureIndex] + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_reflect", text="Reflect") + col = split.column() + col.prop(curMaterial, "reflect") + col.enabled = curMaterial.is_reflect + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_specular", text="Specular") + col = split.column() + col.prop(curMaterial, "specular") + col.enabled = curMaterial.is_specular + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_transp", text="Transparency") + col = split.column() + col.prop(curMaterial, "transp") + col.enabled = curMaterial.is_transp + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_rot", text="Rotation") + col = split.column() + col.prop(curMaterial, "rot") + col.enabled = curMaterial.is_rot + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_col", text="Color") + col = split.column() + col.prop(curMaterial, "col") + col.enabled = curMaterial.is_col + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_tex", text="Texture TEX") + col = split.column() + col.prop(curMaterial, "tex") + col.enabled = curMaterial.is_tex + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_ttx", text="Texture TTX") + col = split.column() + col.prop(curMaterial, "ttx") + col.enabled = curMaterial.is_ttx + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_itx", text="Texture ITX") + col = split.column() + col.prop(curMaterial, "itx") + col.enabled = curMaterial.is_itx + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_att", text="Att") + col = split.column() + col.prop(curMaterial, "att") + col.enabled = curMaterial.is_att + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_msk", text="Maskfile") + col = split.column() + col.prop(curMaterial, "msk") + col.enabled = curMaterial.is_msk + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_power", text="Power") + col = split.column() + col.prop(curMaterial, "power") + col.enabled = curMaterial.is_power + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_coord", text="Coord") + col = split.column() + col.prop(curMaterial, "coord") + col.enabled = curMaterial.is_coord + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_env", text="Env") + col = split.column() + col.prop(curMaterial, "envId") + col.prop(curMaterial, "env") + col.enabled = curMaterial.is_env + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_rotPoint", text="Rotation Center") + col = split.column() + col.prop(curMaterial, "rotPoint") + col.enabled = curMaterial.is_rotPoint + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_move", text="Movement") + col = split.column() + col.prop(curMaterial, "move") + col.enabled = curMaterial.is_move + + box.prop(curMaterial, "is_noz", text="No Z") + box.prop(curMaterial, "is_nof", text="No F") + box.prop(curMaterial, "is_notile", text="No tiling") + box.prop(curMaterial, "is_notileu", text="No tiling U") + box.prop(curMaterial, "is_notilev", text="No tiling V") + box.prop(curMaterial, "is_alphamirr", text="Alphamirr") + box.prop(curMaterial, "is_bumpcoord", text="Bympcoord") + box.prop(curMaterial, "is_usecol", text="UseCol") + box.prop(curMaterial, "is_wave", text="Wave") + + + + class OBJECT_PT_b3d_misc_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_misc_panel" bl_label = "О плагине" @@ -2574,6 +2924,10 @@ def draw(self, context): OBJECT_PT_b3d_pob_edit_panel, OBJECT_PT_b3d_pfb_edit_panel, OBJECT_PT_b3d_pvb_edit_panel, + OBJECT_PT_b3d_res_module_panel, + OBJECT_PT_b3d_maskfiles_panel, + OBJECT_PT_b3d_textures_panel, + OBJECT_PT_b3d_materials_panel, OBJECT_PT_b3d_blocks_panel, OBJECT_PT_b3d_func_panel, OBJECT_PT_b3d_misc_panel, diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index 0917978..be542d6 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -543,19 +543,23 @@ def drawFieldByType(l_self, context, obj, zclass): props.action = 'ADD' props.bname = bname props.pname = pname + props.customindex = "custom_index" props = col.operator("custom.list_action", icon='REMOVE', text="") props.action = 'REMOVE' props.bname = bname props.pname = pname + props.customindex = "custom_index" col.separator() props = col.operator("custom.list_action", icon='TRIA_UP', text="") props.action = 'UP' props.bname = bname props.pname = pname + props.customindex = "custom_index" props = col.operator("custom.list_action", icon='TRIA_DOWN', text="") props.action = 'DOWN' props.bname = bname props.pname = pname + props.customindex = "custom_index" # row = box.row() diff --git a/src/2.80/addons/b3d_tools/custom_UIList.py b/src/2.80/addons/b3d_tools/custom_UIList.py index 86a26da..b8a6f82 100644 --- a/src/2.80/addons/b3d_tools/custom_UIList.py +++ b/src/2.80/addons/b3d_tools/custom_UIList.py @@ -49,9 +49,58 @@ # Operators # ------------------------------------------------------------------- -class CUSTOM_OT_actions(Operator): +def action_invoke(self, context, event, arr_bname = False): + scn = context.scene + idx = getattr(scn, self.customindex) + mytool = scn.my_tool + + if arr_bname: + param = getattr(getattr(mytool, self.bname)[self.bindex], self.pname) + else: + param = getattr(getattr(mytool, self.bname), self.pname) + + try: + item = param[idx] + except IndexError: + pass + else: + if self.action == 'DOWN' and idx < len(param) - 1: + item_next = param[idx+1].name + param.move(idx, idx+1) + idx += 1 + info = 'Item "%s" moved to position %d' % (item.name, idx + 1) + self.report({'INFO'}, info) + + elif self.action == 'UP' and idx >= 1: + item_prev = param[idx-1].name + param.move(idx, idx-1) + idx -= 1 + info = 'Item "%s" moved to position %d' % (item.name, idx + 1) + self.report({'INFO'}, info) + + elif self.action == 'REMOVE': + info = 'Item "%s" removed from list' % (param[idx].name) + idx -= 1 + param.remove(idx) + self.report({'INFO'}, info) + + if self.action == 'ADD': + if context.object: + item = param.add() + # item.name = context.object.name + # item.obj = context.object + item['value'] = 0.0 + idx = len(param)-1 + # info = '"%s" added to list' % (item.name) + # self.report({'INFO'}, info) + else: + pass + # self.report({'INFO'}, "Nothing selected in the Viewport") + return {"FINISHED"} + +class CUSTOM_OT_actions_arrbname(Operator): """Move items up and down, add and remove""" - bl_idname = "custom.list_action" + bl_idname = "custom.list_action_arrbname" bl_label = "List Actions" bl_description = "Move items up and down, add and remove" bl_options = {'REGISTER'} @@ -65,53 +114,38 @@ class CUSTOM_OT_actions(Operator): bname: bpy.props.StringProperty() + bindex: bpy.props.IntProperty(default=-1) + pname: bpy.props.StringProperty() + customindex: bpy.props.StringProperty() + def invoke(self, context, event): - scn = context.scene - idx = scn.custom_index - mytool = scn.my_tool + return action_invoke(self, context, event, True) - param = getattr(getattr(mytool, self.bname), self.pname) - try: - item = param[idx] - except IndexError: - pass - else: - if self.action == 'DOWN' and idx < len(param) - 1: - item_next = param[idx+1].name - param.move(idx, idx+1) - scn.custom_index += 1 - info = 'Item "%s" moved to position %d' % (item.name, scn.custom_index + 1) - self.report({'INFO'}, info) - - elif self.action == 'UP' and idx >= 1: - item_prev = param[idx-1].name - param.move(idx, idx-1) - scn.custom_index -= 1 - info = 'Item "%s" moved to position %d' % (item.name, scn.custom_index + 1) - self.report({'INFO'}, info) - - elif self.action == 'REMOVE': - info = 'Item "%s" removed from list' % (param[idx].name) - scn.custom_index -= 1 - param.remove(idx) - self.report({'INFO'}, info) - - if self.action == 'ADD': - if context.object: - item = param.add() - # item.name = context.object.name - # item.obj = context.object - item['value'] = 0.0 - scn.custom_index = len(param)-1 - # info = '"%s" added to list' % (item.name) - # self.report({'INFO'}, info) - else: - pass - # self.report({'INFO'}, "Nothing selected in the Viewport") - return {"FINISHED"} +class CUSTOM_OT_actions(Operator): + """Move items up and down, add and remove""" + bl_idname = "custom.list_action" + bl_label = "List Actions" + bl_description = "Move items up and down, add and remove" + bl_options = {'REGISTER'} + + action: bpy.props.EnumProperty( + items=( + ('UP', "Up", ""), + ('DOWN', "Down", ""), + ('REMOVE', "Remove", ""), + ('ADD', "Add", ""))) + + bname: bpy.props.StringProperty() + + pname: bpy.props.StringProperty() + + customindex: bpy.props.StringProperty() + + def invoke(self, context, event): + return action_invoke(self, context, event, False) class CUSTOM_OT_addViewportSelection(Operator): @@ -360,7 +394,7 @@ def draw(self, context): rows = 2 row = layout.row() - row.template_list("CUSTOM_UL_items", "", scn, "custom", scn, "custom_index", rows=rows) + row.template_list("CUSTOM_UL_items", "float_list", scn, "custom", scn, "custom_index", rows=rows) col = row.column(align=True) col.operator("custom.list_action", icon='ADD', text="").action = 'ADD' @@ -369,24 +403,6 @@ def draw(self, context): col.operator("custom.list_action", icon='TRIA_UP', text="").action = 'UP' col.operator("custom.list_action", icon='TRIA_DOWN', text="").action = 'DOWN' - # row = layout.row() - # col = row.column(align=True) - # row = col.row(align=True) - # row.operator("custom.print_items", icon="LINENUMBERS_ON") - # row = col.row(align=True) - # row.operator("custom.clear_list", icon="X") - # row.operator("custom.remove_duplicates", icon="GHOST_ENABLED") - - # row = layout.row() - # col = row.column(align=True) - # row = col.row(align=True) - # row.operator("custom.add_viewport_selection", icon="HAND") #LINENUMBERS_OFF, ANIM - # row = col.row(align=True) - # row.operator("custom.select_items", icon="VIEW3D", text="Select Item in 3D View") - # row.operator("custom.select_items", icon="GROUP", text="Select All Items in 3D View").select_all = True - # row = col.row(align=True) - # row.operator("custom.delete_object", icon="X") - # ------------------------------------------------------------------- # Collection @@ -405,6 +421,7 @@ class CUSTOM_PG_objectCollection(PropertyGroup): classes = ( CUSTOM_OT_actions, + CUSTOM_OT_actions_arrbname, CUSTOM_OT_addViewportSelection, CUSTOM_OT_printItems, CUSTOM_OT_clearList, @@ -424,6 +441,9 @@ def register(): # Custom scene properties bpy.types.Scene.custom = CollectionProperty(type=CUSTOM_PG_objectCollection) bpy.types.Scene.custom_index = IntProperty() + bpy.types.Scene.textures_index = IntProperty() + bpy.types.Scene.materials_index = IntProperty() + bpy.types.Scene.maskfiles_index = IntProperty() def unregister(): @@ -433,6 +453,10 @@ def unregister(): del bpy.types.Scene.custom del bpy.types.Scene.custom_index + del bpy.types.Scene.textures_index + del bpy.types.Scene.materials_index + del bpy.types.Scene.maskfiles_index + if __name__ == "__main__": From cf56fd10f204eb231003b781bbb06efdb0dca48c Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Thu, 29 Dec 2022 19:59:55 +0200 Subject: [PATCH 20/47] first successful export! --- src/2.80/addons/b3d_tools/b3d/classes.py | 7 +- src/2.80/addons/b3d_tools/b3d/common.py | 18 +- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 450 ++++++++++++++++---- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 18 +- src/2.80/addons/b3d_tools/b3d/menus.py | 11 +- 5 files changed, 401 insertions(+), 103 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index f78caf9..bcba7fc 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -1690,7 +1690,12 @@ class b_40(): 'description': '', 'default': 0 } - #todo check + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } perFaceBlock_8 = createTypeClass(pfb_8) diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 12c97bf..c2d1377 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -21,11 +21,17 @@ # log = logging.getLogger("common") # log.setLevel(logging.DEBUG) +def getNonCopyName(name): + reIsCopy = re.compile(r'\.[0-9]*$') + matchInd = reIsCopy.search(name) + result = name + if matchInd: + result = name[:matchInd.span()[0]] + return result def isRootObj(obj): return obj.parent is None and obj.name[-4:] == '.b3d' - def isEmptyName(name): reIsEmpty = re.compile(r'.*empty name.*') return reIsEmpty.search(name) @@ -140,6 +146,16 @@ def existsColPropertyByName(colProperty, value): return True return False +def getMaterialIndexInRES(matName): + resModules = bpy.context.scene.my_tool.resModules + delimiterInd = matName.find("_") + resModuleName = matName[:delimiterInd] + materialName = matName[delimiterInd+1:] + curModule = getColPropertyByName(resModules, resModuleName) + curMaterialInd = getColPropertyIndexByName(curModule.materials, materialName) + return curMaterialInd + + def createMaterials(resModule, palette, texturePath, imageFormat): materialList = resModule.materials diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index a864655..2062cce 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -65,7 +65,8 @@ ) from .scripts import ( - prop + prop, + getAllChildren ) from ..common import ( @@ -73,6 +74,9 @@ ) from .common import ( + getColPropertyByName, + getMaterialIndexInRES, + getNonCopyName, isRootObj, isEmptyName ) @@ -250,6 +254,10 @@ def export(file, generate_pro_file): for material in bpy.data.materials: materials.append(material.name) + cp_materials = 0 + cp_data_blocks = 0 + cp_eof = 0 + #Header file.write(b'b3d\x00')#struct.pack("4c",b'B',b'3',b'D',b'\x00')) @@ -266,8 +274,8 @@ def export(file, generate_pro_file): file.write(struct.pack(' 0: + for obj in rChild[:-1]: + if obj['block_type'] == 10 or obj['block_type'] == 9: + curMaxCnt = 2 + elif obj['block_type'] == 21: + curMaxCnt = obj[prop(b_21.GroupCnt)] + exportBlock(obj, True, curLevel, curMaxCnt, [0], {}, file) + file.write(struct.pack(" 0): + l_extra = extra + if(len(block.children) > 0): # TODO: passToMesh only to subchildren for i, ch in enumerate(blChildren[:-1]): - if len(passToMesh): - l_extra = passToMesh[i] + if len(passToMesh) > 0: + l_extra['passToMesh'] = passToMesh exportBlock(ch, False, curLevel+1, curMaxCnt, curGroups, l_extra, file) - if len(passToMesh): - l_extra = passToMesh[-1] + if len(passToMesh) > 0: + l_extra['passToMesh'] = passToMesh exportBlock(blChildren[-1], True, curLevel+1, curMaxCnt, curGroups, l_extra, file) - log.debug("{}_{}".format(curGroups, block.name)) + file.write(struct.pack(" Date: Tue, 3 Jan 2023 11:59:27 +0200 Subject: [PATCH 21/47] export as-is(bad UV) --- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 172 ++++++++++++++------ src/2.80/addons/b3d_tools/b3d/import_b3d.py | 4 +- src/2.80/addons/b3d_tools/b3d/scripts.py | 1 - 3 files changed, 123 insertions(+), 54 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index 2062cce..d582929 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -261,13 +261,6 @@ def export(file, generate_pro_file): #Header file.write(b'b3d\x00')#struct.pack("4c",b'B',b'3',b'D',b'\x00')) - # file.write(struct.pack('> 8) + + if format & 0b10: + uvCount += 1 + + if format & 0b100000 and format & 0b10000: + useNormals = True + if format & 0b1: + normalSwitch = True + else: + normalSwitch = False + + for i, vert in enumerate(poly.vertices): file.write(struct.pack("> 8) + + if format & 0b10: + uvCount += 1 + + if format & 0b100000 and format & 0b10000: + useNormals = True + if format & 0b1: + normalSwitch = True + else: + normalSwitch = False + + for i, vert in enumerate(poly.vertices): file.write(struct.pack("> 8 + format = formatRaw & 0xFF + + if format == 1 or format == 2: + normalSwitch = True + elif format == 3: + normalSwitch = False + + file.write(struct.pack("> 8 + format = formatRaw & 0xFF + + if format == 1 or format == 2: + normalSwitch = True + elif format == 3: + normalSwitch = False + + file.write(struct.pack(" 0): # TODO: passToMesh only to subchildren + if(len(block.children) > 0): for i, ch in enumerate(blChildren[:-1]): if len(passToMesh) > 0: diff --git a/src/2.80/addons/b3d_tools/b3d/import_b3d.py b/src/2.80/addons/b3d_tools/b3d/import_b3d.py index 8f5108b..315f63e 100644 --- a/src/2.80/addons/b3d_tools/b3d/import_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/import_b3d.py @@ -2160,7 +2160,7 @@ def read(file, context, op, filepath): b3dObj[prop(b_36.R)] = bounding_sphere[3] b3dObj[prop(b_36.Name1)] = name1 b3dObj[prop(b_36.Name2)] = name2 - b3dObj[prop(b_36.MType)] = format + b3dObj[prop(b_36.MType)] = formatRaw b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) @@ -2232,7 +2232,7 @@ def read(file, context, op, filepath): b3dObj[prop(b_37.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_37.R)] = bounding_sphere[3] b3dObj[prop(b_37.Name1)] = groupName - b3dObj[prop(b_37.SType)] = format + b3dObj[prop(b_37.SType)] = formatRaw b3dObj.parent = context.scene.objects[objString[-2]] context.collection.objects.link(b3dObj) diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index be542d6..2eb94fe 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -687,7 +687,6 @@ def getFromAttributes(context, obj, attrs, bname, index): mytool = context.scene.my_tool - if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ and getattr(getattr(mytool, bname), "show_"+obj['prop']): From f37867e2603a11a7cc1909caa448517ab54cc41f Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Fri, 6 Jan 2023 23:06:39 +0200 Subject: [PATCH 22/47] block 33 import fix --- src/2.80/addons/b3d_tools/b3d/classes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index bcba7fc..a67c8ab 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -1397,21 +1397,21 @@ class b_33(): 'default': 0.0 } Use_Lights = { - 'prop': 'int1', + 'prop': 'useLight', 'type': fieldType.INT, 'name': 'Исп. свет', 'description': '', 'default': 0 } Light_Type = { - 'prop': 'int2', + 'prop': 'lType', 'type': fieldType.INT, 'name': 'Тип света', 'description': '', 'default': 0 } Flag = { - 'prop': 'int2', + 'prop': 'flag', 'type': fieldType.INT, 'name': 'Флаг', 'description': '', From 80856c47a0a7e3ab2a48c056b29b4530dc25800f Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Fri, 6 Jan 2023 23:07:20 +0200 Subject: [PATCH 23/47] working export (unoptimized size) --- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 55 +++++++++++++-------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index d582929..8d20fda 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -274,7 +274,14 @@ def export(file, generate_pro_file): # curRoot = objs[0] curRoot = bpy.context.object - rChild = curRoot.children + allObjs = curRoot.children + + spaces = [cn for cn in allObjs if cn['block_type'] == 24] + other = [cn for cn in allObjs if cn['block_type'] != 24] + + rChild = [] + rChild.extend(spaces) + rChild.extend(other) resModules = bpy.context.scene.my_tool.resModules curModule = getColPropertyByName(resModules, curRoot.name[:-4]) @@ -299,10 +306,10 @@ def export(file, generate_pro_file): elif obj['block_type'] == 21: curMaxCnt = obj[prop(b_21.GroupCnt)] exportBlock(obj, True, curLevel, curMaxCnt, [0], {}, file) + file.write(struct.pack("> 8 format = formatRaw & 0xFF @@ -1128,13 +1145,9 @@ def exportBlock(obj, isLast, curLevel, maxGroups, curGroups, extra, file): elif format == 3: normalSwitch = False - file.write(struct.pack("> 8 format = formatRaw & 0xFF @@ -1439,7 +1452,7 @@ def forChild(object, root, file): #type 8 - if object['BType'] == 8: + if object['BType'] ==8: export08(object, verticesL, file, faces, uvs) else: export35(object, verticesL, file, faces, uvs) From 708d0f828e5e1525fa01accb8ed130cf8894f817 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 7 Jan 2023 18:34:34 +0200 Subject: [PATCH 24/47] cleanup + reporting --- src/2.80/addons/b3d_tools/__init__.py | 23 -- src/2.80/addons/b3d_tools/b3d/classes.py | 39 +-- src/2.80/addons/b3d_tools/b3d/common.py | 54 ++--- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 11 +- src/2.80/addons/b3d_tools/b3d/imghelp.py | 5 - src/2.80/addons/b3d_tools/b3d/import_b3d.py | 56 ++--- src/2.80/addons/b3d_tools/b3d/menus.py | 23 -- src/2.80/addons/b3d_tools/b3d/panel.py | 251 ++++++++++---------- src/2.80/addons/b3d_tools/b3d/scripts.py | 51 +--- 9 files changed, 204 insertions(+), 309 deletions(-) diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py index e8f44cf..bf83362 100644 --- a/src/2.80/addons/b3d_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -46,25 +46,6 @@ from .tch import tch_unregister, tch_register -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -# bl_info = { "name": "King of The Road Tools", @@ -86,15 +67,11 @@ def register(): - # material_UIList.register() - # object_UIList.register() custom_UIList.register() b3d.register() # tch_register() def unregister(): - # material_UIList.unregister() - # object_UIList.unregister() b3d.unregister() custom_UIList.unregister() # tch_unregister() diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index a67c8ab..2b11c5a 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -19,6 +19,26 @@ from ..common import log +# Dynamic block exmaple +# block_5 = type("block_5", (bpy.types.PropertyGroup,), { +# '__annotations__': { +# 'name': StringProperty( +# name="Имя блока", +# default="", +# maxlen=30, +# ), +# 'XYZ': FloatVectorProperty( +# name='Координаты блока', +# description='', +# default=(0.0, 0.0, 0.0) +# ), +# 'R': FloatProperty( +# name = "Радиус", +# description = "", + +# ) +# } +# }) class fieldType(enum.Enum): STRING = 1 @@ -449,25 +469,6 @@ class b_5(): 'default': 0.0 } -# block_5 = type("block_5", (bpy.types.PropertyGroup,), { -# '__annotations__': { -# 'name': StringProperty( -# name="Имя блока", -# default="", -# maxlen=30, -# ), -# 'XYZ': FloatVectorProperty( -# name='Координаты блока', -# description='', -# default=(0.0, 0.0, 0.0) -# ), -# 'R': FloatProperty( -# name = "Радиус", -# description = "", - -# ) -# } -# }) class b_6(): XYZ = { diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index c2d1377..56fe95b 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -7,20 +7,6 @@ from ..common import log -from bpy.props import ( - FloatProperty, - IntProperty, - FloatVectorProperty, - BoolProperty, - StringProperty, - PointerProperty -) -from bpy.types import UIList - -# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) -# log = logging.getLogger("common") -# log.setLevel(logging.DEBUG) - def getNonCopyName(name): reIsCopy = re.compile(r'\.[0-9]*$') matchInd = reIsCopy.search(name) @@ -32,17 +18,26 @@ def getNonCopyName(name): def isRootObj(obj): return obj.parent is None and obj.name[-4:] == '.b3d' +def getRootObj(obj): + result = obj + while not isRootObj(result): + result = result.parent + return result + def isEmptyName(name): reIsEmpty = re.compile(r'.*empty name.*') return reIsEmpty.search(name) -def ShowMessageBox(message = "", title = "Message Box", icon = 'INFO'): - - def draw(self, context): - self.layout.label(text=message) - - bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) +def isMeshBlock(obj): + # 18 - for correct transform apply + return obj.get("block_type") is not None \ + and (obj["block_type"]==8 or obj["block_type"]==35\ + or obj["block_type"]==28 \ + # or obj["block_type"]==18 + ) +def isRefBlock(obj): + return obj.get("block_type") is not None and obj["block_type"]==18 def unmaskShort(num): bits = [int(digit) for digit in bin(num)[2:]] @@ -105,24 +100,6 @@ def __init__(self): self.usecol = False # bool self.wave = False # bool -class Vector3F(): - - def __init__(self, file=None, tuple=None): - if file != None: - tpl = struct.unpack("<3f", file.read(12)) - self.x = tpl[0] - self.y = tpl[1] - self.z = tpl[2] - elif tuple != None: - self.x = tuple[0] - self.y = tuple[1] - self.z = tuple[2] - else: - self.x = 0 - self.y = 0 - self.z = 0 - - def getColPropertyByName(colProperty, value): result = None for item in colProperty: @@ -139,7 +116,6 @@ def getColPropertyIndexByName(colProperty, value): break return result - def existsColPropertyByName(colProperty, value): for item in colProperty: if item.value == value: diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index 8d20fda..6259310 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -78,6 +78,7 @@ getMaterialIndexInRES, getNonCopyName, isRootObj, + getRootObj, isEmptyName ) @@ -272,9 +273,15 @@ def export(file, generate_pro_file): objs = [cn for cn in bpy.data.objects if isRootObj(cn)] # curRoot = objs[0] - curRoot = bpy.context.object + obj = bpy.context.object + curRoot = getRootObj(obj) - allObjs = curRoot.children + allObjs = [] + + if isRootObj(obj): + allObjs = curRoot.children + else: + allObjs = [obj] spaces = [cn for cn in allObjs if cn['block_type'] == 24] other = [cn for cn in allObjs if cn['block_type'] != 24] diff --git a/src/2.80/addons/b3d_tools/b3d/imghelp.py b/src/2.80/addons/b3d_tools/b3d/imghelp.py index 06ae0ff..2a4d230 100644 --- a/src/2.80/addons/b3d_tools/b3d/imghelp.py +++ b/src/2.80/addons/b3d_tools/b3d/imghelp.py @@ -4,13 +4,8 @@ import logging import sys - from ..common import log -# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) -# log = logging.getLogger("imghelp") -# log.setLevel(logging.DEBUG) - def parsePLM(filepath): colors = [] with open(filepath, "rb") as plmFile: diff --git a/src/2.80/addons/b3d_tools/b3d/import_b3d.py b/src/2.80/addons/b3d_tools/b3d/import_b3d.py index 315f63e..9b73da8 100644 --- a/src/2.80/addons/b3d_tools/b3d/import_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/import_b3d.py @@ -64,8 +64,6 @@ from .imghelp import TXRtoTGA32 from .imghelp import parsePLM from .common import ( - ShowMessageBox, - Vector3F, createMaterials, getColPropertyByName, getColPropertyIndexByName, @@ -96,9 +94,6 @@ from ..common import log -# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) -# log = logging.getLogger("import_b3d") -# log.setLevel(logging.DEBUG) def thread_import_b3d(self, files, context): for b3dfile in files: @@ -348,15 +343,15 @@ def parseRAW(file, context, op, filepath): b3dObj2 = bpy.data.objects.new(basename2, b3dMesh2) context.collection.objects.link(b3dObj2) -def importTextures(filepath, resModules, op): +def importTextures(filepath, resModules, self): commonPalette = [] noextPath, ext = os.path.splitext(filepath) resPath = '' - if len(op.res_location) > 0 and os.path.exists(op.res_location): - resPath = op.res_location + if len(self.res_location) > 0 and os.path.exists(self.res_location): + resPath = self.res_location else: resPath = os.path.join(noextPath + ".res") @@ -373,7 +368,7 @@ def importTextures(filepath, resModules, op): if resModule: #delete old materials for m in [cn.value for cn in resModule.materials]: - mat = bpy.data.materials["{}_{}".format(res_basename, m)] + mat = bpy.data.materials.get("{}_{}".format(res_basename, m)) if mat: bpy.data.materials.remove(mat) #delete RES module @@ -385,19 +380,17 @@ def importTextures(filepath, resModules, op): resModule = resModules.add() resModule.value = res_basename - if op.to_import_textures: - if op.to_unpack_res: + if self.to_import_textures: + if self.to_unpack_res: unpackRES(resModule, resPath, True) else: unpackRES(resModule, resPath, False) - if op.to_import_textures and not os.path.exists(commonResPath): - # ShowMessageBox("Common.res path is wrong or is not set. Textures weren't imported! Please, set path to Common.res in addon preferences.", - # "COMMON.res wrong path", - # "ERROR") - op.to_import_textures = False + if self.to_import_textures and not os.path.exists(commonResPath): + self.report({'ERROR'}, "Common.res path is wrong or is not set. Textures weren't imported! Please, set path to Common.res in addon preferences.") + self.to_import_textures = False - if op.to_import_textures and os.path.exists(commonResPath): + if self.to_import_textures and os.path.exists(commonResPath): # commonPath = os.path.join(r"D:\_PROJECTS\DB2\Hard Truck 2", r"COMMON") # commonResPath = os.path.join(commonPath, r"COMMON.RES") commonPath = os.path.join(os.path.dirname(commonResPath)) @@ -421,7 +414,7 @@ def importTextures(filepath, resModules, op): #2. Распаковка .RES и конвертация .txr и .msk в .tga 32bit # txrFolder = os.path.join(texturePath, "txr") - if op.to_convert_txr: + if self.to_convert_txr: folder_content = os.listdir(texturePath) reTXR = re.compile(r'\.txr') for path in folder_content: @@ -430,9 +423,9 @@ def importTextures(filepath, resModules, op): TXRtoTGA32(fullpath) #3. Парсинг и добавление материалов - createMaterials(resModule, commonPalette, texturePath, op.textures_format) + createMaterials(resModule, commonPalette, texturePath, self.textures_format) -def read(file, context, op, filepath): +def read(file, context, self, filepath): if file.read(3) == b'b3d': log.info("correct file") else: @@ -451,8 +444,7 @@ def read(file, context, op, filepath): resModules = getattr(mytool, "resModules") - importTextures(filepath, resModules, op) - + importTextures(filepath, resModules, self) noextPath, ext = os.path.splitext(filepath) basepath = os.path.dirname(filepath) @@ -461,8 +453,8 @@ def read(file, context, op, filepath): #Пути resPath = '' - if len(op.res_location) > 0 and os.path.exists(op.res_location): - resPath = op.res_location + if len(self.res_location) > 0 and os.path.exists(self.res_location): + resPath = self.res_location else: resPath = os.path.join(noextPath + ".res") @@ -473,7 +465,7 @@ def read(file, context, op, filepath): # commonPath = os.path.join(bpy.context.preferences.addons['import_b3d'].preferences.COMMON_RES_Path, r"COMMON") - blocksToImport = op.blocks_to_import + blocksToImport = self.blocks_to_import usedBlocks = {} for block in blocksToImport: @@ -941,7 +933,7 @@ def read(file, context, op, filepath): realName = b3dObj.name objString[len(objString)-1] = b3dObj.name - if op.to_import_textures: + if self.to_import_textures: #For assignMaterialByVertices just-in-case # bpy.ops.object.mode_set(mode = 'OBJECT') #Set appropriate meaterials @@ -953,9 +945,9 @@ def read(file, context, op, filepath): for vertArr in texnums[texnum]: newVertArr = getUsedFace(vertArr, oldNewTransf) - # op.lock.acquire() + # self.lock.acquire() assignMaterialByVertices(b3dObj, newVertArr, lastIndex) - # op.lock.release() + # self.lock.release() else: for texnum in texnums: mat = bpy.data.materials["{}_{}".format(resModule.value, resModule.materials[int(texnum)].value)] @@ -1673,7 +1665,7 @@ def read(file, context, op, filepath): uvsMesh = [uvOver[i][j][0],1 - uvOver[i][j][1]] customUV.data[loop].uv = uvsMesh - if op.to_import_textures: + if self.to_import_textures: #For assignMaterialByVertices just-in-case # bpy.ops.object.mode_set(mode = 'OBJECT') #Set appropriate meaterials @@ -1684,9 +1676,9 @@ def read(file, context, op, filepath): lastIndex = len(b3dMesh.materials)-1 for vertArr in texnums[texnum]: - # op.lock.acquire() + # self.lock.acquire() assignMaterialByVertices(b3dObj, vertArr, lastIndex) - # op.lock.release() + # self.lock.release() else: for texnum in texnums: mat = bpy.data.materials["{}_{}".format(resModule.value, resModule.materials[int(texnum)].value)] @@ -2076,7 +2068,7 @@ def read(file, context, op, filepath): createCustomAttribute(b3dMesh, curNormalsOff, pvb_35, pvb_35.Normal_Switch) createCustomAttribute(b3dMesh, curNormals, pvb_35, pvb_35.Custom_Normal) - if op.to_import_textures: + if self.to_import_textures: mat = bpy.data.materials["{}_{}".format(resModule.value, resModule.materials[int(texNum)].value)] b3dMesh.materials.append(mat) diff --git a/src/2.80/addons/b3d_tools/b3d/menus.py b/src/2.80/addons/b3d_tools/b3d/menus.py index abb52ce..def1768 100644 --- a/src/2.80/addons/b3d_tools/b3d/menus.py +++ b/src/2.80/addons/b3d_tools/b3d/menus.py @@ -111,18 +111,6 @@ def invoke(self, context, event): wm.fileselect_add(self) return {"RUNNING_MODAL"} - - # def thread_import_b3d(self, files, context): - # for b3dfile in files: - # filepath = os.path.join(self.directory, b3dfile.name) - - # print('Importing file', filepath) - # t = time.mktime(datetime.datetime.now().timetuple()) - # with open(filepath, 'rb') as file: - # import_b3d.read(file, context, self, filepath) - # t = time.mktime(datetime.datetime.now().timetuple()) - t - # print('Finished importing in', t, 'seconds') - def execute(self, context): evens = [cn for i,cn in enumerate(self.files) if i%2==0] odds = [cn for i,cn in enumerate(self.files) if i%2==1] @@ -139,17 +127,6 @@ def execute(self, context): t1.join() t2.join() - # for b3dfile in self.files: - # filepath = os.path.join(self.directory, b3dfile.name) - - # print('Importing file', filepath) - # t = time.mktime(datetime.datetime.now().timetuple()) - # with open(filepath, 'rb') as file: - # import_b3d.read(file, context, self, filepath) - # t = time.mktime(datetime.datetime.now().timetuple()) - t - # print('Finished importing in', t, 'seconds') - - tt = time.mktime(datetime.datetime.now().timetuple()) - tt print('All imported in', tt, 'seconds') diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index ae0f179..c24b1ae 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -1648,7 +1648,7 @@ def execute(self, context): scene = context.scene mytool = scene.my_tool - applyRemoveTransforms() + applyRemoveTransforms(self) return {'FINISHED'} @@ -1661,7 +1661,7 @@ def execute(self, context): scene = context.scene mytool = scene.my_tool - showHideObjByType(23) + showHideObjByType(self, 23) return {'FINISHED'} @@ -1707,6 +1707,7 @@ def execute(self, context): for obj in objs: showLOD(obj) + self.report({'INFO'}, "{} LOD objects(block 10) are shown".format(len(objs))) return {'FINISHED'} @@ -1726,6 +1727,7 @@ def execute(self, context): for obj in objs: hideLOD(obj) + self.report({'INFO'}, "{} LOD objects(block 10) are hidden".format(len(objs))) return {'FINISHED'} @@ -1748,6 +1750,8 @@ def execute(self, context): for obj in objs: showConditionals(obj, self.group) + self.report({'INFO'}, "{} Conditional objects(block 21) are shown".format(len(objs))) + return {'FINISHED'} @@ -1769,6 +1773,7 @@ def execute(self, context): for obj in objs: hideConditionals(obj, self.group) + self.report({'INFO'}, "{} Conditional objects(block 21) are hidden".format(len(objs))) return {'FINISHED'} @@ -2484,13 +2489,10 @@ def poll(self,context): def draw(self, context): layout = self.layout - # print(dir(context)) mytool = context.scene.my_tool type = mytool.addBlocks_enum - # print(dir(mytool)) - layout.prop(mytool, "addBlocks_enum") if type == "room": @@ -2617,16 +2619,17 @@ def draw(self, context): box = self.layout.box() maskfiles_index = scene.maskfiles_index - curMaskfile = curResModule.maskfiles[maskfiles_index] + if len(curResModule.maskfiles): + curMaskfile = curResModule.maskfiles[maskfiles_index] - box.prop(curMaskfile, "is_noload", text="Noload") + box.prop(curMaskfile, "is_noload", text="Noload") - split = box.split(factor=0.3) - split.prop(curMaskfile, "is_someint", text="?Someint?") - col = split.column() - col.prop(curMaskfile, "someint") + split = box.split(factor=0.3) + split.prop(curMaskfile, "is_someint", text="?Someint?") + col = split.column() + col.prop(curMaskfile, "someint") - col.enabled = curMaskfile.is_someint + col.enabled = curMaskfile.is_someint class OBJECT_PT_b3d_textures_panel(bpy.types.Panel): @@ -2691,18 +2694,19 @@ def draw(self, context): box = self.layout.box() textureIndex = scene.textures_index - curTexture = curResModule.textures[textureIndex] + if (len(curResModule.textures)): + curTexture = curResModule.textures[textureIndex] - box.prop(curTexture, "is_memfix", text="Memfix") - box.prop(curTexture, "is_noload", text="Noload") - box.prop(curTexture, "is_bumpcoord", text="Bympcoord") + box.prop(curTexture, "is_memfix", text="Memfix") + box.prop(curTexture, "is_noload", text="Noload") + box.prop(curTexture, "is_bumpcoord", text="Bympcoord") - split = box.split(factor=0.3) - split.prop(curTexture, "is_someint", text="?Someint?") - col = split.column() - col.prop(curTexture, "someint") + split = box.split(factor=0.3) + split.prop(curTexture, "is_someint", text="?Someint?") + col = split.column() + col.prop(curTexture, "someint") - col.enabled = curTexture.is_someint + col.enabled = curTexture.is_someint class OBJECT_PT_b3d_materials_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_materials_panel" @@ -2766,108 +2770,109 @@ def draw(self, context): box = self.layout.box() textureIndex = scene.materials_index - curMaterial = curResModule.materials[textureIndex] - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_reflect", text="Reflect") - col = split.column() - col.prop(curMaterial, "reflect") - col.enabled = curMaterial.is_reflect - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_specular", text="Specular") - col = split.column() - col.prop(curMaterial, "specular") - col.enabled = curMaterial.is_specular - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_transp", text="Transparency") - col = split.column() - col.prop(curMaterial, "transp") - col.enabled = curMaterial.is_transp - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_rot", text="Rotation") - col = split.column() - col.prop(curMaterial, "rot") - col.enabled = curMaterial.is_rot - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_col", text="Color") - col = split.column() - col.prop(curMaterial, "col") - col.enabled = curMaterial.is_col - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_tex", text="Texture TEX") - col = split.column() - col.prop(curMaterial, "tex") - col.enabled = curMaterial.is_tex - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_ttx", text="Texture TTX") - col = split.column() - col.prop(curMaterial, "ttx") - col.enabled = curMaterial.is_ttx - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_itx", text="Texture ITX") - col = split.column() - col.prop(curMaterial, "itx") - col.enabled = curMaterial.is_itx - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_att", text="Att") - col = split.column() - col.prop(curMaterial, "att") - col.enabled = curMaterial.is_att - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_msk", text="Maskfile") - col = split.column() - col.prop(curMaterial, "msk") - col.enabled = curMaterial.is_msk - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_power", text="Power") - col = split.column() - col.prop(curMaterial, "power") - col.enabled = curMaterial.is_power - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_coord", text="Coord") - col = split.column() - col.prop(curMaterial, "coord") - col.enabled = curMaterial.is_coord - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_env", text="Env") - col = split.column() - col.prop(curMaterial, "envId") - col.prop(curMaterial, "env") - col.enabled = curMaterial.is_env - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_rotPoint", text="Rotation Center") - col = split.column() - col.prop(curMaterial, "rotPoint") - col.enabled = curMaterial.is_rotPoint - - split = box.split(factor=0.3) - split.prop(curMaterial, "is_move", text="Movement") - col = split.column() - col.prop(curMaterial, "move") - col.enabled = curMaterial.is_move - - box.prop(curMaterial, "is_noz", text="No Z") - box.prop(curMaterial, "is_nof", text="No F") - box.prop(curMaterial, "is_notile", text="No tiling") - box.prop(curMaterial, "is_notileu", text="No tiling U") - box.prop(curMaterial, "is_notilev", text="No tiling V") - box.prop(curMaterial, "is_alphamirr", text="Alphamirr") - box.prop(curMaterial, "is_bumpcoord", text="Bympcoord") - box.prop(curMaterial, "is_usecol", text="UseCol") - box.prop(curMaterial, "is_wave", text="Wave") + if (len(curResModule.materials)): + curMaterial = curResModule.materials[textureIndex] + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_reflect", text="Reflect") + col = split.column() + col.prop(curMaterial, "reflect") + col.enabled = curMaterial.is_reflect + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_specular", text="Specular") + col = split.column() + col.prop(curMaterial, "specular") + col.enabled = curMaterial.is_specular + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_transp", text="Transparency") + col = split.column() + col.prop(curMaterial, "transp") + col.enabled = curMaterial.is_transp + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_rot", text="Rotation") + col = split.column() + col.prop(curMaterial, "rot") + col.enabled = curMaterial.is_rot + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_col", text="Color") + col = split.column() + col.prop(curMaterial, "col") + col.enabled = curMaterial.is_col + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_tex", text="Texture TEX") + col = split.column() + col.prop(curMaterial, "tex") + col.enabled = curMaterial.is_tex + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_ttx", text="Texture TTX") + col = split.column() + col.prop(curMaterial, "ttx") + col.enabled = curMaterial.is_ttx + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_itx", text="Texture ITX") + col = split.column() + col.prop(curMaterial, "itx") + col.enabled = curMaterial.is_itx + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_att", text="Att") + col = split.column() + col.prop(curMaterial, "att") + col.enabled = curMaterial.is_att + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_msk", text="Maskfile") + col = split.column() + col.prop(curMaterial, "msk") + col.enabled = curMaterial.is_msk + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_power", text="Power") + col = split.column() + col.prop(curMaterial, "power") + col.enabled = curMaterial.is_power + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_coord", text="Coord") + col = split.column() + col.prop(curMaterial, "coord") + col.enabled = curMaterial.is_coord + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_env", text="Env") + col = split.column() + col.prop(curMaterial, "envId") + col.prop(curMaterial, "env") + col.enabled = curMaterial.is_env + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_rotPoint", text="Rotation Center") + col = split.column() + col.prop(curMaterial, "rotPoint") + col.enabled = curMaterial.is_rotPoint + + split = box.split(factor=0.3) + split.prop(curMaterial, "is_move", text="Movement") + col = split.column() + col.prop(curMaterial, "move") + col.enabled = curMaterial.is_move + + box.prop(curMaterial, "is_noz", text="No Z") + box.prop(curMaterial, "is_nof", text="No F") + box.prop(curMaterial, "is_notile", text="No tiling") + box.prop(curMaterial, "is_notileu", text="No tiling U") + box.prop(curMaterial, "is_notilev", text="No tiling V") + box.prop(curMaterial, "is_alphamirr", text="Alphamirr") + box.prop(curMaterial, "is_bumpcoord", text="Bympcoord") + box.prop(curMaterial, "is_usecol", text="UseCol") + box.prop(curMaterial, "is_wave", text="Wave") diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index 2eb94fe..57ac717 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -15,15 +15,13 @@ from .common import ( getPolygonsBySelectedVertices, getSelectedVertices, - isRootObj + isRootObj, + isMeshBlock ) from .classes import ( fieldType, b_common ) -# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) -# log = logging.getLogger("common") - reb3dSpace = re.compile(r'.*b3dSpaceCopy.*') reb3dMesh = re.compile(r'.*b3dcopy.*') @@ -183,7 +181,7 @@ def applyTransform(root): stack.append([directChild, prevSpace, prevSpaceCopy]) -def applyRemoveTransforms(): +def applyRemoveTransforms(self): toRemove = False for obj in (bpy.data.objects): if reb3dSpace.search(obj.name): @@ -191,8 +189,10 @@ def applyRemoveTransforms(): break if toRemove: removeTransforms() + self.report({'INFO'}, "Transforms removed") else: applyTransforms() + self.report({'INFO'}, "Transforms applied") def removeTransforms(): spaces = [cn for cn in bpy.data.objects if reb3dSpace.search(cn.name)] @@ -215,15 +215,17 @@ def removeTransforms(): bpy.ops.object.delete() -def showHideObjByType(type): +def showHideObjByType(self, type): objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] hiddenObj = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type and cn.hide_get()] if len(objs) == len(hiddenObj): for obj in objs: obj.hide_set(False) + self.report({'INFO'}, "{} (block {}) objects are shown".format(len(objs), type)) else: for obj in objs: obj.hide_set(True) + self.report({'INFO'}, "{} (block {}) objects are hidden".format(len(objs))) def showHideObjTreeByType(type): objs = [cn for cn in bpy.data.objects if cn.get("block_type") is not None and cn["block_type"]==type] @@ -300,33 +302,6 @@ def getHierarchyRoots(root): return res -# def getNBlockHierarchy(root, block_type, rootnum=0, curlevel=0, arr=[]): -# for obj in root.children: -# if obj['block_type'] == block_type: -# print("block_type block") -# arr.append([rootnum, curlevel, obj]) -# getNBlockHierarchy(obj, block_type, rootnum, curlevel+1, arr) -# rootnum+=1 -# elif obj['block_type'] == 18: -# print("ref block") -# refObj = bpy.data.objects[obj[prop(b_18.Add_Name)]] -# arr.append([rootnum, curlevel, refObj]) -# getNBlockHierarchy(refObj, block_type, rootnum, curlevel+1, arr) -# rootnum+=1 -# getNBlockHierarchy(obj, block_type, rootnum, curlevel, arr) - -def isMeshBlock(obj): - # 18 - for correct transform apply - return obj.get("block_type") is not None \ - and (obj["block_type"]==8 or obj["block_type"]==35\ - or obj["block_type"]==28 \ - # or obj["block_type"]==18 - ) - -def isRefBlock(obj): - return obj.get("block_type") is not None and obj["block_type"]==18 - - def processLOD(root, state, explevel = 0, curlevel = -1): stack = [[root, curlevel, False]] @@ -829,14 +804,10 @@ def createCustomAttribute(mesh, values, zclass, zobj): elif ctype == 'pfb': domain = 'FACE' - # log.debug(domain) - # log.debug(zobj['type']) if zobj['type'] == fieldType.FLOAT: ztype = 'FLOAT' mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) attr = mesh.attributes[zobj['prop']].data - # log.debug(len(attr)) - # log.debug(len(values)) for i in range(len(attr)): setattr(attr[i], "value", values[i]) @@ -844,8 +815,6 @@ def createCustomAttribute(mesh, values, zclass, zobj): ztype = 'FLOAT_VECTOR' mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) attr = mesh.attributes[zobj['prop']].data - # log.debug(len(attr)) - # log.debug(len(values)) for i in range(len(attr)): setattr(attr[i], "vector", values[i]) @@ -853,8 +822,6 @@ def createCustomAttribute(mesh, values, zclass, zobj): ztype = 'INT' mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) attr = mesh.attributes[zobj['prop']].data - # log.debug(len(attr)) - # log.debug(len(values)) for i in range(len(attr)): setattr(attr[i], "value", values[i]) @@ -862,7 +829,5 @@ def createCustomAttribute(mesh, values, zclass, zobj): ztype = 'INT' mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) attr = mesh.attributes[zobj['prop']].data - # log.debug(len(attr)) - # log.debug(len(values)) for i in range(len(attr)): setattr(attr[i], "value", values[i]) \ No newline at end of file From f70f1d1233d2dc8668054ca24cce1da6c757a19a Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sun, 8 Jan 2023 16:22:48 +0200 Subject: [PATCH 25/47] various fixes --- src/2.80/addons/b3d_tools/b3d/classes.py | 8 ++- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 77 +++++++++++++++------ src/2.80/addons/b3d_tools/b3d/import_b3d.py | 65 +++++++++-------- src/2.80/addons/b3d_tools/b3d/menus.py | 2 + src/2.80/addons/b3d_tools/b3d/panel.py | 4 +- src/2.80/addons/b3d_tools/b3d/scripts.py | 2 +- 6 files changed, 99 insertions(+), 59 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 2b11c5a..19c1446 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -1498,7 +1498,13 @@ class b_34(): 'description': '', 'default': 0.0 } - #todo check + UnkInt = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизв.', + 'description': '', + 'default': 0 + } class b_35(): XYZ = { diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index 6259310..80c479c 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -312,7 +312,7 @@ def export(file, generate_pro_file): curMaxCnt = 2 elif obj['block_type'] == 21: curMaxCnt = obj[prop(b_21.GroupCnt)] - exportBlock(obj, True, curLevel, curMaxCnt, [0], {}, file) + exportBlock(obj, False, curLevel, curMaxCnt, [0], {}, file) file.write(struct.pack(" 1: + for i in range(curMaxCnt-1): + file.write(struct.pack(" Date: Sun, 8 Jan 2023 23:39:07 +0200 Subject: [PATCH 26/47] empty name --- src/2.80/addons/b3d_tools/b3d/common.py | 3 ++- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 4 +++- src/2.80/addons/b3d_tools/b3d/scripts.py | 4 +++- src/2.80/addons/b3d_tools/consts.py | 2 ++ utils/b3dsplit.py | 6 ++++-- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 56fe95b..2c3f6bd 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -6,6 +6,7 @@ import re from ..common import log +from ..consts import EMPTY_NAME def getNonCopyName(name): reIsCopy = re.compile(r'\.[0-9]*$') @@ -25,7 +26,7 @@ def getRootObj(obj): return result def isEmptyName(name): - reIsEmpty = re.compile(r'.*empty name.*') + reIsEmpty = re.compile(r'.*{}.*'.format(EMPTY_NAME)) return reIsEmpty.search(name) def isMeshBlock(obj): diff --git a/src/2.80/addons/b3d_tools/b3d/import_b3d.py b/src/2.80/addons/b3d_tools/b3d/import_b3d.py index 501eb7a..5112af5 100644 --- a/src/2.80/addons/b3d_tools/b3d/import_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/import_b3d.py @@ -55,6 +55,8 @@ pvb_35 ) +from ..consts import EMPTY_NAME + from .scripts import ( prop, createCustomAttribute @@ -131,7 +133,7 @@ def onebyte(file): def readName(file): objName = file.read(32) if (objName[0] == 0): - objName = "empty name" + objName = EMPTY_NAME #objname = "Untitled_0x" + str(hex(pos-36)) else: objName = (objName.decode("cp1251").rstrip('\0')) diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index a524225..f45c546 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -22,6 +22,8 @@ fieldType, b_common ) +from ..consts import EMPTY_NAME + reb3dSpace = re.compile(r'.*b3dSpaceCopy.*') reb3dMesh = re.compile(r'.*b3dcopy.*') @@ -134,7 +136,7 @@ def applyTransform(root): if not block.hide_get(): - if spaceName == 'empty name': + if spaceName == EMPTY_NAME: spaceName = prevSpace spaceObj = bpy.data.objects.get(spaceName) diff --git a/src/2.80/addons/b3d_tools/consts.py b/src/2.80/addons/b3d_tools/consts.py index 66e02d5..b3d16d3 100644 --- a/src/2.80/addons/b3d_tools/consts.py +++ b/src/2.80/addons/b3d_tools/consts.py @@ -1,4 +1,6 @@ +EMPTY_NAME = '~' + blockTypeList = [ ('6566754', "b3d", "b3d"), ('00', "00", "2D фон"), diff --git a/utils/b3dsplit.py b/utils/b3dsplit.py index 4ea4b0d..a8312fe 100644 --- a/utils/b3dsplit.py +++ b/utils/b3dsplit.py @@ -13,6 +13,8 @@ rootsFile = None rootsFromFile = False +EMPTY_NAME = '~' + if len(args) == 2: filename = args[1] outdir = os.path.dirname(filename) @@ -62,7 +64,7 @@ def getHierarchyRoots(refObjs): def readName(file): objName = file.read(32) if (objName[0] == 0): - objName = "empty name" + objName = EMPTY_NAME #objname = "Untitled_0x" + str(hex(pos-36)) else: objName = (objName.decode("cp1251").rstrip('\0')) @@ -665,7 +667,7 @@ def read(file): curLevel = list(objs) objs = set() - spaces = [cn for cn in list(g_spaces) if cn != 'empty name'] + spaces = [cn for cn in list(g_spaces) if cn != EMPTY_NAME] objs = list(g_objs) spaces.sort() From 1f1df401ad94292687d34e95478183d6e546a986 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Mon, 9 Jan 2023 00:55:37 +0200 Subject: [PATCH 27/47] group skip fix --- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index 80c479c..ac0cca3 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -495,7 +495,8 @@ def exportBlock(obj, isLast, curLevel, maxGroups, curGroups, extra, file): #write Group Chunk if block['level_group'] > curGroups[curLevel]: log.debug('group ended') - file.write(struct.pack(" Date: Mon, 9 Jan 2023 13:15:24 +0200 Subject: [PATCH 28/47] Update README.MD --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 8e1d256..05328c3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Blender-VWI Плагины для форматов файлов игрового движка Virtual World Inventor. ##### Текущие планы -* Доработка экспорта b3d. +* Доработка экспорта b3d + .res. ## Поддерживаемые игры | Название игры | Название игры (международное) | Год выхода | @@ -12,7 +12,8 @@ ## Поддерживаемые форматы файлов | Расширение | Описание | Импорт | Экспорт | |-----------|-----------------------|:----------:|:----------:| -| .b3d + .res | Модели, логика, различные объекты | Да | Нет | +| .b3d | Модели, логика, различные объекты | Да | Да | +| .b3d + .res | Модели, логика, различные объекты + текстуры | Да | Нет | | .way | Пути транспорта для ИИ | Да | Нет | | .tch/.tech | Параметры транспорта и динамических объектов | | Да | @@ -56,20 +57,19 @@ b3dsplit - извлечение из b3d-файла прочих моделей Hard Truck classic games (VWI engine) import/export plugins for Blender. #### Roadmap -* Export support +* .b3d + .res export support -## Supported games and formats - -1. Hard Truck: Road to Victory (1998) - -| Расширение | Описание | Import | +## Supported games +| Title | Title (ENG) | Release year | |-----------|-----------------------|:----------:| -| .b3d | Models, game logic, various objects | Yes | +| Дальнобойщики: Путь к победе | Hard Truck: Road to Victory | 1998 | +| Дальнобойщики - 2 | Hard Truck 2 (King of the Road) | 2000 (2003) -2. Hard Truck: King Of The Road (2003) +## Supported formats -| Расширение | Описание | Import | Export | +| Extension | Description | Import | Export | |-----------|-----------------------|:----------:|:----------:| -| .b3d | Models, game logic, various objects | Yes | No | +| .b3d | Models, game logic, various objects | Yes | Yes | +| .b3d + .res | Models, game logic, various objects + textures | Yes | No | | .way | AI paths | Yes | No | | .tch/.tech | Transport parameters | | Yes | \ No newline at end of file From e0f3a5b801858d058c5edb08a4e3855f3760e331 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 14 Jan 2023 14:06:53 +0200 Subject: [PATCH 29/47] more enums --- src/2.80/addons/b3d_tools/b3d/__init__.py | 4 + src/2.80/addons/b3d_tools/b3d/class_descr.py | 1622 +++++++++++++++++ src/2.80/addons/b3d_tools/b3d/classes.py | 1670 +----------------- src/2.80/addons/b3d_tools/b3d/common.py | 80 +- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 8 +- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 2 +- src/2.80/addons/b3d_tools/b3d/menus.py | 2 +- src/2.80/addons/b3d_tools/b3d/panel.py | 4 +- src/2.80/addons/b3d_tools/b3d/scripts.py | 108 +- src/2.80/addons/b3d_tools/custom_UIList.py | 6 +- 10 files changed, 1874 insertions(+), 1632 deletions(-) create mode 100644 src/2.80/addons/b3d_tools/b3d/class_descr.py diff --git a/src/2.80/addons/b3d_tools/b3d/__init__.py b/src/2.80/addons/b3d_tools/b3d/__init__.py index b0bea9f..6048423 100644 --- a/src/2.80/addons/b3d_tools/b3d/__init__.py +++ b/src/2.80/addons/b3d_tools/b3d/__init__.py @@ -7,6 +7,7 @@ import importlib importlib.reload(common) + importlib.reload(class_descr) importlib.reload(classes) importlib.reload(import_b3d) importlib.reload(export_b3d) @@ -17,6 +18,7 @@ import bpy from . import ( common, + class_descr, classes, import_b3d, export_b3d, @@ -27,6 +29,7 @@ def register(): print("registering addon") + class_descr.register() classes.register() menus.register() panel.register() @@ -37,3 +40,4 @@ def unregister(): panel.unregister() menus.unregister() classes.unregister() + class_descr.unregister() diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py new file mode 100644 index 0000000..c7e1d2a --- /dev/null +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -0,0 +1,1622 @@ +from email.policy import default +import bpy +import enum + +from bpy.props import (StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + EnumProperty, + PointerProperty, + FloatVectorProperty, + CollectionProperty + ) + +from bpy.types import (Panel, + Operator, + PropertyGroup, + ) + +from ..common import log + +from ..consts import ( + collisionTypeList, + generatorTypeList +) + +# Dynamic block exmaple +# block_5 = type("block_5", (bpy.types.PropertyGroup,), { +# '__annotations__': { +# 'name': StringProperty( +# name="Имя блока", +# default="", +# maxlen=30, +# ), +# 'XYZ': FloatVectorProperty( +# name='Координаты блока', +# description='', +# default=(0.0, 0.0, 0.0) +# ), +# 'R': FloatProperty( +# name = "Радиус", +# description = "", + +# ) +# } +# }) + + + +class fieldType(enum.Enum): + STRING = 1 + COORD = 2 + RAD = 3 + INT = 4 + FLOAT = 5 + ENUM = 6 + LIST = 7 + V_FORMAT = 8 + MATERIAL_IND = 9 + SPACE_NAME = 10 + REFERENCEABLE = 11 + + +class ActiveBlock(bpy.types.PropertyGroup): + name: StringProperty() + state : BoolProperty() + +class FloatBlock(bpy.types.PropertyGroup): + value: FloatProperty() + +class MaskfileBlock(bpy.types.PropertyGroup): + value: StringProperty() + + is_noload: BoolProperty(default=False) + is_someint: BoolProperty(default=False) + someint: IntProperty(default=0) + +class TextureBlock(bpy.types.PropertyGroup): + value: StringProperty() + + is_memfix: BoolProperty(default=False) + is_noload: BoolProperty(default=False) + is_bumpcoord: BoolProperty(default=False) + is_someint: BoolProperty(default=False) + someint: IntProperty() + +class MaterialBlock(bpy.types.PropertyGroup): + value: StringProperty() + + is_reflect: BoolProperty(default=False) + reflect: FloatProperty(default=0.0) + + is_specular: BoolProperty(default=False) + specular: FloatProperty(default=0.0) + + is_transp: BoolProperty(default=False) + transp: FloatProperty(default=0.0) + + is_rot: BoolProperty(default=False) + rot: FloatProperty(default=0.0) + + is_col: BoolProperty(default=False) + col: IntProperty(default=0) + + is_tex: BoolProperty(default=False) + tex: IntProperty(default=0) + + is_ttx: BoolProperty(default=False) + ttx: IntProperty(default=0) + + is_itx: BoolProperty(default=False) + itx: IntProperty(default=0) + + is_att: BoolProperty(default=False) + att: IntProperty(default=0) + + is_msk: BoolProperty(default=False) + msk: IntProperty(default=0) + + is_power: BoolProperty(default=False) + power: IntProperty(default=0) + + is_coord: BoolProperty(default=False) + coord: IntProperty(default=0) + + is_env: BoolProperty(default=False) + envId: IntProperty(default=0) + env: FloatVectorProperty(default=(0.0, 0.0), size=2) + + is_rotPoint: BoolProperty(default=False) + rotPoint: FloatVectorProperty(default=(0.0, 0.0), size=2) + + is_move: BoolProperty(default=False) + move: FloatVectorProperty(default=(0.0, 0.0), size=2) + + is_noz: BoolProperty(default=False) + is_nof: BoolProperty(default=False) + is_notile: BoolProperty(default=False) + is_notileu: BoolProperty(default=False) + is_notilev: BoolProperty(default=False) + is_alphamirr: BoolProperty(default=False) + is_bumpcoord: BoolProperty(default=False) + is_usecol: BoolProperty(default=False) + is_wave: BoolProperty(default=False) + +class ResBlock(bpy.types.PropertyGroup): + value: StringProperty() + textures: CollectionProperty(type=TextureBlock) + materials: CollectionProperty(type=MaterialBlock) + maskfiles: CollectionProperty(type=MaskfileBlock) + + +class pvb_8(): + Normal_Switch = { + 'prop': 'normal_switch', + 'type': fieldType.FLOAT, + 'name': 'Выключатель нормали', + 'description': '', + 'default': 0.0 + } + Custom_Normal = { + 'prop': 'custom_normal', + 'type': fieldType.COORD, + 'name': 'Кастомная нормаль', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + + +class pvb_35(): + Normal_Switch = { + 'prop': 'normal_switch', + 'type': fieldType.FLOAT, + 'name': 'Выключатель нормали', + 'description': '', + 'default': 0.0 + } + Custom_Normal = { + 'prop': 'custom_normal', + 'type': fieldType.COORD, + 'name': 'Кастомная нормаль', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + +class pfb_8(): + Format_Flags = { + 'prop': 'format_flags', + 'type': fieldType.V_FORMAT, + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + +class pfb_28(): + Format_Flags = { + 'prop': 'format_flags', + 'type': fieldType.V_FORMAT, + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + + +class pfb_35(): + Format_Flags = { + 'prop': 'format_flags', + 'type': fieldType.V_FORMAT, + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + + +class b_common(): + LevelGroup = { + 'prop': 'level_group', + 'type': fieldType.INT, + 'name': 'Группа блока', + 'description': '', + 'default': 0 + } + +class b_1(): + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Неизв. название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Неизв. название 2', + 'description': '', + 'default': '' + } + +class b_2(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_3(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + +class b_4(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.SPACE_NAME, + 'name': 'Трансформация', + 'description': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Название 2', + 'description': '', + 'default': '' + } + +class b_5(): + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Имя блока', + 'description': '', + 'default': '' + } + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + + +class b_6(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Название 2', + 'description': '', + 'default': '' + } + +class b_7(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название группы', + 'description': '', + 'default': '' + } + +class b_8(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + +class b_9(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_10(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + LOD_XYZ = { + 'prop': 'LOD_XYZ', + 'type': fieldType.COORD, + 'name': 'Центр LOD', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + LOD_R = { + 'prop': 'LOD_R', + 'type': fieldType.RAD, + 'name': 'Радиус LOD', + 'description': '', + 'default': 0.0 + } + +class b_11(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_12(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_13(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_14(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_15(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_16(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Float2 = { + 'prop': 'float2', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 3', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 4', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_17(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Float2 = { + 'prop': 'float2', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 3', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 4', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_18(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Space_Name = { + 'prop': 'space_name', + 'type': fieldType.SPACE_NAME, + 'name': 'Название трансформации (24)', + 'description': '' + } + Add_Name = { + 'prop': 'add_name', + 'type': fieldType.REFERENCEABLE, + 'name': 'Название переносимого блока', + 'description': '' + } + +class b_20(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_21(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + GroupCnt = { + 'prop': 'group_cnt', + 'type': fieldType.INT, + 'name': 'Количество групп', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + +class b_22(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_23(): + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Surface = { + 'prop': 'CType', + 'type': fieldType.ENUM, + 'subtype': fieldType.INT, + 'name': 'Тип поверхности', + 'description': '', + 'default': 0, + 'items': collisionTypeList + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +class b_24(): + Flag = { + 'prop': 'flag', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + +class b_25(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Name = { + 'prop': 'name', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Unk_Float2 = { + 'prop': 'float2', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0.0 + } + Unk_Float3 = { + 'prop': 'float3', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 3', + 'description': '', + 'default': 0.0 + } + Unk_Float4 = { + 'prop': 'float4', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 4', + 'description': '', + 'default': 0.0 + } + Unk_Float5 = { + 'prop': 'float5', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 5', + 'description': '', + 'default': 0.0 + } + +class b_26(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ3 = { + 'prop': 'unk_XYZ3', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 3', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + +class b_27(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Flag = { + 'prop': 'flag', + 'type': fieldType.INT, + 'name': 'Флаг', + 'description': '', + 'default': 0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Material = { + 'prop': 'material', + 'type': fieldType.INT, + 'name': 'Материал', + 'description': '', + 'default': 0 + } + +class b_28(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + #todo: check + +class b_29(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_XYZ = { + 'prop': 'unk_XYZ', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Неизв. радиус', + 'description': '', + 'default': 0.0 + } + +class b_30(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name = { + 'prop': 'name', + 'type': fieldType.STRING, + 'name': 'Название комнаты', + 'description': '', + 'default': '' + } + XYZ1 = { + 'prop': 'XYZ1', + 'type': fieldType.COORD, + 'name': 'Координаты 1. точки', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + XYZ2 = { + 'prop': 'XYZ2', + 'type': fieldType.COORD, + 'name': 'Координаты 2. точки', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + +class b_31(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R = { + 'prop': 'unk_R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + #todo: check + +class b_33(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Use_Lights = { + 'prop': 'useLight', + 'type': fieldType.INT, + 'name': 'Исп. свет', + 'description': '', + 'default': 0 + } + Light_Type = { + 'prop': 'lType', + 'type': fieldType.INT, + 'name': 'Тип света', + 'description': '', + 'default': 0 + } + Flag = { + 'prop': 'flag', + 'type': fieldType.INT, + 'name': 'Флаг', + 'description': '', + 'default': 0 + } + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 1', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Неизв. координаты 2', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизв. 1', + 'description': '', + 'default': 0.0 + } + Unk_Float2 = { + 'prop': 'float2', + 'type': fieldType.FLOAT, + 'name': 'Неизв. 2', + 'description': '', + 'default': 0.0 + } + Light_R = { + 'prop': 'light_radius', + 'type': fieldType.FLOAT, + 'name': 'Радиус света', + 'description': '', + 'default': 0.0 + } + Intens = { + 'prop': 'intensity', + 'type': fieldType.FLOAT, + 'name': 'Интенсивность', + 'description': '', + 'default': 0.0 + } + Unk_Float3 = { + 'prop': 'float3', + 'type': fieldType.FLOAT, + 'name': 'Неизв. 3', + 'description': '', + 'default': 0.0 + } + Unk_Float4 = { + 'prop': 'float4', + 'type': fieldType.FLOAT, + 'name': 'Неизв. 4', + 'description': '', + 'default': 0.0 + } + RGB = { + 'prop': 'rgb', + 'type': fieldType.COORD, + 'name': 'RGB', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + + +class b_34(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + UnkInt = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизв.', + 'description': '', + 'default': 0 + } + +class b_35(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + MType = { + 'prop': 'mType', + 'type': fieldType.INT, + 'name': 'Переменная 1', + 'description': '', + 'default': 0 + } + TexNum = { + 'prop': 'texnum', + 'type': fieldType.MATERIAL_IND, + 'name': 'Номер текстуры', + 'description': '', + } + +class b_36(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.STRING, + 'name': 'Название 2', + 'description': '', + 'default': '' + } + MType = { + 'prop': 'MType', + 'type': fieldType.INT, + 'name': 'Переменная 1', + 'description': '', + 'default': 0 + } + +class b_37(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + SType = { + 'prop': 'SType', + 'type': fieldType.INT, + 'name': 'Переменная 1', + 'description': '', + 'default': 0 + } + +class b_39(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Color_R = { + 'prop': 'color_r', + 'type': fieldType.INT, + 'name': 'Радиус цвета', + 'description': '', + 'default': 0 + } + Unk_Float1 = { + 'prop': 'float1', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0.0 + } + Fog_Start = { + 'prop': 'fog_start', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 3', + 'description': '', + 'default': 0.0 + } + Fog_End = { + 'prop': 'fog_end', + 'type': fieldType.FLOAT, + 'name': 'Неизвестная 4', + 'description': '', + 'default': 0.0 + } + Color_Id = { + 'prop': 'color_id', + 'type': fieldType.INT, + 'name': 'ID цвета', + 'description': '', + 'default': 0 + } + +class b_40(): + XYZ = { + 'prop': 'XYZ', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'R', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название 1', + 'description': '', + 'default': '' + } + Name2 = { + 'prop': 'name2', + 'type': fieldType.ENUM, + 'subtype': fieldType.STRING, + 'name': 'Тип генератора', + 'description': '', + 'default': '$$TreeGenerator', + 'items': generatorTypeList + } + Unk_Int1 = { + 'prop': 'int1', + 'type': fieldType.INT, + 'name': 'Неизвестная 1', + 'description': '', + 'default': 0 + } + Unk_Int2 = { + 'prop': 'int2', + 'type': fieldType.INT, + 'name': 'Неизвестная 2', + 'description': '', + 'default': 0 + } + Unk_List = { + 'prop': 'list1', + 'type': fieldType.LIST, + 'name': 'Неизв. параметры', + 'description': '', + } + +_classes = ( + ActiveBlock, + FloatBlock, + TextureBlock, + MaskfileBlock, + MaterialBlock, + ResBlock +) + +def register(): + for cls in _classes: + bpy.utils.register_class(cls) + +def unregister(): + for cls in _classes[::-1]: #reversed + bpy.utils.unregister_class(cls) diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 19c1446..cc38280 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -1,6 +1,5 @@ -from email.policy import default + import bpy -import enum from bpy.props import (StringProperty, BoolProperty, @@ -12,133 +11,62 @@ CollectionProperty ) -from bpy.types import (Panel, - Operator, - PropertyGroup, - ) - -from ..common import log - -# Dynamic block exmaple -# block_5 = type("block_5", (bpy.types.PropertyGroup,), { -# '__annotations__': { -# 'name': StringProperty( -# name="Имя блока", -# default="", -# maxlen=30, -# ), -# 'XYZ': FloatVectorProperty( -# name='Координаты блока', -# description='', -# default=(0.0, 0.0, 0.0) -# ), -# 'R': FloatProperty( -# name = "Радиус", -# description = "", - -# ) -# } -# }) - -class fieldType(enum.Enum): - STRING = 1 - COORD = 2 - RAD = 3 - INT = 4 - FLOAT = 5 - ENUM = 6 - LIST = 7 - V_FORMAT = 8 - - -class ActiveBlock(bpy.types.PropertyGroup): - name: StringProperty() - state : BoolProperty() - -class FloatBlock(bpy.types.PropertyGroup): - value: FloatProperty() - -class MaskfileBlock(bpy.types.PropertyGroup): - value: StringProperty() - - is_noload: BoolProperty(default=False) - is_someint: BoolProperty(default=False) - someint: IntProperty(default=0) - -class TextureBlock(bpy.types.PropertyGroup): - value: StringProperty() - - is_memfix: BoolProperty(default=False) - is_noload: BoolProperty(default=False) - is_bumpcoord: BoolProperty(default=False) - is_someint: BoolProperty(default=False) - someint: IntProperty() - -class MaterialBlock(bpy.types.PropertyGroup): - value: StringProperty() - - is_reflect: BoolProperty(default=False) - reflect: FloatProperty(default=0.0) - - is_specular: BoolProperty(default=False) - specular: FloatProperty(default=0.0) - - is_transp: BoolProperty(default=False) - transp: FloatProperty(default=0.0) - - is_rot: BoolProperty(default=False) - rot: FloatProperty(default=0.0) - - is_col: BoolProperty(default=False) - col: IntProperty(default=0) - - is_tex: BoolProperty(default=False) - tex: IntProperty(default=0) - - is_ttx: BoolProperty(default=False) - ttx: IntProperty(default=0) - - is_itx: BoolProperty(default=False) - itx: IntProperty(default=0) - - is_att: BoolProperty(default=False) - att: IntProperty(default=0) - - is_msk: BoolProperty(default=False) - msk: IntProperty(default=0) - - is_power: BoolProperty(default=False) - power: IntProperty(default=0) - - is_coord: BoolProperty(default=False) - coord: IntProperty(default=0) - - is_env: BoolProperty(default=False) - envId: IntProperty(default=0) - env: FloatVectorProperty(default=(0.0, 0.0), size=2) - - is_rotPoint: BoolProperty(default=False) - rotPoint: FloatVectorProperty(default=(0.0, 0.0), size=2) - - is_move: BoolProperty(default=False) - move: FloatVectorProperty(default=(0.0, 0.0), size=2) - - is_noz: BoolProperty(default=False) - is_nof: BoolProperty(default=False) - is_notile: BoolProperty(default=False) - is_notileu: BoolProperty(default=False) - is_notilev: BoolProperty(default=False) - is_alphamirr: BoolProperty(default=False) - is_bumpcoord: BoolProperty(default=False) - is_usecol: BoolProperty(default=False) - is_wave: BoolProperty(default=False) +from .class_descr import ( + fieldType, + FloatBlock +) -class ResBlock(bpy.types.PropertyGroup): - value: StringProperty() - textures: CollectionProperty(type=TextureBlock) - materials: CollectionProperty(type=MaterialBlock) - maskfiles: CollectionProperty(type=MaskfileBlock) +from .class_descr import ( + b_1, + b_2, + b_3, + b_4, + b_5, + b_6, + b_7, + b_8, + b_9, + b_10, + b_11, + b_12, + b_13, + b_14, + b_15, + b_16, + b_17, + b_18, + b_20, + b_21, + b_22, + b_23, + b_24, + b_25, + b_26, + b_27, + b_28, + b_29, + b_30, + b_31, + b_33, + b_34, + b_35, + b_36, + b_37, + b_39, + b_40, + pfb_8, + pfb_28, + pfb_35, + pvb_8, + pvb_35, + b_common +) +from .common import ( + resMaterialsCallback, + spacesCallback, + referenceablesCallback +) def createTypeClass(zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] @@ -164,7 +92,10 @@ def createTypeClass(zclass): or obj['type'] == fieldType.FLOAT \ or obj['type'] == fieldType.INT \ or obj['type'] == fieldType.ENUM \ - or obj['type'] == fieldType.LIST: + or obj['type'] == fieldType.LIST \ + or obj['type'] == fieldType.MATERIAL_IND \ + or obj['type'] == fieldType.SPACE_NAME \ + or obj['type'] == fieldType.REFERENCEABLE: attributes['__annotations__']["show_"+propName] = lockProp @@ -213,6 +144,27 @@ def createTypeClass(zclass): type = FloatBlock ) + elif obj['type'] == fieldType.MATERIAL_IND: + prop = EnumProperty( + name = obj['name'], + description = obj['description'], + items = resMaterialsCallback + ) + + elif obj['type'] == fieldType.SPACE_NAME: + prop = EnumProperty( + name = obj['name'], + description = obj['description'], + items = spacesCallback + ) + + elif obj['type'] == fieldType.REFERENCEABLE: + prop = EnumProperty( + name = obj['name'], + description = obj['description'], + items = referenceablesCallback + ) + attributes['__annotations__'][propName] = prop elif obj['type'] == fieldType.V_FORMAT: @@ -250,1460 +202,6 @@ def createTypeClass(zclass): newclass = type("{}_gen".format(zclass.__name__), (bpy.types.PropertyGroup,), attributes) return newclass -class pvb_8(): - Normal_Switch = { - 'prop': 'normal_switch', - 'type': fieldType.FLOAT, - 'name': 'Выключатель нормали', - 'description': '', - 'default': 0.0 - } - Custom_Normal = { - 'prop': 'custom_normal', - 'type': fieldType.COORD, - 'name': 'Кастомная нормаль', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - - -class pvb_35(): - Normal_Switch = { - 'prop': 'normal_switch', - 'type': fieldType.FLOAT, - 'name': 'Выключатель нормали', - 'description': '', - 'default': 0.0 - } - Custom_Normal = { - 'prop': 'custom_normal', - 'type': fieldType.COORD, - 'name': 'Кастомная нормаль', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - -class pfb_8(): - Format_Flags = { - 'prop': 'format_flags', - 'type': fieldType.V_FORMAT, - } - Unk_Float1 = { - 'prop': 'float1', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0.0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - -class pfb_28(): - Format_Flags = { - 'prop': 'format_flags', - 'type': fieldType.V_FORMAT, - } - Unk_Float1 = { - 'prop': 'float1', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0.0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - - -class pfb_35(): - Format_Flags = { - 'prop': 'format_flags', - 'type': fieldType.V_FORMAT, - } - Unk_Float1 = { - 'prop': 'float1', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0.0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - - -class b_common(): - LevelGroup = { - 'prop': 'level_group', - 'type': fieldType.INT, - 'name': 'Группа блока', - 'description': '', - 'default': 0 - } - -class b_1(): - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Неизв. название 1', - 'description': '', - 'default': '' - } - Name2 = { - 'prop': 'name2', - 'type': fieldType.STRING, - 'name': 'Неизв. название 2', - 'description': '', - 'default': '' - } - -class b_2(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_R = { - 'prop': 'unk_R', - 'type': fieldType.RAD, - 'name': 'Неизв. радиус', - 'description': '', - 'default': 0.0 - } - -class b_3(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - -class b_4(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Название 1', - 'description': '', - 'default': '' - } - Name2 = { - 'prop': 'name2', - 'type': fieldType.STRING, - 'name': 'Название 2', - 'description': '', - 'default': '' - } - -class b_5(): - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Имя блока', - 'description': '', - 'default': '' - } - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - - -class b_6(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Название 1', - 'description': '', - 'default': '' - } - Name2 = { - 'prop': 'name2', - 'type': fieldType.STRING, - 'name': 'Название 2', - 'description': '', - 'default': '' - } - -class b_7(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Название группы', - 'description': '', - 'default': '' - } - -class b_8(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - -class b_9(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_R = { - 'prop': 'unk_R', - 'type': fieldType.RAD, - 'name': 'Неизв. радиус', - 'description': '', - 'default': 0.0 - } - -class b_10(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - LOD_XYZ = { - 'prop': 'LOD_XYZ', - 'type': fieldType.COORD, - 'name': 'Центр LOD', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - LOD_R = { - 'prop': 'LOD_R', - 'type': fieldType.RAD, - 'name': 'Радиус LOD', - 'description': '', - 'default': 0.0 - } - -class b_11(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_R = { - 'prop': 'unk_R', - 'type': fieldType.RAD, - 'name': 'Неизв. радиус', - 'description': '', - 'default': 0.0 - } - -class b_12(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_R = { - 'prop': 'unk_R', - 'type': fieldType.RAD, - 'name': 'Неизв. радиус', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - -class b_13(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - -class b_14(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_R = { - 'prop': 'unk_R', - 'type': fieldType.RAD, - 'name': 'Неизв. радиус', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - -class b_15(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - -class b_16(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ1 = { - 'prop': 'unk_XYZ1', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_XYZ2 = { - 'prop': 'unk_XYZ2', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_Float1 = { - 'prop': 'float1', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0.0 - } - Unk_Float2 = { - 'prop': 'float2', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 3', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 4', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - -class b_17(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ1 = { - 'prop': 'unk_XYZ1', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_XYZ2 = { - 'prop': 'unk_XYZ2', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_Float1 = { - 'prop': 'float1', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0.0 - } - Unk_Float2 = { - 'prop': 'float2', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 3', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 4', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - -class b_18(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Space_Name = { - 'prop': 'space_name', - 'type': fieldType.STRING, - 'name': 'Название трансформации (24)', - 'description': '', - 'default': '' - } - Add_Name = { - 'prop': 'add_name', - 'type': fieldType.STRING, - 'name': 'Название переносимого блока', - 'description': '', - 'default': '' - } - -class b_20(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - -class b_21(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - GroupCnt = { - 'prop': 'group_cnt', - 'type': fieldType.INT, - 'name': 'Количество групп', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - -class b_22(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_R = { - 'prop': 'unk_R', - 'type': fieldType.RAD, - 'name': 'Неизв. радиус', - 'description': '', - 'default': 0.0 - } - -class b_23(): - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Surface = { - 'prop': 'CType', - 'type': fieldType.INT, - 'name': 'Тип поверхности', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - -class b_24(): - Flag = { - 'prop': 'flag', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - -class b_25(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Name = { - 'prop': 'name', - 'type': fieldType.STRING, - 'name': 'Название 1', - 'description': '', - 'default': '' - } - Unk_XYZ1 = { - 'prop': 'unk_XYZ1', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_XYZ2 = { - 'prop': 'unk_XYZ2', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_Float1 = { - 'prop': 'float1', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0.0 - } - Unk_Float2 = { - 'prop': 'float2', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0.0 - } - Unk_Float3 = { - 'prop': 'float3', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 3', - 'description': '', - 'default': 0.0 - } - Unk_Float4 = { - 'prop': 'float4', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 4', - 'description': '', - 'default': 0.0 - } - Unk_Float5 = { - 'prop': 'float5', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 5', - 'description': '', - 'default': 0.0 - } - -class b_26(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ1 = { - 'prop': 'unk_XYZ1', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_XYZ2 = { - 'prop': 'unk_XYZ2', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_XYZ3 = { - 'prop': 'unk_XYZ3', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 3', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - -class b_27(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Flag = { - 'prop': 'flag', - 'type': fieldType.INT, - 'name': 'Флаг', - 'description': '', - 'default': 0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Material = { - 'prop': 'material', - 'type': fieldType.INT, - 'name': 'Материал', - 'description': '', - 'default': 0 - } - -class b_28(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - #todo: check - -class b_29(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - Unk_XYZ = { - 'prop': 'unk_XYZ', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_R = { - 'prop': 'unk_R', - 'type': fieldType.RAD, - 'name': 'Неизв. радиус', - 'description': '', - 'default': 0.0 - } - -class b_30(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Name = { - 'prop': 'name', - 'type': fieldType.STRING, - 'name': 'Название комнаты', - 'description': '', - 'default': '' - } - XYZ1 = { - 'prop': 'XYZ1', - 'type': fieldType.COORD, - 'name': 'Координаты 1. точки', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - XYZ2 = { - 'prop': 'XYZ2', - 'type': fieldType.COORD, - 'name': 'Координаты 2. точки', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - -class b_31(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Unk_XYZ1 = { - 'prop': 'unk_XYZ1', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_R = { - 'prop': 'unk_R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - Unk_XYZ2 = { - 'prop': 'unk_XYZ2', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - #todo: check - -class b_33(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Use_Lights = { - 'prop': 'useLight', - 'type': fieldType.INT, - 'name': 'Исп. свет', - 'description': '', - 'default': 0 - } - Light_Type = { - 'prop': 'lType', - 'type': fieldType.INT, - 'name': 'Тип света', - 'description': '', - 'default': 0 - } - Flag = { - 'prop': 'flag', - 'type': fieldType.INT, - 'name': 'Флаг', - 'description': '', - 'default': 0 - } - Unk_XYZ1 = { - 'prop': 'unk_XYZ1', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_XYZ2 = { - 'prop': 'unk_XYZ2', - 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - Unk_Float1 = { - 'prop': 'float1', - 'type': fieldType.FLOAT, - 'name': 'Неизв. 1', - 'description': '', - 'default': 0.0 - } - Unk_Float2 = { - 'prop': 'float2', - 'type': fieldType.FLOAT, - 'name': 'Неизв. 2', - 'description': '', - 'default': 0.0 - } - Light_R = { - 'prop': 'light_radius', - 'type': fieldType.FLOAT, - 'name': 'Радиус света', - 'description': '', - 'default': 0.0 - } - Intens = { - 'prop': 'intensity', - 'type': fieldType.FLOAT, - 'name': 'Интенсивность', - 'description': '', - 'default': 0.0 - } - Unk_Float3 = { - 'prop': 'float3', - 'type': fieldType.FLOAT, - 'name': 'Неизв. 3', - 'description': '', - 'default': 0.0 - } - Unk_Float4 = { - 'prop': 'float4', - 'type': fieldType.FLOAT, - 'name': 'Неизв. 4', - 'description': '', - 'default': 0.0 - } - RGB = { - 'prop': 'rgb', - 'type': fieldType.COORD, - 'name': 'RGB', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - - -class b_34(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - UnkInt = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизв.', - 'description': '', - 'default': 0 - } - -class b_35(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - MType = { - 'prop': 'mType', - 'type': fieldType.INT, - 'name': 'Переменная 1', - 'description': '', - 'default': 0 - } - TexNum = { - 'prop': 'texnum', - 'type': fieldType.INT, - 'name': 'Номер текстуры', - 'description': '', - 'default': 0 - } - -class b_36(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Название 1', - 'description': '', - 'default': '' - } - Name2 = { - 'prop': 'name2', - 'type': fieldType.STRING, - 'name': 'Название 2', - 'description': '', - 'default': '' - } - MType = { - 'prop': 'MType', - 'type': fieldType.INT, - 'name': 'Переменная 1', - 'description': '', - 'default': 0 - } - -class b_37(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Название 1', - 'description': '', - 'default': '' - } - SType = { - 'prop': 'SType', - 'type': fieldType.INT, - 'name': 'Переменная 1', - 'description': '', - 'default': 0 - } - -class b_39(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Color_R = { - 'prop': 'color_r', - 'type': fieldType.INT, - 'name': 'Радиус цвета', - 'description': '', - 'default': 0 - } - Unk_Float1 = { - 'prop': 'float1', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0.0 - } - Fog_Start = { - 'prop': 'fog_start', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 3', - 'description': '', - 'default': 0.0 - } - Fog_End = { - 'prop': 'fog_end', - 'type': fieldType.FLOAT, - 'name': 'Неизвестная 4', - 'description': '', - 'default': 0.0 - } - Color_Id = { - 'prop': 'color_id', - 'type': fieldType.INT, - 'name': 'ID цвета', - 'description': '', - 'default': 0 - } - -class b_40(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Название 1', - 'description': '', - 'default': '' - } - Name2 = { - 'prop': 'name2', - 'type': fieldType.STRING, - 'name': 'Название 2', - 'description': '', - 'default': '' - } - Unk_Int1 = { - 'prop': 'int1', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', - 'description': '', - 'default': 0 - } - Unk_Int2 = { - 'prop': 'int2', - 'type': fieldType.INT, - 'name': 'Неизвестная 2', - 'description': '', - 'default': 0 - } - Unk_List = { - 'prop': 'list1', - 'type': fieldType.LIST, - 'name': 'Неизв. параметры', - 'description': '', - } - perFaceBlock_8 = createTypeClass(pfb_8) perFaceBlock_28 = createTypeClass(pfb_28) @@ -1752,12 +250,6 @@ class b_40(): block_40 = createTypeClass(b_40) _classes = ( - ActiveBlock, - FloatBlock, - TextureBlock, - MaskfileBlock, - MaterialBlock, - ResBlock, block_1, block_2, block_3, @@ -1809,4 +301,4 @@ def register(): def unregister(): for cls in _classes[::-1]: #reversed - bpy.utils.unregister_class(cls) + bpy.utils.unregister_class(cls) \ No newline at end of file diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 2c3f6bd..282efc3 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -4,6 +4,7 @@ import logging import sys import re +import time from ..common import log from ..consts import EMPTY_NAME @@ -244,4 +245,81 @@ def getSelectedVertices(obj): if v.select: selectedVertices.append(v) - return selectedVertices \ No newline at end of file + return selectedVertices + + +def getAllChildren(obj): + allChildren = [] + # if len((obj.children)): + currentObjs = [obj] + if currentObjs: + nextChildren = [] + + for obj in currentObjs: + # if obj.children: + nextChildren.extend(obj.children) + currentObjs = nextChildren + # if currentObjs: + allChildren.extend(currentObjs) + return allChildren + +def referenceablesCallback(scene, context): + + mytool = context.scene.my_tool + rootObj = getRootObj(context.object) + + referenceables = [cn for cn in rootObj.children if cn.get('block_type') != 24] + + enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(referenceables)] + + print("fetched referenceables") + + return enumProperties + +def spacesCallback(scene, context): + + mytool = context.scene.my_tool + rootObj = getRootObj(context.object) + + spaces = [cn for cn in bpy.data.objects if cn.get('block_type') == 24 and getRootObj(cn) == rootObj] + + enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(spaces)] + + print("fetched spaces") + + return enumProperties + +def resMaterialsCallback(scene, context): + + mytool = context.scene.my_tool + rootObj = getRootObj(context.object) + moduleName = rootObj.name[:-4] + + resModules = mytool.resModules + curModule = getColPropertyByName(resModules, moduleName) + + enumProperties = [(str(i), cn.value, "") for i, cn in enumerate(curModule.materials)] + + return enumProperties + +def roomsCallback(scene, context): + + mytool = context.scene.my_tool + rootObj = getRootObj(context.object) + + rooms = [cn for cn in rootObj.children if cn.name[:5] == 'room_'] + + enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(rooms)] + + return enumProperties + + +def modulesCallback(scene, context): + + mytool = context.scene.my_tool + + modules = [cn for cn in bpy.data.objects if isRootObj(cn)] + + enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(modules)] + + return enumProperties \ No newline at end of file diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index ac0cca3..94f42af 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -19,7 +19,7 @@ import bpy_extras.mesh_utils -from .classes import ( +from .class_descr import ( b_1, b_2, b_3, @@ -65,8 +65,7 @@ ) from .scripts import ( - prop, - getAllChildren + prop ) from ..common import ( @@ -79,7 +78,8 @@ getNonCopyName, isRootObj, getRootObj, - isEmptyName + isEmptyName, + getAllChildren ) from bpy_extras.io_utils import ( diff --git a/src/2.80/addons/b3d_tools/b3d/import_b3d.py b/src/2.80/addons/b3d_tools/b3d/import_b3d.py index 5112af5..a351ad7 100644 --- a/src/2.80/addons/b3d_tools/b3d/import_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/import_b3d.py @@ -10,7 +10,7 @@ import logging from pathlib import Path -from .classes import ( +from .class_descr import ( b_1, b_2, b_3, diff --git a/src/2.80/addons/b3d_tools/b3d/menus.py b/src/2.80/addons/b3d_tools/b3d/menus.py index c3e19d4..75f8e54 100644 --- a/src/2.80/addons/b3d_tools/b3d/menus.py +++ b/src/2.80/addons/b3d_tools/b3d/menus.py @@ -23,7 +23,7 @@ AddonPreferences ) -from .classes import ActiveBlock +from .class_descr import ActiveBlock from . import ( import_b3d ) diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index 4be5619..40eb67a 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -50,7 +50,7 @@ block_31,block_33,block_34,block_35,block_36,block_37,block_39,block_40,block_common,\ perFaceBlock_8, perFaceBlock_28, perFaceBlock_35, perVertBlock_8, perVertBlock_35 ) -from .classes import ( +from .class_descr import ( b_1,b_2,b_3,b_4,b_5,b_6,b_7,b_8,b_9,b_10,\ b_11,b_12,b_13,b_14,b_15,b_16,b_17,b_18,b_20,\ b_21,b_22,b_23,b_24,b_25,b_26,b_27,b_28,b_29,b_30,\ @@ -78,7 +78,6 @@ - # ------------------------------------------------------------------------ # store properties in the active scene # ------------------------------------------------------------------------ @@ -93,6 +92,7 @@ def resModuleCallback(scene, context): return enumProperties + class PanelSettings(bpy.types.PropertyGroup): block1: PointerProperty(type=block_1) diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index f45c546..46ef197 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -5,7 +5,7 @@ import sys import re -from .classes import ( +from .class_descr import ( b_18, b_21 ) @@ -16,9 +16,11 @@ getPolygonsBySelectedVertices, getSelectedVertices, isRootObj, - isMeshBlock + isMeshBlock, + getRootObj, + getAllChildren ) -from .classes import ( +from .class_descr import ( fieldType, b_common ) @@ -71,21 +73,6 @@ def prop(obj): return obj['prop'] - -def getAllChildren(obj): - allChildren = [] - currentObjs = [obj] - while(1): - nextChildren = [] - if len(currentObjs) > 0: - for obj in currentObjs: - nextChildren.extend(obj.children) - currentObjs = nextChildren - allChildren.extend(currentObjs) - else: - break - return allChildren - def applyTransforms(): roots = [cn for cn in bpy.data.objects if isRootObj(cn)] for root in roots: @@ -482,7 +469,10 @@ def drawFieldByType(l_self, context, obj, zclass): or ftype == fieldType.INT \ or ftype == fieldType.FLOAT \ or ftype == fieldType.ENUM \ - or ftype == fieldType.LIST: + or ftype == fieldType.LIST \ + or ftype == fieldType.MATERIAL_IND \ + or ftype == fieldType.SPACE_NAME \ + or ftype == fieldType.REFERENCEABLE: box = l_self.layout.box() box.prop(getattr(mytool, bname), "show_"+pname) @@ -503,7 +493,10 @@ def drawFieldByType(l_self, context, obj, zclass): elif ftype == fieldType.FLOAT: col.prop(getattr(mytool, bname), pname) - elif ftype == fieldType.ENUM: + elif ftype == fieldType.ENUM \ + or ftype == fieldType.MATERIAL_IND \ + or ftype == fieldType.SPACE_NAME \ + or ftype == fieldType.REFERENCEABLE: col.prop(getattr(mytool, bname), pname) elif ftype == fieldType.LIST: @@ -567,6 +560,7 @@ def drawFieldByType(l_self, context, obj, zclass): col.enabled = True else: col.enabled = False + elif ftype == fieldType.V_FORMAT: box = l_self.layout.box() box.prop(getattr(mytool, bname), "show_{}".format(pname)) @@ -598,15 +592,44 @@ def getObjsByType(context, object, zclass): if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ and getattr(getattr(mytool, bname), "show_"+obj['prop']): - if obj['type'] == fieldType.FLOAT or obj['type'] == fieldType.RAD: - getattr(mytool, bname)[obj['prop']] = float(object[obj['prop']]) + if obj['type'] == fieldType.FLOAT \ + or obj['type'] == fieldType.RAD: + setattr( + getattr(mytool, bname), + obj['prop'], + float(object[obj['prop']]) + ) elif obj['type'] == fieldType.INT: - getattr(mytool, bname)[obj['prop']] = int(object[obj['prop']]) + setattr( + getattr(mytool, bname), + obj['prop'], + int(object[obj['prop']]) + ) elif obj['type'] == fieldType.STRING: getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) + elif obj['type'] == fieldType.SPACE_NAME \ + or obj['type'] == fieldType.REFERENCEABLE \ + or obj['type'] == fieldType.MATERIAL_IND: + setattr( + getattr(mytool, bname), + obj['prop'], + str(object[obj['prop']]) + ) + + elif obj['type'] == fieldType.ENUM: + + if obj['subtype'] == fieldType.INT \ + or obj['subtype'] == fieldType.STRING \ + or obj['subtype'] == fieldType.FLOAT: + setattr( + getattr(mytool, bname), + obj['prop'], + str(object[obj['prop']]) + ) + elif obj['type'] == fieldType.LIST: col = getattr(getattr(mytool, bname), obj['prop']) @@ -619,7 +642,11 @@ def getObjsByType(context, object, zclass): # getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) else: - getattr(mytool, bname)[obj['prop']] = object[obj['prop']] + setattr( + getattr(mytool, bname), + obj['prop'], + object[obj['prop']] + ) def setAllObjsByType(context, object, zclass): setObjsByType(context, object, b_common) @@ -636,16 +663,34 @@ def setObjsByType(context, object, zclass): and getattr(getattr(mytool, bname), "show_"+obj['prop']): if obj['type'] == fieldType.FLOAT or obj['type'] == fieldType.RAD: - object[obj['prop']] = float(getattr(mytool, bname)[obj['prop']]) + object[obj['prop']] = float(getattr(getattr(mytool, bname), obj['prop'])) + + elif obj['type'] == fieldType.INT \ + or obj['type'] == fieldType.MATERIAL_IND: + object[obj['prop']] = int(getattr(getattr(mytool, bname), obj['prop'])) + - elif obj['type'] == fieldType.INT: - object[obj['prop']] = int(getattr(mytool, bname)[obj['prop']]) elif obj['type'] == fieldType.STRING: - object[obj['prop']] = str(getattr(mytool, bname)[obj['prop']]) + object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) + + elif obj['type'] == fieldType.SPACE_NAME \ + or obj['type'] == fieldType.REFERENCEABLE: + object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) + + elif obj['type'] == fieldType.ENUM: + + if obj['subtype'] == fieldType.INT: + object[obj['prop']] = int(getattr(getattr(mytool, bname), obj['prop'])) + + elif obj['subtype'] == fieldType.STRING: + object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) + + elif obj['subtype'] == fieldType.FLOAT: + object[obj['prop']] = float(getattr(getattr(mytool, bname), obj['prop'])) elif obj['type'] == fieldType.COORD: - xyz = getattr(mytool, bname)[obj['prop']] + xyz = getattr(getattr(mytool, bname), obj['prop']) object[obj['prop']] = (xyz[0],xyz[1],xyz[2]) elif obj['type'] == fieldType.LIST: @@ -658,7 +703,7 @@ def setObjsByType(context, object, zclass): object[obj['prop']] = arr else: - object[obj['prop']] = getattr(mytool, bname)[obj['prop']] + object[obj['prop']] = getattr(getattr(mytool, bname), obj['prop']) def getFromAttributes(context, obj, attrs, bname, index): @@ -832,4 +877,5 @@ def createCustomAttribute(mesh, values, zclass, zobj): mesh.attributes.new(name=zobj['prop'], type=ztype, domain=domain) attr = mesh.attributes[zobj['prop']].data for i in range(len(attr)): - setattr(attr[i], "value", values[i]) \ No newline at end of file + setattr(attr[i], "value", values[i]) + diff --git a/src/2.80/addons/b3d_tools/custom_UIList.py b/src/2.80/addons/b3d_tools/custom_UIList.py index b8a6f82..66ce85b 100644 --- a/src/2.80/addons/b3d_tools/custom_UIList.py +++ b/src/2.80/addons/b3d_tools/custom_UIList.py @@ -419,7 +419,7 @@ class CUSTOM_PG_objectCollection(PropertyGroup): # Register & Unregister # ------------------------------------------------------------------- -classes = ( +_classes = ( CUSTOM_OT_actions, CUSTOM_OT_actions_arrbname, CUSTOM_OT_addViewportSelection, @@ -435,7 +435,7 @@ class CUSTOM_PG_objectCollection(PropertyGroup): def register(): from bpy.utils import register_class - for cls in classes: + for cls in _classes: register_class(cls) # Custom scene properties @@ -448,7 +448,7 @@ def register(): def unregister(): from bpy.utils import unregister_class - for cls in classes[::-1]: + for cls in _classes[::-1]: unregister_class(cls) del bpy.types.Scene.custom From 8a7edb1e09a124d7f2a6939ce78a573f5c0b136d Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 14 Jan 2023 14:40:06 +0200 Subject: [PATCH 30/47] old getAllChildren --- src/2.80/addons/b3d_tools/b3d/common.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 282efc3..4e41a38 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -250,17 +250,16 @@ def getSelectedVertices(obj): def getAllChildren(obj): allChildren = [] - # if len((obj.children)): currentObjs = [obj] - if currentObjs: + while(1): nextChildren = [] - - for obj in currentObjs: - # if obj.children: - nextChildren.extend(obj.children) - currentObjs = nextChildren - # if currentObjs: - allChildren.extend(currentObjs) + if len(currentObjs) > 0: + for obj in currentObjs: + nextChildren.extend(obj.children) + currentObjs = nextChildren + allChildren.extend(currentObjs) + else: + break return allChildren def referenceablesCallback(scene, context): From 8cda37d9209c610baea176ab3a8d7c0447b11f5f Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Mon, 16 Jan 2023 00:02:04 +0200 Subject: [PATCH 31/47] block 30 updated edit --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 76 +- src/2.80/addons/b3d_tools/b3d/classes.py | 118 +- src/2.80/addons/b3d_tools/b3d/common.py | 42 +- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 4891 +++++++++--------- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 234 +- src/2.80/addons/b3d_tools/b3d/menus.py | 11 +- src/2.80/addons/b3d_tools/b3d/scripts.py | 110 +- 7 files changed, 2902 insertions(+), 2580 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index c7e1d2a..78d330b 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -55,10 +55,13 @@ class fieldType(enum.Enum): FLOAT = 5 ENUM = 6 LIST = 7 - V_FORMAT = 8 - MATERIAL_IND = 9 - SPACE_NAME = 10 - REFERENCEABLE = 11 + ENUM_STR = 8 + V_FORMAT = 20 + MATERIAL_IND = 21 + SPACE_NAME = 22 + REFERENCEABLE = 23 + ROOM = 24 + RES_MODULE = 25 class ActiveBlock(bpy.types.PropertyGroup): @@ -333,7 +336,8 @@ class b_4(): } Name1 = { 'prop': 'name1', - 'type': fieldType.SPACE_NAME, + 'type': fieldType.ENUM_STR, + 'subtype': fieldType.SPACE_NAME, 'name': 'Трансформация', 'description': '' } @@ -845,13 +849,15 @@ class b_18(): } Space_Name = { 'prop': 'space_name', - 'type': fieldType.SPACE_NAME, + 'type': fieldType.ENUM, + 'subtype': fieldType.SPACE_NAME, 'name': 'Название трансформации (24)', 'description': '' } Add_Name = { 'prop': 'add_name', - 'type': fieldType.REFERENCEABLE, + 'type': fieldType.ENUM, + 'subtype': fieldType.REFERENCEABLE, 'name': 'Название переносимого блока', 'description': '' } @@ -1207,27 +1213,52 @@ class b_30(): 'description': '', 'default': 0.0 } - Name = { - 'prop': 'name', - 'type': fieldType.STRING, - 'name': 'Название комнаты', + ResModule1 = { + 'prop': '1_roomName_res', + 'type': fieldType.ENUM_STR, + 'subtype': fieldType.RES_MODULE, + 'name': '1. модуль', 'description': '', 'default': '' } - XYZ1 = { - 'prop': 'XYZ1', - 'type': fieldType.COORD, - 'name': 'Координаты 1. точки', + RoomName1 = { + 'prop': '1_roomName', + 'type': fieldType.ENUM_STR, + 'subtype': fieldType.ROOM, + 'name': 'Название 1. комнаты', 'description': '', - 'default': (0.0, 0.0, 0.0) + 'default': '' } - XYZ2 = { - 'prop': 'XYZ2', - 'type': fieldType.COORD, - 'name': 'Координаты 2. точки', + ResModule2 = { + 'prop': '2_roomName_res', + 'type': fieldType.ENUM_STR, + 'subtype': fieldType.RES_MODULE, + 'name': '2. модуль', 'description': '', - 'default': (0.0, 0.0, 0.0) + 'default': '' } + RoomName2 = { + 'prop': '2_roomName', + 'type': fieldType.ENUM_STR, + 'subtype': fieldType.ROOM, + 'name': 'Название 2. комнаты', + 'description': '', + 'default': '' + } + # XYZ1 = { + # 'prop': 'XYZ1', + # 'type': fieldType.COORD, + # 'name': 'Координаты 1. точки', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # XYZ2 = { + # 'prop': 'XYZ2', + # 'type': fieldType.COORD, + # 'name': 'Координаты 2. точки', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } class b_31(): XYZ = { @@ -1429,7 +1460,8 @@ class b_35(): } TexNum = { 'prop': 'texnum', - 'type': fieldType.MATERIAL_IND, + 'type': fieldType.ENUM, + 'subtype': fieldType.MATERIAL_IND, 'name': 'Номер текстуры', 'description': '', } diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index cc38280..9198fea 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -65,11 +65,31 @@ from .common import ( resMaterialsCallback, spacesCallback, - referenceablesCallback + referenceablesCallback, + roomsCallback, + modulesCallback, + getMytoolBlockName ) + +def setStrValue(bname, pname): + def callback_func(self, context): + + mytool = context.scene.my_tool + setattr( + getattr(mytool, bname), + '{}'.format(pname), + getattr(getattr(mytool, bname), '{}_enum'.format(pname)) + ) + + return callback_func + def createTypeClass(zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + + bname, bnum = getMytoolBlockName(zclass) + + block_num = zclass.__name__.split('_')[1] attributes = { '__annotations__' : { @@ -77,7 +97,7 @@ def createTypeClass(zclass): } for attr in attrs: obj = zclass.__dict__[attr] - propName = obj['prop'] + pname = obj['prop'] prop = None lockProp = BoolProperty( @@ -91,21 +111,17 @@ def createTypeClass(zclass): or obj['type'] == fieldType.RAD \ or obj['type'] == fieldType.FLOAT \ or obj['type'] == fieldType.INT \ - or obj['type'] == fieldType.ENUM \ - or obj['type'] == fieldType.LIST \ - or obj['type'] == fieldType.MATERIAL_IND \ - or obj['type'] == fieldType.SPACE_NAME \ - or obj['type'] == fieldType.REFERENCEABLE: + or obj['type'] == fieldType.LIST: - attributes['__annotations__']["show_"+propName] = lockProp + attributes['__annotations__']["show_"+pname] = lockProp if obj['type'] == fieldType.STRING: prop = StringProperty( name = obj['name'], description = obj['description'], default = obj['default'], - maxlen = 30 + maxlen = 32 ) elif obj['type'] == fieldType.COORD: @@ -129,14 +145,6 @@ def createTypeClass(zclass): default = obj['default'] ) - elif obj['type'] == fieldType.ENUM: - prop = EnumProperty( - name = obj['name'], - description = obj['description'], - default = obj['default'], - items = obj['items'] - ) - elif obj['type'] == fieldType.LIST: prop = CollectionProperty( name = obj['name'], @@ -144,60 +152,102 @@ def createTypeClass(zclass): type = FloatBlock ) - elif obj['type'] == fieldType.MATERIAL_IND: - prop = EnumProperty( - name = obj['name'], - description = obj['description'], - items = resMaterialsCallback + attributes['__annotations__'][pname] = prop + + elif obj['type'] == fieldType.ENUM \ + or obj['type'] == fieldType.ENUM_STR: + + attributes['__annotations__']["show_"+pname] = lockProp + enum_callback = None + + if obj.get('subtype') == fieldType.SPACE_NAME: + enum_callback = spacesCallback + elif obj.get('subtype') == fieldType.REFERENCEABLE: + enum_callback = referenceablesCallback + elif obj.get('subtype') == fieldType.MATERIAL_IND: + enum_callback = resMaterialsCallback + elif obj.get('subtype') == fieldType.ROOM: + enum_callback = roomsCallback(bname, '{}_res'.format(pname)) + elif obj.get('subtype') == fieldType.RES_MODULE: + enum_callback = modulesCallback + + if obj['type'] == fieldType.ENUM: + prop = None + if enum_callback == None: + prop = EnumProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'], + items = obj['items'] + ) + else: + prop = EnumProperty( + name = obj['name'], + description = obj['description'], + items = enum_callback + ) + + attributes['__annotations__'][pname] = prop + + elif obj['type'] == fieldType.ENUM_STR: + prop = None + prop_enum = None + prop_switch = None + + prop_switch = BoolProperty( + name = 'Use dropdown', + description = 'Выбор из Dropdown списка', + default = False ) - elif obj['type'] == fieldType.SPACE_NAME: - prop = EnumProperty( + prop_enum = EnumProperty( name = obj['name'], description = obj['description'], - items = spacesCallback + items = enum_callback, + update = setStrValue(bname, pname) ) - elif obj['type'] == fieldType.REFERENCEABLE: - prop = EnumProperty( + prop = StringProperty( name = obj['name'], description = obj['description'], - items = referenceablesCallback + maxlen = 32 ) - attributes['__annotations__'][propName] = prop + attributes['__annotations__']['{}_switch'.format(pname)] = prop_switch + attributes['__annotations__']['{}_enum'.format(pname)] = prop_enum + attributes['__annotations__']['{}'.format(pname)] = prop elif obj['type'] == fieldType.V_FORMAT: - attributes['__annotations__']["show_{}".format(propName)] = lockProp + attributes['__annotations__']["show_{}".format(pname)] = lockProp prop1 = BoolProperty( name = 'Смещенная триангуляция', description = 'Порядок в котором считываются вертексы, зависит от этой переменной', default = True ) - attributes['__annotations__']['{}_{}'.format(propName, 'triang_offset')] = prop1 + attributes['__annotations__']['{}_{}'.format(pname, 'triang_offset')] = prop1 prop2 = BoolProperty( name = 'Использовать UV', description = 'Когда активен, при экспорте записывает UV.', default = True ) - attributes['__annotations__']['{}_{}'.format(propName, 'use_uvs')] = prop2 + attributes['__annotations__']['{}_{}'.format(pname, 'use_uvs')] = prop2 prop3 = BoolProperty( name = 'Использовать нормали', description = 'Когда активен, при экспорте записывает нормали.', default = True ) - attributes['__annotations__']['{}_{}'.format(propName, 'use_normals')] = prop3 + attributes['__annotations__']['{}_{}'.format(pname, 'use_normals')] = prop3 prop4 = BoolProperty( name = 'Выключатель нормалей', description = 'Когда активен, использует float для вкл./выкл. нормалей. Когда неактивен использует float vector для обычных нормалей. Игнорируется если пункт "Использовать нормали" неактивен', default = True ) - attributes['__annotations__']['{}_{}'.format(propName, 'normal_flag')] = prop4 + attributes['__annotations__']['{}_{}'.format(pname, 'normal_flag')] = prop4 newclass = type("{}_gen".format(zclass.__name__), (bpy.types.PropertyGroup,), attributes) return newclass diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 4e41a38..f7a394e 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -262,7 +262,23 @@ def getAllChildren(obj): break return allChildren -def referenceablesCallback(scene, context): +def getMytoolBlockName(zclass): + bname = '' + btype, bnum = zclass.__name__.split('_') + if btype == 'b': + bname = 'block{}'.format(bnum) + elif btype == 'pfb': + bname = 'perFaceBlock{}'.format(bnum) + elif btype == 'pvb': + bname = 'perVertBlock{}'.format(bnum) + + return [bname, bnum] + +def referenceablesCallback(self, context): + + # print(dir(scene)) + # print(context.object) + # print(dir(context)) mytool = context.scene.my_tool rootObj = getRootObj(context.object) @@ -275,7 +291,7 @@ def referenceablesCallback(scene, context): return enumProperties -def spacesCallback(scene, context): +def spacesCallback(self, context): mytool = context.scene.my_tool rootObj = getRootObj(context.object) @@ -288,7 +304,7 @@ def spacesCallback(scene, context): return enumProperties -def resMaterialsCallback(scene, context): +def resMaterialsCallback(self, context): mytool = context.scene.my_tool rootObj = getRootObj(context.object) @@ -301,19 +317,25 @@ def resMaterialsCallback(scene, context): return enumProperties -def roomsCallback(scene, context): +def roomsCallback(bname, pname): + def callback_func(self, context): - mytool = context.scene.my_tool - rootObj = getRootObj(context.object) + enumProperties = [] - rooms = [cn for cn in rootObj.children if cn.name[:5] == 'room_'] + mytool = context.scene.my_tool + resModule = getattr(getattr(mytool, bname), pname) - enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(rooms)] + rootObj = bpy.data.objects.get('{}.b3d'.format(resModule)) + if rootObj: + rooms = [cn for cn in rootObj.children if cn.get('block_type') == 19] - return enumProperties + enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(rooms)] + + return enumProperties + return callback_func -def modulesCallback(scene, context): +def modulesCallback(self, context): mytool = context.scene.my_tool diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index 94f42af..0e5cd6b 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -147,16 +147,6 @@ def uv_from_vert_average(uv_layer, v): else: return None -def write(file, context, op, filepath, generate_pro_file, textures_path): - - global myFile_pro - myFile_pro = filepath - if generate_pro_file == True: - export_pro(myFile_pro, textures_path) - - global myFile - myFile = filepath - export(myFile, generate_pro_file) def MsgBox(label = "", title = "Error", icon = 'ERROR'): @@ -231,1108 +221,1201 @@ def delete_clone(): b3d_node.select = True bpy.ops.object.delete() +def getRoomName(curResModule, roomString): + result = '' + roomSplit = roomString.split(':') + resModule = roomSplit[0] + roomName = roomSplit[1] -def export(file, generate_pro_file): - file = open(myFile,'wb') - - global global_matrix - global_matrix = axis_conversion(to_forward="-Z", - to_up="Y", - ).to_4x4() * Matrix.Scale(1, 4) - - global generatePro - generatePro = generate_pro_file - - global verNums - verNums = [] - - #ba = bytearray(b'\x00' * 20) - - #file.write(ba) + if curResModule == resModule: + result = roomName + else: + result = roomString - materials = [] + return result - for material in bpy.data.materials: - materials.append(material.name) +class B3DExporter: - cp_materials = 0 - cp_data_blocks = 0 - cp_eof = 0 + borders = {} + currentRes = '' + currentRoomName = '' - #Header + def createBorderList(self): - file.write(b'b3d\x00')#struct.pack("4c",b'B',b'3',b'D',b'\x00')) + self.borders = {} - file.write(struct.pack(' 0: - for obj in rChild[:-1]: - if obj['block_type'] == 10 or obj['block_type'] == 9: - curMaxCnt = 2 - elif obj['block_type'] == 21: - curMaxCnt = obj[prop(b_21.GroupCnt)] - exportBlock(obj, False, curLevel, curMaxCnt, [0], {}, file) - - file.write(struct.pack(" 0: + for obj in rChild[:-1]: + if obj['block_type'] == 10 or obj['block_type'] == 9: + curMaxCnt = 2 + elif obj['block_type'] == 21: + curMaxCnt = obj[prop(b_21.GroupCnt)] + self.exportBlock(obj, False, curLevel, curMaxCnt, [0], {}, file) - #write Group Chunk - if block['level_group'] > curGroups[curLevel]: - log.debug('group ended') - for i in range(block['level_group'] - curGroups[curLevel]): - file.write(struct.pack(" curGroups[curLevel]: + log.debug('group ended') + for i in range(block['level_group'] - curGroups[curLevel]): + file.write(struct.pack("> 8) - - if format & 0b10: - uvCount += 1 - - if format & 0b100000 and format & 0b10000: - useNormals = True - if format & 0b1: - normalSwitch = True - else: - normalSwitch = False - - l_uvs = {} - for li in poly.loop_indices: - vi = mesh.loops[li].vertex_index - l_uvs[vi] = mesh.uv_layers['UVmapPoly0'].data[li].uv - - for i, vert in enumerate(poly.vertices): - file.write(struct.pack("> 8) - toProcessChild = True + if format & 0b10: + uvCount += 1 - elif objType == 12: + if format & 0b100000 and format & 0b10000: + useNormals = True + if format & 0b1: + normalSwitch = True + else: + normalSwitch = False + + l_uvs = {} + for li in poly.loop_indices: + vi = mesh.loops[li].vertex_index + l_uvs[vi] = mesh.uv_layers['UVmapPoly0'].data[li].uv + + for i, vert in enumerate(poly.vertices): + file.write(struct.pack("> 8) - - if format & 0b10: - uvCount += 1 - - if format & 0b100000 and format & 0b10000: - useNormals = True - if format & 0b1: - normalSwitch = True - else: - normalSwitch = False - - l_uvs = {} - for li in poly.loop_indices: - vi = mesh.loops[li].vertex_index - l_uvs[vi] = mesh.uv_layers['UVmapPoly0'].data[li].uv - - for i, vert in enumerate(poly.vertices): - file.write(struct.pack("> 8) + + if format & 0b10: + uvCount += 1 + + if format & 0b100000 and format & 0b10000: + useNormals = True + if format & 0b1: + normalSwitch = True else: - file.write(struct.pack("> 8 - format = formatRaw & 0xFF + #temporary + # if isSecondUvs: + # formatRaw = 258 + # else: + # formatRaw = 2 - if format == 1 or format == 2: - normalSwitch = True - elif format == 3: - normalSwitch = False + extraUvCount = formatRaw >> 8 + format = formatRaw & 0xFF + if format == 1 or format == 2: + normalSwitch = True + elif format == 3: + normalSwitch = False - file.write(struct.pack("> 8 - format = formatRaw & 0xFF - - if format == 1 or format == 2: - normalSwitch = True - elif format == 3: + # isSecondUvs = False + formatRaw = block[prop(b_37.SType)] normalSwitch = False + file.write(struct.pack("<3f", *block[prop(b_37.XYZ)])) + file.write(struct.pack("> 8 + format = formatRaw & 0xFF - file.write(struct.pack(" 0): - for i, ch in enumerate(blChildren[:-1]): + elif objType == 40: - if len(passToMesh) > 0: - l_extra['passToMesh'] = passToMesh - exportBlock(ch, False, curLevel+1, curMaxCnt, curGroups, l_extra, file) + file.write(struct.pack("<3f", *block[prop(b_40.XYZ)])) + file.write(struct.pack(" 0: - l_extra['passToMesh'] = passToMesh - exportBlock(blChildren[-1], True, curLevel+1, curMaxCnt, curGroups, l_extra, file) + if toProcessChild: + l_extra = extra + if(len(blChildren) > 0): + for i, ch in enumerate(blChildren[:-1]): - # log.debug("{}_{}".format(curGroups, block.name)) + if len(passToMesh) > 0: + l_extra['passToMesh'] = passToMesh + self.exportBlock(ch, False, curLevel+1, curMaxCnt, curGroups, l_extra, file) - # called from parent object with 0 children - if toProcessChild and len(blChildren) == 0 and curMaxCnt > 1: - for i in range(curMaxCnt-1): - file.write(struct.pack(" 0: + l_extra['passToMesh'] = passToMesh + self.exportBlock(blChildren[-1], True, curLevel+1, curMaxCnt, curGroups, l_extra, file) + + # log.debug("{}_{}".format(curGroups, block.name)) + + # called from parent object with 0 children + if toProcessChild and len(blChildren) == 0 and curMaxCnt > 1: + for i in range(curMaxCnt-1): + file.write(struct.pack(" 0: - mesh_blocks += 1 - - if len(flat_faces) > 0: - mesh_blocks += 1 - - file.write(struct.pack(" 0: - file.write(struct.pack(" 0: - file.write(struct.pack(" 180): - object.rotation_euler[0] = (360-(object.rotation_euler[0] * 180/PI)) * PI/180 - - if ((object.rotation_euler[1] * 180/PI) < -180): - object.rotation_euler[1] = (360+(object.rotation_euler[1] * 180/PI)) * PI/180 - elif ((object.rotation_euler[1] * 180/PI) > 180): - object.rotation_euler[1] = (360-(object.rotation_euler[1] * 180/PI)) * PI/180 - - if ((object.rotation_euler[2] * 180/PI) < -180): - object.rotation_euler[2] = (360+(object.rotation_euler[2] * 180/PI)) * PI/180 - elif ((object.rotation_euler[2] * 180/PI) > 180): - object.rotation_euler[2] = (360-(object.rotation_euler[2] * 180/PI)) * PI/180 - """ - - #file.write(struct.pack(" 0: - mesh_blocks += 1 - - if len(flat_faces) > 0: - mesh_blocks += 1 - - file.write(struct.pack(" 0: - file.write(struct.pack(" 0: - file.write(struct.pack(" 0: - mesh_blocks += 1 - - if len(flat_faces) > 0: - mesh_blocks += 1 - - file.write(struct.pack(" 0: - file.write(struct.pack(" 0: - file.write(struct.pack(" 0: +# mesh_blocks += 1 + +# if len(flat_faces) > 0: +# mesh_blocks += 1 + +# file.write(struct.pack(" 0: +# file.write(struct.pack(" 0: +# file.write(struct.pack(" 180): +# object.rotation_euler[0] = (360-(object.rotation_euler[0] * 180/PI)) * PI/180 + +# if ((object.rotation_euler[1] * 180/PI) < -180): +# object.rotation_euler[1] = (360+(object.rotation_euler[1] * 180/PI)) * PI/180 +# elif ((object.rotation_euler[1] * 180/PI) > 180): +# object.rotation_euler[1] = (360-(object.rotation_euler[1] * 180/PI)) * PI/180 + +# if ((object.rotation_euler[2] * 180/PI) < -180): +# object.rotation_euler[2] = (360+(object.rotation_euler[2] * 180/PI)) * PI/180 +# elif ((object.rotation_euler[2] * 180/PI) > 180): +# object.rotation_euler[2] = (360-(object.rotation_euler[2] * 180/PI)) * PI/180 +# """ + +# #file.write(struct.pack(" 0: +# mesh_blocks += 1 + +# if len(flat_faces) > 0: +# mesh_blocks += 1 + +# file.write(struct.pack(" 0: +# file.write(struct.pack(" 0: +# file.write(struct.pack(" 0: +# mesh_blocks += 1 + +# if len(flat_faces) > 0: +# mesh_blocks += 1 + +# file.write(struct.pack(" 0: +# file.write(struct.pack(" 0: +# file.write(struct.pack(" Date: Tue, 17 Jan 2023 21:58:16 +0200 Subject: [PATCH 32/47] b_28 fix --- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 36 +++++++++++---------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/import_b3d.py b/src/2.80/addons/b3d_tools/b3d/import_b3d.py index ebc3d4e..0429500 100644 --- a/src/2.80/addons/b3d_tools/b3d/import_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/import_b3d.py @@ -1600,8 +1600,8 @@ def read(file, context, self, filepath): poly_block_uvs[0][curface] = vertex_block_uvs[0][curface] for j in range(uvCount-1): poly_block_uvs[j][curface] = struct.unpack("<2f",file.read(8)) - else: - poly_block_uvs[0][curface] = vertex_block_uvs[0][curface] + # else: + # poly_block_uvs[0][curface] = vertex_block_uvs[0][curface] curface += 1 @@ -1657,24 +1657,26 @@ def read(file, context, self, filepath): # Tr.join() for u, uvMap in enumerate(vertex_block_uvs): - customUV = b3dMesh.uv_layers.new() - customUV.name = "UVmapVert{}".format(u) - uvsMesh = [] + if len(uvMap): + customUV = b3dMesh.uv_layers.new() + customUV.name = "UVmapVert{}".format(u) + uvsMesh = [] - for i, texpoly in enumerate(b3dMesh.polygons): - for j,loop in enumerate(texpoly.loop_indices): - uvsMesh = (uvMap[uv_indexes[i][j]][0],1 - uvMap[uv_indexes[i][j]][1]) - customUV.data[loop].uv = uvsMesh + for i, texpoly in enumerate(b3dMesh.polygons): + for j,loop in enumerate(texpoly.loop_indices): + uvsMesh = (uvMap[uv_indexes[i][j]][0],1 - uvMap[uv_indexes[i][j]][1]) + customUV.data[loop].uv = uvsMesh for u, uvOver in enumerate(overriden_uvs): - customUV = b3dMesh.uv_layers.new() - customUV.name = "UVmapPoly{}".format(u) - uvsMesh = [] - - for i, texpoly in enumerate(b3dMesh.polygons): - for j,loop in enumerate(texpoly.loop_indices): - uvsMesh = [uvOver[i][j][0],1 - uvOver[i][j][1]] - customUV.data[loop].uv = uvsMesh + if len(uvOver): + customUV = b3dMesh.uv_layers.new() + customUV.name = "UVmapPoly{}".format(u) + uvsMesh = [] + + for i, texpoly in enumerate(b3dMesh.polygons): + for j,loop in enumerate(texpoly.loop_indices): + uvsMesh = [uvOver[i][j][0],1 - uvOver[i][j][1]] + customUV.data[loop].uv = uvsMesh if self.to_import_textures: #For assignMaterialByVertices just-in-case From d42bae5381ca1c204c672605f04abed080f589db Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Tue, 17 Jan 2023 22:05:02 +0200 Subject: [PATCH 33/47] b3dsplit fix --- utils/b3dsplit.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/b3dsplit.py b/utils/b3dsplit.py index a8312fe..932c487 100644 --- a/utils/b3dsplit.py +++ b/utils/b3dsplit.py @@ -19,6 +19,8 @@ filename = args[1] outdir = os.path.dirname(filename) elif len(args) == 3: + filename = args[1] + outdir = os.path.dirname(filename) rootsFromFile = True rootsFile = args[2] else: From fb45fdcf2120df5bb96b0a53f7b01fc84f1c7542 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sun, 22 Jan 2023 19:26:26 +0200 Subject: [PATCH 34/47] border sphere edit --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 447 +++++--- src/2.80/addons/b3d_tools/b3d/classes.py | 4 +- src/2.80/addons/b3d_tools/b3d/common.py | 18 +- src/2.80/addons/b3d_tools/b3d/panel.py | 1000 +----------------- src/2.80/addons/b3d_tools/b3d/scripts.py | 255 +++-- 5 files changed, 543 insertions(+), 1181 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index 78d330b..7eedf66 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -56,12 +56,15 @@ class fieldType(enum.Enum): ENUM = 6 LIST = 7 ENUM_STR = 8 - V_FORMAT = 20 - MATERIAL_IND = 21 - SPACE_NAME = 22 - REFERENCEABLE = 23 - ROOM = 24 - RES_MODULE = 25 + + V_FORMAT = 21 + MATERIAL_IND = 22 + SPACE_NAME = 23 + REFERENCEABLE = 24 + ROOM = 25 + RES_MODULE = 26 + + SPHERE_EDIT = 41 class ActiveBlock(bpy.types.PropertyGroup): @@ -275,19 +278,23 @@ class b_1(): class b_2(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -305,35 +312,43 @@ class b_2(): class b_3(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } class b_4(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Name1 = { 'prop': 'name1', 'type': fieldType.ENUM_STR, @@ -350,44 +365,52 @@ class b_4(): } class b_5(): - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Имя блока', - 'description': '', - 'default': '' - } - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Имя блока', + 'description': '', + 'default': '' + } + XYZ = { + 'prop': 'b3d_border_center', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'b3d_border_rad', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } class b_6(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -404,59 +427,71 @@ class b_6(): } class b_7(): - XYZ = { - 'prop': 'XYZ', - 'type': fieldType.COORD, - 'name': 'Координаты блока', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'R', - 'type': fieldType.RAD, - 'name': 'Радиус', - 'description': '', - 'default': 0.0 - } - Name1 = { - 'prop': 'name1', - 'type': fieldType.STRING, - 'name': 'Название группы', - 'description': '', - 'default': '' - } + XYZ = { + 'prop': 'b3d_border_center', + 'type': fieldType.COORD, + 'name': 'Координаты блока', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + R = { + 'prop': 'b3d_border_rad', + 'type': fieldType.RAD, + 'name': 'Радиус', + 'description': '', + 'default': 0.0 + } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } + Name1 = { + 'prop': 'name1', + 'type': fieldType.STRING, + 'name': 'Название группы', + 'description': '', + 'default': '' + } class b_8(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } class b_9(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -474,19 +509,23 @@ class b_9(): class b_10(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } LOD_XYZ = { 'prop': 'LOD_XYZ', 'type': fieldType.COORD, @@ -504,19 +543,23 @@ class b_10(): class b_11(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -534,19 +577,23 @@ class b_11(): class b_12(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -584,19 +631,23 @@ class b_12(): class b_13(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -620,19 +671,23 @@ class b_13(): class b_14(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -670,19 +725,23 @@ class b_14(): class b_15(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -706,19 +765,23 @@ class b_15(): class b_16(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, @@ -770,19 +833,23 @@ class b_16(): class b_17(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, @@ -834,19 +901,23 @@ class b_17(): class b_18(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Space_Name = { 'prop': 'space_name', 'type': fieldType.ENUM, @@ -864,19 +935,23 @@ class b_18(): class b_20(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -900,19 +975,23 @@ class b_20(): class b_21(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } GroupCnt = { 'prop': 'group_cnt', 'type': fieldType.INT, @@ -930,19 +1009,23 @@ class b_21(): class b_22(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -1058,19 +1141,23 @@ class b_25(): class b_26(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, @@ -1095,19 +1182,23 @@ class b_26(): class b_27(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Flag = { 'prop': 'flag', 'type': fieldType.INT, @@ -1132,19 +1223,23 @@ class b_27(): class b_28(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -1156,19 +1251,23 @@ class b_28(): class b_29(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -1200,19 +1299,23 @@ class b_29(): class b_30(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } ResModule1 = { 'prop': '1_roomName_res', 'type': fieldType.ENUM_STR, @@ -1245,36 +1348,26 @@ class b_30(): 'description': '', 'default': '' } - # XYZ1 = { - # 'prop': 'XYZ1', - # 'type': fieldType.COORD, - # 'name': 'Координаты 1. точки', - # 'description': '', - # 'default': (0.0, 0.0, 0.0) - # } - # XYZ2 = { - # 'prop': 'XYZ2', - # 'type': fieldType.COORD, - # 'name': 'Координаты 2. точки', - # 'description': '', - # 'default': (0.0, 0.0, 0.0) - # } class b_31(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -1314,19 +1407,23 @@ class b_31(): class b_33(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Use_Lights = { 'prop': 'useLight', 'type': fieldType.INT, @@ -1415,19 +1512,23 @@ class b_33(): class b_34(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } UnkInt = { 'prop': 'int1', 'type': fieldType.INT, @@ -1438,19 +1539,23 @@ class b_34(): class b_35(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } MType = { 'prop': 'mType', 'type': fieldType.INT, @@ -1468,19 +1573,23 @@ class b_35(): class b_36(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -1505,19 +1614,23 @@ class b_36(): class b_37(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -1535,19 +1648,23 @@ class b_37(): class b_39(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Color_R = { 'prop': 'color_r', 'type': fieldType.INT, @@ -1586,19 +1703,23 @@ class b_39(): class b_40(): XYZ = { - 'prop': 'XYZ', + 'prop': 'b3d_border_center', 'type': fieldType.COORD, 'name': 'Координаты блока', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { - 'prop': 'R', + 'prop': 'b3d_border_rad', 'type': fieldType.RAD, 'name': 'Радиус', 'description': '', 'default': 0.0 } + Set_Bound = { + 'prop': 'b3d_border', + 'type': fieldType.SPHERE_EDIT + } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -1636,6 +1757,84 @@ class b_40(): 'description': '', } +def getClassDefByType(blockNum): + zclass = None + if blockNum == 1: + zclass = b_1 + elif blockNum == 2: + zclass = b_2 + elif blockNum == 3: + zclass = b_3 + elif blockNum == 4: + zclass = b_4 + elif blockNum == 5: + zclass = b_5 + elif blockNum == 6: + zclass = b_6 + elif blockNum == 7: + zclass = b_7 + elif blockNum == 8: + zclass = b_8 + elif blockNum == 9: + zclass = b_9 + elif blockNum == 10: + zclass = b_10 + elif blockNum == 11: + zclass = b_11 + elif blockNum == 12: + zclass = b_12 + elif blockNum == 13: + zclass = b_13 + elif blockNum == 14: + zclass = b_14 + elif blockNum == 15: + zclass = b_15 + elif blockNum == 16: + zclass = b_16 + elif blockNum == 17: + zclass = b_17 + elif blockNum == 18: + zclass = b_18 + elif blockNum == 20: + zclass = b_20 + elif blockNum == 21: + zclass = b_21 + elif blockNum == 22: + zclass = b_22 + elif blockNum == 23: + zclass = b_23 + elif blockNum == 24: + zclass = b_24 + elif blockNum == 25: + zclass = b_25 + elif blockNum == 26: + zclass = b_26 + elif blockNum == 27: + zclass = b_27 + elif blockNum == 28: + zclass = b_28 + elif blockNum == 29: + zclass = b_29 + elif blockNum == 30: + zclass = b_30 + elif blockNum == 31: + zclass = b_31 + elif blockNum == 33: + zclass = b_33 + elif blockNum == 34: + zclass = b_34 + elif blockNum == 35: + zclass = b_35 + elif blockNum == 36: + zclass = b_36 + elif blockNum == 37: + zclass = b_37 + elif blockNum == 39: + zclass = b_39 + elif blockNum == 40: + zclass = b_40 + return zclass + _classes = ( ActiveBlock, FloatBlock, diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 9198fea..1390813 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -68,7 +68,7 @@ referenceablesCallback, roomsCallback, modulesCallback, - getMytoolBlockName + getMytoolBlockNameByClass ) @@ -87,7 +87,7 @@ def callback_func(self, context): def createTypeClass(zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockName(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass) block_num = zclass.__name__.split('_')[1] attributes = { diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index f7a394e..c06d82e 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -262,7 +262,7 @@ def getAllChildren(obj): break return allChildren -def getMytoolBlockName(zclass): +def getMytoolBlockNameByClass(zclass): bname = '' btype, bnum = zclass.__name__.split('_') if btype == 'b': @@ -274,11 +274,19 @@ def getMytoolBlockName(zclass): return [bname, bnum] -def referenceablesCallback(self, context): - # print(dir(scene)) - # print(context.object) - # print(dir(context)) +def getMytoolBlockName(btype, bnum): + bname = '' + if btype == 'b': + bname = 'block{}'.format(bnum) + elif btype == 'pfb': + bname = 'perFaceBlock{}'.format(bnum) + elif btype == 'pvb': + bname = 'perVertBlock{}'.format(bnum) + + return bname + +def referenceablesCallback(self, context): mytool = context.scene.my_tool rootObj = getRootObj(context.object) diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index 40eb67a..1305fa5 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -39,7 +39,9 @@ getPerFaceByType, setPerFaceByType, getPerVertexByType, - setPerVertexByType + setPerVertexByType, + showSphere, + ) @@ -51,6 +53,7 @@ perFaceBlock_8, perFaceBlock_28, perFaceBlock_35, perVertBlock_8, perVertBlock_35 ) from .class_descr import ( + getClassDefByType, b_1,b_2,b_3,b_4,b_5,b_6,b_7,b_8,b_9,b_10,\ b_11,b_12,b_13,b_14,b_15,b_16,b_17,b_18,b_20,\ b_21,b_22,b_23,b_24,b_25,b_26,b_27,b_28,b_29,b_30,\ @@ -618,9 +621,6 @@ def execute(self, context): object = bpy.data.objects.new(object_name, None) object.location=cursor_pos object['block_type'] = block_type - # setAllObjsByType(context, object, b_1) - # object['block_type'] = block_type - # object['add_space'] = mytool.addSpaceName_string bpy.context.scene.objects.link(object) elif block_type == 1: @@ -628,9 +628,6 @@ def execute(self, context): object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_1) - # object['block_type'] = block_type - # object['add_space'] = mytool.addSpaceName_string - # object['route_name'] = mytool.routeName_string bpy.context.scene.objects.link(object) elif block_type == 2: @@ -638,9 +635,6 @@ def execute(self, context): object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_2) - # object['block_type'] = block_type - # object['add_space'] = mytool.addSpaceName_string - # object['route_name'] = mytool.routeName_string bpy.context.scene.objects.link(object) elif block_type == 3: @@ -648,8 +642,6 @@ def execute(self, context): object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_3) - # object['block_type'] = block_type - # object['node_radius'] = mytool.Radius bpy.context.scene.objects.link(object) elif block_type == 4: @@ -657,10 +649,6 @@ def execute(self, context): object.location=cursor_pos #(0.0,0.0,0.0) object['block_type'] = block_type setAllObjsByType(context, object, b_4) - # object['block_type'] = block_type - # object['node_radius'] = mytool.Radius - # object['add_name'] = mytool.addBlockName4_string - # object['add_name1'] = mytool.addBlockName_string bpy.context.scene.objects.link(object) elif block_type == 5: @@ -668,9 +656,6 @@ def execute(self, context): object.location=cursor_pos #(0.0,0.0,0.0) object['block_type'] = block_type setAllObjsByType(context, object, b_5) - # object['block_type'] = block_type - # object['node_radius'] = mytool.Radius - # object['add_name'] = mytool.addBlockName_string bpy.context.scene.objects.link(object) elif block_type == 6: @@ -706,9 +691,6 @@ def execute(self, context): object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_10) - # object['block_type'] = block_type - # object['node_radius'] = mytool.Radius - # object['lod_distance'] = mytool.LOD_Distance bpy.context.scene.objects.link(object) elif block_type == 11: @@ -723,10 +705,6 @@ def execute(self, context): object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_12) - # object['block_type'] = block_type - # object['pos'] = 1 - # object['height'] = mytool.CH - # object['CType'] = int(mytool.CollisionType_enum) bpy.context.scene.objects.link(object) elif block_type == 13: @@ -734,22 +712,6 @@ def execute(self, context): object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_13) - # object['block_type'] = block_type - # if mytool.triggerType_enum == "loader": - # object['type'] = "loader" - # object['route_name'] = mytool.routeName_string - # if mytool.triggerType_enum == "radar0": - # object['type'] = "radar0" - # object['var0'] = 30 - # object['var1'] = 3005 - # object['var2'] = 4 - # object['speed_limit'] = mytool.speed_limit - # if mytool.triggerType_enum == "radar1": - # object['type'] = "radar1" - # object['var0'] = 30 - # object['var1'] = -1 - # object['var2'] = 4 - # object['speed_limit'] = mytool.speed_limit bpy.context.scene.objects.link(object) elif block_type == 14: @@ -757,33 +719,6 @@ def execute(self, context): object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_14) - # if mytool.T14_enum == "car": - # object['var0'] = 0 - # object['var1'] = mytool.Radius - # object['var2'] = mytool.Radius/2 - # object['var3'] = 10 - # object['var4'] = 18 - # elif mytool.T14_enum == "trl": - # object['var0'] = 0 - # object['var1'] = mytool.Radius - # object['var2'] = mytool.Radius/2 - # object['var3'] = 16 - # object['var4'] = 25 - - # elif mytool.T14_enum == "trl_cyc": - # object['var0'] = 0 - # object['var1'] = mytool.Radius - # object['var2'] = mytool.Radius/2 - # object['var3'] = 18 - # object['var4'] = 25 - - # elif mytool.T14_enum == "clk": - # object['var0'] = 0 - # object['var1'] = mytool.Radius * 0.08 - # object['var2'] = mytool.Radius * 0.51 - # object['var3'] = mytool.Radius - # object['var4'] = 0 - # bpy.context.scene.objects.link(object) elif block_type == 15: object = bpy.data.objects.new(object_name, None) @@ -811,9 +746,6 @@ def execute(self, context): object['block_type'] = block_type object.location=cursor_pos setAllObjsByType(context, object, b_18) - # object['node_radius'] = mytool.Radius - # object['add_name'] = mytool.addBlockName_string - # object['space_name'] = mytool.addSpaceName_string bpy.context.scene.objects.link(object) elif block_type == 19: @@ -840,34 +772,13 @@ def execute(self, context): object.location = (0,0,0) object['block_type'] = block_type setAllObjsByType(context, object, b_20) - #object = bpy.context.selected_objects[0] context.scene.objects.link(object) - # object.name = mytool.BlockName_string elif block_type == 21: - # if mytool.Refer_bool is False: - # object_name = mytool.Type21_enum - # else: - # object_name = 'refer_' + mytool.Type21_enum - # object = bpy.data.objects.new(object_name, None) - # object['node_radius'] = mytool.Radius - # object['groups_num'] = mytool.groupsNum_int object['block_type'] = block_type object.location=cursor_pos setAllObjsByType(context, object, b_20) bpy.context.scene.objects.link(object) - # for i in range(mytool.groupsNum_int): - # group = bpy.data.objects.new((mytool.addGroupName_string + str(i)), None) - # group['block_type'] = 5 - # group['node_radius'] = mytool.Radius - # group['add_name'] = "" - # bpy.context.scene.objects.link(group) - # group.parent = object - # if (i < mytool.groupsNum_int - 1): - # separator = bpy.data.objects.new((mytool.addGroupName_string + str(i) + "_444"), None) - # separator['block_type'] = 444 - # bpy.context.scene.objects.link(separator) - # separator.parent = object elif block_type == 22: object = bpy.data.objects.new(object_name, None) @@ -884,24 +795,17 @@ def execute(self, context): bpy.context.scene.objects.link(object) elif block_type == 24: - # object = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, location=(0.0,0.0,0.0)) - # object = bpy.context.selected_objects[0] object = bpy.data.objects.new(object_name, None) object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_24) bpy.context.scene.objects.link(object) - # object['flag'] = int(mytool.add24Flag_enum) - # object.name = mytool.BlockName_string elif block_type == 25: object = bpy.data.objects.new(object_name, None) object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_25) - # object['sound_name'] = mytool.addSoundName_string - # object['RSound'] = mytool.RSound - # object['SLevel'] = mytool.SLevel bpy.context.scene.objects.link(object) elif block_type == 26: @@ -923,9 +827,6 @@ def execute(self, context): object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_28) - # object['node_radius'] = mytool.Radius - # object['sprite_radius'] = mytool.T28_radius - # object['texNum'] = mytool.texNum_int bpy.context.scene.objects.link(object) elif block_type == 29: @@ -936,43 +837,10 @@ def execute(self, context): bpy.context.scene.objects.link(object) elif block_type == 30: - # object_name = mytool.BlockName_string - - # myvertex = [] - # myfaces = [] - - # mypoint = [(0, -20, 0)] - # myvertex.extend(mypoint) - - # mypoint = [(0, -20, 100)] - # myvertex.extend(mypoint) - - # mypoint = [(0, 20, 100)] - # myvertex.extend(mypoint) - - # mypoint = [(0, 20, 0)] - # myvertex.extend(mypoint) - - # myface = [(0, 1, 2, 3)] - # myfaces.extend(myface) - - - # mymesh = bpy.data.meshes.new(object_name) - - # bpy.context.scene.objects.link(object) - - - # mymesh.from_pydata(myvertex, [], myfaces) - - # mymesh.update(calc_edges=True) - object = bpy.data.objects.new(object_name, None) - object.location=cursor_pos object['block_type'] = block_type setAllObjsByType(context, object, b_30) - # object['radius'] = mytool.Radius - # object['room_name'] = mytool.addRoomName_string bpy.context.scene.objects.link(object) elif block_type == 31: @@ -987,14 +855,6 @@ def execute(self, context): object = bpy.data.objects.new(object_name, None) object.location=cursor_pos setAllObjsByType(context, object, b_33) - # object['block_type'] = block_type - # object['node_radius'] = mytool.Radius - # object['light_radius'] = mytool.RadiusLight - # object['light_type'] = int(mytool.LType_enum) - # object['intensity'] = mytool.Intensity - # object['R'] = mytool.R / 255 - # object['G'] = mytool.G / 255 - # object['B'] = mytool.B / 255 bpy.context.scene.objects.link(object) elif block_type == 34: @@ -1038,37 +898,6 @@ def execute(self, context): object['block_type'] = block_type setAllObjsByType(context, object, b_40) bpy.context.scene.objects.link(object) - # if mytool.generatorType_enum == "$$TreeGenerator1": - # point = bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, calc_uvs=True, enter_editmode=True, location=(0.0,0.0,0.0)) - # mesh0 = bpy.ops.mesh.primitive_cone_add(vertices=12, radius1=0.5, radius2=0.0, depth=1.0, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 1.0)) - # mesh1 = bpy.ops.mesh.primitive_cone_add(vertices=12, radius1=0.3, radius2=0.0, depth=0.6, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 1.4)) - # tree = bpy.ops.mesh.primitive_cylinder_add(vertices=12, radius=0.05, depth=0.5, end_fill_type='NGON', calc_uvs=True, enter_editmode=True, location=(0.0, 0.0, 0.25)) - # object = bpy.context.selected_objects[0] - # object['block_type'] = block_type - # object['scale'] = mytool.Scale - # object['TGType'] = mytool.TGType_int - # object['GType'] = mytool.generatorType_enum - # object.name = mytool.BlockName_string - # bpy.ops.object.mode_set(mode = 'OBJECT') - # object.location = bpy.context.scene.cursor_location - - # if mytool.generatorType_enum == "$$DynamicGlow": - # object = bpy.data.objects.new(object_name, None) - # object.location=cursor_pos - - # object['block_type'] = block_type - # object['node_radius'] = mytool.Radius - # object['scale'] = mytool.Scale - # object['mat_name'] = mytool.materialName_string - # object['GType'] = mytool.generatorType_enum - # object.name = mytool.BlockName_string - # bpy.context.scene.objects.link(object) - - # if block_type == 444: - # object = bpy.data.objects.new(object_name, None) - # object['block_type'] = 444 - # object.location=(0.0,0.0,0.0) - # bpy.context.scene.objects.link(object) return {'FINISHED'} class GetVertexValuesOperator(bpy.types.Operator): @@ -1116,172 +945,10 @@ def execute(self, context): object = bpy.context.object block_type = object['block_type'] - if block_type == 1: - getAllObjsByType(context, object, b_1) - - elif block_type == 2: - getAllObjsByType(context, object, b_2) - - elif block_type == 3: - getAllObjsByType(context, object, b_3) - - elif block_type == 4: - getAllObjsByType(context, object, b_4) - - elif block_type == 5: - # for f in block_5.__dict__['__annotations__'].keys(): - # mytool.block_5[f] = object[f] - getAllObjsByType(context, object, b_5) - # mytool.block_5[prop(b_5.Name1)] = object[prop(b_5.Name1)] - # mytool.block_5[prop(b_5.XYZ)] = object[prop(b_5.XYZ)] - # mytool.block_5[prop(b_5.R)] = object[prop(b_5.R)] - - elif block_type == 6: - getAllObjsByType(context, object, b_6) - - elif block_type == 7: - getAllObjsByType(context, object, b_7) - # if 'BType' in object: - # mytool.Faces_enum = str(object['BType']) - # else: - # mytool.Faces_enum = str(35) - # object['BType'] = 35 - # if "type1" in object: - # mytool.addBlockMeshType_enum = str(object['type1']) - # else: - # object['type1'] = "manual" - # mytool.addBlockMeshType_enum = str(object['type1']) - # mytool.MType_enum = str(object['MType']) - # mytool.FType_enum = str(object['FType']) - # mytool.texNum_int = object['texNum'] - - elif block_type == 8: - getAllObjsByType(context, object, b_8) - - elif block_type == 9: - getAllObjsByType(context, object, b_9) - - elif block_type == 10: - getAllObjsByType(context, object, b_10) - # mytool.Radius1 = object['node_radius'] - # mytool.LOD_Distance1 = object['lod_distance'] - - elif block_type == 11: - getAllObjsByType(context, object, b_11) - - elif block_type == 12: - getAllObjsByType(context, object, b_12) - # mytool.CH1 = object['height'] - # mytool.CollisionType_enum = object['CType'] - - elif block_type == 13: - getAllObjsByType(context, object, b_13) - - elif block_type == 14: - getAllObjsByType(context, object, b_14) - - elif block_type == 15: - getAllObjsByType(context, object, b_15) - - elif block_type == 16: - getAllObjsByType(context, object, b_16) - - elif block_type == 17: - getAllObjsByType(context, object, b_17) - - elif block_type == 18: - getAllObjsByType(context, object, b_18) - # mytool.Radius1 = object['node_radius'] - # mytool.addBlockName1_string = object['add_name'] - # mytool.addSpaceName1_string = object['space_name'] - - elif block_type == 20: - getAllObjsByType(context, object, b_20) - - elif block_type == 21: - getAllObjsByType(context, object, b_21) - # mytool.groupsNum1_int = object['groups_num'] - # mytool.Radius1 = object['node_radius'] - - elif block_type == 22: - getAllObjsByType(context, object, b_22) - - elif block_type == 23: - getAllObjsByType(context, object, b_23) - # mytool.CollisionType_enum = str(object['CType']) - - elif block_type == 24: - getAllObjsByType(context, object, b_24) - # mytool.add24Flag_enum1 = str(object['flag']) - - elif block_type == 25: - getAllObjsByType(context, object, b_25) - # mytool.RSound1 = (object['RSound']) - # mytool.addSoundName1_string = object['sound_name'] - # mytool.SLevel1 = (object['SLevel']) - - elif block_type == 26: - getAllObjsByType(context, object, b_26) - - elif block_type == 27: - getAllObjsByType(context, object, b_27) - - elif block_type == 28: - getAllObjsByType(context, object, b_28) - # mytool.texNum_int = object['texNum'] - # mytool.T28_radius1 = object['sprite_radius'] - - elif block_type == 29: - getAllObjsByType(context, object, b_29) - - elif block_type == 30: - getAllObjsByType(context, object, b_30) + zclass = getClassDefByType(block_type) - elif block_type == 31: - getAllObjsByType(context, object, b_31) - - elif block_type == 33: - getAllObjsByType(context, object, b_33) - # mytool.Radius1 = object['node_radius'] - # mytool.LType_enum = str(object['light_type']) - # mytool.RadiusLight1 = object['light_radius'] - # mytool.Intensity1 = object['intensity'] - # mytool.R1 = object['R'] * 255 - # mytool.G1 = object['G'] * 255 - # mytool.B1 = object['B'] * 255 - - elif block_type == 34: - getAllObjsByType(context, object, b_34) - - elif block_type == 35: - getAllObjsByType(context, object, b_35) - - elif block_type == 36: - getAllObjsByType(context, object, b_36) - - elif block_type == 37: - getAllObjsByType(context, object, b_37) - # if 'BType' in object: - # mytool.Faces_enum = str(object['BType']) - # else: - # mytool.Faces_enum = str(35) - # object['BType'] = 35 - # if "type1" in object: - # mytool.addBlockMeshType_enum = str(object['type1']) - # else: - # object['type1'] = "manual" - # mytool.addBlockMeshType_enum = str(object['type1']) - # #mytool.addMeshType_enum = str(object['type2']) - # mytool.SType_enum = str(object['SType']) - # mytool.MType_enum = str(object['MType']) - # mytool.FType_enum = str(object['FType']) - # mytool.texNum_int = object['texNum'] - - elif block_type == 39: - getAllObjsByType(context, object, b_39) - - elif block_type == 40: - getAllObjsByType(context, object, b_40) + if zclass is not None: + getAllObjsByType(context, object, zclass) return {'FINISHED'} @@ -1356,155 +1023,10 @@ def execute(self, context): object['block_type'] = block_type - if block_type == 1: - setAllObjsByType(context, object, b_1) - - elif block_type == 2: - setAllObjsByType(context, object, b_2) - - elif block_type == 3: - setAllObjsByType(context, object, b_3) - - elif block_type == 4: - setAllObjsByType(context, object, b_4) - - elif block_type == 5: - setAllObjsByType(context, object, b_5) - # object['add_name'] = mytool.addBlockName1_string - # object['node_radius'] = mytool.Radius1 - - elif block_type == 6: - setAllObjsByType(context, object, b_6) - - - elif block_type == 7: - setAllObjsByType(context, object, b_7) - # object['type1'] = str(mytool.addBlockMeshType_enum) - # object['BType'] = int(mytool.Faces_enum) - # object['FType'] = int(mytool.FType_enum) - # object['MType'] = int(mytool.MType_enum) - # object['texNum'] = int(mytool.texNum_int) - - elif block_type == 8: - setAllObjsByType(context, object, b_8) - - elif block_type == 9: - setAllObjsByType(context, object, b_9) - - elif block_type == 10: - setAllObjsByType(context, object, b_10) - # object['node_radius'] = mytool.Radius1 - # object['lod_distance'] = mytool.LOD_Distance1 - - elif block_type == 11: - setAllObjsByType(context, object, b_11) - - elif block_type == 12: - setAllObjsByType(context, object, b_12) - # object['height'] = mytool.CH1 - # object['CType'] = int(mytool.CollisionType_enum) - - elif block_type == 13: - setAllObjsByType(context, object, b_13) + zclass = getClassDefByType(block_type) - elif block_type == 14: - setAllObjsByType(context, object, b_14) - - elif block_type == 15: - setAllObjsByType(context, object, b_15) - - elif block_type == 16: - setAllObjsByType(context, object, b_16) - - elif block_type == 17: - setAllObjsByType(context, object, b_17) - - elif block_type == 18: - setAllObjsByType(context, object, b_18) - # object['node_radius'] = mytool.Radius1 - # object['add_name'] = mytool.addBlockName1_string - # object['space_name'] = mytool.addSpaceName1_string - - elif block_type == 20: - setAllObjsByType(context, object, b_20) - - elif block_type == 21: - setAllObjsByType(context, object, b_21) - # object['groups_num'] = mytool.groupsNum1_int - # object['node_radius'] = mytool.Radius1 - - elif block_type == 22: - setAllObjsByType(context, object, b_22) - - elif block_type == 23: - setAllObjsByType(context, object, b_23) - # object['CType'] = int(mytool.CollisionType_enum) - - elif block_type == 24: - setAllObjsByType(context, object, b_24) - # object['flag'] = int(mytool.add24Flag_enum1) - - elif block_type == 25: - setAllObjsByType(context, object, b_25) - # object['RSound'] = mytool.RSound1 - # object['sound_name'] = mytool.addSoundName1_string - # object['SLevel'] = mytool.SLevel1 - - elif block_type == 26: - setAllObjsByType(context, object, b_26) - - elif block_type == 27: - setAllObjsByType(context, object, b_27) - - elif block_type == 28: - setAllObjsByType(context, object, b_28) - # object['texNum'] = mytool.texNum_int - # object['node_radius'] = mytool.Radius1 - # object['sprite_radius'] = mytool.T28_radius1 - - elif block_type == 29: - setAllObjsByType(context, object, b_29) - - elif block_type == 30: - setAllObjsByType(context, object, b_30) - - elif block_type == 31: - setAllObjsByType(context, object, b_31) - - elif block_type == 33: - setAllObjsByType(context, object, b_33) - # object['node_radius'] = mytool.Radius1 - # object['light_type'] = int(mytool.LType_enum) - # object['light_radius'] = mytool.RadiusLight1 - # object['intensity'] = mytool.Intensity1 - object['R'] = mytool.R1 / 255 - object['G'] = mytool.G1 / 255 - object['B'] = mytool.B1 / 255 - - elif block_type == 34: - setAllObjsByType(context, object, b_34) - - elif block_type == 35: - setAllObjsByType(context, object, b_35) - - elif block_type == 36: - setAllObjsByType(context, object, b_36) - - elif block_type == 37: - setAllObjsByType(context, object, b_37) - # object['type1'] = str(mytool.addBlockMeshType_enum) - # # object['type2'] = str(mytool.addMeshType_enum) - # object['BType'] = int(mytool.Faces_enum) - # object['SType'] = int(mytool.SType_enum) - # object['MType'] = int(mytool.MType_enum) - # object['FType'] = int(mytool.FType_enum) - # object['texNum'] = int(mytool.texNum_int) - - elif block_type == 39: - setAllObjsByType(context, object, b_39) - - elif block_type == 40: - setAllObjsByType(context, object, b_40) + if zclass is not None: + setAllObjsByType(context, object, zclass) return {'FINISHED'} @@ -1731,7 +1253,6 @@ def execute(self, context): return {'FINISHED'} - class ShowConditionalsOperator(bpy.types.Operator): bl_idname = "wm.show_conditional_operator" bl_label = "Отобразить обьекты с условием" @@ -1837,6 +1358,26 @@ def type19(name): return {'FINISHED'} +class ShowSphereOperator(bpy.types.Operator): + bl_idname = "b3d.show_sphere_operator" + bl_label = "Показать/Скрыть сферу" + bl_description = "Показывает/скрывает сферу" + + pname: bpy.props.StringProperty() + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + obj = context.object + + showSphere(context, obj, self.pname) + + self.report({'INFO'}, "Sphere shown") + + return {'FINISHED'} + + # ------------------------------------------------------------------------ # panels # ------------------------------------------------------------------------ @@ -1868,244 +1409,10 @@ def draw(self, context): layout.prop(mytool, "addBlockType_enum", text="") layout.prop(mytool, "BlockName_string") - # if block_type == 6566754: - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - - # if block_type == 0: - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "addSpaceName_string") - - - if block_type == 1: - drawAllFieldsByType(self, context, b_1) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "addSpaceName_string") - # layout.prop(mytool, "routeName_string") + zclass = getClassDefByType(block_type) - elif block_type == 2: - drawAllFieldsByType(self, context, b_2) - - elif block_type == 3: - drawAllFieldsByType(self, context, b_3) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "Radius") - - elif block_type == 4: - drawAllFieldsByType(self, context, b_4) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "Radius") - # layout.prop(mytool, "addBlockName4_string") - # layout.prop(mytool, "addBlockName_string") - - elif block_type == 5: - drawAllFieldsByType(self, context, b_5) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "addBlockName_string") - # layout.prop(mytool, "Radius") - - elif block_type == 6: - drawAllFieldsByType(self, context, b_6) - - elif block_type == 7: - drawAllFieldsByType(self, context, b_7) - - elif block_type == 8: - drawAllFieldsByType(self, context, b_8) - - elif block_type == 9: - drawAllFieldsByType(self, context, b_9) - - elif block_type == 10: - drawAllFieldsByType(self, context, b_10) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "Radius") - # layout.prop(mytool, "LOD_Distance") - - elif block_type == 11: - drawAllFieldsByType(self, context, b_11) - - elif block_type == 12: - drawAllFieldsByType(self, context, b_12) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "CH") - # layout.prop(mytool, "CollisionType_enum") - - elif block_type == 13: - drawAllFieldsByType(self, context, b_13) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "triggerType_enum", text="") - # if mytool.triggerType_enum == "loader": - # layout.prop(mytool, "routeName_string") - # elif mytool.triggerType_enum == "radar0" or "radar1": - # layout.prop(mytool, "speed_limit") - - elif block_type == 14: - drawAllFieldsByType(self, context, b_14) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # self.layout.label(text="Вариант преднастроек:") - # layout.prop(mytool, "T14_enum", text="") - # layout.prop(mytool, "Radius") - - elif block_type == 15: - drawAllFieldsByType(self, context, b_15) - - elif block_type == 16: - drawAllFieldsByType(self, context, b_16) - - elif block_type == 17: - drawAllFieldsByType(self, context, b_17) - - elif block_type == 18: - drawAllFieldsByType(self, context, b_18) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "Radius") - # layout.prop(mytool, "addBlockName_string") - # layout.prop(mytool, "addSpaceName_string") - - elif block_type == 19: - pass - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - - elif block_type == 20: - drawAllFieldsByType(self, context, b_20) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - - elif block_type == 21: - drawAllFieldsByType(self, context, b_21) - # self.layout.label(text="Имя блока:") - # layout.prop(mytool, "Type21_enum", text="") - # layout.prop(mytool, "Refer_bool") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "Radius") - # layout.prop(mytool, "groupsNum_int") - # layout.prop(mytool, "addGroupName_string") - - elif block_type == 22: - drawAllFieldsByType(self, context, b_22) - - elif block_type == 23: - drawAllFieldsByType(self, context, b_23) - - elif block_type == 24: - drawAllFieldsByType(self, context, b_24) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # self.layout.label(text="Флаг:") - # layout.prop(mytool, "add24Flag_enum", text="") - - elif block_type == 25: - drawAllFieldsByType(self, context, b_25) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "addSoundName_string") - # layout.prop(mytool, "RSound") - # layout.prop(mytool, "SLevel") - - elif block_type == 26: - drawAllFieldsByType(self, context, b_26) - - elif block_type == 27: - drawAllFieldsByType(self, context, b_27) - - elif block_type == 28: - drawAllFieldsByType(self, context, b_28) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "Radius") - # layout.prop(mytool, "T28_radius") - # layout.prop(mytool, "texNum_int") - - elif block_type == 29: - drawAllFieldsByType(self, context, b_29) - - elif block_type == 30: - drawAllFieldsByType(self, context, b_30) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "Radius") - # layout.prop(mytool, "addRoomName_string") - - elif block_type == 31: - drawAllFieldsByType(self, context, b_31) - - elif block_type == 33: - drawAllFieldsByType(self, context, b_33) - # layout.prop(mytool, "BlockName_string") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # layout.prop(mytool, "LType_enum") - # layout.prop(mytool, "Radius") - # layout.prop(mytool, "RadiusLight") - # layout.prop(mytool, "Intensity") - # layout.prop(mytool, "R") - # layout.prop(mytool, "G") - # layout.prop(mytool, "B") - - elif block_type == 34: - drawAllFieldsByType(self, context, b_34) - - elif block_type == 35: - drawAllFieldsByType(self, context, b_35) - - elif block_type == 36: - drawAllFieldsByType(self, context, b_36) - - elif block_type == 37: - drawAllFieldsByType(self, context, b_37) - - elif block_type == 39: - drawAllFieldsByType(self, context, b_39) - - elif block_type == 40: - drawAllFieldsByType(self, context, b_40) - # layout.prop(mytool, "BlockName_string") - # layout.prop(mytool, "Radius") - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") - # self.layout.label(text="Тип генератора:") - # layout.prop(mytool, "generatorType_enum", text="") - # if mytool.generatorType_enum == "$$TreeGenerator1": - # layout.prop(mytool, "TGType_int") - # layout.prop(mytool, "Scale") - # if mytool.generatorType_enum == "$$DynamicGlow": - # layout.prop(mytool, "materialName_string") - # layout.prop(mytool, "Scale") - # else: - # self.layout.label(text="Данный тип генератора не поддерживается.") - - # elif block_type == 444: - # self.layout.label(text="Тип блока:") - # layout.prop(mytool, "addBlockType_enum", text="") + if zclass is not None: + drawAllFieldsByType(self, context, zclass) layout.operator("wm.add_operator") @@ -2201,7 +1508,6 @@ def draw(self, context): if object is not None: drawCommon(self, object) - class OBJECT_PT_b3d_pob_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pob_edit_panel" bl_label = "Параметры обьекта" @@ -2242,235 +1548,18 @@ def draw(self, context): lenStr = str(len(object.children)) - if block_type == 0: - pass - - elif block_type == 1: - drawAllFieldsByType(self, context, b_1) - - elif block_type == 2: - drawAllFieldsByType(self, context, b_2) - - elif block_type == 3: - drawAllFieldsByType(self, context, b_3) - - elif block_type == 4: - drawAllFieldsByType(self, context, b_4) - - elif block_type == 5: - drawAllFieldsByType(self, context, b_5) - # layout.prop(getattr(mytool, 'block5'), "name1") - # layout.prop(mytool.block5, "XYZ") - # layout.prop(mytool.block5, "R") - # if 'add_name' in object: - # pass - # else: - # self.layout.label(text="Имя присоединённого блока не указано. Сохраните настройки,") - # self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 6: - drawAllFieldsByType(self, context, b_6) - - elif block_type == 7: - drawAllFieldsByType(self, context, b_7) - # if 'texNum' in object: - # layout.prop(mytool, "addBlockMeshType_enum") - - # if (mytool.addBlockMeshType_enum) == "auto": - # layout.prop(mytool, "FType_enum") - # layout.prop(mytool, "MType_enum") - # else: - # layout.prop(mytool, "Faces_enum") - # if int(mytool.Faces_enum) == 35: - # layout.prop(mytool, "MType_enum") - # else: - # layout.prop(mytool, "FType_enum") - - # layout.prop(mytool, "texNum_int") - # else: - # self.layout.label(text="Указаны не все атрибуты объекта.") - # self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 8: - drawAllFieldsByType(self, context, b_8) - - elif block_type == 9: - drawAllFieldsByType(self, context, b_9) - - elif block_type == 10: - drawAllFieldsByType(self, context, b_10) - # if 'node_radius' in object: - # layout.prop(mytool, "Radius1") - # layout.prop(mytool, "LOD_Distance1") - # else: - # self.layout.label(text="Указаны не все атрибуты объекта.") - # self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 11: - drawAllFieldsByType(self, context, b_11) - - elif block_type == 12: - drawAllFieldsByType(self, context, b_12) - # if 'CType' in object: - # self.layout.label(text="Тип коллизии:") - # layout.prop(mytool, "CollisionType_enum", text="") - # layout.prop(mytool, "CH1") - # else: - # self.layout.label(text="Тип коллизии не указан. Сохраните настройки,") - # self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 13: - drawAllFieldsByType(self, context, b_13) - - elif block_type == 14: - drawAllFieldsByType(self, context, b_14) - - elif block_type == 15: - drawAllFieldsByType(self, context, b_15) - - elif block_type == 16: - drawAllFieldsByType(self, context, b_16) - - elif block_type == 17: - drawAllFieldsByType(self, context, b_17) - - elif block_type == 18: - drawAllFieldsByType(self, context, b_18) - # if 'add_name' in object: - # layout.prop(mytool, "Radius1") - # layout.prop(mytool, "addBlockName1_string") - # layout.prop(mytool, "addSpaceName1_string") - # else: - # self.layout.label(text="Указаны не все атрибуты объекта.") - # self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 19: - pass - - elif block_type == 20: - drawAllFieldsByType(self, context, b_20) - - elif block_type == 21: - drawAllFieldsByType(self, context, b_21) - # if 'groups_num' in object: - # layout.prop(mytool, "groupsNum1_int") - # layout.prop(mytool, "Radius1") - # else: - # self.layout.label(text="Кол-во групп не указано. Сохраните настройки,") - # self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 23: - drawAllFieldsByType(self, context, b_23) - # if 'CType' in object: - # self.layout.label(text="Тип коллизии:") - # layout.prop(mytool, "CollisionType_enum", text="") - # else: - # self.layout.label(text="Тип коллизии не указан. Сохраните настройки,") - # self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 24: - drawAllFieldsByType(self, context, b_24) - # if 'flag' in object: - # layout.prop(mytool, "add24Flag_enum1", text="") - # else: - # self.layout.label(text="Флаг блока не указан. Сохраните настройки,") - # self.layout.label(text="а затем попробуйте выделить блок заново.") - - elif block_type == 25: - drawAllFieldsByType(self, context, b_25) - # if 'RSound' in object: - # layout.prop(mytool, "addSoundName1_string") - # layout.prop(mytool, "RSound1") - # layout.prop(mytool, "SLevel1") - # else: - # self.layout.label(text="Указаны не все атрибуты объекта.") - # self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 26: - drawAllFieldsByType(self, context, b_26) - - elif block_type == 27: - drawAllFieldsByType(self, context, b_27) + zclass = getClassDefByType(block_type) - elif block_type == 28: - drawAllFieldsByType(self, context, b_28) - # if 'sprite_radius' in object: - # layout.prop(mytool, "Radius1") - # layout.prop(mytool, "T28_radius1") - # layout.prop(mytool, "texNum_int") - # else: - # self.layout.label(text="Указаны не все атрибуты объекта.") - # self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 29: - drawAllFieldsByType(self, context, b_29) - - elif block_type == 30: - drawAllFieldsByType(self, context, b_30) - - elif block_type == 31: - drawAllFieldsByType(self, context, b_31) - - elif block_type == 33: - drawAllFieldsByType(self, context, b_33) - # layout.prop(mytool, "Radius1") - # layout.prop(mytool, "LType_enum") - # layout.prop(mytool, "RadiusLight1") - # layout.prop(mytool, "Intensity1") - # layout.prop(mytool, "R1") - # layout.prop(mytool, "G1") - # layout.prop(mytool, "B1") - - elif block_type == 34: - drawAllFieldsByType(self, context, b_34) + layout.operator("wm.get_block_values_operator") + layout.operator("wm.set_block_values_operator") - elif block_type == 35: - drawAllFieldsByType(self, context, b_35) - - elif block_type == 36: - drawAllFieldsByType(self, context, b_36) - - elif block_type == 37: - drawAllFieldsByType(self, context, b_37) - # if 'texNum' in object: - # layout.prop(mytool, "addBlockMeshType_enum") - - # if (mytool.addBlockMeshType_enum) == "auto": - # layout.prop(mytool, "SType_enum") - # #layout.prop(mytool, "FType_enum") - # #layout.prop(mytool, "addMeshType_enum") - # layout.prop(mytool, "FType_enum") - # layout.prop(mytool, "MType_enum") - # else: - # layout.prop(mytool, "Faces_enum") - # if int(mytool.Faces_enum) == 35: - # layout.prop(mytool, "MType_enum") - # layout.prop(mytool, "SType_enum") - # else: - # layout.prop(mytool, "SType_enum") - # layout.prop(mytool, "FType_enum") - - # layout.prop(mytool, "texNum_int") - # else: - # self.layout.label(text="Указаны не все атрибуты объекта.") - # self.layout.label(text="Сохраните настройки, а затем попробуйте выделить блок заново.") - - elif block_type == 39: - drawAllFieldsByType(self, context, b_39) - - elif block_type == 40: - drawAllFieldsByType(self, context, b_40) - # self.layout.label(text="Тип генератора: " + object['GType']) - - # elif block_type == 444: - # self.layout.label(text="Тип объекта - разделитель") + if zclass is not None: + drawAllFieldsByType(self, context, zclass) - else: - self.layout.label(text="Выбранный объект не имеет типа.") - self.layout.label(text="Чтобы указать его, нажмите на кнопку сохранения настроек.") + # else: + # self.layout.label(text="Выбранный объект не имеет типа.") + # self.layout.label(text="Чтобы указать его, нажмите на кнопку сохранения настроек.") - layout.operator("wm.get_block_values_operator") - layout.operator("wm.set_block_values_operator") layout.operator("wm.del_block_values_operator") layout.operator("wm.fix_uv_operator") layout.operator("wm.fix_verts_operator") @@ -2538,7 +1627,6 @@ def draw(self, context): oper = box.operator("wm.hide_conditional_operator") oper.group = getattr(mytool, 'conditionGroup') - class OBJECT_PT_b3d_res_module_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_res_module_panel" bl_label = "Игровые ресурсы" @@ -2631,7 +1719,6 @@ def draw(self, context): col.enabled = curMaskfile.is_someint - class OBJECT_PT_b3d_textures_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_textures_panel" bl_label = "Текстуры" @@ -2874,9 +1961,6 @@ def draw(self, context): box.prop(curMaterial, "is_usecol", text="UseCol") box.prop(curMaterial, "is_wave", text="Wave") - - - class OBJECT_PT_b3d_misc_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_misc_panel" bl_label = "О плагине" @@ -2924,6 +2008,8 @@ def draw(self, context): ShowConditionalsOperator, HideConditionalsOperator, AddBlocksOperator, + ShowSphereOperator, + OBJECT_PT_b3d_add_panel, OBJECT_PT_b3d_edit_panel, OBJECT_PT_b3d_pob_edit_panel, diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index 2c1c4cc..b60b7c4 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -19,6 +19,7 @@ isMeshBlock, getRootObj, getAllChildren, + getMytoolBlockNameByClass, getMytoolBlockName ) from .class_descr import ( @@ -416,6 +417,66 @@ def hideConditionals(root, group): else: processCond(root, group, True) +def createCenterDriver(srcObj, bname, pname): + d = None + for i in range(3): + + d = srcObj.driver_add('location', i).driver + + v = d.variables.new() + v.name = 'location{}'.format(i) + v.targets[0].id_type = 'SCENE' + v.targets[0].id = bpy.context.scene + v.targets[0].data_path = 'my_tool.{}.{}[{}]'.format(bname, pname, i) + + d.expression = v.name + +def createRadDriver(srcObj, bname, pname): + d = srcObj.driver_add('empty_display_size').driver + + v1 = d.variables.new() + v1.name = 'rad' + v1.targets[0].id_type = 'SCENE' + v1.targets[0].id = bpy.context.scene + v1.targets[0].data_path = 'my_tool.{}.{}'.format(bname, pname) + + d.expression = v1.name + +def showSphere(context, root, pname): + + objName = "{}||{}||{}".format(root.name, pname, 'temp') + + b3dObj = bpy.data.objects.get(objName) + + if b3dObj is not None: + bpy.data.objects.remove(b3dObj, do_unlink=True) + else: + + bnum = root.get('block_type') + + centerName = "{}_center".format(pname) + radName = "{}_rad".format(pname) + + center = root.get(centerName) + rad = root.get(radName) + + # creating object + + b3dObj = bpy.data.objects.new(objName, None) + b3dObj.empty_display_type = 'SPHERE' + b3dObj.empty_display_size = rad + b3dObj.location = center + b3dObj.parent = root.parent + + context.collection.objects.link(b3dObj) + + # center driver + bname = getMytoolBlockName('b', bnum) + + createCenterDriver(b3dObj, bname, centerName) + + # rad driver + createRadDriver(b3dObj, bname, radName) def drawCommon(l_self, obj): block_type = None @@ -451,14 +512,21 @@ def drawFieldsByType(l_self, context, zclass): def drawFieldByType(l_self, context, obj, zclass): - bname, bnum = getMytoolBlockName(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass) ftype = obj['type'] subtype = obj.get('subtype') pname = obj['prop'] mytool = context.scene.my_tool - if ftype == fieldType.STRING \ + if ftype == fieldType.SPHERE_EDIT: + box = l_self.layout.box() + col = box.column() + + props = col.operator("b3d.show_sphere_operator") + props.pname = pname + + elif ftype == fieldType.STRING \ or ftype == fieldType.COORD \ or ftype == fieldType.RAD \ or ftype == fieldType.INT \ @@ -580,7 +648,7 @@ def getAllObjsByType(context, object, zclass): def getObjsByType(context, object, zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockName(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass) # btype = zclass.__name__.split('_')[1] # bname = "block{}".format(btype) @@ -589,59 +657,59 @@ def getObjsByType(context, object, zclass): obj = zclass.__dict__[property] # print(dir(getattr(mytool, bname))) + if obj['type'] != fieldType.SPHERE_EDIT: + if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + and getattr(getattr(mytool, bname), "show_"+obj['prop']): + + if obj['type'] == fieldType.FLOAT \ + or obj['type'] == fieldType.RAD: + setattr( + getattr(mytool, bname), + obj['prop'], + float(object[obj['prop']]) + ) + + elif obj['type'] == fieldType.INT: + setattr( + getattr(mytool, bname), + obj['prop'], + int(object[obj['prop']]) + ) + + elif obj['type'] == fieldType.STRING: + getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) + + elif obj['type'] == fieldType.ENUM \ + or obj['type'] == fieldType.ENUM_STR: + # if obj['subtype'] == fieldType.INT \ + # or obj['subtype'] == fieldType.STRING \ + # or obj['subtype'] == fieldType.FLOAT \ + # or obj['subtype'] == fieldType.SPACE_NAME \ + # or obj['subtype'] == fieldType.REFERENCEABLE \ + # or obj['subtype'] == fieldType.MATERIAL_IND: + setattr( + getattr(mytool, bname), + obj['prop'], + str(object[obj['prop']]) + ) + + elif obj['type'] == fieldType.LIST: + + col = getattr(getattr(mytool, bname), obj['prop']) + + col.clear() + for i, obj in enumerate(object[obj['prop']]): + item = col.add() + item.index = i + item.value = obj + # getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) - if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ - and getattr(getattr(mytool, bname), "show_"+obj['prop']): - - if obj['type'] == fieldType.FLOAT \ - or obj['type'] == fieldType.RAD: - setattr( - getattr(mytool, bname), - obj['prop'], - float(object[obj['prop']]) - ) - - elif obj['type'] == fieldType.INT: - setattr( - getattr(mytool, bname), - obj['prop'], - int(object[obj['prop']]) - ) - - elif obj['type'] == fieldType.STRING: - getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) - - elif obj['type'] == fieldType.ENUM \ - or obj['type'] == fieldType.ENUM_STR: - # if obj['subtype'] == fieldType.INT \ - # or obj['subtype'] == fieldType.STRING \ - # or obj['subtype'] == fieldType.FLOAT \ - # or obj['subtype'] == fieldType.SPACE_NAME \ - # or obj['subtype'] == fieldType.REFERENCEABLE \ - # or obj['subtype'] == fieldType.MATERIAL_IND: - setattr( - getattr(mytool, bname), - obj['prop'], - str(object[obj['prop']]) - ) - - elif obj['type'] == fieldType.LIST: - - col = getattr(getattr(mytool, bname), obj['prop']) - - col.clear() - for i, obj in enumerate(object[obj['prop']]): - item = col.add() - item.index = i - item.value = obj - # getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) - - else: - setattr( - getattr(mytool, bname), - obj['prop'], - object[obj['prop']] - ) + else: + setattr( + getattr(mytool, bname), + obj['prop'], + object[obj['prop']] + ) def setAllObjsByType(context, object, zclass): setObjsByType(context, object, b_common) @@ -650,60 +718,61 @@ def setAllObjsByType(context, object, zclass): def setObjsByType(context, object, zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockName(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass) # btype = zclass.__name__.split('_')[1] # bname = "block{}".format(btype) mytool = context.scene.my_tool for property in attrs: obj = zclass.__dict__[property] - if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ - and getattr(getattr(mytool, bname), "show_"+obj['prop']): + if obj['type'] != fieldType.SPHERE_EDIT: + if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + and getattr(getattr(mytool, bname), "show_"+obj['prop']): - if obj['type'] == fieldType.FLOAT or obj['type'] == fieldType.RAD: - object[obj['prop']] = float(getattr(getattr(mytool, bname), obj['prop'])) + if obj['type'] == fieldType.FLOAT or obj['type'] == fieldType.RAD: + object[obj['prop']] = float(getattr(getattr(mytool, bname), obj['prop'])) - elif obj['type'] == fieldType.INT: - object[obj['prop']] = int(getattr(getattr(mytool, bname), obj['prop'])) + elif obj['type'] == fieldType.INT: + object[obj['prop']] = int(getattr(getattr(mytool, bname), obj['prop'])) - # elif obj['type'] == fieldType.MATERIAL_IND: - # object[obj['prop']] = int(getattr(getattr(mytool, bname), obj['prop'])) + # elif obj['type'] == fieldType.MATERIAL_IND: + # object[obj['prop']] = int(getattr(getattr(mytool, bname), obj['prop'])) - elif obj['type'] == fieldType.STRING: - object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) + elif obj['type'] == fieldType.STRING: + object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) - # elif obj['type'] == fieldType.SPACE_NAME \ - # or obj['type'] == fieldType.REFERENCEABLE: - # object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) + # elif obj['type'] == fieldType.SPACE_NAME \ + # or obj['type'] == fieldType.REFERENCEABLE: + # object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) - elif obj['type'] == fieldType.ENUM: + elif obj['type'] == fieldType.ENUM: - if obj['subtype'] == fieldType.INT: - object[obj['prop']] = int(getattr(getattr(mytool, bname), obj['prop'])) + if obj['subtype'] == fieldType.INT: + object[obj['prop']] = int(getattr(getattr(mytool, bname), obj['prop'])) - elif obj['subtype'] == fieldType.STRING: - object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) + elif obj['subtype'] == fieldType.STRING: + object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) - elif obj['subtype'] == fieldType.FLOAT: - object[obj['prop']] = float(getattr(getattr(mytool, bname), obj['prop'])) + elif obj['subtype'] == fieldType.FLOAT: + object[obj['prop']] = float(getattr(getattr(mytool, bname), obj['prop'])) - elif obj['type'] == fieldType.ENUM_STR: - object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) + elif obj['type'] == fieldType.ENUM_STR: + object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) - elif obj['type'] == fieldType.COORD: - xyz = getattr(getattr(mytool, bname), obj['prop']) - object[obj['prop']] = (xyz[0],xyz[1],xyz[2]) + elif obj['type'] == fieldType.COORD: + xyz = getattr(getattr(mytool, bname), obj['prop']) + object[obj['prop']] = (xyz[0],xyz[1],xyz[2]) - elif obj['type'] == fieldType.LIST: - collect = getattr(getattr(mytool, bname), obj['prop']) + elif obj['type'] == fieldType.LIST: + collect = getattr(getattr(mytool, bname), obj['prop']) - arr = [] - for item in list(collect): - arr.append(item.value) + arr = [] + for item in list(collect): + arr.append(item.value) - object[obj['prop']] = arr + object[obj['prop']] = arr - else: - object[obj['prop']] = getattr(getattr(mytool, bname), obj['prop']) + else: + object[obj['prop']] = getattr(getattr(mytool, bname), obj['prop']) def getFromAttributes(context, obj, attrs, bname, index): @@ -772,7 +841,7 @@ def setFromAttributes(context, obj, attrs, bname, index): def getPerFaceByType(context, object, zclass): zattrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockName(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass) # btype = zclass.__name__.split('_')[1] # bname = "perFaceBlock{}".format(btype) @@ -793,7 +862,7 @@ def getPerFaceByType(context, object, zclass): def getPerVertexByType(context, object, zclass): zattrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockName(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass) # btype = zclass.__name__.split('_')[1] # bname = "perVertBlock{}".format(btype) @@ -815,7 +884,7 @@ def getPerVertexByType(context, object, zclass): def setPerVertexByType(context, object, zclass): zattrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockName(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass) # btype = zclass.__name__.split('_')[1] # bname = "perVertBlock{}".format(btype) @@ -836,7 +905,7 @@ def setPerVertexByType(context, object, zclass): def setPerFaceByType(context, object, zclass): zattrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockName(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass) # btype = zclass.__name__.split('_')[1] # bname = "perFaceBlock{}".format(btype) From 5383f649bebe2b7242ce3b82d4944a8e2d1f0acf Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 28 Jan 2023 11:26:18 +0200 Subject: [PATCH 35/47] modal get operator --- src/2.80/addons/b3d_tools/b3d/panel.py | 51 ++++++++++++++++++++---- src/2.80/addons/b3d_tools/b3d/scripts.py | 4 +- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index 1305fa5..0ef8cfe 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -40,7 +40,7 @@ setPerFaceByType, getPerVertexByType, setPerVertexByType, - showSphere, + showHideSphere, ) @@ -940,8 +940,6 @@ def execute(self, context): scene = context.scene mytool = scene.my_tool - global block_type - global lenStr object = bpy.context.object block_type = object['block_type'] @@ -1358,8 +1356,8 @@ def type19(name): return {'FINISHED'} -class ShowSphereOperator(bpy.types.Operator): - bl_idname = "b3d.show_sphere_operator" +class ShowHideSphereOperator(bpy.types.Operator): + bl_idname = "wm.show_hide_sphere_operator" bl_label = "Показать/Скрыть сферу" bl_description = "Показывает/скрывает сферу" @@ -1371,12 +1369,39 @@ def execute(self, context): obj = context.object - showSphere(context, obj, self.pname) + showHideSphere(context, obj, self.pname) - self.report({'INFO'}, "Sphere shown") + self.report({'INFO'}, "Sphere shown or hidden") return {'FINISHED'} +class GetValuesModalOperator(bpy.types.Operator): + bl_idname = "wm.get_block_values_modal_operator" + bl_label = "Обновление панели" + bl_description = "Обновляет значения в b3d панели" + + # @classmethod + # def poll(cls, context): + # return context.object is not None and context.object.get('block_type') is not None + + def modal(self, context, event): + if event.type == 'LEFTMOUSE': + if context.object is not None: + obj = context.object + if context.object.get('block_type') is not None: + block_type = obj.get('block_type') + + zclass = getClassDefByType(block_type) + if zclass is not None: + getAllObjsByType(context, obj, zclass) + + return {'PASS_THROUGH'} + + def execute(self, context): + wm = context.window_manager + wm.modal_handler_add(self) + return {'RUNNING_MODAL'} + # ------------------------------------------------------------------------ # panels @@ -2008,7 +2033,8 @@ def draw(self, context): ShowConditionalsOperator, HideConditionalsOperator, AddBlocksOperator, - ShowSphereOperator, + ShowHideSphereOperator, + GetValuesModalOperator, OBJECT_PT_b3d_add_panel, OBJECT_PT_b3d_edit_panel, @@ -2024,13 +2050,22 @@ def draw(self, context): OBJECT_PT_b3d_misc_panel, ) +# @bpy.app.handlers.persistent +def load_handler(scene): + print('invoking modal operator') + bpy.ops.wm.get_block_values_modal_operator() + def register(): for cls in _classes: bpy.utils.register_class(cls) bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=PanelSettings) + bpy.app.handlers.load_post.append(load_handler) + def unregister(): del bpy.types.Scene.my_tool for cls in _classes[::-1]: bpy.utils.unregister_class(cls) + if load_handler in bpy.app.handlers.load_post: + bpy.app.handlers.load_post.remove(load_handler) diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index b60b7c4..b5afd85 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -442,7 +442,7 @@ def createRadDriver(srcObj, bname, pname): d.expression = v1.name -def showSphere(context, root, pname): +def showHideSphere(context, root, pname): objName = "{}||{}||{}".format(root.name, pname, 'temp') @@ -523,7 +523,7 @@ def drawFieldByType(l_self, context, obj, zclass): box = l_self.layout.box() col = box.column() - props = col.operator("b3d.show_sphere_operator") + props = col.operator("wm.show_hide_sphere_operator") props.pname = pname elif ftype == fieldType.STRING \ From b0f1953437a118eadd6e6f43c7566a90097dde88 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 28 Jan 2023 14:21:38 +0200 Subject: [PATCH 36/47] eng --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 403 +++++++-------- src/2.80/addons/b3d_tools/b3d/classes.py | 22 +- src/2.80/addons/b3d_tools/b3d/panel.py | 514 +++---------------- src/2.80/addons/b3d_tools/b3d/scripts.py | 6 +- src/2.80/addons/b3d_tools/consts.py | 150 +++--- src/2.80/addons/b3d_tools/way/__init__.py | 54 +- 6 files changed, 407 insertions(+), 742 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index 7eedf66..f334531 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -21,24 +21,25 @@ from ..consts import ( collisionTypeList, - generatorTypeList + generatorTypeList, + b24FlagList ) # Dynamic block exmaple # block_5 = type("block_5", (bpy.types.PropertyGroup,), { # '__annotations__': { # 'name': StringProperty( -# name="Имя блока", +# name="Block name", # default="", # maxlen=30, # ), # 'XYZ': FloatVectorProperty( -# name='Координаты блока', +# name='Block border coord', # description='', # default=(0.0, 0.0, 0.0) # ), # 'R': FloatProperty( -# name = "Радиус", +# name = "Block border rad", # description = "", # ) @@ -160,14 +161,14 @@ class pvb_8(): Normal_Switch = { 'prop': 'normal_switch', 'type': fieldType.FLOAT, - 'name': 'Выключатель нормали', + 'name': 'Normal switcher', 'description': '', 'default': 0.0 } Custom_Normal = { 'prop': 'custom_normal', 'type': fieldType.COORD, - 'name': 'Кастомная нормаль', + 'name': 'Custom normal', 'description': '', 'default': (0.0, 0.0, 0.0) } @@ -177,14 +178,14 @@ class pvb_35(): Normal_Switch = { 'prop': 'normal_switch', 'type': fieldType.FLOAT, - 'name': 'Выключатель нормали', + 'name': 'Normal switcher', 'description': '', 'default': 0.0 } Custom_Normal = { 'prop': 'custom_normal', 'type': fieldType.COORD, - 'name': 'Кастомная нормаль', + 'name': 'Custom normal', 'description': '', 'default': (0.0, 0.0, 0.0) } @@ -197,14 +198,14 @@ class pfb_8(): Unk_Float1 = { 'prop': 'float1', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0.0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } @@ -217,14 +218,14 @@ class pfb_28(): Unk_Float1 = { 'prop': 'float1', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0.0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } @@ -238,14 +239,14 @@ class pfb_35(): Unk_Float1 = { 'prop': 'float1', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0.0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } @@ -255,7 +256,7 @@ class b_common(): LevelGroup = { 'prop': 'level_group', 'type': fieldType.INT, - 'name': 'Группа блока', + 'name': 'Block group', 'description': '', 'default': 0 } @@ -264,14 +265,14 @@ class b_1(): Name1 = { 'prop': 'name1', 'type': fieldType.STRING, - 'name': 'Неизв. название 1', + 'name': 'Unk. name 1', 'description': '', 'default': '' } Name2 = { 'prop': 'name2', 'type': fieldType.STRING, - 'name': 'Неизв. название 2', + 'name': 'Unk. name 2', 'description': '', 'default': '' } @@ -280,14 +281,14 @@ class b_2(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -298,14 +299,14 @@ class b_2(): Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Неизв. координаты', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { 'prop': 'unk_R', 'type': fieldType.RAD, - 'name': 'Неизв. радиус', + 'name': 'Unk. rad', 'description': '', 'default': 0.0 } @@ -314,14 +315,14 @@ class b_3(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -334,14 +335,14 @@ class b_4(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -353,13 +354,13 @@ class b_4(): 'prop': 'name1', 'type': fieldType.ENUM_STR, 'subtype': fieldType.SPACE_NAME, - 'name': 'Трансформация', + 'name': 'Place', 'description': '' } Name2 = { 'prop': 'name2', 'type': fieldType.STRING, - 'name': 'Название 2', + 'name': 'Name 2', 'description': '', 'default': '' } @@ -368,21 +369,21 @@ class b_5(): Name1 = { 'prop': 'name1', 'type': fieldType.STRING, - 'name': 'Имя блока', + 'name': 'Block name', 'description': '', 'default': '' } XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -396,14 +397,14 @@ class b_6(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -414,14 +415,14 @@ class b_6(): Name1 = { 'prop': 'name1', 'type': fieldType.STRING, - 'name': 'Название 1', + 'name': 'Name 1', 'description': '', 'default': '' } Name2 = { 'prop': 'name2', 'type': fieldType.STRING, - 'name': 'Название 2', + 'name': 'Name 2', 'description': '', 'default': '' } @@ -430,14 +431,14 @@ class b_7(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -448,7 +449,7 @@ class b_7(): Name1 = { 'prop': 'name1', 'type': fieldType.STRING, - 'name': 'Название группы', + 'name': 'Group name', 'description': '', 'default': '' } @@ -457,14 +458,14 @@ class b_8(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -477,14 +478,14 @@ class b_9(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -495,14 +496,14 @@ class b_9(): Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Неизв. координаты', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { 'prop': 'unk_R', 'type': fieldType.RAD, - 'name': 'Неизв. радиус', + 'name': 'Unk. rad', 'description': '', 'default': 0.0 } @@ -511,14 +512,14 @@ class b_10(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -529,14 +530,14 @@ class b_10(): LOD_XYZ = { 'prop': 'LOD_XYZ', 'type': fieldType.COORD, - 'name': 'Центр LOD', + 'name': 'LOD coord', 'description': '', 'default': (0.0, 0.0, 0.0) } LOD_R = { 'prop': 'LOD_R', 'type': fieldType.RAD, - 'name': 'Радиус LOD', + 'name': 'LOD rad', 'description': '', 'default': 0.0 } @@ -545,14 +546,14 @@ class b_11(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -563,14 +564,14 @@ class b_11(): Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Неизв. координаты', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { 'prop': 'unk_R', 'type': fieldType.RAD, - 'name': 'Неизв. радиус', + 'name': 'Unk. rad', 'description': '', 'default': 0.0 } @@ -579,14 +580,14 @@ class b_12(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -597,35 +598,35 @@ class b_12(): Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Неизв. координаты', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { 'prop': 'unk_R', 'type': fieldType.RAD, - 'name': 'Неизв. радиус', + 'name': 'Unk. rad', 'description': '', 'default': 0.0 } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } @@ -633,14 +634,14 @@ class b_13(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -651,21 +652,21 @@ class b_13(): Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } @@ -673,14 +674,14 @@ class b_14(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -691,35 +692,35 @@ class b_14(): Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Неизв. координаты', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { 'prop': 'unk_R', 'type': fieldType.RAD, - 'name': 'Неизв. радиус', + 'name': 'Unk. rad', 'description': '', 'default': 0.0 } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } @@ -727,14 +728,14 @@ class b_15(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -745,21 +746,21 @@ class b_15(): Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } @@ -767,14 +768,14 @@ class b_16(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -785,49 +786,49 @@ class b_16(): Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', + 'name': 'Unk. coord 1', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_XYZ2 = { 'prop': 'unk_XYZ2', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', + 'name': 'Unk. coord 2', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_Float1 = { 'prop': 'float1', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0.0 } Unk_Float2 = { 'prop': 'float2', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0.0 } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 3', + 'name': 'Unk. 3', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 4', + 'name': 'Unk. 4', 'description': '', 'default': 0 } Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } @@ -835,14 +836,14 @@ class b_17(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -853,49 +854,49 @@ class b_17(): Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', + 'name': 'Unk. coord 1', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_XYZ2 = { 'prop': 'unk_XYZ2', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', + 'name': 'Unk. coord 2', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_Float1 = { 'prop': 'float1', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0.0 } Unk_Float2 = { 'prop': 'float2', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0.0 } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 3', + 'name': 'Unk. 3', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 4', + 'name': 'Unk. 4', 'description': '', 'default': 0 } Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } @@ -903,14 +904,14 @@ class b_18(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -922,14 +923,14 @@ class b_18(): 'prop': 'space_name', 'type': fieldType.ENUM, 'subtype': fieldType.SPACE_NAME, - 'name': 'Название трансформации (24)', + 'name': 'Place name (24)', 'description': '' } Add_Name = { 'prop': 'add_name', 'type': fieldType.ENUM, 'subtype': fieldType.REFERENCEABLE, - 'name': 'Название переносимого блока', + 'name': 'Transfer block name', 'description': '' } @@ -937,14 +938,14 @@ class b_20(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -955,21 +956,21 @@ class b_20(): Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } @@ -977,14 +978,14 @@ class b_21(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -995,14 +996,14 @@ class b_21(): GroupCnt = { 'prop': 'group_cnt', 'type': fieldType.INT, - 'name': 'Количество групп', + 'name': 'Group count', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } @@ -1011,14 +1012,14 @@ class b_22(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1029,14 +1030,14 @@ class b_22(): Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Неизв. координаты', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { 'prop': 'unk_R', 'type': fieldType.RAD, - 'name': 'Неизв. радиус', + 'name': 'Unk. rad', 'description': '', 'default': 0.0 } @@ -1045,7 +1046,7 @@ class b_23(): Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } @@ -1053,7 +1054,7 @@ class b_23(): 'prop': 'CType', 'type': fieldType.ENUM, 'subtype': fieldType.INT, - 'name': 'Тип поверхности', + 'name': 'Surface type', 'description': '', 'default': 0, 'items': collisionTypeList @@ -1061,80 +1062,82 @@ class b_23(): Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } class b_24(): Flag = { 'prop': 'flag', - 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'type': fieldType.ENUM, + 'subtype': fieldType.INT, + 'name': 'Show flag', 'description': '', - 'default': 0 + 'default': 0, + 'items': b24FlagList } class b_25(): XYZ = { 'prop': 'XYZ', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Name = { 'prop': 'name', 'type': fieldType.STRING, - 'name': 'Название 1', + 'name': 'Name 1', 'description': '', 'default': '' } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', + 'name': 'Unk. coord 1', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_XYZ2 = { 'prop': 'unk_XYZ2', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', + 'name': 'Unk. coord 2', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_Float1 = { 'prop': 'float1', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0.0 } Unk_Float2 = { 'prop': 'float2', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0.0 } Unk_Float3 = { 'prop': 'float3', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 3', + 'name': 'Unk. 3', 'description': '', 'default': 0.0 } Unk_Float4 = { 'prop': 'float4', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 4', + 'name': 'Unk. 4', 'description': '', 'default': 0.0 } Unk_Float5 = { 'prop': 'float5', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 5', + 'name': 'Unk. 5', 'description': '', 'default': 0.0 } @@ -1143,14 +1146,14 @@ class b_26(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1161,21 +1164,21 @@ class b_26(): Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', + 'name': 'Unk. coord 1', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_XYZ2 = { 'prop': 'unk_XYZ2', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', + 'name': 'Unk. coord 2', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_XYZ3 = { 'prop': 'unk_XYZ3', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 3', + 'name': 'Unk. coord 3', 'description': '', 'default': (0.0, 0.0, 0.0) } @@ -1184,14 +1187,14 @@ class b_27(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1202,21 +1205,21 @@ class b_27(): Flag = { 'prop': 'flag', 'type': fieldType.INT, - 'name': 'Флаг', + 'name': 'Flag', 'description': '', 'default': 0 } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Неизв. координаты', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Material = { 'prop': 'material', 'type': fieldType.INT, - 'name': 'Материал', + 'name': 'Material', 'description': '', 'default': 0 } @@ -1225,14 +1228,14 @@ class b_28(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1243,7 +1246,7 @@ class b_28(): Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Sprite center coord', 'description': '', 'default': (0.0, 0.0, 0.0) } @@ -1253,14 +1256,14 @@ class b_29(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1271,28 +1274,28 @@ class b_29(): Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, - 'name': 'Неизв. координаты', + 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { 'prop': 'unk_R', 'type': fieldType.RAD, - 'name': 'Неизв. радиус', + 'name': 'Unk. rad', 'description': '', 'default': 0.0 } @@ -1301,14 +1304,14 @@ class b_30(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1320,7 +1323,7 @@ class b_30(): 'prop': '1_roomName_res', 'type': fieldType.ENUM_STR, 'subtype': fieldType.RES_MODULE, - 'name': '1. модуль', + 'name': '1. module', 'description': '', 'default': '' } @@ -1328,7 +1331,7 @@ class b_30(): 'prop': '1_roomName', 'type': fieldType.ENUM_STR, 'subtype': fieldType.ROOM, - 'name': 'Название 1. комнаты', + 'name': '1. room', 'description': '', 'default': '' } @@ -1336,7 +1339,7 @@ class b_30(): 'prop': '2_roomName_res', 'type': fieldType.ENUM_STR, 'subtype': fieldType.RES_MODULE, - 'name': '2. модуль', + 'name': '2. module', 'description': '', 'default': '' } @@ -1344,7 +1347,7 @@ class b_30(): 'prop': '2_roomName', 'type': fieldType.ENUM_STR, 'subtype': fieldType.ROOM, - 'name': 'Название 2. комнаты', + 'name': '2. room', 'description': '', 'default': '' } @@ -1353,14 +1356,14 @@ class b_31(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1371,35 +1374,35 @@ class b_31(): Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', + 'name': 'Unk. coord 1', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { 'prop': 'unk_R', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Unk. rad', 'description': '', 'default': 0.0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } Unk_XYZ2 = { 'prop': 'unk_XYZ2', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', + 'name': 'Unk. coord 1', 'description': '', 'default': (0.0, 0.0, 0.0) } @@ -1409,14 +1412,14 @@ class b_33(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1427,77 +1430,77 @@ class b_33(): Use_Lights = { 'prop': 'useLight', 'type': fieldType.INT, - 'name': 'Исп. свет', + 'name': 'Use lights', 'description': '', 'default': 0 } Light_Type = { 'prop': 'lType', 'type': fieldType.INT, - 'name': 'Тип света', + 'name': 'Light type', 'description': '', 'default': 0 } Flag = { 'prop': 'flag', 'type': fieldType.INT, - 'name': 'Флаг', + 'name': 'Flag', 'description': '', 'default': 0 } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 1', + 'name': 'Unk. coord 1', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_XYZ2 = { 'prop': 'unk_XYZ2', 'type': fieldType.COORD, - 'name': 'Неизв. координаты 2', + 'name': 'Unk. coord 2', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_Float1 = { 'prop': 'float1', 'type': fieldType.FLOAT, - 'name': 'Неизв. 1', + 'name': 'Unk. 1', 'description': '', 'default': 0.0 } Unk_Float2 = { 'prop': 'float2', 'type': fieldType.FLOAT, - 'name': 'Неизв. 2', + 'name': 'Unk. 2', 'description': '', 'default': 0.0 } Light_R = { 'prop': 'light_radius', 'type': fieldType.FLOAT, - 'name': 'Радиус света', + 'name': 'Light rad', 'description': '', 'default': 0.0 } Intens = { 'prop': 'intensity', 'type': fieldType.FLOAT, - 'name': 'Интенсивность', + 'name': 'Light intensity', 'description': '', 'default': 0.0 } Unk_Float3 = { 'prop': 'float3', 'type': fieldType.FLOAT, - 'name': 'Неизв. 3', + 'name': 'Unk. 3', 'description': '', 'default': 0.0 } Unk_Float4 = { 'prop': 'float4', 'type': fieldType.FLOAT, - 'name': 'Неизв. 4', + 'name': 'Unk. 4', 'description': '', 'default': 0.0 } @@ -1514,14 +1517,14 @@ class b_34(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1532,7 +1535,7 @@ class b_34(): UnkInt = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизв.', + 'name': 'Unk. 1', 'description': '', 'default': 0 } @@ -1541,14 +1544,14 @@ class b_35(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1559,7 +1562,7 @@ class b_35(): MType = { 'prop': 'mType', 'type': fieldType.INT, - 'name': 'Переменная 1', + 'name': 'Type', 'description': '', 'default': 0 } @@ -1567,7 +1570,7 @@ class b_35(): 'prop': 'texnum', 'type': fieldType.ENUM, 'subtype': fieldType.MATERIAL_IND, - 'name': 'Номер текстуры', + 'name': 'Texture', 'description': '', } @@ -1575,14 +1578,14 @@ class b_36(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1593,21 +1596,21 @@ class b_36(): Name1 = { 'prop': 'name1', 'type': fieldType.STRING, - 'name': 'Название 1', + 'name': 'Name 1', 'description': '', 'default': '' } Name2 = { 'prop': 'name2', 'type': fieldType.STRING, - 'name': 'Название 2', + 'name': 'Name 2', 'description': '', 'default': '' } MType = { 'prop': 'MType', 'type': fieldType.INT, - 'name': 'Переменная 1', + 'name': 'Type', 'description': '', 'default': 0 } @@ -1616,14 +1619,14 @@ class b_37(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1634,14 +1637,14 @@ class b_37(): Name1 = { 'prop': 'name1', 'type': fieldType.STRING, - 'name': 'Название 1', + 'name': 'Name 1', 'description': '', 'default': '' } SType = { 'prop': 'SType', 'type': fieldType.INT, - 'name': 'Переменная 1', + 'name': 'Type', 'description': '', 'default': 0 } @@ -1650,14 +1653,14 @@ class b_39(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1668,35 +1671,35 @@ class b_39(): Color_R = { 'prop': 'color_r', 'type': fieldType.INT, - 'name': 'Радиус цвета', + 'name': 'Color rad', 'description': '', 'default': 0 } Unk_Float1 = { 'prop': 'float1', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0.0 } Fog_Start = { 'prop': 'fog_start', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 3', + 'name': 'Unk. 3', 'description': '', 'default': 0.0 } Fog_End = { 'prop': 'fog_end', 'type': fieldType.FLOAT, - 'name': 'Неизвестная 4', + 'name': 'Unk. 4', 'description': '', 'default': 0.0 } Color_Id = { 'prop': 'color_id', 'type': fieldType.INT, - 'name': 'ID цвета', + 'name': 'Color ID', 'description': '', 'default': 0 } @@ -1705,14 +1708,14 @@ class b_40(): XYZ = { 'prop': 'b3d_border_center', 'type': fieldType.COORD, - 'name': 'Координаты блока', + 'name': 'Block border coord', 'description': '', 'default': (0.0, 0.0, 0.0) } R = { 'prop': 'b3d_border_rad', 'type': fieldType.RAD, - 'name': 'Радиус', + 'name': 'Block border rad', 'description': '', 'default': 0.0 } @@ -1723,7 +1726,7 @@ class b_40(): Name1 = { 'prop': 'name1', 'type': fieldType.STRING, - 'name': 'Название 1', + 'name': 'Name 1', 'description': '', 'default': '' } @@ -1731,7 +1734,7 @@ class b_40(): 'prop': 'name2', 'type': fieldType.ENUM, 'subtype': fieldType.STRING, - 'name': 'Тип генератора', + 'name': 'Generator type', 'description': '', 'default': '$$TreeGenerator', 'items': generatorTypeList @@ -1739,21 +1742,21 @@ class b_40(): Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, - 'name': 'Неизвестная 1', + 'name': 'Unk. 1', 'description': '', 'default': 0 } Unk_Int2 = { 'prop': 'int2', 'type': fieldType.INT, - 'name': 'Неизвестная 2', + 'name': 'Unk. 2', 'description': '', 'default': 0 } Unk_List = { 'prop': 'list1', 'type': fieldType.LIST, - 'name': 'Неизв. параметры', + 'name': 'Unk. params', 'description': '', } diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 1390813..b002945 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -101,8 +101,8 @@ def createTypeClass(zclass): prop = None lockProp = BoolProperty( - name = "Вкл./Выкл.", - description = "Включить/выключить параметр для редактирования", + name = "On./Off.", + description = "Enable/Disable param for editing", default = True ) @@ -196,7 +196,7 @@ def createTypeClass(zclass): prop_switch = BoolProperty( name = 'Use dropdown', - description = 'Выбор из Dropdown списка', + description = 'Dropdown selection', default = False ) @@ -222,29 +222,29 @@ def createTypeClass(zclass): attributes['__annotations__']["show_{}".format(pname)] = lockProp prop1 = BoolProperty( - name = 'Смещенная триангуляция', - description = 'Порядок в котором считываются вертексы, зависит от этой переменной', + name = 'Triangulation offset', + description = 'Order in which vertexes are read depends on that', default = True ) attributes['__annotations__']['{}_{}'.format(pname, 'triang_offset')] = prop1 prop2 = BoolProperty( - name = 'Использовать UV', - description = 'Когда активен, при экспорте записывает UV.', + name = 'Use UV', + description = 'If active, writes UV during export.', default = True ) attributes['__annotations__']['{}_{}'.format(pname, 'use_uvs')] = prop2 prop3 = BoolProperty( - name = 'Использовать нормали', - description = 'Когда активен, при экспорте записывает нормали.', + name = 'Use normals', + description = 'If active, writes normal during export.', default = True ) attributes['__annotations__']['{}_{}'.format(pname, 'use_normals')] = prop3 prop4 = BoolProperty( - name = 'Выключатель нормалей', - description = 'Когда активен, использует float для вкл./выкл. нормалей. Когда неактивен использует float vector для обычных нормалей. Игнорируется если пункт "Использовать нормали" неактивен', + name = 'Normal switch', + description = 'If active, use for en(dis)abling normals. If not active use for common normals. Is ignored if "Use normals" is inactive', default = True ) attributes['__annotations__']['{}_{}'.format(pname, 'normal_flag')] = prop4 diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index 0ef8cfe..4efb436 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -146,428 +146,64 @@ class PanelSettings(bpy.types.PropertyGroup): resModules: CollectionProperty(type=ResBlock) selectedResModule: EnumProperty( - name="RES модуль", - description="Выбранный RES модуль", + name="RES module", + description="Selected RES module", items=resModuleCallback ) conditionGroup : bpy.props.IntProperty( - name='Номер условия', - description='Номер условия(группа обьекта), который надо скрыть/отобразить. Если -1, то берутся все доступные номера. При слишком большом числе берётся ближайшее подходящее.', + name='Event number', + description='Event number(object group), that should be shown/hidden. If -1, then all events are chosen. If event number is too big, closest suitable number is chosen.', default=-1, min=-1 ) - coordinates : bpy.props.FloatVectorProperty( - name='Координаты блока', - description='', - default=(0.0, 0.0, 0.0) - ) - BlockName_string : bpy.props.StringProperty( - name="Имя блока", + name="Block name", default="", maxlen=30, ) addBlockType_enum : bpy.props.EnumProperty( - name="Тип блока", + name="Block type", items= consts.blockTypeList ) - - CollisionType_enum : bpy.props.EnumProperty( - name="Тип коллизии", - items=consts.collisionTypeList, - ) - Radius : bpy.props.FloatProperty( - name = "Радиус блока", - description = "Дальность прорисовки блока", - default = 1.0, - ) - - Radius1 : bpy.props.FloatProperty( - name = "Радиус блока", - description = "Дальность прорисовки блока", - default = 1.0, - ) - - LOD_Distance : bpy.props.FloatProperty( - name = "Дальность отображения LOD", - description = "Маскимальная дальность отображения LOD", - default = 10.0, - ) - - LOD_Distance1 : bpy.props.FloatProperty( - name = "Дальность отображения LOD", - description = "Маскимальная дальность отображения LOD", - default = 10.0, - ) - - Intensity : bpy.props.FloatProperty( - name = "Интенсивность освещения", - description = "Яркость источника света", - default = 1.0, - min = 0.0, - ) - - Intensity1 : bpy.props.FloatProperty( - name = "Интенсивность освещения", - description = "Яркость источника света", - default = 1.0, - min = 0.0, - ) - - R : bpy.props.FloatProperty( - name = "R", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - G : bpy.props.FloatProperty( - name = "G", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - B : bpy.props.FloatProperty( - name = "B", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - R1 : bpy.props.FloatProperty( - name = "R", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - G1 : bpy.props.FloatProperty( - name = "G", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - B1 : bpy.props.FloatProperty( - name = "B", - description = "", - default = 255, - min = 0.0, - max = 255, - ) - - RadiusLight : bpy.props.FloatProperty( - name = "Радиус освещения", - description = "", - default = 1, - min = 0.0, - ) - - RadiusLight1 : bpy.props.FloatProperty( - name = "Радиус освещения", - description = "", - default = 1, - min = 0.0, - ) - - LType_enum : bpy.props.EnumProperty( - name= "Тип источника света", - items = consts.lTypeList, - ) - - SType_enum : bpy.props.EnumProperty( - name= "Тип записи вершин", - items = consts.sTypeList, - ) - - MType_enum : bpy.props.EnumProperty( - name="Тип записи полигонов (35)", - items=consts.mTypeList, - ) - - texNum_int : bpy.props.IntProperty( - name = "Номер текстуры", - description="Номер используемой текстуры.", - ) - - addBlockName_string : bpy.props.StringProperty( - name="Присоединённый блок", - description="Имя блока, который будет приписан к текущему блоку, например: hit_BmwM5 приписан к BmwM5 (05)", - default="", - maxlen=30, - ) - - addBlockName1_string : bpy.props.StringProperty( - name="Присоединённый блок", - description="Имя блока, который будет приписан к текущему блоку, например: hit_BmwM5 приписан к BmwM5 (05)", - default="", - maxlen=30, - ) - - addSpaceName_string : bpy.props.StringProperty( - name="Используемый локатор", - description="Имя блока, который будет использоваться в качестве локатора для привязанного блока, например: AirportSpace и Airport", - default="", - maxlen=30, - ) - - addSpaceName1_string : bpy.props.StringProperty( - name="Используемый локатор", - description="Имя блока, который будет использоваться в качестве локатора для привязанного блока, например: AirportSpace и Airport", - default="", - maxlen=30, - ) - - add24Flag_enum : bpy.props.EnumProperty( - name="Флаг", - items=[ ('0', "0", "Присоединённый объект не будет отображаться"), - ('1', "1", "Присоединённый объект будет отображаться"), - ] - ) - - add24Flag_enum1 : bpy.props.EnumProperty( - name="Флаг", - items=[ ('0', "0", "Присоединённый объект не будет отображаться"), - ('1', "1", "Присоединённый объект будет отображаться"), - ] - ) - - TGType_int : bpy.props.IntProperty( - name = "Тип модели дерева", - description="", - ) - - Scale : bpy.props.FloatProperty( - name = "Масштаб генератора", - description="", - min=0.0, - default=9.5, - ) - - generatorType_enum : bpy.props.EnumProperty( - name="Тип генератора", - items=consts.generatorTypeList, - ) - - groupsNum_int : bpy.props.IntProperty( - name = "Кол-во групп", - description="Кол-во переключаемых групп.", - ) - - groupsNum1_int : bpy.props.IntProperty( - name = "Кол-во групп", - description="Кол-во переключаемых групп.", - ) - - Refer_bool = bpy.props.BoolProperty( - name="refer", - description="", - default = False - ) - - Type21_enum : bpy.props.EnumProperty( - name="Имя 21 блока", - items=consts.conditionBlockTypeList, - ) - - addGroupName_string : bpy.props.StringProperty( - name="Имя группы", - description="Имя переключаемой группы", - default="", - maxlen=30, - ) - - T14_enum : bpy.props.EnumProperty( - name="Преднастройки", - items=[ ('car', "Для транспорта", ""), - ('trl', "Для полуприцепа", ""), - ('trl_cyc', "Для полуприцепа-цистерны", ""), - ('clk', "Для коллизии", ""), - ] - ) - - T28_radius : bpy.props.FloatProperty( - name = "Радиус спрайта", - description = "Радиус плоскости спрайта", - default = 1.0, - min = 0.01, - ) - - T28_radius1 : bpy.props.FloatProperty( - name = "Радиус спрайта", - description = "Радиус плоскости спрайта", + name = "Block rad", + description = "Block rendering distance", default = 1.0, - min = 0.01, - ) - - CH : bpy.props.FloatProperty( - name = "Высота коллизии", - description = "Высота плоскости коллизии", - ) - - CH1 : bpy.props.FloatProperty( - name = "Высота коллизии", - description = "Высота плоскости коллизии", - ) - - RSound : bpy.props.FloatProperty( - name = "Радиус звука", - description = "Радиус звука", - default = 10.0, - min = 0.0, - ) - - RSound1 : bpy.props.FloatProperty( - name = "Радиус звука", - description = "Радиус звука", - default = 10.0, - min = 0.0, - ) - - addSoundName_string : bpy.props.StringProperty( - name="Присоединённый звуковой файл", - description="Имя звукового файла, который будет использоваться данным блоком", - default="", - maxlen=30, - ) - - addSoundName1_string : bpy.props.StringProperty( - name="Присоединённый звуковой файл", - description="Имя звукового файла, который будет использоваться данным блоком", - default="", - maxlen=30, - ) - - SLevel : bpy.props.FloatProperty( - name = "Уровень громкости звука", - description = "Уровень громкости звука", - default = 1.0, - min = 0.0, - max = 1.0, - ) - - SLevel1 : bpy.props.FloatProperty( - name = "Уровень громкости звука", - description = "Уровень громкости звука", - default = 1.0, - min = 0.0, - max = 1.0, - ) - - addRoomName_string : bpy.props.StringProperty( - name="Присоединённая комната", - description="Имя комнаты, которая будет загружена", - default="", - maxlen=30, - ) - - FType_enum : bpy.props.EnumProperty( - name="Тип записи полигонов (08)", - items=(('0', "Тип 0", "С нормалями"), - ('1', "Тип 1", "Без нормалей"), - ('2', "Тип 2", "С нормалями, UV разрывная"), - ('128', "Тип 128", ""), - ('144', "Тип 144", ""), - ), - ) - - Faces_enum : bpy.props.EnumProperty( - name="Тип блока полигонов", - items=(('8', "8", ""), - ('35', "35", ""), - ), - ) - - addBlockMeshType_enum : bpy.props.EnumProperty( - name="Тип записи модели", - items=[ ('auto', "Автоматический", "Экспортер сам определит, какой блок использовать (8, 35 или оба)"), - ('manual', "Ручной", "Будет записан блок, который выбран в настройках"), - ] - ) - - addMeshType_enum : bpy.props.EnumProperty( - name="Тип записи полигонов", - items=[ ('uv0', "Обычный", ""), - ('uv1', "С разрывной UV", ""), - ] - ) - - materialName_string : bpy.props.StringProperty( - name="Имя материала", - description="Имя материала, который будет использоваться генератором", - default="", - maxlen=10, - ) - - routeName_string : bpy.props.StringProperty( - name="Имя участка карты", - description="Имя участка карты, который будет загружен", - default="", - maxlen=2, - ) - - triggerType_enum : bpy.props.EnumProperty( - name="Тип триггера", - items=(('loader', "Загрузчик", "Загрузчик участков карты"), - ('radar0', "Радар 0", "Event 0"), - ('radar1', "Радар 1", "Event 1"), - ), - ) - - addBlockName4_string : bpy.props.StringProperty( - name="Родительский блок", - description="", - default="", - maxlen=30, - ) - - speed_limit : bpy.props.FloatProperty( - name = "Ограничение скорости", - description = "", - default = 60.0, - min = 0.0, ) addBlocks_enum : bpy.props.EnumProperty( - name="Тип сборки", - items=[ ('room', "Комната", "Комната с коллизией"), - #('07', "07", "Меш (ДБ1)"), + name="Assembly type", + items=[ ('room', "Room", "Room"), + #('07', "07", "Mesh (HT1)"), #('10', "10", "LOD"), - #('12', "12", "Плоскость коллизии"), - #('14', "14", "Блок, связанный с автомобилями"), - #('18', "18", "Связка локатора и 3D-модели, например: FiatWheel0Space и Single0Wheel14"), - #('19', "19", "Контейнер, в отличие от блока типа 05, не имеет возможности привязки"), - #('20', "20", "Плоская коллизия"), - #('21', "21", "Контейнер с обработкой событий"), - #('23', "23", "Объёмная коллизия"), - #('24', "24", "Локатор"), - #('28', "28", "3D-спрайт"), - #('33', "33", "Источник света"), - #('37', "37", "Меш"), - #('40', "40", "Генератор объектов"), + #('12', "12", "Unk"), + #('14', "14", "Car trigger"), + #('18', "18", "Connector"), + #('19', "19", "Room container"), + #('20', "20", "2D collision"), + #('21', "21", "Event container"), + #('23', "23", "3D collision"), + #('24', "24", "Locator"), + #('28', "28", "2D-sprite"), + #('33', "33", "Light source"), + #('37', "37", "Mesh"), + #('40', "40", "Object generator"), ] ) addRoomNameIndex_string : bpy.props.StringProperty( - name="Имя комнаты", + name="Room name", description="", default="aa_000", maxlen=30, ) mirrorType_enum : bpy.props.EnumProperty( - name="Тип блока", + name="Block type", items=[ ('x', "x", ""), ('y', "y", ""), ('z', "z", ""), @@ -596,7 +232,7 @@ class PanelSettings(bpy.types.PropertyGroup): class AddOperator(bpy.types.Operator): bl_idname = "wm.add_operator" - bl_label = "Добавить блок на сцену" + bl_label = "Add block to scene" def execute(self, context): scene = context.scene @@ -902,7 +538,7 @@ def execute(self, context): class GetVertexValuesOperator(bpy.types.Operator): bl_idname = "wm.get_vertex_values_operator" - bl_label = "Получить настройки блока" + bl_label = "Get block values" def execute(self, context): object = bpy.context.selected_objects[0] @@ -917,7 +553,7 @@ def execute(self, context): class GetFaceValuesOperator(bpy.types.Operator): bl_idname = "wm.get_face_values_operator" - bl_label = "Получить настройки блока" + bl_label = "Get block values" def execute(self, context): object = bpy.context.selected_objects[0] @@ -934,7 +570,7 @@ def execute(self, context): class GetValuesOperator(bpy.types.Operator): bl_idname = "wm.get_block_values_operator" - bl_label = "Получить настройки блока" + bl_label = "Get block values" def execute(self, context): scene = context.scene @@ -952,7 +588,7 @@ def execute(self, context): class SetFaceValuesOperator(bpy.types.Operator): bl_idname = "wm.set_face_values_operator" - bl_label = "Сохранить настройки блока" + bl_label = "Save block values" def execute(self, context): curtype = bpy.context.object['block_type'] @@ -974,7 +610,7 @@ def execute(self, context): class SetVertexValuesOperator(bpy.types.Operator): bl_idname = "wm.set_vertex_values_operator" - bl_label = "Сохранить настройки блока" + bl_label = "Save block values" def execute(self, context): curtype = bpy.context.object['block_type'] @@ -994,7 +630,7 @@ def execute(self, context): class SetValuesOperator(bpy.types.Operator): bl_idname = "wm.set_block_values_operator" - bl_label = "Сохранить настройки блока" + bl_label = "Save block values" def execute(self, context): scene = context.scene @@ -1030,7 +666,7 @@ def execute(self, context): class DelValuesOperator(bpy.types.Operator): bl_idname = "wm.del_block_values_operator" - bl_label = "Удалить настройки блока" + bl_label = "Delete block values" def execute(self, context): scene = context.scene @@ -1051,7 +687,7 @@ def execute(self, context): class FixUVOperator(bpy.types.Operator): bl_idname = "wm.fix_uv_operator" - bl_label = "Исправить UV для экспорта" + bl_label = "Fix UV for export" def execute(self, context): @@ -1090,7 +726,7 @@ def execute(self, context): class FixVertsOperator(bpy.types.Operator): bl_idname = "wm.fix_verts_operator" - bl_label = "Исправить меш для экспорта" + bl_label = "Fix mesh for export" def execute(self, context): @@ -1112,7 +748,7 @@ def execute(self, context): class MirrorAndFlipObjectsOperator(bpy.types.Operator): bl_idname = "wm.mirror_objects_operator" - bl_label = "Отзеркалить объекты" + bl_label = "Mirror objects" def execute(self, context): scene = context.scene @@ -1161,8 +797,8 @@ def execute(self, context): class ApplyTransformsOperator(bpy.types.Operator): bl_idname = "wm.apply_transforms_operator" - bl_label = "Расположить/Убрать обьекты" - bl_description = "Создаёт копии обьектов и располагает по местам(блок 24) указанным в блоке 18" + bl_label = "Arrange/Remove objects" + bl_description = "Creates copies of objects and arrange them at places(24) specified in connector(18)" def execute(self, context): scene = context.scene @@ -1174,8 +810,8 @@ def execute(self, context): class ShowHideCollisionsOperator(bpy.types.Operator): bl_idname = "wm.show_hide_collisions_operator" - bl_label = "Отобразить/Скрыть коллизии" - bl_description = "Если скрыты все коллизии(23), показывает их. Иначе - скрывает." + bl_label = "Show/Hide collisions" + bl_description = "If all 3d collisions(23) are hidden, shows them. otherwise - hide." def execute(self, context): scene = context.scene @@ -1187,8 +823,8 @@ def execute(self, context): class ShowHideRoomBordersOperator(bpy.types.Operator): bl_idname = "wm.show_hide_room_borders_operator" - bl_label = "Отобразить/Скрыть границы комнат" - bl_description = "Если скрыты все границы комнат(30), показывает их. Иначе - скрывает." + bl_label = "Show/Hide portals" + bl_description = "If all portals(30) are hidden, shows them. Otherwise - hide." def execute(self, context): scene = context.scene @@ -1200,8 +836,8 @@ def execute(self, context): class ShowHideGeneratorsOperator(bpy.types.Operator): bl_idname = "wm.show_hide_generator_operator" - bl_label = "Отобразить/Скрыть генераторы обьектов" - bl_description = "Если скрыты все генераторы обьектов(40), показывает их. Иначе - скрывает." + bl_label = "Show/Hide generator blocks" + bl_description = "If all generator blocks(40) are hidden, shows them. Otherwise - hide." def execute(self, context): scene = context.scene @@ -1213,9 +849,9 @@ def execute(self, context): class ShowLODOperator(bpy.types.Operator): bl_idname = "wm.show_lod_operator" - bl_label = "Отобразить LOD модели" - bl_description = "Показывает LOD(10) выделенного обьекта. " + \ - "Если нет активного обьекта показывает LOD у всех обьектов сцены" + bl_label = "Show LOD" + bl_description = "Shows LOD(10) of selected object. " + \ + "If there is no active object, show LOD of all scene objects." def execute(self, context): scene = context.scene @@ -1233,9 +869,9 @@ def execute(self, context): class HideLODOperator(bpy.types.Operator): bl_idname = "wm.hide_lod_operator" - bl_label = "Скрыть LOD модели" - bl_description = "Скрывает LOD(10) выделенного обьекта. " + \ - "Если нет активного обьекта скрывает LOD у всех обьектов сцены" + bl_label = "Hide LOD" + bl_description = "Hides LOD(10) of selected object. " + \ + "If there is no active object, hide LOD of all scene objects." def execute(self, context): scene = context.scene @@ -1253,9 +889,9 @@ def execute(self, context): class ShowConditionalsOperator(bpy.types.Operator): bl_idname = "wm.show_conditional_operator" - bl_label = "Отобразить обьекты с условием" - bl_description = "Показывает выбранное условие блока 21 выделенного обьекта. " + \ - "Если нет активного обьекта показывает выбранное условие блока 21 у всех обьектов сцены" + bl_label = "Show events" + bl_description = "Show event from selected event block(21). " + \ + "If there is no active event block, show event of all scene event objects(21)" group : bpy.props.IntProperty() @@ -1276,9 +912,9 @@ def execute(self, context): class HideConditionalsOperator(bpy.types.Operator): bl_idname = "wm.hide_conditional_operator" - bl_label = "Скрыть обьекты с условием" - bl_description = "Скрывает выбранное условие блока 21 выделенного обьекта. " + \ - "Если нет активного обьекта скрывает выбранное условие блока 21 у всех обьектов сцены" + bl_label = "Hide events" + bl_description = "Hide event from selected event block(21). " + \ + "If there is no active event block, hide event of all scene event objects(21)" group : bpy.props.IntProperty() @@ -1298,7 +934,7 @@ def execute(self, context): class AddBlocksOperator(bpy.types.Operator): bl_idname = "wm.add1_operator" - bl_label = "Добавить сборку блоков на сцену" + bl_label = "Add block assembly to scene" def execute(self, context): scene = context.scene @@ -1358,8 +994,8 @@ def type19(name): class ShowHideSphereOperator(bpy.types.Operator): bl_idname = "wm.show_hide_sphere_operator" - bl_label = "Показать/Скрыть сферу" - bl_description = "Показывает/скрывает сферу" + bl_label = "Show/Hide sphere" + bl_description = "Shows/Hides sphere" pname: bpy.props.StringProperty() @@ -1377,8 +1013,8 @@ def execute(self, context): class GetValuesModalOperator(bpy.types.Operator): bl_idname = "wm.get_block_values_modal_operator" - bl_label = "Обновление панели" - bl_description = "Обновляет значения в b3d панели" + bl_label = "Automatically get block values on object select" + bl_description = "Updates values in b3d panel" # @classmethod # def poll(cls, context): @@ -1409,7 +1045,7 @@ def execute(self, context): class OBJECT_PT_b3d_add_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_add_panel" - bl_label = "Добавление блоков" + bl_label = "Add blocks" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "b3d Tools" @@ -1430,7 +1066,7 @@ def draw(self, context): global block_type block_type = int(mytool.addBlockType_enum) - self.layout.label(text="Тип блока:") + self.layout.label(text="Block type:") layout.prop(mytool, "addBlockType_enum", text="") layout.prop(mytool, "BlockName_string") @@ -1443,7 +1079,7 @@ def draw(self, context): class OBJECT_PT_b3d_pfb_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pfb_edit_panel" - bl_label = "Параметры полигона" + bl_label = "Polygon params" bl_parent_id = "OBJECT_PT_b3d_edit_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1480,7 +1116,7 @@ def draw(self, context): class OBJECT_PT_b3d_pvb_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pvb_edit_panel" - bl_label = "Параметры вершины" + bl_label = "Vertex params" bl_parent_id = "OBJECT_PT_b3d_edit_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1515,7 +1151,7 @@ def draw(self, context): class OBJECT_PT_b3d_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_edit_panel" - bl_label = "Редактирование блоков" + bl_label = "Block edit" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "b3d Tools" @@ -1535,7 +1171,7 @@ def draw(self, context): class OBJECT_PT_b3d_pob_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pob_edit_panel" - bl_label = "Параметры обьекта" + bl_label = "Object params" bl_parent_id = "OBJECT_PT_b3d_edit_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1591,7 +1227,7 @@ def draw(self, context): class OBJECT_PT_b3d_blocks_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_blocks_panel" - bl_label = "Сборки блоков" + bl_label = "Blocks assembly" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "b3d Tools" @@ -1617,7 +1253,7 @@ def draw(self, context): class OBJECT_PT_b3d_func_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_func_panel" - bl_label = "Дополнительные функции" + bl_label = "Additional options" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "b3d Tools" @@ -1654,7 +1290,7 @@ def draw(self, context): class OBJECT_PT_b3d_res_module_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_res_module_panel" - bl_label = "Игровые ресурсы" + bl_label = "RES resources" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "b3d Tools" @@ -1672,7 +1308,7 @@ def draw(self, context): class OBJECT_PT_b3d_maskfiles_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_maskfiles_panel" - bl_label = "MSK-файлы" + bl_label = "MSK-files" bl_parent_id = "OBJECT_PT_b3d_res_module_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1746,7 +1382,7 @@ def draw(self, context): class OBJECT_PT_b3d_textures_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_textures_panel" - bl_label = "Текстуры" + bl_label = "Textures" bl_parent_id = "OBJECT_PT_b3d_res_module_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1822,7 +1458,7 @@ def draw(self, context): class OBJECT_PT_b3d_materials_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_materials_panel" - bl_label = "Материалы" + bl_label = "Materials" bl_parent_id = "OBJECT_PT_b3d_res_module_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1988,7 +1624,7 @@ def draw(self, context): class OBJECT_PT_b3d_misc_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_misc_panel" - bl_label = "О плагине" + bl_label = "About add-on" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "b3d Tools" @@ -2003,7 +1639,7 @@ def draw(self, context): scene = context.scene mytool = scene.my_tool - self.layout.label(text="Автор плагина: aleko2144") + self.layout.label(text="Add-on author: aleko2144") self.layout.label(text="vk.com/rnr_mods") # ------------------------------------------------------------------------ # register and unregister diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index b5afd85..d9a74be 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -490,9 +490,9 @@ def drawCommon(l_self, obj): lenStr = str(len(obj.children)) box = l_self.layout.box() - box.label(text="Тип блока: " + str(block_type)) - box.label(text="Кол-во вложенных блоков: " + lenStr) - box.label(text="Группа блока: " + str(level_group)) + box.label(text="Block type: " + str(block_type)) + box.label(text="Children block count: " + lenStr) + box.label(text="Block group: " + str(level_group)) def drawAllFieldsByType(l_self, context, zclass): if zclass.__name__.split('_')[0] == 'b': diff --git a/src/2.80/addons/b3d_tools/consts.py b/src/2.80/addons/b3d_tools/consts.py index b3d16d3..88d26e4 100644 --- a/src/2.80/addons/b3d_tools/consts.py +++ b/src/2.80/addons/b3d_tools/consts.py @@ -3,82 +3,108 @@ blockTypeList = [ ('6566754', "b3d", "b3d"), - ('00', "00", "2D фон"), - ('01', "01", "Камера"), - ('02', "02", "Неизв. блок"), - ('03', "03", "Контейнер"), - ('04', "04", "Контейнер с возможностью привязки к нему других блоков"), - ('05', "05", "Контейнер с возможностью привязки к нему другого блока"), - ('06', "06", "Блок вершин"), - ('07', "07", "Блок вершин"), - ('08', "08", "Блок полигонов"), - ('09', "09", "Триггер"), + ('00', "00", "2D background"), + ('01', "01", "Camera"), + ('02', "02", "Unknown block"), + ('03', "03", "Container"), + ('04', "04", "Container containing other blocks"), + ('05', "05", "Container containing other blocks"), + ('06', "06", "Vertex block (HT1)"), + ('07', "07", "Vertex block (HT2)"), + ('08', "08", "Polygon block"), + ('09', "09", "Trigger"), ('10', "10", "LOD"), - ('11', "11", "Неизв. блок"), - ('12', "12", "Плоскость коллизии"), - ('13', "13", "Триггер (загрузчик карты)"), - ('14', "14", "Блок, связанный с автомобилями"), - ('15', "15", "Неизв. блок"), - ('16', "16", "Неизв. блок"), - ('17', "17", "Неизв. блок"), - ('18', "18", "Связка локатора и 3D-модели, например: FiatWheel0Space и Single0Wheel14"), - ('19', "19", "Контейнер, в отличие от блока типа 05, не имеет возможности привязки"), - ('20', "20", "Плоская коллизия"), - ('21', "21", "Контейнер с обработкой событий"), - ('22', "22", "Блок-локатор"), - ('23', "23", "Объёмная коллизия"), - ('24', "24", "Локатор"), - ('25', "25", "Звуковой объект"), - ('26', "26", "Блок-локатор"), - ('27', "27", "Блок-локатор"), - ('28', "28", "Блок-локатор"), - ('29', "29", "Неизв. блок"), - ('30', "30", "Триггер для загрузки участков карты"), - ('31', "31", "Неизв. блок"), - ('33', "33", "Источник света"), - ('34', "34", "Неизв. блок"), - ('35', "35", "Блок полигонов"), - ('36', "36", "Блок вершин"), - ('37', "37", "Блок вершин"), - ('39', "39", "Блок-локатор"), - ('40', "40", "Генератор объектов") - # ('444', "Разделитель", "Разделитель"), + ('11', "11", "Unknown block"), + ('12', "12", "Unknown trigger"), + ('13', "13", "Unknown trigger(map load)"), + ('14', "14", "Unknown trigger(car related)"), + ('15', "15", "Unknown block"), + ('16', "16", "Unknown block"), + ('17', "17", "Unknown block"), + ('18', "18", "Connector between space block(24) and root container block. Exmaple: FiatWheel0Space and Single0Wheel14"), + ('19', "19", "Room container"), + ('20', "20", "Flat vertical collision"), + ('21', "21", "Container with event handling"), + ('22', "22", "Locator?"), + ('23', "23", "3D collision"), + ('24', "24", "Space"), + ('25', "25", "Sound"), + ('26', "26", "Locator?"), + ('27', "27", "Locator?"), + ('28', "28", "2D Sprite"), + ('29', "29", "Unknown block"), + ('30', "30", "Portal"), + ('31', "31", "Unknown block"), + ('33', "33", "Light source"), + ('34', "34", "Unknown block"), + ('35', "35", "Polygon block"), + ('36', "36", "Vertex block (HT1)"), + ('37', "37", "Vertex block (HT2)"), + ('39', "39", "Locator?"), + ('40', "40", "Object generator") ] collisionTypeList = [ - ('0', "стандарт", ""), - ('1', "асфальт", ""), - ('2', "земля", ""), - ('3', "вязкое болото", ""), - ('4', "легкопроходимое болото", ""), - ('5', "мокрый асфальт", ""), - ('7', "лёд", ""), - ('8', "вода (уничтожает автомобиль)", ""), - ('10', "песок", ""), - ('11', "пустыня", ""), - ('13', "шипы", ""), - ('16', "лёд (следы от шин не остаются)", "") + ('0', "standart", ""), + ('1', "asphalt", ""), + ('2', "earth", ""), + ('3', "swamp (hard to pass)", ""), + ('4', "swamp (easy to pass)", ""), + ('5', "wet asphalt", ""), + ('7', "ice", ""), + ('8', "water (destroys truck)", ""), + ('10', "sand", ""), + ('11', "desert", ""), + ('13', "spikes", ""), + ('16', "ice (no tire marks)", "") ] lTypeList = [ - ('0', 'Тип 0', ""), - ('1', 'Тип 1', ""), - ('2', 'Тип 2', ""), - ('3', 'Тип 3', "") + ('0', 'Type 0', ""), + ('1', 'Type 1', ""), + ('2', 'Type 2', ""), + ('3', 'Type 3', "") ] sTypeList = [ - ('2', "Тип 2, координаты + UV + нормали", "Данный тип используется на обычных моделях"), - ('3', "Тип 3, координаты + UV", "Данный тип используется на моделях света фар"), - ('258', "Тип 258, координаты + UV + нормали + 2 float", "Данный тип используется для моделей асфальтированных дорог"), - ('514', "Тип 514, координаты + UV + нормали + 4 float", "Данный тип используется на моделях поверхности воды"), - ('515', "Тип 515, координаты + UV + нормали + 2 float", "Тоже самое, что и 258. Данный тип используется для моделей асфальтированных дорог") + ('2', "Type 2, coords + UV + normals", "Is used on common models"), + ('3', "Type 3, coords + UV", "Is used on headlight models"), + ('258', "Type 258, coords + UV + normals + 2 float", "Is used on asphalt road models"), + ('514', "Type 514, coords + UV + normals + 4 float", "Is used on water surface"), + ('515', "Type 515, coords + UV + normals + 2 float", "Same as 258. Is used on asphalt road models") ] +fTypeList = [ + ('0', "Type 0", "With normals"), + ('1', "Type 1", "No normals"), + ('2', "Type 2", "With normals, breakable UV"), + ('128', "Type 128", ""), + ('144', "Type 144", "") +] + + mTypeList = [ - ('1', "Тип 1, с разрывной UV", "Каждый трис модели записывается вместе со собственной UV."), - ('3', "Тип 3, без разрывной UV", "Этот тип можно использовать для моделей, которые используют текстуру отражений.") + ('1', "Type 1, Breakable UV", "Each polygon saves its own UV."), + ('3', "Type 3, Unbroken UV", "Can be used for models, that use reflection texture.") +] + +b24FlagList = [ + ('0', "0", "Attached object won't be shown"), + ('1', "1", "Attached object will be shown") +] + +b14Enum = [ + ('car', "For car", ""), + ('trl', "For trailer", ""), + ('trl_cyc', "For tank-trailer", ""), + ('clk', "For collision", "") +] + +triggerTypeList = [ + ('loader', "Loader", "Map part loader"), + ('radar0', "Radar 0", "Event 0"), + ('radar1', "Radar 1", "Event 1") ] generatorTypeList = [ diff --git a/src/2.80/addons/b3d_tools/way/__init__.py b/src/2.80/addons/b3d_tools/way/__init__.py index 6285807..b64f7ad 100644 --- a/src/2.80/addons/b3d_tools/way/__init__.py +++ b/src/2.80/addons/b3d_tools/way/__init__.py @@ -59,7 +59,7 @@ class PanelSettings1(PropertyGroup): # ) addWBlockType_enum = EnumProperty( - name="Тип блока", + name="Block type", items=[ ('VDAT', "VDAT", ""), # ('WDTH', "WDTH", ""), # ('RTEN', "RTEN", ""), @@ -78,7 +78,7 @@ class PanelSettings1(PropertyGroup): ) addWDBlockType_enum = EnumProperty( - name="Тип блока", + name="Block type", items=[ ('way', "Way", ""), ('room', "Room", ""), ('rseg', "Road segment", ""), @@ -88,58 +88,58 @@ class PanelSettings1(PropertyGroup): ) attr_int_0 = IntProperty( - name = "Параметр 1", - description="Тип дороги", + name = "Param 1", + description="Road type", default = 1, min = 0 ) attr_dbl_0 = FloatProperty( - name = "Граница дороги", + name = "Road border", description="A integer property", default = 0, min = 0 ) attr_int_1 = IntProperty( - name = "Параметр 3", + name = "Param 3", description="-", default = 1, min = 0 ) wdth_dbl_0 = FloatProperty( - name = "Параметр 1", + name = "Param 1", description="", min = 0 ) wdth_dbl_1 = FloatProperty( - name = "Параметр 2", + name = "Param 2", description="", min = 0 ) flag_int = IntProperty( - name = "Флаг", + name = "Flag", description="", min = 0, ) name_string = StringProperty( - name="Имя объекта", + name="Object name", default="", maxlen=20, ) ########################################## mnam_string = StringProperty( - name="Имя карты", + name="Map name", default="aa", maxlen=2, ) rnam_string = StringProperty( - name="Имя комнаты", + name="Room name", default="room_aa_000", maxlen=20, ) @@ -151,42 +151,42 @@ class PanelSettings1(PropertyGroup): ) wdth_val = FloatProperty( - name = "Ширина дороги", + name = "Road width", description="", default=14, min = 0, ) attr_1 = IntProperty( - name = "Тип дороги", + name = "Road type", description="", default = 1, min = 0 ) attr_2 = FloatProperty( - name = "Граница дороги", + name = "Road border", description="", default = 0.1, min = 0 ) attr_3 = IntProperty( - name = "Параметр 3", + name = "Param 3", description="", default = 1, min = 0 ) flag_val = IntProperty( - name = "Флаг", + name = "Flag", description="", min = 0, ) class AddOperator1(bpy.types.Operator): bl_idname = "wm.add_operator1" - bl_label = "Добавить блок на сцену" + bl_label = "Add block to scene" def execute(self, context): scene = context.scene @@ -261,7 +261,7 @@ def execute(self, context): class SetValuesOperator1(bpy.types.Operator): bl_idname = "wm.set_values_operator1" - bl_label = "Сохранить настройки блока" + bl_label = "Save block values" def execute(self, context): scene = context.scene @@ -282,7 +282,7 @@ def execute(self, context): class AddOperator11(bpy.types.Operator): bl_idname = "wm.add_operator11" - bl_label = "Добавить объект на сцену" + bl_label = "Add object to scene" def execute(self, context): scene = context.scene @@ -350,7 +350,7 @@ def execute(self, context): class OBJECT_PT_way_add_panel(Panel): bl_idname = "OBJECT_PT_way_add_panel" - bl_label = "Добавление блоков" + bl_label = "Add blocks" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "way Tools" @@ -367,7 +367,7 @@ def draw(self, context): global blockW_type blockW_type = waytool.addWBlockType_enum - self.layout.label(text="Тип блока:") + self.layout.label(text="Block type:") layout.prop(waytool, "addWBlockType_enum", text="") if blockW_type == "ATTR": @@ -395,7 +395,7 @@ def draw(self, context): class GetValuesOperator1(bpy.types.Operator): bl_idname = "wm.get_values_operator1" - bl_label = "Получить настройки блока" + bl_label = "Get block values" def execute(self, context): scene = context.scene @@ -428,7 +428,7 @@ def execute(self, context): class OBJECT_PT_way_edit_panel(Panel): bl_idname = "OBJECT_PT_way_edit_panel" - bl_label = "Редактирование блоков" + bl_label = "Block edit" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "way Tools" @@ -471,7 +471,7 @@ def draw(self, context): class OBJECT_PT_way_misc_panel(Panel): bl_idname = "OBJECT_PT_way_misc_panel" - bl_label = "О плагине" + bl_label = "About add-on" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "way Tools" @@ -486,12 +486,12 @@ def draw(self, context): scene = context.scene waytool = scene.way_tool - self.layout.label(text="Автор плагина: aleko2144") + self.layout.label(text="Plugin author: aleko2144") self.layout.label(text="vk.com/rnr_mods") class OBJECT_PT_blocks_panel(Panel): bl_idname = "OBJECT_PT_blocks_panel" - bl_label = "Создание блоков" + bl_label = "Adding blocks" bl_space_type = "VIEW_3D" bl_region_type = getRegion() bl_category = "way Tools" From 00ca18d849c86fafa15418d514c67dce9c9ff474 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Wed, 1 Feb 2023 23:59:56 +0200 Subject: [PATCH 37/47] various QoL fixes --- src/2.80/addons/b3d_tools/__init__.py | 2 + src/2.80/addons/b3d_tools/b3d/class_descr.py | 163 +++++++++- src/2.80/addons/b3d_tools/b3d/common.py | 15 +- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 77 +++-- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 176 +++++----- src/2.80/addons/b3d_tools/b3d/panel.py | 159 ++++++---- src/2.80/addons/b3d_tools/b3d/scripts.py | 318 +++++++++---------- src/2.80/addons/b3d_tools/consts.py | 10 + 8 files changed, 561 insertions(+), 359 deletions(-) diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py index bf83362..9406522 100644 --- a/src/2.80/addons/b3d_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -25,6 +25,7 @@ # importlib.reload(material_UIList) importlib.reload(custom_UIList) importlib.reload(common) + importlib.reload(consts) importlib.reload(way) importlib.reload(tch) importlib.reload(b3d) @@ -35,6 +36,7 @@ # material_UIList, custom_UIList, common, + consts, way, tch, b3d diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index f334531..eab9c69 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -22,7 +22,9 @@ from ..consts import ( collisionTypeList, generatorTypeList, - b24FlagList + b24FlagList, + BLOCK_TYPE, + LEVEL_GROUP ) # Dynamic block exmaple @@ -49,6 +51,7 @@ class fieldType(enum.Enum): + IGNORE = 0 STRING = 1 COORD = 2 RAD = 3 @@ -156,6 +159,63 @@ class ResBlock(bpy.types.PropertyGroup): materials: CollectionProperty(type=MaterialBlock) maskfiles: CollectionProperty(type=MaskfileBlock) +borderSphereGroup = 'border_sphere' + +# class_descr configuration: + +# prop - Required - Key used to save property in Blenders custom properties. +# group - Optional - Used to determine what elements to group together. +# type - Required - Type of the field. +# Type specific configurations + +# fieldType.STRING + # 'name': 'name', + # 'description': '', + # 'default': '' + +# fieldType.COORD + # 'name': 'Name', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + +# fieldType.INT + # 'name': 'Name', + # 'description': '', + # 'default': 0 + +# fieldType.FLOAT + # 'name': 'Name', + # 'description': '', + # 'default': 0.0 + +# fieldType.ENUM - static + # 'subtype': fieldType.INT, + # 'name': 'Name', + # 'description': '' + +# fieldType.LIST + # 'name': 'Name', + # 'description': '' + +# fieldType.ENUM_STR - dynamic + # 'subtype': fieldType.SPACE_NAME, + # 'name': 'Name', + # 'description': '' + +# fieldType.V_FORMAT + +# Used as subtypes +# fieldType.MATERIAL_IND +# fieldType.SPACE_NAME +# fieldType.REFERENCEABLE +# fieldType.ROOM +# fieldType.RES_MODULE + +# Custom operators +# fieldType.SPHERE_EDIT + + + class pvb_8(): Normal_Switch = { @@ -254,7 +314,7 @@ class pfb_35(): class b_common(): LevelGroup = { - 'prop': 'level_group', + 'prop': LEVEL_GROUP, 'type': fieldType.INT, 'name': 'Block group', 'description': '', @@ -280,6 +340,7 @@ class b_1(): class b_2(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -287,6 +348,7 @@ class b_2(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -294,6 +356,7 @@ class b_2(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ = { @@ -314,6 +377,7 @@ class b_2(): class b_3(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -321,6 +385,7 @@ class b_3(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -328,12 +393,14 @@ class b_3(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } class b_4(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -341,6 +408,7 @@ class b_4(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -348,6 +416,7 @@ class b_4(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Name1 = { @@ -375,6 +444,7 @@ class b_5(): } XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -382,6 +452,7 @@ class b_5(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -389,6 +460,7 @@ class b_5(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } @@ -396,6 +468,7 @@ class b_5(): class b_6(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -403,6 +476,7 @@ class b_6(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -410,6 +484,7 @@ class b_6(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Name1 = { @@ -430,6 +505,7 @@ class b_6(): class b_7(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -437,6 +513,7 @@ class b_7(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -444,6 +521,7 @@ class b_7(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Name1 = { @@ -457,6 +535,7 @@ class b_7(): class b_8(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -464,6 +543,7 @@ class b_8(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -471,12 +551,14 @@ class b_8(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } class b_9(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -484,6 +566,7 @@ class b_9(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -491,6 +574,7 @@ class b_9(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ = { @@ -511,6 +595,7 @@ class b_9(): class b_10(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -518,6 +603,7 @@ class b_10(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -525,6 +611,7 @@ class b_10(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } LOD_XYZ = { @@ -545,6 +632,7 @@ class b_10(): class b_11(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -552,6 +640,7 @@ class b_11(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -559,6 +648,7 @@ class b_11(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ = { @@ -579,6 +669,7 @@ class b_11(): class b_12(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -586,6 +677,7 @@ class b_12(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -593,6 +685,7 @@ class b_12(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ = { @@ -633,6 +726,7 @@ class b_12(): class b_13(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -640,6 +734,7 @@ class b_13(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -647,6 +742,7 @@ class b_13(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_Int1 = { @@ -673,6 +769,7 @@ class b_13(): class b_14(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -680,6 +777,7 @@ class b_14(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -687,6 +785,7 @@ class b_14(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ = { @@ -727,6 +826,7 @@ class b_14(): class b_15(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -734,6 +834,7 @@ class b_15(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -741,6 +842,7 @@ class b_15(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_Int1 = { @@ -767,6 +869,7 @@ class b_15(): class b_16(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -774,6 +877,7 @@ class b_16(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -781,6 +885,7 @@ class b_16(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ1 = { @@ -835,6 +940,7 @@ class b_16(): class b_17(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -842,6 +948,7 @@ class b_17(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -849,6 +956,7 @@ class b_17(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ1 = { @@ -903,6 +1011,7 @@ class b_17(): class b_18(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -910,6 +1019,7 @@ class b_18(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -917,6 +1027,7 @@ class b_18(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Space_Name = { @@ -937,6 +1048,7 @@ class b_18(): class b_20(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -944,6 +1056,7 @@ class b_20(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -951,6 +1064,7 @@ class b_20(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_Int1 = { @@ -977,6 +1091,7 @@ class b_20(): class b_21(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -984,6 +1099,7 @@ class b_21(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -991,6 +1107,7 @@ class b_21(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } GroupCnt = { @@ -1011,6 +1128,7 @@ class b_21(): class b_22(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1018,6 +1136,7 @@ class b_22(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1025,6 +1144,7 @@ class b_22(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ = { @@ -1145,6 +1265,7 @@ class b_25(): class b_26(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1152,6 +1273,7 @@ class b_26(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1159,6 +1281,7 @@ class b_26(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ1 = { @@ -1186,6 +1309,7 @@ class b_26(): class b_27(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1193,6 +1317,7 @@ class b_27(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1200,6 +1325,7 @@ class b_27(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Flag = { @@ -1227,6 +1353,7 @@ class b_27(): class b_28(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1234,6 +1361,7 @@ class b_28(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1241,6 +1369,7 @@ class b_28(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_XYZ = { @@ -1255,6 +1384,7 @@ class b_28(): class b_29(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1262,6 +1392,7 @@ class b_29(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1269,6 +1400,7 @@ class b_29(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_Int1 = { @@ -1303,6 +1435,7 @@ class b_29(): class b_30(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1310,6 +1443,7 @@ class b_30(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1317,6 +1451,7 @@ class b_30(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } ResModule1 = { @@ -1355,6 +1490,7 @@ class b_30(): class b_31(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1362,6 +1498,7 @@ class b_31(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1369,6 +1506,7 @@ class b_31(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Unk_Int1 = { @@ -1411,6 +1549,7 @@ class b_31(): class b_33(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1418,6 +1557,7 @@ class b_33(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1425,6 +1565,7 @@ class b_33(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Use_Lights = { @@ -1516,6 +1657,7 @@ class b_33(): class b_34(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1523,6 +1665,7 @@ class b_34(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1530,6 +1673,7 @@ class b_34(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } UnkInt = { @@ -1543,6 +1687,7 @@ class b_34(): class b_35(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1550,6 +1695,7 @@ class b_35(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1557,6 +1703,7 @@ class b_35(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } MType = { @@ -1577,6 +1724,7 @@ class b_35(): class b_36(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1584,6 +1732,7 @@ class b_36(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1591,6 +1740,7 @@ class b_36(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Name1 = { @@ -1618,6 +1768,7 @@ class b_36(): class b_37(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1625,6 +1776,7 @@ class b_37(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1632,6 +1784,7 @@ class b_37(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Name1 = { @@ -1652,6 +1805,7 @@ class b_37(): class b_39(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1659,6 +1813,7 @@ class b_39(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1666,6 +1821,7 @@ class b_39(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Color_R = { @@ -1707,6 +1863,7 @@ class b_39(): class b_40(): XYZ = { 'prop': 'b3d_border_center', + 'group': borderSphereGroup, 'type': fieldType.COORD, 'name': 'Block border coord', 'description': '', @@ -1714,6 +1871,7 @@ class b_40(): } R = { 'prop': 'b3d_border_rad', + 'group': borderSphereGroup, 'type': fieldType.RAD, 'name': 'Block border rad', 'description': '', @@ -1721,6 +1879,7 @@ class b_40(): } Set_Bound = { 'prop': 'b3d_border', + 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } Name1 = { diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index c06d82e..41479a3 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -7,7 +7,10 @@ import time from ..common import log -from ..consts import EMPTY_NAME +from ..consts import ( + BLOCK_TYPE, + EMPTY_NAME +) def getNonCopyName(name): reIsCopy = re.compile(r'\.[0-9]*$') @@ -291,12 +294,10 @@ def referenceablesCallback(self, context): mytool = context.scene.my_tool rootObj = getRootObj(context.object) - referenceables = [cn for cn in rootObj.children if cn.get('block_type') != 24] + referenceables = [cn for cn in rootObj.children if cn.get(BLOCK_TYPE) != 24] enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(referenceables)] - print("fetched referenceables") - return enumProperties def spacesCallback(self, context): @@ -304,12 +305,10 @@ def spacesCallback(self, context): mytool = context.scene.my_tool rootObj = getRootObj(context.object) - spaces = [cn for cn in bpy.data.objects if cn.get('block_type') == 24 and getRootObj(cn) == rootObj] + spaces = [cn for cn in bpy.data.objects if cn.get(BLOCK_TYPE) == 24 and getRootObj(cn) == rootObj] enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(spaces)] - print("fetched spaces") - return enumProperties def resMaterialsCallback(self, context): @@ -335,7 +334,7 @@ def callback_func(self, context): rootObj = bpy.data.objects.get('{}.b3d'.format(resModule)) if rootObj: - rooms = [cn for cn in rootObj.children if cn.get('block_type') == 19] + rooms = [cn for cn in rootObj.children if cn.get(BLOCK_TYPE) == 19] enumProperties = [(cn.name, cn.name, "") for i, cn in enumerate(rooms)] diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index 0e5cd6b..a260945 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -61,13 +61,19 @@ pfb_28, pfb_35, pvb_8, - pvb_35 + pvb_35, + b_common ) from .scripts import ( prop ) +from ..consts import ( + LEVEL_GROUP, + BLOCK_TYPE +) + from ..common import ( log ) @@ -244,7 +250,7 @@ def createBorderList(self): self.borders = {} - borderBlocks = [cn for cn in bpy.data.objects if cn.get('block_type') == 30 \ + borderBlocks = [cn for cn in bpy.data.objects if cn.get(BLOCK_TYPE) == 30 \ and (cn.get(prop(b_30.ResModule1)) == self.currentRes or cn.get(prop(b_30.ResModule2)) == self.currentRes)] for bb in borderBlocks: @@ -327,8 +333,8 @@ def export(self, filepath): else: allObjs = [obj] - spaces = [cn for cn in allObjs if cn['block_type'] == 24] - other = [cn for cn in allObjs if cn['block_type'] != 24] + spaces = [cn for cn in allObjs if cn[BLOCK_TYPE] == 24] + other = [cn for cn in allObjs if cn[BLOCK_TYPE] != 24] rChild = [] rChild.extend(spaces) @@ -355,18 +361,18 @@ def export(self, filepath): # prevLevel = 0 if len(rChild) > 0: for obj in rChild[:-1]: - if obj['block_type'] == 10 or obj['block_type'] == 9: + if obj[BLOCK_TYPE] == 10 or obj[BLOCK_TYPE] == 9: curMaxCnt = 2 - elif obj['block_type'] == 21: + elif obj[BLOCK_TYPE] == 21: curMaxCnt = obj[prop(b_21.GroupCnt)] self.exportBlock(obj, False, curLevel, curMaxCnt, [0], {}, file) file.write(struct.pack(" curGroups[curLevel]: + if block[LEVEL_GROUP] > curGroups[curLevel]: log.debug('group ended') - for i in range(block['level_group'] - curGroups[curLevel]): + for i in range(block[LEVEL_GROUP] - curGroups[curLevel]): file.write(struct.pack(" 1: nextState = isActive and True if clevel == 1: - if directChild['level_group'] == l_group or l_group == -1: + if directChild[LEVEL_GROUP] == l_group or l_group == -1: stack.append([directChild, clevel+1, glevel, groupMax, nextState]) else: stack.append([directChild, clevel+1, glevel, groupMax, False]) @@ -444,6 +455,11 @@ def createRadDriver(srcObj, bname, pname): def showHideSphere(context, root, pname): + transfCollection = bpy.data.collections.get(TEMP_COLLECTION) + if transfCollection is None: + transfCollection = bpy.data.collections.new(TEMP_COLLECTION) + bpy.context.scene.collection.children.link(transfCollection) + objName = "{}||{}||{}".format(root.name, pname, 'temp') b3dObj = bpy.data.objects.get(objName) @@ -452,7 +468,7 @@ def showHideSphere(context, root, pname): bpy.data.objects.remove(b3dObj, do_unlink=True) else: - bnum = root.get('block_type') + bnum = root.get(BLOCK_TYPE) centerName = "{}_center".format(pname) radName = "{}_rad".format(pname) @@ -468,7 +484,7 @@ def showHideSphere(context, root, pname): b3dObj.location = center b3dObj.parent = root.parent - context.collection.objects.link(b3dObj) + transfCollection.objects.link(b3dObj) # center driver bname = getMytoolBlockName('b', bnum) @@ -481,11 +497,11 @@ def showHideSphere(context, root, pname): def drawCommon(l_self, obj): block_type = None level_group = None - if 'block_type' in obj: - block_type = obj['block_type'] + if BLOCK_TYPE in obj: + block_type = obj[BLOCK_TYPE] - if 'level_group' in obj: - level_group = obj['level_group'] + if LEVEL_GROUP in obj: + level_group = obj[LEVEL_GROUP] lenStr = str(len(obj.children)) @@ -502,144 +518,122 @@ def drawAllFieldsByType(l_self, context, zclass): drawFieldsByType(l_self, context, zclass) def drawFieldsByType(l_self, context, zclass): - # btype = zclass.__name__.split('_')[1] - # bname = "block{}".format(btype) attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + boxes = {} for attr in attrs: obj = zclass.__dict__[attr] - drawFieldByType(l_self, context, obj, zclass) - -def drawFieldByType(l_self, context, obj, zclass): + bname, bnum = getMytoolBlockNameByClass(zclass) - bname, bnum = getMytoolBlockNameByClass(zclass) - - ftype = obj['type'] - subtype = obj.get('subtype') - pname = obj['prop'] - mytool = context.scene.my_tool + ftype = obj['type'] + subtype = obj.get('subtype') + curGroupName = obj.get('group') + pname = obj['prop'] + mytool = context.scene.my_tool + curLayout = l_self.layout - if ftype == fieldType.SPHERE_EDIT: - box = l_self.layout.box() - col = box.column() + if curGroupName is not None: + if boxes.get(curGroupName) is None: + boxes[curGroupName] = l_self.layout.box() + curLayout = boxes[curGroupName] - props = col.operator("wm.show_hide_sphere_operator") - props.pname = pname - elif ftype == fieldType.STRING \ - or ftype == fieldType.COORD \ - or ftype == fieldType.RAD \ - or ftype == fieldType.INT \ - or ftype == fieldType.FLOAT \ - or ftype == fieldType.ENUM \ - or ftype == fieldType.ENUM_STR \ - or ftype == fieldType.LIST: + if ftype == fieldType.SPHERE_EDIT: + box = curLayout.box() + col = box.column() - box = l_self.layout.box() - box.prop(getattr(mytool, bname), "show_"+pname) - - col = box.column() - if ftype == fieldType.STRING: - col.prop(getattr(mytool, bname), pname) - - elif ftype == fieldType.COORD: - col.prop(getattr(mytool, bname), pname) + props = col.operator("wm.show_hide_sphere_operator") + props.pname = pname - elif ftype == fieldType.RAD: - col.prop(getattr(mytool, bname), pname) + elif ftype == fieldType.STRING \ + or ftype == fieldType.COORD \ + or ftype == fieldType.RAD \ + or ftype == fieldType.INT \ + or ftype == fieldType.FLOAT \ + or ftype == fieldType.ENUM \ + or ftype == fieldType.ENUM_STR \ + or ftype == fieldType.LIST: - elif ftype == fieldType.INT: - col.prop(getattr(mytool, bname), pname) + box = curLayout.box() + box.prop(getattr(mytool, bname), "show_"+pname) - elif ftype == fieldType.FLOAT: - col.prop(getattr(mytool, bname), pname) + col = box.column() + if ftype == fieldType.STRING: + col.prop(getattr(mytool, bname), pname) - elif ftype == fieldType.ENUM: - col.prop(getattr(mytool, bname), pname) + elif ftype == fieldType.COORD: + col.prop(getattr(mytool, bname), pname) - elif ftype == fieldType.ENUM_STR: - col.prop(getattr(mytool, bname), '{}_switch'.format(pname)) + elif ftype == fieldType.RAD: + col.prop(getattr(mytool, bname), pname) - if(getattr(getattr(mytool, bname), '{}_switch'.format(pname))): - col.prop(getattr(mytool, bname), '{}_enum'.format(pname)) - else: + elif ftype == fieldType.INT: col.prop(getattr(mytool, bname), pname) - elif ftype == fieldType.LIST: - collect = getattr(mytool, bname) + elif ftype == fieldType.FLOAT: + col.prop(getattr(mytool, bname), pname) - scn = bpy.context.scene + elif ftype == fieldType.ENUM: + col.prop(getattr(mytool, bname), pname) - rows = 2 - row = box.row() - row.template_list("CUSTOM_UL_items", "", collect, pname, scn, "custom_index", rows=rows) + elif ftype == fieldType.ENUM_STR: + col.prop(getattr(mytool, bname), '{}_switch'.format(pname)) - col = row.column(align=True) - props = col.operator("custom.list_action", icon='ADD', text="") - props.action = 'ADD' - props.bname = bname - props.pname = pname - props.customindex = "custom_index" - props = col.operator("custom.list_action", icon='REMOVE', text="") - props.action = 'REMOVE' - props.bname = bname - props.pname = pname - props.customindex = "custom_index" - col.separator() - props = col.operator("custom.list_action", icon='TRIA_UP', text="") - props.action = 'UP' - props.bname = bname - props.pname = pname - props.customindex = "custom_index" - props = col.operator("custom.list_action", icon='TRIA_DOWN', text="") - props.action = 'DOWN' - props.bname = bname - props.pname = pname - props.customindex = "custom_index" - - - # row = box.row() - # col = row.column(align=True) - # row = col.row(align=True) - # row.operator("custom.print_items", icon="LINENUMBERS_ON") - # row = col.row(align=True) - # row.operator("custom.clear_list", icon="X") - # row.operator("custom.remove_duplicates", icon="GHOST_ENABLED") - - # row = box.row() - # col = row.column(align=True) - # row = col.row(align=True) - # row.operator("custom.add_viewport_selection", icon="HAND") #LINENUMBERS_OFF, ANIM - # row = col.row(align=True) - # row.operator("custom.select_items", icon="VIEW3D", text="Select Item in 3D View") - # row.operator("custom.select_items", icon="GROUP", text="Select All Items in 3D View").select_all = True - # row = col.row(align=True) - # row.operator("custom.delete_object", icon="X") - - # collect = getattr(getattr(mytool, bname), pname) - # print(dir(collect)) - # for item in collect.items(): - # print(item) - # col.prop(item, "value") - - if getattr(getattr(mytool, bname), "show_"+pname): - col.enabled = True - else: - col.enabled = False - - elif ftype == fieldType.V_FORMAT: - box = l_self.layout.box() - box.prop(getattr(mytool, bname), "show_{}".format(pname)) - col1 = box.column() - col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'triang_offset')) - col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_uvs')) - col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_normals')) - col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'normal_flag')) - - if getattr(getattr(mytool, bname), "show_"+pname): - col1.enabled = True - else: - col1.enabled = False + if(getattr(getattr(mytool, bname), '{}_switch'.format(pname))): + col.prop(getattr(mytool, bname), '{}_enum'.format(pname)) + else: + col.prop(getattr(mytool, bname), pname) + + elif ftype == fieldType.LIST: + collect = getattr(mytool, bname) + + scn = bpy.context.scene + + rows = 2 + row = box.row() + row.template_list("CUSTOM_UL_items", "", collect, pname, scn, "custom_index", rows=rows) + + col = row.column(align=True) + props = col.operator("custom.list_action", icon='ADD', text="") + props.action = 'ADD' + props.bname = bname + props.pname = pname + props.customindex = "custom_index" + props = col.operator("custom.list_action", icon='REMOVE', text="") + props.action = 'REMOVE' + props.bname = bname + props.pname = pname + props.customindex = "custom_index" + col.separator() + props = col.operator("custom.list_action", icon='TRIA_UP', text="") + props.action = 'UP' + props.bname = bname + props.pname = pname + props.customindex = "custom_index" + props = col.operator("custom.list_action", icon='TRIA_DOWN', text="") + props.action = 'DOWN' + props.bname = bname + props.pname = pname + props.customindex = "custom_index" + + if getattr(getattr(mytool, bname), "show_"+pname): + col.enabled = True + else: + col.enabled = False + + elif ftype == fieldType.V_FORMAT: + box = curLayout.box() + box.prop(getattr(mytool, bname), "show_{}".format(pname)) + col1 = box.column() + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'triang_offset')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_uvs')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_normals')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'normal_flag')) + + if getattr(getattr(mytool, bname), "show_"+pname): + col1.enabled = True + else: + col1.enabled = False def getAllObjsByType(context, object, zclass): getObjsByType(context, object, b_common) @@ -650,13 +644,10 @@ def getObjsByType(context, object, zclass): bname, bnum = getMytoolBlockNameByClass(zclass) - # btype = zclass.__name__.split('_')[1] - # bname = "block{}".format(btype) mytool = context.scene.my_tool for property in attrs: obj = zclass.__dict__[property] - # print(dir(getattr(mytool, bname))) if obj['type'] != fieldType.SPHERE_EDIT: if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ and getattr(getattr(mytool, bname), "show_"+obj['prop']): @@ -681,12 +672,6 @@ def getObjsByType(context, object, zclass): elif obj['type'] == fieldType.ENUM \ or obj['type'] == fieldType.ENUM_STR: - # if obj['subtype'] == fieldType.INT \ - # or obj['subtype'] == fieldType.STRING \ - # or obj['subtype'] == fieldType.FLOAT \ - # or obj['subtype'] == fieldType.SPACE_NAME \ - # or obj['subtype'] == fieldType.REFERENCEABLE \ - # or obj['subtype'] == fieldType.MATERIAL_IND: setattr( getattr(mytool, bname), obj['prop'], @@ -702,7 +687,6 @@ def getObjsByType(context, object, zclass): item = col.add() item.index = i item.value = obj - # getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) else: setattr( @@ -719,8 +703,6 @@ def setObjsByType(context, object, zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] bname, bnum = getMytoolBlockNameByClass(zclass) - # btype = zclass.__name__.split('_')[1] - # bname = "block{}".format(btype) mytool = context.scene.my_tool for property in attrs: obj = zclass.__dict__[property] @@ -843,8 +825,6 @@ def getPerFaceByType(context, object, zclass): bname, bnum = getMytoolBlockNameByClass(zclass) - # btype = zclass.__name__.split('_')[1] - # bname = "perFaceBlock{}".format(btype) mesh = object.data bpy.ops.object.mode_set(mode = 'OBJECT') polygons = getPolygonsBySelectedVertices(object) @@ -864,12 +844,9 @@ def getPerVertexByType(context, object, zclass): bname, bnum = getMytoolBlockNameByClass(zclass) - # btype = zclass.__name__.split('_')[1] - # bname = "perVertBlock{}".format(btype) mesh = object.data bpy.ops.object.mode_set(mode = 'OBJECT') vertices = getSelectedVertices(object) - # log.debug(vertices) indexes = [cn.index for cn in vertices] if len(indexes) > 0: @@ -886,8 +863,6 @@ def setPerVertexByType(context, object, zclass): bname, bnum = getMytoolBlockNameByClass(zclass) - # btype = zclass.__name__.split('_')[1] - # bname = "perVertBlock{}".format(btype) mesh = object.data bpy.ops.object.mode_set(mode = 'OBJECT') @@ -907,8 +882,6 @@ def setPerFaceByType(context, object, zclass): bname, bnum = getMytoolBlockNameByClass(zclass) - # btype = zclass.__name__.split('_')[1] - # bname = "perFaceBlock{}".format(btype) mesh = object.data bpy.ops.object.mode_set(mode = 'OBJECT') @@ -924,7 +897,6 @@ def setPerFaceByType(context, object, zclass): bpy.ops.object.mode_set(mode = 'EDIT') def createCustomAttribute(mesh, values, zclass, zobj): - # attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] ctype, btype = zclass.__name__.split('_') domain = '' if ctype == 'pvb': diff --git a/src/2.80/addons/b3d_tools/consts.py b/src/2.80/addons/b3d_tools/consts.py index 88d26e4..651a27f 100644 --- a/src/2.80/addons/b3d_tools/consts.py +++ b/src/2.80/addons/b3d_tools/consts.py @@ -1,6 +1,16 @@ EMPTY_NAME = '~' +LEVEL_GROUP = 'level_group' + +BLOCK_TYPE = 'block_type' + +TRANSF_COLLECTION = 'Transformed objects' + +TEMP_COLLECTION = 'Temporary objects' + +BORDER_COLLECTION = 'Border objects' + blockTypeList = [ ('6566754', "b3d", "b3d"), ('00', "00", "2D background"), From 0c55395d159c24f0701c46a98e6e65bc1a037c52 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 4 Feb 2023 03:22:32 +0200 Subject: [PATCH 38/47] custom properties direct edit --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 70 +++++-- src/2.80/addons/b3d_tools/b3d/classes.py | 105 ++++++---- src/2.80/addons/b3d_tools/b3d/common.py | 2 +- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 193 +++++++---------- src/2.80/addons/b3d_tools/b3d/panel.py | 63 +++++- src/2.80/addons/b3d_tools/b3d/scripts.py | 210 +++++++++++-------- src/2.80/addons/b3d_tools/consts.py | 2 +- 7 files changed, 368 insertions(+), 277 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index eab9c69..3bf532a 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -59,7 +59,7 @@ class fieldType(enum.Enum): FLOAT = 5 ENUM = 6 LIST = 7 - ENUM_STR = 8 + ENUM_DYN = 8 V_FORMAT = 21 MATERIAL_IND = 22 @@ -197,7 +197,7 @@ class ResBlock(bpy.types.PropertyGroup): # 'name': 'Name', # 'description': '' -# fieldType.ENUM_STR - dynamic +# fieldType.ENUM_DYN - dynamic # 'subtype': fieldType.SPACE_NAME, # 'name': 'Name', # 'description': '' @@ -421,8 +421,9 @@ class b_4(): } Name1 = { 'prop': 'name1', - 'type': fieldType.ENUM_STR, - 'subtype': fieldType.SPACE_NAME, + 'type': fieldType.ENUM_DYN, + 'subtype': fieldType.STRING, + 'callback': fieldType.SPACE_NAME, 'name': 'Place', 'description': '' } @@ -578,19 +579,26 @@ class b_9(): 'type': fieldType.SPHERE_EDIT } Unk_XYZ = { - 'prop': 'unk_XYZ', + 'prop': 'b3d_b9_center', + 'group': 'b9_group', 'type': fieldType.COORD, 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } Unk_R = { - 'prop': 'unk_R', + 'prop': 'b3d_b9_rad', + 'group': 'b9_group', 'type': fieldType.RAD, 'name': 'Unk. rad', 'description': '', 'default': 0.0 } + Set_B9 = { + 'prop': 'b3d_b9', + 'group': 'b9_group', + 'type': fieldType.SPHERE_EDIT + } class b_10(): XYZ = { @@ -615,19 +623,26 @@ class b_10(): 'type': fieldType.SPHERE_EDIT } LOD_XYZ = { - 'prop': 'LOD_XYZ', + 'prop': 'b3d_LOD_center', + 'group': 'LOD_group', 'type': fieldType.COORD, 'name': 'LOD coord', 'description': '', 'default': (0.0, 0.0, 0.0) } LOD_R = { - 'prop': 'LOD_R', + 'prop': 'b3d_LOD_rad', + 'group': 'LOD_group', 'type': fieldType.RAD, 'name': 'LOD rad', 'description': '', 'default': 0.0 } + Set_LOD = { + 'prop': 'b3d_LOD', + 'group': 'LOD_group', + 'type': fieldType.SPHERE_EDIT + } class b_11(): XYZ = { @@ -1032,15 +1047,17 @@ class b_18(): } Space_Name = { 'prop': 'space_name', - 'type': fieldType.ENUM, - 'subtype': fieldType.SPACE_NAME, + 'type': fieldType.ENUM_DYN, + 'subtype': fieldType.STRING, + 'callback': fieldType.SPACE_NAME, 'name': 'Place name (24)', 'description': '' } Add_Name = { 'prop': 'add_name', - 'type': fieldType.ENUM, - 'subtype': fieldType.REFERENCEABLE, + 'type': fieldType.ENUM_DYN, + 'subtype': fieldType.STRING, + 'callback': fieldType.REFERENCEABLE, 'name': 'Transfer block name', 'description': '' } @@ -1456,32 +1473,40 @@ class b_30(): } ResModule1 = { 'prop': '1_roomName_res', - 'type': fieldType.ENUM_STR, - 'subtype': fieldType.RES_MODULE, + 'group': 'resModule1', + 'type': fieldType.ENUM_DYN, + 'subtype': fieldType.STRING, + 'callback': fieldType.RES_MODULE, 'name': '1. module', 'description': '', 'default': '' } RoomName1 = { 'prop': '1_roomName', - 'type': fieldType.ENUM_STR, - 'subtype': fieldType.ROOM, + 'group': 'resModule1', + 'type': fieldType.ENUM_DYN, + 'subtype': fieldType.STRING, + 'callback': fieldType.ROOM, 'name': '1. room', 'description': '', 'default': '' } ResModule2 = { 'prop': '2_roomName_res', - 'type': fieldType.ENUM_STR, - 'subtype': fieldType.RES_MODULE, + 'group': 'resModule2', + 'type': fieldType.ENUM_DYN, + 'subtype': fieldType.STRING, + 'callback': fieldType.RES_MODULE, 'name': '2. module', 'description': '', 'default': '' } RoomName2 = { 'prop': '2_roomName', - 'type': fieldType.ENUM_STR, - 'subtype': fieldType.ROOM, + 'group': 'resModule2', + 'type': fieldType.ENUM_DYN, + 'subtype': fieldType.STRING, + 'callback': fieldType.ROOM, 'name': '2. room', 'description': '', 'default': '' @@ -1715,8 +1740,9 @@ class b_35(): } TexNum = { 'prop': 'texnum', - 'type': fieldType.ENUM, - 'subtype': fieldType.MATERIAL_IND, + 'type': fieldType.ENUM_DYN, + 'subtype': fieldType.INT, + 'callback': fieldType.MATERIAL_IND, 'name': 'Texture', 'description': '', } diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index b002945..62c0fdc 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -72,17 +72,26 @@ ) -def setStrValue(bname, pname): - def callback_func(self, context): +def setCustObjValue(subtype, bname, pname): + def callback_func(self, context): + + mytool = context.scene.my_tool + result = getattr(getattr(mytool, bname), '{}_enum'.format(pname)) + if subtype == fieldType.INT: + result = int(result) + elif subtype == fieldType.FLOAT: + result = float(result) + elif subtype == fieldType.FLOAT: + result = str(result) + + setattr( + bpy.context.object, + '["{}"]'.format(pname), + result + ) - mytool = context.scene.my_tool - setattr( - getattr(mytool, bname), - '{}'.format(pname), - getattr(getattr(mytool, bname), '{}_enum'.format(pname)) - ) + return callback_func - return callback_func def createTypeClass(zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] @@ -114,7 +123,7 @@ def createTypeClass(zclass): or obj['type'] == fieldType.LIST: - attributes['__annotations__']["show_"+pname] = lockProp + # attributes['__annotations__']["show_"+pname] = lockProp if obj['type'] == fieldType.STRING: prop = StringProperty( @@ -155,67 +164,79 @@ def createTypeClass(zclass): attributes['__annotations__'][pname] = prop elif obj['type'] == fieldType.ENUM \ - or obj['type'] == fieldType.ENUM_STR: + or obj['type'] == fieldType.ENUM_DYN: - attributes['__annotations__']["show_"+pname] = lockProp + # attributes['__annotations__']["show_"+pname] = lockProp enum_callback = None + subtype = obj.get('subtype') - if obj.get('subtype') == fieldType.SPACE_NAME: + if obj.get('callback') == fieldType.SPACE_NAME: enum_callback = spacesCallback - elif obj.get('subtype') == fieldType.REFERENCEABLE: + elif obj.get('callback') == fieldType.REFERENCEABLE: enum_callback = referenceablesCallback - elif obj.get('subtype') == fieldType.MATERIAL_IND: + elif obj.get('callback') == fieldType.MATERIAL_IND: enum_callback = resMaterialsCallback - elif obj.get('subtype') == fieldType.ROOM: + elif obj.get('callback') == fieldType.ROOM: enum_callback = roomsCallback(bname, '{}_res'.format(pname)) - elif obj.get('subtype') == fieldType.RES_MODULE: + elif obj.get('callback') == fieldType.RES_MODULE: enum_callback = modulesCallback if obj['type'] == fieldType.ENUM: - prop = None - if enum_callback == None: - prop = EnumProperty( - name = obj['name'], - description = obj['description'], - default = obj['default'], - items = obj['items'] - ) - else: - prop = EnumProperty( - name = obj['name'], - description = obj['description'], - items = enum_callback - ) - - attributes['__annotations__'][pname] = prop - - elif obj['type'] == fieldType.ENUM_STR: - prop = None + # prop = None prop_enum = None prop_switch = None prop_switch = BoolProperty( name = 'Use dropdown', description = 'Dropdown selection', - default = False + default = True ) prop_enum = EnumProperty( name = obj['name'], description = obj['description'], - items = enum_callback, - update = setStrValue(bname, pname) + items = obj['items'], + default = obj['default'], + update = setCustObjValue(subtype, bname, pname) ) - prop = StringProperty( + # prop = EnumProperty( + # name = obj['name'], + # description = obj['description'], + # default = obj['default'], + # items = obj['items'] + # ) + + attributes['__annotations__']['{}_switch'.format(pname)] = prop_switch + attributes['__annotations__']['{}_enum'.format(pname)] = prop_enum + + elif obj['type'] == fieldType.ENUM_DYN: + # prop = None + prop_enum = None + prop_switch = None + + prop_switch = BoolProperty( + name = 'Use dropdown', + description = 'Dropdown selection', + default = True + ) + + prop_enum = EnumProperty( name = obj['name'], description = obj['description'], - maxlen = 32 + items = enum_callback, + update = setCustObjValue(subtype, bname, pname) ) + # prop = StringProperty( + # name = obj['name'], + # description = obj['description'], + # maxlen = 32 + # ) + attributes['__annotations__']['{}_switch'.format(pname)] = prop_switch attributes['__annotations__']['{}_enum'.format(pname)] = prop_enum - attributes['__annotations__']['{}'.format(pname)] = prop + # attributes['__annotations__']['{}'.format(pname)] = prop elif obj['type'] == fieldType.V_FORMAT: diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 41479a3..981336b 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -330,7 +330,7 @@ def callback_func(self, context): enumProperties = [] mytool = context.scene.my_tool - resModule = getattr(getattr(mytool, bname), pname) + resModule = context.object.path_resolve('["{}"]'.format(pname)) rootObj = bpy.data.objects.get('{}.b3d'.format(resModule)) if rootObj: diff --git a/src/2.80/addons/b3d_tools/b3d/import_b3d.py b/src/2.80/addons/b3d_tools/b3d/import_b3d.py index 661058d..b9de442 100644 --- a/src/2.80/addons/b3d_tools/b3d/import_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/import_b3d.py @@ -572,10 +572,10 @@ def read(file, context, self, filepath): b3dObj[LEVEL_GROUP] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dName + objString[-1] = b3dObj.name elif (type == 1): name1 = readName(file) #? @@ -591,10 +591,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_1.Name1)] = name1 b3dObj[prop(b_1.Name2)] = name2 - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 2): #контейнер хз @@ -614,10 +614,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_2.Unk_XYZ)] = unknown_sphere[0:3] b3dObj[prop(b_2.Unk_R)] = unknown_sphere[3] - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 3): # @@ -634,10 +634,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_3.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_3.R)] = bounding_sphere[3] - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 4): #похоже на контейнер 05 совмещенный с 12 @@ -658,10 +658,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_4.Name1)] = name1 b3dObj[prop(b_4.Name2)] = name2 - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 5): #общий контейнер @@ -680,10 +680,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_5.R)] = (bounding_sphere[3]) b3dObj[prop(b_5.Name1)] = name - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 6): vertexes = [] @@ -715,10 +715,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_6.Name1)] = name1 b3dObj[prop(b_6.Name2)] = name2 - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 7): #25? xyzuv TailLight? похоже на "хвост" движения mesh format = 0 @@ -755,10 +755,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_7.R)] = bounding_sphere[3] b3dObj[prop(b_7.Name1)] = groupName - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 8): #тоже фейсы face faces = [] @@ -945,10 +945,10 @@ def read(file, context, self, filepath): b3dObj['pos'] = pos b3dObj[prop(b_8.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_8.R)] = bounding_sphere[3] - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name if self.to_import_textures: #For assignMaterialByVertices just-in-case @@ -990,10 +990,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_9.Unk_XYZ)] = unknown_sphere[0:3] b3dObj[prop(b_9.Unk_R)] = unknown_sphere[3] - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 10): #контейнер, хз о чем LOD @@ -1013,10 +1013,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_10.LOD_XYZ)] = unknown_sphere[0:3] b3dObj[prop(b_10.LOD_R)] = unknown_sphere[3] - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 11): @@ -1036,10 +1036,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_11.Unk_XYZ)] = unknown_sphere[0:3] b3dObj[prop(b_11.Unk_R)] = unknown_sphere[3] - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 12): @@ -1067,10 +1067,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_12.Unk_Int2)] = unknown2 b3dObj[prop(b_12.Unk_List)] = l_params - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 13): @@ -1095,10 +1095,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_13.Unk_Int2)] = unknown2 b3dObj[prop(b_13.Unk_List)] = l_params - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 14): #sell_ ? @@ -1129,10 +1129,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_14.Unk_Int2)] = unknown2 b3dObj[prop(b_14.Unk_List)] = l_params - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 15): @@ -1157,10 +1157,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_15.Unk_Int2)] = unknown2 b3dObj[prop(b_15.Unk_List)] = l_params - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 16): @@ -1196,10 +1196,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_13.Unk_List)] = l_params - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 17): @@ -1234,10 +1234,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_17.Unk_Int2)] = unknown2 b3dObj[prop(b_17.Unk_List)] = l_params - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 18): #контейнер "применить к" @@ -1259,10 +1259,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_18.Add_Name)] = add_name b3dObj[prop(b_18.Space_Name)] = space_name - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 19): @@ -1279,10 +1279,10 @@ def read(file, context, self, filepath): b3dObj[LEVEL_GROUP] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 20): @@ -1331,10 +1331,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_20.Unk_Int2)] = unknown2 b3dObj[prop(b_20.Unk_List)] = unknowns - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 21): #testkey??? @@ -1354,10 +1354,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_21.R)] = bounding_sphere[3] b3dObj[prop(b_21.GroupCnt)] = groupCnt b3dObj[prop(b_21.Unk_Int2)] = unknown2 - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 23): #colision mesh @@ -1397,10 +1397,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_23.Surface)] = ctype b3dObj[prop(b_23.Unk_List)] = unknowns - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 24): #настройки положения обьекта @@ -1459,10 +1459,10 @@ def read(file, context, self, filepath): b3dObj.rotation_euler[2] = z_d b3dObj.location = sp_pos b3dObj[prop(b_24.Flag)] = flag - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 25): #copSiren????/ контейнер @@ -1490,10 +1490,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_25.Unk_Float4)] = unknown2[3] b3dObj[prop(b_25.Unk_Float5)] = unknown2[4] - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 26): @@ -1518,10 +1518,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_26.Unk_XYZ2)] = unknown_sphere2 b3dObj[prop(b_26.Unk_XYZ3)] = unknown_sphere3 - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 27): @@ -1544,10 +1544,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_27.Unk_XYZ)] = unknown_sphere b3dObj[prop(b_27.Material)] = materialId - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 28): #face @@ -1714,10 +1714,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_28.R)] = bounding_sphere[3] b3dObj[prop(b_28.Unk_XYZ)] = sprite_center - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) #добавляем в сцену обьект realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 29): @@ -1746,10 +1746,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_29.Unk_XYZ)] = unknown_sphere[0:3] b3dObj[prop(b_29.Unk_R)] = unknown_sphere[3] - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 30): @@ -1804,47 +1804,6 @@ def read(file, context, self, filepath): (p2[0], p2[1], p2[2]), ] - - - # b3dMesh = (bpy.data.meshes.new(objName)) - #0-x - #1-y - #2-z - - # l_vertexes = [ - # (p1[0], p1[1], p1[2]), - # (p1[0], p1[1], p2[2]), - # (p2[0], p2[1], p2[2]), - # (p2[0], p2[1], p1[2]), - # ] - - # l_faces = [ - # (0,1,2), - # (2,3,0) - # ] - - # Ev = threading.Event() - # Tr = threading.Thread(target=b3dMesh.from_pydata, args = (l_vertexes,[],l_faces)) - # Tr.start() - # Ev.set() - # Tr.join() - - - # b3dObj = bpy.data.objects.new(objName, b3dMesh) - # b3dObj[BLOCK_TYPE] = type - # b3dObj[LEVEL_GROUP] = levelGroups[lvl - 1] - # b3dObj['pos'] = pos - # b3dObj[prop(b_30.XYZ)] = bounding_sphere[0:3] - # b3dObj[prop(b_30.R)] = bounding_sphere[3] - # b3dObj[prop(b_30.Name)] = connectedRoomName - # b3dObj[prop(b_30.XYZ1)] = p1 - # b3dObj[prop(b_30.XYZ2)] = p2 - - # b3dObj.parent = context.scene.objects[objString[-2]] - # context.collection.objects.link(b3dObj) - # realName = b3dObj.name - # objString[len(objString)-1] = b3dObj.name - elif (type == 31): bounding_sphere = struct.unpack("<4f",file.read(16)) @@ -1871,10 +1830,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_31.Unk_Int2)] = num2 b3dObj[prop(b_31.Unk_XYZ2)] = unknown - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 33): #lamp @@ -1919,10 +1878,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_33.RGB)] = RGB - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 34): #lamp num = 0 @@ -1963,10 +1922,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_34.R)] = bounding_sphere[3] b3dObj[prop(b_34.UnkInt)] = unknown1 - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 35): #mesh @@ -2142,7 +2101,7 @@ def read(file, context, self, filepath): b3dObj = bpy.data.objects.new(objName, b3dMesh) - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) b3dObj[BLOCK_TYPE] = type b3dObj[LEVEL_GROUP] = levelGroups[lvl - 1] b3dObj['pos'] = str(pos) @@ -2160,7 +2119,7 @@ def read(file, context, self, filepath): # for face in b3dMesh.polygons: # face.use_smooth = True context.collection.objects.link(b3dObj) #добавляем в сцену обьект - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 36): @@ -2189,7 +2148,6 @@ def read(file, context, self, filepath): vertexCount = struct.unpack(" 0: if format == 0: - # objString[len(objString)-1] = objString[-2] pass else: for i in range(vertexCount): @@ -2294,10 +2251,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_37.Name1)] = groupName b3dObj[prop(b_37.SType)] = formatRaw - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 39): @@ -2324,10 +2281,10 @@ def read(file, context, self, filepath): b3dObj[prop(b_39.Fog_End)] = fog_end b3dObj[prop(b_39.Color_Id)] = colorId - b3dObj.parent = context.scene.objects[objString[-2]] + b3dObj.parent = context.scene.objects.get(objString[-2]) context.collection.objects.link(b3dObj) realName = b3dObj.name - objString[len(objString)-1] = b3dObj.name + objString[-1] = b3dObj.name elif (type == 40): l_params = [] @@ -2363,8 +2320,8 @@ def read(file, context, self, filepath): context.collection.objects.link(b3dObj) realName = b3dObj.name - b3dObj.parent = context.scene.objects[objString[-2]] - objString[len(objString)-1] = b3dObj.name + b3dObj.parent = context.scene.objects.get(objString[-2]) + objString[-1] = b3dObj.name else: log.warning('smthng wrng') @@ -2433,8 +2390,6 @@ def read(file, context, self, filepath): b3dObj.parent = None transfCollection.objects.link(b3dObj) - # realName = b3dObj.name - # objString[len(objString)-1] = b3dObj.name def readWayTxt(file, context, op, filepath): diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index 9b2567e..54e77f8 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -40,7 +40,8 @@ getPerVertexByType, setPerVertexByType, showHideSphere, - + getObjByProp, + setObjByProp ) @@ -585,6 +586,26 @@ def execute(self, context): return {'FINISHED'} +class GetPropValueOperator(bpy.types.Operator): + bl_idname = "wm.get_prop_value_operator" + bl_label = "Get param value" + + pname: StringProperty() + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + object = bpy.context.object + block_type = object[consts.BLOCK_TYPE] + + zclass = getClassDefByType(block_type) + + if zclass is not None: + getObjByProp(context, object, zclass, self.pname) + + return {'FINISHED'} + class SetFaceValuesOperator(bpy.types.Operator): bl_idname = "wm.set_face_values_operator" bl_label = "Save block values" @@ -663,6 +684,27 @@ def execute(self, context): return {'FINISHED'} + +class SetPropValueOperator(bpy.types.Operator): + bl_idname = "wm.set_prop_value_operator" + bl_label = "Save param value" + + pname: StringProperty() + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + object = bpy.context.object + block_type = object[consts.BLOCK_TYPE] + + zclass = getClassDefByType(block_type) + + if zclass is not None: + setObjByProp(context, object, zclass, self.pname) + + return {'FINISHED'} + class DelValuesOperator(bpy.types.Operator): bl_idname = "wm.del_block_values_operator" bl_label = "Delete block values" @@ -1110,9 +1152,9 @@ def draw(self, context): if block_type == 35: drawAllFieldsByType(self, context, pfb_35) - - layout.operator("wm.get_face_values_operator") - layout.operator("wm.set_face_values_operator") + if block_type in [8, 28, 35]: + layout.operator("wm.get_face_values_operator") + layout.operator("wm.set_face_values_operator") class OBJECT_PT_b3d_pvb_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pvb_edit_panel" @@ -1145,9 +1187,9 @@ def draw(self, context): if block_type == 35: drawAllFieldsByType(self, context, pvb_35) - - layout.operator("wm.get_vertex_values_operator") - layout.operator("wm.set_vertex_values_operator") + if block_type in [8, 28, 35]: + layout.operator("wm.get_vertex_values_operator") + layout.operator("wm.set_vertex_values_operator") class OBJECT_PT_b3d_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_edit_panel" @@ -1211,8 +1253,8 @@ def draw(self, context): zclass = getClassDefByType(block_type) - layout.operator("wm.get_block_values_operator") - layout.operator("wm.set_block_values_operator") + # layout.operator("wm.get_block_values_operator") + # layout.operator("wm.set_block_values_operator") if zclass is not None: drawAllFieldsByType(self, context, zclass) @@ -1672,12 +1714,15 @@ def draw(self, context): AddOperator, # getters GetValuesOperator, + GetPropValueOperator, GetFaceValuesOperator, GetVertexValuesOperator, # setters SetValuesOperator, + SetPropValueOperator, SetFaceValuesOperator, SetVertexValuesOperator, + # others DelValuesOperator, FixUVOperator, FixVertsOperator, diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index e90687e..6654d24 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -250,7 +250,7 @@ def getHierarchyRoots(root): while globalRoot.parent is not None: globalRoot = globalRoot.parent - blocks18 = [cn for cn in bpy.data.objects if cn[BLOCK_TYPE] is not None and cn[BLOCK_TYPE] == 18] + blocks18 = [cn for cn in bpy.data.objects if cn[BLOCK_TYPE] is not None and cn[BLOCK_TYPE] == 18 and getRootObj(cn) == globalRoot] ref_set = set() for cn in blocks18: #out refs @@ -436,9 +436,11 @@ def createCenterDriver(srcObj, bname, pname): v = d.variables.new() v.name = 'location{}'.format(i) - v.targets[0].id_type = 'SCENE' - v.targets[0].id = bpy.context.scene - v.targets[0].data_path = 'my_tool.{}.{}[{}]'.format(bname, pname, i) + # v.targets[0].id_type = 'SCENE' + # v.targets[0].id = bpy.context.scene + # v.targets[0].data_path = 'my_tool.{}.{}[{}]'.format(bname, pname, i) + v.targets[0].id = bpy.context.object + v.targets[0].data_path = '["{}"][{}]'.format(pname, i) d.expression = v.name @@ -447,9 +449,11 @@ def createRadDriver(srcObj, bname, pname): v1 = d.variables.new() v1.name = 'rad' - v1.targets[0].id_type = 'SCENE' - v1.targets[0].id = bpy.context.scene - v1.targets[0].data_path = 'my_tool.{}.{}'.format(bname, pname) + # v1.targets[0].id_type = 'SCENE' + # v1.targets[0].id = bpy.context.scene + # v1.targets[0].data_path = 'my_tool.{}.{}'.format(bname, pname) + v1.targets[0].id = bpy.context.object + v1.targets[0].data_path = '["{}"]'.format(pname) d.expression = v1.name @@ -525,10 +529,11 @@ def drawFieldsByType(l_self, context, zclass): obj = zclass.__dict__[attr] bname, bnum = getMytoolBlockNameByClass(zclass) - ftype = obj['type'] + ftype = obj.get('type') subtype = obj.get('subtype') curGroupName = obj.get('group') - pname = obj['prop'] + propText = obj.get('name') + pname = obj.get('prop') mytool = context.scene.my_tool curLayout = l_self.layout @@ -551,38 +556,30 @@ def drawFieldsByType(l_self, context, zclass): or ftype == fieldType.INT \ or ftype == fieldType.FLOAT \ or ftype == fieldType.ENUM \ - or ftype == fieldType.ENUM_STR \ + or ftype == fieldType.ENUM_DYN \ or ftype == fieldType.LIST: box = curLayout.box() - box.prop(getattr(mytool, bname), "show_"+pname) + # box.prop(getattr(mytool, bname), "show_"+pname) col = box.column() - if ftype == fieldType.STRING: - col.prop(getattr(mytool, bname), pname) - - elif ftype == fieldType.COORD: - col.prop(getattr(mytool, bname), pname) - - elif ftype == fieldType.RAD: - col.prop(getattr(mytool, bname), pname) - - elif ftype == fieldType.INT: - col.prop(getattr(mytool, bname), pname) - - elif ftype == fieldType.FLOAT: - col.prop(getattr(mytool, bname), pname) - - elif ftype == fieldType.ENUM: - col.prop(getattr(mytool, bname), pname) - - elif ftype == fieldType.ENUM_STR: + if ftype in [ + fieldType.STRING, + fieldType.COORD, + fieldType.RAD, + fieldType.INT, + fieldType.FLOAT + ]: + col.prop(context.object, '["{}"]'.format(pname), text=propText) + + elif ftype in [fieldType.ENUM_DYN, fieldType.ENUM]: col.prop(getattr(mytool, bname), '{}_switch'.format(pname)) if(getattr(getattr(mytool, bname), '{}_switch'.format(pname))): col.prop(getattr(mytool, bname), '{}_enum'.format(pname)) else: - col.prop(getattr(mytool, bname), pname) + # col.prop(getattr(mytool, bname), pname) + col.prop(context.object, '["{}"]'.format(pname), text=propText) elif ftype == fieldType.LIST: collect = getattr(mytool, bname) @@ -590,6 +587,12 @@ def drawFieldsByType(l_self, context, zclass): scn = bpy.context.scene rows = 2 + + row = box.row() + props = row.operator("wm.get_prop_value_operator") + props.pname = pname + props = row.operator("wm.set_prop_value_operator") + props.pname = pname row = box.row() row.template_list("CUSTOM_UL_items", "", collect, pname, scn, "custom_index", rows=rows) @@ -616,89 +619,130 @@ def drawFieldsByType(l_self, context, zclass): props.pname = pname props.customindex = "custom_index" - if getattr(getattr(mytool, bname), "show_"+pname): - col.enabled = True - else: - col.enabled = False + # if getattr(getattr(mytool, bname), "show_"+pname): + # col.enabled = True + # else: + # col.enabled = False elif ftype == fieldType.V_FORMAT: box = curLayout.box() - box.prop(getattr(mytool, bname), "show_{}".format(pname)) + # box.prop(getattr(mytool, bname), "show_{}".format(pname)) col1 = box.column() col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'triang_offset')) col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_uvs')) col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_normals')) col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'normal_flag')) - if getattr(getattr(mytool, bname), "show_"+pname): - col1.enabled = True - else: - col1.enabled = False + # if getattr(getattr(mytool, bname), "show_"+pname): + # col1.enabled = True + # else: + # col1.enabled = False def getAllObjsByType(context, object, zclass): getObjsByType(context, object, b_common) getObjsByType(context, object, zclass) -def getObjsByType(context, object, zclass): - attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] +def getObjByProp(context, object, zclass, pname): + attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] bname, bnum = getMytoolBlockNameByClass(zclass) mytool = context.scene.my_tool for property in attrs: obj = zclass.__dict__[property] - if obj['type'] != fieldType.SPHERE_EDIT: - if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ - and getattr(getattr(mytool, bname), "show_"+obj['prop']): + if obj['prop'] == pname: - if obj['type'] == fieldType.FLOAT \ - or obj['type'] == fieldType.RAD: - setattr( - getattr(mytool, bname), - obj['prop'], - float(object[obj['prop']]) - ) + if obj['type'] == fieldType.LIST: - elif obj['type'] == fieldType.INT: - setattr( - getattr(mytool, bname), - obj['prop'], - int(object[obj['prop']]) - ) + col = getattr(getattr(mytool, bname), obj['prop']) - elif obj['type'] == fieldType.STRING: - getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) + col.clear() + for i, obj in enumerate(object[obj['prop']]): + item = col.add() + item.index = i + item.value = obj - elif obj['type'] == fieldType.ENUM \ - or obj['type'] == fieldType.ENUM_STR: - setattr( - getattr(mytool, bname), - obj['prop'], - str(object[obj['prop']]) - ) - elif obj['type'] == fieldType.LIST: +def getObjsByType(context, object, zclass): + attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + bname, bnum = getMytoolBlockNameByClass(zclass) - col = getattr(getattr(mytool, bname), obj['prop']) + mytool = context.scene.my_tool + for property in attrs: + obj = zclass.__dict__[property] - col.clear() - for i, obj in enumerate(object[obj['prop']]): - item = col.add() - item.index = i - item.value = obj + if obj['type'] != fieldType.SPHERE_EDIT: + # if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + # and getattr(getattr(mytool, bname), "show_"+obj['prop']): + + if obj['type'] == fieldType.FLOAT \ + or obj['type'] == fieldType.RAD: + setattr( + getattr(mytool, bname), + obj['prop'], + float(object[obj['prop']]) + ) + + elif obj['type'] == fieldType.INT: + setattr( + getattr(mytool, bname), + obj['prop'], + int(object[obj['prop']]) + ) + + elif obj['type'] == fieldType.STRING: + getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) + + elif obj['type'] == fieldType.ENUM \ + or obj['type'] == fieldType.ENUM_DYN: + setattr( + getattr(mytool, bname), + obj['prop'], + str(object[obj['prop']]) + ) + + elif obj['type'] == fieldType.LIST: + + col = getattr(getattr(mytool, bname), obj['prop']) + + col.clear() + for i, obj in enumerate(object[obj['prop']]): + item = col.add() + item.index = i + item.value = obj - else: - setattr( - getattr(mytool, bname), - obj['prop'], - object[obj['prop']] - ) + else: + setattr( + getattr(mytool, bname), + obj['prop'], + object[obj['prop']] + ) def setAllObjsByType(context, object, zclass): setObjsByType(context, object, b_common) setObjsByType(context, object, zclass) +def setObjByProp(context, object, zclass, pname): + + attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] + bname, bnum = getMytoolBlockNameByClass(zclass) + + mytool = context.scene.my_tool + for property in attrs: + obj = zclass.__dict__[property] + + if obj['prop'] == pname: + + if obj['type'] == fieldType.LIST: + collect = getattr(getattr(mytool, bname), obj['prop']) + + arr = [] + for item in list(collect): + arr.append(item.value) + + object[obj['prop']] = arr + def setObjsByType(context, object, zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] @@ -707,8 +751,8 @@ def setObjsByType(context, object, zclass): for property in attrs: obj = zclass.__dict__[property] if obj['type'] != fieldType.SPHERE_EDIT: - if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ - and getattr(getattr(mytool, bname), "show_"+obj['prop']): + # if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + # and getattr(getattr(mytool, bname), "show_"+obj['prop']): if obj['type'] == fieldType.FLOAT or obj['type'] == fieldType.RAD: object[obj['prop']] = float(getattr(getattr(mytool, bname), obj['prop'])) @@ -737,7 +781,7 @@ def setObjsByType(context, object, zclass): elif obj['subtype'] == fieldType.FLOAT: object[obj['prop']] = float(getattr(getattr(mytool, bname), obj['prop'])) - elif obj['type'] == fieldType.ENUM_STR: + elif obj['type'] == fieldType.ENUM_DYN: object[obj['prop']] = str(getattr(getattr(mytool, bname), obj['prop'])) elif obj['type'] == fieldType.COORD: diff --git a/src/2.80/addons/b3d_tools/consts.py b/src/2.80/addons/b3d_tools/consts.py index 651a27f..34d2a65 100644 --- a/src/2.80/addons/b3d_tools/consts.py +++ b/src/2.80/addons/b3d_tools/consts.py @@ -57,7 +57,7 @@ collisionTypeList = [ ('0', "standart", ""), ('1', "asphalt", ""), - ('2', "earth", ""), + ('2', "grass", ""), ('3', "swamp (hard to pass)", ""), ('4', "swamp (easy to pass)", ""), ('5', "wet asphalt", ""), From 17c7e4e8d7c3d733acb18ce4c429f030ff817659 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 4 Feb 2023 15:12:53 +0200 Subject: [PATCH 39/47] separate single block edit --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 3 +- src/2.80/addons/b3d_tools/b3d/classes.py | 157 +++++++++++++---- src/2.80/addons/b3d_tools/b3d/common.py | 14 +- src/2.80/addons/b3d_tools/b3d/panel.py | 120 +++++++++++-- src/2.80/addons/b3d_tools/b3d/scripts.py | 170 ++++++++++--------- 5 files changed, 330 insertions(+), 134 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index 3bf532a..16eda96 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -198,7 +198,8 @@ class ResBlock(bpy.types.PropertyGroup): # 'description': '' # fieldType.ENUM_DYN - dynamic - # 'subtype': fieldType.SPACE_NAME, + # 'subtype': fieldType.STRING + # 'callback': fieldType.SPACE_NAME, # 'name': 'Name', # 'description': '' diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 62c0fdc..cd12b27 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -92,11 +92,10 @@ def callback_func(self, context): return callback_func - -def createTypeClass(zclass): +def createTypeClass(zclass, multipleEdit = True): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockNameByClass(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass, multipleEdit) block_num = zclass.__name__.split('_')[1] attributes = { @@ -109,11 +108,12 @@ def createTypeClass(zclass): pname = obj['prop'] prop = None - lockProp = BoolProperty( - name = "On./Off.", - description = "Enable/Disable param for editing", - default = True - ) + if multipleEdit: # lock switches only for multiple edit + lockProp = BoolProperty( + name = "On./Off.", + description = "Enable/Disable param for editing", + default = True + ) if obj['type'] == fieldType.STRING \ or obj['type'] == fieldType.COORD \ @@ -122,10 +122,10 @@ def createTypeClass(zclass): or obj['type'] == fieldType.INT \ or obj['type'] == fieldType.LIST: + if multipleEdit: # lock switches only for multiple edit + attributes['__annotations__']["show_"+pname] = lockProp - # attributes['__annotations__']["show_"+pname] = lockProp - - if obj['type'] == fieldType.STRING: + if obj['type'] == fieldType.STRING and multipleEdit: prop = StringProperty( name = obj['name'], description = obj['description'], @@ -133,21 +133,21 @@ def createTypeClass(zclass): maxlen = 32 ) - elif obj['type'] == fieldType.COORD: + elif obj['type'] == fieldType.COORD and multipleEdit: prop = FloatVectorProperty( name = obj['name'], description = obj['description'], default = obj['default'] ) - elif obj['type'] == fieldType.RAD or obj['type'] == fieldType.FLOAT: + elif (obj['type'] == fieldType.RAD or obj['type'] == fieldType.FLOAT) and multipleEdit: prop = FloatProperty( name = obj['name'], description = obj['description'], default = obj['default'] ) - elif obj['type'] == fieldType.INT: + elif obj['type'] == fieldType.INT and multipleEdit: prop = IntProperty( name = obj['name'], description = obj['description'], @@ -166,7 +166,10 @@ def createTypeClass(zclass): elif obj['type'] == fieldType.ENUM \ or obj['type'] == fieldType.ENUM_DYN: - # attributes['__annotations__']["show_"+pname] = lockProp + + if multipleEdit: # lock switches only for multiple edit + attributes['__annotations__']["show_"+pname] = lockProp + enum_callback = None subtype = obj.get('subtype') @@ -182,14 +185,14 @@ def createTypeClass(zclass): enum_callback = modulesCallback if obj['type'] == fieldType.ENUM: - # prop = None + prop = None prop_enum = None prop_switch = None prop_switch = BoolProperty( name = 'Use dropdown', description = 'Dropdown selection', - default = True + default = False ) prop_enum = EnumProperty( @@ -200,16 +203,20 @@ def createTypeClass(zclass): update = setCustObjValue(subtype, bname, pname) ) - # prop = EnumProperty( - # name = obj['name'], - # description = obj['description'], - # default = obj['default'], - # items = obj['items'] - # ) + if multipleEdit: + prop = EnumProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'], + items = obj['items'] + ) attributes['__annotations__']['{}_switch'.format(pname)] = prop_switch attributes['__annotations__']['{}_enum'.format(pname)] = prop_enum + if multipleEdit: + attributes['__annotations__']['{}'.format(pname)] = prop + elif obj['type'] == fieldType.ENUM_DYN: # prop = None prop_enum = None @@ -218,7 +225,7 @@ def createTypeClass(zclass): prop_switch = BoolProperty( name = 'Use dropdown', description = 'Dropdown selection', - default = True + default = False ) prop_enum = EnumProperty( @@ -228,17 +235,22 @@ def createTypeClass(zclass): update = setCustObjValue(subtype, bname, pname) ) - # prop = StringProperty( - # name = obj['name'], - # description = obj['description'], - # maxlen = 32 - # ) + + if multipleEdit: + if subtype == fieldType.STRING: + prop = StringProperty( + name = obj['name'], + description = obj['description'], + maxlen = 32 + ) attributes['__annotations__']['{}_switch'.format(pname)] = prop_switch attributes['__annotations__']['{}_enum'.format(pname)] = prop_enum - # attributes['__annotations__']['{}'.format(pname)] = prop - elif obj['type'] == fieldType.V_FORMAT: + if multipleEdit: + attributes['__annotations__']['{}'.format(pname)] = prop + + elif obj['type'] == fieldType.V_FORMAT: # currently only available in vertex edit attributes['__annotations__']["show_{}".format(pname)] = lockProp @@ -270,7 +282,10 @@ def createTypeClass(zclass): ) attributes['__annotations__']['{}_{}'.format(pname, 'normal_flag')] = prop4 - newclass = type("{}_gen".format(zclass.__name__), (bpy.types.PropertyGroup,), attributes) + if multipleEdit: + newclass = type("{}_gen".format(zclass.__name__), (bpy.types.PropertyGroup,), attributes) + else: + newclass = type("s_{}_gen".format(zclass.__name__), (bpy.types.PropertyGroup,), attributes) return newclass @@ -281,6 +296,44 @@ def createTypeClass(zclass): perVertBlock_8 = createTypeClass(pvb_8) perVertBlock_35 = createTypeClass(pvb_35) +s_block_1 = createTypeClass(b_1, False) +s_block_2 = createTypeClass(b_2, False) +s_block_3 = createTypeClass(b_3, False) +s_block_4 = createTypeClass(b_4, False) +s_block_5 = createTypeClass(b_5, False) +s_block_6 = createTypeClass(b_6, False) +s_block_7 = createTypeClass(b_7, False) +s_block_8 = createTypeClass(b_8, False) +s_block_9 = createTypeClass(b_9, False) +s_block_10 = createTypeClass(b_10, False) +s_block_11 = createTypeClass(b_11, False) +s_block_12 = createTypeClass(b_12, False) +s_block_13 = createTypeClass(b_13, False) +s_block_14 = createTypeClass(b_14, False) +s_block_15 = createTypeClass(b_15, False) +s_block_16 = createTypeClass(b_16, False) +s_block_17 = createTypeClass(b_17, False) +s_block_18 = createTypeClass(b_18, False) +s_block_20 = createTypeClass(b_20, False) +s_block_21 = createTypeClass(b_21, False) +s_block_22 = createTypeClass(b_22, False) +s_block_23 = createTypeClass(b_23, False) +s_block_24 = createTypeClass(b_24, False) +s_block_25 = createTypeClass(b_25, False) +s_block_26 = createTypeClass(b_26, False) +s_block_27 = createTypeClass(b_27, False) +s_block_28 = createTypeClass(b_28, False) +s_block_29 = createTypeClass(b_29, False) +s_block_30 = createTypeClass(b_30, False) +s_block_31 = createTypeClass(b_31, False) +s_block_33 = createTypeClass(b_33, False) +s_block_34 = createTypeClass(b_34, False) +s_block_35 = createTypeClass(b_35, False) +s_block_36 = createTypeClass(b_36, False) +s_block_37 = createTypeClass(b_37, False) +s_block_39 = createTypeClass(b_39, False) +s_block_40 = createTypeClass(b_40, False) + block_common = createTypeClass(b_common) block_1 = createTypeClass(b_1) block_2 = createTypeClass(b_2) @@ -321,6 +374,44 @@ def createTypeClass(zclass): block_40 = createTypeClass(b_40) _classes = ( + s_block_1, + s_block_2, + s_block_3, + s_block_4, + s_block_5, + s_block_6, + s_block_7, + s_block_8, + s_block_9, + s_block_10, + s_block_11, + s_block_12, + s_block_13, + s_block_14, + s_block_15, + s_block_16, + s_block_17, + s_block_18, + s_block_20, + s_block_21, + s_block_22, + s_block_23, + s_block_24, + s_block_25, + s_block_26, + s_block_27, + s_block_28, + s_block_29, + s_block_30, + s_block_31, + s_block_33, + s_block_34, + s_block_35, + s_block_36, + s_block_37, + s_block_39, + s_block_40, + block_1, block_2, block_3, @@ -359,9 +450,11 @@ def createTypeClass(zclass): block_39, block_40, block_common, + perFaceBlock_8, perFaceBlock_28, perFaceBlock_35, + perVertBlock_8, perVertBlock_35 ) diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 981336b..6331b54 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -265,11 +265,14 @@ def getAllChildren(obj): break return allChildren -def getMytoolBlockNameByClass(zclass): +def getMytoolBlockNameByClass(zclass, multipleClass = True): bname = '' btype, bnum = zclass.__name__.split('_') if btype == 'b': - bname = 'block{}'.format(bnum) + if multipleClass: + bname = 'block{}'.format(bnum) + else: + bname = 'sBlock{}'.format(bnum) elif btype == 'pfb': bname = 'perFaceBlock{}'.format(bnum) elif btype == 'pvb': @@ -278,10 +281,13 @@ def getMytoolBlockNameByClass(zclass): return [bname, bnum] -def getMytoolBlockName(btype, bnum): +def getMytoolBlockName(btype, bnum, multipleClass = False): bname = '' if btype == 'b': - bname = 'block{}'.format(bnum) + if multipleClass: + bname = 'block{}'.format(bnum) + else: + bname = 'sBlock{}'.format(bnum) elif btype == 'pfb': bname = 'perFaceBlock{}'.format(bnum) elif btype == 'pvb': diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index 54e77f8..1c8b350 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -48,9 +48,15 @@ from .classes import ( block_1,block_2,block_3,block_4,block_5,block_6,block_7,block_8,block_9,block_10,\ block_11,block_12,block_13,block_14,block_15,block_16,block_17,block_18,block_20,\ - block_21,block_22,block_23,block_24,block_25,block_26,block_27,block_28,block_29,block_30,\ - block_31,block_33,block_34,block_35,block_36,block_37,block_39,block_40,block_common,\ - perFaceBlock_8, perFaceBlock_28, perFaceBlock_35, perVertBlock_8, perVertBlock_35 + block_21,block_22,block_23,block_24,block_25,block_26,block_27,block_28,block_29,\ + block_30,block_31,block_33,block_34,block_35,block_36,block_37,block_39,block_40,\ + + block_common,perFaceBlock_8, perFaceBlock_28, perFaceBlock_35, perVertBlock_8, perVertBlock_35,\ + + s_block_1,s_block_2,s_block_3,s_block_4,s_block_5,s_block_6,s_block_7,s_block_8,s_block_9,s_block_10,\ + s_block_11,s_block_12,s_block_13,s_block_14,s_block_15,s_block_16,s_block_17,s_block_18,s_block_20,\ + s_block_21,s_block_22,s_block_23,s_block_24,s_block_25,s_block_26,s_block_27,s_block_28,s_block_29,\ + s_block_30,s_block_31,s_block_33,s_block_34,s_block_35,s_block_36,s_block_37,s_block_39,s_block_40,\ ) from .class_descr import ( getClassDefByType, @@ -98,6 +104,44 @@ def resModuleCallback(scene, context): class PanelSettings(bpy.types.PropertyGroup): + sBlock1: PointerProperty(type=s_block_1) + sBlock2: PointerProperty(type=s_block_2) + sBlock3: PointerProperty(type=s_block_3) + sBlock4: PointerProperty(type=s_block_4) + sBlock5: PointerProperty(type=s_block_5) + sBlock6: PointerProperty(type=s_block_6) + sBlock7: PointerProperty(type=s_block_7) + sBlock8: PointerProperty(type=s_block_8) + sBlock9: PointerProperty(type=s_block_9) + sBlock10: PointerProperty(type=s_block_10) + sBlock11: PointerProperty(type=s_block_11) + sBlock12: PointerProperty(type=s_block_12) + sBlock13: PointerProperty(type=s_block_13) + sBlock14: PointerProperty(type=s_block_14) + sBlock15: PointerProperty(type=s_block_15) + sBlock16: PointerProperty(type=s_block_16) + sBlock17: PointerProperty(type=s_block_17) + sBlock18: PointerProperty(type=s_block_18) + sBlock20: PointerProperty(type=s_block_20) + sBlock21: PointerProperty(type=s_block_21) + sBlock22: PointerProperty(type=s_block_22) + sBlock23: PointerProperty(type=s_block_23) + sBlock24: PointerProperty(type=s_block_24) + sBlock25: PointerProperty(type=s_block_25) + sBlock26: PointerProperty(type=s_block_26) + sBlock27: PointerProperty(type=s_block_27) + sBlock28: PointerProperty(type=s_block_28) + sBlock29: PointerProperty(type=s_block_29) + sBlock30: PointerProperty(type=s_block_30) + sBlock31: PointerProperty(type=s_block_31) + sBlock33: PointerProperty(type=s_block_33) + sBlock34: PointerProperty(type=s_block_34) + sBlock35: PointerProperty(type=s_block_35) + sBlock36: PointerProperty(type=s_block_36) + sBlock37: PointerProperty(type=s_block_37) + sBlock39: PointerProperty(type=s_block_39) + sBlock40: PointerProperty(type=s_block_40) + block1: PointerProperty(type=block_1) block2: PointerProperty(type=block_2) block3: PointerProperty(type=block_3) @@ -1121,7 +1165,7 @@ def draw(self, context): class OBJECT_PT_b3d_pfb_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pfb_edit_panel" - bl_label = "Polygon params" + bl_label = "Multiple polygons edit" bl_parent_id = "OBJECT_PT_b3d_edit_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1158,7 +1202,7 @@ def draw(self, context): class OBJECT_PT_b3d_pvb_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pvb_edit_panel" - bl_label = "Vertex params" + bl_label = "Multiple vertexes edit" bl_parent_id = "OBJECT_PT_b3d_edit_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1213,7 +1257,7 @@ def draw(self, context): class OBJECT_PT_b3d_pob_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pob_edit_panel" - bl_label = "Object params" + bl_label = "Multiple block edit" bl_parent_id = "OBJECT_PT_b3d_edit_panel" bl_space_type = "VIEW_3D" bl_region_type = getRegion() @@ -1237,24 +1281,17 @@ def draw(self, context): # for i in range(1): if object is not None: - level_group = None - if consts.BLOCK_TYPE in object: block_type = object[consts.BLOCK_TYPE] else: block_type = None - if consts.LEVEL_GROUP in object: - level_group = object[consts.LEVEL_GROUP] - else: - level_group = None - lenStr = str(len(object.children)) zclass = getClassDefByType(block_type) - # layout.operator("wm.get_block_values_operator") - # layout.operator("wm.set_block_values_operator") + layout.operator("wm.get_block_values_operator") + layout.operator("wm.set_block_values_operator") if zclass is not None: drawAllFieldsByType(self, context, zclass) @@ -1263,9 +1300,55 @@ def draw(self, context): # self.layout.label(text="Выбранный объект не имеет типа.") # self.layout.label(text="Чтобы указать его, нажмите на кнопку сохранения настроек.") - layout.operator("wm.del_block_values_operator") - layout.operator("wm.fix_uv_operator") - layout.operator("wm.fix_verts_operator") + # layout.operator("wm.del_block_values_operator") + # layout.operator("wm.fix_uv_operator") + # layout.operator("wm.fix_verts_operator") + +class OBJECT_PT_b3d_pob_single_edit_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_pob_single_edit_panel" + bl_label = "Single block edit" + bl_parent_id = "OBJECT_PT_b3d_edit_panel" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + mytool = context.scene.my_tool + + type(context) + #for i in range(len(bpy.context.selected_objects)): + + object = bpy.context.object + + # if len(bpy.context.selected_objects): + # for i in range(1): + if object is not None: + + if consts.BLOCK_TYPE in object: + block_type = object[consts.BLOCK_TYPE] + else: + block_type = None + + lenStr = str(len(object.children)) + + zclass = getClassDefByType(block_type) + + if zclass is not None: + drawAllFieldsByType(self, context, zclass, False) + + # else: + # self.layout.label(text="Выбранный объект не имеет типа.") + # self.layout.label(text="Чтобы указать его, нажмите на кнопку сохранения настроек.") + + # layout.operator("wm.del_block_values_operator") + # layout.operator("wm.fix_uv_operator") + # layout.operator("wm.fix_verts_operator") class OBJECT_PT_b3d_blocks_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_blocks_panel" @@ -1742,6 +1825,7 @@ def draw(self, context): OBJECT_PT_b3d_usage_panel, OBJECT_PT_b3d_add_panel, OBJECT_PT_b3d_edit_panel, + OBJECT_PT_b3d_pob_single_edit_panel, OBJECT_PT_b3d_pob_edit_panel, OBJECT_PT_b3d_pfb_edit_panel, OBJECT_PT_b3d_pvb_edit_panel, diff --git a/src/2.80/addons/b3d_tools/b3d/scripts.py b/src/2.80/addons/b3d_tools/b3d/scripts.py index 6654d24..0bb17f9 100644 --- a/src/2.80/addons/b3d_tools/b3d/scripts.py +++ b/src/2.80/addons/b3d_tools/b3d/scripts.py @@ -514,20 +514,21 @@ def drawCommon(l_self, obj): box.label(text="Children block count: " + lenStr) box.label(text="Block group: " + str(level_group)) -def drawAllFieldsByType(l_self, context, zclass): +def drawAllFieldsByType(l_self, context, zclass, multipleEdit = True): if zclass.__name__.split('_')[0] == 'b': - drawFieldsByType(l_self, context, b_common) - drawFieldsByType(l_self, context, zclass) + drawFieldsByType(l_self, context, b_common, multipleEdit) + drawFieldsByType(l_self, context, zclass, multipleEdit) else: - drawFieldsByType(l_self, context, zclass) + drawFieldsByType(l_self, context, zclass, multipleEdit) -def drawFieldsByType(l_self, context, zclass): +def drawFieldsByType(l_self, context, zclass, multipleEdit = True): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] boxes = {} for attr in attrs: obj = zclass.__dict__[attr] - bname, bnum = getMytoolBlockNameByClass(zclass) + + bname, bnum = getMytoolBlockNameByClass(zclass, multipleEdit) ftype = obj.get('type') subtype = obj.get('subtype') @@ -544,11 +545,12 @@ def drawFieldsByType(l_self, context, zclass): if ftype == fieldType.SPHERE_EDIT: - box = curLayout.box() - col = box.column() + if not multipleEdit: # sphere edit available only in single object edit + box = curLayout.box() + col = box.column() - props = col.operator("wm.show_hide_sphere_operator") - props.pname = pname + props = col.operator("wm.show_hide_sphere_operator") + props.pname = pname elif ftype == fieldType.STRING \ or ftype == fieldType.COORD \ @@ -560,7 +562,8 @@ def drawFieldsByType(l_self, context, zclass): or ftype == fieldType.LIST: box = curLayout.box() - # box.prop(getattr(mytool, bname), "show_"+pname) + if multipleEdit: + box.prop(getattr(mytool, bname), "show_"+pname) col = box.column() if ftype in [ @@ -570,16 +573,22 @@ def drawFieldsByType(l_self, context, zclass): fieldType.INT, fieldType.FLOAT ]: - col.prop(context.object, '["{}"]'.format(pname), text=propText) + if multipleEdit: # getting from my_tool + col.prop(getattr(mytool, bname), pname) + else: + col.prop(context.object, '["{}"]'.format(pname), text=propText) elif ftype in [fieldType.ENUM_DYN, fieldType.ENUM]: + col.prop(getattr(mytool, bname), '{}_switch'.format(pname)) if(getattr(getattr(mytool, bname), '{}_switch'.format(pname))): col.prop(getattr(mytool, bname), '{}_enum'.format(pname)) else: - # col.prop(getattr(mytool, bname), pname) - col.prop(context.object, '["{}"]'.format(pname), text=propText) + if multipleEdit: + col.prop(getattr(mytool, bname), pname) + else: + col.prop(context.object, '["{}"]'.format(pname), text=propText) elif ftype == fieldType.LIST: collect = getattr(mytool, bname) @@ -619,33 +628,33 @@ def drawFieldsByType(l_self, context, zclass): props.pname = pname props.customindex = "custom_index" - # if getattr(getattr(mytool, bname), "show_"+pname): - # col.enabled = True - # else: - # col.enabled = False + if multipleEdit: + if getattr(getattr(mytool, bname), "show_"+pname): + col.enabled = True + else: + col.enabled = False elif ftype == fieldType.V_FORMAT: - box = curLayout.box() - # box.prop(getattr(mytool, bname), "show_{}".format(pname)) - col1 = box.column() - col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'triang_offset')) - col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_uvs')) - col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_normals')) - col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'normal_flag')) - - # if getattr(getattr(mytool, bname), "show_"+pname): - # col1.enabled = True - # else: - # col1.enabled = False + if multipleEdit: + box = curLayout.box() + box.prop(getattr(mytool, bname), "show_{}".format(pname)) + + col1 = box.column() + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'triang_offset')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_uvs')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'use_normals')) + col1.prop(getattr(mytool, bname), "{}_{}".format(pname, 'normal_flag')) + + if getattr(getattr(mytool, bname), "show_"+pname): + col1.enabled = True + else: + col1.enabled = False -def getAllObjsByType(context, object, zclass): - getObjsByType(context, object, b_common) - getObjsByType(context, object, zclass) def getObjByProp(context, object, zclass, pname): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockNameByClass(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass, True) mytool = context.scene.my_tool for property in attrs: @@ -663,6 +672,9 @@ def getObjByProp(context, object, zclass, pname): item.index = i item.value = obj +def getAllObjsByType(context, object, zclass): + getObjsByType(context, object, b_common) + getObjsByType(context, object, zclass) def getObjsByType(context, object, zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] @@ -673,60 +685,56 @@ def getObjsByType(context, object, zclass): obj = zclass.__dict__[property] if obj['type'] != fieldType.SPHERE_EDIT: - # if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ - # and getattr(getattr(mytool, bname), "show_"+obj['prop']): + if getattr(getattr(mytool, bname), "show_"+obj['prop']) is not None \ + and getattr(getattr(mytool, bname), "show_"+obj['prop']): - if obj['type'] == fieldType.FLOAT \ - or obj['type'] == fieldType.RAD: - setattr( - getattr(mytool, bname), - obj['prop'], - float(object[obj['prop']]) - ) - - elif obj['type'] == fieldType.INT: - setattr( - getattr(mytool, bname), - obj['prop'], - int(object[obj['prop']]) - ) - - elif obj['type'] == fieldType.STRING: - getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) - - elif obj['type'] == fieldType.ENUM \ - or obj['type'] == fieldType.ENUM_DYN: - setattr( - getattr(mytool, bname), - obj['prop'], - str(object[obj['prop']]) - ) - - elif obj['type'] == fieldType.LIST: + if obj['type'] == fieldType.FLOAT \ + or obj['type'] == fieldType.RAD: + setattr( + getattr(mytool, bname), + obj['prop'], + float(object[obj['prop']]) + ) - col = getattr(getattr(mytool, bname), obj['prop']) + elif obj['type'] == fieldType.INT: + setattr( + getattr(mytool, bname), + obj['prop'], + int(object[obj['prop']]) + ) - col.clear() - for i, obj in enumerate(object[obj['prop']]): - item = col.add() - item.index = i - item.value = obj + elif obj['type'] == fieldType.STRING: + getattr(mytool, bname)[obj['prop']] = str(object[obj['prop']]) - else: - setattr( - getattr(mytool, bname), - obj['prop'], - object[obj['prop']] - ) + elif obj['type'] == fieldType.ENUM \ + or obj['type'] == fieldType.ENUM_DYN: + setattr( + getattr(mytool, bname), + obj['prop'], + str(object[obj['prop']]) + ) -def setAllObjsByType(context, object, zclass): - setObjsByType(context, object, b_common) - setObjsByType(context, object, zclass) + elif obj['type'] == fieldType.LIST: + + col = getattr(getattr(mytool, bname), obj['prop']) + + col.clear() + for i, obj in enumerate(object[obj['prop']]): + item = col.add() + item.index = i + item.value = obj + + else: + setattr( + getattr(mytool, bname), + obj['prop'], + object[obj['prop']] + ) def setObjByProp(context, object, zclass, pname): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] - bname, bnum = getMytoolBlockNameByClass(zclass) + bname, bnum = getMytoolBlockNameByClass(zclass, True) mytool = context.scene.my_tool for property in attrs: @@ -743,6 +751,10 @@ def setObjByProp(context, object, zclass, pname): object[obj['prop']] = arr +def setAllObjsByType(context, object, zclass): + setObjsByType(context, object, b_common) + setObjsByType(context, object, zclass) + def setObjsByType(context, object, zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] From 94649cc906950eeb3f6523f039e798c401f51ca3 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sun, 5 Feb 2023 21:40:35 +0200 Subject: [PATCH 40/47] grouping + various fixes --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 12 +- src/2.80/addons/b3d_tools/b3d/classes.py | 5 +- src/2.80/addons/b3d_tools/b3d/common.py | 9 + src/2.80/addons/b3d_tools/b3d/export_b3d.py | 378 +++++++--------- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 224 +++++----- src/2.80/addons/b3d_tools/b3d/menus.py | 9 +- src/2.80/addons/b3d_tools/b3d/panel.py | 435 ++++--------------- src/2.80/addons/b3d_tools/b3d/scripts.py | 69 +-- src/2.80/addons/b3d_tools/consts.py | 81 ++-- 9 files changed, 456 insertions(+), 766 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index 16eda96..8605dbf 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -312,16 +312,6 @@ class pfb_35(): 'default': 0 } - -class b_common(): - LevelGroup = { - 'prop': LEVEL_GROUP, - 'type': fieldType.INT, - 'name': 'Block group', - 'description': '', - 'default': 0 - } - class b_1(): Name1 = { 'prop': 'name1', @@ -1390,7 +1380,7 @@ class b_28(): 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } - Unk_XYZ = { + Sprite_Center = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, 'name': 'Sprite center coord', diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index cd12b27..7d9fd74 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -58,8 +58,7 @@ pfb_28, pfb_35, pvb_8, - pvb_35, - b_common + pvb_35 ) from .common import ( @@ -334,7 +333,6 @@ def createTypeClass(zclass, multipleEdit = True): s_block_39 = createTypeClass(b_39, False) s_block_40 = createTypeClass(b_40, False) -block_common = createTypeClass(b_common) block_1 = createTypeClass(b_1) block_2 = createTypeClass(b_2) block_3 = createTypeClass(b_3) @@ -449,7 +447,6 @@ def createTypeClass(zclass, multipleEdit = True): block_37, block_39, block_40, - block_common, perFaceBlock_8, perFaceBlock_28, diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 6331b54..98c5e93 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -295,6 +295,15 @@ def getMytoolBlockName(btype, bnum, multipleClass = False): return bname +def getLevelGroup(obj): + parent = obj.parent + # log.debug(parent) + if parent is None: + return 0 + if parent.get(BLOCK_TYPE) == 444: + return int(parent.name[6]) #GROUP_n + return 0 + def referenceablesCallback(self, context): mytool = context.scene.my_tool diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index a260945..f51e192 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -8,6 +8,7 @@ import bmesh import bpy import mathutils +from mathutils import Vector import os.path from bpy.props import * from mathutils import Matrix @@ -61,8 +62,7 @@ pfb_28, pfb_35, pvb_8, - pvb_35, - b_common + pvb_35 ) from .scripts import ( @@ -85,7 +85,8 @@ isRootObj, getRootObj, isEmptyName, - getAllChildren + getAllChildren, + getLevelGroup ) from bpy_extras.io_utils import ( @@ -240,215 +241,198 @@ def getRoomName(curResModule, roomString): return result -class B3DExporter: +borders = {} +currentRes = '' +currentRoomName = '' + +def createBorderList(): + global borders + global currentRes borders = {} - currentRes = '' - currentRoomName = '' - def createBorderList(self): + borderBlocks = [cn for cn in bpy.data.objects if cn.get(BLOCK_TYPE) == 30 \ + and (cn.get(prop(b_30.ResModule1)) == currentRes or cn.get(prop(b_30.ResModule2)) == currentRes)] - self.borders = {} + for bb in borderBlocks: - borderBlocks = [cn for cn in bpy.data.objects if cn.get(BLOCK_TYPE) == 30 \ - and (cn.get(prop(b_30.ResModule1)) == self.currentRes or cn.get(prop(b_30.ResModule2)) == self.currentRes)] + border1 = '{}:{}'.format(bb[prop(b_30.ResModule1)], bb[prop(b_30.RoomName1)]) + border2 = '{}:{}'.format(bb[prop(b_30.ResModule2)], bb[prop(b_30.RoomName2)]) - for bb in borderBlocks: + if not border1 in borders: + borders[border1] = [] + borders[border1].append(bb) + else: + borders[border1].append(bb) - border1 = '{}:{}'.format(bb[prop(b_30.ResModule1)], bb[prop(b_30.RoomName1)]) - border2 = '{}:{}'.format(bb[prop(b_30.ResModule2)], bb[prop(b_30.RoomName2)]) + if not border2 in borders: + borders[border2] = [] + borders[border2].append(bb) + else: + borders[border2].append(bb) - if not border1 in self.borders: - self.borders[border1] = [] - self.borders[border1].append(bb) - else: - self.borders[border1].append(bb) - if not border2 in self.borders: - self.borders[border2] = [] - self.borders[border2].append(bb) - else: - self.borders[border2].append(bb) +def write(file, context, op, filepath): + global myFile_pro + myFile_pro = filepath - def write(self, file, context, op, filepath): + export(filepath) - global myFile_pro - myFile_pro = filepath - # if generate_pro_file == True: - # export_pro(myFile_pro, textures_path) +def export(filepath): - # global myFile - # myFile = filepath - self.export(filepath) + global currentRes - def export(self, filepath): - file = open(filepath, 'wb') + file = open(filepath, 'wb') - # global global_matrix - # global_matrix = axis_conversion(to_forward="-Z", - # to_up="Y", - # ).to_4x4() * Matrix.Scale(1, 4) + materials = [] - # global generatePro - # generatePro = generate_pro_file + for material in bpy.data.materials: + materials.append(material.name) - # global verNums - # verNums = [] + cp_materials = 0 + cp_data_blocks = 0 + cp_eof = 0 - #ba = bytearray(b'\x00' * 20) + #Header - #file.write(ba) + file.write(b'b3d\x00')#struct.pack("4c",b'B',b'3',b'D',b'\x00')) - materials = [] + file.write(struct.pack(' 0: + for obj in rChild[:-1]: + if obj[BLOCK_TYPE] == 10 or obj[BLOCK_TYPE] == 9: + curMaxCnt = 2 + elif obj[BLOCK_TYPE] == 21: + curMaxCnt = obj[prop(b_21.GroupCnt)] + exportBlock(obj, False, curLevel, curMaxCnt, [0], {}, file) + + file.write(struct.pack(" 0: - for obj in rChild[:-1]: - if obj[BLOCK_TYPE] == 10 or obj[BLOCK_TYPE] == 9: - curMaxCnt = 2 - elif obj[BLOCK_TYPE] == 21: - curMaxCnt = obj[prop(b_21.GroupCnt)] - self.exportBlock(obj, False, curLevel, curMaxCnt, [0], {}, file) + block = obj - file.write(struct.pack(" 0: + file.write(struct.pack(" 0): + for i, ch in enumerate(blChildren[:-1]): - log.debug("{}_{}_{}_{}".format(block[BLOCK_TYPE], curLevel, block[LEVEL_GROUP], block.name)) + exportBlock(ch, False, curLevel+1, curMaxCnt, curGroups, extra, file) - if len(curGroups) <= curLevel: - curGroups.append(0) + exportBlock(blChildren[-1], True, curLevel+1, curMaxCnt, curGroups, extra, file) - #write Group Chunk - if block[LEVEL_GROUP] > curGroups[curLevel]: - log.debug('group ended') - for i in range(block[LEVEL_GROUP] - curGroups[curLevel]): - file.write(struct.pack(" 0: l_extra['passToMesh'] = passToMesh - self.exportBlock(ch, False, curLevel+1, curMaxCnt, curGroups, l_extra, file) + exportBlock(ch, False, curLevel+1, curMaxCnt, curGroups, l_extra, file) if len(passToMesh) > 0: l_extra['passToMesh'] = passToMesh - self.exportBlock(blChildren[-1], True, curLevel+1, curMaxCnt, curGroups, l_extra, file) - - # log.debug("{}_{}".format(curGroups, block.name)) - - # called from parent object with 0 children - if toProcessChild and len(blChildren) == 0 and curMaxCnt > 1: - for i in range(curMaxCnt-1): - file.write(struct.pack(" 0: + + log.debug(objString) + levelGroups[lvl] +=1 + parentObj = context.scene.objects.get(objString[-1]) + print(parentObj.name) + if parentObj.name[:6] != 'GROUP_': + print('not group_chunk') + else: + print('is group_chunk') + + if parentObj.name[:6] == 'GROUP_': + del objString[-1] + parentObj = context.scene.objects.get(objString[-1]) + + if levelGroups[lvl] > 0: + log.debug(parentObj.children) + if len(parentObj.children) == 0: + groupObjName = 'GROUP_{}'.format(0) + log.debug(groupObjName) + + b3dObj = bpy.data.objects.new(groupObjName, None) + b3dObj[BLOCK_TYPE] = 444 + + b3dObj.parent = parentObj + context.collection.objects.link(b3dObj) + # objString.append(b3dObj.name) + + + groupObjName = 'GROUP_{}'.format(levelGroups[lvl]) + log.debug(groupObjName) + + b3dObj = bpy.data.objects.new(groupObjName, None) + b3dObj[BLOCK_TYPE] = 444 + + b3dObj.parent = context.scene.objects.get(objString[-1]) + context.collection.objects.link(b3dObj) + + objString.append(b3dObj.name) + continue elif ex == ChunkType.BEGIN_CHUNK: lvl+=1 @@ -547,14 +593,34 @@ def read(file, context, self, filepath): levelGroups.append(0) t1 = time.perf_counter() - objString.append(objString[-1]) + + parentObj = context.scene.objects.get(objString[-1]) + + if parentObj.get(BLOCK_TYPE) in [9, 10, 21]: + + groupObjName = 'GROUP_{}'.format(0) + log.debug(groupObjName) + + b3dObj = bpy.data.objects.new(groupObjName, None) + b3dObj[BLOCK_TYPE] = 444 + + b3dObj.parent = parentObj + context.collection.objects.link(b3dObj) + + objString.append(b3dObj.name) + + objString.append("") + onlyName = readName(file) type = struct.unpack(" groupMax-1: l_group = groupMax-1 + + if block[BLOCK_TYPE] in [9, 10, 21]: + for ch in block.children: + blChildren.extend(ch.children) + else: + blChildren = block.children + if isActive and isMeshBlock(block): block.hide_set(state) - for directChild in block.children: + for directChild in blChildren: log.debug("Processing {}".format(directChild.name)) nextState = False if glevel == 1: @@ -396,7 +417,8 @@ def processCond(root, group, state): elif glevel > 1: nextState = isActive and True if clevel == 1: - if directChild[LEVEL_GROUP] == l_group or l_group == -1: + # if directChild[LEVEL_GROUP] == l_group or l_group == -1: + if getLevelGroup(directChild) == l_group or l_group == -1: stack.append([directChild, clevel+1, glevel, groupMax, nextState]) else: stack.append([directChild, clevel+1, glevel, groupMax, False]) @@ -499,27 +521,22 @@ def showHideSphere(context, root, pname): createRadDriver(b3dObj, bname, radName) def drawCommon(l_self, obj): - block_type = None - level_group = None - if BLOCK_TYPE in obj: - block_type = obj[BLOCK_TYPE] + block_type = None + level_group = None + if BLOCK_TYPE in obj: + block_type = obj[BLOCK_TYPE] - if LEVEL_GROUP in obj: - level_group = obj[LEVEL_GROUP] + level_group = getLevelGroup(obj) - lenStr = str(len(obj.children)) + lenStr = str(len(obj.children)) - box = l_self.layout.box() - box.label(text="Block type: " + str(block_type)) - box.label(text="Children block count: " + lenStr) - box.label(text="Block group: " + str(level_group)) + box = l_self.layout.box() + box.label(text="Block type: " + str(block_type)) + box.label(text="Children block count: " + lenStr) + box.label(text="Block group: " + str(level_group)) def drawAllFieldsByType(l_self, context, zclass, multipleEdit = True): - if zclass.__name__.split('_')[0] == 'b': - drawFieldsByType(l_self, context, b_common, multipleEdit) - drawFieldsByType(l_self, context, zclass, multipleEdit) - else: - drawFieldsByType(l_self, context, zclass, multipleEdit) + drawFieldsByType(l_self, context, zclass, multipleEdit) def drawFieldsByType(l_self, context, zclass, multipleEdit = True): @@ -673,7 +690,6 @@ def getObjByProp(context, object, zclass, pname): item.value = obj def getAllObjsByType(context, object, zclass): - getObjsByType(context, object, b_common) getObjsByType(context, object, zclass) def getObjsByType(context, object, zclass): @@ -752,9 +768,10 @@ def setObjByProp(context, object, zclass, pname): object[obj['prop']] = arr def setAllObjsByType(context, object, zclass): - setObjsByType(context, object, b_common) setObjsByType(context, object, zclass) +# def setObjsDefaultByType(context, object, zclass): + def setObjsByType(context, object, zclass): attrs = [obj for obj in zclass.__dict__.keys() if not obj.startswith('__')] diff --git a/src/2.80/addons/b3d_tools/consts.py b/src/2.80/addons/b3d_tools/consts.py index 34d2a65..9f597cb 100644 --- a/src/2.80/addons/b3d_tools/consts.py +++ b/src/2.80/addons/b3d_tools/consts.py @@ -12,46 +12,47 @@ BORDER_COLLECTION = 'Border objects' blockTypeList = [ - ('6566754', "b3d", "b3d"), - ('00', "00", "2D background"), - ('01', "01", "Camera"), - ('02', "02", "Unknown block"), - ('03', "03", "Container"), - ('04', "04", "Container containing other blocks"), - ('05', "05", "Container containing other blocks"), - ('06', "06", "Vertex block (HT1)"), - ('07', "07", "Vertex block (HT2)"), - ('08', "08", "Polygon block"), - ('09', "09", "Trigger"), - ('10', "10", "LOD"), - ('11', "11", "Unknown block"), - ('12', "12", "Unknown trigger"), - ('13', "13", "Unknown trigger(map load)"), - ('14', "14", "Unknown trigger(car related)"), - ('15', "15", "Unknown block"), - ('16', "16", "Unknown block"), - ('17', "17", "Unknown block"), - ('18', "18", "Connector between space block(24) and root container block. Exmaple: FiatWheel0Space and Single0Wheel14"), - ('19', "19", "Room container"), - ('20', "20", "Flat vertical collision"), - ('21', "21", "Container with event handling"), - ('22', "22", "Locator?"), - ('23', "23", "3D collision"), - ('24', "24", "Space"), - ('25', "25", "Sound"), - ('26', "26", "Locator?"), - ('27', "27", "Locator?"), - ('28', "28", "2D Sprite"), - ('29', "29", "Unknown block"), - ('30', "30", "Portal"), - ('31', "31", "Unknown block"), - ('33', "33", "Light source"), - ('34', "34", "Unknown block"), - ('35', "35", "Polygon block"), - ('36', "36", "Vertex block (HT1)"), - ('37', "37", "Vertex block (HT2)"), - ('39', "39", "Locator?"), - ('40', "40", "Object generator") + ('111', "b3d root", "b3d"), + ('444', "Group", "Grouping object"), + ('00', "00(Unk?)", "2D background"), + ('01', "01(Camera)", "Camera"), + ('02', "02(Unk?)", "Unknown block"), + ('03', "03(Container)", "Container"), + ('04', "04(Container)", "Container containing other blocks"), + ('05', "05(Container)", "Container containing other blocks"), + ('06', "06(Vertexes)", "Vertex block (HT1)"), + ('07', "07(Vertexes)", "Vertex block (HT2)"), + ('08', "08(Polygons)", "Polygon block"), + ('09', "09(Trigger)", "Trigger"), + ('10', "10(LOD)", "LOD"), + ('11', "11(Trigger)", "Unknown block"), + ('12', "12(Trigger)", "Unknown trigger"), + ('13', "13(Trigger)", "Unknown trigger(map load)"), + ('14', "14(Trigger)", "Unknown trigger(car related)"), + ('15', "15(Trigger)", "Unknown block"), + ('16', "16(Trigger)", "Unknown block"), + ('17', "17(Trigger)", "Unknown block"), + ('18', "18(Connector)", "Connector between space block(24) and root container block. Exmaple: FiatWheel0Space and Single0Wheel14"), + ('19', "19(Room)", "Room container"), + ('20', "20(2D collision)", "Flat vertical collision"), + ('21', "21(Event)", "Container with event handling"), + ('22', "22(Trigger)", "Locator?"), + ('23', "23(3D collision)", "3D collision"), + ('24', "24(Space)", "Space"), + ('25', "25(Sound)", "Sound"), + ('26', "26(Unk?)", "Locator?"), + ('27', "27(Unk?)", "Locator?"), + ('28', "28(2D Sprite)", "2D Sprite"), + ('29', "29(Unk?)", "Unknown block"), + ('30', "30(Portal)", "Portal"), + ('31', "31(Unk?)", "Unknown block"), + ('33', "33(Light)", "Light source"), + ('34', "34(Unk?)", "Unknown block"), + ('35', "35(Polygons)", "Polygon block"), + ('36', "36(Vertexes)", "Vertex block (HT1)"), + ('37', "37(Vertexes)", "Vertex block (HT2)"), + ('39', "39(Unk?)", "Locator?"), + ('40', "40(Generator)", "Object generator"), ] collisionTypeList = [ From 0328ae6b85ad8922a4d42dbb0337cd062bb2cc7b Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sat, 11 Feb 2023 14:48:34 +0200 Subject: [PATCH 41/47] b3dSqlite --- utils/b3dSqlite.py | 1108 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1108 insertions(+) create mode 100644 utils/b3dSqlite.py diff --git a/utils/b3dSqlite.py b/utils/b3dSqlite.py new file mode 100644 index 0000000..ef4d66b --- /dev/null +++ b/utils/b3dSqlite.py @@ -0,0 +1,1108 @@ +import sqlite3 +import struct +import logging +import sys +import os +import enum + +filename = '' +outdir = '' + + +# dbName = r'.\testHT1.db' +dbName = r'.\testHT2.db' + +# reloadTables = True +reloadTables = False + +args = sys.argv + +if len(args) == 2: + filename = args[1] + outdir = os.path.dirname(filename) +else: + print(args) + print("Wrong number of parameters") + print("") + print('Usage: python b3dSqlite.py ') + print(' - (obligatory) Path to .b3d file to export meshes') + print('Tested with Python v.3.9.13') + sys.exit() + + +logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) +log = logging.getLogger("sqliteb3d") +log.setLevel(logging.DEBUG) + +b3dBlocks = [ + 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,33,34,35,36,37,39,40 +] + +class ChunkType(enum.Enum): + END_CHUNK = 0 + END_CHUNKS = 1 + BEGIN_CHUNK = 2 + GROUP_CHUNK = 3 + +def openclose(file): + oc = file.read(4) + if (oc == (b'\x4D\x01\x00\x00')): # Begin_Chunk(111) + return ChunkType.BEGIN_CHUNK + elif oc == (b'\x2B\x02\x00\x00'): # End_Chunk(555) + return ChunkType.END_CHUNK + elif oc == (b'\xbc\x01\x00\x00'): # Group_Chunk(444) + return ChunkType.GROUP_CHUNK + elif oc == (b'\xde\x00\00\00'): # End_Chunks(222) + return ChunkType.END_CHUNKS + else: + log.debug(oc) + log.debug(file.tell()) + raise Exception() + +def readName(file): + objName = file.read(32) + if (objName[0] == 0): + objName = '' + #objname = "Untitled_0x" + str(hex(pos-36)) + else: + objName = (objName.decode("cp1251").rstrip('\0')) + return objName + +def tabSphere(name, isInt = False): + ctype = "INT" if isInt else "FLOAT" + return """ + {name}_x {ctype}, + {name}_y {ctype}, + {name}_z {ctype}, + {name}_r {ctype}""".format(name=name, ctype=ctype) + +def tabPoint(name, isInt = False): + ctype = "INT" if isInt else "FLOAT" + return """ + {name}_x {ctype}, + {name}_y {ctype}, + {name}_z {ctype}""".format(name=name, ctype=ctype) + +def getBlockColumnByType(blockType, noTypes = False): + blockColumns = "" + if blockType == 1: + blockColumns = """ + name1 VARCHAR(32), + name2 VARCHAR(32) + """ + elif blockType == 2: + blockColumns = """ + {}, + {}, + child_cnt INT + """.format( + tabSphere("bound_sphere"), + tabSphere("unk_sphere") + ) + elif blockType == 3: + blockColumns = """ + {}, + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 4: + blockColumns = """ + {}, + name1 VARCHAR(32), + name2 VARCHAR(32), + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 5: + blockColumns = """ + {}, + name1 VARCHAR(32), + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 6: + blockColumns = """ + {}, + name1 VARCHAR(32), + name2 VARCHAR(32), + vertex_cnt INT, + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 7: + blockColumns = """ + {}, + name1 VARCHAR(32), + vertex_cnt INT, + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 8: + blockColumns = """ + {}, + poly_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType in [9,10,22]: + blockColumns = """ + {}, + {}, + child_cnt INT + """.format( + tabSphere("bound_sphere"), + tabSphere("unk_sphere") + ) + elif blockType == 11: + blockColumns = """ + {}, + {}, + {}, + float1 FLOAT, + float2 FLOAT, + child_cnt INT + """.format( + tabSphere("bound_sphere"), + tabPoint("unk_point1"), + tabPoint("unk_point2") + ) + elif blockType in [12, 14]: + blockColumns = """ + {}, + {}, + int1 INT, + int2 INT, + unk_cnt INT + """.format( + tabSphere("bound_sphere"), + tabSphere("unk_sphere") + ) + elif blockType in [13, 15]: + blockColumns = """ + {}, + int1 INT, + int2 INT, + unk_cnt INT + """.format( + tabSphere("bound_sphere"), + tabSphere("unk_sphere") + ) + elif blockType in [16, 17]: + blockColumns = """ + {}, + {}, + {}, + float1 FLOAT, + float2 FLOAT, + int1 INT, + int2 INT, + poly_cnt INT + """.format( + tabSphere("bound_sphere"), + tabPoint("point1"), + tabPoint("point2"), + ) + elif blockType == 18: + blockColumns = """ + {}, + space_name VARCHAR(32), + add_name VARCHAR(32) + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 19: + blockColumns = """ + child_cnt INT + """ + elif blockType == 20: + blockColumns = """ + {}, + vertex_cnt INT, + int1 INT, + int2 INT, + unk_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 21: + blockColumns = """ + {}, + int1 INT, + int2 INT, + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 23: + blockColumns = """ + int1 INT, + surface INT, + unk_cnt INT, + poly_cnt INT + """ + elif blockType == 24: + blockColumns = """ + {}, + {}, + {}, + {}, + flag INT, + child_cnt INT + """.format( + tabPoint("transf1"), + tabPoint("transf2"), + tabPoint("transf3"), + tabPoint("pos") + ) + elif blockType == 25: + blockColumns = """ + {}, + name1 VARCHAR(32), + {}, + {}, + float1 FLOAT, + float2 FLOAT, + float3 FLOAT, + float4 FLOAT, + float5 FLOAT + """.format( + tabPoint("point1", True), + tabPoint("point2"), + tabPoint("point3") + ) + elif blockType == 26: + blockColumns = """ + {}, + {}, + {}, + {}, + child_cnt INT + """.format( + tabSphere("bound_sphere"), + tabSphere("point1"), + tabSphere("point2"), + tabSphere("point3") + ) + elif blockType == 27: + blockColumns = """ + {}, + flag1 INT, + {}, + material INT + """.format( + tabSphere("bound_sphere"), + tabPoint("unk_point"), + ) + elif blockType == 28: + blockColumns = """ + {}, + {}, + vertex_cnt INT + """.format( + tabSphere("bound_sphere"), + tabPoint("sprite_center"), + ) + elif blockType == 29: + blockColumns = """ + {}, + unk_cnt INT, + int2 INT, + {}, + child_cnt INT + """.format( + tabSphere("bound_sphere"), + tabSphere("unk_sphere"), + ) + elif blockType == 30: + blockColumns = """ + {}, + room_name VARCHAR(32), + {}, + {} + """.format( + tabSphere("bound_sphere"), + tabPoint("point1"), + tabPoint("point2"), + ) + elif blockType == 31: + blockColumns = """ + {}, + unk_cnt INT, + {}, + int1 INT, + {} + """.format( + tabSphere("bound_sphere"), + tabSphere("unk_sphere"), + tabPoint("unk_point"), + ) + elif blockType == 33: + blockColumns = """ + {}, + use_lights INT, + light_type INT, + flag1 INT, + {}, + {}, + float1 FLOAT, + float2 FLOAT, + light_r FLOAT, + intensity FLOAT, + float3 FLOAT, + float4 FLOAT, + {}, + child_cnt INT + """.format( + tabSphere("bound_sphere"), + tabPoint("unk_sphere1"), + tabPoint("unk_sphere2"), + tabPoint("rgb"), + ) + elif blockType == 34: + blockColumns = """ + {}, + int1 INT, + unk_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 35: + blockColumns = """ + {}, + mtype INT, + texnum INT, + poly_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 36: + blockColumns = """ + {}, + name1 VARCHAR(32), + name2 VARCHAR(32), + format INT, + vertex_cnt INT, + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 37: + blockColumns = """ + {}, + name1 VARCHAR(32), + format INT, + vertex_cnt INT, + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 39: + blockColumns = """ + {}, + color_r INT, + float1 FLOAT, + fog_start FLOAT, + fog_end FLOAT, + color_id INT, + child_cnt INT + """.format( + tabSphere("bound_sphere") + ) + elif blockType == 40: + blockColumns = """ + {}, + name1 VARCHAR(32), + name2 VARCHAR(32), + int1 INT, + int2 INT, + unk_cnt INT + """.format( + tabSphere("bound_sphere") + ) + + if noTypes: + blockColumns = blockColumns.replace(" INT", "") + blockColumns = blockColumns.replace(" FLOAT", "") + blockColumns = blockColumns.replace(" VARCHAR(32)", "") + + return blockColumns + +insertColumns = {} +for blockType in b3dBlocks: + insertColumns[blockType] = getBlockColumnByType(blockType, True) + +def createTableByType(con, blockType): + + cur = con.cursor() + + sqlStatement = """ + CREATE TABLE IF NOT EXISTS b_{}( + id INTEGER PRIMARY KEY AUTOINCREMENT, + b3dmodule VARCHAR(32), + b3dname VARCHAR(32), + {} + ) + """ + blockColumns = getBlockColumnByType(blockType) + + cur.execute(sqlStatement.format(blockType, blockColumns)) + +def getPlaceholders(cnt): + if cnt > 0: + arr = ['?'] * cnt + return ",".join(arr) + return "" + +def insertByType(con, blockType, row): + + # log.debug("inserting {}".format(blockType)) + + cur = con.cursor() + + count = (insertColumns[blockType]).count(",")+1+2 + + sqlStatement = """ + INSERT INTO b_{}(b3dmodule, b3dname, {}) + VALUES ({}) + """.format(blockType, insertColumns[blockType], getPlaceholders(count)) + + cur.execute(sqlStatement, row) + con.commit() + +def readb3d(con, file): + + resBasename = os.path.basename(file.name)[:-4] #cut extension + + if file.read(3) == b'b3d': + log.info("correct file") + else: + log.error("b3d error") + + file.seek(1,1) + filesize = struct.unpack("> 8 #ah + + if format & 0b10: + uvCount += 1 + + unkF = struct.unpack("> 8) + 1 #ah + unknown3 = struct.unpack(" 0: + f = struct.unpack("<"+str(num0)+"f",file.read(4*num0)) + + childCnt = struct.unpack("> 8 #ah + + if format & 0b10: + uvCount += 1 + + unkF = struct.unpack("> 8 + format = formatRaw & 0xFF + + vertexCount = struct.unpack("> 8 + format = formatRaw & 0xFF + vertexCount = struct.unpack(" 0: + if format == 0: + # objString[len(objString)-1] = objString[-2] + pass + else: + for i in range(vertexCount): + vertex = struct.unpack("<3f",file.read(12)) + uv = struct.unpack("<2f",file.read(8)) + for j in range(uvCount): + uv = struct.unpack("<2f",file.read(8)) + if format == 1 or format == 2: + normal = struct.unpack("<3f",file.read(12)) + elif format == 3: + normal_off = struct.unpack(" Date: Sat, 11 Feb 2023 14:52:14 +0200 Subject: [PATCH 42/47] origin point + block11 + bound sphere export --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 22 +- src/2.80/addons/b3d_tools/b3d/classes.py | 5 + src/2.80/addons/b3d_tools/b3d/common.py | 61 ++++ src/2.80/addons/b3d_tools/b3d/export_b3d.py | 311 +++++++++++++------ src/2.80/addons/b3d_tools/b3d/import_b3d.py | 58 ++-- src/2.80/addons/b3d_tools/b3d/scripts.py | 9 +- utils/b3dSqlite.py | 2 +- utils/b3dsplit.py | 5 +- 8 files changed, 350 insertions(+), 123 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index 8605dbf..88328e3 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -657,15 +657,29 @@ class b_11(): 'group': borderSphereGroup, 'type': fieldType.SPHERE_EDIT } - Unk_XYZ = { - 'prop': 'unk_XYZ', + Unk_XYZ1 = { + 'prop': 'unk_XYZ1', 'type': fieldType.COORD, 'name': 'Unk. coord', 'description': '', 'default': (0.0, 0.0, 0.0) } - Unk_R = { - 'prop': 'unk_R', + Unk_XYZ2 = { + 'prop': 'unk_XYZ2', + 'type': fieldType.COORD, + 'name': 'Unk. coord', + 'description': '', + 'default': (0.0, 0.0, 0.0) + } + Unk_R1 = { + 'prop': 'unk_R1', + 'type': fieldType.RAD, + 'name': 'Unk. rad', + 'description': '', + 'default': 0.0 + } + Unk_R2 = { + 'prop': 'unk_R1', 'type': fieldType.RAD, 'name': 'Unk. rad', 'description': '', diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 7d9fd74..768e922 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -242,6 +242,11 @@ def createTypeClass(zclass, multipleEdit = True): description = obj['description'], maxlen = 32 ) + if subtype == fieldType.INT: + prop = IntProperty( + name = obj['name'], + description = obj['description'] + ) attributes['__annotations__']['{}_switch'.format(pname)] = prop_switch attributes['__annotations__']['{}_enum'.format(pname)] = prop_enum diff --git a/src/2.80/addons/b3d_tools/b3d/common.py b/src/2.80/addons/b3d_tools/b3d/common.py index 98c5e93..01c0638 100644 --- a/src/2.80/addons/b3d_tools/b3d/common.py +++ b/src/2.80/addons/b3d_tools/b3d/common.py @@ -5,6 +5,7 @@ import sys import re import time +from mathutils import Vector from ..common import log from ..consts import ( @@ -295,6 +296,66 @@ def getMytoolBlockName(btype, bnum, multipleClass = False): return bname +def getPythagorLength(p1, p2): + return (sum(map(lambda xx,yy : (xx-yy)**2,p1,p2)))**0.5 + +# https://b3d.interplanety.org/en/how-to-calculate-the-bounding-sphere-for-selected-objects/ +def getMultObjBoundingSphere(objnTransfs, mode='BBOX'): + # return the bounding sphere center and radius for objects (in global coordinates) + # if not isinstance(objects, list): + # objects = [objects] + points_co_global = [] + # if mode == 'GEOMETRY': + # # GEOMETRY - by all vertices/points - more precis, more slow + # for obj in objects: + # points_co_global.extend([obj.matrix_world @ vertex.co for vertex in obj.data.vertices]) + if mode == 'BBOX': + # BBOX - by object bounding boxes - less precis, quick + for objnTransf in objnTransfs: + obj = bpy.data.objects[objnTransf['obj']] + transf = bpy.data.objects[objnTransf['transf']] + points_co_global.extend([transf.matrix_world @ Vector(bbox) for bbox in obj.bound_box]) + + def get_center(l): + return (max(l) + min(l)) / 2 if l else 0.0 + + x, y, z = [[point_co[i] for point_co in points_co_global] for i in range(3)] + b_sphere_center = Vector([get_center(axis) for axis in [x, y, z]]) if (x and y and z) else None + b_sphere_radius = max(((point - b_sphere_center) for point in points_co_global)) if b_sphere_center else None + return [b_sphere_center, b_sphere_radius.length] + +# https://blender.stackexchange.com/questions/62040/get-center-of-geometry-of-an-object +def getSingleCoundingSphere(obj, local = False): + center = 0.125 * sum((Vector(b) for b in obj.bound_box), Vector()) + p1 = obj.bound_box[0] + if not local: + center = obj.matrix_world @ center + p1 = obj.matrix_world @ Vector(obj.bound_box[0]) + rad = getPythagorLength(center, p1) + return [center, rad] + + +def recalcToLocalCoord(center, vertexes): + newVertexes = [] + for vert in vertexes: + newVert = [0.0,0.0,0.0] + newVert[0] = vert[0] - center[0] + newVert[1] = vert[1] - center[1] + newVert[2] = vert[2] - center[2] + newVertexes.append(newVert) + + return newVertexes + +def getCenterCoord(vertices): + if len(vertices) == 0: + return (0.0, 0.0, 0.0) + x = [p[0] for p in vertices] + y = [p[1] for p in vertices] + z = [p[2] for p in vertices] + centroid = (sum(x) / len(vertices), sum(y) / len(vertices), sum(z) / len(vertices)) + + return centroid + def getLevelGroup(obj): parent = obj.parent # log.debug(parent) diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index f51e192..5b2bc54 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -86,7 +86,9 @@ getRootObj, isEmptyName, getAllChildren, - getLevelGroup + getLevelGroup, + getMultObjBoundingSphere, + getSingleCoundingSphere ) from bpy_extras.io_utils import ( @@ -245,6 +247,101 @@ def getRoomName(curResModule, roomString): currentRes = '' currentRoomName = '' + +meshesInEmpty = {} +emptyToMeshKeys = {} +uniqueArrays = {} +createdBounders = {} + +def fillBoundingSphereLists(): + + global meshesInEmpty + global emptyToMeshKeys + global uniqueArrays + global createdBounders + + # Getting 'empty' objects + objs = [cn for cn in bpy.data.objects if cn.get(BLOCK_TYPE) in [8, 28, 35]] + + for obj in objs: + curMeshName = obj.name + curObj = obj.parent + while not isRootObj(curObj): + if curObj.get(BLOCK_TYPE) != 444: + if meshesInEmpty.get(curObj.name) is None: + meshesInEmpty[curObj.name] = [] + meshesInEmpty[curObj.name].append({ + "obj": curMeshName, + "transf": curMeshName + }) + else: + meshesInEmpty[curObj.name].append({ + "obj": curMeshName, + "transf": curMeshName + }) + + curObj = curObj.parent + + #extend with 18 blocks + objs = [cn for cn in bpy.data.objects if cn.get(BLOCK_TYPE) == 18] + + for obj in objs: + referenceableName = obj.get(prop(b_18.Add_Name)) + spaceName = obj.get(prop(b_18.Space_Name)) + curMeshList = meshesInEmpty.get(referenceableName) + # log.debug(curMeshList) + if curMeshList is not None: + + # global coords for 18 blocks parents + globalTransfMeshList = [{ + "obj": cn.get("obj"), + "transf": spaceName + # "transf": cn.get("transf") + } for cn in curMeshList] + + curObj = obj.parent + while not isRootObj(curObj): + if curObj.get(BLOCK_TYPE) != 444: + if meshesInEmpty.get(curObj.name) is None: + meshesInEmpty[curObj.name] = [] + meshesInEmpty[curObj.name].extend(globalTransfMeshList) + else: + meshesInEmpty[curObj.name].extend(globalTransfMeshList) + + curObj = curObj.parent + + # local coords for 18 block itself + curObj = obj + localTransfMeshList = [{ + "obj": cn.get("obj"), + # "transf": spaceName + "transf": cn.get("transf") + } for cn in curMeshList] + + if meshesInEmpty.get(curObj.name) is None: + meshesInEmpty[curObj.name] = [] + meshesInEmpty[curObj.name].extend(localTransfMeshList) + else: + meshesInEmpty[curObj.name].extend(localTransfMeshList) + + # meshesInEmptyStr = [str(cn) for cn in meshesInEmpty.values()] + + # for m in meshesInEmptyStr: + # log.debug(m) + + for emptyName in meshesInEmpty.keys(): + meshesInEmpty[emptyName].sort(key= lambda x: "{}{}".format(str(x["obj"]), str(x["transf"]))) + + key = "||".join(["{}{}".format(str(cn["obj"]), str(cn["transf"])) for cn in meshesInEmpty[emptyName]]) + emptyToMeshKeys[emptyName] = key + if not key in uniqueArrays: + uniqueArrays[key] = meshesInEmpty[emptyName] + + for key in uniqueArrays.keys(): + # objArr = [bpy.data.objects[cn] for cn in uniqueArrays[key]] + # createdBounders[key] = getMultObjBoundingSphere(objArr) + createdBounders[key] = getMultObjBoundingSphere(uniqueArrays[key]) + def createBorderList(): global borders @@ -271,6 +368,48 @@ def createBorderList(): else: borders[border2].append(bb) +def writeMeshSphere(file, obj): + + blockType = obj.get(BLOCK_TYPE) + + if blockType in [ + 8,35, + 28,30 + ]: + result = getSingleCoundingSphere(obj) + center = result[0] + rad = result[1] + + file.write(struct.pack("<3f", *center)) + file.write(struct.pack(" 0: for obj in rChild[:-1]: - if obj[BLOCK_TYPE] == 10 or obj[BLOCK_TYPE] == 9: + if obj.get(BLOCK_TYPE) == 10 or obj.get(BLOCK_TYPE) == 9: curMaxCnt = 2 - elif obj[BLOCK_TYPE] == 21: + elif obj.get(BLOCK_TYPE) == 21: curMaxCnt = obj[prop(b_21.GroupCnt)] exportBlock(obj, False, curLevel, curMaxCnt, [0], {}, file) file.write(struct.pack(" 0: - log.debug(objString) - levelGroups[lvl] +=1 parentObj = context.scene.objects.get(objString[-1]) - print(parentObj.name) - if parentObj.name[:6] != 'GROUP_': - print('not group_chunk') - else: - print('is group_chunk') if parentObj.name[:6] == 'GROUP_': del objString[-1] parentObj = context.scene.objects.get(objString[-1]) if levelGroups[lvl] > 0: - log.debug(parentObj.children) + if len(parentObj.children) == 0: groupObjName = 'GROUP_{}'.format(0) - log.debug(groupObjName) b3dObj = bpy.data.objects.new(groupObjName, None) b3dObj[BLOCK_TYPE] = 444 @@ -573,9 +567,7 @@ def read(file, context, self, filepath): context.collection.objects.link(b3dObj) # objString.append(b3dObj.name) - groupObjName = 'GROUP_{}'.format(levelGroups[lvl]) - log.debug(groupObjName) b3dObj = bpy.data.objects.new(groupObjName, None) b3dObj[BLOCK_TYPE] = 444 @@ -599,7 +591,6 @@ def read(file, context, self, filepath): if parentObj.get(BLOCK_TYPE) in [9, 10, 21]: groupObjName = 'GROUP_{}'.format(0) - log.debug(groupObjName) b3dObj = bpy.data.objects.new(groupObjName, None) b3dObj[BLOCK_TYPE] = 444 @@ -930,6 +921,8 @@ def read(file, context, self, filepath): curNormals.append(l_normals[newOldTransf[i]]) curNormalsOff.append(l_normals_off[newOldTransf[i]]) + curVertexes = recalcToLocalCoord(bounding_sphere[:3], curVertexes) + b3dMesh.from_pydata(curVertexes,[],curFaces) # Ev = threading.Event() @@ -991,6 +984,7 @@ def read(file, context, self, filepath): b3dObj = bpy.data.objects.new(objName, b3dMesh) b3dObj[BLOCK_TYPE] = type + b3dObj.location = bounding_sphere[0:3] b3dObj[prop(b_8.XYZ)] = bounding_sphere[0:3] b3dObj[prop(b_8.R)] = bounding_sphere[3] b3dObj.parent = parentObj @@ -1065,7 +1059,10 @@ def read(file, context, self, filepath): elif (type == 11): bounding_sphere = struct.unpack("<4f",file.read(16)) - unknown_sphere = struct.unpack("<4f",file.read(16)) + unknown_point1 = struct.unpack("<3f",file.read(12)) + unknown_point2 = struct.unpack("<3f",file.read(12)) + unknown_r1 = struct.unpack("') - print(' - (obligatory) Path to .b3d file to export meshes') + print(' - (obligatory) Path to .b3d file to fill SQLite') print('Tested with Python v.3.9.13') sys.exit() diff --git a/utils/b3dsplit.py b/utils/b3dsplit.py index 932c487..43040d2 100644 --- a/utils/b3dsplit.py +++ b/utils/b3dsplit.py @@ -288,7 +288,10 @@ def read(file): elif (type == 11): bounding_sphere = struct.unpack("<4f",file.read(16)) - unknown_sphere = struct.unpack("<4f",file.read(16)) + unknown_point = struct.unpack("<3f",file.read(12)) + unknown_point2 = struct.unpack("<3f",file.read(12)) + unk1 = struct.unpack(" Date: Sat, 11 Feb 2023 17:22:51 +0200 Subject: [PATCH 43/47] no bound sphere property --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 1398 +++++++++--------- src/2.80/addons/b3d_tools/b3d/classes.py | 20 +- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 21 +- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 132 +- src/2.80/addons/b3d_tools/b3d/panel.py | 26 +- 5 files changed, 810 insertions(+), 787 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index 88328e3..a926c51 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -329,27 +329,27 @@ class b_1(): } class b_2(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -365,51 +365,51 @@ class b_2(): 'default': 0.0 } -class b_3(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } +# class b_3(): + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } class b_4(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Name1 = { 'prop': 'name1', 'type': fieldType.ENUM_DYN, @@ -434,51 +434,51 @@ class b_5(): 'description': '', 'default': '' } - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } class b_6(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -495,27 +495,27 @@ class b_6(): } class b_7(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -524,51 +524,51 @@ class b_7(): 'default': '' } -class b_8(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } +# class b_8(): + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } class b_9(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ = { 'prop': 'b3d_b9_center', 'group': 'b9_group', @@ -592,27 +592,27 @@ class b_9(): } class b_10(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } LOD_XYZ = { 'prop': 'b3d_LOD_center', 'group': 'LOD_group', @@ -636,27 +636,27 @@ class b_10(): } class b_11(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, @@ -687,27 +687,27 @@ class b_11(): } class b_12(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -744,27 +744,27 @@ class b_12(): } class b_13(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -787,27 +787,27 @@ class b_13(): } class b_14(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -844,27 +844,27 @@ class b_14(): } class b_15(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -887,27 +887,27 @@ class b_15(): } class b_16(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, @@ -958,27 +958,27 @@ class b_16(): } class b_17(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, @@ -1029,27 +1029,27 @@ class b_17(): } class b_18(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Space_Name = { 'prop': 'space_name', 'type': fieldType.ENUM_DYN, @@ -1068,27 +1068,27 @@ class b_18(): } class b_20(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -1111,27 +1111,27 @@ class b_20(): } class b_21(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } GroupCnt = { 'prop': 'group_cnt', 'type': fieldType.INT, @@ -1148,27 +1148,27 @@ class b_21(): } class b_22(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -1285,27 +1285,27 @@ class b_25(): } class b_26(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_XYZ1 = { 'prop': 'unk_XYZ1', 'type': fieldType.COORD, @@ -1329,27 +1329,27 @@ class b_26(): } class b_27(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Flag = { 'prop': 'flag', 'type': fieldType.INT, @@ -1373,27 +1373,27 @@ class b_27(): } class b_28(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Sprite_Center = { 'prop': 'unk_XYZ', 'type': fieldType.COORD, @@ -1404,27 +1404,27 @@ class b_28(): #todo: check class b_29(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -1455,27 +1455,27 @@ class b_29(): } class b_30(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } ResModule1 = { 'prop': '1_roomName_res', 'group': 'resModule1', @@ -1518,27 +1518,27 @@ class b_30(): } class b_31(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Unk_Int1 = { 'prop': 'int1', 'type': fieldType.INT, @@ -1577,27 +1577,27 @@ class b_31(): #todo: check class b_33(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Use_Lights = { 'prop': 'useLight', 'type': fieldType.INT, @@ -1685,27 +1685,27 @@ class b_33(): class b_34(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } UnkInt = { 'prop': 'int1', 'type': fieldType.INT, @@ -1715,27 +1715,27 @@ class b_34(): } class b_35(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } MType = { 'prop': 'mType', 'type': fieldType.INT, @@ -1753,27 +1753,27 @@ class b_35(): } class b_36(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -1797,27 +1797,27 @@ class b_36(): } class b_37(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -1834,27 +1834,27 @@ class b_37(): } class b_39(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Color_R = { 'prop': 'color_r', 'type': fieldType.INT, @@ -1892,27 +1892,27 @@ class b_39(): } class b_40(): - XYZ = { - 'prop': 'b3d_border_center', - 'group': borderSphereGroup, - 'type': fieldType.COORD, - 'name': 'Block border coord', - 'description': '', - 'default': (0.0, 0.0, 0.0) - } - R = { - 'prop': 'b3d_border_rad', - 'group': borderSphereGroup, - 'type': fieldType.RAD, - 'name': 'Block border rad', - 'description': '', - 'default': 0.0 - } - Set_Bound = { - 'prop': 'b3d_border', - 'group': borderSphereGroup, - 'type': fieldType.SPHERE_EDIT - } + # XYZ = { + # 'prop': 'b3d_border_center', + # 'group': borderSphereGroup, + # 'type': fieldType.COORD, + # 'name': 'Block border coord', + # 'description': '', + # 'default': (0.0, 0.0, 0.0) + # } + # R = { + # 'prop': 'b3d_border_rad', + # 'group': borderSphereGroup, + # 'type': fieldType.RAD, + # 'name': 'Block border rad', + # 'description': '', + # 'default': 0.0 + # } + # Set_Bound = { + # 'prop': 'b3d_border', + # 'group': borderSphereGroup, + # 'type': fieldType.SPHERE_EDIT + # } Name1 = { 'prop': 'name1', 'type': fieldType.STRING, @@ -1956,8 +1956,8 @@ def getClassDefByType(blockNum): zclass = b_1 elif blockNum == 2: zclass = b_2 - elif blockNum == 3: - zclass = b_3 + # elif blockNum == 3: + # zclass = b_3 elif blockNum == 4: zclass = b_4 elif blockNum == 5: @@ -1966,8 +1966,8 @@ def getClassDefByType(blockNum): zclass = b_6 elif blockNum == 7: zclass = b_7 - elif blockNum == 8: - zclass = b_8 + # elif blockNum == 8: + # zclass = b_8 elif blockNum == 9: zclass = b_9 elif blockNum == 10: diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 768e922..38973df 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -19,12 +19,12 @@ from .class_descr import ( b_1, b_2, - b_3, + # b_3, b_4, b_5, b_6, b_7, - b_8, + # b_8, b_9, b_10, b_11, @@ -302,12 +302,12 @@ def createTypeClass(zclass, multipleEdit = True): s_block_1 = createTypeClass(b_1, False) s_block_2 = createTypeClass(b_2, False) -s_block_3 = createTypeClass(b_3, False) +# s_block_3 = createTypeClass(b_3, False) s_block_4 = createTypeClass(b_4, False) s_block_5 = createTypeClass(b_5, False) s_block_6 = createTypeClass(b_6, False) s_block_7 = createTypeClass(b_7, False) -s_block_8 = createTypeClass(b_8, False) +# s_block_8 = createTypeClass(b_8, False) s_block_9 = createTypeClass(b_9, False) s_block_10 = createTypeClass(b_10, False) s_block_11 = createTypeClass(b_11, False) @@ -340,12 +340,12 @@ def createTypeClass(zclass, multipleEdit = True): block_1 = createTypeClass(b_1) block_2 = createTypeClass(b_2) -block_3 = createTypeClass(b_3) +# block_3 = createTypeClass(b_3) block_4 = createTypeClass(b_4) block_5 = createTypeClass(b_5) block_6 = createTypeClass(b_6) block_7 = createTypeClass(b_7) -block_8 = createTypeClass(b_8) +# block_8 = createTypeClass(b_8) block_9 = createTypeClass(b_9) block_10 = createTypeClass(b_10) block_11 = createTypeClass(b_11) @@ -379,12 +379,12 @@ def createTypeClass(zclass, multipleEdit = True): _classes = ( s_block_1, s_block_2, - s_block_3, + # s_block_3, s_block_4, s_block_5, s_block_6, s_block_7, - s_block_8, + # s_block_8, s_block_9, s_block_10, s_block_11, @@ -417,12 +417,12 @@ def createTypeClass(zclass, multipleEdit = True): block_1, block_2, - block_3, + # block_3, block_4, block_5, block_6, block_7, - block_8, + # block_8, block_9, block_10, block_11, diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index 5b2bc54..2171c81 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -23,12 +23,12 @@ from .class_descr import ( b_1, b_2, - b_3, + # b_3, b_4, b_5, b_6, b_7, - b_8, + # b_8, b_9, b_10, b_11, @@ -528,10 +528,21 @@ def export(filepath): file.write(struct.pack(" Date: Sun, 12 Feb 2023 11:27:20 +0200 Subject: [PATCH 44/47] import simplify + block add --- src/2.80/addons/b3d_tools/b3d/class_descr.py | 25 +- src/2.80/addons/b3d_tools/b3d/classes.py | 23 +- src/2.80/addons/b3d_tools/b3d/export_b3d.py | 25 +- src/2.80/addons/b3d_tools/b3d/import_b3d.py | 129 +++--- src/2.80/addons/b3d_tools/b3d/menus.py | 21 +- src/2.80/addons/b3d_tools/b3d/panel.py | 420 ++++++++++++++----- src/2.80/addons/b3d_tools/consts.py | 20 +- 7 files changed, 443 insertions(+), 220 deletions(-) diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index a926c51..8e48118 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -23,6 +23,7 @@ collisionTypeList, generatorTypeList, b24FlagList, + vTypeList, BLOCK_TYPE, LEVEL_GROUP ) @@ -1788,12 +1789,14 @@ class b_36(): 'description': '', 'default': '' } - MType = { - 'prop': 'MType', - 'type': fieldType.INT, - 'name': 'Type', + VType = { + 'prop': 'vType', + 'type': fieldType.ENUM, + 'subtype': fieldType.INT, + 'name': 'Vertex type', 'description': '', - 'default': 0 + 'default': 2, + 'items': vTypeList } class b_37(): @@ -1825,12 +1828,14 @@ class b_37(): 'description': '', 'default': '' } - SType = { - 'prop': 'SType', - 'type': fieldType.INT, - 'name': 'Type', + VType = { + 'prop': 'vType', + 'type': fieldType.ENUM, + 'subtype': fieldType.INT, + 'name': 'Vertex type', 'description': '', - 'default': 0 + 'default': 1, + 'items': vTypeList } class b_39(): diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index 38973df..fe23568 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -80,7 +80,7 @@ def callback_func(self, context): result = int(result) elif subtype == fieldType.FLOAT: result = float(result) - elif subtype == fieldType.FLOAT: + elif subtype == fieldType.STRING: result = str(result) setattr( @@ -203,12 +203,19 @@ def createTypeClass(zclass, multipleEdit = True): ) if multipleEdit: - prop = EnumProperty( - name = obj['name'], - description = obj['description'], - default = obj['default'], - items = obj['items'] - ) + if subtype == fieldType.STRING: + prop = StringProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'], + maxlen = 32 + ) + elif subtype == fieldType.INT: + prop = IntProperty( + name = obj['name'], + description = obj['description'], + default = obj['default'] + ) attributes['__annotations__']['{}_switch'.format(pname)] = prop_switch attributes['__annotations__']['{}_enum'.format(pname)] = prop_enum @@ -242,7 +249,7 @@ def createTypeClass(zclass, multipleEdit = True): description = obj['description'], maxlen = 32 ) - if subtype == fieldType.INT: + elif subtype == fieldType.INT: prop = IntProperty( name = obj['name'], description = obj['description'] diff --git a/src/2.80/addons/b3d_tools/b3d/export_b3d.py b/src/2.80/addons/b3d_tools/b3d/export_b3d.py index 2171c81..5cff3bf 100644 --- a/src/2.80/addons/b3d_tools/b3d/export_b3d.py +++ b/src/2.80/addons/b3d_tools/b3d/export_b3d.py @@ -718,7 +718,9 @@ def exportBlock(obj, isLast, curLevel, maxGroups, curGroups, extra, file): # file.write(struct.pack("> 8 format = formatRaw & 0xFF - if format == 1 or format == 2: - log.debug("normals 3f") - elif format == 3: - log.debug("normals f") - vertex_block_uvs.append([]) for i in range(uvCount): vertex_block_uvs.append([]) @@ -2192,7 +2182,7 @@ def read(file, context, self, filepath): # b3dObj[prop(b_36.R)] = bounding_sphere[3] b3dObj[prop(b_36.Name1)] = name1 b3dObj[prop(b_36.Name2)] = name2 - b3dObj[prop(b_36.MType)] = formatRaw + b3dObj[prop(b_36.VType)] = formatRaw b3dObj.parent = parentObj context.collection.objects.link(b3dObj) @@ -2215,11 +2205,6 @@ def read(file, context, self, filepath): uvCount = formatRaw >> 8 format = formatRaw & 0xFF - if format == 1 or format == 2: - log.debug("normals 3f") - elif format == 3: - log.debug("normals f") - vertex_block_uvs.append([]) for i in range(uvCount): vertex_block_uvs.append([]) @@ -2261,7 +2246,7 @@ def read(file, context, self, filepath): # b3dObj[prop(b_37.XYZ)] = bounding_sphere[0:3] # b3dObj[prop(b_37.R)] = bounding_sphere[3] b3dObj[prop(b_37.Name1)] = groupName - b3dObj[prop(b_37.SType)] = formatRaw + b3dObj[prop(b_37.VType)] = formatRaw b3dObj.parent = parentObj context.collection.objects.link(b3dObj) diff --git a/src/2.80/addons/b3d_tools/b3d/menus.py b/src/2.80/addons/b3d_tools/b3d/menus.py index 2d54d0b..e313301 100644 --- a/src/2.80/addons/b3d_tools/b3d/menus.py +++ b/src/2.80/addons/b3d_tools/b3d/menus.py @@ -191,19 +191,14 @@ class ExportB3D(Operator, ImportHelper): filename_ext = '.b3d' filter_glob : StringProperty(default='*.b3d', options={'HIDDEN'}) - generate_pro_file : BoolProperty(name='Generate .pro file', - description='Generate .pro file, which can used'\ - 'to assembly the resources file', default=False) - - textures_path : StringProperty( - name="Textures directory", - default="txr\\", - ) - - partial_export: BoolProperty( - name="Partial export", - default=False, - ) + # generate_pro_file : BoolProperty(name='Generate .pro file', + # description='Generate .pro file, which can used'\ + # 'to assembly the resources file', default=False) + + # textures_path : StringProperty( + # name="Textures directory", + # default="txr\\", + # ) def execute(self, context): print('Exporting file', self.filepath) diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index 229728d..bc7525c 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -11,7 +11,8 @@ ) from ..common import ( - getRegion + getRegion, + log ) from .. import consts @@ -42,7 +43,8 @@ setPerVertexByType, showHideSphere, getObjByProp, - setObjByProp + setObjByProp, + createCustomAttribute ) @@ -231,9 +233,42 @@ class PanelSettings(bpy.types.PropertyGroup): default = 1.0, ) + castType_enum : bpy.props.EnumProperty( + name="Cast type", + items=[ + ('mesh', "Mesh", "Cast selected meshes to vertices(6,7,36,37) polygons blocks(8,35)"), + ('colis3D', "3D collision", "Creates copy of selected mesh for 3D collision(23)"), + ('colis2D', "2D collision", "Cast selected curve to 2D collision(20)") + ] + ) + + vertexBlock_enum : bpy.props.EnumProperty( + name="Vertex block type", + default = '37', + items=[ + ('6', "6(no Normals)", "Block without normals. Mostly used in HT1"), + ('7', "7(no Normals)", "Block without normals. Mostly used in HT2"), + ('36', "36(with Normals)", "Block with normals. Mostly used in HT1"), + ('37', "37(with Normals)", "Block with normals. Mostly used in HT2") + ] + ) + + polyBlock_enum : bpy.props.EnumProperty( + name="Poly block type", + default = '8', + items=[ + ('8', "8(multiple textures)", "Block can use multiple materials per mesh. Casn use N-gons"), + ('35', "35(single texture)", "Block use single materials per mesh. Use triangles") + ] + ) + + addBlocks_enum : bpy.props.EnumProperty( name="Assembly type", - items=[ ('room', "Room", "Room"), + items=[ + ('LOD_9', "Trigger(9)", "Trigger(9)"), + ('LOD_10', "LOD(10)", "LOD(10)"), + ('LOD_21', "Event(21)", "Event(21)"), #('07', "07", "Mesh (HT1)"), #('10', "10", "LOD"), #('12', "12", "Unk"), @@ -251,6 +286,13 @@ class PanelSettings(bpy.types.PropertyGroup): ] ) + LODLevel_int : bpy.props.IntProperty( + name='LOD level', + description='LOD level', + default=0, + min=0 + ) + addRoomNameIndex_string : bpy.props.StringProperty( name="Room name", description="", @@ -266,6 +308,11 @@ class PanelSettings(bpy.types.PropertyGroup): ] ) + parent_str : bpy.props.StringProperty( + name ='Selected parent', + description = 'New object will be parented to this object' + ) + # ------------------------------------------------------------------------ # menus # ------------------------------------------------------------------------ @@ -286,8 +333,8 @@ class PanelSettings(bpy.types.PropertyGroup): # operators / buttons # ------------------------------------------------------------------------ -class AddOperator(bpy.types.Operator): - bl_idname = "wm.add_operator" +class SingleAddOperator(bpy.types.Operator): + bl_idname = "wm.single_add_operator" bl_label = "Add block to scene" def execute(self, context): @@ -307,6 +354,7 @@ def execute(self, context): zclass = getClassDefByType(block_type) + # objects that are located in 0,0,0(technical empties) if block_type in [ 111,444, 0,1,2,3,4,5, @@ -318,48 +366,233 @@ def execute(self, context): # 23 - 3d collision # 28 - 2d sprite # 30 - portal - 24,25,26,27,29,31,33,34,39,40 + # 24 - locator + 25,26,27,29,31,33,34,39 + # 40 - generator ]: object = bpy.data.objects.new(object_name, None) - object.location=cursor_pos + object.location=(0.0,0.0,0.0) object[consts.BLOCK_TYPE] = block_type if parentObj is not None and block_type != 111: object.parent = parentObj - setAllObjsByType(context, object, zclass) + if block_type not in [111, 444, 0, 3, 8, 19]: # blocks without custom parameters + setAllObjsByType(context, object, zclass) context.collection.objects.link(object) - elif block_type == 28: + if block_type in [9,10,22,21]: #objects with subgroups + + groupCnt = 0 + if block_type in [9,10,21]: + groupCnt = 2 + elif block_type == 21: + groupCnt = object[prop(b_21.GroupCnt)] - bname, bnum = getMytoolBlockNameByClass(zclass) + for i in range(groupCnt): + group = bpy.data.objects.new("GROUP_{}".format(i), None) + group.location=(0.0,0.0,0.0) + group[consts.BLOCK_TYPE] = 444 + group.parent = object + context.collection.objects.link(group) + + elif block_type in [24, 40]: # empties which location is important + + object = bpy.data.objects.new(object_name, None) + object.location=cursor_pos + object[consts.BLOCK_TYPE] = block_type + if parentObj is not None and block_type != 111: + object.parent = parentObj + if block_type not in [111, 444, 0, 3, 8, 19]: # blocks without custom parameters + setAllObjsByType(context, object, zclass) - spriteCenter = getattr(mytool, bname) + if block_type == 24: + object.empty_display_type = 'ARROWS' + elif block_type == 40: + object.empty_display_type = 'SPHERE' + object.empty_display_size = 5 - l_vertexes = [ - () - ] + context.collection.objects.link(object) - elif block_type == 20: - points = [(0,0,0), (0,1,0)] - curveData = bpy.data.curves.new('curve', type='CURVE') + elif block_type in [28, 30]: - curveData.dimensions = '3D' - curveData.resolution_u = 2 + spriteCenter = cursor_pos - polyline = curveData.splines.new('POLY') - polyline.points.add(len(points)-1) - for i, coord in enumerate(points): - x,y,z = coord - polyline.points[i].co = (x, y, z, 1) + l_vertexes = [] - curveData.bevel_depth = 0.01 - object = bpy.data.objects.new(object_name, curveData) - object.location = (0,0,0) + if block_type == 28: + l_vertexes = [ + (0.0, -1.0, -1.0), + (0.0, -1.0, 1.0), + (0.0, 1.0, 1.0), + (0.0, 1.0, -1.0) + ] + elif block_type == 30: + l_vertexes = [ + (0.0, -10.0, -20.0), + (0.0, -10.0, 20.0), + (0.0, 10.0, 20.0), + (0.0, 10.0, -20.0) + ] + + l_faces = [(0,1,2,3)] + + b3dMesh = (bpy.data.meshes.new(object_name)) + b3dMesh.from_pydata(l_vertexes,[],l_faces) + + object = bpy.data.objects.new(object_name, b3dMesh) + object.location=spriteCenter object[consts.BLOCK_TYPE] = block_type - setAllObjsByType(context, object, b_20) + if parentObj is not None and block_type != 111: + object.parent = parentObj + if block_type not in [111, 444, 0, 3, 8, 19]: # blocks without custom parameters + setAllObjsByType(context, object, zclass) context.collection.objects.link(object) return {'FINISHED'} +class TemplateAddOperator(bpy.types.Operator): + bl_idname = "wm.template_add_operator" + bl_label = "Add block assembly to scene" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + global type + + type = mytool.addBlocks_enum + + global cursor_pos + cursor_pos = bpy.context.scene.cursor_location + + def type05(name, radius, add_name): + object_name = name + object = bpy.data.objects.new(object_name, None) + object[consts.BLOCK_TYPE] = 5 + object.location=cursor_pos + object['node_radius'] = radius + object['add_name'] = add_name + bpy.context.scene.objects.link(object) + object.select = True + + def type19(name): + object_name = name + object = bpy.data.objects.new(object_name, None) + object[consts.BLOCK_TYPE] = 19 + object.location=cursor_pos + bpy.context.scene.objects.link(object) + object.select = True + + if type == "room": + type19("room_" + mytool.addRoomNameIndex_string) + room = bpy.context.selected_objects[0] + + type05(("road_" + mytool.addRoomNameIndex_string), mytool.Radius, ("hit_road_" + mytool.addRoomNameIndex_string)) + road = bpy.context.selected_objects[0] + + type05(("obj_" + mytool.addRoomNameIndex_string), mytool.Radius, ("hit_obj_" + mytool.addRoomNameIndex_string)) + obj = bpy.context.selected_objects[0] + + hit_road = type05(("hit_road_" + mytool.addRoomNameIndex_string), 0, "") + hit_obj = type05(("hit_obj_" + mytool.addRoomNameIndex_string), 0, "") + + bpy.ops.object.select_all(action='DESELECT') + + room.select = True + road.select = True + obj.select = True + + bpy.context.scene.objects.active = room + + bpy.ops.object.parent_set() + + bpy.ops.object.select_all(action='DESELECT') + + return {'FINISHED'} + +class CastAddOperator(bpy.types.Operator): + bl_idname = "wm.cast_add_operator" + bl_label = "Cast to B3D" + + def execute(self, context): + scene = context.scene + mytool = scene.my_tool + + cursor_pos = bpy.context.scene.cursor.location + + castType = mytool.castType_enum + parentObj = bpy.data.objects.get(mytool.parent_str) + + if castType == 'mesh': + vertType = int(mytool.vertexBlock_enum) + polyType = int(mytool.polyBlock_enum) + + vertclass = getClassDefByType(vertType) + polyclass = getClassDefByType(polyType) + + #creating vertex block + vertObj = bpy.data.objects.new(consts.EMPTY_NAME, None) + vertObj.location=(0.0,0.0,0.0) + vertObj[consts.BLOCK_TYPE] = vertType + vertObj.parent = parentObj + setAllObjsByType(context, vertObj, vertclass) + context.collection.objects.link(vertObj) + + # creating poly blocks + for polyObj in context.selected_objects: + if polyObj.type == 'MESH': + + newObj = polyObj.copy() + newObj.data = polyObj.data.copy() + newObj[consts.BLOCK_TYPE] = polyType + newObj.parent = vertObj + if polyType != 8: + setAllObjsByType(context, newObj, polyclass) + + formats = [2]*len(newObj.data.polygons) + if polyType == 8: + createCustomAttribute(newObj.data, formats, pfb_8, pfb_8.Format_Flags) + elif polyType == 35: + createCustomAttribute(newObj.data, formats, pfb_35, pfb_35.Format_Flags) + + context.collection.objects.link(newObj) + + log.info("Created new B3D object: {}.".format(newObj.name)) + else: + log.info("Selected object {} is not Mesh. Changes not applied.".format(polyObj.name)) + + elif castType == 'colis2D': + + for polyObj in context.selected_objects: + if polyObj.type == 'CURVE': + newObj = polyObj.copy() + newObj.data = polyObj.data.copy() + newObj[consts.BLOCK_TYPE] = 20 + newObj.parent = parentObj + setAllObjsByType(context, newObj, b_20) + context.collection.objects.link(newObj) + log.info("Created new B3D 2d colision: {}.".format(newObj.name)) + else: + log.info("Selected object {} is not Curve. Changes not applied.".format(polyObj.name)) + + elif castType == 'colis3D': + + for polyObj in context.selected_objects: + if polyObj.type == 'MESH': + newObj = polyObj.copy() + newObj.data = polyObj.data.copy() + + newObj[consts.BLOCK_TYPE] = 23 + newObj.parent = parentObj + setAllObjsByType(context, newObj, b_23) + + context.collection.objects.link(newObj) + + log.info("Created new B3D 3d collision: {}.".format(newObj.name)) + else: + log.info("Selected object {} is not Mesh. Changes not applied.".format(polyObj.name)) + + return {'FINISHED'} + class GetVertexValuesOperator(bpy.types.Operator): bl_idname = "wm.get_vertex_values_operator" bl_label = "Get block values" @@ -508,7 +741,6 @@ def execute(self, context): return {'FINISHED'} - class SetPropValueOperator(bpy.types.Operator): bl_idname = "wm.set_prop_value_operator" bl_label = "Save param value" @@ -797,66 +1029,6 @@ def execute(self, context): return {'FINISHED'} -class AddBlocksOperator(bpy.types.Operator): - bl_idname = "wm.add1_operator" - bl_label = "Add block assembly to scene" - - def execute(self, context): - scene = context.scene - mytool = scene.my_tool - - global type - - type = mytool.addBlocks_enum - - global cursor_pos - cursor_pos = bpy.context.scene.cursor_location - - def type05(name, radius, add_name): - object_name = name - object = bpy.data.objects.new(object_name, None) - object[consts.BLOCK_TYPE] = 5 - object.location=cursor_pos - object['node_radius'] = radius - object['add_name'] = add_name - bpy.context.scene.objects.link(object) - object.select = True - - def type19(name): - object_name = name - object = bpy.data.objects.new(object_name, None) - object[consts.BLOCK_TYPE] = 19 - object.location=cursor_pos - bpy.context.scene.objects.link(object) - object.select = True - - if type == "room": - type19("room_" + mytool.addRoomNameIndex_string) - room = bpy.context.selected_objects[0] - - type05(("road_" + mytool.addRoomNameIndex_string), mytool.Radius, ("hit_road_" + mytool.addRoomNameIndex_string)) - road = bpy.context.selected_objects[0] - - type05(("obj_" + mytool.addRoomNameIndex_string), mytool.Radius, ("hit_obj_" + mytool.addRoomNameIndex_string)) - obj = bpy.context.selected_objects[0] - - hit_road = type05(("hit_road_" + mytool.addRoomNameIndex_string), 0, "") - hit_obj = type05(("hit_obj_" + mytool.addRoomNameIndex_string), 0, "") - - bpy.ops.object.select_all(action='DESELECT') - - room.select = True - road.select = True - obj.select = True - - bpy.context.scene.objects.active = room - - bpy.ops.object.parent_set() - - bpy.ops.object.select_all(action='DESELECT') - - return {'FINISHED'} - class ShowHideSphereOperator(bpy.types.Operator): bl_idname = "wm.show_hide_sphere_operator" bl_label = "Show/Hide sphere" @@ -903,7 +1075,6 @@ def draw(self, context): box = layout.box() box.label(text="Selected object: " + str(objectName)) - class OBJECT_PT_b3d_single_add_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_single_add_panel" bl_label = "Single block" @@ -937,7 +1108,7 @@ def draw(self, context): if zclass is not None: drawAllFieldsByType(self, context, zclass) - layout.operator("wm.add_operator") + layout.operator("wm.single_add_operator") class OBJECT_PT_b3d_template_add_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_template_add_panel" @@ -960,11 +1131,62 @@ def draw(self, context): layout.prop(mytool, "addBlocks_enum") - if type == "room": - layout.prop(mytool, "addRoomNameIndex_string") - layout.prop(mytool, "Radius") + if type == "LOD_9": + + layout.prop(mytool, "LODLevel_int") + + zclass = getClassDefByType(9) + drawAllFieldsByType(self, context, zclass) + + elif type == "LOD_10": + + layout.prop(mytool, "LODLevel_int") + + zclass = getClassDefByType(10) + drawAllFieldsByType(self, context, zclass) + + elif type == "LOD_21": + + layout.prop(mytool, "LODLevel_int") + + zclass = getClassDefByType(21) + drawAllFieldsByType(self, context, zclass) + + # layout.prop(mytool, "addRoomNameIndex_string") + # layout.prop(mytool, "Radius") + + + layout.operator("wm.template_add_operator") + +class OBJECT_PT_b3d_cast_add_panel(bpy.types.Panel): + bl_idname = "OBJECT_PT_b3d_cast_add_panel" + bl_label = "Cast to B3D object" + bl_parent_id = "OBJECT_PT_b3d_add_panel" + bl_space_type = "VIEW_3D" + bl_region_type = getRegion() + bl_category = "b3d Tools" + #bl_context = "objectmode" + + @classmethod + def poll(self,context): + return context.object is not None + + def draw(self, context): + layout = self.layout + mytool = context.scene.my_tool + + layout.prop(mytool, 'parent_str') + + layout.prop(mytool, "castType_enum") + castType = mytool.castType_enum + box = layout.box() + if castType == 'mesh': + box.prop(mytool, "vertexBlock_enum") + box.prop(mytool, "polyBlock_enum") + + - layout.operator("wm.add1_operator") + box.operator("wm.cast_add_operator") class OBJECT_PT_b3d_pfb_edit_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_b3d_pfb_edit_panel" @@ -1552,7 +1774,9 @@ def draw(self, context): _classes = ( PanelSettings, - AddOperator, + SingleAddOperator, + TemplateAddOperator, + CastAddOperator, # getters GetValuesOperator, GetPropValueOperator, @@ -1576,12 +1800,12 @@ def draw(self, context): ShowHideGeneratorsOperator, ShowConditionalsOperator, HideConditionalsOperator, - AddBlocksOperator, ShowHideSphereOperator, OBJECT_PT_b3d_add_panel, OBJECT_PT_b3d_single_add_panel, - OBJECT_PT_b3d_template_add_panel, + # OBJECT_PT_b3d_template_add_panel, + OBJECT_PT_b3d_cast_add_panel, OBJECT_PT_b3d_edit_panel, OBJECT_PT_b3d_pob_single_edit_panel, OBJECT_PT_b3d_pob_edit_panel, diff --git a/src/2.80/addons/b3d_tools/consts.py b/src/2.80/addons/b3d_tools/consts.py index 9f597cb..3cef23f 100644 --- a/src/2.80/addons/b3d_tools/consts.py +++ b/src/2.80/addons/b3d_tools/consts.py @@ -22,7 +22,7 @@ ('05', "05(Container)", "Container containing other blocks"), ('06', "06(Vertexes)", "Vertex block (HT1)"), ('07', "07(Vertexes)", "Vertex block (HT2)"), - ('08', "08(Polygons)", "Polygon block"), + # ('08', "08(Polygons)", "Polygon block"), ('09', "09(Trigger)", "Trigger"), ('10', "10(LOD)", "LOD"), ('11', "11(Trigger)", "Unknown block"), @@ -34,10 +34,10 @@ ('17', "17(Trigger)", "Unknown block"), ('18', "18(Connector)", "Connector between space block(24) and root container block. Exmaple: FiatWheel0Space and Single0Wheel14"), ('19', "19(Room)", "Room container"), - ('20', "20(2D collision)", "Flat vertical collision"), + # ('20', "20(2D collision)", "Flat vertical collision"), ('21', "21(Event)", "Container with event handling"), ('22', "22(Trigger)", "Locator?"), - ('23', "23(3D collision)", "3D collision"), + # ('23', "23(3D collision)", "3D collision"), ('24', "24(Space)", "Space"), ('25', "25(Sound)", "Sound"), ('26', "26(Unk?)", "Locator?"), @@ -48,7 +48,7 @@ ('31', "31(Unk?)", "Unknown block"), ('33', "33(Light)", "Light source"), ('34', "34(Unk?)", "Unknown block"), - ('35', "35(Polygons)", "Polygon block"), + # ('35', "35(Polygons)", "Polygon block"), ('36', "36(Vertexes)", "Vertex block (HT1)"), ('37', "37(Vertexes)", "Vertex block (HT2)"), ('39', "39(Unk?)", "Locator?"), @@ -70,11 +70,13 @@ ('16', "ice (no tire marks)", "") ] -lTypeList = [ - ('0', 'Type 0', ""), - ('1', 'Type 1', ""), - ('2', 'Type 2', ""), - ('3', 'Type 3', "") + + +vTypeList = [ + ('0', '0(No normals)', "No normals"), + ('1', '1(With normals)', "With normals"), + ('2', '2(With normals)', "With normals"), + ('3', '3(Normal switch)', "Normal switch") ] From 05239ca17e6cc3e4897a793eeb74057869f9b1bd Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sun, 12 Feb 2023 11:40:29 +0200 Subject: [PATCH 45/47] enable way import --- src/2.80/addons/b3d_tools/__init__.py | 2 ++ src/2.80/addons/b3d_tools/b3d/class_descr.py | 4 ++-- src/2.80/addons/b3d_tools/b3d/classes.py | 4 ++-- src/2.80/addons/b3d_tools/b3d/menus.py | 4 ++-- src/2.80/addons/b3d_tools/b3d/panel.py | 4 ++-- src/2.80/addons/b3d_tools/custom_UIList.py | 4 ++-- src/2.80/addons/b3d_tools/way/__init__.py | 7 ++++--- src/2.80/addons/b3d_tools/way/menus.py | 4 ++-- 8 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py index 9406522..d8e9ae7 100644 --- a/src/2.80/addons/b3d_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -70,11 +70,13 @@ def register(): custom_UIList.register() + way.register() b3d.register() # tch_register() def unregister(): b3d.unregister() + way.unregister() custom_UIList.unregister() # tch_unregister() diff --git a/src/2.80/addons/b3d_tools/b3d/class_descr.py b/src/2.80/addons/b3d_tools/b3d/class_descr.py index 8e48118..6a1d97f 100644 --- a/src/2.80/addons/b3d_tools/b3d/class_descr.py +++ b/src/2.80/addons/b3d_tools/b3d/class_descr.py @@ -2033,14 +2033,14 @@ def getClassDefByType(blockNum): zclass = b_40 return zclass -_classes = ( +_classes = [ ActiveBlock, FloatBlock, TextureBlock, MaskfileBlock, MaterialBlock, ResBlock -) +] def register(): for cls in _classes: diff --git a/src/2.80/addons/b3d_tools/b3d/classes.py b/src/2.80/addons/b3d_tools/b3d/classes.py index fe23568..3a9536f 100644 --- a/src/2.80/addons/b3d_tools/b3d/classes.py +++ b/src/2.80/addons/b3d_tools/b3d/classes.py @@ -383,7 +383,7 @@ def createTypeClass(zclass, multipleEdit = True): block_39 = createTypeClass(b_39) block_40 = createTypeClass(b_40) -_classes = ( +_classes = [ s_block_1, s_block_2, # s_block_3, @@ -466,7 +466,7 @@ def createTypeClass(zclass, multipleEdit = True): perVertBlock_8, perVertBlock_35 -) +] def register(): for cls in _classes: diff --git a/src/2.80/addons/b3d_tools/b3d/menus.py b/src/2.80/addons/b3d_tools/b3d/menus.py index e313301..f279e01 100644 --- a/src/2.80/addons/b3d_tools/b3d/menus.py +++ b/src/2.80/addons/b3d_tools/b3d/menus.py @@ -247,12 +247,12 @@ def menu_func_import(self, context): def menu_func_export(self, context): self.layout.operator(ExportB3D.bl_idname, text='KOTR B3D (.b3d)') -_classes = ( +_classes = [ HTImportPreferences, ImportB3D, ImportRAW, ExportB3D -) +] def register(): diff --git a/src/2.80/addons/b3d_tools/b3d/panel.py b/src/2.80/addons/b3d_tools/b3d/panel.py index bc7525c..78c49b1 100644 --- a/src/2.80/addons/b3d_tools/b3d/panel.py +++ b/src/2.80/addons/b3d_tools/b3d/panel.py @@ -1772,7 +1772,7 @@ def draw(self, context): # register and unregister # ------------------------------------------------------------------------ -_classes = ( +_classes = [ PanelSettings, SingleAddOperator, TemplateAddOperator, @@ -1817,7 +1817,7 @@ def draw(self, context): OBJECT_PT_b3d_materials_panel, OBJECT_PT_b3d_func_panel, OBJECT_PT_b3d_misc_panel, -) +] def register(): for cls in _classes: diff --git a/src/2.80/addons/b3d_tools/custom_UIList.py b/src/2.80/addons/b3d_tools/custom_UIList.py index 66ce85b..a9b6445 100644 --- a/src/2.80/addons/b3d_tools/custom_UIList.py +++ b/src/2.80/addons/b3d_tools/custom_UIList.py @@ -419,7 +419,7 @@ class CUSTOM_PG_objectCollection(PropertyGroup): # Register & Unregister # ------------------------------------------------------------------- -_classes = ( +_classes = [ CUSTOM_OT_actions, CUSTOM_OT_actions_arrbname, CUSTOM_OT_addViewportSelection, @@ -431,7 +431,7 @@ class CUSTOM_PG_objectCollection(PropertyGroup): CUSTOM_UL_items, CUSTOM_PT_objectList, CUSTOM_PG_objectCollection, -) +] def register(): from bpy.utils import register_class diff --git a/src/2.80/addons/b3d_tools/way/__init__.py b/src/2.80/addons/b3d_tools/way/__init__.py index b64f7ad..4fc07c4 100644 --- a/src/2.80/addons/b3d_tools/way/__init__.py +++ b/src/2.80/addons/b3d_tools/way/__init__.py @@ -1118,12 +1118,13 @@ def execute(self, context): # Only needed if you want to add into a dynamic menu def menu_func_export(self, context): - self.layout.operator(ExportSomeData.bl_idname, text="KOTR WAY (.way") + pass + # self.layout.operator(ExportSomeData.bl_idname, text="KOTR WAY (.way") def menu_func_import(self, context): self.layout.operator(ImportSomeData.bl_idname, text="KOTR WAY (.way)") -_classes = ( +_classes = [ PanelSettings1, AddOperator1, SetValuesOperator1, @@ -1135,7 +1136,7 @@ def menu_func_import(self, context): OBJECT_PT_blocks_panel, ImportSomeData, ExportSomeData -) +] def register(): diff --git a/src/2.80/addons/b3d_tools/way/menus.py b/src/2.80/addons/b3d_tools/way/menus.py index 45e0dad..6391a00 100644 --- a/src/2.80/addons/b3d_tools/way/menus.py +++ b/src/2.80/addons/b3d_tools/way/menus.py @@ -57,9 +57,9 @@ def menu_func_export(self, context): pass -_classes = ( +_classes = [ ImportWayTxt -) +] def register(): From bf1280c6b31244e737e635c6a0d90e1421c51465 Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sun, 12 Feb 2023 11:50:02 +0200 Subject: [PATCH 46/47] new version --- README.md | 2 +- src/2.80/addons/b3d_tools/__init__.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 05328c3..1d52af6 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ b3dsplit - извлечение из b3d-файла прочих моделей ## Авторы Юрий Гладышенко и Андрей Прожога. -Обновление: Иван Карцев +Обновление: LabVaKars ## Ссылки diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py index d8e9ae7..a420046 100644 --- a/src/2.80/addons/b3d_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -52,9 +52,9 @@ bl_info = { "name": "King of The Road Tools", "description": "", - "author": "Andrey Prozhoga", - "version": (1, 2, 2), - "blender": (2, 80, 0), + "author": "Andrey Prozhoga, LabVaKars", + "version": (1, 3, 1), + "blender": (2, 93, 0), "location": "3D View > Tools", "warning": "", "wiki_url": "", From f5085f308a2afe5e162933d0121bf09071a418dc Mon Sep 17 00:00:00 2001 From: LabVaKars Date: Sun, 12 Feb 2023 11:57:50 +0200 Subject: [PATCH 47/47] v.2.3.1 --- src/2.80/addons/b3d_tools/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/2.80/addons/b3d_tools/__init__.py b/src/2.80/addons/b3d_tools/__init__.py index a420046..af21e70 100644 --- a/src/2.80/addons/b3d_tools/__init__.py +++ b/src/2.80/addons/b3d_tools/__init__.py @@ -53,7 +53,7 @@ "name": "King of The Road Tools", "description": "", "author": "Andrey Prozhoga, LabVaKars", - "version": (1, 3, 1), + "version": (2, 3, 1), "blender": (2, 93, 0), "location": "3D View > Tools", "warning": "",