fully finish bm import/export function
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
# our generated mesh should be save as binary
|
||||||
|
*.bin binary
|
||||||
@@ -45,7 +45,6 @@ class ExportBM(bpy.types.Operator, bpy_extras.io_utils.ExportHelper):
|
|||||||
export_bm(context, self.filepath, self.export_mode, self.export_target)
|
export_bm(context, self.filepath, self.export_mode, self.export_target)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
# ========================================== method
|
# ========================================== method
|
||||||
|
|
||||||
bm_current_version = 11
|
bm_current_version = 11
|
||||||
@@ -286,21 +285,19 @@ def import_bm(context,filepath,externalTexture,blenderTempFolder):
|
|||||||
|
|
||||||
# create real object
|
# create real object
|
||||||
obj = bpy.data.objects.new(item.name, neededMesh)
|
obj = bpy.data.objects.new(item.name, neededMesh)
|
||||||
obj.matrix_world = object_worldMatrix
|
if (not object_isComponent) and object_isForcedNoComponent and (forcedCollection is not None):
|
||||||
obj.hide_viewport = object_isHidden
|
|
||||||
|
|
||||||
|
|
||||||
if (not object_isComponent) and object_isForcedNoComponent and (forcedCollection != None):
|
|
||||||
forcedCollection.objects.link(obj)
|
forcedCollection.objects.link(obj)
|
||||||
else:
|
else:
|
||||||
collection.objects.link(obj)
|
collection.objects.link(obj)
|
||||||
|
obj.matrix_world = object_worldMatrix
|
||||||
|
obj.hide_set(object_isHidden)
|
||||||
|
|
||||||
fobject.close()
|
fobject.close()
|
||||||
view_layer.update()
|
view_layer.update()
|
||||||
|
|
||||||
tempFolderObj.cleanup()
|
tempFolderObj.cleanup()
|
||||||
|
|
||||||
def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
def export_bm(context,filepath,export_mode, export_target):
|
||||||
# ============================================ alloc a temp folder
|
# ============================================ alloc a temp folder
|
||||||
tempFolderObj = tempfile.TemporaryDirectory()
|
tempFolderObj = tempfile.TemporaryDirectory()
|
||||||
tempFolder = tempFolderObj.name
|
tempFolder = tempFolderObj.name
|
||||||
@@ -338,13 +335,13 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
|||||||
|
|
||||||
# clean no mesh object
|
# clean no mesh object
|
||||||
currentMesh = obj.data
|
currentMesh = obj.data
|
||||||
if currentMesh == None:
|
if currentMesh is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# judge component
|
# judge component
|
||||||
object_isComponent = is_component(obj.name)
|
object_isComponent = is_component(obj.name)
|
||||||
object_isForcedNoComponent = False
|
object_isForcedNoComponent = False
|
||||||
if (forcedCollection != None) and (obj.name in forcedCollection.objects):
|
if (forcedCollection is not None) and (obj.name in forcedCollection.objects):
|
||||||
# change it to forced no component
|
# change it to forced no component
|
||||||
object_isComponent = False
|
object_isComponent = False
|
||||||
object_isForcedNoComponent = True
|
object_isForcedNoComponent = True
|
||||||
@@ -363,16 +360,17 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
|||||||
meshId = get_component_id(obj.name)
|
meshId = get_component_id(obj.name)
|
||||||
|
|
||||||
# get visibility
|
# get visibility
|
||||||
object_isHidden = obj.hide_viewport
|
object_isHidden = not obj.visible_get()
|
||||||
|
|
||||||
# write finfo first
|
# write finfo first
|
||||||
write_string(finfo, obj.name)
|
write_string(finfo, obj.name)
|
||||||
write_uint32(finfo, info_bm_type.OBJECT)
|
write_uint8(finfo, info_bm_type.OBJECT)
|
||||||
write_uint64(finfo, fobject.tell())
|
write_uint64(finfo, fobject.tell())
|
||||||
|
|
||||||
# write fobject
|
# write fobject
|
||||||
write_bool(fobject, object_isComponent)
|
write_bool(fobject, object_isComponent)
|
||||||
write_bool(fobject, object_isForcedNoComponent)
|
write_bool(fobject, object_isForcedNoComponent)
|
||||||
|
print(object_isHidden)
|
||||||
write_bool(fobject, object_isHidden)
|
write_bool(fobject, object_isHidden)
|
||||||
write_worldMatrix(fobject, obj.matrix_world)
|
write_worldMatrix(fobject, obj.matrix_world)
|
||||||
write_uint32(fobject, meshId)
|
write_uint32(fobject, meshId)
|
||||||
@@ -388,7 +386,7 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
|||||||
|
|
||||||
# write finfo first
|
# write finfo first
|
||||||
write_string(finfo, mesh.name)
|
write_string(finfo, mesh.name)
|
||||||
write_uint32(finfo, info_bm_type.MESH)
|
write_uint8(finfo, info_bm_type.MESH)
|
||||||
write_uint64(finfo, fmesh.tell())
|
write_uint64(finfo, fmesh.tell())
|
||||||
|
|
||||||
# write fmesh
|
# write fmesh
|
||||||
@@ -472,11 +470,10 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
|||||||
textureSet = set()
|
textureSet = set()
|
||||||
textureList = []
|
textureList = []
|
||||||
textureCount = 0
|
textureCount = 0
|
||||||
# todo: texture filter have duplicated name error. fix it later
|
|
||||||
for material in materialList:
|
for material in materialList:
|
||||||
# write finfo first
|
# write finfo first
|
||||||
write_string(finfo, material.name)
|
write_string(finfo, material.name)
|
||||||
write_uint32(finfo, info_bm_type.MATERIAL)
|
write_uint8(finfo, info_bm_type.MATERIAL)
|
||||||
write_uint64(finfo, fmaterial.tell())
|
write_uint64(finfo, fmaterial.tell())
|
||||||
|
|
||||||
# try get original written data
|
# try get original written data
|
||||||
@@ -491,13 +488,13 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
|||||||
if mat_wrap:
|
if mat_wrap:
|
||||||
use_mirror = mat_wrap.metallic != 0.0
|
use_mirror = mat_wrap.metallic != 0.0
|
||||||
if use_mirror:
|
if use_mirror:
|
||||||
set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic))
|
material_colAmbient = set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic))
|
||||||
else:
|
else:
|
||||||
set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0))
|
material_colAmbient = set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0))
|
||||||
set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2]))
|
material_colDiffuse = set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2]))
|
||||||
set_value_when_none(material_colSpecular, (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular))
|
material_colSpecular = set_value_when_none(material_colSpecular, (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular))
|
||||||
set_value_when_none(material_colEmissive, mat_wrap.emission_color[:3])
|
material_colEmissive = set_value_when_none(material_colEmissive, mat_wrap.emission_color[:3])
|
||||||
set_value_when_none(material_specularPower, 0.0)
|
material_specularPower = set_value_when_none(material_specularPower, 0.0)
|
||||||
|
|
||||||
# confirm texture
|
# confirm texture
|
||||||
tex_wrap = getattr(mat_wrap, "base_color_texture", None)
|
tex_wrap = getattr(mat_wrap, "base_color_texture", None)
|
||||||
@@ -526,11 +523,11 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
# no Principled BSDF. write garbage
|
# no Principled BSDF. write garbage
|
||||||
set_value_when_none(material_colAmbient, (0.8, 0.8, 0.8))
|
material_colAmbient = set_value_when_none(material_colAmbient, (0.8, 0.8, 0.8))
|
||||||
set_value_when_none(material_colDiffuse, (0.8, 0.8, 0.8))
|
material_colDiffuse = set_value_when_none(material_colDiffuse, (0.8, 0.8, 0.8))
|
||||||
set_value_when_none(material_colSpecular, (0.8, 0.8, 0.8))
|
material_colSpecular = set_value_when_none(material_colSpecular, (0.8, 0.8, 0.8))
|
||||||
set_value_when_none(material_colEmissive, (0.8, 0.8, 0.8))
|
material_colEmissive = set_value_when_none(material_colEmissive, (0.8, 0.8, 0.8))
|
||||||
set_value_when_none(material_specularPower, 0.0)
|
material_specularPower = set_value_when_none(material_specularPower, 0.0)
|
||||||
|
|
||||||
material_useTexture = False
|
material_useTexture = False
|
||||||
material_texture = 0
|
material_texture = 0
|
||||||
@@ -553,7 +550,7 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
|||||||
for texture in textureList:
|
for texture in textureList:
|
||||||
# write finfo first
|
# write finfo first
|
||||||
write_string(finfo, texture.name)
|
write_string(finfo, texture.name)
|
||||||
write_uint32(finfo, info_bm_type.TEXTURE)
|
write_uint8(finfo, info_bm_type.TEXTURE)
|
||||||
write_uint64(finfo, ftexture.tell())
|
write_uint64(finfo, ftexture.tell())
|
||||||
|
|
||||||
# confirm internal
|
# confirm internal
|
||||||
@@ -605,7 +602,68 @@ class info_block_helper():
|
|||||||
self.blenderData = None
|
self.blenderData = None
|
||||||
|
|
||||||
def load_component(component_id):
|
def load_component(component_id):
|
||||||
return None
|
# get file first
|
||||||
|
compName = config.component_list[component_id]
|
||||||
|
selectedFile = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
'meshes',
|
||||||
|
compName + '.bin'
|
||||||
|
)
|
||||||
|
|
||||||
|
# read file. please note this sector is sync with import_bm's mesh's code. when something change, please change each other.
|
||||||
|
fmesh = open(selectedFile, 'rb')
|
||||||
|
|
||||||
|
# create real mesh, we don't need to consider name. blender will solve duplicated name
|
||||||
|
mesh = bpy.data.meshes.new('mesh_' + compName)
|
||||||
|
|
||||||
|
vList = []
|
||||||
|
vnList = []
|
||||||
|
faceList = []
|
||||||
|
# in first read, store all data into list
|
||||||
|
listCount = read_uint32(fmesh)
|
||||||
|
for i in range(listCount):
|
||||||
|
cache = read_3vector(fmesh)
|
||||||
|
# switch yz
|
||||||
|
vList.append((cache[0], cache[2], cache[1]))
|
||||||
|
listCount = read_uint32(fmesh)
|
||||||
|
for i in range(listCount):
|
||||||
|
cache = read_3vector(fmesh)
|
||||||
|
# switch yz
|
||||||
|
vnList.append((cache[0], cache[2], cache[1]))
|
||||||
|
|
||||||
|
listCount = read_uint32(fmesh)
|
||||||
|
for i in range(listCount):
|
||||||
|
faceData = read_component_face(fmesh)
|
||||||
|
|
||||||
|
# we need invert triangle sort
|
||||||
|
faceList.append((
|
||||||
|
faceData[4], faceData[5],
|
||||||
|
faceData[2], faceData[3],
|
||||||
|
faceData[0], faceData[1]
|
||||||
|
))
|
||||||
|
|
||||||
|
# then, we need add correspond count for vertices
|
||||||
|
mesh.vertices.add(len(vList))
|
||||||
|
mesh.loops.add(len(faceList)*3) # triangle face confirm
|
||||||
|
mesh.polygons.add(len(faceList))
|
||||||
|
mesh.create_normals_split()
|
||||||
|
|
||||||
|
# add vertices data
|
||||||
|
mesh.vertices.foreach_set("co", unpack_list(vList))
|
||||||
|
mesh.loops.foreach_set("vertex_index", unpack_list(flat_component_vertices_index(faceList)))
|
||||||
|
mesh.loops.foreach_set("normal", unpack_list(flat_component_vertices_normal(faceList, vnList)))
|
||||||
|
for i in range(len(faceList)):
|
||||||
|
mesh.polygons[i].loop_start = i * 3
|
||||||
|
mesh.polygons[i].loop_total = 3
|
||||||
|
|
||||||
|
mesh.polygons[i].use_smooth = True
|
||||||
|
|
||||||
|
mesh.validate(clean_customdata=False)
|
||||||
|
mesh.update(calc_edges=False, calc_edges_loose=False)
|
||||||
|
|
||||||
|
fmesh.close()
|
||||||
|
|
||||||
|
return mesh
|
||||||
|
|
||||||
def flat_vertices_index(faceList):
|
def flat_vertices_index(faceList):
|
||||||
for item in faceList:
|
for item in faceList:
|
||||||
@@ -625,13 +683,28 @@ def flat_vertices_uv(faceList, vtList):
|
|||||||
yield vtList[item[4]]
|
yield vtList[item[4]]
|
||||||
yield vtList[item[7]]
|
yield vtList[item[7]]
|
||||||
|
|
||||||
|
def flat_component_vertices_index(faceList):
|
||||||
|
for item in faceList:
|
||||||
|
yield (item[0], )
|
||||||
|
yield (item[2], )
|
||||||
|
yield (item[4], )
|
||||||
|
|
||||||
|
def flat_component_vertices_normal(faceList, vnList):
|
||||||
|
for item in faceList:
|
||||||
|
yield vnList[item[1]]
|
||||||
|
yield vnList[item[3]]
|
||||||
|
yield vnList[item[5]]
|
||||||
|
|
||||||
# export
|
# export
|
||||||
|
|
||||||
def is_component(name):
|
def is_component(name):
|
||||||
return get_component_id(name) != -1
|
return get_component_id(name) != -1
|
||||||
|
|
||||||
def get_component_id(name):
|
def get_component_id(name):
|
||||||
return -1 # todo: finish this, -1 mean not a component
|
for ind, comp in enumerate(config.component_list):
|
||||||
|
if name.startswith(comp):
|
||||||
|
return ind
|
||||||
|
return -1
|
||||||
|
|
||||||
def is_external_texture(name):
|
def is_external_texture(name):
|
||||||
if name in config.external_texture_list:
|
if name in config.external_texture_list:
|
||||||
@@ -648,13 +721,15 @@ def mesh_triangulate(me):
|
|||||||
|
|
||||||
def try_get_custom_property(obj, field):
|
def try_get_custom_property(obj, field):
|
||||||
try:
|
try:
|
||||||
cache = obj[field]
|
return obj[field]
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set_value_when_none(obj, newValue):
|
def set_value_when_none(obj, newValue):
|
||||||
if obj == None:
|
if obj is None:
|
||||||
obj = newValue
|
return newValue
|
||||||
|
else:
|
||||||
|
return obj
|
||||||
|
|
||||||
# ======================================================================================= file io assistant
|
# ======================================================================================= file io assistant
|
||||||
|
|
||||||
@@ -702,6 +777,9 @@ def read_2vector(fs):
|
|||||||
def read_face(fs):
|
def read_face(fs):
|
||||||
return struct.unpack("IIIIIIIII", fs.read(4*9))
|
return struct.unpack("IIIIIIIII", fs.read(4*9))
|
||||||
|
|
||||||
|
def read_component_face(fs):
|
||||||
|
return struct.unpack("IIIIII", fs.read(4*6))
|
||||||
|
|
||||||
# export
|
# export
|
||||||
|
|
||||||
def write_string(fs,str):
|
def write_string(fs,str):
|
||||||
|
|||||||
@@ -1,85 +1,113 @@
|
|||||||
external_texture_list = set([
|
external_texture_list = set([
|
||||||
'Ball_LightningSphere1.bmp',
|
"atari.avi",
|
||||||
'Ball_LightningSphere2.bmp',
|
"atari.bmp",
|
||||||
'Ball_LightningSphere3.bmp',
|
"Ball_LightningSphere1.bmp",
|
||||||
'Ball_Paper.bmp',
|
"Ball_LightningSphere2.bmp",
|
||||||
'Ball_Stone.bmp',
|
"Ball_LightningSphere3.bmp",
|
||||||
'Ball_Wood.bmp',
|
"Ball_Paper.bmp",
|
||||||
'Brick.bmp',
|
"Ball_Stone.bmp",
|
||||||
'Button01_deselect.tga',
|
"Ball_Wood.bmp",
|
||||||
'Button01_select.tga',
|
"Brick.bmp",
|
||||||
'Button01_special.tga',
|
"Button01_deselect.tga",
|
||||||
'Column_beige.bmp',
|
"Button01_select.tga",
|
||||||
'Column_beige_fade.tga',
|
"Button01_special.tga",
|
||||||
'Column_blue.bmp',
|
"Column_beige.bmp",
|
||||||
'Cursor.tga',
|
"Column_beige_fade.tga",
|
||||||
'Dome.bmp',
|
"Column_blue.bmp",
|
||||||
'DomeEnvironment.bmp',
|
"Cursor.tga",
|
||||||
'DomeShadow.tga',
|
"Dome.bmp",
|
||||||
'ExtraBall.bmp',
|
"DomeEnvironment.bmp",
|
||||||
'ExtraParticle.bmp',
|
"DomeShadow.tga",
|
||||||
'E_Holzbeschlag.bmp',
|
"ExtraBall.bmp",
|
||||||
'FloorGlow.bmp',
|
"ExtraParticle.bmp",
|
||||||
'Floor_Side.bmp',
|
"E_Holzbeschlag.bmp",
|
||||||
'Floor_Top_Border.bmp',
|
"FloorGlow.bmp",
|
||||||
'Floor_Top_Borderless.bmp',
|
"Floor_Side.bmp",
|
||||||
'Floor_Top_Checkpoint.bmp',
|
"Floor_Top_Border.bmp",
|
||||||
'Floor_Top_Flat.bmp',
|
"Floor_Top_Borderless.bmp",
|
||||||
'Floor_Top_Profil.bmp',
|
"Floor_Top_Checkpoint.bmp",
|
||||||
'Floor_Top_ProfilFlat.bmp',
|
"Floor_Top_Flat.bmp",
|
||||||
'Font_1.tga',
|
"Floor_Top_Profil.bmp",
|
||||||
'Gravitylogo_intro.bmp',
|
"Floor_Top_ProfilFlat.bmp",
|
||||||
'HardShadow.bmp',
|
"Font_1.tga",
|
||||||
'Laterne_Glas.bmp',
|
"Gravitylogo_intro.bmp",
|
||||||
'Laterne_Schatten.tga',
|
"HardShadow.bmp",
|
||||||
'Laterne_Verlauf.tga',
|
"Laterne_Glas.bmp",
|
||||||
'Logo.bmp',
|
"Laterne_Schatten.tga",
|
||||||
'Metal_stained.bmp',
|
"Laterne_Verlauf.tga",
|
||||||
'Misc_Ufo.bmp',
|
"Logo.bmp",
|
||||||
'Misc_UFO_Flash.bmp',
|
"Metal_stained.bmp",
|
||||||
'Modul03_Floor.bmp',
|
"Misc_Ufo.bmp",
|
||||||
'Modul03_Wall.bmp',
|
"Misc_UFO_Flash.bmp",
|
||||||
'Modul11_13_Wood.bmp',
|
"Modul03_Floor.bmp",
|
||||||
'Modul11_Wood.bmp',
|
"Modul03_Wall.bmp",
|
||||||
'Modul15.bmp',
|
"Modul11_13_Wood.bmp",
|
||||||
'Modul16.bmp',
|
"Modul11_Wood.bmp",
|
||||||
'Modul18.bmp',
|
"Modul15.bmp",
|
||||||
'Modul18_Gitter.tga',
|
"Modul16.bmp",
|
||||||
'Modul30_d_Seiten.bmp',
|
"Modul18.bmp",
|
||||||
'Particle_Flames.bmp',
|
"Modul18_Gitter.tga",
|
||||||
'Particle_Smoke.bmp',
|
"Modul30_d_Seiten.bmp",
|
||||||
'PE_Bal_balloons.bmp',
|
"Particle_Flames.bmp",
|
||||||
'PE_Bal_platform.bmp',
|
"Particle_Smoke.bmp",
|
||||||
'PE_Ufo_env.bmp',
|
"PE_Bal_balloons.bmp",
|
||||||
'Pfeil.tga',
|
"PE_Bal_platform.bmp",
|
||||||
'P_Extra_Life_Oil.bmp',
|
"PE_Ufo_env.bmp",
|
||||||
'P_Extra_Life_Particle.bmp',
|
"Pfeil.tga",
|
||||||
'P_Extra_Life_Shadow.bmp',
|
"P_Extra_Life_Oil.bmp",
|
||||||
'Rail_Environment.bmp',
|
"P_Extra_Life_Particle.bmp",
|
||||||
'sandsack.bmp',
|
"P_Extra_Life_Shadow.bmp",
|
||||||
'SkyLayer.bmp',
|
"Rail_Environment.bmp",
|
||||||
'Sky_Vortex.bmp',
|
"sandsack.bmp",
|
||||||
'Stick_Bottom.tga',
|
"SkyLayer.bmp",
|
||||||
'Stick_Stripes.bmp',
|
"Sky_Vortex.bmp",
|
||||||
'Target.bmp',
|
"Stick_Bottom.tga",
|
||||||
'Tower_Roof.bmp',
|
"Stick_Stripes.bmp",
|
||||||
'Trafo_Environment.bmp',
|
"Target.bmp",
|
||||||
'Trafo_FlashField.bmp',
|
"Tower_Roof.bmp",
|
||||||
'Trafo_Shadow_Big.tga',
|
"Trafo_Environment.bmp",
|
||||||
'Tut_Pfeil01.tga',
|
"Trafo_FlashField.bmp",
|
||||||
'Tut_Pfeil_Hoch.tga',
|
"Trafo_Shadow_Big.tga",
|
||||||
'Wolken_intro.tga',
|
"Tut_Pfeil01.tga",
|
||||||
'Wood_Metal.bmp',
|
"Tut_Pfeil_Hoch.tga",
|
||||||
'Wood_MetalStripes.bmp',
|
"Wolken_intro.tga",
|
||||||
'Wood_Misc.bmp',
|
"Wood_Metal.bmp",
|
||||||
'Wood_Nailed.bmp',
|
"Wood_MetalStripes.bmp",
|
||||||
'Wood_Old.bmp',
|
"Wood_Misc.bmp",
|
||||||
'Wood_Panel.bmp',
|
"Wood_Nailed.bmp",
|
||||||
'Wood_Plain.bmp',
|
"Wood_Old.bmp",
|
||||||
'Wood_Plain2.bmp',
|
"Wood_Panel.bmp",
|
||||||
'Wood_Raft.bmp'
|
"Wood_Plain.bmp",
|
||||||
|
"Wood_Plain2.bmp",
|
||||||
|
"Wood_Raft.bmp"
|
||||||
])
|
])
|
||||||
|
|
||||||
component_list = [
|
component_list = [
|
||||||
|
"P_Extra_Life",
|
||||||
|
"P_Extra_Point",
|
||||||
|
"P_Trafo_Paper",
|
||||||
|
"P_Trafo_Stone",
|
||||||
|
"P_Trafo_Wood",
|
||||||
|
"P_Ball_Paper",
|
||||||
|
"P_Ball_Stone",
|
||||||
|
"P_Ball_Wood",
|
||||||
|
"P_Box",
|
||||||
|
"P_Dome",
|
||||||
|
"P_Modul_01",
|
||||||
|
"P_Modul_03",
|
||||||
|
"P_Modul_08",
|
||||||
|
"P_Modul_17",
|
||||||
|
"P_Modul_18",
|
||||||
|
"P_Modul_19",
|
||||||
|
"P_Modul_25",
|
||||||
|
"P_Modul_26",
|
||||||
|
"P_Modul_29",
|
||||||
|
"P_Modul_30",
|
||||||
|
"P_Modul_34",
|
||||||
|
"P_Modul_37",
|
||||||
|
"P_Modul_41",
|
||||||
|
"PC_TwoFlames",
|
||||||
|
"PE_Balloon",
|
||||||
|
"PR_Resetpoint",
|
||||||
|
"PS_FourFlames"
|
||||||
]
|
]
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user