Merge branch 'main' of http://git.1960life.de/gitlab-instance-a86b4f08/1960-utils
This commit is contained in:
BIN
Blender/_Release/L1960_Tools_1_3_0.zip
Normal file
BIN
Blender/_Release/L1960_Tools_1_3_0.zip
Normal file
Binary file not shown.
BIN
Blender/_Release/L1960_Tools_1_4_0.zip
Normal file
BIN
Blender/_Release/L1960_Tools_1_4_0.zip
Normal file
Binary file not shown.
BIN
Blender/_Release/L1960_Tools_1_5_0.zip
Normal file
BIN
Blender/_Release/L1960_Tools_1_5_0.zip
Normal file
Binary file not shown.
BIN
Blender/_Release/L1960_Tools_1_6_0.zip
Normal file
BIN
Blender/_Release/L1960_Tools_1_6_0.zip
Normal file
Binary file not shown.
94
Blender/_Source/L1960_Tools_1_3_0/CubeProjection.py
Normal file
94
Blender/_Source/L1960_Tools_1_3_0/CubeProjection.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import bpy
|
||||||
|
from math import pi
|
||||||
|
|
||||||
|
L1960_Arr_PlainData = [
|
||||||
|
["Proj_Empty_01", (0, 0, 2), (0, 0, 0)],
|
||||||
|
["Proj_Empty_02", (2, 0, 0), ((pi * 90 / 180), 0, (pi * 90 / 180))],
|
||||||
|
["Proj_Empty_03", (0, 2, 0), ((pi * 90 / 180), 0, (pi * 180 / 180))],
|
||||||
|
["Proj_Empty_04", (0, 0, -2), ((pi * 180 / 180), 0, 0)],
|
||||||
|
["Proj_Empty_05", (-2, 0, 0), ((pi * 90 / 180), 0, (pi * -90 / 180))],
|
||||||
|
["Proj_Empty_06", (0, -2, 0), ((pi * 90 / 180), 0, 0)]
|
||||||
|
]
|
||||||
|
|
||||||
|
class MESH_OT_add_auto_cube_projection(bpy.types.Operator):
|
||||||
|
"""Check Empty´s for projecting, if not existing create new one´s"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.add_auto_cube_projection"
|
||||||
|
bl_label = "Add Plain_Axes to scene"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
scene = bpy.context.scene
|
||||||
|
oldSelection = bpy.context.selected_objects
|
||||||
|
oldActive = bpy.context.active_object
|
||||||
|
|
||||||
|
for EmptyData in L1960_Arr_PlainData:
|
||||||
|
|
||||||
|
EmptyName = EmptyData[0]
|
||||||
|
EmptyLocation = EmptyData[1]
|
||||||
|
EmptyRotation = EmptyData[2]
|
||||||
|
|
||||||
|
if not scene.objects.get(EmptyName):
|
||||||
|
bpy.ops.object.empty_add(type='PLAIN_AXES', align='WORLD', location=EmptyLocation, scale=(1, 1, 1), rotation=EmptyRotation)
|
||||||
|
empty = bpy.context.active_object
|
||||||
|
empty.name = EmptyName
|
||||||
|
empty.hide_select = True
|
||||||
|
empty.hide_set(True)
|
||||||
|
|
||||||
|
#Change back to old selection and select old active
|
||||||
|
for obj in oldSelection:
|
||||||
|
obj.select_set(True)
|
||||||
|
bpy.context.view_layer.objects.active = oldActive
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Added/Fixed Emptys for Projection to Scene')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
class MESH_OT_add_modifier_to_mesh(bpy.types.Operator):
|
||||||
|
"""Add Modifier to selected Mesh´s and prepare UV-Maps"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.add_modifier_to_mesh"
|
||||||
|
bl_label = "Add Modifier to selected Mesh"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
newModifierName = "CubeTexModifier"
|
||||||
|
Arr_obj = bpy.context.selected_objects
|
||||||
|
if len(Arr_obj) < 1:
|
||||||
|
self.report({'WARNING'}, 'Select a mesh to add the UVProject-Modifier')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
empty_objs = [emp_obj for emp_obj in bpy.context.scene.objects if emp_obj.name.startswith("Proj_Empty")]
|
||||||
|
if len(empty_objs) < 6:
|
||||||
|
self.report({'WARNING'}, 'Create/Recreate projectors, they need to be set up first!')
|
||||||
|
return {"CANCELLED"};
|
||||||
|
|
||||||
|
for obj in Arr_obj:
|
||||||
|
|
||||||
|
if obj.data.uv_layers.get("UVMap"):
|
||||||
|
obj.data.uv_layers['UVMap'].name = 'UVMap0'
|
||||||
|
|
||||||
|
if not obj.data.uv_layers.get("UVMap0"):
|
||||||
|
obj.data.uv_layers.new(name = 'UVMap0')
|
||||||
|
|
||||||
|
if not obj.data.uv_layers.get("UVMap1"):
|
||||||
|
obj.data.uv_layers.new(name = 'UVMap1')
|
||||||
|
|
||||||
|
|
||||||
|
if obj.type == "MESH" and newModifierName not in obj.modifiers:
|
||||||
|
obj.modifiers.new(type='UV_PROJECT', name=newModifierName)
|
||||||
|
mod = obj.modifiers[newModifierName]
|
||||||
|
mod.uv_layer = "UVMap1"
|
||||||
|
mod.projector_count = 6
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for p in mod.projectors:
|
||||||
|
p.object = bpy.data.objects[L1960_Arr_PlainData[i][0]]
|
||||||
|
i = i+1
|
||||||
|
else:
|
||||||
|
self.report({'INFO'}, 'UVProject-Modifier allready set')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Added UVProject-Modifier to mesh')
|
||||||
|
return {"FINISHED"}
|
||||||
65
Blender/_Source/L1960_Tools_1_3_0/FixMaterials.py
Normal file
65
Blender/_Source/L1960_Tools_1_3_0/FixMaterials.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
def replace_material(bad_mat, good_mat):
|
||||||
|
bad_mat.user_remap(good_mat)
|
||||||
|
bpy.data.materials.remove(bad_mat)
|
||||||
|
|
||||||
|
|
||||||
|
def get_duplicate_materials(og_material):
|
||||||
|
|
||||||
|
common_name = og_material.name
|
||||||
|
|
||||||
|
if common_name[-3:].isnumeric():
|
||||||
|
common_name = common_name[:-4]
|
||||||
|
|
||||||
|
duplicate_materials = []
|
||||||
|
|
||||||
|
for material in bpy.data.materials:
|
||||||
|
if material is not og_material:
|
||||||
|
name = material.name
|
||||||
|
if name[-3:].isnumeric() and name[-4] == ".":
|
||||||
|
name = name[:-4]
|
||||||
|
|
||||||
|
if name == common_name:
|
||||||
|
duplicate_materials.append(material)
|
||||||
|
|
||||||
|
text = "{} duplicate materials found"
|
||||||
|
print(text.format(len(duplicate_materials)))
|
||||||
|
|
||||||
|
return duplicate_materials
|
||||||
|
|
||||||
|
|
||||||
|
def remove_all_duplicate_materials():
|
||||||
|
i = 0
|
||||||
|
while i < len(bpy.data.materials):
|
||||||
|
|
||||||
|
og_material = bpy.data.materials[i]
|
||||||
|
|
||||||
|
print("og material: " + og_material.name)
|
||||||
|
|
||||||
|
# get duplicate materials
|
||||||
|
duplicate_materials = get_duplicate_materials(og_material)
|
||||||
|
|
||||||
|
# replace all duplicates
|
||||||
|
for duplicate_material in duplicate_materials:
|
||||||
|
replace_material(duplicate_material, og_material)
|
||||||
|
|
||||||
|
# adjust name to no trailing numbers
|
||||||
|
if og_material.name[-3:].isnumeric() and og_material.name[-4] == ".":
|
||||||
|
og_material.name = og_material.name[:-4]
|
||||||
|
|
||||||
|
i = i+1
|
||||||
|
|
||||||
|
class MESH_OT_fix_material_names(bpy.types.Operator):
|
||||||
|
"""Fixes the material naming, if duplicated are present e.g. Material.001, Material.002 ..."""
|
||||||
|
|
||||||
|
bl_idname = "mesh.fix_material_names"
|
||||||
|
bl_label = "Fixes the material naming, if duplicated are present"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
remove_all_duplicate_materials()
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'All duplicated Materials merged/fixed')
|
||||||
|
return {"FINISHED"}
|
||||||
65
Blender/_Source/L1960_Tools_1_3_0/__init__.py
Normal file
65
Blender/_Source/L1960_Tools_1_3_0/__init__.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
bl_info = {
|
||||||
|
"name": "L1960 Tools",
|
||||||
|
"author": "Prodeath21",
|
||||||
|
"version": (1, 3, 0),
|
||||||
|
"blender": (2, 80, 0),
|
||||||
|
"location": "3D Viewport > Sidebar > 1960Life category",
|
||||||
|
"description": "Set´s up the Projection-Modifier automatically and add´s in the Emptys if not allready created.",
|
||||||
|
"category": "Object",
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------------------
|
||||||
|
# Import modules
|
||||||
|
# ----------------------------------------------
|
||||||
|
if "bpy" in locals():
|
||||||
|
import imp
|
||||||
|
imp.reload(CubeProjection)
|
||||||
|
imp.reload(FixMaterials)
|
||||||
|
print("L1960 Tools: Reloaded multifiles")
|
||||||
|
else:
|
||||||
|
import bpy
|
||||||
|
from . import CubeProjection
|
||||||
|
from . import FixMaterials
|
||||||
|
|
||||||
|
from . CubeProjection import MESH_OT_add_auto_cube_projection, MESH_OT_add_modifier_to_mesh
|
||||||
|
from . FixMaterials import MESH_OT_fix_material_names
|
||||||
|
|
||||||
|
class L1960_PT_AutoAddProjection(bpy.types.Panel):
|
||||||
|
pass
|
||||||
|
#where to add the panel
|
||||||
|
bl_space_type = "VIEW_3D"
|
||||||
|
bl_region_type = "UI"
|
||||||
|
|
||||||
|
#add labels
|
||||||
|
bl_label = "1960-Life Tools"
|
||||||
|
bl_category = "1960-Life"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
"""define the layout of the panel"""
|
||||||
|
self.layout.label(text="UV-Projection")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator("mesh.add_auto_cube_projection", text="Set up Projectors")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator("mesh.add_modifier_to_mesh", text="Add Modifier to Mesh")
|
||||||
|
self.layout.separator()
|
||||||
|
self.layout.label(text="Materials")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator("mesh.fix_material_names", text="Fix Material Name´s")
|
||||||
|
#self.layout.separator()
|
||||||
|
#self.layout.label(text="LOD´s")
|
||||||
|
#row = self.layout.row()
|
||||||
|
#row.operator("mesh.prepareLods_decimate", text="Create LOD´s with decimate")
|
||||||
|
|
||||||
|
#register the panel with blender
|
||||||
|
modules = [L1960_PT_AutoAddProjection, MESH_OT_add_auto_cube_projection, MESH_OT_add_modifier_to_mesh, MESH_OT_fix_material_names]
|
||||||
|
|
||||||
|
def register():
|
||||||
|
for mod in modules:
|
||||||
|
bpy.utils.register_class(mod)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
for mod in modules:
|
||||||
|
bpy.utils.unregister_class(mod)
|
||||||
|
|
||||||
|
if __name__== "__main__":
|
||||||
|
register()
|
||||||
94
Blender/_Source/L1960_Tools_1_4_0/CubeProjection.py
Normal file
94
Blender/_Source/L1960_Tools_1_4_0/CubeProjection.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import bpy
|
||||||
|
from math import pi
|
||||||
|
|
||||||
|
L1960_Arr_PlainData = [
|
||||||
|
["Proj_Empty_01", (0, 0, 2), (0, 0, 0)],
|
||||||
|
["Proj_Empty_02", (2, 0, 0), ((pi * 90 / 180), 0, (pi * 90 / 180))],
|
||||||
|
["Proj_Empty_03", (0, 2, 0), ((pi * 90 / 180), 0, (pi * 180 / 180))],
|
||||||
|
["Proj_Empty_04", (0, 0, -2), ((pi * 180 / 180), 0, 0)],
|
||||||
|
["Proj_Empty_05", (-2, 0, 0), ((pi * 90 / 180), 0, (pi * -90 / 180))],
|
||||||
|
["Proj_Empty_06", (0, -2, 0), ((pi * 90 / 180), 0, 0)]
|
||||||
|
]
|
||||||
|
|
||||||
|
class MESH_OT_add_auto_cube_projection(bpy.types.Operator):
|
||||||
|
"""Check Empty´s for projecting, if not existing create new one´s"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.add_auto_cube_projection"
|
||||||
|
bl_label = "Add Plain_Axes to scene"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
scene = bpy.context.scene
|
||||||
|
oldSelection = bpy.context.selected_objects
|
||||||
|
oldActive = bpy.context.active_object
|
||||||
|
|
||||||
|
for EmptyData in L1960_Arr_PlainData:
|
||||||
|
|
||||||
|
EmptyName = EmptyData[0]
|
||||||
|
EmptyLocation = EmptyData[1]
|
||||||
|
EmptyRotation = EmptyData[2]
|
||||||
|
|
||||||
|
if not scene.objects.get(EmptyName):
|
||||||
|
bpy.ops.object.empty_add(type='PLAIN_AXES', align='WORLD', location=EmptyLocation, scale=(1, 1, 1), rotation=EmptyRotation)
|
||||||
|
empty = bpy.context.active_object
|
||||||
|
empty.name = EmptyName
|
||||||
|
empty.hide_select = True
|
||||||
|
empty.hide_set(True)
|
||||||
|
|
||||||
|
#Change back to old selection and select old active
|
||||||
|
for obj in oldSelection:
|
||||||
|
obj.select_set(True)
|
||||||
|
bpy.context.view_layer.objects.active = oldActive
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Added/Fixed Emptys for Projection to Scene')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
class MESH_OT_add_modifier_to_mesh(bpy.types.Operator):
|
||||||
|
"""Add Modifier to selected Mesh´s and prepare UV-Maps"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.add_modifier_to_mesh"
|
||||||
|
bl_label = "Add Modifier to selected Mesh"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
newModifierName = "CubeTexModifier"
|
||||||
|
Arr_obj = bpy.context.selected_objects
|
||||||
|
if len(Arr_obj) < 1:
|
||||||
|
self.report({'WARNING'}, 'Select a mesh to add the UVProject-Modifier')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
empty_objs = [emp_obj for emp_obj in bpy.context.scene.objects if emp_obj.name.startswith("Proj_Empty")]
|
||||||
|
if len(empty_objs) < 6:
|
||||||
|
self.report({'WARNING'}, 'Create/Recreate projectors, they need to be set up first!')
|
||||||
|
return {"CANCELLED"};
|
||||||
|
|
||||||
|
for obj in Arr_obj:
|
||||||
|
|
||||||
|
if obj.data.uv_layers.get("UVMap"):
|
||||||
|
obj.data.uv_layers['UVMap'].name = 'UVMap0'
|
||||||
|
|
||||||
|
if not obj.data.uv_layers.get("UVMap0"):
|
||||||
|
obj.data.uv_layers.new(name = 'UVMap0')
|
||||||
|
|
||||||
|
if not obj.data.uv_layers.get("UVMap1"):
|
||||||
|
obj.data.uv_layers.new(name = 'UVMap1')
|
||||||
|
|
||||||
|
|
||||||
|
if obj.type == "MESH" and newModifierName not in obj.modifiers:
|
||||||
|
obj.modifiers.new(type='UV_PROJECT', name=newModifierName)
|
||||||
|
mod = obj.modifiers[newModifierName]
|
||||||
|
mod.uv_layer = "UVMap1"
|
||||||
|
mod.projector_count = 6
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for p in mod.projectors:
|
||||||
|
p.object = bpy.data.objects[L1960_Arr_PlainData[i][0]]
|
||||||
|
i = i+1
|
||||||
|
else:
|
||||||
|
self.report({'INFO'}, 'UVProject-Modifier allready set')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Added UVProject-Modifier to mesh')
|
||||||
|
return {"FINISHED"}
|
||||||
65
Blender/_Source/L1960_Tools_1_4_0/FixMaterials.py
Normal file
65
Blender/_Source/L1960_Tools_1_4_0/FixMaterials.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
def replace_material(bad_mat, good_mat):
|
||||||
|
bad_mat.user_remap(good_mat)
|
||||||
|
bpy.data.materials.remove(bad_mat)
|
||||||
|
|
||||||
|
|
||||||
|
def get_duplicate_materials(og_material):
|
||||||
|
|
||||||
|
common_name = og_material.name
|
||||||
|
|
||||||
|
if common_name[-3:].isnumeric():
|
||||||
|
common_name = common_name[:-4]
|
||||||
|
|
||||||
|
duplicate_materials = []
|
||||||
|
|
||||||
|
for material in bpy.data.materials:
|
||||||
|
if material is not og_material:
|
||||||
|
name = material.name
|
||||||
|
if name[-3:].isnumeric() and name[-4] == ".":
|
||||||
|
name = name[:-4]
|
||||||
|
|
||||||
|
if name == common_name:
|
||||||
|
duplicate_materials.append(material)
|
||||||
|
|
||||||
|
text = "{} duplicate materials found"
|
||||||
|
print(text.format(len(duplicate_materials)))
|
||||||
|
|
||||||
|
return duplicate_materials
|
||||||
|
|
||||||
|
|
||||||
|
def remove_all_duplicate_materials():
|
||||||
|
i = 0
|
||||||
|
while i < len(bpy.data.materials):
|
||||||
|
|
||||||
|
og_material = bpy.data.materials[i]
|
||||||
|
|
||||||
|
print("og material: " + og_material.name)
|
||||||
|
|
||||||
|
# get duplicate materials
|
||||||
|
duplicate_materials = get_duplicate_materials(og_material)
|
||||||
|
|
||||||
|
# replace all duplicates
|
||||||
|
for duplicate_material in duplicate_materials:
|
||||||
|
replace_material(duplicate_material, og_material)
|
||||||
|
|
||||||
|
# adjust name to no trailing numbers
|
||||||
|
if og_material.name[-3:].isnumeric() and og_material.name[-4] == ".":
|
||||||
|
og_material.name = og_material.name[:-4]
|
||||||
|
|
||||||
|
i = i+1
|
||||||
|
|
||||||
|
class MESH_OT_fix_material_names(bpy.types.Operator):
|
||||||
|
"""Fixes the material naming, if duplicated are present e.g. Material.001, Material.002 ..."""
|
||||||
|
|
||||||
|
bl_idname = "mesh.fix_material_names"
|
||||||
|
bl_label = "Fixes the material naming, if duplicated are present"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
remove_all_duplicate_materials()
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'All duplicated Materials merged/fixed')
|
||||||
|
return {"FINISHED"}
|
||||||
13
Blender/_Source/L1960_Tools_1_4_0/PrepareLods.py
Normal file
13
Blender/_Source/L1960_Tools_1_4_0/PrepareLods.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
class MESH_OT_prepare_lods_decimate(bpy.types.Operator):
|
||||||
|
"""Copy current Mesh and apply decimate Modifier"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.prepare_lods_decimate"
|
||||||
|
bl_label = "Copy current Mesh and apply decimate Modifier"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Currently not in use')
|
||||||
|
return {"FINISHED"}
|
||||||
74
Blender/_Source/L1960_Tools_1_4_0/__init__.py
Normal file
74
Blender/_Source/L1960_Tools_1_4_0/__init__.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
bl_info = {
|
||||||
|
"name": "L1960 Tools",
|
||||||
|
"author": "Prodeath21",
|
||||||
|
"version": (1, 4, 0),
|
||||||
|
"blender": (2, 80, 0),
|
||||||
|
"location": "3D Viewport > Sidebar > 1960Life category",
|
||||||
|
"description": "Set´s up the Projection-Modifier automatically and add´s in the Emptys if not allready created.",
|
||||||
|
"category": "Object",
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------------------
|
||||||
|
# Import modules
|
||||||
|
# ----------------------------------------------
|
||||||
|
if "bpy" in locals():
|
||||||
|
import imp
|
||||||
|
imp.reload(CubeProjection)
|
||||||
|
imp.reload(FixMaterials)
|
||||||
|
imp.reload(PrepareLods)
|
||||||
|
print("L1960 Tools: Reloaded multifiles")
|
||||||
|
else:
|
||||||
|
from . import CubeProjection
|
||||||
|
from . import FixMaterials
|
||||||
|
from . import PrepareLods
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
from . CubeProjection import MESH_OT_add_auto_cube_projection, MESH_OT_add_modifier_to_mesh
|
||||||
|
from . FixMaterials import MESH_OT_fix_material_names
|
||||||
|
from . PrepareLods import MESH_OT_prepare_lods_decimate
|
||||||
|
|
||||||
|
class L1960_PT_tools(bpy.types.Panel):
|
||||||
|
pass
|
||||||
|
#where to add the panel
|
||||||
|
bl_space_type = "VIEW_3D"
|
||||||
|
bl_region_type = "UI"
|
||||||
|
|
||||||
|
#add labels
|
||||||
|
bl_label = "1960-Life Tools"
|
||||||
|
bl_category = "1960-Life"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
"""define the layout of the panel"""
|
||||||
|
self.layout.label(text="UV-Projection")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator("mesh.add_auto_cube_projection", text="Set up Projectors")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator("mesh.add_modifier_to_mesh", text="Add Modifier to Mesh")
|
||||||
|
self.layout.separator()
|
||||||
|
self.layout.label(text="Materials")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator("mesh.fix_material_names", text="Fix Material Name´s")
|
||||||
|
self.layout.separator()
|
||||||
|
self.layout.label(text="LOD´s")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator("mesh.prepare_lods_decimate", text="Create LOD´s with decimate")
|
||||||
|
|
||||||
|
#register the panel with blender
|
||||||
|
modules = [ L1960_PT_tools,
|
||||||
|
MESH_OT_add_auto_cube_projection,
|
||||||
|
MESH_OT_add_modifier_to_mesh,
|
||||||
|
MESH_OT_fix_material_names,
|
||||||
|
MESH_OT_prepare_lods_decimate
|
||||||
|
]
|
||||||
|
|
||||||
|
def register():
|
||||||
|
for mod in modules:
|
||||||
|
bpy.utils.register_class(mod)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
for mod in modules:
|
||||||
|
bpy.utils.unregister_class(mod)
|
||||||
|
|
||||||
|
if __name__== "__main__":
|
||||||
|
register()
|
||||||
94
Blender/_Source/L1960_Tools_1_5_0/CubeProjection.py
Normal file
94
Blender/_Source/L1960_Tools_1_5_0/CubeProjection.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import bpy
|
||||||
|
from math import pi
|
||||||
|
|
||||||
|
L1960_Arr_PlainData = [
|
||||||
|
["Proj_Empty_01", (0, 0, 2), (0, 0, 0)],
|
||||||
|
["Proj_Empty_02", (2, 0, 0), ((pi * 90 / 180), 0, (pi * 90 / 180))],
|
||||||
|
["Proj_Empty_03", (0, 2, 0), ((pi * 90 / 180), 0, (pi * 180 / 180))],
|
||||||
|
["Proj_Empty_04", (0, 0, -2), ((pi * 180 / 180), 0, 0)],
|
||||||
|
["Proj_Empty_05", (-2, 0, 0), ((pi * 90 / 180), 0, (pi * -90 / 180))],
|
||||||
|
["Proj_Empty_06", (0, -2, 0), ((pi * 90 / 180), 0, 0)]
|
||||||
|
]
|
||||||
|
|
||||||
|
class MESH_OT_add_auto_cube_projection(bpy.types.Operator):
|
||||||
|
"""Check Empty´s for projecting, if not existing create new one´s"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.add_auto_cube_projection"
|
||||||
|
bl_label = "Add Plain_Axes to scene"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
scene = bpy.context.scene
|
||||||
|
oldSelection = bpy.context.selected_objects
|
||||||
|
oldActive = bpy.context.active_object
|
||||||
|
|
||||||
|
for EmptyData in L1960_Arr_PlainData:
|
||||||
|
|
||||||
|
EmptyName = EmptyData[0]
|
||||||
|
EmptyLocation = EmptyData[1]
|
||||||
|
EmptyRotation = EmptyData[2]
|
||||||
|
|
||||||
|
if not scene.objects.get(EmptyName):
|
||||||
|
bpy.ops.object.empty_add(type='PLAIN_AXES', align='WORLD', location=EmptyLocation, scale=(1, 1, 1), rotation=EmptyRotation)
|
||||||
|
empty = bpy.context.active_object
|
||||||
|
empty.name = EmptyName
|
||||||
|
empty.hide_select = True
|
||||||
|
empty.hide_set(True)
|
||||||
|
|
||||||
|
#Change back to old selection and select old active
|
||||||
|
for obj in oldSelection:
|
||||||
|
obj.select_set(True)
|
||||||
|
bpy.context.view_layer.objects.active = oldActive
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Added/Fixed Emptys for Projection to Scene')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
class MESH_OT_add_modifier_to_mesh(bpy.types.Operator):
|
||||||
|
"""Add Modifier to selected Mesh´s and prepare UV-Maps"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.add_modifier_to_mesh"
|
||||||
|
bl_label = "Add Modifier to selected Mesh"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
newModifierName = "CubeTexModifier"
|
||||||
|
Arr_obj = bpy.context.selected_objects
|
||||||
|
if len(Arr_obj) < 1:
|
||||||
|
self.report({'WARNING'}, 'Select a mesh to add the UVProject-Modifier')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
empty_objs = [emp_obj for emp_obj in bpy.context.scene.objects if emp_obj.name.startswith("Proj_Empty")]
|
||||||
|
if len(empty_objs) < 6:
|
||||||
|
self.report({'WARNING'}, 'Create/Recreate projectors, they need to be set up first!')
|
||||||
|
return {"CANCELLED"};
|
||||||
|
|
||||||
|
for obj in Arr_obj:
|
||||||
|
|
||||||
|
if obj.data.uv_layers.get("UVMap"):
|
||||||
|
obj.data.uv_layers['UVMap'].name = 'UVMap0'
|
||||||
|
|
||||||
|
if not obj.data.uv_layers.get("UVMap0"):
|
||||||
|
obj.data.uv_layers.new(name = 'UVMap0')
|
||||||
|
|
||||||
|
if not obj.data.uv_layers.get("UVMap1"):
|
||||||
|
obj.data.uv_layers.new(name = 'UVMap1')
|
||||||
|
|
||||||
|
|
||||||
|
if obj.type == "MESH" and newModifierName not in obj.modifiers:
|
||||||
|
obj.modifiers.new(type='UV_PROJECT', name=newModifierName)
|
||||||
|
mod = obj.modifiers[newModifierName]
|
||||||
|
mod.uv_layer = "UVMap1"
|
||||||
|
mod.projector_count = 6
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for p in mod.projectors:
|
||||||
|
p.object = bpy.data.objects[L1960_Arr_PlainData[i][0]]
|
||||||
|
i = i+1
|
||||||
|
else:
|
||||||
|
self.report({'INFO'}, 'UVProject-Modifier allready set')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Added UVProject-Modifier to mesh')
|
||||||
|
return {"FINISHED"}
|
||||||
65
Blender/_Source/L1960_Tools_1_5_0/FixMaterials.py
Normal file
65
Blender/_Source/L1960_Tools_1_5_0/FixMaterials.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
def replace_material(bad_mat, good_mat):
|
||||||
|
bad_mat.user_remap(good_mat)
|
||||||
|
bpy.data.materials.remove(bad_mat)
|
||||||
|
|
||||||
|
|
||||||
|
def get_duplicate_materials(og_material):
|
||||||
|
|
||||||
|
common_name = og_material.name
|
||||||
|
|
||||||
|
if common_name[-3:].isnumeric():
|
||||||
|
common_name = common_name[:-4]
|
||||||
|
|
||||||
|
duplicate_materials = []
|
||||||
|
|
||||||
|
for material in bpy.data.materials:
|
||||||
|
if material is not og_material:
|
||||||
|
name = material.name
|
||||||
|
if name[-3:].isnumeric() and name[-4] == ".":
|
||||||
|
name = name[:-4]
|
||||||
|
|
||||||
|
if name == common_name:
|
||||||
|
duplicate_materials.append(material)
|
||||||
|
|
||||||
|
text = "{} duplicate materials found"
|
||||||
|
print(text.format(len(duplicate_materials)))
|
||||||
|
|
||||||
|
return duplicate_materials
|
||||||
|
|
||||||
|
|
||||||
|
def remove_all_duplicate_materials():
|
||||||
|
i = 0
|
||||||
|
while i < len(bpy.data.materials):
|
||||||
|
|
||||||
|
og_material = bpy.data.materials[i]
|
||||||
|
|
||||||
|
print("og material: " + og_material.name)
|
||||||
|
|
||||||
|
# get duplicate materials
|
||||||
|
duplicate_materials = get_duplicate_materials(og_material)
|
||||||
|
|
||||||
|
# replace all duplicates
|
||||||
|
for duplicate_material in duplicate_materials:
|
||||||
|
replace_material(duplicate_material, og_material)
|
||||||
|
|
||||||
|
# adjust name to no trailing numbers
|
||||||
|
if og_material.name[-3:].isnumeric() and og_material.name[-4] == ".":
|
||||||
|
og_material.name = og_material.name[:-4]
|
||||||
|
|
||||||
|
i = i+1
|
||||||
|
|
||||||
|
class MESH_OT_fix_material_names(bpy.types.Operator):
|
||||||
|
"""Fixes the material naming, if duplicated are present e.g. Material.001, Material.002 ..."""
|
||||||
|
|
||||||
|
bl_idname = "mesh.fix_material_names"
|
||||||
|
bl_label = "Fixes the material naming, if duplicated are present"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
remove_all_duplicate_materials()
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'All duplicated Materials fixed')
|
||||||
|
return {"FINISHED"}
|
||||||
40
Blender/_Source/L1960_Tools_1_5_0/PrepareLods.py
Normal file
40
Blender/_Source/L1960_Tools_1_5_0/PrepareLods.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
class MESH_OT_prepare_lods_decimate(bpy.types.Operator):
|
||||||
|
"""Copy current Mesh and apply decimate Modifier"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.prepare_lods_decimate"
|
||||||
|
bl_label = "Copy current Mesh and apply decimate Modifier"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
#Selected Mesh
|
||||||
|
obj = bpy.context.active_object
|
||||||
|
|
||||||
|
if obj not in bpy.context.selected_objects or obj.type != "MESH":
|
||||||
|
self.report({'WARNING'}, 'Select a Mesh to continue')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
if not obj.name[:-1].endswith('LOD'):
|
||||||
|
obj.name = obj.name + '_LOD0'
|
||||||
|
|
||||||
|
LODnumber = context.scene.lod_slider #Get from Slider
|
||||||
|
startLODcount = int(obj.name[-1])
|
||||||
|
endLODcount = startLODcount + LODnumber
|
||||||
|
|
||||||
|
for i in range (startLODcount + 1, endLODcount):
|
||||||
|
new_obj = obj.copy()
|
||||||
|
new_obj.data = obj.data.copy()
|
||||||
|
new_obj.name = obj.name[:-1] + str(i)
|
||||||
|
bpy.context.collection.objects.link(new_obj)
|
||||||
|
|
||||||
|
for t in range (startLODcount, i):
|
||||||
|
newModifierName = 'LOD_Decimate_' + str(t)
|
||||||
|
new_obj.modifiers.new(type='DECIMATE', name=newModifierName)
|
||||||
|
mod = new_obj.modifiers[newModifierName]
|
||||||
|
mod.ratio = 0.49
|
||||||
|
mod.use_collapse_triangulate = True
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'LOD´s created')
|
||||||
|
return {"FINISHED"}
|
||||||
82
Blender/_Source/L1960_Tools_1_5_0/__init__.py
Normal file
82
Blender/_Source/L1960_Tools_1_5_0/__init__.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
bl_info = {
|
||||||
|
"name": "L1960 Tools",
|
||||||
|
"author": "Prodeath21",
|
||||||
|
"version": (1, 5, 0),
|
||||||
|
"blender": (2, 80, 0),
|
||||||
|
"location": "3D Viewport > Sidebar > 1960Life category",
|
||||||
|
"description": "Set´s up the Projection-Modifier automatically and add´s in the Emptys if not allready created.",
|
||||||
|
"category": "Object",
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------------------
|
||||||
|
# Import modules
|
||||||
|
# ----------------------------------------------
|
||||||
|
if "bpy" in locals():
|
||||||
|
import imp
|
||||||
|
imp.reload(CubeProjection)
|
||||||
|
imp.reload(FixMaterials)
|
||||||
|
imp.reload(PrepareLods)
|
||||||
|
print("L1960 Tools: Reloaded multifiles")
|
||||||
|
else:
|
||||||
|
from . import CubeProjection
|
||||||
|
from . import FixMaterials
|
||||||
|
from . import PrepareLods
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
from . CubeProjection import MESH_OT_add_auto_cube_projection, MESH_OT_add_modifier_to_mesh
|
||||||
|
from . FixMaterials import MESH_OT_fix_material_names
|
||||||
|
from . PrepareLods import MESH_OT_prepare_lods_decimate
|
||||||
|
|
||||||
|
class L1960_PT_tools(bpy.types.Panel):
|
||||||
|
pass
|
||||||
|
#where to add the panel
|
||||||
|
bl_space_type = "VIEW_3D"
|
||||||
|
bl_region_type = "UI"
|
||||||
|
|
||||||
|
#add labels
|
||||||
|
bl_label = "1960-Life Tools"
|
||||||
|
bl_category = "1960-Life"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
"""define the layout of the panel"""
|
||||||
|
box = self.layout.box()
|
||||||
|
box.label(text="UV-Projection")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("mesh.add_auto_cube_projection", text="Set up Projectors")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("mesh.add_modifier_to_mesh", text="Add Modifier to Mesh")
|
||||||
|
self.layout.separator()
|
||||||
|
box = self.layout.box()
|
||||||
|
box.label(text="Materials")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("mesh.fix_material_names", text="Fix Material Name´s")
|
||||||
|
self.layout.separator()
|
||||||
|
box = self.layout.box()
|
||||||
|
box.label(text="LOD´s")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("mesh.prepare_lods_decimate", text="Create LOD´s")
|
||||||
|
box.prop(context.scene, "lod_slider", text="")
|
||||||
|
|
||||||
|
#register the panel with blender
|
||||||
|
modules = [ L1960_PT_tools,
|
||||||
|
MESH_OT_add_auto_cube_projection,
|
||||||
|
MESH_OT_add_modifier_to_mesh,
|
||||||
|
MESH_OT_fix_material_names,
|
||||||
|
MESH_OT_prepare_lods_decimate
|
||||||
|
]
|
||||||
|
|
||||||
|
def register():
|
||||||
|
for mod in modules:
|
||||||
|
bpy.utils.register_class(mod)
|
||||||
|
|
||||||
|
bpy.types.Scene.lod_slider = bpy.props.IntProperty(name="LOD Number", default=3, min=0, max=10)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
for mod in modules:
|
||||||
|
bpy.utils.unregister_class(mod)
|
||||||
|
|
||||||
|
del bpy.types.Scene.lod_slider
|
||||||
|
|
||||||
|
if __name__== "__main__":
|
||||||
|
register()
|
||||||
94
Blender/_Source/L1960_Tools_1_6_0/CubeProjection.py
Normal file
94
Blender/_Source/L1960_Tools_1_6_0/CubeProjection.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import bpy
|
||||||
|
from math import pi
|
||||||
|
|
||||||
|
L1960_Arr_PlainData = [
|
||||||
|
["Proj_Empty_01", (0, 0, 2), (0, 0, 0)],
|
||||||
|
["Proj_Empty_02", (2, 0, 0), ((pi * 90 / 180), 0, (pi * 90 / 180))],
|
||||||
|
["Proj_Empty_03", (0, 2, 0), ((pi * 90 / 180), 0, (pi * 180 / 180))],
|
||||||
|
["Proj_Empty_04", (0, 0, -2), ((pi * 180 / 180), 0, 0)],
|
||||||
|
["Proj_Empty_05", (-2, 0, 0), ((pi * 90 / 180), 0, (pi * -90 / 180))],
|
||||||
|
["Proj_Empty_06", (0, -2, 0), ((pi * 90 / 180), 0, 0)]
|
||||||
|
]
|
||||||
|
|
||||||
|
class MESH_OT_add_auto_cube_projection(bpy.types.Operator):
|
||||||
|
"""Check Empty´s for projecting, if not existing create new one´s"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.add_auto_cube_projection"
|
||||||
|
bl_label = "Add Plain_Axes to scene"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
scene = bpy.context.scene
|
||||||
|
oldSelection = bpy.context.selected_objects
|
||||||
|
oldActive = bpy.context.active_object
|
||||||
|
|
||||||
|
for EmptyData in L1960_Arr_PlainData:
|
||||||
|
|
||||||
|
EmptyName = EmptyData[0]
|
||||||
|
EmptyLocation = EmptyData[1]
|
||||||
|
EmptyRotation = EmptyData[2]
|
||||||
|
|
||||||
|
if not scene.objects.get(EmptyName):
|
||||||
|
bpy.ops.object.empty_add(type='PLAIN_AXES', align='WORLD', location=EmptyLocation, scale=(1, 1, 1), rotation=EmptyRotation)
|
||||||
|
empty = bpy.context.active_object
|
||||||
|
empty.name = EmptyName
|
||||||
|
empty.hide_select = True
|
||||||
|
empty.hide_set(True)
|
||||||
|
|
||||||
|
#Change back to old selection and select old active
|
||||||
|
for obj in oldSelection:
|
||||||
|
obj.select_set(True)
|
||||||
|
bpy.context.view_layer.objects.active = oldActive
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Added/Fixed Emptys for Projection to Scene')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
class MESH_OT_add_modifier_to_mesh(bpy.types.Operator):
|
||||||
|
"""Add Modifier to selected Mesh´s and prepare UV-Maps"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.add_modifier_to_mesh"
|
||||||
|
bl_label = "Add Modifier to selected Mesh"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
newModifierName = "CubeTexModifier"
|
||||||
|
Arr_obj = bpy.context.selected_objects
|
||||||
|
if len(Arr_obj) < 1:
|
||||||
|
self.report({'WARNING'}, 'Select a mesh to add the UVProject-Modifier')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
empty_objs = [emp_obj for emp_obj in bpy.context.scene.objects if emp_obj.name.startswith("Proj_Empty")]
|
||||||
|
if len(empty_objs) < 6:
|
||||||
|
self.report({'WARNING'}, 'Create/Recreate projectors, they need to be set up first!')
|
||||||
|
return {"CANCELLED"};
|
||||||
|
|
||||||
|
for obj in Arr_obj:
|
||||||
|
|
||||||
|
if obj.data.uv_layers.get("UVMap"):
|
||||||
|
obj.data.uv_layers['UVMap'].name = 'UVMap0'
|
||||||
|
|
||||||
|
if not obj.data.uv_layers.get("UVMap0"):
|
||||||
|
obj.data.uv_layers.new(name = 'UVMap0')
|
||||||
|
|
||||||
|
if not obj.data.uv_layers.get("UVMap1"):
|
||||||
|
obj.data.uv_layers.new(name = 'UVMap1')
|
||||||
|
|
||||||
|
|
||||||
|
if obj.type == "MESH" and newModifierName not in obj.modifiers:
|
||||||
|
obj.modifiers.new(type='UV_PROJECT', name=newModifierName)
|
||||||
|
mod = obj.modifiers[newModifierName]
|
||||||
|
mod.uv_layer = "UVMap1"
|
||||||
|
mod.projector_count = 6
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for p in mod.projectors:
|
||||||
|
p.object = bpy.data.objects[L1960_Arr_PlainData[i][0]]
|
||||||
|
i = i+1
|
||||||
|
else:
|
||||||
|
self.report({'INFO'}, 'UVProject-Modifier allready set')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Added UVProject-Modifier to mesh')
|
||||||
|
return {"FINISHED"}
|
||||||
65
Blender/_Source/L1960_Tools_1_6_0/FixMaterials.py
Normal file
65
Blender/_Source/L1960_Tools_1_6_0/FixMaterials.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
def replace_material(bad_mat, good_mat):
|
||||||
|
bad_mat.user_remap(good_mat)
|
||||||
|
bpy.data.materials.remove(bad_mat)
|
||||||
|
|
||||||
|
|
||||||
|
def get_duplicate_materials(og_material):
|
||||||
|
|
||||||
|
common_name = og_material.name
|
||||||
|
|
||||||
|
if common_name[-3:].isnumeric():
|
||||||
|
common_name = common_name[:-4]
|
||||||
|
|
||||||
|
duplicate_materials = []
|
||||||
|
|
||||||
|
for material in bpy.data.materials:
|
||||||
|
if material is not og_material:
|
||||||
|
name = material.name
|
||||||
|
if name[-3:].isnumeric() and name[-4] == ".":
|
||||||
|
name = name[:-4]
|
||||||
|
|
||||||
|
if name == common_name:
|
||||||
|
duplicate_materials.append(material)
|
||||||
|
|
||||||
|
text = "{} duplicate materials found"
|
||||||
|
print(text.format(len(duplicate_materials)))
|
||||||
|
|
||||||
|
return duplicate_materials
|
||||||
|
|
||||||
|
|
||||||
|
def remove_all_duplicate_materials():
|
||||||
|
i = 0
|
||||||
|
while i < len(bpy.data.materials):
|
||||||
|
|
||||||
|
og_material = bpy.data.materials[i]
|
||||||
|
|
||||||
|
print("og material: " + og_material.name)
|
||||||
|
|
||||||
|
# get duplicate materials
|
||||||
|
duplicate_materials = get_duplicate_materials(og_material)
|
||||||
|
|
||||||
|
# replace all duplicates
|
||||||
|
for duplicate_material in duplicate_materials:
|
||||||
|
replace_material(duplicate_material, og_material)
|
||||||
|
|
||||||
|
# adjust name to no trailing numbers
|
||||||
|
if og_material.name[-3:].isnumeric() and og_material.name[-4] == ".":
|
||||||
|
og_material.name = og_material.name[:-4]
|
||||||
|
|
||||||
|
i = i+1
|
||||||
|
|
||||||
|
class MESH_OT_fix_material_names(bpy.types.Operator):
|
||||||
|
"""Fixes the material naming, if duplicated are present e.g. Material.001, Material.002 ..."""
|
||||||
|
|
||||||
|
bl_idname = "mesh.fix_material_names"
|
||||||
|
bl_label = "Fixes the material naming, if duplicated are present"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
remove_all_duplicate_materials()
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'All duplicated Materials fixed')
|
||||||
|
return {"FINISHED"}
|
||||||
40
Blender/_Source/L1960_Tools_1_6_0/PrepareLods.py
Normal file
40
Blender/_Source/L1960_Tools_1_6_0/PrepareLods.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
class MESH_OT_prepare_lods_decimate(bpy.types.Operator):
|
||||||
|
"""Copy current Mesh and apply decimate Modifier"""
|
||||||
|
|
||||||
|
bl_idname = "mesh.prepare_lods_decimate"
|
||||||
|
bl_label = "Copy current Mesh and apply decimate Modifier"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
#Selected Mesh
|
||||||
|
obj = bpy.context.active_object
|
||||||
|
|
||||||
|
if obj not in bpy.context.selected_objects or obj.type != "MESH":
|
||||||
|
self.report({'WARNING'}, 'Select a Mesh to continue')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
if not obj.name[:-1].endswith('LOD'):
|
||||||
|
obj.name = obj.name + '_LOD0'
|
||||||
|
|
||||||
|
LODnumber = context.scene.lod_slider #Get from Slider
|
||||||
|
startLODcount = int(obj.name[-1])
|
||||||
|
endLODcount = startLODcount + LODnumber
|
||||||
|
|
||||||
|
for i in range (startLODcount + 1, endLODcount):
|
||||||
|
new_obj = obj.copy()
|
||||||
|
new_obj.data = obj.data.copy()
|
||||||
|
new_obj.name = obj.name[:-1] + str(i)
|
||||||
|
bpy.context.collection.objects.link(new_obj)
|
||||||
|
|
||||||
|
for t in range (startLODcount, i):
|
||||||
|
newModifierName = 'LOD_Decimate_' + str(t)
|
||||||
|
new_obj.modifiers.new(type='DECIMATE', name=newModifierName)
|
||||||
|
mod = new_obj.modifiers[newModifierName]
|
||||||
|
mod.ratio = 0.49
|
||||||
|
mod.use_collapse_triangulate = True
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'LOD´s created')
|
||||||
|
return {"FINISHED"}
|
||||||
104
Blender/_Source/L1960_Tools_1_6_0/__init__.py
Normal file
104
Blender/_Source/L1960_Tools_1_6_0/__init__.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
bl_info = {
|
||||||
|
"name": "L1960 Tools",
|
||||||
|
"author": "Prodeath21",
|
||||||
|
"version": (1, 6, 0),
|
||||||
|
"blender": (2, 80, 0),
|
||||||
|
"location": "3D Viewport > Sidebar > 1960Life category",
|
||||||
|
"description": "Set´s up the Projection-Modifier automatically and add´s in the Emptys if not allready created.",
|
||||||
|
"category": "Object",
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------------------
|
||||||
|
# Import modules
|
||||||
|
# ----------------------------------------------
|
||||||
|
if "bpy" in locals():
|
||||||
|
import imp
|
||||||
|
imp.reload(CubeProjection)
|
||||||
|
imp.reload(FixMaterials)
|
||||||
|
imp.reload(PrepareLods)
|
||||||
|
print("L1960 Tools: Reloaded multifiles")
|
||||||
|
else:
|
||||||
|
from . import CubeProjection
|
||||||
|
from . import FixMaterials
|
||||||
|
from . import PrepareLods
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
from . CubeProjection import MESH_OT_add_auto_cube_projection, MESH_OT_add_modifier_to_mesh
|
||||||
|
from . FixMaterials import MESH_OT_fix_material_names
|
||||||
|
from . PrepareLods import MESH_OT_prepare_lods_decimate
|
||||||
|
|
||||||
|
class L1960_PT_tools(bpy.types.Panel):
|
||||||
|
pass
|
||||||
|
#where to add the panel
|
||||||
|
bl_space_type = "VIEW_3D"
|
||||||
|
bl_region_type = "UI"
|
||||||
|
|
||||||
|
#add labels
|
||||||
|
bl_label = "1960-Life Tools"
|
||||||
|
bl_category = "1960-Life"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
"""define the layout of the panel"""
|
||||||
|
box = self.layout.box()
|
||||||
|
# UV-Project helper
|
||||||
|
box.label(text="UV-Projection")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("mesh.add_auto_cube_projection", text="Set up Projectors")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("mesh.add_modifier_to_mesh", text="Add Modifier to Mesh")
|
||||||
|
self.layout.separator()
|
||||||
|
box = self.layout.box()
|
||||||
|
# Materials helper
|
||||||
|
box.label(text="Materials")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("mesh.fix_material_names", text="Fix Material Name´s")
|
||||||
|
self.layout.separator()
|
||||||
|
box = self.layout.box()
|
||||||
|
# Generate LODs
|
||||||
|
box.label(text="LOD´s")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("mesh.prepare_lods_decimate", text="Create LOD´s")
|
||||||
|
box.prop(context.scene, "lod_slider", text="LOD Number")
|
||||||
|
###############################
|
||||||
|
# Enfusion Blender Tools Linked
|
||||||
|
box = self.layout.box()
|
||||||
|
box.label(text="EBT Linked")
|
||||||
|
row = box.row()
|
||||||
|
row.operator("view3d.ebt_sort", text="Sort Objects")
|
||||||
|
# colliders setup is allowed in both OBJECT and EDIT mode
|
||||||
|
row = box.row()
|
||||||
|
row.operator("view3d.ebt_colliders_setup", text=" Colliders Setup")
|
||||||
|
row = box.row()
|
||||||
|
# Light Setup
|
||||||
|
row.operator("view3d.ebt_setup_light", text=" Light Setup")
|
||||||
|
row = box.row()
|
||||||
|
col = row.column(align=True)
|
||||||
|
# Update Materials
|
||||||
|
col.operator("scene.ebt_update_enf_materials",)
|
||||||
|
row = box.row()
|
||||||
|
col = row.column(align=True)
|
||||||
|
|
||||||
|
|
||||||
|
#register the panel with blender
|
||||||
|
modules = [ L1960_PT_tools,
|
||||||
|
MESH_OT_add_auto_cube_projection,
|
||||||
|
MESH_OT_add_modifier_to_mesh,
|
||||||
|
MESH_OT_fix_material_names,
|
||||||
|
MESH_OT_prepare_lods_decimate
|
||||||
|
]
|
||||||
|
|
||||||
|
def register():
|
||||||
|
for mod in modules:
|
||||||
|
bpy.utils.register_class(mod)
|
||||||
|
|
||||||
|
bpy.types.Scene.lod_slider = bpy.props.IntProperty(name="LOD Number", default=3, min=0, max=10)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
for mod in modules:
|
||||||
|
bpy.utils.unregister_class(mod)
|
||||||
|
|
||||||
|
del bpy.types.Scene.lod_slider
|
||||||
|
|
||||||
|
if __name__== "__main__":
|
||||||
|
register()
|
||||||
Reference in New Issue
Block a user