add MeshUVModifier
This commit is contained in:
parent
16d4fc2bca
commit
bcbe9c987e
@ -1,4 +1,4 @@
|
|||||||
import bpy, bmesh
|
import bpy, bmesh, mathutils
|
||||||
import typing, array, collections
|
import typing, array, collections
|
||||||
from . import UTIL_functions, UTIL_virtools_types
|
from . import UTIL_functions, UTIL_virtools_types
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ class TemporaryMesh():
|
|||||||
if self.__mTempMesh is None: return False
|
if self.__mTempMesh is None: return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def dispose(self):
|
def dispose(self) -> None:
|
||||||
if self.is_valid():
|
if self.is_valid():
|
||||||
self.__mTempMesh = None
|
self.__mTempMesh = None
|
||||||
self.__mBindingObject.to_mesh_clear()
|
self.__mBindingObject.to_mesh_clear()
|
||||||
@ -103,6 +103,41 @@ class TemporaryMesh():
|
|||||||
raise UTIL_functions.BBPException('try calling invalid TemporaryMesh.')
|
raise UTIL_functions.BBPException('try calling invalid TemporaryMesh.')
|
||||||
return self.__mTempMesh
|
return self.__mTempMesh
|
||||||
|
|
||||||
|
class MeshUVModFaceDescriptor():
|
||||||
|
__mBMeshFace: bmesh.types.BMFace
|
||||||
|
__mBMeshUVLayers: bmesh.types.BMLayerItem
|
||||||
|
|
||||||
|
def __init__(self, bm_uv_layers: bmesh.types.BMLayerItem):
|
||||||
|
self.__mBMeshFace = None
|
||||||
|
self.__mBMeshUVLayers = bm_uv_layers
|
||||||
|
|
||||||
|
def _set_internal_face_data(self, bm_face: bmesh.types.BMFace):
|
||||||
|
"""
|
||||||
|
Only should be called by MeshUVModifier.
|
||||||
|
"""
|
||||||
|
self.__mBMeshFace = bm_face
|
||||||
|
|
||||||
|
def is_face_selected(self) -> bool:
|
||||||
|
return self.__mBMeshFace.select
|
||||||
|
|
||||||
|
def get_face_normal(self) -> UTIL_virtools_types.ConstVxVector3:
|
||||||
|
return (self.__mBMeshFace.normal.x, self.__mBMeshFace.normal.y, self.__mBMeshFace.normal.z)
|
||||||
|
|
||||||
|
def get_face_vertex_count(self) -> int:
|
||||||
|
return len(self.__mBMeshFace.loops)
|
||||||
|
|
||||||
|
def get_face_vertex_pos_by_index(self, index: int) -> UTIL_virtools_types.ConstVxVector3:
|
||||||
|
if index < 0 or index >= len(self.__mBMeshFace.loops):
|
||||||
|
raise UTIL_functions.BBPException('invalid index for getting face vertex position.')
|
||||||
|
|
||||||
|
v: mathutils = self.__mBMeshFace.verts[index].co
|
||||||
|
return (v.x, v.y, v.z)
|
||||||
|
|
||||||
|
def set_face_vertex_uv_by_index(self, index: int, v: UTIL_virtools_types.ConstVxVector2) -> None:
|
||||||
|
if index < 0 or index >= len(self.__mBMeshFace.loops):
|
||||||
|
raise UTIL_functions.BBPException('invalid index for getting face vertex position.')
|
||||||
|
|
||||||
|
self.__mBMeshFace.loops[index][self.__mBMeshUVLayers].uv = (v[0], v[1])
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -115,8 +150,6 @@ class MeshReader():
|
|||||||
|
|
||||||
__mAssocMesh: bpy.types.Mesh | None ##< The binding mesh for this reader. None if this reader is invalid.
|
__mAssocMesh: bpy.types.Mesh | None ##< The binding mesh for this reader. None if this reader is invalid.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, assoc_mesh: bpy.types.Mesh):
|
def __init__(self, assoc_mesh: bpy.types.Mesh):
|
||||||
self.__mAssocMesh = assoc_mesh
|
self.__mAssocMesh = assoc_mesh
|
||||||
|
|
||||||
@ -134,7 +167,7 @@ class MeshReader():
|
|||||||
def __exit__(self, exc_type, exc_value, traceback):
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
self.dispose()
|
self.dispose()
|
||||||
|
|
||||||
def dispose(self):
|
def dispose(self) -> None:
|
||||||
if self.is_valid():
|
if self.is_valid():
|
||||||
# reset mesh
|
# reset mesh
|
||||||
self.__mAssocMesh.free_normals_split()
|
self.__mAssocMesh.free_normals_split()
|
||||||
@ -493,4 +526,57 @@ class MeshWriter():
|
|||||||
self.__mAssocMesh.materials.clear()
|
self.__mAssocMesh.materials.clear()
|
||||||
|
|
||||||
class MeshUVModifier():
|
class MeshUVModifier():
|
||||||
pass
|
|
||||||
|
__mMeshFromEdit: bool ##< Decide how we get BMesh
|
||||||
|
__mAssocMesh: bpy.types.Mesh | None
|
||||||
|
__mBMesh: bmesh.types.BMesh
|
||||||
|
|
||||||
|
def __init__(self, mesh: bpy.types.Mesh, is_from_edit: bool):
|
||||||
|
self.__mMeshFromEdit = is_from_edit
|
||||||
|
self.__mAssocMesh = mesh
|
||||||
|
|
||||||
|
if self.is_valid():
|
||||||
|
# load mesh with different strategy
|
||||||
|
if self.__mMeshFromEdit:
|
||||||
|
self.__mBMesh = bmesh.from_edit_mesh(self.__mAssocMesh)
|
||||||
|
else:
|
||||||
|
self.__mBMesh = bmesh.new()
|
||||||
|
self.__mBMesh.from_mesh(self.__mAssocMesh)
|
||||||
|
|
||||||
|
def is_valid(self) -> bool:
|
||||||
|
return self.__mAssocMesh is not None
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
|
self.dispose()
|
||||||
|
|
||||||
|
def dispose(self) -> None:
|
||||||
|
if self.is_valid():
|
||||||
|
# sync mesh with different strategy
|
||||||
|
if self.__mMeshFromEdit:
|
||||||
|
bmesh.update_edit_mesh(self.__mAssocMesh, False, False)
|
||||||
|
else:
|
||||||
|
self.__mBMesh.to_mesh(self.__mAssocMesh)
|
||||||
|
|
||||||
|
# free variable
|
||||||
|
self.__mBMesh.free()
|
||||||
|
self.__mAssocMesh = None
|
||||||
|
|
||||||
|
def get_face_count(self) -> int:
|
||||||
|
if not self.is_valid():
|
||||||
|
raise UTIL_functions.BBPException('try to call an invalid MeshUVModifier.')
|
||||||
|
|
||||||
|
return len(self.__mBMesh.faces)
|
||||||
|
|
||||||
|
def get_face(self) -> typing.Iterator[MeshUVModFaceDescriptor]:
|
||||||
|
if not self.is_valid():
|
||||||
|
raise UTIL_functions.BBPException('try to call an invalid MeshUVModifier.')
|
||||||
|
|
||||||
|
# verify() will return existing one or create new one if not existing.
|
||||||
|
uv_layer: bmesh.types.BMLayerCollection = self.__mBMesh.loops.layers.uv
|
||||||
|
cache: MeshUVModFaceDescriptor = MeshUVModFaceDescriptor(uv_layer.verify())
|
||||||
|
for face in self.__mBMesh.faces:
|
||||||
|
cache._set_internal_face_data(face)
|
||||||
|
yield cache
|
||||||
|
Loading…
Reference in New Issue
Block a user