From 9424045976be48c538a326a77c01e1b6c370c831 Mon Sep 17 00:00:00 2001 From: satabol Date: Wed, 8 Nov 2023 22:51:03 +0300 Subject: [PATCH 1/2] fix #5053. Node Find UV Coord on Surface has wrong object on UVMap out. 1. Now count of out sockets equals to count of input objects 2. Append Matrix socket of objects --- index.yaml | 2 +- menus/full_by_data_type.yaml | 2 +- menus/full_nortikin.yaml | 2 +- nodes/object_nodes/points_from_uv_to_mesh.py | 132 ++++++++------- old_nodes/points_from_uv_to_mesh_mk2.py | 164 +++++++++++++++++++ 5 files changed, 238 insertions(+), 64 deletions(-) create mode 100644 old_nodes/points_from_uv_to_mesh_mk2.py diff --git a/index.yaml b/index.yaml index e6edaf5752..5d4d66f4f6 100644 --- a/index.yaml +++ b/index.yaml @@ -767,7 +767,7 @@ - SvSetCustomUVMap - SvUVtextureNode - SvMeshUVColorNode - - SvUVPointonMeshNodeMK2 + - SvUVPointonMeshNodeMK3 - SvSampleUVColorNode - SvArmaturePropsNode - SvLatticePropsNode diff --git a/menus/full_by_data_type.yaml b/menus/full_by_data_type.yaml index e905e2ae10..b69cc76e58 100644 --- a/menus/full_by_data_type.yaml +++ b/menus/full_by_data_type.yaml @@ -796,7 +796,7 @@ - SvSetCustomUVMap - SvUVtextureNode - SvMeshUVColorNode - - SvUVPointonMeshNodeMK2 + - SvUVPointonMeshNodeMK3 - SvSampleUVColorNode - SvArmaturePropsNode - SvLatticePropsNode diff --git a/menus/full_nortikin.yaml b/menus/full_nortikin.yaml index f83e340cec..e8d772cf36 100644 --- a/menus/full_nortikin.yaml +++ b/menus/full_nortikin.yaml @@ -913,7 +913,7 @@ - SvSetCustomUVMap - SvUVtextureNode - SvMeshUVColorNode - - SvUVPointonMeshNodeMK2 + - SvUVPointonMeshNodeMK3 - SvSampleUVColorNode - SvArmaturePropsNode - SvLatticePropsNode diff --git a/nodes/object_nodes/points_from_uv_to_mesh.py b/nodes/object_nodes/points_from_uv_to_mesh.py index e884f94b23..7b27722561 100644 --- a/nodes/object_nodes/points_from_uv_to_mesh.py +++ b/nodes/object_nodes/points_from_uv_to_mesh.py @@ -18,13 +18,14 @@ import bpy import bmesh +from mathutils import Matrix, Vector from mathutils.bvhtree import BVHTree from mathutils.geometry import barycentric_transform import numpy as np from bpy.props import BoolProperty, StringProperty, FloatVectorProperty, EnumProperty from sverchok.node_tree import SverchCustomTreeNode -from sverchok.data_structure import (updateNode) +from sverchok.data_structure import updateNode, zip_long_repeat def UV(self, bm, uv_layer): @@ -47,9 +48,9 @@ def UV(self, bm, uv_layer): return [vertices_new, polygons_new] -class SvUVPointonMeshNodeMK2(SverchCustomTreeNode, bpy.types.Node): +class SvUVPointonMeshNodeMK3(SverchCustomTreeNode, bpy.types.Node): ''' Transform vectors from UV space to Object space ''' - bl_idname = 'SvUVPointonMeshNodeMK2' + bl_idname = 'SvUVPointonMeshNodeMK3' bl_label = 'Find UV Coord on Surface' bl_icon = 'GROUP_UVS' is_scene_dependent = True @@ -88,77 +89,86 @@ def sv_draw_buttons(self, context, layout): def sv_init(self, context): si, so = self.inputs.new, self.outputs.new - si('SvObjectSocket', 'Mesh Object') + si('SvMatrixSocket', 'Object Matrix') + si('SvObjectSocket', 'Object Mesh') si('SvVerticesSocket', 'Point on UV') so('SvVerticesSocket', 'Point on mesh') so('SvVerticesSocket', 'UVMapVert') so('SvStringsSocket', 'UVMapPoly') def process(self): - Object, PointsUV = self.inputs + ObjectMatrixes, Object, PointsUV = self.inputs Pom, uvV, uvP = self.outputs - obj = Object.sv_get()[0] # triangulate faces - if not obj.data.uv_layers: - raise Exception(f"Object '{obj.data.name}' has no UV Maps. Open Properties->Data->UV Maps and check list of UV Maps.") - - # get all UV Maps name in object UV Maps list - uv_layer_active_render_name = obj.data.uv_layers[0].name - for uv in obj.data.uv_layers: - if uv.active_render==True: - uv_layer_active_render_name = uv.name # get UV Map name active render (photo mark) - break - - bm = bmesh.new() - if self.apply_modifiers: - # apply modifiers and build mesh after it - sv_depsgraph = bpy.context.evaluated_depsgraph_get() - scene_object = sv_depsgraph.objects[ obj.name ] - object_to_mesh = scene_object.to_mesh(preserve_all_data_layers=True, depsgraph=sv_depsgraph) - bm.from_mesh(object_to_mesh) - scene_object.to_mesh_clear() - else: - # get mesh of original object from scene - bm.from_mesh(obj.data) - - uv_layer_active = bm.loops.layers.uv.active - uv_layer_active_render = obj.data.uv_layers[0] - for uv in bm.loops.layers.uv: - if uv.name==uv_layer_active_render_name: - uv_layer_active_render = uv - break - - if self.uv_select_mode=='active_item': - uv_layer = uv_layer_active - else: #if self.uv_select_mode=='active_render': - uv_layer = uv_layer_active_render - - bm.verts.ensure_lookup_table() - bm.faces.ensure_lookup_table() - UVMAPV, UVMAPP = UV(self, bm, uv_layer) - if Pom.is_linked: - # resore UV to 3D - pointuv = PointsUV.sv_get()[0] - bvh = BVHTree.FromPolygons(UVMAPV, UVMAPP, all_triangles=False, epsilon=0.0) - out = [] # result in 3D - for Puv in pointuv: - loc, norm, ind, dist = bvh.find_nearest(Puv) - _found_poly = bm.faces[ind] - _p1, _p2, _p3 = [v.co for v in bm.faces[ind].verts[0:3] ] - _uv1, _uv2, _uv3 = [l[uv_layer].uv.to_3d() for l in _found_poly.loops[0:3] ] - _V = barycentric_transform(Puv, _uv1, _uv2, _uv3, _p1, _p2, _p3) - out.append(_V[:]) + objs = Object.sv_get() + PointsUV = PointsUV.sv_get() + Matrixes = ObjectMatrixes.sv_get(default = [Matrix()]) + POMs, UVMAPPs, UVMAPVs = [], [], [] + for i, (obj, PointUV, obj_matrix) in enumerate(zip_long_repeat(objs,PointsUV, Matrixes) ): + if not obj.data.uv_layers: + raise Exception(f"Object '{obj.data.name}'[{i}] has no UV Maps. Open Properties->Data->UV Maps and check list of UV Maps.") - Pom.sv_set([out]) - bm.clear() + # get all UV Maps name in object UV Maps list + uv_layer_active_render_name = obj.data.uv_layers[0].name + for uv in obj.data.uv_layers: + if uv.active_render==True: + uv_layer_active_render_name = uv.name # get UV Map name active render (photo mark) + break + + bm = bmesh.new() + if self.apply_modifiers: + # apply modifiers and build mesh after it + sv_depsgraph = bpy.context.evaluated_depsgraph_get() + scene_object = sv_depsgraph.objects[ obj.name ] + object_to_mesh = scene_object.to_mesh(preserve_all_data_layers=True, depsgraph=sv_depsgraph) + bm.from_mesh(object_to_mesh) + scene_object.to_mesh_clear() + else: + # get mesh of original object from scene + bm.from_mesh(obj.data) + + uv_layer_active = bm.loops.layers.uv.active + uv_layer_active_render = obj.data.uv_layers[0] + for uv in bm.loops.layers.uv: + if uv.name==uv_layer_active_render_name: + uv_layer_active_render = uv + break + + if self.uv_select_mode=='active_item': + uv_layer = uv_layer_active + else: #if self.uv_select_mode=='active_render': + uv_layer = uv_layer_active_render + + bm.verts.ensure_lookup_table() + bm.faces.ensure_lookup_table() + UVMAPV, UVMAPP = UV(self, bm, uv_layer) + if Pom.is_linked: + # resore UV to 3D + bvh = BVHTree.FromPolygons(UVMAPV, UVMAPP, all_triangles=False, epsilon=0.0) + pom = [] # result in 3D + for Puv in PointUV: + loc, norm, ind, dist = bvh.find_nearest(Puv) + _found_poly = bm.faces[ind] + _p1, _p2, _p3 = [v.co for v in bm.faces[ind].verts[0:3] ] + _uv1, _uv2, _uv3 = [l[uv_layer].uv.to_3d() for l in _found_poly.loops[0:3] ] + _V = barycentric_transform(Puv, _uv1, _uv2, _uv3, _p1, _p2, _p3) + pom.append( obj_matrix @ Vector(_V[:])) + + POMs.append(pom) + bm.clear() + UVMAPVs.append(UVMAPV) + UVMAPPs.append(UVMAPP) + + if Pom.is_linked: + Pom.sv_set(POMs) if uvV.is_linked: - uvV.sv_set([UVMAPV]) - uvP.sv_set([UVMAPP]) + uvV.sv_set(UVMAPVs) + uvP.sv_set(UVMAPPs) def register(): - bpy.utils.register_class(SvUVPointonMeshNodeMK2) + bpy.utils.register_class(SvUVPointonMeshNodeMK3) def unregister(): - bpy.utils.unregister_class(SvUVPointonMeshNodeMK2) + bpy.utils.unregister_class(SvUVPointonMeshNodeMK3) diff --git a/old_nodes/points_from_uv_to_mesh_mk2.py b/old_nodes/points_from_uv_to_mesh_mk2.py new file mode 100644 index 0000000000..e884f94b23 --- /dev/null +++ b/old_nodes/points_from_uv_to_mesh_mk2.py @@ -0,0 +1,164 @@ +# ##### 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 ##### + +import bpy +import bmesh +from mathutils.bvhtree import BVHTree +from mathutils.geometry import barycentric_transform +import numpy as np +from bpy.props import BoolProperty, StringProperty, FloatVectorProperty, EnumProperty +from sverchok.node_tree import SverchCustomTreeNode + +from sverchok.data_structure import (updateNode) + + +def UV(self, bm, uv_layer): + # makes UV from layout texture area to sverchok vertices and polygons. + vertices_dict = {} + polygons_new = [] + polygons_new_append = polygons_new.append + for fi in bm.faces: + polygons_new_pol = [] + polygons_new_pol_append = polygons_new_pol.append + for loop in fi.loops: + li = loop.index + polygons_new_pol_append(li) + uv = loop[uv_layer].uv + vertices_dict[li] = [ uv.x, uv.y, 0.0] + + polygons_new_append(polygons_new_pol) + + vertices_new = list( vertices_dict.values() ) + return [vertices_new, polygons_new] + + +class SvUVPointonMeshNodeMK2(SverchCustomTreeNode, bpy.types.Node): + ''' Transform vectors from UV space to Object space ''' + bl_idname = 'SvUVPointonMeshNodeMK2' + bl_label = 'Find UV Coord on Surface' + bl_icon = 'GROUP_UVS' + is_scene_dependent = True + is_animation_dependent = True + + object_ref: StringProperty(default='', update=updateNode) + + apply_modifiers: BoolProperty( + name="Apply Modifiers", description="Off: use original object from scene\nOn: Apply modifiers before select UV Map", + default=False, update=updateNode) + + uv_select_modes = [ + ('active_item', "Active Selected", "UV Map selected by an active elem in the list of UV Maps of object data", 0), + ('active_render', "Active Render", "UV Map selected by property active_render in the list of UV Maps of object data (actived photo icon)", 1) + ] + + uv_select_mode : EnumProperty( + name = "Select UV Map by", + description = "UV Map select from object data property by", + items = uv_select_modes, + default = 'active_item', + update = updateNode) + + def sv_draw_buttons(self, context, layout): + row = layout.row() + col = row.column() + col.label(text='Apply midifiers:') + col = row.column() + col.alignment = 'LEFT' + col.prop(self, 'apply_modifiers', expand=True, text='') + row = layout.row() + row.column().label(text="Select UV Map by:") + row.column().prop(self, 'uv_select_mode', expand=True ) #, text='') + + + + def sv_init(self, context): + si, so = self.inputs.new, self.outputs.new + si('SvObjectSocket', 'Mesh Object') + si('SvVerticesSocket', 'Point on UV') + so('SvVerticesSocket', 'Point on mesh') + so('SvVerticesSocket', 'UVMapVert') + so('SvStringsSocket', 'UVMapPoly') + + def process(self): + Object, PointsUV = self.inputs + Pom, uvV, uvP = self.outputs + obj = Object.sv_get()[0] # triangulate faces + if not obj.data.uv_layers: + raise Exception(f"Object '{obj.data.name}' has no UV Maps. Open Properties->Data->UV Maps and check list of UV Maps.") + + # get all UV Maps name in object UV Maps list + uv_layer_active_render_name = obj.data.uv_layers[0].name + for uv in obj.data.uv_layers: + if uv.active_render==True: + uv_layer_active_render_name = uv.name # get UV Map name active render (photo mark) + break + + bm = bmesh.new() + if self.apply_modifiers: + # apply modifiers and build mesh after it + sv_depsgraph = bpy.context.evaluated_depsgraph_get() + scene_object = sv_depsgraph.objects[ obj.name ] + object_to_mesh = scene_object.to_mesh(preserve_all_data_layers=True, depsgraph=sv_depsgraph) + bm.from_mesh(object_to_mesh) + scene_object.to_mesh_clear() + else: + # get mesh of original object from scene + bm.from_mesh(obj.data) + + uv_layer_active = bm.loops.layers.uv.active + uv_layer_active_render = obj.data.uv_layers[0] + for uv in bm.loops.layers.uv: + if uv.name==uv_layer_active_render_name: + uv_layer_active_render = uv + break + + if self.uv_select_mode=='active_item': + uv_layer = uv_layer_active + else: #if self.uv_select_mode=='active_render': + uv_layer = uv_layer_active_render + + bm.verts.ensure_lookup_table() + bm.faces.ensure_lookup_table() + UVMAPV, UVMAPP = UV(self, bm, uv_layer) + if Pom.is_linked: + # resore UV to 3D + pointuv = PointsUV.sv_get()[0] + bvh = BVHTree.FromPolygons(UVMAPV, UVMAPP, all_triangles=False, epsilon=0.0) + out = [] # result in 3D + for Puv in pointuv: + loc, norm, ind, dist = bvh.find_nearest(Puv) + _found_poly = bm.faces[ind] + _p1, _p2, _p3 = [v.co for v in bm.faces[ind].verts[0:3] ] + _uv1, _uv2, _uv3 = [l[uv_layer].uv.to_3d() for l in _found_poly.loops[0:3] ] + _V = barycentric_transform(Puv, _uv1, _uv2, _uv3, _p1, _p2, _p3) + out.append(_V[:]) + + Pom.sv_set([out]) + bm.clear() + + if uvV.is_linked: + uvV.sv_set([UVMAPV]) + uvP.sv_set([UVMAPP]) + + +def register(): + bpy.utils.register_class(SvUVPointonMeshNodeMK2) + + +def unregister(): + bpy.utils.unregister_class(SvUVPointonMeshNodeMK2) From 3bdfc4b52b428068aa701607e3cf7f300e9496c9 Mon Sep 17 00:00:00 2001 From: satabol Date: Thu, 9 Nov 2023 16:46:06 +0300 Subject: [PATCH 2/2] fix #5053. Node Find UV Coord on Surface has wrong object on UVMap out. [1.] Now count of out sockets equals to count of input objects [2.] Append Matrix socket of objects 3. Revert version number MK3->MK2 4. Check nesting levels of input datas --- index.yaml | 2 +- menus/full_by_data_type.yaml | 2 +- menus/full_nortikin.yaml | 2 +- nodes/object_nodes/points_from_uv_to_mesh.py | 35 ++-- old_nodes/points_from_uv_to_mesh_mk2.py | 164 ------------------- 5 files changed, 27 insertions(+), 178 deletions(-) delete mode 100644 old_nodes/points_from_uv_to_mesh_mk2.py diff --git a/index.yaml b/index.yaml index 5d4d66f4f6..e6edaf5752 100644 --- a/index.yaml +++ b/index.yaml @@ -767,7 +767,7 @@ - SvSetCustomUVMap - SvUVtextureNode - SvMeshUVColorNode - - SvUVPointonMeshNodeMK3 + - SvUVPointonMeshNodeMK2 - SvSampleUVColorNode - SvArmaturePropsNode - SvLatticePropsNode diff --git a/menus/full_by_data_type.yaml b/menus/full_by_data_type.yaml index b69cc76e58..e905e2ae10 100644 --- a/menus/full_by_data_type.yaml +++ b/menus/full_by_data_type.yaml @@ -796,7 +796,7 @@ - SvSetCustomUVMap - SvUVtextureNode - SvMeshUVColorNode - - SvUVPointonMeshNodeMK3 + - SvUVPointonMeshNodeMK2 - SvSampleUVColorNode - SvArmaturePropsNode - SvLatticePropsNode diff --git a/menus/full_nortikin.yaml b/menus/full_nortikin.yaml index e8d772cf36..f83e340cec 100644 --- a/menus/full_nortikin.yaml +++ b/menus/full_nortikin.yaml @@ -913,7 +913,7 @@ - SvSetCustomUVMap - SvUVtextureNode - SvMeshUVColorNode - - SvUVPointonMeshNodeMK3 + - SvUVPointonMeshNodeMK2 - SvSampleUVColorNode - SvArmaturePropsNode - SvLatticePropsNode diff --git a/nodes/object_nodes/points_from_uv_to_mesh.py b/nodes/object_nodes/points_from_uv_to_mesh.py index 7b27722561..02ac8d16b1 100644 --- a/nodes/object_nodes/points_from_uv_to_mesh.py +++ b/nodes/object_nodes/points_from_uv_to_mesh.py @@ -25,7 +25,7 @@ from bpy.props import BoolProperty, StringProperty, FloatVectorProperty, EnumProperty from sverchok.node_tree import SverchCustomTreeNode -from sverchok.data_structure import updateNode, zip_long_repeat +from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level def UV(self, bm, uv_layer): @@ -48,9 +48,9 @@ def UV(self, bm, uv_layer): return [vertices_new, polygons_new] -class SvUVPointonMeshNodeMK3(SverchCustomTreeNode, bpy.types.Node): +class SvUVPointonMeshNodeMK2(SverchCustomTreeNode, bpy.types.Node): ''' Transform vectors from UV space to Object space ''' - bl_idname = 'SvUVPointonMeshNodeMK3' + bl_idname = 'SvUVPointonMeshNodeMK2' bl_label = 'Find UV Coord on Surface' bl_icon = 'GROUP_UVS' is_scene_dependent = True @@ -86,8 +86,8 @@ def sv_draw_buttons(self, context, layout): row.column().prop(self, 'uv_select_mode', expand=True ) #, text='') - def sv_init(self, context): + self.width = 250 si, so = self.inputs.new, self.outputs.new si('SvMatrixSocket', 'Object Matrix') si('SvObjectSocket', 'Object Mesh') @@ -97,13 +97,26 @@ def sv_init(self, context): so('SvStringsSocket', 'UVMapPoly') def process(self): - ObjectMatrixes, Object, PointsUV = self.inputs + if not any(socket.is_linked for socket in self.outputs): + return + + iObjectMatrixes, iObjects, iPointsUV = self.inputs + Matrixes = iObjectMatrixes.sv_get(default = [Matrix()]) + Objects = iObjects.sv_get(default=[]) + if len(Objects)==0: + raise Exception(f'socket "Object Mesh" has to be connected or object has to be selected') Pom, uvV, uvP = self.outputs - objs = Object.sv_get() - PointsUV = PointsUV.sv_get() - Matrixes = ObjectMatrixes.sv_get(default = [Matrix()]) + PointsUV = iPointsUV.sv_get(default=[]) + + Matrixes = ensure_nesting_level(Matrixes, 1) + Objects = ensure_nesting_level(Objects, 1) + if iPointsUV.is_linked: + PointsUV = ensure_nesting_level(PointsUV, 3) + else: + PointsUV = [[]] + POMs, UVMAPPs, UVMAPVs = [], [], [] - for i, (obj, PointUV, obj_matrix) in enumerate(zip_long_repeat(objs,PointsUV, Matrixes) ): + for i, (obj_matrix, obj, PointUV) in enumerate(zip_long_repeat(Matrixes, Objects,PointsUV) ): if not obj.data.uv_layers: raise Exception(f"Object '{obj.data.name}'[{i}] has no UV Maps. Open Properties->Data->UV Maps and check list of UV Maps.") @@ -167,8 +180,8 @@ def process(self): def register(): - bpy.utils.register_class(SvUVPointonMeshNodeMK3) + bpy.utils.register_class(SvUVPointonMeshNodeMK2) def unregister(): - bpy.utils.unregister_class(SvUVPointonMeshNodeMK3) + bpy.utils.unregister_class(SvUVPointonMeshNodeMK2) diff --git a/old_nodes/points_from_uv_to_mesh_mk2.py b/old_nodes/points_from_uv_to_mesh_mk2.py deleted file mode 100644 index e884f94b23..0000000000 --- a/old_nodes/points_from_uv_to_mesh_mk2.py +++ /dev/null @@ -1,164 +0,0 @@ -# ##### 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 ##### - -import bpy -import bmesh -from mathutils.bvhtree import BVHTree -from mathutils.geometry import barycentric_transform -import numpy as np -from bpy.props import BoolProperty, StringProperty, FloatVectorProperty, EnumProperty -from sverchok.node_tree import SverchCustomTreeNode - -from sverchok.data_structure import (updateNode) - - -def UV(self, bm, uv_layer): - # makes UV from layout texture area to sverchok vertices and polygons. - vertices_dict = {} - polygons_new = [] - polygons_new_append = polygons_new.append - for fi in bm.faces: - polygons_new_pol = [] - polygons_new_pol_append = polygons_new_pol.append - for loop in fi.loops: - li = loop.index - polygons_new_pol_append(li) - uv = loop[uv_layer].uv - vertices_dict[li] = [ uv.x, uv.y, 0.0] - - polygons_new_append(polygons_new_pol) - - vertices_new = list( vertices_dict.values() ) - return [vertices_new, polygons_new] - - -class SvUVPointonMeshNodeMK2(SverchCustomTreeNode, bpy.types.Node): - ''' Transform vectors from UV space to Object space ''' - bl_idname = 'SvUVPointonMeshNodeMK2' - bl_label = 'Find UV Coord on Surface' - bl_icon = 'GROUP_UVS' - is_scene_dependent = True - is_animation_dependent = True - - object_ref: StringProperty(default='', update=updateNode) - - apply_modifiers: BoolProperty( - name="Apply Modifiers", description="Off: use original object from scene\nOn: Apply modifiers before select UV Map", - default=False, update=updateNode) - - uv_select_modes = [ - ('active_item', "Active Selected", "UV Map selected by an active elem in the list of UV Maps of object data", 0), - ('active_render', "Active Render", "UV Map selected by property active_render in the list of UV Maps of object data (actived photo icon)", 1) - ] - - uv_select_mode : EnumProperty( - name = "Select UV Map by", - description = "UV Map select from object data property by", - items = uv_select_modes, - default = 'active_item', - update = updateNode) - - def sv_draw_buttons(self, context, layout): - row = layout.row() - col = row.column() - col.label(text='Apply midifiers:') - col = row.column() - col.alignment = 'LEFT' - col.prop(self, 'apply_modifiers', expand=True, text='') - row = layout.row() - row.column().label(text="Select UV Map by:") - row.column().prop(self, 'uv_select_mode', expand=True ) #, text='') - - - - def sv_init(self, context): - si, so = self.inputs.new, self.outputs.new - si('SvObjectSocket', 'Mesh Object') - si('SvVerticesSocket', 'Point on UV') - so('SvVerticesSocket', 'Point on mesh') - so('SvVerticesSocket', 'UVMapVert') - so('SvStringsSocket', 'UVMapPoly') - - def process(self): - Object, PointsUV = self.inputs - Pom, uvV, uvP = self.outputs - obj = Object.sv_get()[0] # triangulate faces - if not obj.data.uv_layers: - raise Exception(f"Object '{obj.data.name}' has no UV Maps. Open Properties->Data->UV Maps and check list of UV Maps.") - - # get all UV Maps name in object UV Maps list - uv_layer_active_render_name = obj.data.uv_layers[0].name - for uv in obj.data.uv_layers: - if uv.active_render==True: - uv_layer_active_render_name = uv.name # get UV Map name active render (photo mark) - break - - bm = bmesh.new() - if self.apply_modifiers: - # apply modifiers and build mesh after it - sv_depsgraph = bpy.context.evaluated_depsgraph_get() - scene_object = sv_depsgraph.objects[ obj.name ] - object_to_mesh = scene_object.to_mesh(preserve_all_data_layers=True, depsgraph=sv_depsgraph) - bm.from_mesh(object_to_mesh) - scene_object.to_mesh_clear() - else: - # get mesh of original object from scene - bm.from_mesh(obj.data) - - uv_layer_active = bm.loops.layers.uv.active - uv_layer_active_render = obj.data.uv_layers[0] - for uv in bm.loops.layers.uv: - if uv.name==uv_layer_active_render_name: - uv_layer_active_render = uv - break - - if self.uv_select_mode=='active_item': - uv_layer = uv_layer_active - else: #if self.uv_select_mode=='active_render': - uv_layer = uv_layer_active_render - - bm.verts.ensure_lookup_table() - bm.faces.ensure_lookup_table() - UVMAPV, UVMAPP = UV(self, bm, uv_layer) - if Pom.is_linked: - # resore UV to 3D - pointuv = PointsUV.sv_get()[0] - bvh = BVHTree.FromPolygons(UVMAPV, UVMAPP, all_triangles=False, epsilon=0.0) - out = [] # result in 3D - for Puv in pointuv: - loc, norm, ind, dist = bvh.find_nearest(Puv) - _found_poly = bm.faces[ind] - _p1, _p2, _p3 = [v.co for v in bm.faces[ind].verts[0:3] ] - _uv1, _uv2, _uv3 = [l[uv_layer].uv.to_3d() for l in _found_poly.loops[0:3] ] - _V = barycentric_transform(Puv, _uv1, _uv2, _uv3, _p1, _p2, _p3) - out.append(_V[:]) - - Pom.sv_set([out]) - bm.clear() - - if uvV.is_linked: - uvV.sv_set([UVMAPV]) - uvP.sv_set([UVMAPP]) - - -def register(): - bpy.utils.register_class(SvUVPointonMeshNodeMK2) - - -def unregister(): - bpy.utils.unregister_class(SvUVPointonMeshNodeMK2)