- Add body_mesh submodule with VRM_OT_separate_non_skin_faces operator - Add VRM_PT_body_mesh_separator panel for UI integration - Add utility functions for mesh operations and edge dissolution logic - Add comprehensive edge dissolution configuration files for all body parts (head, torso, arms, legs, hands) with UV coordinates - Add test utilities for validating mesh separation operations - Add .gitignore to exclude Python cache files and test artifacts - Register body_mesh module in editor package initialization - Update registration.py to include new body mesh components
61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
# SPDX-License-Identifier: MIT OR GPL-3.0-or-later
|
|
"""
|
|
Property-based tests for body_mesh utility functions.
|
|
|
|
Feature: vrm-body-mesh-separator
|
|
"""
|
|
from hypothesis import given, settings
|
|
from hypothesis import strategies as st
|
|
|
|
from .utils import generate_unique_name, is_skin_material
|
|
|
|
|
|
class TestIsSkinMaterial:
|
|
"""
|
|
Property 2: 材质分类正确性
|
|
*For any* 材质名称字符串,`is_skin_material`函数应该返回True当且仅当该名称包含"SKIN"子字符串(不区分大小写)。
|
|
**Validates: Requirements 2.2, 2.3**
|
|
"""
|
|
|
|
@given(st.text())
|
|
@settings(max_examples=100)
|
|
def test_skin_material_classification_property(self, material_name: str) -> None:
|
|
"""
|
|
Feature: vrm-body-mesh-separator, Property 2: 材质分类正确性
|
|
For any material name string, is_skin_material returns True
|
|
if and only if the name contains "SKIN" (case-insensitive).
|
|
"""
|
|
result = is_skin_material(material_name)
|
|
expected = "SKIN" in material_name.upper()
|
|
assert result == expected, (
|
|
f"is_skin_material('{material_name}') returned {result}, "
|
|
f"expected {expected}"
|
|
)
|
|
|
|
|
|
class TestGenerateUniqueName:
|
|
"""
|
|
Property 6: 唯一命名保证
|
|
*For any* 基础名称和已存在名称集合,`generate_unique_name`返回的名称不应该在已存在名称集合中。
|
|
**Validates: Requirements 4.2**
|
|
"""
|
|
|
|
@given(
|
|
st.text(min_size=1, max_size=50).filter(lambda x: x.strip()),
|
|
st.sets(st.text(min_size=1, max_size=50), max_size=20),
|
|
)
|
|
@settings(max_examples=100)
|
|
def test_unique_name_generation_property(
|
|
self, base_name: str, existing_names: set[str]
|
|
) -> None:
|
|
"""
|
|
Feature: vrm-body-mesh-separator, Property 6: 唯一命名保证
|
|
For any base name and set of existing names, generate_unique_name
|
|
returns a name that is not in the existing names set.
|
|
"""
|
|
result = generate_unique_name(base_name, existing_names)
|
|
assert result not in existing_names, (
|
|
f"generate_unique_name('{base_name}', {existing_names}) "
|
|
f"returned '{result}' which is in existing_names"
|
|
)
|