More Fixes
- Fixes an other error in the updater due to urllib not being imported and used correctly. - Small Atlas Texturing fixes and UI Improvements.
This commit is contained in:
@@ -29,6 +29,24 @@ def register() -> None:
|
|||||||
description=t("MergeArmatures.selected_armature.label")
|
description=t("MergeArmatures.selected_armature.label")
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
register_property((bpy.types.Object, "material_group_expanded", bpy.props.BoolProperty(
|
||||||
|
name="Expand Material Group",
|
||||||
|
description="Show/hide materials for this mesh",
|
||||||
|
default=False
|
||||||
|
)))
|
||||||
|
|
||||||
|
register_property((bpy.types.Material, "material_expanded", bpy.props.BoolProperty(
|
||||||
|
name="Expand Material",
|
||||||
|
description="Show/hide material properties",
|
||||||
|
default=False
|
||||||
|
)))
|
||||||
|
|
||||||
|
register_property((bpy.types.Material, "include_in_atlas", bpy.props.BoolProperty(
|
||||||
|
name=t("TextureAtlas.include_in_atlas"),
|
||||||
|
description=t("TextureAtlas.include_in_atlas_desc"),
|
||||||
|
default=True
|
||||||
|
)))
|
||||||
|
|
||||||
register_property((bpy.types.Scene, "merge_armature_apply_transforms", bpy.props.BoolProperty(
|
register_property((bpy.types.Scene, "merge_armature_apply_transforms", bpy.props.BoolProperty(
|
||||||
default=False,
|
default=False,
|
||||||
name=t("MergeArmature.merge_armatures.apply_transforms.label"),
|
name=t("MergeArmature.merge_armatures.apply_transforms.label"),
|
||||||
|
|||||||
+4
-3
@@ -7,6 +7,7 @@ import shutil
|
|||||||
import pathlib
|
import pathlib
|
||||||
import zipfile
|
import zipfile
|
||||||
import time
|
import time
|
||||||
|
from urllib import request, error
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
from ..functions.translations import t
|
from ..functions.translations import t
|
||||||
@@ -140,9 +141,9 @@ def get_github_releases() -> bool:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
ssl._create_default_https_context = ssl._create_unverified_context
|
ssl._create_default_https_context = ssl._create_unverified_context
|
||||||
with urllib.request.urlopen(f'https://api.github.com/repos/{GITHUB_REPO}/releases') as url:
|
with request.urlopen(f'https://api.github.com/repos/{GITHUB_REPO}/releases') as url:
|
||||||
data = json.loads(url.read().decode())
|
data = json.loads(url.read().decode())
|
||||||
except urllib.error.URLError:
|
except error.URLError:
|
||||||
print('URL ERROR')
|
print('URL ERROR')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -214,7 +215,7 @@ def download_file(update_url: str) -> None:
|
|||||||
try:
|
try:
|
||||||
ssl._create_default_https_context = ssl._create_unverified_context
|
ssl._create_default_https_context = ssl._create_unverified_context
|
||||||
urllib.request.urlretrieve(update_url, update_zip_file)
|
urllib.request.urlretrieve(update_url, update_zip_file)
|
||||||
except urllib.error.URLError:
|
except error.URLError:
|
||||||
finish_update(error=t('download_file.cantConnect'))
|
finish_update(error=t('download_file.cantConnect'))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,20 @@ from ..core.common import SceneMatClass, MaterialListBool
|
|||||||
from ..core.packer.rectangle_packer import MaterialImageList, BinPacker
|
from ..core.packer.rectangle_packer import MaterialImageList, BinPacker
|
||||||
from ..functions.translations import t
|
from ..functions.translations import t
|
||||||
|
|
||||||
|
class MaterialImageList:
|
||||||
|
def __init__(self):
|
||||||
|
self.albedo: Image = None
|
||||||
|
self.normal: Image = None
|
||||||
|
self.emission: Image = None
|
||||||
|
self.ambient_occlusion: Image = None
|
||||||
|
self.height: Image = None
|
||||||
|
self.roughness: Image = None
|
||||||
|
self.material: Material = None
|
||||||
|
self.parent_mesh: Object = None
|
||||||
|
self.w: int = 0
|
||||||
|
self.h: int = 0
|
||||||
|
self.fit = None
|
||||||
|
|
||||||
def scale_images_to_largest(images:list[Image]) -> set:
|
def scale_images_to_largest(images:list[Image]) -> set:
|
||||||
print([image.name for image in images])
|
print([image.name for image in images])
|
||||||
x: int=0
|
x: int=0
|
||||||
@@ -38,65 +52,68 @@ def MaterialImageList_to_Image_list(classitem: MaterialImageList) -> list[Image]
|
|||||||
|
|
||||||
|
|
||||||
def get_material_images_from_scene(context: Context) -> list[MaterialImageList]:
|
def get_material_images_from_scene(context: Context) -> list[MaterialImageList]:
|
||||||
mat: SceneMatClass = None
|
|
||||||
material_image_list: list[MaterialImageList] = []
|
material_image_list: list[MaterialImageList] = []
|
||||||
for mat in context.scene.materials:
|
|
||||||
new_mat_image_item: MaterialImageList = MaterialImageList()
|
|
||||||
try:
|
|
||||||
new_mat_image_item.albedo = bpy.data.images[mat.mat.texture_atlas_albedo]
|
|
||||||
except Exception as e:
|
|
||||||
name: str = mat.mat.name+"_albedo_replacement"
|
|
||||||
if name in bpy.data.images:
|
|
||||||
bpy.data.images.remove(image=bpy.data.images[name],do_unlink=True)
|
|
||||||
new_mat_image_item.albedo = bpy.data.images.new(name=name,width=32,height=32, alpha=True)
|
|
||||||
new_mat_image_item.albedo.pixels[:] = numpy.tile(numpy.array([0.0,0.0,0.0,1.0]), 32*32)
|
|
||||||
try:
|
|
||||||
new_mat_image_item.normal = bpy.data.images[mat.mat.texture_atlas_normal]
|
|
||||||
except Exception:
|
|
||||||
name: str = mat.mat.name+"_normal_replacement"
|
|
||||||
if name in bpy.data.images:
|
|
||||||
bpy.data.images.remove(image=bpy.data.images[name],do_unlink=True)
|
|
||||||
new_mat_image_item.normal = bpy.data.images.new(name=name,width=32,height=32, alpha=True)
|
|
||||||
new_mat_image_item.normal.pixels[:] = numpy.tile(numpy.array([0.5,0.5,1.0,1.0]), 32*32)
|
|
||||||
try:
|
|
||||||
new_mat_image_item.emission = bpy.data.images[mat.mat.texture_atlas_emission]
|
|
||||||
except Exception:
|
|
||||||
name: str = mat.mat.name+"_emission_replacement"
|
|
||||||
if name in bpy.data.images:
|
|
||||||
bpy.data.images.remove(image=bpy.data.images[name],do_unlink=True)
|
|
||||||
new_mat_image_item.emission = bpy.data.images.new(name=name,width=32,height=32, alpha=True)
|
|
||||||
new_mat_image_item.emission.pixels[:] = numpy.tile(numpy.array([0.0,0.0,0.0,1.0]), 32*32)
|
|
||||||
|
|
||||||
try:
|
for obj in context.scene.objects:
|
||||||
new_mat_image_item.ambient_occlusion = bpy.data.images[mat.mat.texture_atlas_ambient_occlusion]
|
if obj.type == 'MESH':
|
||||||
except Exception:
|
for mat_slot in obj.material_slots:
|
||||||
name: str = mat.mat.name+"_ambient_occlusion_replacement"
|
if mat_slot.material and mat_slot.material.include_in_atlas:
|
||||||
if name in bpy.data.images:
|
new_mat_image_item = MaterialImageList()
|
||||||
bpy.data.images.remove(image=bpy.data.images[name],do_unlink=True)
|
try:
|
||||||
new_mat_image_item.ambient_occlusion = bpy.data.images.new(name=name,width=32,height=32, alpha=True)
|
new_mat_image_item.albedo = bpy.data.images[mat_slot.material.texture_atlas_albedo]
|
||||||
new_mat_image_item.ambient_occlusion.pixels[:] = numpy.tile(numpy.array([1.0,1.0,1.0,1.0]), 32*32)
|
except Exception:
|
||||||
try:
|
name = mat_slot.material.name + "_albedo_replacement"
|
||||||
new_mat_image_item.height = bpy.data.images[mat.mat.texture_atlas_height]
|
if name in bpy.data.images:
|
||||||
except Exception:
|
bpy.data.images.remove(image=bpy.data.images[name], do_unlink=True)
|
||||||
name: str = mat.mat.name+"_height_replacement"
|
new_mat_image_item.albedo = bpy.data.images.new(name=name, width=32, height=32, alpha=True)
|
||||||
if name in bpy.data.images:
|
new_mat_image_item.albedo.pixels[:] = numpy.tile(numpy.array([0.0,0.0,0.0,1.0]), 32*32)
|
||||||
bpy.data.images.remove(image=bpy.data.images[name],do_unlink=True)
|
try:
|
||||||
new_mat_image_item.height = bpy.data.images.new(name=name,width=32,height=32, alpha=True)
|
new_mat_image_item.normal = bpy.data.images[mat_slot.material.texture_atlas_normal]
|
||||||
new_mat_image_item.height.pixels[:] = numpy.tile(numpy.array([0.5,0.5,0.5,1.0]), 32*32)
|
except Exception:
|
||||||
|
name = mat_slot.material.name + "_normal_replacement"
|
||||||
|
if name in bpy.data.images:
|
||||||
|
bpy.data.images.remove(image=bpy.data.images[name], do_unlink=True)
|
||||||
|
new_mat_image_item.normal = bpy.data.images.new(name=name, width=32, height=32, alpha=True)
|
||||||
|
new_mat_image_item.normal.pixels[:] = numpy.tile(numpy.array([0.5,0.5,1.0,1.0]), 32*32)
|
||||||
|
try:
|
||||||
|
new_mat_image_item.emission = bpy.data.images[mat_slot.material.texture_atlas_emission]
|
||||||
|
except Exception:
|
||||||
|
name = mat_slot.material.name + "_emission_replacement"
|
||||||
|
if name in bpy.data.images:
|
||||||
|
bpy.data.images.remove(image=bpy.data.images[name], do_unlink=True)
|
||||||
|
new_mat_image_item.emission = bpy.data.images.new(name=name, width=32, height=32, alpha=True)
|
||||||
|
new_mat_image_item.emission.pixels[:] = numpy.tile(numpy.array([0.0,0.0,0.0,1.0]), 32*32)
|
||||||
|
try:
|
||||||
|
new_mat_image_item.ambient_occlusion = bpy.data.images[mat_slot.material.texture_atlas_ambient_occlusion]
|
||||||
|
except Exception:
|
||||||
|
name = mat_slot.material.name + "_ambient_occlusion_replacement"
|
||||||
|
if name in bpy.data.images:
|
||||||
|
bpy.data.images.remove(image=bpy.data.images[name], do_unlink=True)
|
||||||
|
new_mat_image_item.ambient_occlusion = bpy.data.images.new(name=name, width=32, height=32, alpha=True)
|
||||||
|
new_mat_image_item.ambient_occlusion.pixels[:] = numpy.tile(numpy.array([1.0,1.0,1.0,1.0]), 32*32)
|
||||||
|
try:
|
||||||
|
new_mat_image_item.height = bpy.data.images[mat_slot.material.texture_atlas_height]
|
||||||
|
except Exception:
|
||||||
|
name = mat_slot.material.name + "_height_replacement"
|
||||||
|
if name in bpy.data.images:
|
||||||
|
bpy.data.images.remove(image=bpy.data.images[name], do_unlink=True)
|
||||||
|
new_mat_image_item.height = bpy.data.images.new(name=name, width=32, height=32, alpha=True)
|
||||||
|
new_mat_image_item.height.pixels[:] = numpy.tile(numpy.array([0.5,0.5,0.5,1.0]), 32*32)
|
||||||
|
try:
|
||||||
|
new_mat_image_item.roughness = bpy.data.images[mat_slot.material.texture_atlas_roughness]
|
||||||
|
except Exception:
|
||||||
|
name = mat_slot.material.name + "_roughness_replacement"
|
||||||
|
if name in bpy.data.images:
|
||||||
|
bpy.data.images.remove(image=bpy.data.images[name], do_unlink=True)
|
||||||
|
new_mat_image_item.roughness = bpy.data.images.new(name=name, width=32, height=32, alpha=True)
|
||||||
|
new_mat_image_item.roughness.pixels[:] = numpy.tile(numpy.array([1.0,1.0,1.0,0.0]), 32*32)
|
||||||
|
|
||||||
|
new_mat_image_item.material = mat_slot.material
|
||||||
|
new_mat_image_item.parent_mesh = obj
|
||||||
|
material_image_list.append(new_mat_image_item)
|
||||||
|
|
||||||
try:
|
|
||||||
new_mat_image_item.roughness = bpy.data.images[mat.mat.texture_atlas_roughness]
|
|
||||||
except Exception:
|
|
||||||
name: str = mat.mat.name+"_roughness_replacement"
|
|
||||||
if name in bpy.data.images:
|
|
||||||
bpy.data.images.remove(image=bpy.data.images[name],do_unlink=True)
|
|
||||||
new_mat_image_item.roughness = bpy.data.images.new(name=name,width=32,height=32, alpha=True)
|
|
||||||
new_mat_image_item.roughness.pixels[:] = numpy.tile(numpy.array([1.0,1.0,1.0,0.0]), 32*32)
|
|
||||||
new_mat_image_item.material = mat.mat
|
|
||||||
material_image_list.append(new_mat_image_item)
|
|
||||||
return material_image_list
|
return material_image_list
|
||||||
|
|
||||||
|
|
||||||
def prep_images_in_scene(context: Context) -> list[MaterialImageList]:
|
def prep_images_in_scene(context: Context) -> list[MaterialImageList]:
|
||||||
preped_images: list[MaterialImageList] = get_material_images_from_scene(context)
|
preped_images: list[MaterialImageList] = get_material_images_from_scene(context)
|
||||||
for MaterialImageClass in preped_images:
|
for MaterialImageClass in preped_images:
|
||||||
@@ -124,13 +141,16 @@ class AvatarToolKit_OT_AtlasMaterials(Operator):
|
|||||||
|
|
||||||
def execute(self, context: Context) -> set:
|
def execute(self, context: Context) -> set:
|
||||||
try:
|
try:
|
||||||
mat_images: list[MaterialImageList] = prep_images_in_scene(context)
|
# Only get materials marked for atlas creation
|
||||||
|
mat_images: list[MaterialImageList] = [m for m in prep_images_in_scene(context) if m.material.include_in_atlas]
|
||||||
|
|
||||||
|
if not mat_images:
|
||||||
|
self.report({'WARNING'}, t("TextureAtlas.no_materials_selected"))
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
packer: BinPacker = BinPacker(mat_images)
|
packer: BinPacker = BinPacker(mat_images)
|
||||||
|
|
||||||
mat_images = packer.fit()
|
mat_images = packer.fit()
|
||||||
|
|
||||||
|
|
||||||
size: list[int] = [max([matimg.fit.w + matimg.albedo.size[0] for matimg in mat_images]),
|
size: list[int] = [max([matimg.fit.w + matimg.albedo.size[0] for matimg in mat_images]),
|
||||||
max([matimg.fit.h + matimg.albedo.size[1] for matimg in mat_images])]
|
max([matimg.fit.h + matimg.albedo.size[1] for matimg in mat_images])]
|
||||||
print([matimg.fit.w + matimg.albedo.size[1] for matimg in mat_images])
|
print([matimg.fit.w + matimg.albedo.size[1] for matimg in mat_images])
|
||||||
@@ -144,18 +164,17 @@ class AvatarToolKit_OT_AtlasMaterials(Operator):
|
|||||||
h: int = int(mat.albedo.size[1])
|
h: int = int(mat.albedo.size[1])
|
||||||
|
|
||||||
for obj in bpy.data.objects:
|
for obj in bpy.data.objects:
|
||||||
mesh: Mesh = obj.data
|
if obj.type == 'MESH':
|
||||||
|
mesh: Mesh = obj.data
|
||||||
|
for layer in mesh.polygons:
|
||||||
for layer in mesh.polygons:
|
if obj.material_slots[layer.material_index].material:
|
||||||
if obj.material_slots[layer.material_index].material:
|
if obj.material_slots[layer.material_index].material == mat.material:
|
||||||
if obj.material_slots[layer.material_index].material == mat.material:
|
for loop_idx in layer.loop_indices:
|
||||||
for loop_idx in layer.loop_indices:
|
layer_loops: MeshUVLoopLayer
|
||||||
layer_loops: MeshUVLoopLayer
|
for layer_loops in mesh.uv_layers:
|
||||||
for layer_loops in mesh.uv_layers:
|
uv_item: Float2AttributeValue = layer_loops.uv[loop_idx]
|
||||||
uv_item: Float2AttributeValue = layer_loops.uv[loop_idx]
|
uv_item.vector.x = (uv_item.vector.x*(w/size[0]))+(x/size[0])
|
||||||
uv_item.vector.x = (uv_item.vector.x*(w/size[0]))+(x/size[0])
|
uv_item.vector.y = (uv_item.vector.y*(h/size[1]))+(y/size[1])
|
||||||
uv_item.vector.y = (uv_item.vector.y*(h/size[1]))+(y/size[1])
|
|
||||||
|
|
||||||
for type in ["albedo","normal", "emission","ambient_occlusion","height", "roughness"]:
|
for type in ["albedo","normal", "emission","ambient_occlusion","height", "roughness"]:
|
||||||
new_image_name: str= "Atlas_"+type+"_"+context.scene.name+"_"+Path(bpy.data.filepath).stem
|
new_image_name: str= "Atlas_"+type+"_"+context.scene.name+"_"+Path(bpy.data.filepath).stem
|
||||||
@@ -167,7 +186,6 @@ class AvatarToolKit_OT_AtlasMaterials(Operator):
|
|||||||
|
|
||||||
canvas: Image = bpy.data.images.new(name=new_image_name, width=int(size[0]),height=int(size[1]), alpha=True)
|
canvas: Image = bpy.data.images.new(name=new_image_name, width=int(size[0]),height=int(size[1]), alpha=True)
|
||||||
c_w = canvas.size[0]
|
c_w = canvas.size[0]
|
||||||
#c_h = canvas.size[1]
|
|
||||||
canvas_pixels: list[float] = list(canvas.pixels[:])
|
canvas_pixels: list[float] = list(canvas.pixels[:])
|
||||||
for mat in mat_images:
|
for mat in mat_images:
|
||||||
x: int = int(mat.fit.x)
|
x: int = int(mat.fit.x)
|
||||||
@@ -199,14 +217,12 @@ class AvatarToolKit_OT_AtlasMaterials(Operator):
|
|||||||
canvas.save(filepath=os.path.join(os.path.dirname(bpy.data.filepath),new_image_name+".png"))
|
canvas.save(filepath=os.path.join(os.path.dirname(bpy.data.filepath),new_image_name+".png"))
|
||||||
exec("atlased_mat."+type+" = canvas")
|
exec("atlased_mat."+type+" = canvas")
|
||||||
|
|
||||||
|
#I am sorry for the amount of nodes I'm instanciating here and their values.
|
||||||
|
#This is so that the nodes look pretty in the UI, which I think looks kinda nice. - @989onan
|
||||||
atlased_mat.material = bpy.data.materials.new(name="Atlas_Final_"+bpy.context.scene.name+"_"+Path(bpy.data.filepath).stem)
|
atlased_mat.material = bpy.data.materials.new(name="Atlas_Final_"+bpy.context.scene.name+"_"+Path(bpy.data.filepath).stem)
|
||||||
atlased_mat.material.use_nodes = True
|
atlased_mat.material.use_nodes = True
|
||||||
atlased_mat.material.node_tree.nodes.clear()
|
atlased_mat.material.node_tree.nodes.clear()
|
||||||
|
|
||||||
|
|
||||||
#I am sorry for the amount of nodes I'm instanciating here and their values.
|
|
||||||
#This is so that the nodes look pretty in the UI, which I think looks kinda nice. - @989onan
|
|
||||||
principled_node: ShaderNodeBsdfPrincipled = atlased_mat.material.node_tree.nodes.new(type="ShaderNodeBsdfPrincipled")
|
principled_node: ShaderNodeBsdfPrincipled = atlased_mat.material.node_tree.nodes.new(type="ShaderNodeBsdfPrincipled")
|
||||||
principled_node.location.x = 7.29706335067749
|
principled_node.location.x = 7.29706335067749
|
||||||
principled_node.location.y = 298.918212890625
|
principled_node.location.y = 298.918212890625
|
||||||
@@ -258,12 +274,13 @@ class AvatarToolKit_OT_AtlasMaterials(Operator):
|
|||||||
atlased_mat.material.node_tree.links.new(output_node.inputs["Surface"], principled_node.outputs["BSDF"])
|
atlased_mat.material.node_tree.links.new(output_node.inputs["Surface"], principled_node.outputs["BSDF"])
|
||||||
atlased_mat.material.node_tree.links.new(normal_map_node.inputs["Color"], normal_node.outputs["Color"])
|
atlased_mat.material.node_tree.links.new(normal_map_node.inputs["Color"], normal_node.outputs["Color"])
|
||||||
|
|
||||||
|
# Only update materials for meshes that had materials included in the atlas
|
||||||
for obj in context.scene.objects:
|
for obj in context.scene.objects:
|
||||||
mesh: Mesh = obj.data
|
if obj.type == 'MESH':
|
||||||
mesh.materials.clear()
|
if any(mat_slot.material and mat_slot.material.include_in_atlas for mat_slot in obj.material_slots):
|
||||||
|
mesh: Mesh = obj.data
|
||||||
mesh.materials.append(atlased_mat.material)
|
mesh.materials.clear()
|
||||||
|
mesh.materials.append(atlased_mat.material)
|
||||||
|
|
||||||
self.report({'INFO'}, t("TextureAtlas.atlas_completed"))
|
self.report({'INFO'}, t("TextureAtlas.atlas_completed"))
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -272,4 +289,3 @@ class AvatarToolKit_OT_AtlasMaterials(Operator):
|
|||||||
raise e
|
raise e
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
+28
-20
@@ -40,23 +40,26 @@ class AvatarToolKit_UL_MaterialTextureAtlasProperties(UIList):
|
|||||||
bl_space_type = 'VIEW_3D'
|
bl_space_type = 'VIEW_3D'
|
||||||
bl_region_type = 'UI'
|
bl_region_type = 'UI'
|
||||||
|
|
||||||
def draw_item(self , context: Context, layout: UILayout, data: bpy.types.Object, item:SceneMatClass, icon, active_data, active_propname, index):
|
def draw_item(self, context: Context, layout: UILayout, data: Object, item: SceneMatClass, icon, active_data, active_propname, index):
|
||||||
if context.scene.texture_atlas_Has_Mat_List_Shown:
|
if context.scene.texture_atlas_Has_Mat_List_Shown:
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
row = box.row()
|
row = box.row()
|
||||||
row.label(text=item.mat.name, icon = "MATERIAL")
|
|
||||||
col = box.row()
|
# Draw material entry
|
||||||
col.prop(item.mat, "texture_atlas_albedo")
|
row.prop(item.mat, "material_expanded",
|
||||||
col = box.row()
|
text=item.mat.name,
|
||||||
col.prop(item.mat, "texture_atlas_normal")
|
icon='DOWNARROW_HLT' if item.mat.material_expanded else 'RIGHTARROW',
|
||||||
col = box.row()
|
emboss=False)
|
||||||
col.prop(item.mat, "texture_atlas_emission")
|
row.prop(item.mat, "include_in_atlas", text="")
|
||||||
col = box.row()
|
|
||||||
col.prop(item.mat, "texture_atlas_ambient_occlusion")
|
if item.mat.material_expanded and item.mat.include_in_atlas:
|
||||||
col = box.row()
|
col = box.column(align=True)
|
||||||
col.prop(item.mat, "texture_atlas_height")
|
col.prop(item.mat, "texture_atlas_albedo")
|
||||||
col = box.row()
|
col.prop(item.mat, "texture_atlas_normal")
|
||||||
col.prop(item.mat, "texture_atlas_roughness")
|
col.prop(item.mat, "texture_atlas_emission")
|
||||||
|
col.prop(item.mat, "texture_atlas_ambient_occlusion")
|
||||||
|
col.prop(item.mat, "texture_atlas_height")
|
||||||
|
col.prop(item.mat, "texture_atlas_roughness")
|
||||||
|
|
||||||
@register_wrap
|
@register_wrap
|
||||||
class AvatarToolKit_PT_TextureAtlasPanel(Panel):
|
class AvatarToolKit_PT_TextureAtlasPanel(Panel):
|
||||||
@@ -74,7 +77,6 @@ class AvatarToolKit_PT_TextureAtlasPanel(Panel):
|
|||||||
|
|
||||||
if armature:
|
if armature:
|
||||||
layout.label(text=t("TextureAtlas.label"), icon='TEXTURE')
|
layout.label(text=t("TextureAtlas.label"), icon='TEXTURE')
|
||||||
|
|
||||||
layout.separator(factor=0.5)
|
layout.separator(factor=0.5)
|
||||||
|
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
@@ -86,16 +88,22 @@ class AvatarToolKit_PT_TextureAtlasPanel(Panel):
|
|||||||
|
|
||||||
if context.scene.texture_atlas_Has_Mat_List_Shown:
|
if context.scene.texture_atlas_Has_Mat_List_Shown:
|
||||||
row = box.row()
|
row = box.row()
|
||||||
row.template_list(AvatarToolKit_UL_MaterialTextureAtlasProperties.bl_idname, 'material_list',
|
row.template_list(AvatarToolKit_UL_MaterialTextureAtlasProperties.bl_idname,
|
||||||
context.scene, 'materials', context.scene, 'texture_atlas_material_index',
|
'material_list',
|
||||||
rows=12, type='DEFAULT')
|
context.scene,
|
||||||
|
'materials',
|
||||||
|
context.scene,
|
||||||
|
'texture_atlas_material_index',
|
||||||
|
rows=12,
|
||||||
|
type='DEFAULT')
|
||||||
|
|
||||||
layout.separator(factor=1.0)
|
layout.separator(factor=1.0)
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.scale_y = 1.5
|
row.scale_y = 1.5
|
||||||
row.operator(AvatarToolKit_OT_AtlasMaterials.bl_idname, text=t("TextureAtlas.atlas_materials"), icon='NODE_TEXTURE')
|
row.operator(AvatarToolKit_OT_AtlasMaterials.bl_idname,
|
||||||
|
text=t("TextureAtlas.atlas_materials"),
|
||||||
|
icon='NODE_TEXTURE')
|
||||||
else:
|
else:
|
||||||
layout.label(text=t("Tools.select_armature"), icon='ERROR')
|
layout.label(text=t("Tools.select_armature"), icon='ERROR')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user