feat(body_mesh): Add body mesh separator module with edge dissolution
- 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
This commit is contained in:
60
editor/body_mesh/test_utils.py
Normal file
60
editor/body_mesh/test_utils.py
Normal file
@@ -0,0 +1,60 @@
|
||||
# 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"
|
||||
)
|
||||
Reference in New Issue
Block a user