basic working version
This commit is contained in:
117
addons/io_scene_swbf_msh/msh_model_utilities.py
Normal file
117
addons/io_scene_swbf_msh/msh_model_utilities.py
Normal file
@@ -0,0 +1,117 @@
|
||||
""" Utilities for operating on msh_model objects. """
|
||||
|
||||
from typing import List
|
||||
from .msh_model import *
|
||||
from .msh_utilities import *
|
||||
from mathutils import Vector, Matrix
|
||||
|
||||
def scale_segments(scale: Vector, segments: List[GeometrySegment]):
|
||||
""" Scales are positions in the GeometrySegment list. """
|
||||
|
||||
for segment in segments:
|
||||
for pos in segment.positions:
|
||||
pos = mul_vec(pos, scale)
|
||||
|
||||
def get_model_world_matrix(model: Model, models: List[Model]) -> Matrix:
|
||||
""" Gets a Blender Matrix for transforming the model into world space. """
|
||||
|
||||
transform_stack: List[ModelTransform] = [model.transform]
|
||||
transform_stack.extend((parent.transform for parent in get_model_ancestors(model, models)))
|
||||
|
||||
world_matrix: Matrix = Matrix()
|
||||
|
||||
for transform in reversed(transform_stack):
|
||||
translation_matrix = Matrix.Translation(transform.translation)
|
||||
rotation_matrix = transform.rotation.to_matrix().to_4x4()
|
||||
|
||||
world_matrix = world_matrix @ (translation_matrix @ rotation_matrix)
|
||||
|
||||
return world_matrix
|
||||
|
||||
def sort_by_parent(models: List[Model]) -> List[Model]:
|
||||
""" Sorts a Model list so that models are ordered by their parent.
|
||||
Required for some tools to be able to load .msh files. """
|
||||
|
||||
sorted_models: List[Model] = []
|
||||
|
||||
for root in get_root_models(models):
|
||||
def add_children(model: Model):
|
||||
nonlocal sorted_models
|
||||
|
||||
for child in get_model_children(model, models):
|
||||
sorted_models.append(child)
|
||||
add_children(child)
|
||||
|
||||
sorted_models.append(root)
|
||||
add_children(root)
|
||||
|
||||
return sorted_models
|
||||
|
||||
def reparent_model_roots(models: List[Model]) -> List[Model]:
|
||||
""" Reparents all root models in a list to a new empty node. """
|
||||
|
||||
new_root: Model = Model()
|
||||
new_root.name = get_unique_scene_root_name(models)
|
||||
|
||||
for model in models:
|
||||
if not model.parent:
|
||||
model.parent = new_root.name
|
||||
|
||||
models.insert(0, new_root)
|
||||
|
||||
return models
|
||||
|
||||
def has_multiple_root_models(models: List[Model]) -> bool:
|
||||
""" Checks if a list of Model objects has multiple roots. """
|
||||
|
||||
return sum(1 for root in get_root_models(models)) > 1
|
||||
|
||||
def get_root_models(models: List[Model]) -> Model:
|
||||
""" Generator. Returns all Model objects in a list with no parent. """
|
||||
|
||||
for model in models:
|
||||
if model.parent == "":
|
||||
yield model
|
||||
|
||||
def get_model_children(parent: Model, models: List[Model]) -> Model:
|
||||
""" Generator. Returns all Model objects in a list whose parent is
|
||||
the supplied model. """
|
||||
|
||||
for model in models:
|
||||
if parent.name == model.parent:
|
||||
yield model
|
||||
|
||||
def get_model_ancestors(child: Model, models: List[Model]) -> Model:
|
||||
""" Generator. Yields the parent for a model, then yields the parent's parent,
|
||||
repeating until at the root model. """
|
||||
|
||||
for model in models:
|
||||
if child.parent == model.name:
|
||||
child = model
|
||||
yield model
|
||||
|
||||
def get_unique_scene_root_name(models: List[Model]) -> Model:
|
||||
""" Returns a unique model name of the form of either "SceneRoot" or
|
||||
"SceneRoot{i}". """
|
||||
|
||||
name: str = "SceneRoot"
|
||||
|
||||
if is_model_name_unused(name, models):
|
||||
return name
|
||||
|
||||
for i in range(len(models) + 1):
|
||||
name = f"SceneRoot{i}"
|
||||
|
||||
if is_model_name_unused(name, models):
|
||||
return name
|
||||
|
||||
return name
|
||||
|
||||
def is_model_name_unused(name: str, models: List[Model]) -> bool:
|
||||
""" Checks if there is no Model using a name in a list of models. """
|
||||
|
||||
for model in models:
|
||||
if model.name == name:
|
||||
return False
|
||||
|
||||
return True
|
||||
Reference in New Issue
Block a user