voxcity.importer.rhino_obj ========================== .. py:module:: voxcity.importer.rhino_obj .. autoapi-nested-parse:: Public entry point: add buildings from an OBJ file to a VoxCity model. Functions --------- .. autoapisummary:: voxcity.importer.rhino_obj.add_buildings_from_obj Module Contents --------------- .. py:function:: add_buildings_from_obj(voxcity, obj_path, anchor_lonlat, anchor_elevation, anchor_model_point=(0.0, 0.0, 0.0), rotation=0.0, move=(0.0, 0.0, 0.0), units='m', roles=None, backend='trimesh', z_up=True, swap_yz=False, overwrite=True, auto_window=True, window_keywords=None, window_value=-16, gridvis=False) Voxelize buildings from an OBJ file and stamp them into a VoxCity model. Loads geometry groups from *obj_path*, selects the groups whose resolved role is ``"building"``, places them into the VoxCity domain using an anchor lon/lat + elevation (plus optional rotation/translation/unit scaling), voxelizes each building group, and stamps the resulting cells into a copy of *voxcity*. The input *voxcity* is never mutated; this function always returns a new object. See docs/rhino_obj_import.md for the Rhino export guide and conventions. :param voxcity: source VoxCity object. Read for its grid geometry (``extras['rectangle_vertices']``), voxel shape, DEM, and existing building grids; never mutated. A deep copy is made internally and returned (with buildings stamped in), or returned unmodified (still a deep copy) if no in-domain geometry is found. :param obj_path: path to the OBJ file to import. Must exist on disk; checked before any other validation. :param anchor_lonlat: ``(lon, lat)`` pair giving the geographic position that ``anchor_model_point`` is placed at. Must have exactly 2 elements. :param anchor_elevation: elevation (metres) of ``anchor_model_point`` in the real world. Combined with the VoxCity DEM minimum to fix the vertical (Z) placement of the model. :param anchor_model_point: ``(x, y, z)`` point in OBJ model coordinates (in *units*, pre-scale) that is pinned to ``anchor_lonlat`` / ``anchor_elevation``. Defaults to the model origin ``(0.0, 0.0, 0.0)``. :param rotation: rotation in degrees applied to the model in the horizontal (east/north) plane before placement. Positive values rotate the model counter-clockwise; e.g. at ``rotation=90``, model +X ends up pointing north. Defaults to ``0.0`` (no rotation). :param move: ``(east, north, up)`` offset in metres applied after anchoring, e.g. for fine-tuning placement without changing the anchor. Defaults to ``(0.0, 0.0, 0.0)`` (no offset). :param units: model length unit, used to scale OBJ coordinates to metres. One of ``"m"``, ``"cm"``, ``"mm"``, ``"ft"``, ``"in"`` (case-insensitive). Defaults to ``"m"``. :param roles: optional ``{group_name: role}`` mapping overriding the auto-detected role of a group. Recognized roles: ``"building"`` (voxelized solid as ``-3``), ``"window"`` (surface-voxelized and stamped as glass ``-16`` on the building facade it touches), and ``"skip"`` (excluded). Matching is exact-string only. Groups absent from this mapping are auto-classified (see ``auto_window``). :param backend: voxelization backend. ``"trimesh"`` (default) uses :func:`~voxcity.importer.voxelize.voxelize_mesh` (column z-ray casting). ``"meshlib"`` uses the optional :func:`~voxcity.importer.voxelize.voxelize_mesh_meshlib` SDF backend, which requires the optional ``meshlib`` package to be installed (see Raises below); this backend is best-effort and not empirically verified against a real MeshLib install (see that function's docstring for details). :param z_up: whether the OBJ's vertical axis is already Z-up (Rhino's convention), the default (``True``). When ``False``, the loaded mesh is treated as Y-up and axes 1/2 (Y/Z) are swapped before placement, equivalent to setting ``swap_yz=True``. :param swap_yz: if ``True``, force an explicit Y/Z axis swap on the loaded geometry regardless of ``z_up``. Defaults to ``False``. The effective swap applied is ``swap_yz or (not z_up)``. :param overwrite: if ``True`` (default), newly stamped building voxels overwrite any existing non-empty voxel at that cell (and the collision is counted/logged). If ``False``, only cells that are currently empty are stamped; already-occupied cells are left untouched. :param auto_window: if ``True`` (default), groups whose name or assigned OBJ material name contains a window keyword (see ``window_keywords``) are auto-classified as ``"window"``. An explicit ``roles`` entry always overrides this. :param window_keywords: optional iterable of case-insensitive substrings used for window auto-detection. ``None`` (default) uses ``("window", "glass", "glazing")``. :param window_value: voxel code written for window cells. Defaults to ``-16`` (the standard glass code). :param gridvis: if ``True``, after stamping, display a quick-look 2D visualization of the post-import building height grid. Purely a debugging aid; failures in the visualization step (including a missing/broken plotting backend) are swallowed silently. Defaults to ``False``. :returns: A new VoxCity object with the imported buildings stamped in (or an unmodified deep copy of *voxcity* if no building-role geometry was found, or none of it voxelized to cells inside the domain). The *voxcity* argument passed in is never mutated. :raises FileNotFoundError: if *obj_path* does not exist. :raises ValueError: if *units* is not one of the recognized unit strings, if *backend* is not ``"trimesh"`` or ``"meshlib"``, or if *anchor_lonlat* does not have exactly 2 elements. :raises ImportError: if ``backend="meshlib"`` is requested but the optional ``meshlib`` package is not installed.