python-materialsdb 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_materialsdb-0.2.0/PKG-INFO +170 -0
- python_materialsdb-0.2.0/README.md +143 -0
- python_materialsdb-0.2.0/pyproject.toml +98 -0
- python_materialsdb-0.2.0/setup.cfg +4 -0
- python_materialsdb-0.2.0/src/materialsdb/__init__.py +3 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/materialsdb/cache.py +3 -5
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/materialsdb/classes.py +14 -6
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/materialsdb/config.py +3 -6
- python_materialsdb-0.2.0/src/materialsdb/construction.py +441 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/__main__.py +32 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/discovery.py +28 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/listener.py +151 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/server.py +730 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/static/app-constructions.js +639 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/static/app.js +451 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/static/constructions.html +107 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/static/index.html +56 -0
- python_materialsdb-0.2.0/src/materialsdb/gui/static/picker-core.js +111 -0
- python_materialsdb-0.2.0/src/materialsdb/ifc/__init__.py +0 -0
- python_materialsdb-0.2.0/src/materialsdb/ifc/material_builder.py +295 -0
- python_materialsdb-0.2.0/src/materialsdb/ifc/material_psets.json +596 -0
- python_materialsdb-0.2.0/src/materialsdb/ifc/project_library.py +164 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/materialsdb/query.py +3 -3
- python_materialsdb-0.2.0/src/materialsdb/schema/MaterialsDBIndex100.xsd +60 -0
- python_materialsdb-0.2.0/src/materialsdb/schema/materialsdb102.xsd +820 -0
- python_materialsdb-0.2.0/src/materialsdb/schema/materialsdb103.xsd +938 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/materialsdb/serialiser.py +24 -20
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/materialsdb/store.py +78 -75
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/materialsdb/summary.py +30 -22
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/materialsdb/utils.py +15 -21
- python_materialsdb-0.2.0/src/python_materialsdb.egg-info/PKG-INFO +170 -0
- python_materialsdb-0.2.0/src/python_materialsdb.egg-info/SOURCES.txt +51 -0
- python_materialsdb-0.2.0/src/python_materialsdb.egg-info/entry_points.txt +2 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/python_materialsdb.egg-info/requires.txt +3 -0
- python_materialsdb-0.2.0/tests/test_bonsai_discovery.py +90 -0
- python_materialsdb-0.2.0/tests/test_bonsai_insert.py +443 -0
- python_materialsdb-0.2.0/tests/test_build_bonsai_addon.py +37 -0
- python_materialsdb-0.2.0/tests/test_construction.py +352 -0
- python_materialsdb-0.2.0/tests/test_construction_frontend.py +41 -0
- python_materialsdb-0.2.0/tests/test_construction_ifc.py +83 -0
- python_materialsdb-0.2.0/tests/test_gui_server.py +830 -0
- python_materialsdb-0.2.0/tests/test_listener_payload.py +212 -0
- python_materialsdb-0.2.0/tests/test_material_builder.py +305 -0
- python_materialsdb-0.2.0/tests/test_picker_frontend.py +40 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/tests/test_query.py +1 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/tests/test_serialiser.py +1 -4
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/tests/test_store.py +89 -3
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/tests/test_summary.py +27 -0
- python_materialsdb-0.1.0/PKG-INFO +0 -83
- python_materialsdb-0.1.0/README.md +0 -58
- python_materialsdb-0.1.0/pyproject.toml +0 -14
- python_materialsdb-0.1.0/setup.cfg +0 -43
- python_materialsdb-0.1.0/src/materialsdb/__init__.py +0 -1
- python_materialsdb-0.1.0/src/materialsdb/ifc/material_psets.json +0 -582
- python_materialsdb-0.1.0/src/materialsdb/ifc/project_library.py +0 -299
- python_materialsdb-0.1.0/src/python_materialsdb.egg-info/PKG-INFO +0 -83
- python_materialsdb-0.1.0/src/python_materialsdb.egg-info/SOURCES.txt +0 -26
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/LICENSE.md +0 -0
- {python_materialsdb-0.1.0/src/materialsdb/ifc → python_materialsdb-0.2.0/src/materialsdb/gui}/__init__.py +0 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/python_materialsdb.egg-info/dependency_links.txt +0 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/src/python_materialsdb.egg-info/top_level.txt +0 -0
- {python_materialsdb-0.1.0 → python_materialsdb-0.2.0}/tests/test_project_library.py +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-materialsdb
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A library to work with materialsdb.org open standard for building materials.
|
|
5
|
+
Author-email: Cyril Waechter <cyrwae@hotmail.com>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://github.com/CyrilWaechter/python-materialsdb
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/CyrilWaechter/python-materialsdb/issues
|
|
9
|
+
Project-URL: Community, https://community.osarch.org/
|
|
10
|
+
Keywords: materials,BIM,ifcopenshell,IFC
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE.md
|
|
18
|
+
Requires-Dist: lxml
|
|
19
|
+
Provides-Extra: ifc
|
|
20
|
+
Requires-Dist: ifcopenshell; extra == "ifc"
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest; extra == "dev"
|
|
23
|
+
Requires-Dist: pytest-benchmark; extra == "dev"
|
|
24
|
+
Requires-Dist: ruff==0.16.4; extra == "dev"
|
|
25
|
+
Requires-Dist: ty==0.0.74; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
python-materialsdb is an unofficial python library for [materialsdb.org][1] an open format and database for building materials.
|
|
29
|
+
|
|
30
|
+
# Features :
|
|
31
|
+
## Package
|
|
32
|
+
* serialiser.py :
|
|
33
|
+
* from xml : deserialise from materialsdb*.xsd compliant xml file
|
|
34
|
+
* to xml : serealise classes to a materialsdb*.xsd compliant xml file
|
|
35
|
+
* classes.py : generated classes corresponding to XML elements
|
|
36
|
+
* cache.py : cache latest materials data from producers
|
|
37
|
+
* config.py : set and get user config as language and country
|
|
38
|
+
* ifc/project_library.py : convert deserialised source into IFC (IfcProjectLibrary)
|
|
39
|
+
* gui/server.py : stdlib-only web application to browse and export cached materials (materialsdb-gui)
|
|
40
|
+
|
|
41
|
+
## devutils
|
|
42
|
+
* classes_generator.py : generate classes (dataclasses except for simple type) for materialsdb*.xsd elements
|
|
43
|
+
|
|
44
|
+
# config
|
|
45
|
+
Materials data are often localized. You can set your language and country this way:
|
|
46
|
+
```python
|
|
47
|
+
from materialsdb import config
|
|
48
|
+
|
|
49
|
+
config.set_lang("fr")
|
|
50
|
+
config.set_country("CH")
|
|
51
|
+
```
|
|
52
|
+
Note: in materialsdb standard languages are [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) codes and countries are [ISO_3166-1_alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) codes.
|
|
53
|
+
|
|
54
|
+
# Usage examples :
|
|
55
|
+
Check out some [examples](examples):
|
|
56
|
+
* [Convert latest materials data to ifc](examples/generate_ifc_project_libraries.py)
|
|
57
|
+
* [Create your own materialsdb.org compliant XML](examples/create_layers.py)
|
|
58
|
+
|
|
59
|
+
# Querying materials :
|
|
60
|
+
The library keeps an sqlite index of the cached materials data for fast
|
|
61
|
+
filtering and single-material access:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from materialsdb import query
|
|
65
|
+
|
|
66
|
+
query.refresh() # incremental update from cached xml
|
|
67
|
+
rows = query.search("isolant", sort="lambda") # filtered, sorted summaries
|
|
68
|
+
material = query.get_material(rows[0].id) # full material dataclass
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
# Create a single material in IFC :
|
|
72
|
+
Append one material into an existing ifcopenshell file (idempotent), or build a minimal standalone file.
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from materialsdb import query
|
|
76
|
+
from materialsdb.ifc.material_builder import add_material, create_material_file
|
|
77
|
+
|
|
78
|
+
material = query.get_material("<materialsdb-id>")
|
|
79
|
+
|
|
80
|
+
add_material(existing_ifc_file, material, company="Producer") # idempotent append
|
|
81
|
+
file = create_material_file("<materialsdb-id>") # standalone .ifc
|
|
82
|
+
file.write("single_material.ifc")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
# Material picker GUI :
|
|
86
|
+
Launch the local web application (stdlib only, no extra dependencies):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
materialsdb-gui # opens http://127.0.0.1:8619 in your browser
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Or run straight from a source checkout without installing:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
PYTHONPATH=src python3 -m materialsdb.gui
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The materials index uses schema v2: the first launch after upgrading rebuilds
|
|
99
|
+
it automatically (previous index is discarded — source of truth is your cached
|
|
100
|
+
XML). Click *refresh cache* once to repopulate.
|
|
101
|
+
|
|
102
|
+
Browse, sort and filter all cached materials; multi-select then either export
|
|
103
|
+
a standalone `.ifc`, or open one of your own `.ifc` files and append the
|
|
104
|
+
selected materials into it. The same HTTP API powers future BIM software
|
|
105
|
+
plugins (all mutating calls require a per-launch token).
|
|
106
|
+
|
|
107
|
+
# Construction maker :
|
|
108
|
+
Compose thermal constructions from materialsdb materials and compute their
|
|
109
|
+
U-value (ISO 6946 / SIA 180 surface resistance presets):
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
PYTHONPATH=src python3 -m materialsdb.gui # then open constructions.html
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Create a construction, add materials from the catalog, adjust layer
|
|
116
|
+
thicknesses in millimetres and read the resulting U-value live. Save
|
|
117
|
+
constructions as JSON in your cache directory, export them as standalone
|
|
118
|
+
`.ifc` files containing an `IfcMaterialLayerSet`, or append them into an
|
|
119
|
+
already-open session file.
|
|
120
|
+
|
|
121
|
+
You can also push the construction straight into the IFC model open in
|
|
122
|
+
Bonsai (same target picker as the materials page): it is created or updated
|
|
123
|
+
as an `IfcWallType`/`IfcSlabType`/`IfcRoofType` (per the design usage,
|
|
124
|
+
generic creating all three) with its `IfcMaterialLayerSet` — undoable with
|
|
125
|
+
Ctrl+Z.
|
|
126
|
+
|
|
127
|
+
# Bonsai integration :
|
|
128
|
+
Push materials straight from the picker into the IFC model open in
|
|
129
|
+
[Bonsai](https://bonsai.ifcopenshell.org). Install it from the
|
|
130
|
+
extension repository: in Blender, *Preferences ▸ Get Extensions ▸ ⌄ ▸
|
|
131
|
+
Add Remote Repository* and add
|
|
132
|
+
`https://cyrilwaechter.github.io/python-materialsdb/`, then install
|
|
133
|
+
*materialsdb listener* (updates appear in the same panel). Manual
|
|
134
|
+
install stays available: build `dist/materialsdb_listener.zip` with
|
|
135
|
+
`python3 dev_utils/build_bonsai_addon.py` and use
|
|
136
|
+
*Extensions ▸ Install from Disk*. Start the listener from the
|
|
137
|
+
materialsdb panel in the 3D-view sidebar. The panel can also start the
|
|
138
|
+
GUI server itself (*Start server & open picker*) — it needs
|
|
139
|
+
`pip install python-materialsdb` in a system Python (set the
|
|
140
|
+
interpreter in the add-on preferences if autodiscovery picks the wrong
|
|
141
|
+
one). Then run `materialsdb-gui` as
|
|
142
|
+
usual and hit *send to:* (picking the target instance) in the picker or
|
|
143
|
+
the construction maker. Materials are registered
|
|
144
|
+
into the model's material library (identity + per-layer psets included);
|
|
145
|
+
assigning them to objects stays a normal Bonsai action. Pushed
|
|
146
|
+
constructions become typed elements (`IfcWallType`/`IfcSlabType`/
|
|
147
|
+
`IfcRoofType` per the design usage) with their `IfcMaterialLayerSet`,
|
|
148
|
+
visible in the outliner and revertible with Ctrl+Z. Round-trip: select
|
|
149
|
+
the wall (or its type) in Bonsai and hit *Send type to composer* in the
|
|
150
|
+
materialsdb panel — the construction appears under *incoming from model*
|
|
151
|
+
on the constructions page for editing. Layers whose material is not a
|
|
152
|
+
materialsdb material are kept as "model material" placeholders (λ read
|
|
153
|
+
from the model) and re-attach to the same material on push-back.
|
|
154
|
+
|
|
155
|
+
# How to install
|
|
156
|
+
## Using pip
|
|
157
|
+
```bash
|
|
158
|
+
pip install python-materialsdb
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
# Dependencies
|
|
162
|
+
* [lxml][2] (BSD) : xml parser (tested with version 6.1.1)
|
|
163
|
+
* [ifcopenshell][3] (LGPL) : ifc read/write (tested with version 0.8.5)
|
|
164
|
+
|
|
165
|
+
# Third parties :
|
|
166
|
+
* [materialsdb.org][1] (GPL) : materials schema
|
|
167
|
+
|
|
168
|
+
[1]: http://www.materialsdb.org
|
|
169
|
+
[2]: https://lxml.de
|
|
170
|
+
[3]: ifcopenshell.org
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
python-materialsdb is an unofficial python library for [materialsdb.org][1] an open format and database for building materials.
|
|
2
|
+
|
|
3
|
+
# Features :
|
|
4
|
+
## Package
|
|
5
|
+
* serialiser.py :
|
|
6
|
+
* from xml : deserialise from materialsdb*.xsd compliant xml file
|
|
7
|
+
* to xml : serealise classes to a materialsdb*.xsd compliant xml file
|
|
8
|
+
* classes.py : generated classes corresponding to XML elements
|
|
9
|
+
* cache.py : cache latest materials data from producers
|
|
10
|
+
* config.py : set and get user config as language and country
|
|
11
|
+
* ifc/project_library.py : convert deserialised source into IFC (IfcProjectLibrary)
|
|
12
|
+
* gui/server.py : stdlib-only web application to browse and export cached materials (materialsdb-gui)
|
|
13
|
+
|
|
14
|
+
## devutils
|
|
15
|
+
* classes_generator.py : generate classes (dataclasses except for simple type) for materialsdb*.xsd elements
|
|
16
|
+
|
|
17
|
+
# config
|
|
18
|
+
Materials data are often localized. You can set your language and country this way:
|
|
19
|
+
```python
|
|
20
|
+
from materialsdb import config
|
|
21
|
+
|
|
22
|
+
config.set_lang("fr")
|
|
23
|
+
config.set_country("CH")
|
|
24
|
+
```
|
|
25
|
+
Note: in materialsdb standard languages are [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) codes and countries are [ISO_3166-1_alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) codes.
|
|
26
|
+
|
|
27
|
+
# Usage examples :
|
|
28
|
+
Check out some [examples](examples):
|
|
29
|
+
* [Convert latest materials data to ifc](examples/generate_ifc_project_libraries.py)
|
|
30
|
+
* [Create your own materialsdb.org compliant XML](examples/create_layers.py)
|
|
31
|
+
|
|
32
|
+
# Querying materials :
|
|
33
|
+
The library keeps an sqlite index of the cached materials data for fast
|
|
34
|
+
filtering and single-material access:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from materialsdb import query
|
|
38
|
+
|
|
39
|
+
query.refresh() # incremental update from cached xml
|
|
40
|
+
rows = query.search("isolant", sort="lambda") # filtered, sorted summaries
|
|
41
|
+
material = query.get_material(rows[0].id) # full material dataclass
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
# Create a single material in IFC :
|
|
45
|
+
Append one material into an existing ifcopenshell file (idempotent), or build a minimal standalone file.
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from materialsdb import query
|
|
49
|
+
from materialsdb.ifc.material_builder import add_material, create_material_file
|
|
50
|
+
|
|
51
|
+
material = query.get_material("<materialsdb-id>")
|
|
52
|
+
|
|
53
|
+
add_material(existing_ifc_file, material, company="Producer") # idempotent append
|
|
54
|
+
file = create_material_file("<materialsdb-id>") # standalone .ifc
|
|
55
|
+
file.write("single_material.ifc")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
# Material picker GUI :
|
|
59
|
+
Launch the local web application (stdlib only, no extra dependencies):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
materialsdb-gui # opens http://127.0.0.1:8619 in your browser
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or run straight from a source checkout without installing:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
PYTHONPATH=src python3 -m materialsdb.gui
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The materials index uses schema v2: the first launch after upgrading rebuilds
|
|
72
|
+
it automatically (previous index is discarded — source of truth is your cached
|
|
73
|
+
XML). Click *refresh cache* once to repopulate.
|
|
74
|
+
|
|
75
|
+
Browse, sort and filter all cached materials; multi-select then either export
|
|
76
|
+
a standalone `.ifc`, or open one of your own `.ifc` files and append the
|
|
77
|
+
selected materials into it. The same HTTP API powers future BIM software
|
|
78
|
+
plugins (all mutating calls require a per-launch token).
|
|
79
|
+
|
|
80
|
+
# Construction maker :
|
|
81
|
+
Compose thermal constructions from materialsdb materials and compute their
|
|
82
|
+
U-value (ISO 6946 / SIA 180 surface resistance presets):
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
PYTHONPATH=src python3 -m materialsdb.gui # then open constructions.html
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Create a construction, add materials from the catalog, adjust layer
|
|
89
|
+
thicknesses in millimetres and read the resulting U-value live. Save
|
|
90
|
+
constructions as JSON in your cache directory, export them as standalone
|
|
91
|
+
`.ifc` files containing an `IfcMaterialLayerSet`, or append them into an
|
|
92
|
+
already-open session file.
|
|
93
|
+
|
|
94
|
+
You can also push the construction straight into the IFC model open in
|
|
95
|
+
Bonsai (same target picker as the materials page): it is created or updated
|
|
96
|
+
as an `IfcWallType`/`IfcSlabType`/`IfcRoofType` (per the design usage,
|
|
97
|
+
generic creating all three) with its `IfcMaterialLayerSet` — undoable with
|
|
98
|
+
Ctrl+Z.
|
|
99
|
+
|
|
100
|
+
# Bonsai integration :
|
|
101
|
+
Push materials straight from the picker into the IFC model open in
|
|
102
|
+
[Bonsai](https://bonsai.ifcopenshell.org). Install it from the
|
|
103
|
+
extension repository: in Blender, *Preferences ▸ Get Extensions ▸ ⌄ ▸
|
|
104
|
+
Add Remote Repository* and add
|
|
105
|
+
`https://cyrilwaechter.github.io/python-materialsdb/`, then install
|
|
106
|
+
*materialsdb listener* (updates appear in the same panel). Manual
|
|
107
|
+
install stays available: build `dist/materialsdb_listener.zip` with
|
|
108
|
+
`python3 dev_utils/build_bonsai_addon.py` and use
|
|
109
|
+
*Extensions ▸ Install from Disk*. Start the listener from the
|
|
110
|
+
materialsdb panel in the 3D-view sidebar. The panel can also start the
|
|
111
|
+
GUI server itself (*Start server & open picker*) — it needs
|
|
112
|
+
`pip install python-materialsdb` in a system Python (set the
|
|
113
|
+
interpreter in the add-on preferences if autodiscovery picks the wrong
|
|
114
|
+
one). Then run `materialsdb-gui` as
|
|
115
|
+
usual and hit *send to:* (picking the target instance) in the picker or
|
|
116
|
+
the construction maker. Materials are registered
|
|
117
|
+
into the model's material library (identity + per-layer psets included);
|
|
118
|
+
assigning them to objects stays a normal Bonsai action. Pushed
|
|
119
|
+
constructions become typed elements (`IfcWallType`/`IfcSlabType`/
|
|
120
|
+
`IfcRoofType` per the design usage) with their `IfcMaterialLayerSet`,
|
|
121
|
+
visible in the outliner and revertible with Ctrl+Z. Round-trip: select
|
|
122
|
+
the wall (or its type) in Bonsai and hit *Send type to composer* in the
|
|
123
|
+
materialsdb panel — the construction appears under *incoming from model*
|
|
124
|
+
on the constructions page for editing. Layers whose material is not a
|
|
125
|
+
materialsdb material are kept as "model material" placeholders (λ read
|
|
126
|
+
from the model) and re-attach to the same material on push-back.
|
|
127
|
+
|
|
128
|
+
# How to install
|
|
129
|
+
## Using pip
|
|
130
|
+
```bash
|
|
131
|
+
pip install python-materialsdb
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
# Dependencies
|
|
135
|
+
* [lxml][2] (BSD) : xml parser (tested with version 6.1.1)
|
|
136
|
+
* [ifcopenshell][3] (LGPL) : ifc read/write (tested with version 0.8.5)
|
|
137
|
+
|
|
138
|
+
# Third parties :
|
|
139
|
+
* [materialsdb.org][1] (GPL) : materials schema
|
|
140
|
+
|
|
141
|
+
[1]: http://www.materialsdb.org
|
|
142
|
+
[2]: https://lxml.de
|
|
143
|
+
[3]: ifcopenshell.org
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "python-materialsdb"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "A library to work with materialsdb.org open standard for building materials."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "GPL-3.0-or-later"
|
|
11
|
+
authors = [{ name = "Cyril Waechter", email = "cyrwae@hotmail.com" }]
|
|
12
|
+
keywords = ["materials", "BIM", "ifcopenshell", "IFC"]
|
|
13
|
+
dependencies = ["lxml"]
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
19
|
+
"Topic :: Scientific/Engineering",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/CyrilWaechter/python-materialsdb"
|
|
24
|
+
"Bug Tracker" = "https://github.com/CyrilWaechter/python-materialsdb/issues"
|
|
25
|
+
Community = "https://community.osarch.org/"
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
materialsdb-gui = "materialsdb.gui.__main__:main"
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
ifc = ["ifcopenshell"]
|
|
32
|
+
dev = [
|
|
33
|
+
"pytest",
|
|
34
|
+
"pytest-benchmark",
|
|
35
|
+
"ruff==0.16.4",
|
|
36
|
+
"ty==0.0.74",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[tool.setuptools]
|
|
40
|
+
include-package-data = true
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["src"]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
"*" = ["*.json", "*.xsd", "*.html", "*.js"]
|
|
47
|
+
|
|
48
|
+
[tool.pytest.ini_options]
|
|
49
|
+
testpaths = [
|
|
50
|
+
"tests",
|
|
51
|
+
]
|
|
52
|
+
markers = [
|
|
53
|
+
"benchmark: performance benchmarks (deselected by default)",
|
|
54
|
+
]
|
|
55
|
+
addopts = "-m 'not benchmark'"
|
|
56
|
+
|
|
57
|
+
[tool.ruff]
|
|
58
|
+
line-length = 120
|
|
59
|
+
target-version = "py310"
|
|
60
|
+
extend-exclude = [
|
|
61
|
+
"src/materialsdb/classes.py",
|
|
62
|
+
"*.md",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[tool.ty.src]
|
|
66
|
+
include = ["src", "tests", "dev_utils", "examples"]
|
|
67
|
+
|
|
68
|
+
[[tool.ty.overrides]]
|
|
69
|
+
# Generated file: excluded from ruff/ty per Global Constraints (no-drift policy).
|
|
70
|
+
include = ["src/materialsdb/classes.py"]
|
|
71
|
+
[tool.ty.overrides.rules]
|
|
72
|
+
all = "ignore"
|
|
73
|
+
|
|
74
|
+
[tool.ty.analysis]
|
|
75
|
+
# lxml ships no type information; treat as Any instead of erroring on every use.
|
|
76
|
+
replace-imports-with-any = ["lxml.**"]
|
|
77
|
+
|
|
78
|
+
[[tool.ty.overrides]]
|
|
79
|
+
# Generator emits dynamic setattr-based classes; ty cannot follow the flow of
|
|
80
|
+
# self.file (assigned inside parse_schema) nor os.startfile (Windows-only).
|
|
81
|
+
include = ["dev_utils/classes_generator.py", "examples/generate_ifc_project_libraries.py"]
|
|
82
|
+
[tool.ty.overrides.rules]
|
|
83
|
+
unresolved-attribute = "ignore"
|
|
84
|
+
|
|
85
|
+
[[tool.ty.overrides]]
|
|
86
|
+
# Examples exercise the generated model whose Optional list fields are
|
|
87
|
+
# populated before use; runtime-valid, inference-hostile.
|
|
88
|
+
include = ["examples/create_layers.py"]
|
|
89
|
+
[tool.ty.overrides.rules]
|
|
90
|
+
unresolved-attribute = "ignore"
|
|
91
|
+
possibly-missing-attribute = "ignore"
|
|
92
|
+
|
|
93
|
+
[[tool.ty.overrides]]
|
|
94
|
+
# ifcopenshell's own annotations disagree with its runtime API here.
|
|
95
|
+
include = ["src/materialsdb/ifc/project_library.py"]
|
|
96
|
+
[tool.ty.overrides.rules]
|
|
97
|
+
invalid-argument-type = "ignore"
|
|
98
|
+
invalid-assignment = "ignore"
|
|
@@ -2,7 +2,7 @@ import os
|
|
|
2
2
|
import pathlib
|
|
3
3
|
import urllib.request
|
|
4
4
|
from collections import namedtuple
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
from lxml import etree
|
|
7
7
|
|
|
8
8
|
MATERIALSDBINDEXURLLIST = [
|
|
@@ -13,9 +13,7 @@ MATERIALSDBINDEXURLLIST = [
|
|
|
13
13
|
|
|
14
14
|
def get_cache_folder():
|
|
15
15
|
cache_dir = pathlib.Path(
|
|
16
|
-
os.environ.get("APPDATA")
|
|
17
|
-
or os.environ.get("XDG_CACHE_HOME")
|
|
18
|
-
or pathlib.Path.home() / ".cache"
|
|
16
|
+
os.environ.get("APPDATA") or os.environ.get("XDG_CACHE_HOME") or pathlib.Path.home() / ".cache"
|
|
19
17
|
).joinpath(
|
|
20
18
|
"materialsdb",
|
|
21
19
|
)
|
|
@@ -35,7 +33,7 @@ def parse_cached_index(index) -> etree._ElementTree:
|
|
|
35
33
|
return etree.ElementTree(root)
|
|
36
34
|
|
|
37
35
|
|
|
38
|
-
def get_by_id(root: etree._Element, id: str) ->
|
|
36
|
+
def get_by_id(root: etree._Element, id: str) -> etree._Element | None:
|
|
39
37
|
for company in root:
|
|
40
38
|
if company.get("id") == id:
|
|
41
39
|
return company
|
|
@@ -14,6 +14,12 @@ from dataclasses import dataclass
|
|
|
14
14
|
from typing import Tuple, Optional, List
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
class TDesignUsage(str):
|
|
18
|
+
xs_type: str = "simpleType"
|
|
19
|
+
xml_enum: Tuple[str, ...] = ('consDesignForWall', 'consDesignForRoof', 'consDesignForFloor')
|
|
20
|
+
xml_name: str = "TDesignUsage"
|
|
21
|
+
|
|
22
|
+
|
|
17
23
|
class TLCADB(str):
|
|
18
24
|
xs_type: str = "simpleType"
|
|
19
25
|
xml_enum: Tuple[str, ...] = ('dbKBOB', 'dbOkobauDat', 'dbLux')
|
|
@@ -58,7 +64,7 @@ class T2Lowercase(str):
|
|
|
58
64
|
|
|
59
65
|
class Groupkind(str):
|
|
60
66
|
xs_type: str = "simpleType"
|
|
61
|
-
xml_enum: Tuple[str, ...] = ('Others', 'Water_Proof', 'Vapour_Proof', 'Concrete', 'Wood_Timberproducts', 'Insulation', 'Masonry', 'Metal', 'Mortar', 'Plastics', 'Stone', 'Composite', 'Films', 'Render', 'Covering', 'Glas', 'Soil', '
|
|
67
|
+
xml_enum: Tuple[str, ...] = ('Others', 'Water_Proof', 'Vapour_Proof', 'Concrete', 'Wood_Timberproducts', 'Insulation', 'Masonry', 'Metal', 'Mortar', 'Plastics', 'Stone', 'Composite', 'Films', 'Render', 'Covering', 'Glas', 'Soil', 'Air')
|
|
62
68
|
xml_name: str = "groupkind"
|
|
63
69
|
|
|
64
70
|
|
|
@@ -408,9 +414,10 @@ class Lcia:
|
|
|
408
414
|
@dataclass
|
|
409
415
|
class Lcaversion:
|
|
410
416
|
id: str
|
|
411
|
-
code: Brackguid
|
|
412
417
|
xs_type: str = "element"
|
|
413
|
-
|
|
418
|
+
code: Optional[Brackguid] = None
|
|
419
|
+
disabled: Optional[Boolean] = None
|
|
420
|
+
xml_attributes: Tuple[str, ...] = ('id', 'code', 'disabled')
|
|
414
421
|
xml_name = "lcaversion"
|
|
415
422
|
xml_elements: Tuple[str, ...] = ()
|
|
416
423
|
|
|
@@ -555,11 +562,11 @@ class Vlca:
|
|
|
555
562
|
@dataclass
|
|
556
563
|
class Variation:
|
|
557
564
|
id: Guid
|
|
558
|
-
vgeometry: List[Vgeometry]
|
|
559
|
-
vthermal: List[Vthermal]
|
|
560
565
|
xs_type: str = "element"
|
|
561
566
|
displayorder: Optional[int] = None
|
|
562
567
|
xml_attributes: Tuple[str, ...] = ('id', 'displayorder')
|
|
568
|
+
vgeometry: Optional[List[Vgeometry]] = None
|
|
569
|
+
vthermal: Optional[List[Vthermal]] = None
|
|
563
570
|
vacoustic: Optional[List[Vacoustic]] = None
|
|
564
571
|
vother: Optional[List[Vother]] = None
|
|
565
572
|
vlcia: Optional[List[Vlcia]] = None
|
|
@@ -582,7 +589,8 @@ class Construction:
|
|
|
582
589
|
xs_type: str = "element"
|
|
583
590
|
source: Optional[str] = None
|
|
584
591
|
consref: Optional[str] = None
|
|
585
|
-
|
|
592
|
+
designusage: Optional[TDesignUsage] = None
|
|
593
|
+
xml_attributes: Tuple[str, ...] = ('source', 'consref', 'designusage')
|
|
586
594
|
xml_name = "construction"
|
|
587
595
|
xml_elements: Tuple[str, ...] = ()
|
|
588
596
|
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import os
|
|
2
3
|
import pathlib
|
|
3
|
-
import json
|
|
4
|
-
from typing import Dict
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
def get_config_dir():
|
|
8
7
|
config_dir = pathlib.Path(
|
|
9
|
-
os.environ.get("APPDATA")
|
|
10
|
-
or os.environ.get("XDG_CACHE_HOME")
|
|
11
|
-
or pathlib.Path.home() / ".config"
|
|
8
|
+
os.environ.get("APPDATA") or os.environ.get("XDG_CACHE_HOME") or pathlib.Path.home() / ".config"
|
|
12
9
|
).joinpath(
|
|
13
10
|
"materialsdb",
|
|
14
11
|
)
|
|
@@ -20,7 +17,7 @@ def get_base_config_path() -> pathlib.Path:
|
|
|
20
17
|
return get_config_dir() / "config.json"
|
|
21
18
|
|
|
22
19
|
|
|
23
|
-
def get_base_config() ->
|
|
20
|
+
def get_base_config() -> dict[str, str]:
|
|
24
21
|
base_config_path = get_base_config_path()
|
|
25
22
|
if base_config_path.exists():
|
|
26
23
|
return json.loads(get_base_config_path().read_text("utf-8"))
|