add conflict resolver

This commit is contained in:
2024-01-04 10:35:52 +08:00
parent 680f367a42
commit 2c006b4528
2 changed files with 269 additions and 196 deletions

View File

@ -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