You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Blender-TexTools/op_texel_density_get.py

139 lines
4.3 KiB
Python

import bpy
import bmesh
import operator
import math
from . import utilities_texel
class op(bpy.types.Operator):
4 years ago
bl_idname = "uv.textools_texel_density_get"
bl_label = "Get Texel size"
bl_description = "Get Pixel per unit ratio or Texel density"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
#Only in UV editor mode
if bpy.context.area.type != 'IMAGE_EDITOR':
return False
4 years ago
if not bpy.context.active_object:
return False
if len(bpy.context.selected_objects) == 0:
return False
4 years ago
if bpy.context.active_object.type != 'MESH':
return False
4 years ago
if not bpy.context.object.data.uv_layers:
return False
4 years ago
# if bpy.context.object.mode == 'EDIT':
# # In edit mode requires face select mode
# if bpy.context.scene.tool_settings.mesh_select_mode[2] == False:
# return False
4 years ago
return True
4 years ago
def execute(self, context):
get_texel_density(
self,
context
)
return {'FINISHED'}
def get_texel_density(self, context):
4 years ago
print("Get texel density")
edit_mode = bpy.context.object.mode == 'EDIT'
object_faces = utilities_texel.get_selected_object_faces()
# Warning: No valid input objects
if len(object_faces) == 0:
self.report({'ERROR_INVALID_INPUT'}, "No UV maps or meshes selected" )
return
print("obj faces groups {}".format(len(object_faces)))
# Collect Images / textures
object_images = {}
for obj in object_faces:
image = utilities_texel.get_object_texture_image(obj)
if image:
object_images[obj] = image
fallback_image = None
for area in bpy.context.screen.areas:
if area.type == 'IMAGE_EDITOR':
fallback_image = area.spaces[0].image
break
4 years ago
sum_area_vt = 0
sum_area_uv = 0
# Get area for each triangle in view and UV
for obj in object_faces:
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = obj
obj.select_set( state = True, view_layer = None)
# Find image of object
if obj in object_images:
image = object_images[obj]
else:
image = fallback_image
4 years ago
if image:
bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(obj.data)
uv_layers = bm.loops.layers.uv.verify()
bm.faces.ensure_lookup_table()
for index in object_faces[obj]:
face = bm.faces[index]
# Triangle Verts
triangle_uv = [loop[uv_layers].uv for loop in face.loops ]
triangle_vt = [vert.co for vert in face.verts]
#Triangle Areas
face_area_vt = utilities_texel.get_area_triangle(
triangle_vt[0],
triangle_vt[1],
triangle_vt[2]
)
face_area_uv = utilities_texel.get_area_triangle_uv(
triangle_uv[0],
triangle_uv[1],
triangle_uv[2],
image.size[0],
image.size[1]
)
sum_area_vt+= math.sqrt( face_area_vt )
sum_area_uv+= math.sqrt( face_area_uv ) * min(image.size[0], image.size[1])
# Restore selection
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
for obj in object_faces:
obj.select_set( state = True, view_layer = None)
bpy.context.view_layer.objects.active = list(object_faces.keys())[0]
if edit_mode:
bpy.ops.object.mode_set(mode='EDIT')
# print("Sum verts area {}".format(sum_area_vt))
# print("Sum texture area {}".format(sum_area_uv))
if sum_area_uv == 0 or sum_area_vt == 0:
bpy.context.scene.texToolsSettings.texel_density = 0
else:
bpy.context.scene.texToolsSettings.texel_density = sum_area_uv / sum_area_vt
bpy.utils.register_class(op)
4 years ago