Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# Auto detect text files and perform LF normalization
* text=auto
# SCM syntax highlighting & preventing 3-way merges
pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff
29 changes: 29 additions & 0 deletions .github/workflows/tutorials.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# TODO: setup auto-update pixi.lock https://pixi.sh/latest/advanced/updates_github_actions/#how-to-use

name: Build tutorials

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: prefix-dev/setup-pixi@v0.9.4
with:
pixi-version: v0.67.0
locked: false
cache: true
cache-write: ${{ github.event_name == 'push' && github.ref_name == 'add-pixi' }}
- run: pixi run install-openstudio # NOTE: can openstudio be installable from prefix channel?
- run: pixi run tutorials
- name: Push docs to gh-pages
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: tutorials/_site
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@
*.json
*.suo
*.wsuo
*.lock
*.vsidx
*.sqlite
# pixi environments
.pixi/*
!.pixi/config.toml
EnergyModels/**
build/**
notebooks/.ipynb_checkpoints/**
tutorials/.ipynb_checkpoints/**
notebooks/iframe_figures/**
tutorials/iframe_figures/**
tutorials/test01/**
src/topologicpy.egg-info/**
tutorials/_site/**
10,443 changes: 10,443 additions & 0 deletions pixi.lock

Large diffs are not rendered by default.

103 changes: 103 additions & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
[workspace]
authors = ["Wassim Jabi <wassim.jabi@gmail.com>"]
channels = ["conda-forge", "https://repo.prefix.dev/natlabrockies"] # Note: natlabrockies host energyplus
name = "topologicpy"
platforms = ["linux-64", "osx-arm64"]

[pypi-dependencies]
topologicpy = { path = ".", editable = true }

[environments]
default = { solve-group = "default" }
test = { features = ["test"], solve-group = "default" }
dev = { features = ["dev"], solve-group = "default" }

[feature.test.dependencies]
pytest-xdist = ">=2.4.0,<3.0.0"

[feature.dev.dependencies]
python = ">=3.8, <3.14" # NOTE. pinned here as wasn't getting python ver from pyproject.toml. also
pytest-xdist = ">=2.4.0,<3.0.0"
jupyterlab = ">=4.5.5,<4.5.6"
# jupyterlab-search-replace = "*"
ipywidgets = "*"
networkx = "*"
quarto = "*"
jupytext = ">=1.19.1,<2"
ifcopenshell = "*"
matplotlib = "*"
pyyaml = "*"
kagglehub = "*"
pyvis = "*"
energyplus = "*" # https://prefix.dev/channels/natlabrockies/packages/energyplus

[feature.dev.pypi-dependencies]
openstudio = "*"
honeybee = "*"
honeybee-energy = "*"
honeybee-radiance = "*"
ladybug = "*"
ladybug-geometry = "*"
# TODO: consider using lbt-honeybee as a catch all installing all honeybee deps
jupyterlab-quarto = "*"

[tasks.mk-build-dir]
cmd = "mkdir -p build"
cwd = "."
description = "create build directory"

# NOTE: cmds below can commented out when energyplus added to natlabrockies prefix channel is working
# : currently get the following error:
# ╰─▶ Cannot solve the request because of: energyplus * cannot be installed because there are no viable options:
# └─ energyplus 25.2.0 | 25.2.0 would require
# └─ __glibc >=2.34,<3.0.a0, for which no candidates were found.
# https://prefix.dev/channels/natlabrockies/packages/energyplus
# -------------------------------------------------------------
[target.linux-64.tasks.download-openstudio]
cmd = "wget https://github.com/NREL/OpenStudio/releases/download/v3.10.0/OpenStudio-3.10.0+86d7e215a1-Ubuntu-24.04-x86_64.deb"
cwd = "build"
depends-on = ["mk-build-dir"]
description = "download OpenStudio for Ubuntu 24.04"

[target.linux-64.tasks.install-openstudio]
cmd = "sudo dpkg -i ./OpenStudio-3.10.0+86d7e215a1-Ubuntu-24.04-x86_64.deb"
cwd = "build"
depends-on = ["download-openstudio"]
description = "install OpenStudio on Ubuntu"

[target.osx-arm64.tasks.download-openstudio]
cmd = "curl -LO https://github.com/NREL/OpenStudio/releases/download/v3.10.0/OpenStudio-3.10.0+ce46db07de-Darwin-arm64.dmg"
cwd = "build"
depends-on = ["mk-build-dir"]
description = "download OpenStudio for macOS (Apple Silicon)"

[target.osx-arm64.tasks.install-openstudio]
cmd = "hdiutil attach ./OpenStudio-3.10.0+ce46db07de-Darwin-arm64.dmg -mountpoint /tmp/openstudio_mount && sudo /tmp/openstudio_mount/OpenStudio-3.10.0+ce46db07de-Darwin-arm64.app/Contents/MacOS/OpenStudio-3.10.0+ce46db07de-Darwin-arm64 --accept-licenses --accept-messages --confirm-command install && hdiutil detach /tmp/openstudio_mount"
cwd = "build"
depends-on = ["download-openstudio"]
description = "install OpenStudio on macOS (Apple Silicon)"
# -------------------------------------------------------------

[target.linux-64.tasks.open-tutorials]
cmd= "start index.html" # on wsl requires bash alias start=/mnt/c/windows/explorer.exe
cwd="tutorials/_site"
description="open built tutorials"

[target.osx-arm64.tasks.open-tutorials]
cmd= "open index.html"
cwd="tutorials/_site"
description="open built tutorials"
# -------------------------------------------------------------

[feature.test.tasks]
tests = "pytest"

[feature.dev.tasks]
lab = { cmd="jupyter lab", cwd = "notebooks", description = "open Jupyter Lab for notebooks" }
lab-tutorials = { cmd="jupyter lab", cwd = "tutorials", description = "open Jupyter Lab for tutorials" }
test-energy = { cmd = "pytest tests/test_16EnergyModel.py", cwd = ".", description = "run energy model import tests with dev env" }
del-tutorials = { cmd="rm -rf _site", cwd = "tutorials", description = "delete built tutorials" }
tutorials = { cmd= "quarto render .", cwd = "tutorials", description = "render tutorials using Quarto" }
preview = { cmd= "quarto preview .", cwd = "tutorials", description = "preview tutorials using Quarto" }
list-sidebar = { cmd = "python list_sidebar.py", cwd = "tutorials", description = "list sidebar contents from _quarto.yml" }
analyse-nb-imports = { cmd = "python analyse_nb_imports.py", description = "analyse notebook imports" }
54 changes: 54 additions & 0 deletions resources/edges.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
e00,-0.1,-0.5,-0.5,-0.9,-0.5,-0.5
e01,0,-0.1,-0.5,0,-0.4,-0.5
e02,-0.9,0,-0.5,-0.1,0,-0.5
e03,-1,-0.4,-0.5,-1,-0.1,-0.5
e04,0,-0.5,-0.4,0,-0.5,-0.1
e05,-0.1,-0.5,0,-0.9,-0.5,0
e06,-1,-0.5,-0.1,-1,-0.5,-0.4
e07,0,0,-0.4,0,0,-0.1
e08,0,-0.1,0,0,-0.4,0
e09,-1,0,-0.4,-1,0,-0.1
e10,-0.9,0,0,-0.1,0,0
e11,-1,-0.4,0,-1,-0.1,0
e12,0.9,-0.5,-0.5,0.1,-0.5,-0.5
e13,1,-0.1,-0.5,1,-0.4,-0.5
e14,0.1,0,-0.5,0.9,0,-0.5
e15,1,-0.5,-0.4,1,-0.5,-0.1
e16,0.9,-0.5,0,0.1,-0.5,0
e17,1,0,-0.4,1,0,-0.1
e18,1,-0.1,0,1,-0.4,0
e19,0.1,0,0,0.9,0,0
e20,0,0.4,-0.5,0,0.1,-0.5
e21,-0.9,0.5,-0.5,-0.1,0.5,-0.5
e22,-1,0.1,-0.5,-1,0.4,-0.5
e23,0,0.5,-0.4,0,0.5,-0.1
e24,0,0.4,0,0,0.1,0
e25,-1,0.5,-0.4,-1,0.5,-0.1
e26,-0.9,0.5,0,-0.1,0.5,0
e27,-1,0.1,0,-1,0.4,0
e28,0,-0.5,0.1,0,-0.5,0.4
e29,-0.1,-0.5,0.5,-0.9,-0.5,0.5
e30,-1,-0.5,0.4,-1,-0.5,0.1
e31,0,0,0.1,0,0,0.4
e32,0,-0.1,0.5,0,-0.4,0.5
e33,-1,0,0.1,-1,0,0.4
e34,-0.9,0,0.5,-0.1,0,0.5
e35,-1,-0.4,0.5,-1,-0.1,0.5
e36,1,0.4,-0.5,1,0.1,-0.5
e37,0.1,0.5,-0.5,0.9,0.5,-0.5
e38,1,0.5,-0.4,1,0.5,-0.1
e39,1,0.4,0,1,0.1,0
e40,0.1,0.5,0,0.9,0.5,0
e41,1,-0.5,0.1,1,-0.5,0.4
e42,0.9,-0.5,0.5,0.1,-0.5,0.5
e43,1,0,0.1,1,0,0.4
e44,1,-0.1,0.5,1,-0.4,0.5
e45,0.1,0,0.5,0.9,0,0.5
e46,0,0.5,0.1,0,0.5,0.4
e47,0,0.4,0.5,0,0.1,0.5
e48,-1,0.5,0.1,-1,0.5,0.4
e49,-0.9,0.5,0.5,-0.1,0.5,0.5
e50,-1,0.1,0.5,-1,0.4,0.5
e51,1,0.5,0.1,1,0.5,0.4
e52,1,0.4,0.5,1,0.1,0.5
e53,0.1,0.5,0.5,0.9,0.5,0.5
27 changes: 27 additions & 0 deletions resources/nodes.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
v00,-1,-0.5,-0.5,e00,e03,e06,,,
v01,0,-0.5,-0.5,e00,e01,e04,e12,,
v02,0,0,-0.5,e01,e02,e07,e14,e20,
v03,-1,0,-0.5,e02,e03,e09,e22,,
v04,0,-0.5,0,e04,e05,e08,e16,e28,
v05,-1,-0.5,0,e05,e06,e11,e30,,
v06,0,0,0,e07,e08,e10,e19,e24,e31
v07,-1,0,0,e09,e10,e11,e27,e33,
v08,1,-0.5,-0.5,e12,e13,e15,,,
v09,1,0,-0.5,e13,e14,e17,e36,,
v10,1,-0.5,0,e15,e16,e18,e41,,
v11,1,0,0,e17,e18,e19,e39,e43,
v12,0,0.5,-0.5,e20,e21,e23,e37,,
v13,-1,0.5,-0.5,e21,e22,e25,,,
v14,0,0.5,0,e23,e24,e26,e40,e46,
v15,-1,0.5,0,e25,e26,e27,e48,,
v16,0,-0.5,0.5,e28,e29,e32,e42,,
v17,-1,-0.5,0.5,e29,e30,e35,,,
v18,0,0,0.5,e31,e32,e34,e45,e47,
v19,-1,0,0.5,e33,e34,e35,e50,,
v20,1,0.5,-0.5,e36,e37,e38,,,
v21,1,0.5,0,e38,e39,e40,e51,,
v22,1,-0.5,0.5,e41,e42,e44,,,
v23,1,0,0.5,e43,e44,e45,e52,,
v24,0,0.5,0.5,e46,e47,e49,e53,,
v25,-1,0.5,0.5,e48,e49,e50,,,
v26,1,0.5,0.5,e51,e52,e53,,,
Binary file added resources/typical-house-plan-GF.pdf
Binary file not shown.
Binary file added resources/typical-house-plan-GF.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions tests/test_16EnergyModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest


def test_set_energy_model_log_level():
# Skip if openstudio is not installed
openstudio = pytest.importorskip("openstudio", reason="openstudio is not installed")

try:
openstudio.Logger.instance().standardOutLogger().setLogLevel(openstudio.Fatal)
assert True
except Exception as e:
print("Failed to set OpenStudio log level.")
assert False
2 changes: 2 additions & 0 deletions tutorials/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.quarto/
**/*.quarto_ipynb
133 changes: 133 additions & 0 deletions tutorials/BuildingTower.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
title: Building Tower
jupyter:
jupytext:
text_representation:
extension: .qmd
format_name: quarto
format_version: '1.0'
jupytext_version: 1.19.1
kernelspec:
display_name: Python 3 (ipykernel)
language: python
name: python3
---


```{python}
from topologicpy.Vertex import Vertex
from topologicpy.Edge import Edge
from topologicpy.Wire import Wire
from topologicpy.Face import Face
from topologicpy.Shell import Shell
from topologicpy.Cell import Cell
from topologicpy.CellComplex import CellComplex
from topologicpy.Cluster import Cluster
from topologicpy.Topology import Topology
from topologicpy.Graph import Graph
from topologicpy.Dictionary import Dictionary
```

```{python}
selectors = []
ground = CellComplex.Prism(width=20, length=20, height=1, placement="lowerleft", uSides=6, vSides=6, wSides=1)
ground = Topology.Translate(ground, 0, 0, -1)
ground_cells = Topology.Cells(ground)
d = Dictionary.ByKeyValue("id", 0)
for cell in ground_cells:
s = Topology.InternalVertex(cell)
s = Topology.SetDictionary(s, d)
selectors.append(s)
Topology.Show(ground, xAxis=True, yAxis=True, zAxis=True)
```

```{python}
columns = []
for i in range(2,20,4):
for j in range(2,20,4):
origin = Vertex.ByCoordinates(i,j,0)
column = Cell.Prism(width=0.8, length=0.8, height=3, origin=origin, placement="bottom")
columns.append(column)
columns = Cluster.ByTopologies(columns)

column_cells = Topology.Cells(columns)
d = Dictionary.ByKeyValue("id", 1)
for cell in column_cells:
s = Topology.InternalVertex(cell)
s = Topology.SetDictionary(s, d)
selectors.append(s)

Topology.Show(columns, ground)
```

```{python}
origin = Vertex.ByCoordinates(0.5,0.5,3)
podium = CellComplex.Prism(width=19, length=19, height=3, uSides=4, vSides=4, wSides=1, origin=origin, placement="lowerleft")

podium_cells = Topology.Cells(podium)
d = Dictionary.ByKeyValue("id", 2)
for cell in podium_cells:
s = Topology.InternalVertex(cell)
s = Topology.SetDictionary(s, d)
selectors.append(s)

Topology.Show(ground, columns, podium)
```

```{python}
origin = Vertex.ByCoordinates(1,1,6)
block = CellComplex.Prism(width=18, length=18, height=15, uSides=6, vSides=6, wSides=5, origin=origin, placement="lowerleft")
block_cells = Topology.Cells(block)
d = Dictionary.ByKeyValue("id", 3)
for cell in block_cells:
s = Topology.InternalVertex(cell)
s = Topology.SetDictionary(s, d)
selectors.append(s)

Topology.Show(ground, columns, podium, block)
```

```{python}
origin = Vertex.ByCoordinates(7,7,0)
core = Cell.Prism(width=6, length=6, height=24, origin=origin, placement="lowerleft")
s = Topology.InternalVertex(core)
d = Dictionary.ByKeyValue("id", 4)
s = Topology.SetDictionary(s, d)
selectors.append(s)
Topology.Show(ground, columns, podium, block, core)
```

```{python}
columns = Topology.Difference(columns, core)
podium = Topology.Difference(podium, core)
block = Topology.Difference(block, core)
```

```{python}
ground_cells = Topology.Cells(ground)
column_cells = Topology.Cells(columns)
podium_cells = Topology.Cells(podium)
block_cells = Topology.Cells(block)

all_cells = ground_cells+column_cells+podium_cells+block_cells+[core]
building = CellComplex.ByCells(all_cells)
```

```{python}
Topology.Show(building, selectors, faceOpacity=0.1)
```

```{python}
building = Topology.TransferDictionariesBySelectors(building, selectors, tranCells=True)
```

```{python}
graph = Graph.ByTopology(building)

Graph.Show(graph, vertexSize=12, vertexGroupKey="id")
```

```{python}
status = Graph.ExportToCSV(graph, path=r"test01", nodeLabelKey="id", overwrite=True)
print(status)
```
Loading