Structure
Reference for Structure, which binds one geometry to one material with stable IDs, UVs and a phase screen, and for MaterialAssignment.
Structure and MaterialAssignment live in witwin.core.structure and are exported from witwin.core. Before 0.4.0, Structure lived in witwin.core.material; imports from witwin.core did not change.
from witwin.core import MaterialAssignment, StructureStructure#
class Structure(
geometry: GeometrySpec,
material: MaterialSpec,
name: str | None = None,
priority: int = 0,
enabled: bool = True,
tags=(),
metadata: Mapping[str, Any] | None = None,
*,
structure_id: StructureId | int | None = None,
material_id: MaterialId | int | None = None,
assignment_id: AssignmentId | int | None = None,
surface_id: SurfaceId | int | None = None,
primitive_ids=(),
phase_screen: PhaseScreen | None = None,
uv: torch.Tensor | None = None,
face_uv: torch.Tensor | None = None,
)One geometry bound to one material, with the IDs solvers use. Immutable (frozen dataclass).
Any object with kind and to_mesh(). Raises TypeError otherwise.
Any object with name, capabilities(), evaluate_static() and evaluate_at_frequency(). Raises TypeError otherwise.
NoneA label. Converted to str.
0Stored for solvers, for example to resolve overlaps. Core does not use it.
TrueStored for solvers and tools. Core does not use it; a disabled structure is still part of the scene.
()Labels, stored as a tuple of strings.
NoneFree-form data, stored as a read-only mapping.
NoneNone allocates a new ID; an integer reserves it. Must be at least 0.
NoneNone takes material.material_id when the material has one (every PhysicalMaterial does), else allocates a new ID.
NoneNone allocates; an integer reserves.
NoneNone allocates; an integer reserves.
()Explicit IDs for the structure's primitives (for example triangles). Empty or None means "derive them", see primitive_id.
NoneA height map for this structure's surface. Raises TypeError for another type.
NoneTexture coordinates, shape (T, 2), floating point. Requires face_uv.
NoneUV indices per face, shape (F, 3), int32 or int64, one row per mesh face. Requires uv and a geometry with a faces tensor (a Mesh). UV and mesh tensors must share a device.
Raises ValueError when only one of uv and face_uv is given or their shapes are wrong, and TypeError for wrong dtypes or a geometry without mesh faces.
Attributes#
All constructor arguments are attributes with the same names. tags is a tuple, metadata a read-only mapping, and each *_id holds the resolved ID. primitive_ids is None when none were given.
Structure.primitive_id#
primitive_id(local_index: int) -> PrimitiveIdReturns the stable ID of the primitive at local_index. With explicit primitive_ids it returns primitive_ids[local_index] (raises IndexError past the end). Otherwise it returns (structure_id << 32) | local_index. Raises ValueError for a negative index or one that does not fit in 32 bits.
import torch
from witwin.core import Mesh, PhysicalMaterial, Structure
quad = Mesh(
torch.tensor([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]]),
torch.tensor([[0, 1, 2], [0, 2, 3]]),
fill_mode="surface",
)
tile = Structure(
quad,
PhysicalMaterial(eps_r=4.0),
structure_id=3,
uv=torch.tensor([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]),
face_uv=torch.tensor([[0, 1, 2], [0, 2, 3]]),
)
print(tile.primitive_id(1)) # 12884901889 == (3 << 32) | 1Note
GeometryBase.with_material(material, **kwargs) was meant as a shortcut for Structure(geometry, material, **kwargs). In 0.4.0 it raises ImportError. Call Structure(...) directly.
MaterialAssignment#
@dataclass(frozen=True)
class MaterialAssignment:
assignment_id: AssignmentId
surface_id: SurfaceId
material_id: MaterialId
material: MaterialSpec
phase_screen: PhaseScreen | None = NoneWhich material, and which phase screen, covers which surface. Scene.assignments returns one per structure. Raises TypeError when material is not a MaterialSpec or phase_screen is not a PhaseScreen.