fix: reordered init to suppress warnings and unit-conversion fix
parent
c9936b8942
commit
af358a4d32
|
@ -56,6 +56,7 @@ class ParamsFlow:
|
||||||
msg = f"Symbols in {symbol_values} don't perfectly match the ParamsFlow symbols {self.symbols}"
|
msg = f"Symbols in {symbol_values} don't perfectly match the ParamsFlow symbols {self.symbols}"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
## TODO: MutableDenseMatrix causes error with 'in' check bc it isn't hashable.
|
||||||
return [
|
return [
|
||||||
spux.scale_to_unit_system(arg, unit_system, use_jax_array=True)
|
spux.scale_to_unit_system(arg, unit_system, use_jax_array=True)
|
||||||
if arg not in symbol_values
|
if arg not in symbol_values
|
||||||
|
|
|
@ -30,6 +30,7 @@ from ... import base, events
|
||||||
log = logger.get(__name__)
|
log = logger.get(__name__)
|
||||||
|
|
||||||
FUNCS = {
|
FUNCS = {
|
||||||
|
# Number | Number
|
||||||
'ADD': lambda exprs: exprs[0] + exprs[1],
|
'ADD': lambda exprs: exprs[0] + exprs[1],
|
||||||
'SUB': lambda exprs: exprs[0] - exprs[1],
|
'SUB': lambda exprs: exprs[0] - exprs[1],
|
||||||
'MUL': lambda exprs: exprs[0] * exprs[1],
|
'MUL': lambda exprs: exprs[0] * exprs[1],
|
||||||
|
|
|
@ -974,16 +974,19 @@ class MaxwellSimNode(bpy.types.Node, bl_instance.BLInstance):
|
||||||
Notes:
|
Notes:
|
||||||
Run by Blender when a new instance of a node is added to a tree.
|
Run by Blender when a new instance of a node is added to a tree.
|
||||||
"""
|
"""
|
||||||
# Initialize Sockets
|
|
||||||
## -> Ensures the availability of static sockets before items/methods.
|
|
||||||
## -> Ensures the availability of static sockets before items/methods.
|
|
||||||
self._sync_sockets()
|
|
||||||
|
|
||||||
# Initialize Instance ID
|
# Initialize Instance ID
|
||||||
## -> This is used by various caches from 'bl_cache'.
|
## -> This is used by various caches from 'bl_cache'.
|
||||||
## -> Also generates (first-time) the various enums.
|
## -> Also generates (first-time) the various enums.
|
||||||
self.reset_instance_id()
|
self.reset_instance_id()
|
||||||
|
|
||||||
|
# Initialize Sockets
|
||||||
|
## -> Ensures the availability of static sockets before dynamic fields.
|
||||||
|
self._sync_sockets()
|
||||||
|
|
||||||
|
# Initialize Dynamic Field Persistance
|
||||||
|
## -> Ensures the availability of enum items for subsequent setters.
|
||||||
|
self.regenerate_dynamic_field_persistance()
|
||||||
|
|
||||||
# Initialize Name
|
# Initialize Name
|
||||||
## -> Ensures the availability of sim_node_name immediately.
|
## -> Ensures the availability of sim_node_name immediately.
|
||||||
self.sim_node_name = self.name
|
self.sim_node_name = self.name
|
||||||
|
|
|
@ -51,6 +51,7 @@ class SocketDef(pyd.BaseModel, abc.ABC):
|
||||||
bl_socket: The Blender node socket to alter using data from this SocketDef.
|
bl_socket: The Blender node socket to alter using data from this SocketDef.
|
||||||
"""
|
"""
|
||||||
bl_socket.reset_instance_id()
|
bl_socket.reset_instance_id()
|
||||||
|
bl_socket.regenerate_dynamic_field_persistance()
|
||||||
|
|
||||||
def postinit(self, bl_socket: bpy.types.NodeSocket) -> None:
|
def postinit(self, bl_socket: bpy.types.NodeSocket) -> None:
|
||||||
"""Pre-initialize a real Blender node socket from this socket definition.
|
"""Pre-initialize a real Blender node socket from this socket definition.
|
||||||
|
@ -205,11 +206,12 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance):
|
||||||
"""
|
"""
|
||||||
## TODO: Evaluate this properly
|
## TODO: Evaluate this properly
|
||||||
if self.is_initializing:
|
if self.is_initializing:
|
||||||
log.debug(
|
pass
|
||||||
'%s: Rejected on_prop_changed("%s") while initializing',
|
# log.debug(
|
||||||
self.bl_label,
|
# '%s: Rejected on_prop_changed("%s") while initializing',
|
||||||
prop_name,
|
# self.bl_label,
|
||||||
)
|
# prop_name,
|
||||||
|
# )
|
||||||
elif hasattr(self, prop_name):
|
elif hasattr(self, prop_name):
|
||||||
# Property Callbacks: Active Kind
|
# Property Callbacks: Active Kind
|
||||||
if prop_name == 'active_kind':
|
if prop_name == 'active_kind':
|
||||||
|
|
|
@ -214,9 +214,7 @@ class ExprBLSocket(base.MaxwellSimSocket):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@bl_cache.cached_bl_property()
|
prev_unit: str | None = bl_cache.BLField(None)
|
||||||
def prev_unit(self) -> spux.Unit | None:
|
|
||||||
return self.unit
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Prop-Change Callback
|
# - Prop-Change Callback
|
||||||
|
@ -231,19 +229,21 @@ class ExprBLSocket(base.MaxwellSimSocket):
|
||||||
## -> 1. "Laggy" unit must be different than new unit.
|
## -> 1. "Laggy" unit must be different than new unit.
|
||||||
## -> 2. Unit-conversion of value only within same physical_type
|
## -> 2. Unit-conversion of value only within same physical_type
|
||||||
## -> 3. Never unit-convert expressions w/symbolic variables
|
## -> 3. Never unit-convert expressions w/symbolic variables
|
||||||
## No matter what, prev_unit is always re-armed.
|
## No matter what, prev_unit is always regenerated.
|
||||||
|
prev_unit = (
|
||||||
|
spux.unit_str_to_unit(self.prev_unit)
|
||||||
|
if self.prev_unit is not None
|
||||||
|
else None
|
||||||
|
)
|
||||||
if (
|
if (
|
||||||
self.prev_unit != self.unit
|
prev_unit != self.unit
|
||||||
and self.prev_unit in self.physical_type.valid_units
|
and prev_unit in self.physical_type.valid_units
|
||||||
and not self.symbols
|
and not self.symbols
|
||||||
):
|
):
|
||||||
log.critical(self.value, self.prev_unit, self.unit)
|
self.value = self.value.subs({self.unit: prev_unit})
|
||||||
self.value = spu.convert_to(self.value, self.prev_unit)
|
self.lazy_array_range = self.lazy_array_range.correct_unit(prev_unit)
|
||||||
log.critical(self.value, self.prev_unit, self.unit)
|
|
||||||
self.lazy_array_range = self.lazy_array_range.rescale_to_unit(
|
self.prev_unit = self.active_unit
|
||||||
self.prev_unit
|
|
||||||
)
|
|
||||||
self.prev_unit = bl_cache.Signal.InvalidateCache
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Value Utilities
|
# - Value Utilities
|
||||||
|
@ -378,18 +378,22 @@ class ExprBLSocket(base.MaxwellSimSocket):
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
NS.Vec2: {
|
NS.Vec2: {
|
||||||
MT_Z: lambda: sp.Matrix([Z(i) for i in self.raw_value_int2]),
|
MT_Z: lambda: sp.ImmutableMatrix([Z(i) for i in self.raw_value_int2]),
|
||||||
MT_Q: lambda: sp.Matrix([Q(q[0], q[1]) for q in self.raw_value_rat2]),
|
MT_Q: lambda: sp.ImmutableMatrix(
|
||||||
MT_R: lambda: sp.Matrix([R(r) for r in self.raw_value_float2]),
|
[Q(q[0], q[1]) for q in self.raw_value_rat2]
|
||||||
MT_C: lambda: sp.Matrix(
|
),
|
||||||
|
MT_R: lambda: sp.ImmutableMatrix([R(r) for r in self.raw_value_float2]),
|
||||||
|
MT_C: lambda: sp.ImmutableMatrix(
|
||||||
[c[0] + sp.I * c[1] for c in self.raw_value_complex2]
|
[c[0] + sp.I * c[1] for c in self.raw_value_complex2]
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
NS.Vec3: {
|
NS.Vec3: {
|
||||||
MT_Z: lambda: sp.Matrix([Z(i) for i in self.raw_value_int3]),
|
MT_Z: lambda: sp.ImmutableMatrix([Z(i) for i in self.raw_value_int3]),
|
||||||
MT_Q: lambda: sp.Matrix([Q(q[0], q[1]) for q in self.raw_value_rat3]),
|
MT_Q: lambda: sp.ImmutableMatrix(
|
||||||
MT_R: lambda: sp.Matrix([R(r) for r in self.raw_value_float3]),
|
[Q(q[0], q[1]) for q in self.raw_value_rat3]
|
||||||
MT_C: lambda: sp.Matrix(
|
),
|
||||||
|
MT_R: lambda: sp.ImmutableMatrix([R(r) for r in self.raw_value_float3]),
|
||||||
|
MT_C: lambda: sp.ImmutableMatrix(
|
||||||
[c[0] + sp.I * c[1] for c in self.raw_value_complex3]
|
[c[0] + sp.I * c[1] for c in self.raw_value_complex3]
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -1185,11 +1189,13 @@ class ExprSocketDef(base.SocketDef):
|
||||||
# FlowKind.Value
|
# FlowKind.Value
|
||||||
## -> We must take units into account when setting bl_socket.value
|
## -> We must take units into account when setting bl_socket.value
|
||||||
if self.physical_type is not spux.PhysicalType.NonPhysical:
|
if self.physical_type is not spux.PhysicalType.NonPhysical:
|
||||||
self.active_unit = sp.sstr(self.default_unit)
|
bl_socket.active_unit = sp.sstr(self.default_unit)
|
||||||
bl_socket.value = self.default_value * self.default_unit
|
bl_socket.value = self.default_value * self.default_unit
|
||||||
else:
|
else:
|
||||||
bl_socket.value = self.default_value
|
bl_socket.value = self.default_value
|
||||||
|
|
||||||
|
bl_socket.prev_unit = bl_socket.active_unit
|
||||||
|
|
||||||
# FlowKind.LazyArrayRange
|
# FlowKind.LazyArrayRange
|
||||||
## -> We can directly pass None to unit.
|
## -> We can directly pass None to unit.
|
||||||
bl_socket.lazy_array_range = ct.LazyArrayRangeFlow(
|
bl_socket.lazy_array_range = ct.LazyArrayRangeFlow(
|
||||||
|
|
|
@ -75,6 +75,9 @@ class CachedBLProperty:
|
||||||
|
|
||||||
self.decode_type: type = inspect.signature(getter_method).return_annotation
|
self.decode_type: type = inspect.signature(getter_method).return_annotation
|
||||||
|
|
||||||
|
# Write Suppressing
|
||||||
|
self.suppress_write: dict[str, bool] = {}
|
||||||
|
|
||||||
# Check Non-Empty Type Annotation
|
# Check Non-Empty Type Annotation
|
||||||
## For now, just presume that all types can be encoded/decoded.
|
## For now, just presume that all types can be encoded/decoded.
|
||||||
if self.decode_type is inspect.Signature.empty:
|
if self.decode_type is inspect.Signature.empty:
|
||||||
|
@ -122,6 +125,10 @@ class CachedBLProperty:
|
||||||
return Signal.CacheNotReady
|
return Signal.CacheNotReady
|
||||||
return cached_value
|
return cached_value
|
||||||
|
|
||||||
|
def suppress_next_write(self, bl_instance) -> None:
|
||||||
|
self.suppress_write[bl_instance.instance_id] = True
|
||||||
|
## TODO: Make it a context manager to prevent the worst of surprises
|
||||||
|
|
||||||
def __set__(
|
def __set__(
|
||||||
self, bl_instance: bl_instance.BLInstance | None, value: typ.Any
|
self, bl_instance: bl_instance.BLInstance | None, value: typ.Any
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -144,7 +151,10 @@ class CachedBLProperty:
|
||||||
# Fill Caches
|
# Fill Caches
|
||||||
## -> persist: Fill Persist and Non-Persist Cache
|
## -> persist: Fill Persist and Non-Persist Cache
|
||||||
## -> else: Fill Non-Persist Cache
|
## -> else: Fill Non-Persist Cache
|
||||||
if self.persist:
|
if self.persist and not self.suppress_write.get(
|
||||||
|
bl_instance.instance_id
|
||||||
|
):
|
||||||
|
self.suppress_next_write(bl_instance)
|
||||||
self.bl_prop.write(bl_instance, self.getter_method(bl_instance))
|
self.bl_prop.write(bl_instance, self.getter_method(bl_instance))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -162,7 +172,7 @@ class CachedBLProperty:
|
||||||
self.setter_method(bl_instance, value)
|
self.setter_method(bl_instance, value)
|
||||||
|
|
||||||
# Fill Non-Persistant (and maybe Persistent) Cache
|
# Fill Non-Persistant (and maybe Persistent) Cache
|
||||||
if self.persist:
|
if self.persist and not self.suppress_write.get(bl_instance.instance_id):
|
||||||
self.bl_prop.write(bl_instance, self.getter_method(bl_instance))
|
self.bl_prop.write(bl_instance, self.getter_method(bl_instance))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
import typing as typ
|
import typing as typ
|
||||||
|
|
||||||
from blender_maxwell import contracts as ct
|
|
||||||
from blender_maxwell.utils import bl_instance, logger
|
from blender_maxwell.utils import bl_instance, logger
|
||||||
|
|
||||||
from .signal import Signal
|
from .signal import Signal
|
||||||
|
@ -94,8 +93,9 @@ def read(
|
||||||
# Check if Instance ID is Available
|
# Check if Instance ID is Available
|
||||||
if not bl_instance.instance_id:
|
if not bl_instance.instance_id:
|
||||||
log.debug(
|
log.debug(
|
||||||
"Can't Get CachedBLProperty: Instance ID not (yet) defined on bl_instance.BLInstance %s",
|
'%s (Non-Persist): Tried read() (key=%s), but Instance ID not (yet) defined',
|
||||||
str(bl_instance),
|
str(bl_instance),
|
||||||
|
str(key),
|
||||||
)
|
)
|
||||||
return Signal.CacheNotReady
|
return Signal.CacheNotReady
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,6 @@ class BLInstance:
|
||||||
The Instance ID is a `UUID4`, which is globally unique, negating the need for extraneous overlap-checks.
|
The Instance ID is a `UUID4`, which is globally unique, negating the need for extraneous overlap-checks.
|
||||||
"""
|
"""
|
||||||
self.instance_id = str(uuid.uuid4())
|
self.instance_id = str(uuid.uuid4())
|
||||||
self.regenerate_dynamic_field_persistance()
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def assert_attrs_valid(cls, mandatory_props: set[str]) -> None:
|
def assert_attrs_valid(cls, mandatory_props: set[str]) -> None:
|
||||||
|
|
Loading…
Reference in New Issue