voxcity.importer.loader

Load OBJ geometry groups and route them to import roles (e.g. building vs. window/non-building) before voxelization.

An OBJ file may bundle multiple named objects/groups in a single export (e.g. a Rhino layer-per-group export). load_obj_groups recovers those as separate named meshes; classify_roles/select_building_groups let a caller mark some groups as non-building (windows, context, site furniture, …) so only the actual building geometry gets voxelized.

Attributes

Functions

group_material_name(→ Optional[str])

Return the group's assigned OBJ material name, or None.

load_obj_groups(→ List[Tuple[str, trimesh.Trimesh]])

Load obj_path and return its geometry as a list of (name, mesh).

classify_roles(→ Dict[str, str])

Map each group name to its import role, defaulting to "building".

select_groups_by_role(→ Dict[str, List[Tuple[str, ...)

Bucket (name, mesh) groups by resolved role.

select_building_groups(→ List[Tuple[str, trimesh.Trimesh]])

Return only the building-role groups (back-compat wrapper).

Module Contents

voxcity.importer.loader.DEFAULT_WINDOW_KEYWORDS = ('window', 'glass', 'glazing')
voxcity.importer.loader.group_material_name(mesh) str | None[source]

Return the group’s assigned OBJ material name, or None.

trimesh exposes the material name on TextureVisuals as mesh.visual.material.name. ColorVisuals / untextured meshes (or any missing attribute) yield None so callers fall back to name-only matching.

voxcity.importer.loader.load_obj_groups(obj_path, swap_yz: bool = False) List[Tuple[str, trimesh.Trimesh]][source]

Load obj_path and return its geometry as a list of (name, mesh).

Parameters:
  • obj_path – path to an OBJ file.

  • swap_yz – if True, return copies of each mesh with axes 1 and 2 (Y/Z) swapped, to reconcile Rhino’s Z-up convention with Y-up OBJ exporters. The originally loaded meshes are never mutated.

Returns:

List of (name, mesh) tuples, in the order the geometry was discovered. trimesh collapses an OBJ to a single, unnamed Trimesh (rather than a Scene) whenever the file resolves to only one geometry group — this includes both OBJs with no named scene structure at all and OBJs containing exactly one named o <name> block, since trimesh discards that name in the single-group case. In that situation named parts are recovered first from g <name> group directives (which trimesh otherwise ignores, e.g. g building / g window), then by splitting on material (so e.g. a Glass material becomes its own window-detectable group); if neither yields 2+ groups, a single group named "imported_building_1" is returned.

Raises:
  • FileNotFoundError – if obj_path does not exist or is not a file (e.g. a directory path).

  • ValueError – if the file loads but contains no usable mesh geometry.

voxcity.importer.loader.classify_roles(names: Iterable[str], roles: Dict[str, str] | None = None, *, auto_window: bool = True, window_keywords=DEFAULT_WINDOW_KEYWORDS, material_names: Dict[str, str | None] | None = None) Dict[str, str][source]

Map each group name to its import role, defaulting to "building".

Resolution order per name:
  1. explicit roles[name] if present (overrides everything),

  2. else "window" if auto_window and the group name OR its material name (from material_names) contains a window keyword (case-insensitive substring),

  3. else "building".

Matching against roles is exact string match only. material_names is an optional {name: material_name} mapping; absent/None material names simply skip the material-based check.

voxcity.importer.loader.select_groups_by_role(groups: List[Tuple[str, trimesh.Trimesh]], roles: Dict[str, str] | None = None, *, auto_window: bool = True, window_keywords=DEFAULT_WINDOW_KEYWORDS) Dict[str, List[Tuple[str, trimesh.Trimesh]]][source]

Bucket (name, mesh) groups by resolved role.

Returns {"building": [...], "window": [...]}. Material names are read from each mesh via group_material_name(), so window detection by name or material both work. Any other/unknown role (e.g. "skip") is dropped and logged at INFO.

voxcity.importer.loader.select_building_groups(groups: List[Tuple[str, trimesh.Trimesh]], roles: Dict[str, str] | None = None) List[Tuple[str, trimesh.Trimesh]][source]

Return only the building-role groups (back-compat wrapper).

With auto window detection on by default, groups whose name or material marks them as windows are excluded here (they belong to the "window" bucket of select_groups_by_role()).