feat: update PyBMap and its testbench

- update PyBMap testbench according to BMapSharp testbench.
- use some wrapper function to fetch commonly used type in PyBMap to reduce line count.
- re-place some utils functions in PyBMap.
This commit is contained in:
yyc12345 2024-11-07 17:28:11 +08:00
parent 9dd46b88d9
commit e2e7121c16
3 changed files with 243 additions and 222 deletions

View File

@ -35,7 +35,7 @@ namespace BMapSharp.BMapWrapper {
/// It just writes the data in console. /// It just writes the data in console.
/// </summary> /// </summary>
internal static void BMapSharpCallback(string msg) { internal static void BMapSharpCallback(string msg) {
Console.WriteLine(msg); Console.WriteLine($"[BMapSharp] {msg}");
} }
#endregion #endregion

View File

@ -13,8 +13,9 @@ def _python_callback(strl: bytes):
Simply add a prefix when output. Simply add a prefix when output.
Need a convertion before passing to BMFile. Need a convertion before passing to BMFile.
""" """
# the passing value is bytes, not bmap.bm_CKSTRING. # YYC Remarks:
# i think Python do a auto convertion here. # The passing value to this function is bytes, not bmap.bm_CKSTRING.
# I think Python do an auto convertion in there.
if strl is not None: if strl is not None:
print(f'[PyBMap] {strl.decode(g_BMapEncoding)}') print(f'[PyBMap] {strl.decode(g_BMapEncoding)}')
_g_RawCallback: bmap.bm_callback = bmap.bm_callback(_python_callback) _g_RawCallback: bmap.bm_callback = bmap.bm_callback(_python_callback)
@ -76,68 +77,111 @@ class _AbstractCKObject(_AbstractPointer):
TCKObj = typing.TypeVar('TCKObj', bound = _AbstractCKObject) TCKObj = typing.TypeVar('TCKObj', bound = _AbstractCKObject)
def _vxvector3_assigner(pvector: bmap.bm_VxVector3_p, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None: class _Utils:
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
uservector: virtools_types.VxVector3 = next(itor)
pfloat[idx] = uservector.x
pfloat[idx + 1] = uservector.y
pfloat[idx + 2] = uservector.z
idx += 3
def _vxvector3_iterator(pvector: bmap.bm_VxVector3_p, count: int) -> typing.Iterator[virtools_types.VxVector3]: # @staticmethod
ret: virtools_types.VxVector3 = virtools_types.VxVector3() # def _vector_assigner(pfloat: bmap.bm_CKFLOAT_p, item_count: int, factor_count: int, itor: typing.Iterator[tuple[float, ...]]) -> None:
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p) # idx: int = 0
idx: int = 0 # for _i in range(item_count):
for _ in range(count): # user_vector: tuple[float, ...] = next(itor)
ret.x = pfloat[idx] # for _j in range(factor_count):
ret.y = pfloat[idx + 1] # pfloat[idx] = user_vector[_j]
ret.z = pfloat[idx + 2] # idx += 1
idx += 3
yield ret
def _vxvector2_assigner(pvector: bmap.bm_VxVector2_p, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
uservector: virtools_types.VxVector2 = next(itor)
pfloat[idx] = uservector.x
pfloat[idx + 1] = uservector.y
idx += 2
def _vxvector2_iterator(pvector: bmap.bm_VxVector2_p, count: int) -> typing.Iterator[virtools_types.VxVector2]: # @staticmethod
ret: virtools_types.VxVector2 = virtools_types.VxVector2() # def _vector_iterator(pfloat: bmap.bm_CKFLOAT_p, item_count: int, factor_count: int) -> typing.Iterator[tuple[float, ...]]:
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p) # idx: int = 0
idx: int = 0 # for _i in range(item_count):
for _ in range(count): # yield tuple(map(
ret.x = pfloat[idx] # lambda _j: pfloat[idx + _j], range(factor_count)
ret.y = pfloat[idx + 1] # ))
idx += 2
yield ret
# bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p is just a type hint
# wo do not need distinguish them in code.
# because the type of pindices is decided by runtime.
def _ckfaceindices_assigner(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None: # @staticmethod
idx: int = 0 # def vxvector3_assigner(pvector: bmap.bm_VxVector3_p, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
for _ in range(count): # _Utils._vector_assigner(
userindices: virtools_types.CKFaceIndices = next(itor) # ctypes.cast(pvector, bmap.bm_CKFLOAT_p), count, 3, itor
pindices[idx] = userindices.i1 # )
pindices[idx + 1] = userindices.i2
pindices[idx + 2] = userindices.i3
idx += 3
def _ckfaceindices_iterator(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int) -> typing.Iterator[virtools_types.CKFaceIndices]: @staticmethod
ret: virtools_types.CKFaceIndices = virtools_types.CKFaceIndices() def vxvector3_assigner(pvector: bmap.bm_VxVector3_p, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
idx: int = 0 pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
for _ in range(count): idx: int = 0
ret.i1 = pindices[idx] try:
ret.i2 = pindices[idx + 1] for _ in range(count):
ret.i3 = pindices[idx + 2] uservector: virtools_types.VxVector3 = next(itor)
idx += 3 pfloat[idx] = uservector.x
yield ret pfloat[idx + 1] = uservector.y
pfloat[idx + 2] = uservector.z
idx += 3
except StopIteration:
raise bmap.BMapException("The length of given data is too short when assigning struct array.")
@staticmethod
def vxvector3_iterator(pvector: bmap.bm_VxVector3_p, count: int) -> typing.Iterator[virtools_types.VxVector3]:
ret: virtools_types.VxVector3 = virtools_types.VxVector3()
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
ret.x = pfloat[idx]
ret.y = pfloat[idx + 1]
ret.z = pfloat[idx + 2]
idx += 3
yield ret
@staticmethod
def vxvector2_assigner(pvector: bmap.bm_VxVector2_p, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
idx: int = 0
try:
for _ in range(count):
uservector: virtools_types.VxVector2 = next(itor)
pfloat[idx] = uservector.x
pfloat[idx + 1] = uservector.y
idx += 2
except StopIteration:
raise bmap.BMapException("The length of given data is too short when assigning struct array.")
@staticmethod
def vxvector2_iterator(pvector: bmap.bm_VxVector2_p, count: int) -> typing.Iterator[virtools_types.VxVector2]:
ret: virtools_types.VxVector2 = virtools_types.VxVector2()
pfloat: bmap.bm_CKFLOAT_p = ctypes.cast(pvector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
ret.x = pfloat[idx]
ret.y = pfloat[idx + 1]
idx += 2
yield ret
"""!
@remarks
bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p is just a type hint.
We actually do not need distinguish them in code.
Because the stride when increasing them is decided by their runtime type.
"""
@staticmethod
def ckfaceindices_assigner(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None:
idx: int = 0
try:
for _ in range(count):
userindices: virtools_types.CKFaceIndices = next(itor)
pindices[idx] = userindices.i1
pindices[idx + 1] = userindices.i2
pindices[idx + 2] = userindices.i3
idx += 3
except StopIteration:
raise bmap.BMapException("The length of given data is too short when assigning struct array.")
@staticmethod
def ckfaceindices_iterator(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int) -> typing.Iterator[virtools_types.CKFaceIndices]:
ret: virtools_types.CKFaceIndices = virtools_types.CKFaceIndices()
idx: int = 0
for _ in range(count):
ret.i1 = pindices[idx]
ret.i2 = pindices[idx + 1]
ret.i3 = pindices[idx + 2]
idx += 3
yield ret
#endregion #endregion
@ -159,7 +203,7 @@ if is_bmap_available():
#region Real Type Defines #region Real Type Defines
"""! """!
@remark @remarks
BMFileReader, BMFileWriter, and BMMeshTrans can be create by given constructor. BMFileReader, BMFileWriter, and BMMeshTrans can be create by given constructor.
But they must be destroyed by calling dispose(). Otherwise it may cause memory leak. But they must be destroyed by calling dispose(). Otherwise it may cause memory leak.
You also can use python `with` statement to achieve this automatically. You also can use python `with` statement to achieve this automatically.
@ -225,7 +269,7 @@ class BMTexture(BMObject):
class BMMaterial(BMObject): class BMMaterial(BMObject):
def _set_vxcolor(self, def _set_vxcolor(self,
setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor], bool], setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor], bmap.bm_bool],
col_: virtools_types.VxColor) -> None: col_: virtools_types.VxColor) -> None:
# set to raw color # set to raw color
col: bmap.bm_VxColor = bmap.bm_VxColor() col: bmap.bm_VxColor = bmap.bm_VxColor()
@ -236,7 +280,7 @@ class BMMaterial(BMObject):
# assign # assign
setter_(self._get_pointer(), self._get_ckid(), col) setter_(self._get_pointer(), self._get_ckid(), col)
def _get_vxcolor(self, def _get_vxcolor(self,
getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor_p], bool]) -> virtools_types.VxColor: getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_VxColor_p], bmap.bm_bool]) -> virtools_types.VxColor:
# get raw color # get raw color
col: bmap.bm_VxColor = bmap.bm_VxColor() col: bmap.bm_VxColor = bmap.bm_VxColor()
getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(col)) getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(col))
@ -297,98 +341,79 @@ class BMMaterial(BMObject):
col: bmap.bm_CKDWORD = bmap.bm_CKDWORD(col_.to_dword()) col: bmap.bm_CKDWORD = bmap.bm_CKDWORD(col_.to_dword())
bmap.BMMaterial_SetTextureBorderColor(self._get_pointer(), self._get_ckid(), col) bmap.BMMaterial_SetTextureBorderColor(self._get_pointer(), self._get_ckid(), col)
def _get_enum(self,
enum_type_: typing.Any,
getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_enum_p], bmap.bm_bool]) -> typing.Any:
data: bmap.bm_enum = bmap.bm_enum()
getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return enum_type_(data.value)
def _set_enum(self,
setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_enum], bmap.bm_bool],
data_: typing.Any) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value)
setter_(self._get_pointer(), self._get_ckid(), data)
def get_texture_blend_mode(self) -> virtools_types.VXTEXTURE_BLENDMODE: def get_texture_blend_mode(self) -> virtools_types.VXTEXTURE_BLENDMODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXTEXTURE_BLENDMODE, bmap.BMMaterial_GetTextureBlendMode)
bmap.BMMaterial_GetTextureBlendMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_BLENDMODE(data.value)
def set_texture_blend_mode(self, data_: virtools_types.VXTEXTURE_BLENDMODE) -> None: def set_texture_blend_mode(self, data_: virtools_types.VXTEXTURE_BLENDMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetTextureBlendMode, data_)
bmap.BMMaterial_SetTextureBlendMode(self._get_pointer(), self._get_ckid(), data)
def get_texture_min_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE: def get_texture_min_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXTEXTURE_FILTERMODE, bmap.BMMaterial_GetTextureMinMode)
bmap.BMMaterial_GetTextureMinMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_FILTERMODE(data.value)
def set_texture_min_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None: def set_texture_min_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetTextureMinMode, data_)
bmap.BMMaterial_SetTextureMinMode(self._get_pointer(), self._get_ckid(), data)
def get_texture_mag_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE: def get_texture_mag_mode(self) -> virtools_types.VXTEXTURE_FILTERMODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXTEXTURE_FILTERMODE, bmap.BMMaterial_GetTextureMagMode)
bmap.BMMaterial_GetTextureMagMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_FILTERMODE(data.value)
def set_texture_mag_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None: def set_texture_mag_mode(self, data_: virtools_types.VXTEXTURE_FILTERMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetTextureMagMode, data_)
bmap.BMMaterial_SetTextureMagMode(self._get_pointer(), self._get_ckid(), data)
def get_texture_address_mode(self) -> virtools_types.VXTEXTURE_ADDRESSMODE: def get_texture_address_mode(self) -> virtools_types.VXTEXTURE_ADDRESSMODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXTEXTURE_ADDRESSMODE, bmap.BMMaterial_GetTextureAddressMode)
bmap.BMMaterial_GetTextureAddressMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXTEXTURE_ADDRESSMODE(data.value)
def set_texture_address_mode(self, data_: virtools_types.VXTEXTURE_ADDRESSMODE) -> None: def set_texture_address_mode(self, data_: virtools_types.VXTEXTURE_ADDRESSMODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetTextureAddressMode, data_)
bmap.BMMaterial_SetTextureAddressMode(self._get_pointer(), self._get_ckid(), data)
def get_source_blend(self) -> virtools_types.VXBLEND_MODE: def get_source_blend(self) -> virtools_types.VXBLEND_MODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXBLEND_MODE, bmap.BMMaterial_GetSourceBlend)
bmap.BMMaterial_GetSourceBlend(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXBLEND_MODE(data.value)
def set_source_blend(self, data_: virtools_types.VXBLEND_MODE) -> None: def set_source_blend(self, data_: virtools_types.VXBLEND_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetSourceBlend, data_)
bmap.BMMaterial_SetSourceBlend(self._get_pointer(), self._get_ckid(), data)
def get_dest_blend(self) -> virtools_types.VXBLEND_MODE: def get_dest_blend(self) -> virtools_types.VXBLEND_MODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXBLEND_MODE, bmap.BMMaterial_GetDestBlend)
bmap.BMMaterial_GetDestBlend(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXBLEND_MODE(data.value)
def set_dest_blend(self, data_: virtools_types.VXBLEND_MODE) -> None: def set_dest_blend(self, data_: virtools_types.VXBLEND_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetDestBlend, data_)
bmap.BMMaterial_SetDestBlend(self._get_pointer(), self._get_ckid(), data)
def get_fill_mode(self) -> virtools_types.VXFILL_MODE: def get_fill_mode(self) -> virtools_types.VXFILL_MODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXFILL_MODE, bmap.BMMaterial_GetFillMode)
bmap.BMMaterial_GetFillMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXFILL_MODE(data.value)
def set_fill_mode(self, data_: virtools_types.VXFILL_MODE) -> None: def set_fill_mode(self, data_: virtools_types.VXFILL_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetFillMode, data_)
bmap.BMMaterial_SetFillMode(self._get_pointer(), self._get_ckid(), data)
def get_shade_mode(self) -> virtools_types.VXSHADE_MODE: def get_shade_mode(self) -> virtools_types.VXSHADE_MODE:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXSHADE_MODE, bmap.BMMaterial_GetShadeMode)
bmap.BMMaterial_GetShadeMode(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXSHADE_MODE(data.value)
def set_shade_mode(self, data_: virtools_types.VXSHADE_MODE) -> None: def set_shade_mode(self, data_: virtools_types.VXSHADE_MODE) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetShadeMode, data_)
bmap.BMMaterial_SetShadeMode(self._get_pointer(), self._get_ckid(), data)
def _get_bool(self, getter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_bool_p], bmap.bm_bool]) -> bool:
data: bmap.bm_bool = bmap.bm_bool()
getter_(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def _set_bool(self, setter_: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID, bmap.bm_bool], bmap.bm_bool], data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_)
setter_(self._get_pointer(), self._get_ckid(), data)
def get_alpha_test_enabled(self) -> bool: def get_alpha_test_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool(bmap.BMMaterial_GetAlphaTestEnabled)
bmap.BMMaterial_GetAlphaTestEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_alpha_test_enabled(self, data_: bool) -> None: def set_alpha_test_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool(bmap.BMMaterial_SetAlphaTestEnabled, data_)
bmap.BMMaterial_SetAlphaTestEnabled(self._get_pointer(), self._get_ckid(), data)
def get_alpha_blend_enabled(self) -> bool: def get_alpha_blend_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool(bmap.BMMaterial_GetAlphaBlendEnabled)
bmap.BMMaterial_GetAlphaBlendEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_alpha_blend_enabled(self, data_: bool) -> None: def set_alpha_blend_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool(bmap.BMMaterial_SetAlphaBlendEnabled, data_)
bmap.BMMaterial_SetAlphaBlendEnabled(self._get_pointer(), self._get_ckid(), data)
def get_perspective_correction_enabled(self) -> bool: def get_perspective_correction_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool(bmap.BMMaterial_GetPerspectiveCorrectionEnabled)
bmap.BMMaterial_GetPerspectiveCorrectionEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_perspective_correction_enabled(self, data_: bool) -> None: def set_perspective_correction_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool(bmap.BMMaterial_SetPerspectiveCorrectionEnabled, data_)
bmap.BMMaterial_SetPerspectiveCorrectionEnabled(self._get_pointer(), self._get_ckid(), data)
def get_z_write_enabled(self) -> bool: def get_z_write_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool(bmap.BMMaterial_GetZWriteEnabled)
bmap.BMMaterial_GetZWriteEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_z_write_enabled(self, data_: bool) -> None: def set_z_write_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool(bmap.BMMaterial_SetZWriteEnabled, data_)
bmap.BMMaterial_SetZWriteEnabled(self._get_pointer(), self._get_ckid(), data)
def get_two_sided_enabled(self) -> bool: def get_two_sided_enabled(self) -> bool:
data: bmap.bm_bool = bmap.bm_bool() return self._get_bool(bmap.BMMaterial_GetTwoSidedEnabled)
bmap.BMMaterial_GetTwoSidedEnabled(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return data.value
def set_two_sided_enabled(self, data_: bool) -> None: def set_two_sided_enabled(self, data_: bool) -> None:
data: bmap.bm_bool = bmap.bm_bool(data_) self._set_bool(bmap.BMMaterial_SetTwoSidedEnabled, data_)
bmap.BMMaterial_SetTwoSidedEnabled(self._get_pointer(), self._get_ckid(), data)
def get_alpha_ref(self) -> int: def get_alpha_ref(self) -> int:
data: bmap.bm_CKBYTE = bmap.bm_CKBYTE() data: bmap.bm_CKBYTE = bmap.bm_CKBYTE()
@ -399,19 +424,13 @@ class BMMaterial(BMObject):
bmap.BMMaterial_SetAlphaRef(self._get_pointer(), self._get_ckid(), data) bmap.BMMaterial_SetAlphaRef(self._get_pointer(), self._get_ckid(), data)
def get_alpha_func(self) -> virtools_types.VXCMPFUNC: def get_alpha_func(self) -> virtools_types.VXCMPFUNC:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXCMPFUNC, bmap.BMMaterial_GetAlphaFunc)
bmap.BMMaterial_GetAlphaFunc(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXCMPFUNC(data.value)
def set_alpha_func(self, data_: virtools_types.VXCMPFUNC) -> None: def set_alpha_func(self, data_: virtools_types.VXCMPFUNC) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetAlphaFunc, data_)
bmap.BMMaterial_SetAlphaFunc(self._get_pointer(), self._get_ckid(), data)
def get_z_func(self) -> virtools_types.VXCMPFUNC: def get_z_func(self) -> virtools_types.VXCMPFUNC:
data: bmap.bm_enum = bmap.bm_enum() return self._get_enum(virtools_types.VXCMPFUNC, bmap.BMMaterial_GetZFunc)
bmap.BMMaterial_GetZFunc(self._get_pointer(), self._get_ckid(), ctypes.byref(data))
return virtools_types.VXCMPFUNC(data.value)
def set_z_func(self, data_: virtools_types.VXCMPFUNC) -> None: def set_z_func(self, data_: virtools_types.VXCMPFUNC) -> None:
data: bmap.bm_enum = bmap.bm_enum(data_.value) self._set_enum(bmap.BMMaterial_SetZFunc, data_)
bmap.BMMaterial_SetZFunc(self._get_pointer(), self._get_ckid(), data)
class BMMesh(BMObject): class BMMesh(BMObject):
@ -437,33 +456,33 @@ class BMMesh(BMObject):
# get raw pointer and return # get raw pointer and return
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMesh_GetVertexPositions(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) bmap.BMMesh_GetVertexPositions(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
return _vxvector3_iterator(raw_vector, self.get_vertex_count()) return _Utils.vxvector3_iterator(raw_vector, self.get_vertex_count())
def set_vertex_positions(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None: def set_vertex_positions(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
# get raw float pointer and assign # get raw float pointer and assign
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMesh_GetVertexPositions(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) bmap.BMMesh_GetVertexPositions(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
_vxvector3_assigner(raw_vector, self.get_vertex_count(), itor) _Utils.vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
def get_vertex_normals(self) -> typing.Iterator[virtools_types.VxVector3]: def get_vertex_normals(self) -> typing.Iterator[virtools_types.VxVector3]:
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMesh_GetVertexNormals(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) bmap.BMMesh_GetVertexNormals(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
return _vxvector3_iterator(raw_vector, self.get_vertex_count()) return _Utils.vxvector3_iterator(raw_vector, self.get_vertex_count())
def set_vertex_normals(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None: def set_vertex_normals(self, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMesh_GetVertexNormals(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) bmap.BMMesh_GetVertexNormals(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
_vxvector3_assigner(raw_vector, self.get_vertex_count(), itor) _Utils.vxvector3_assigner(raw_vector, self.get_vertex_count(), itor)
def get_vertex_uvs(self) -> typing.Iterator[virtools_types.VxVector2]: def get_vertex_uvs(self) -> typing.Iterator[virtools_types.VxVector2]:
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p() raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p()
bmap.BMMesh_GetVertexUVs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) bmap.BMMesh_GetVertexUVs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
return _vxvector2_iterator(raw_vector, self.get_vertex_count()) return _Utils.vxvector2_iterator(raw_vector, self.get_vertex_count())
def set_vertex_uvs(self, itor: typing.Iterator[virtools_types.VxVector2]) -> None: def set_vertex_uvs(self, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p() raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p()
bmap.BMMesh_GetVertexUVs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector)) bmap.BMMesh_GetVertexUVs(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_vector))
_vxvector2_assigner(raw_vector, self.get_vertex_count(), itor) _Utils.vxvector2_assigner(raw_vector, self.get_vertex_count(), itor)
def get_face_count(self) -> int: def get_face_count(self) -> int:
count: bmap.bm_CKDWORD = bmap.bm_CKDWORD() count: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
@ -477,12 +496,12 @@ class BMMesh(BMObject):
def get_face_indices(self) -> typing.Iterator[virtools_types.CKFaceIndices]: def get_face_indices(self) -> typing.Iterator[virtools_types.CKFaceIndices]:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p() raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p()
bmap.BMMesh_GetFaceIndices(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx)) bmap.BMMesh_GetFaceIndices(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx))
return _ckfaceindices_iterator(raw_idx, self.get_face_count()) return _Utils.ckfaceindices_iterator(raw_idx, self.get_face_count())
def set_face_indices(self, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None: def set_face_indices(self, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p() raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p()
bmap.BMMesh_GetFaceIndices(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx)) bmap.BMMesh_GetFaceIndices(self._get_pointer(), self._get_ckid(), ctypes.byref(raw_idx))
_ckfaceindices_assigner(raw_idx, self.get_face_count(), itor) _Utils.ckfaceindices_assigner(raw_idx, self.get_face_count(), itor)
def get_face_material_slot_indexs(self) -> typing.Iterator[int]: def get_face_material_slot_indexs(self) -> typing.Iterator[int]:
raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p() raw_idx: bmap.bm_CKWORD_p = bmap.bm_CKWORD_p()
@ -621,7 +640,7 @@ class BMFileReader(_AbstractPointer):
self._set_pointer(g_InvalidPtr) self._set_pointer(g_InvalidPtr)
def __get_ckobject_count(self, def __get_ckobject_count(self,
count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bool]) -> int: count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bmap.bm_bool]) -> int:
# get size # get size
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD() csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
count_getter(self._get_pointer(), ctypes.byref(csize)) count_getter(self._get_pointer(), ctypes.byref(csize))
@ -629,8 +648,8 @@ class BMFileReader(_AbstractPointer):
def __get_ckobjects(self, def __get_ckobjects(self,
class_type: type[TCKObj], class_type: type[TCKObj],
count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bool], count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bmap.bm_bool],
obj_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD, bmap.bm_CKID_p], bool]) -> typing.Iterator[TCKObj]: obj_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD, bmap.bm_CKID_p], bmap.bm_bool]) -> typing.Iterator[TCKObj]:
# get size first # get size first
csize: int = self.__get_ckobject_count(count_getter) csize: int = self.__get_ckobject_count(count_getter)
@ -646,47 +665,23 @@ class BMFileReader(_AbstractPointer):
def get_texture_count(self) -> int: def get_texture_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetTextureCount) return self.__get_ckobject_count(bmap.BMFile_GetTextureCount)
def get_textures(self) -> typing.Iterator[BMTexture]: def get_textures(self) -> typing.Iterator[BMTexture]:
return self.__get_ckobjects( return self.__get_ckobjects(BMTexture, bmap.BMFile_GetTextureCount, bmap.BMFile_GetTexture)
BMTexture,
bmap.BMFile_GetTextureCount,
bmap.BMFile_GetTexture
)
def get_material_count(self) -> int: def get_material_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetMaterialCount) return self.__get_ckobject_count(bmap.BMFile_GetMaterialCount)
def get_materials(self) -> typing.Iterator[BMMaterial]: def get_materials(self) -> typing.Iterator[BMMaterial]:
return self.__get_ckobjects( return self.__get_ckobjects(BMMaterial, bmap.BMFile_GetMaterialCount, bmap.BMFile_GetMaterial)
BMMaterial,
bmap.BMFile_GetMaterialCount,
bmap.BMFile_GetMaterial
)
def get_mesh_count(self) -> int: def get_mesh_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetMeshCount) return self.__get_ckobject_count(bmap.BMFile_GetMeshCount)
def get_meshs(self) -> typing.Iterator[BMMesh]: def get_meshs(self) -> typing.Iterator[BMMesh]:
return self.__get_ckobjects( return self.__get_ckobjects(BMMesh, bmap.BMFile_GetMeshCount, bmap.BMFile_GetMesh)
BMMesh,
bmap.BMFile_GetMeshCount,
bmap.BMFile_GetMesh
)
def get_3dobject_count(self) -> int: def get_3dobject_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_Get3dObjectCount) return self.__get_ckobject_count(bmap.BMFile_Get3dObjectCount)
def get_3dobjects(self) -> typing.Iterator[BM3dObject]: def get_3dobjects(self) -> typing.Iterator[BM3dObject]:
return self.__get_ckobjects( return self.__get_ckobjects(BM3dObject, bmap.BMFile_Get3dObjectCount, bmap.BMFile_Get3dObject)
BM3dObject,
bmap.BMFile_Get3dObjectCount,
bmap.BMFile_Get3dObject
)
def get_group_count(self) -> int: def get_group_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetGroupCount) return self.__get_ckobject_count(bmap.BMFile_GetGroupCount)
def get_groups(self) -> typing.Iterator[BMGroup]: def get_groups(self) -> typing.Iterator[BMGroup]:
return self.__get_ckobjects( return self.__get_ckobjects(BMGroup, bmap.BMFile_GetGroupCount, bmap.BMFile_GetGroup)
BMGroup,
bmap.BMFile_GetGroupCount,
bmap.BMFile_GetGroup
)
class BMFileWriter(_AbstractPointer): class BMFileWriter(_AbstractPointer):
def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]): def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]):
@ -729,7 +724,7 @@ class BMFileWriter(_AbstractPointer):
def __create_ckobject(self, def __create_ckobject(self,
class_type: type[TCKObj], class_type: type[TCKObj],
creator: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID_p], bool]) -> TCKObj: creator: typing.Callable[[bmap.bm_void_p, bmap.bm_CKID_p], bmap.bm_bool]) -> TCKObj:
# prepare id container # prepare id container
retid: bmap.bm_CKID = bmap.bm_CKID() retid: bmap.bm_CKID = bmap.bm_CKID()
# create new one # create new one
@ -738,34 +733,15 @@ class BMFileWriter(_AbstractPointer):
return class_type(self._get_pointer(), retid) return class_type(self._get_pointer(), retid)
def create_texture(self) -> BMTexture: def create_texture(self) -> BMTexture:
return self.__create_ckobject( return self.__create_ckobject(BMTexture, bmap.BMFile_CreateTexture)
BMTexture,
bmap.BMFile_CreateTexture
)
def create_material(self) -> BMMaterial: def create_material(self) -> BMMaterial:
return self.__create_ckobject( return self.__create_ckobject(BMMaterial, bmap.BMFile_CreateMaterial)
BMMaterial,
bmap.BMFile_CreateMaterial
)
def create_mesh(self) -> BMMesh: def create_mesh(self) -> BMMesh:
return self.__create_ckobject( return self.__create_ckobject(BMMesh, bmap.BMFile_CreateMesh)
BMMesh,
bmap.BMFile_CreateMesh
)
def create_3dobject(self) -> BM3dObject: def create_3dobject(self) -> BM3dObject:
return self.__create_ckobject( return self.__create_ckobject(BM3dObject, bmap.BMFile_Create3dObject)
BM3dObject,
bmap.BMFile_Create3dObject
)
def create_group(self) -> BMGroup: def create_group(self) -> BMGroup:
return self.__create_ckobject( return self.__create_ckobject(BMGroup, bmap.BMFile_CreateGroup)
BMGroup,
bmap.BMFile_CreateGroup
)
class BMMeshTrans(_AbstractPointer): class BMMeshTrans(_AbstractPointer):
def __init__(self): def __init__(self):
@ -795,7 +771,7 @@ class BMMeshTrans(_AbstractPointer):
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMeshTrans_PrepareVertex(self._get_pointer(), ctypes.byref(raw_vector)) bmap.BMMeshTrans_PrepareVertex(self._get_pointer(), ctypes.byref(raw_vector))
# set by pointer # set by pointer
_vxvector3_assigner(raw_vector, count, itor) _Utils.vxvector3_assigner(raw_vector, count, itor)
def prepare_normal(self, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None: def prepare_normal(self, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count) csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
@ -804,7 +780,7 @@ class BMMeshTrans(_AbstractPointer):
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p() raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMeshTrans_PrepareNormal(self._get_pointer(), ctypes.byref(raw_vector)) bmap.BMMeshTrans_PrepareNormal(self._get_pointer(), ctypes.byref(raw_vector))
_vxvector3_assigner(raw_vector, count, itor) _Utils.vxvector3_assigner(raw_vector, count, itor)
def prepare_uv(self, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None: def prepare_uv(self, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count) csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
@ -813,7 +789,7 @@ class BMMeshTrans(_AbstractPointer):
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p() raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p()
bmap.BMMeshTrans_PrepareUV(self._get_pointer(), ctypes.byref(raw_vector)) bmap.BMMeshTrans_PrepareUV(self._get_pointer(), ctypes.byref(raw_vector))
_vxvector2_assigner(raw_vector, count, itor) _Utils.vxvector2_assigner(raw_vector, count, itor)
def prepare_mtl_slot(self, count: int, itor: typing.Iterator[BMMaterial | None]) -> None: def prepare_mtl_slot(self, count: int, itor: typing.Iterator[BMMaterial | None]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count) csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
@ -853,9 +829,9 @@ class BMMeshTrans(_AbstractPointer):
# iterate and assign # iterate and assign
# assigne triple indices # assigne triple indices
_ckfaceindices_assigner(raw_vec_idx, count, vec_idx) _Utils.ckfaceindices_assigner(raw_vec_idx, count, vec_idx)
_ckfaceindices_assigner(raw_nml_idx, count, nml_idx) _Utils.ckfaceindices_assigner(raw_nml_idx, count, nml_idx)
_ckfaceindices_assigner(raw_uv_idx, count, uv_idx) _Utils.ckfaceindices_assigner(raw_uv_idx, count, uv_idx)
# assign mtl index # assign mtl index
idx: int = 0 idx: int = 0
for _ in range(count): for _ in range(count):

View File

@ -9,26 +9,71 @@ def main() -> None:
texture_folder: str = 'F:\\Ballance\\Ballance\\Textures' texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
encodings: tuple[str, ...] = ('cp1252', ) encodings: tuple[str, ...] = ('cp1252', )
with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader: with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader:
print('===== Groups =====') # print('===== Groups =====')
for gp in reader.get_groups(): # for gp in reader.get_groups():
print(gp.get_name()) # print(gp.get_name())
# for gp_item in gp.get_objects():
# print(f'\t{gp_item.get_name()}')
print('===== 3dObjects =====') # print('===== 3dObjects =====')
for obj in reader.get_3dobjects(): # for obj in reader.get_3dobjects():
print(obj.get_name()) # print(obj.get_name())
# current_mesh = obj.get_current_mesh()
# mesh_name = '<null>' if current_mesh is None else current_mesh.get_name()
# print(f'\tMesh: {mesh_name}')
# print(f'\tVisibility: {obj.get_visibility()}')
# print(f'\tMatrix: {obj.get_world_matrix().to_const()}')
print('===== Meshes =====') # print('===== Meshes =====')
for mesh in reader.get_meshs(): # for mesh in reader.get_meshs():
print(mesh.get_name()) # print(mesh.get_name())
print('===== Materials =====') # print(f'\tLit Mode: {mesh.get_lit_mode()}')
for mtl in reader.get_materials(): # print(f'\tVertex Count: {mesh.get_vertex_count()}')
print(mtl.get_name()) # print(f'\tFace Count: {mesh.get_face_count()}')
# print(f'\tMaterial Slot Count: {mesh.get_material_slot_count()}')
# print('===== Materials =====')
# for mtl in reader.get_materials():
# print(mtl.get_name())
# print(f'\tDiffuse: {mtl.get_diffuse().to_const_rgba()}')
# print(f'\tAmbient: {mtl.get_ambient().to_const_rgba()}')
# print(f'\tSpecular: {mtl.get_specular().to_const_rgba()}')
# print(f'\tEmissive: {mtl.get_emissive().to_const_rgba()}')
# print(f'\tSpecular Power: {mtl.get_specular_power()}')
# print(f'\tTexture Border Color: {mtl.get_texture_border_color().to_const_rgba()}')
# print(f'\tTexture Blend Mode: {mtl.get_texture_blend_mode()}')
# print(f'\tTexture Min Mode: {mtl.get_texture_min_mode()}')
# print(f'\tTexture Mag Mode: {mtl.get_texture_mag_mode()}')
# print(f'\tSource Blend: {mtl.get_source_blend()}')
# print(f'\tDest Blend: {mtl.get_dest_blend()}')
# print(f'\tFill Mode: {mtl.get_fill_mode()}')
# print(f'\tShade Mode: {mtl.get_shade_mode()}')
# print(f'\tAlpha Test Enabled: {mtl.get_alpha_test_enabled()}')
# print(f'\tAlpha Blend Enabled: {mtl.get_alpha_blend_enabled()}')
# print(f'\tPerspective Correction Enabled: {mtl.get_perspective_correction_enabled()}')
# print(f'\tZ Write Enabled: {mtl.get_z_write_enabled()}')
# print(f'\tTwo Sided Enabled: {mtl.get_two_sided_enabled()}')
# print(f'\tAlpha Ref: {mtl.get_alpha_ref()}')
# print(f'\tAlpha Func: {mtl.get_alpha_func()}')
# print(f'\tZ Func: {mtl.get_z_func()}')
print('===== Textures =====') print('===== Textures =====')
for tex in reader.get_textures(): for tex in reader.get_textures():
print(tex.get_name()) print(tex.get_name())
print(f'\tFile Name: {tex.get_file_name()}')
print(f'\tSave Options: {tex.get_save_options()}')
print(f'\tVideo Format: {tex.get_video_format()}')
print('===== END =====') print('===== END =====')
if __name__ == '__main__': if __name__ == '__main__':