add conflict resolver
This commit is contained in:
parent
680f367a42
commit
2c006b4528
@ -21,7 +21,8 @@ class BBP_OT_import_virtools(bpy.types.Operator, UTIL_file_browser.ImportVirtool
|
||||
def execute(self, context):
|
||||
_import_virtools(
|
||||
self.general_get_filename(),
|
||||
self.general_get_vt_encodings()
|
||||
self.general_get_vt_encodings(),
|
||||
self.general_get_conflict_resolver()
|
||||
)
|
||||
self.report({'INFO'}, "Virtools File Importing Finished.")
|
||||
return {'FINISHED'}
|
||||
@ -34,7 +35,7 @@ class BBP_OT_import_virtools(bpy.types.Operator, UTIL_file_browser.ImportVirtool
|
||||
layout.label(text = 'Virtools Params')
|
||||
self.draw_virtools_params(layout.box())
|
||||
|
||||
def _import_virtools(file_name_: str, encodings_: tuple[str]) -> None:
|
||||
def _import_virtools(file_name_: str, encodings_: tuple[str], resolver: UTIL_ioport_shared.ConflictResolver) -> None:
|
||||
# create temp folder
|
||||
with tempfile.TemporaryDirectory() as vt_temp_folder:
|
||||
print(f'Virtools Engine Temp: {vt_temp_folder}')
|
||||
@ -50,22 +51,23 @@ def _import_virtools(file_name_: str, encodings_: tuple[str]) -> None:
|
||||
with ProgressReport(wm = bpy.context.window_manager) as progress:
|
||||
# import textures
|
||||
texture_cret_map: dict[bmap.BMTexture, bpy.types.Image] = _import_virtools_textures(
|
||||
reader, progress)
|
||||
reader, progress, resolver)
|
||||
# import materials
|
||||
material_cret_map: dict[bmap.BMMaterial, bpy.types.Material] = _import_virtools_materials(
|
||||
reader, progress, texture_cret_map)
|
||||
reader, progress, resolver, texture_cret_map)
|
||||
# import meshes
|
||||
mesh_cret_map: dict[bmap.BMMesh, bpy.types.Mesh] = _import_virtools_meshes(
|
||||
reader, progress, material_cret_map)
|
||||
reader, progress, resolver, material_cret_map)
|
||||
# import 3dobjects
|
||||
obj3d_cret_map: dict[bmap.BM3dObject, bpy.types.Object] = _import_virtools_3dobjects(
|
||||
reader, progress, mesh_cret_map)
|
||||
reader, progress, resolver, mesh_cret_map)
|
||||
# import groups
|
||||
_import_virtools_groups(reader, progress, obj3d_cret_map)
|
||||
|
||||
def _import_virtools_textures(
|
||||
reader: bmap.BMFileReader,
|
||||
progress:ProgressReport
|
||||
progress: ProgressReport,
|
||||
resolver: UTIL_ioport_shared.ConflictResolver
|
||||
) -> dict[bmap.BMTexture, bpy.types.Image]:
|
||||
# create map
|
||||
texture_cret_map: dict[bmap.BMTexture, bpy.types.Image] = {}
|
||||
@ -76,13 +78,13 @@ def _import_virtools_textures(
|
||||
print(f'Texture Raw Data Temp: {rawdata_temp}')
|
||||
|
||||
for vttexture in reader.get_textures():
|
||||
tex: bpy.types.Image
|
||||
tex_cret: typing.Callable[[], bpy.types.Image]
|
||||
texpath_to_load: str | None = vttexture.get_file_name()
|
||||
|
||||
# if no assoc file path (what? but it is real happended)
|
||||
# this is invalid image, create a blank image instead
|
||||
if texpath_to_load is None:
|
||||
tex = bpy.data.images.new("", 1, 1)
|
||||
tex_cret = lambda: bpy.data.images.new("", 1, 1)
|
||||
else:
|
||||
# if this image is raw data, save it in external folder before loading
|
||||
# the attribute of raw data saving is the file path is not absolute path
|
||||
@ -96,21 +98,28 @@ def _import_virtools_textures(
|
||||
# detect whether it is ballance texture and load
|
||||
try_blc_tex: str | None = UTIL_ballance_texture.get_ballance_texture_filename(texpath_to_load)
|
||||
|
||||
if try_blc_tex:
|
||||
if try_blc_tex is not None:
|
||||
# load as ballance texture
|
||||
tex = UTIL_ballance_texture.load_ballance_texture(try_blc_tex)
|
||||
tex_cret = lambda: UTIL_ballance_texture.load_ballance_texture(typing.cast(str, try_blc_tex))
|
||||
else:
|
||||
# load as other textures
|
||||
tex = UTIL_ballance_texture.load_other_texture(texpath_to_load)
|
||||
tex_cret = lambda: UTIL_ballance_texture.load_other_texture(typing.cast(str, texpath_to_load))
|
||||
|
||||
# set texture cfg
|
||||
rawtex: PROP_virtools_texture.RawVirtoolsTexture = PROP_virtools_texture.RawVirtoolsTexture()
|
||||
rawtex.mSaveOptions = vttexture.get_save_options()
|
||||
rawtex.mVideoFormat = vttexture.get_video_format()
|
||||
PROP_virtools_texture.set_raw_virtools_texture(tex, rawtex)
|
||||
# create real texture by tex cret fct
|
||||
(tex, init_tex) = resolver.create_texture(
|
||||
UTIL_virtools_types.virtools_name_regulator(vttexture.get_name()),
|
||||
tex_cret
|
||||
)
|
||||
|
||||
# init tex if needed
|
||||
if init_tex:
|
||||
# set texture cfg
|
||||
rawtex: PROP_virtools_texture.RawVirtoolsTexture = PROP_virtools_texture.RawVirtoolsTexture()
|
||||
rawtex.mSaveOptions = vttexture.get_save_options()
|
||||
rawtex.mVideoFormat = vttexture.get_video_format()
|
||||
PROP_virtools_texture.set_raw_virtools_texture(tex, rawtex)
|
||||
|
||||
# rename and insert it to map
|
||||
tex.name = UTIL_virtools_types.virtools_name_regulator(vttexture.get_name())
|
||||
# insert it to map
|
||||
texture_cret_map[vttexture] = tex
|
||||
|
||||
# inc steps
|
||||
@ -122,7 +131,8 @@ def _import_virtools_textures(
|
||||
|
||||
def _import_virtools_materials(
|
||||
reader: bmap.BMFileReader,
|
||||
progress: ProgressReport,
|
||||
progress: ProgressReport,
|
||||
resolver: UTIL_ioport_shared.ConflictResolver,
|
||||
texture_cret_map: dict[bmap.BMTexture, bpy.types.Image]
|
||||
) -> dict[bmap.BMMaterial, bpy.types.Material]:
|
||||
# create map and prepare progress
|
||||
@ -130,48 +140,51 @@ def _import_virtools_materials(
|
||||
progress.enter_substeps(reader.get_material_count(), "Loading Materials")
|
||||
|
||||
for vtmaterial in reader.get_materials():
|
||||
# create new raw material
|
||||
rawmtl: PROP_virtools_material.RawVirtoolsMaterial = PROP_virtools_material.RawVirtoolsMaterial()
|
||||
|
||||
rawmtl.mDiffuse = vtmaterial.get_diffuse()
|
||||
rawmtl.mAmbient = vtmaterial.get_ambient()
|
||||
rawmtl.mSpecular = vtmaterial.get_specular()
|
||||
rawmtl.mEmissive = vtmaterial.get_emissive()
|
||||
rawmtl.mSpecularPower = vtmaterial.get_specular_power()
|
||||
|
||||
mtltex: bmap.BMTexture | None = vtmaterial.get_texture()
|
||||
if mtltex:
|
||||
rawmtl.mTexture = texture_cret_map.get(mtltex, None)
|
||||
else:
|
||||
rawmtl.mTexture = None
|
||||
rawmtl.mTextureBorderColor = vtmaterial.get_texture_border_color()
|
||||
|
||||
rawmtl.mTextureBlendMode = vtmaterial.get_texture_blend_mode()
|
||||
rawmtl.mTextureMinMode = vtmaterial.get_texture_min_mode()
|
||||
rawmtl.mTextureMagMode = vtmaterial.get_texture_mag_mode()
|
||||
rawmtl.mTextureAddressMode = vtmaterial.get_texture_address_mode()
|
||||
|
||||
rawmtl.mSourceBlend = vtmaterial.get_source_blend()
|
||||
rawmtl.mDestBlend = vtmaterial.get_dest_blend()
|
||||
rawmtl.mFillMode = vtmaterial.get_fill_mode()
|
||||
rawmtl.mShadeMode = vtmaterial.get_shade_mode()
|
||||
|
||||
rawmtl.mEnableAlphaTest = vtmaterial.get_alpha_test_enabled()
|
||||
rawmtl.mEnableAlphaBlend = vtmaterial.get_alpha_blend_enabled()
|
||||
rawmtl.mEnablePerspectiveCorrection = vtmaterial.get_perspective_correction_enabled()
|
||||
rawmtl.mEnableZWrite = vtmaterial.get_z_write_enabled()
|
||||
rawmtl.mEnableTwoSided = vtmaterial.get_two_sided_enabled()
|
||||
|
||||
rawmtl.mAlphaRef = vtmaterial.get_alpha_ref()
|
||||
rawmtl.mAlphaFunc = vtmaterial.get_alpha_func()
|
||||
rawmtl.mZFunc = vtmaterial.get_z_func()
|
||||
|
||||
# create mtl and apply it
|
||||
mtl: bpy.types.Material = bpy.data.materials.new(
|
||||
# create mtl
|
||||
(mtl, init_mtl) = resolver.create_material(
|
||||
UTIL_virtools_types.virtools_name_regulator(vtmaterial.get_name())
|
||||
)
|
||||
PROP_virtools_material.set_raw_virtools_material(mtl, rawmtl)
|
||||
PROP_virtools_material.apply_to_blender_material(mtl)
|
||||
|
||||
# apply it if necessary
|
||||
if init_mtl:
|
||||
# create new raw material
|
||||
rawmtl: PROP_virtools_material.RawVirtoolsMaterial = PROP_virtools_material.RawVirtoolsMaterial()
|
||||
|
||||
rawmtl.mDiffuse = vtmaterial.get_diffuse()
|
||||
rawmtl.mAmbient = vtmaterial.get_ambient()
|
||||
rawmtl.mSpecular = vtmaterial.get_specular()
|
||||
rawmtl.mEmissive = vtmaterial.get_emissive()
|
||||
rawmtl.mSpecularPower = vtmaterial.get_specular_power()
|
||||
|
||||
mtltex: bmap.BMTexture | None = vtmaterial.get_texture()
|
||||
if mtltex:
|
||||
rawmtl.mTexture = texture_cret_map.get(mtltex, None)
|
||||
else:
|
||||
rawmtl.mTexture = None
|
||||
rawmtl.mTextureBorderColor = vtmaterial.get_texture_border_color()
|
||||
|
||||
rawmtl.mTextureBlendMode = vtmaterial.get_texture_blend_mode()
|
||||
rawmtl.mTextureMinMode = vtmaterial.get_texture_min_mode()
|
||||
rawmtl.mTextureMagMode = vtmaterial.get_texture_mag_mode()
|
||||
rawmtl.mTextureAddressMode = vtmaterial.get_texture_address_mode()
|
||||
|
||||
rawmtl.mSourceBlend = vtmaterial.get_source_blend()
|
||||
rawmtl.mDestBlend = vtmaterial.get_dest_blend()
|
||||
rawmtl.mFillMode = vtmaterial.get_fill_mode()
|
||||
rawmtl.mShadeMode = vtmaterial.get_shade_mode()
|
||||
|
||||
rawmtl.mEnableAlphaTest = vtmaterial.get_alpha_test_enabled()
|
||||
rawmtl.mEnableAlphaBlend = vtmaterial.get_alpha_blend_enabled()
|
||||
rawmtl.mEnablePerspectiveCorrection = vtmaterial.get_perspective_correction_enabled()
|
||||
rawmtl.mEnableZWrite = vtmaterial.get_z_write_enabled()
|
||||
rawmtl.mEnableTwoSided = vtmaterial.get_two_sided_enabled()
|
||||
|
||||
rawmtl.mAlphaRef = vtmaterial.get_alpha_ref()
|
||||
rawmtl.mAlphaFunc = vtmaterial.get_alpha_func()
|
||||
rawmtl.mZFunc = vtmaterial.get_z_func()
|
||||
|
||||
PROP_virtools_material.set_raw_virtools_material(mtl, rawmtl)
|
||||
PROP_virtools_material.apply_to_blender_material(mtl)
|
||||
|
||||
# add into map and step
|
||||
material_cret_map[vtmaterial] = mtl
|
||||
@ -183,7 +196,8 @@ def _import_virtools_materials(
|
||||
|
||||
def _import_virtools_meshes(
|
||||
reader: bmap.BMFileReader,
|
||||
progress: ProgressReport,
|
||||
progress: ProgressReport,
|
||||
resolver: UTIL_ioport_shared.ConflictResolver,
|
||||
material_cret_map: dict[bmap.BMMaterial, bpy.types.Material]
|
||||
) -> dict[bmap.BMMesh, bpy.types.Mesh]:
|
||||
# create map and prepare progress
|
||||
@ -192,79 +206,81 @@ def _import_virtools_meshes(
|
||||
|
||||
for vtmesh in reader.get_meshs():
|
||||
# create mesh
|
||||
mesh: bpy.types.Mesh = bpy.data.meshes.new(
|
||||
(mesh, init_mesh) = resolver.create_mesh(
|
||||
UTIL_virtools_types.virtools_name_regulator(vtmesh.get_name())
|
||||
)
|
||||
|
||||
# open mesh writer
|
||||
with UTIL_blender_mesh.MeshWriter(mesh) as meshoper:
|
||||
# construct data provider
|
||||
data_prov: UTIL_blender_mesh.MeshWriterIngredient = UTIL_blender_mesh.MeshWriterIngredient()
|
||||
# set mesh data if necessary
|
||||
if init_mesh:
|
||||
# open mesh writer
|
||||
with UTIL_blender_mesh.MeshWriter(mesh) as meshoper:
|
||||
# construct data provider
|
||||
data_prov: UTIL_blender_mesh.MeshWriterIngredient = UTIL_blender_mesh.MeshWriterIngredient()
|
||||
|
||||
# constructor data itor
|
||||
def pos_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||
for v in vtmesh.get_vertex_positions():
|
||||
UTIL_virtools_types.vxvector3_conv_co(v)
|
||||
yield v
|
||||
def nml_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||
for v in vtmesh.get_vertex_normals():
|
||||
UTIL_virtools_types.vxvector3_conv_co(v)
|
||||
yield v
|
||||
def uv_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector2]:
|
||||
for v in vtmesh.get_vertex_uvs():
|
||||
UTIL_virtools_types.vxvector2_conv_co(v)
|
||||
yield v
|
||||
def face_iterator() -> typing.Iterator[UTIL_blender_mesh.FaceData]:
|
||||
face: UTIL_blender_mesh.FaceData = UTIL_blender_mesh.FaceData(
|
||||
[UTIL_blender_mesh.FaceVertexData() for i in range(3)]
|
||||
)
|
||||
# constructor data itor
|
||||
def pos_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||
for v in vtmesh.get_vertex_positions():
|
||||
UTIL_virtools_types.vxvector3_conv_co(v)
|
||||
yield v
|
||||
def nml_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||
for v in vtmesh.get_vertex_normals():
|
||||
UTIL_virtools_types.vxvector3_conv_co(v)
|
||||
yield v
|
||||
def uv_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector2]:
|
||||
for v in vtmesh.get_vertex_uvs():
|
||||
UTIL_virtools_types.vxvector2_conv_co(v)
|
||||
yield v
|
||||
def face_iterator() -> typing.Iterator[UTIL_blender_mesh.FaceData]:
|
||||
face: UTIL_blender_mesh.FaceData = UTIL_blender_mesh.FaceData(
|
||||
[UTIL_blender_mesh.FaceVertexData() for i in range(3)]
|
||||
)
|
||||
|
||||
findices_itor = vtmesh.get_face_indices()
|
||||
fmtl_itor = vtmesh.get_face_material_slot_indexs()
|
||||
for _ in range(vtmesh.get_face_count()):
|
||||
# set indices data
|
||||
vtindices = next(findices_itor)
|
||||
face.mIndices[0].mPosIdx = vtindices.i1
|
||||
face.mIndices[0].mNmlIdx = vtindices.i1
|
||||
face.mIndices[0].mUvIdx = vtindices.i1
|
||||
face.mIndices[1].mPosIdx = vtindices.i2
|
||||
face.mIndices[1].mNmlIdx = vtindices.i2
|
||||
face.mIndices[1].mUvIdx = vtindices.i2
|
||||
face.mIndices[2].mPosIdx = vtindices.i3
|
||||
face.mIndices[2].mNmlIdx = vtindices.i3
|
||||
face.mIndices[2].mUvIdx = vtindices.i3
|
||||
# swap indices
|
||||
face.conv_co()
|
||||
findices_itor = vtmesh.get_face_indices()
|
||||
fmtl_itor = vtmesh.get_face_material_slot_indexs()
|
||||
for _ in range(vtmesh.get_face_count()):
|
||||
# set indices data
|
||||
vtindices = next(findices_itor)
|
||||
face.mIndices[0].mPosIdx = vtindices.i1
|
||||
face.mIndices[0].mNmlIdx = vtindices.i1
|
||||
face.mIndices[0].mUvIdx = vtindices.i1
|
||||
face.mIndices[1].mPosIdx = vtindices.i2
|
||||
face.mIndices[1].mNmlIdx = vtindices.i2
|
||||
face.mIndices[1].mUvIdx = vtindices.i2
|
||||
face.mIndices[2].mPosIdx = vtindices.i3
|
||||
face.mIndices[2].mNmlIdx = vtindices.i3
|
||||
face.mIndices[2].mUvIdx = vtindices.i3
|
||||
# swap indices
|
||||
face.conv_co()
|
||||
|
||||
# set mtl data
|
||||
vtmtl = next(fmtl_itor)
|
||||
face.mMtlIdx = vtmtl
|
||||
# set mtl data
|
||||
vtmtl = next(fmtl_itor)
|
||||
face.mMtlIdx = vtmtl
|
||||
|
||||
# return
|
||||
yield face
|
||||
def mtl_iterator() -> typing.Iterator[bpy.types.Material | None]:
|
||||
for vtmtl in vtmesh.get_material_slots():
|
||||
if vtmtl:
|
||||
yield material_cret_map.get(vtmtl, None)
|
||||
else:
|
||||
yield None
|
||||
# return
|
||||
yield face
|
||||
def mtl_iterator() -> typing.Iterator[bpy.types.Material | None]:
|
||||
for vtmtl in vtmesh.get_material_slots():
|
||||
if vtmtl:
|
||||
yield material_cret_map.get(vtmtl, None)
|
||||
else:
|
||||
yield None
|
||||
|
||||
# assign to data provider
|
||||
data_prov.mVertexPosition = pos_iterator()
|
||||
data_prov.mVertexNormal = nml_iterator()
|
||||
data_prov.mVertexUV = uv_iterator()
|
||||
data_prov.mFace = face_iterator()
|
||||
data_prov.mMaterial = mtl_iterator()
|
||||
# assign to data provider
|
||||
data_prov.mVertexPosition = pos_iterator()
|
||||
data_prov.mVertexNormal = nml_iterator()
|
||||
data_prov.mVertexUV = uv_iterator()
|
||||
data_prov.mFace = face_iterator()
|
||||
data_prov.mMaterial = mtl_iterator()
|
||||
|
||||
# add part
|
||||
meshoper.add_ingredient(data_prov)
|
||||
# add part
|
||||
meshoper.add_ingredient(data_prov)
|
||||
|
||||
# end of mesh writer
|
||||
# end of mesh writer
|
||||
|
||||
# set other mesh settings
|
||||
mesh_settings: PROP_virtools_mesh.RawVirtoolsMesh = PROP_virtools_mesh.RawVirtoolsMesh()
|
||||
mesh_settings.mLitMode = vtmesh.get_lit_mode()
|
||||
PROP_virtools_mesh.set_raw_virtools_mesh(mesh, mesh_settings)
|
||||
# set other mesh settings
|
||||
mesh_settings: PROP_virtools_mesh.RawVirtoolsMesh = PROP_virtools_mesh.RawVirtoolsMesh()
|
||||
mesh_settings.mLitMode = vtmesh.get_lit_mode()
|
||||
PROP_virtools_mesh.set_raw_virtools_mesh(mesh, mesh_settings)
|
||||
|
||||
# add into map and step
|
||||
mesh_cret_map[vtmesh] = mesh
|
||||
@ -276,7 +292,8 @@ def _import_virtools_meshes(
|
||||
|
||||
def _import_virtools_3dobjects(
|
||||
reader: bmap.BMFileReader,
|
||||
progress: ProgressReport,
|
||||
progress: ProgressReport,
|
||||
resolver: UTIL_ioport_shared.ConflictResolver,
|
||||
mesh_cret_map: dict[bmap.BMMesh, bpy.types.Mesh]
|
||||
) -> dict[bmap.BM3dObject, bpy.types.Object]:
|
||||
# create map and prepare progress
|
||||
@ -288,25 +305,35 @@ def _import_virtools_3dobjects(
|
||||
blender_collection = blender_view_layer.active_layer_collection.collection
|
||||
|
||||
for vt3dobj in reader.get_3dobjects():
|
||||
# get virtools binding mesh data first
|
||||
vt3dobj_data: bmap.BMMesh | None = vt3dobj.get_current_mesh()
|
||||
|
||||
# create 3d object with mesh
|
||||
obj3d: bpy.types.Object = bpy.data.objects.new(
|
||||
(obj3d, init_obj3d) = resolver.create_object(
|
||||
UTIL_virtools_types.virtools_name_regulator(vt3dobj.get_name()),
|
||||
mesh_cret_map.get(vt3dobj.get_current_mesh(), None)
|
||||
None if vt3dobj_data is None else mesh_cret_map.get(vt3dobj_data, None)
|
||||
)
|
||||
|
||||
# link to collection
|
||||
blender_collection.objects.link(obj3d)
|
||||
# setup if necessary
|
||||
if init_obj3d:
|
||||
# link to collection
|
||||
blender_collection.objects.link(obj3d)
|
||||
|
||||
# set world matrix
|
||||
vtmat: UTIL_virtools_types.VxMatrix = vt3dobj.get_world_matrix()
|
||||
UTIL_virtools_types.vxmatrix_conv_co(vtmat)
|
||||
obj3d.matrix_world = UTIL_virtools_types.vxmatrix_to_blender(vtmat)
|
||||
# set world matrix
|
||||
vtmat: UTIL_virtools_types.VxMatrix = vt3dobj.get_world_matrix()
|
||||
UTIL_virtools_types.vxmatrix_conv_co(vtmat)
|
||||
obj3d.matrix_world = UTIL_virtools_types.vxmatrix_to_blender(vtmat)
|
||||
|
||||
# set visibility
|
||||
obj3d.hide_set(not vt3dobj.get_visibility())
|
||||
# set visibility
|
||||
obj3d.hide_set(not vt3dobj.get_visibility())
|
||||
|
||||
# add into map and step
|
||||
obj3d_cret_map[vt3dobj] = obj3d
|
||||
# add into map
|
||||
# NOTE: the return value only provided to group setter
|
||||
# and group setter should only set group data to new created 3d objects
|
||||
# thus we only insert pair when this 3d obj is new created.
|
||||
obj3d_cret_map[vt3dobj] = obj3d
|
||||
|
||||
# step forward
|
||||
progress.step()
|
||||
|
||||
# leave progress and return
|
||||
|
@ -1,5 +1,5 @@
|
||||
import bpy
|
||||
import enum
|
||||
import enum, typing
|
||||
from . import UTIL_virtools_types, UTIL_functions
|
||||
from . import PROP_ptrprop_resolver
|
||||
|
||||
@ -12,11 +12,9 @@ from . import PROP_ptrprop_resolver
|
||||
class ConflictStrategy(enum.IntEnum):
|
||||
Rename = enum.auto()
|
||||
Current = enum.auto()
|
||||
Replace = enum.auto()
|
||||
_g_ConflictStrategyDesc: dict[ConflictStrategy, tuple[str, str]] = {
|
||||
ConflictStrategy.Rename: ('Rename', 'Rename the new one'),
|
||||
ConflictStrategy.Current: ('Use Current', 'Use current one'),
|
||||
ConflictStrategy.Replace: ('Replace', 'Replace the old one with new one'),
|
||||
}
|
||||
_g_EnumHelper_ConflictStrategy: UTIL_functions.EnumPropHelper = UTIL_functions.EnumPropHelper(
|
||||
ConflictStrategy,
|
||||
@ -27,6 +25,103 @@ _g_EnumHelper_ConflictStrategy: UTIL_functions.EnumPropHelper = UTIL_functions.E
|
||||
lambda _: ''
|
||||
)
|
||||
|
||||
#region Assist Classes
|
||||
|
||||
class ExportEditModeBackup():
|
||||
"""
|
||||
The class which save Edit Mode when exporting and restore it after exporting.
|
||||
Because edit mode is not allowed when exporting.
|
||||
Support `with` statement.
|
||||
|
||||
```
|
||||
with ExportEditModeBackup():
|
||||
# do some exporting work
|
||||
blabla()
|
||||
# restore automatically when exiting "with"
|
||||
```
|
||||
"""
|
||||
mInEditMode: bool
|
||||
|
||||
def __init__(self):
|
||||
if bpy.context.object and bpy.context.object.mode == "EDIT":
|
||||
# set and toggle it. otherwise exporting will failed.
|
||||
self.mInEditMode = True
|
||||
bpy.ops.object.editmode_toggle()
|
||||
else:
|
||||
self.mInEditMode = False
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
if self.mInEditMode:
|
||||
bpy.ops.object.editmode_toggle()
|
||||
self.mInEditMode = False
|
||||
|
||||
class ConflictResolver():
|
||||
"""
|
||||
This class frequently used when importing objects.
|
||||
This class accept 4 conflict strategies for object, mesh, material and texture,
|
||||
and provide 4 general creation functions to handle these strategies.
|
||||
Each general creation functions will return an instance and a bool indicating whether this instance need be initialized.
|
||||
"""
|
||||
|
||||
__mObjectStrategy: ConflictStrategy
|
||||
__mMeshStrategy: ConflictStrategy
|
||||
__mMaterialStrategy: ConflictStrategy
|
||||
__mTextureStrategy: ConflictStrategy
|
||||
|
||||
def __init__(self, obj_strategy: ConflictStrategy, mesh_strategy: ConflictStrategy, mtl_strategy: ConflictStrategy, tex_strategy: ConflictStrategy):
|
||||
self.__mObjectStrategy = obj_strategy
|
||||
self.__mMeshStrategy = mesh_strategy
|
||||
self.__mMaterialStrategy = mtl_strategy
|
||||
self.__mTextureStrategy = tex_strategy
|
||||
|
||||
def create_object(self, name: str, data: bpy.types.Mesh) -> tuple[bpy.types.Object, bool]:
|
||||
"""
|
||||
Create object according to conflict strategy.
|
||||
`data` will only be applied when creating new object (no existing instance or strategy order rename)
|
||||
"""
|
||||
if self.__mObjectStrategy == ConflictStrategy.Current:
|
||||
old: bpy.types.Object | None = bpy.data.objects.get(name, None)
|
||||
if old is not None:
|
||||
return (old, False)
|
||||
return (bpy.data.objects.new(name, data), True)
|
||||
|
||||
def create_mesh(self, name: str) -> tuple[bpy.types.Mesh, bool]:
|
||||
if self.__mMeshStrategy == ConflictStrategy.Current:
|
||||
old: bpy.types.Mesh | None = bpy.data.meshes.get(name, None)
|
||||
if old is not None:
|
||||
return (old, False)
|
||||
return (bpy.data.meshes.new(name), True)
|
||||
|
||||
def create_material(self, name: str) -> tuple[bpy.types.Material, bool]:
|
||||
if self.__mMaterialStrategy == ConflictStrategy.Current:
|
||||
old: bpy.types.Material | None = bpy.data.materials.get(name, None)
|
||||
if old is not None:
|
||||
return (old, False)
|
||||
return (bpy.data.materials.new(name), True)
|
||||
|
||||
def create_texture(self, name: str, fct_cret: typing.Callable[[], bpy.types.Image]) -> tuple[bpy.types.Image, bool]:
|
||||
"""
|
||||
Create texture according to conflict strategy.
|
||||
If the strategy order current, it will return current existing instance.
|
||||
If no existing instance or strategy order rename, it will call `fct_cret` to create new texture.
|
||||
|
||||
Because texture do not have a general creation function, we frequently create it by other modules provided texture functions.
|
||||
So `fct_cret` is the real creation function. And it will not be executed if no creation happended.
|
||||
"""
|
||||
if self.__mTextureStrategy == ConflictStrategy.Current:
|
||||
old: bpy.types.Image | None = bpy.data.images.get(name, None)
|
||||
if old is not None:
|
||||
return (old, False)
|
||||
# create texture, set name, and return
|
||||
tex: bpy.types.Image = fct_cret()
|
||||
tex.name = name
|
||||
return (tex, True)
|
||||
|
||||
#endregion
|
||||
|
||||
class ImportParams():
|
||||
texture_conflict_strategy: bpy.props.EnumProperty(
|
||||
name = "Texture Name Conflict",
|
||||
@ -78,6 +173,14 @@ class ImportParams():
|
||||
def general_get_object_conflict_strategy(self) -> ConflictStrategy:
|
||||
return _g_EnumHelper_ConflictStrategy.get_selection(self.object_conflict_strategy)
|
||||
|
||||
def general_get_conflict_resolver(self) -> ConflictResolver:
|
||||
return ConflictResolver(
|
||||
self.general_get_object_conflict_strategy(),
|
||||
self.general_get_mesh_conflict_strategy(),
|
||||
self.general_get_material_conflict_strategy(),
|
||||
self.general_get_texture_conflict_strategy()
|
||||
)
|
||||
|
||||
class ExportParams():
|
||||
export_mode: bpy.props.EnumProperty(
|
||||
name = "Export Mode",
|
||||
@ -128,60 +231,3 @@ class VirtoolsParams():
|
||||
# get encoding, split it by `;` and strip blank chars.
|
||||
encodings: str = self.vt_encodings
|
||||
return tuple(map(lambda x: x.strip(), encodings.split(';')))
|
||||
|
||||
class ExportEditModeBackup():
|
||||
"""
|
||||
The class which save Edit Mode when exporting and restore it after exporting.
|
||||
Because edit mode is not allowed when exporting.
|
||||
Support `with` statement.
|
||||
|
||||
```
|
||||
with ExportEditModeBackup():
|
||||
# do some exporting work
|
||||
blabla()
|
||||
# restore automatically when exiting "with"
|
||||
```
|
||||
"""
|
||||
mInEditMode: bool
|
||||
|
||||
def __init__(self):
|
||||
if bpy.context.object and bpy.context.object.mode == "EDIT":
|
||||
# set and toggle it. otherwise exporting will failed.
|
||||
self.mInEditMode = True
|
||||
bpy.ops.object.editmode_toggle()
|
||||
else:
|
||||
self.mInEditMode = False
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
if self.mInEditMode:
|
||||
bpy.ops.object.editmode_toggle()
|
||||
self.mInEditMode = False
|
||||
|
||||
class ConflictResolver():
|
||||
"""
|
||||
This class frequently used when importing objects.
|
||||
This class accept 4 conflict strategies for object, mesh, material and texture,
|
||||
and provide 4 general creation functions to handle these strategies.
|
||||
Each general creation functions will return an instance and a bool indicating whether this instance need be initialized.
|
||||
|
||||
This class also provide 3 static common creation functions without considering conflict.
|
||||
They just a redirect calling to `bpy.data.xxx.new()`.
|
||||
No static texture (Image) creation function because texture is not created from `bpy.data.images`.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def create_object(name: str, data: bpy.types.Mesh) -> bpy.types.Object:
|
||||
return bpy.data.objects.new(name, data)
|
||||
|
||||
@staticmethod
|
||||
def create_mesh(name: str) -> bpy.types.Mesh:
|
||||
return bpy.data.meshes.new(name)
|
||||
|
||||
@staticmethod
|
||||
def create_material(name: str) -> bpy.types.Material:
|
||||
return bpy.data.materials.new(name)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user