Convex graph encoding and representation toolkit for building geometry
Project description
CUGER_building
Introduction
CUGER is a Python-based open-source representation tool that decomposes complex building shapes/plans into convex geometry and encodes them into an improved LPG (Logical Property Graph) structure.
It further supports bidirectional conversion between LPG and RDF, enabling seamless interoperability across heterogeneous building data ecosystems. 🔄
CUGER is not only designed for converting design models into engineering-level BIM/BEM structures, but also for transforming building models into graph datasets for GNN training—supporting downstream tasks such as performance prediction, spatial reasoning, and surrogate simulation. 🧠📐
Conceptually, the framework draws inspiration from Arkin, Ronald C. (1987), “Path Planning for a Vision-Based Autonomous Robot.”
CUGER is built on top of Moosas, and to access its full functionality—including building-model conversion, geometric/semantic recognition, and structured graph generation—you need to install both CUGER and Moosas.
The algorithm is also integrated into Moosas+, and its implementation can be found in: 👉 moosas/MoosasPy/encoding
New: Simplify (LOD) Module
CUGER now includes a geometry simplification stage before convex decomposition.
precise: keep original geometry (no simplification)medium: simplify to multi-layer OBB representationlow: simplify to single OBB representation
This feature is integrated in the processing pipeline as:
Simplify (LOD) -> Convexify -> (optional) Moosas export -> (optional) Graph generation
Installation
Install from PyPI
pip install cuger
The core package only contains the code under cuger/cuger.
If you also need Moosas-based export (.geo/.xml/.idf/.owl) and graph generation,
please install Moosas separately.
Install from git
git clone https://github.com/Romeo_Leeyh/CUGER_building.git
cd cuger
pip install -e .
# or install requirements directly
pip install -r requirements.txt
Install Moosas+
If you just want to try the algorithm to split building models, this step can be ignored. For full installation instructions, please visit the Moosas+ repository.
Usage
Run with Test Script
You can run the example script in test.py.
This will process sample building models under tests/examples/
and generate outputs in tests/example_results/.
tests
├── examples
│ └── example0.geo # Sample test case
└── example_results
├── geo_s # Simplified geometry (_s_<lod>.geo)
├── figure_convex # Convex decomposition figures
├── figure_graph # Graph visualization figures
├── geo_c # Convex converted geometric files
├── graph # Generated graph nodes and edges
├── new_geo # Exported .geo files
├── new_idf # Exported .idf files
├── new_rdf # Exported .rdf files
└── new_xml # Exported .xml files
To run the test:
python test.py
Use as a Python package
The public API follows the same main flow used in test.py:
from cuger import PipelineOptions, process_geo_directory, process_geo_file
options = PipelineOptions(lod="medium")
process_geo_file("tests/examples/example0.geo", "tests/example_results", options=options)
process_geo_directory("tests/examples", "tests/example_results", options=options)
If you only want simplification + convex decomposition and do not want to depend on Moosas:
from cuger import PipelineOptions, process_geo_file
options = PipelineOptions(
lod="medium",
run_moosas=False,
generate_graph=False,
)
process_geo_file("tests/examples/example0.geo", "tests/example_results", options=options)
CLI
After installation, you can also use the packaged command:
cuger -s tests/examples/example0.geo -o tests/example_results -l medium
cuger -i tests/examples -o tests/example_results -l medium
Publish to PyPI
Before publishing, update the version in pyproject.toml.
Build the package:
python -m pip install -U build twine
python -m build
This generates:
dist/cuger-<version>.tar.gzdist/cuger-<version>-py3-none-any.whl
Validate the distribution metadata locally:
python -m twine check dist/*
Upload to TestPyPI first:
python -m twine upload --repository testpypi dist/*
Then test installation:
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple cuger
If everything looks good, upload to the official PyPI index:
python -m twine upload dist/*
After release, verify installation from PyPI:
pip install -U cuger
Optional: configure credentials with .pypirc or environment variables such as
TWINE_USERNAME and TWINE_PASSWORD to avoid typing them each time.
GitHub Actions Auto Publish (PyPI)
This repository includes CI workflow: .github/workflows/publish-pypi.yml.
- Push tag
v*(for examplev0.1.1) -> build and publish to PyPI - Manual run (
workflow_dispatch) -> choose testpypi or pypi
One-time configuration (Trusted Publisher)
-
In PyPI project settings (
cuger), add a Trusted Publisher. -
Owner: your GitHub org/user.
-
Repository:
cugerrepository. -
Workflow name:
publish-pypi.yml. -
Environment:
pypi. -
In TestPyPI project settings (
cuger), add another Trusted Publisher. -
Use the same repository and workflow.
-
Environment:
testpypi. -
In GitHub repository settings, create environments:
pypiandtestpypi.
No PyPI API token secret is required when using Trusted Publisher (OIDC).
Release commands
# 1) bump version in pyproject.toml
# 2) commit and push
git tag v0.1.1
git push origin v0.1.1
If you want to dry-run to TestPyPI first, use Actions -> Publish Python Package -> Run workflow -> repository=testpypi.
Run with CLI (main.py)
main.py supports interactive mode and command-line mode.
# interactive mode
python main.py
# batch process a directory
python main.py -i tests/examples -o tests/example_results -l medium
# process a single file
python main.py -s tests/examples/example0.geo -o tests/example_results -l low
LOD options:
precise(default copy/no simplify in simplify stage)medium(recommended)low
Module I/O Explanation
CUGER operates through a series of processing modules. Each module consumes specific input files and produces standardized outputs that together form the unified graph-based representation of the building model.
Input
.geofile
The primary geometric description of the building.
This file contains surfaces, edges, vertex positions, and semantic tags used to reconstruct the building’s spatial structure.
Intermediate Outputs
-
geo_s/<case_name>_s_<lod>.geo
Simplified geometry generated by the new simplify stage.lod=precise: copied from input geometrylod=medium: multi-layer OBB simplified geometrylod=low: single OBB simplified geometry
-
figure_convex/<case_name>_convex.png
Visualization of the convex decomposition process, showing how non-convex polygons are split. -
figure_graph/<case_name>_graph.png
Graph-level visualizations illustrating nodes, edges, and spatial relationships. -
geo_c/<case_name>_c.geo
Converted or cleaned geometric files after preprocessing and convex decomposition.
Graph Outputs
-
graph/<case_name>.json
Encodes all nodes (faces, spaces, openings, etc.) with geometric, semantic, and topological attributes.Encodes adjacency relations, directional edges, and multi-scale topology for downstream GNN tasks.
Exported Model Formats
new_geo/<case_name>.geo
Reconstructed geometry exported back into.geoformat.new_idf/<case_name>.idf(in development)
Prototype EnergyPlus IDF export based on the generated graph structure.new_rdf/<case_name>.owl
Semantic web representation exported as RDF, suitable for linked-data workflows, which is dumped in.owlformat.new_xml/<case_name>.xml
XML-based representation for interoperability with external BIM or simulation environments.
Processing Stages
- Simplify (
simplify_process)
Input.geo-> simplified.geoingeo_s/according to selected LOD. - Convexify (
convex_process)
Simplified.geo-> convex.geoingeo_c/. - Model Export (Moosas, optional)
Convex.geo->.geo/.xml/.owl/.idfexports. - Graph Construction (
graph_process, optional)
Build LPG JSON graph and visualization figures.
Function
Core entry points:
main.py(CLI + interactive processing)test.py(example pipeline run)cuger/__transform/process.pysimplify_process(...)convex_process(...)graph_process(...)
Citation
If you used this project in your research, please cite the paper below:
@article{liGeometryGraphAutomation2026,
title = {From Geometry to Graph: {{Automation}} of Building Performance Modeling via Convex Graph Encoding},
shorttitle = {From Geometry to Graph},
author = {Li, Yihui and Xiao, Jun and Zhou, Hao and Lin, Borong},
year = 2026,
month = mar,
journal = {Automation in Construction},
volume = {183},
pages = {106815},
issn = {0926-5805},
doi = {10.1016/j.autcon.2026.106815},
}
@inproceedings{Li2024GraphConvex,
author = {Li, Yihui and Xiao, Jun and Zhou, Hao and Lin, Borong.},
title = {A Cross-Scale Normative Encoding Representation Method for 3D Building Models Suitable for Graph Neural Networks},
booktitle = {Proceedings of the Building Simulation Conference 2025},
publisher = {IBPSA},
address = {Brisbane, Australia},
month = {August},
year = {2025},
pages = {},
doi = {10.26868/25222708.2025.1305}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cuger-0.1.0.tar.gz.
File metadata
- Download URL: cuger-0.1.0.tar.gz
- Upload date:
- Size: 43.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40e10f1816db1151fa4da4b3b78a3e21ad36485f11b2aff885ca0ffa9b0159ae
|
|
| MD5 |
da128562eb936504b774204f64239cef
|
|
| BLAKE2b-256 |
7cada0a8fa1d0988f37a3bb9022098588e8d7f034acc0ed5cd3a94d90f5841b0
|
Provenance
The following attestation bundles were made for cuger-0.1.0.tar.gz:
Publisher:
publish-pypi.yml on Romeo-Leeyh/CUGER_building
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cuger-0.1.0.tar.gz -
Subject digest:
40e10f1816db1151fa4da4b3b78a3e21ad36485f11b2aff885ca0ffa9b0159ae - Sigstore transparency entry: 1076509825
- Sigstore integration time:
-
Permalink:
Romeo-Leeyh/CUGER_building@6e638dc39df5a5d1642c1f628c4dc8c648f5f20d -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Romeo-Leeyh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@6e638dc39df5a5d1642c1f628c4dc8c648f5f20d -
Trigger Event:
push
-
Statement type:
File details
Details for the file cuger-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cuger-0.1.0-py3-none-any.whl
- Upload date:
- Size: 45.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2542a649d4fcfe38c6148c215833214dc43858cc909d69097b1adc2c09f5f24
|
|
| MD5 |
e7255c7a9582abb64faa8e4f9440ca8e
|
|
| BLAKE2b-256 |
656913a392fd332d8b5955d36daccfc404ae1175e97faa057ccef7a430194fc4
|
Provenance
The following attestation bundles were made for cuger-0.1.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on Romeo-Leeyh/CUGER_building
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cuger-0.1.0-py3-none-any.whl -
Subject digest:
b2542a649d4fcfe38c6148c215833214dc43858cc909d69097b1adc2c09f5f24 - Sigstore transparency entry: 1076509860
- Sigstore integration time:
-
Permalink:
Romeo-Leeyh/CUGER_building@6e638dc39df5a5d1642c1f628c4dc8c648f5f20d -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Romeo-Leeyh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@6e638dc39df5a5d1642c1f628c4dc8c648f5f20d -
Trigger Event:
push
-
Statement type: