"""Vector component promote/demote conversion registrations.
These conversions are machine-agnostic adapters that split Vec3/Vec4
attributes into named float components, or rebuild vectors from floats.
Attribute names are chosen by the caller at registration time.
"""
import pyvcad as pv
from pyvcad_attribute_resolver.registry import register_conversion
from .data import VECTOR_COMPONENTS_TAG
def _vec3_to_scalars_factory(source, x_name, y_name, z_name):
def _factory():
return pv.Vec3ToScalarsConverter(source, x_name, y_name, z_name)
return _factory
def _vec4_to_scalars_factory(source, x_name, y_name, z_name, w_name):
def _factory():
return pv.Vec4ToScalarsConverter(source, x_name, y_name, z_name, w_name)
return _factory
def _scalars_to_vec3_factory(x_name, y_name, z_name, target):
def _factory():
return pv.ScalarsToVec3Converter(x_name, y_name, z_name, target)
return _factory
def _scalars_to_vec4_factory(x_name, y_name, z_name, w_name, target):
def _factory():
return pv.ScalarsToVec4Converter(x_name, y_name, z_name, w_name, target)
return _factory
[docs]
def register_vec3_to_scalars_conversions(source, x_name, y_name, z_name):
"""Register Vec3 demotion edges that produce three named float attributes.
One converter instance produces all three outputs. Separate graph edges are
registered for each component so ``adapt(..., [x_name])`` (and likewise for
Y/Z) can discover the conversion.
"""
factory = _vec3_to_scalars_factory(source, x_name, y_name, z_name)
for target in (x_name, y_name, z_name):
register_conversion(
source=source,
target=target,
converter_factory=factory,
name=f"vector_components_{source}_to_{target}",
priority=0,
tags=[VECTOR_COMPONENTS_TAG],
)
[docs]
def register_vec4_to_scalars_conversions(source, x_name, y_name, z_name, w_name):
"""Register Vec4 demotion edges that produce four named float attributes."""
factory = _vec4_to_scalars_factory(source, x_name, y_name, z_name, w_name)
for target in (x_name, y_name, z_name, w_name):
register_conversion(
source=source,
target=target,
converter_factory=factory,
name=f"vector_components_{source}_to_{target}",
priority=0,
tags=[VECTOR_COMPONENTS_TAG],
)
[docs]
def register_scalars_to_vec3_conversions(x_name, y_name, z_name, target):
"""Register a multi-input conversion that builds a Vec3 from three floats."""
register_conversion(
source=x_name,
target=target,
converter_factory=_scalars_to_vec3_factory(x_name, y_name, z_name, target),
name=f"vector_components_{x_name}_{y_name}_{z_name}_to_{target}",
priority=0,
tags=[VECTOR_COMPONENTS_TAG],
required_inputs=[x_name, y_name, z_name],
)
[docs]
def register_scalars_to_vec4_conversions(x_name, y_name, z_name, w_name, target):
"""Register a multi-input conversion that builds a Vec4 from four floats."""
register_conversion(
source=x_name,
target=target,
converter_factory=_scalars_to_vec4_factory(
x_name, y_name, z_name, w_name, target
),
name=f"vector_components_{x_name}_{y_name}_{z_name}_{w_name}_to_{target}",
priority=0,
tags=[VECTOR_COMPONENTS_TAG],
required_inputs=[x_name, y_name, z_name, w_name],
)
[docs]
def register_vector_component_conversions(
vec3_source=None,
vec3_x=None,
vec3_y=None,
vec3_z=None,
vec4_source=None,
vec4_x=None,
vec4_y=None,
vec4_z=None,
vec4_w=None,
register_demote=True,
register_promote=True,
):
"""Register demote and/or promote conversions for the supplied attribute names.
Pass a complete Vec3 name set and/or a complete Vec4 name set. Incomplete
name sets are ignored. At least one complete set must be provided.
"""
has_vec3 = None not in (vec3_source, vec3_x, vec3_y, vec3_z)
has_vec4 = None not in (vec4_source, vec4_x, vec4_y, vec4_z, vec4_w)
if not has_vec3 and not has_vec4:
raise ValueError(
"Provide a complete Vec3 name set and/or a complete Vec4 name set."
)
if has_vec3:
if register_demote:
register_vec3_to_scalars_conversions(vec3_source, vec3_x, vec3_y, vec3_z)
if register_promote:
register_scalars_to_vec3_conversions(vec3_x, vec3_y, vec3_z, vec3_source)
if has_vec4:
if register_demote:
register_vec4_to_scalars_conversions(
vec4_source, vec4_x, vec4_y, vec4_z, vec4_w
)
if register_promote:
register_scalars_to_vec4_conversions(
vec4_x, vec4_y, vec4_z, vec4_w, vec4_source
)
__all__ = [
"register_vector_component_conversions",
"register_vec3_to_scalars_conversions",
"register_vec4_to_scalars_conversions",
"register_scalars_to_vec3_conversions",
"register_scalars_to_vec4_conversions",
]