python-materialsdb 0.3.2__tar.gz → 0.4.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.3.2 → python_materialsdb-0.4.0}/PKG-INFO +17 -2
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/README.md +16 -1
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/pyproject.toml +1 -1
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/classes.py +1 -1
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/config.py +17 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/listener.py +104 -18
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/server.py +561 -5
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/static/app-constructions.js +8 -19
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/static/app.js +308 -35
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/static/constructions.html +1 -5
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/static/index.html +20 -5
- python_materialsdb-0.4.0/src/materialsdb/gui/static/settings.html +74 -0
- python_materialsdb-0.4.0/src/materialsdb/gui/static/settings.js +643 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/ifc/material_builder.py +62 -49
- python_materialsdb-0.4.0/src/materialsdb/schemes.py +196 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/store.py +101 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/utils.py +5 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/python_materialsdb.egg-info/PKG-INFO +17 -2
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/python_materialsdb.egg-info/SOURCES.txt +8 -0
- python_materialsdb-0.4.0/tests/test_bonsai_discovery.py +224 -0
- python_materialsdb-0.4.0/tests/test_bonsai_insert.py +1550 -0
- python_materialsdb-0.4.0/tests/test_bonsai_safety_net.py +48 -0
- python_materialsdb-0.4.0/tests/test_config.py +33 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_construction_frontend.py +1 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_gui_server.py +886 -5
- python_materialsdb-0.4.0/tests/test_listener_payload.py +571 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_material_builder.py +96 -0
- python_materialsdb-0.4.0/tests/test_model_changes_frontend.py +42 -0
- python_materialsdb-0.4.0/tests/test_schemes.py +80 -0
- python_materialsdb-0.4.0/tests/test_settings_frontend.py +84 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_store.py +116 -0
- python_materialsdb-0.3.2/tests/test_bonsai_discovery.py +0 -90
- python_materialsdb-0.3.2/tests/test_bonsai_insert.py +0 -714
- python_materialsdb-0.3.2/tests/test_listener_payload.py +0 -288
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/LICENSE.md +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/setup.cfg +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/__init__.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/cache.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/construction.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/__init__.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/__main__.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/discovery.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/gui/static/picker-core.js +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/ifc/__init__.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/ifc/material_psets.json +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/ifc/project_library.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/query.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/schema/MaterialsDBIndex100.xsd +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/schema/materialsdb102.xsd +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/schema/materialsdb103.xsd +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/serialiser.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/materialsdb/summary.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/python_materialsdb.egg-info/dependency_links.txt +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/python_materialsdb.egg-info/entry_points.txt +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/python_materialsdb.egg-info/requires.txt +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/src/python_materialsdb.egg-info/top_level.txt +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_build_bonsai_addon.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_cache.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_construction.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_construction_ifc.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_picker_frontend.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_project_library.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_query.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_serialiser.py +0 -0
- {python_materialsdb-0.3.2 → python_materialsdb-0.4.0}/tests/test_summary.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-materialsdb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A library to work with materialsdb.org open standard for building materials.
|
|
5
5
|
Author-email: Cyril Waechter <cyrwae@hotmail.com>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -107,6 +107,17 @@ a standalone `.ifc`, or open one of your own `.ifc` files and append the
|
|
|
107
107
|
selected materials into it. The same HTTP API powers future BIM software
|
|
108
108
|
plugins (all mutating calls require a per-launch token).
|
|
109
109
|
|
|
110
|
+
# Colour schemes & settings :
|
|
111
|
+
The Settings page (top navigation) holds language and country, the active
|
|
112
|
+
colour scheme and an *always use category colours* switch. Materials with a
|
|
113
|
+
producer colour keep it unless the switch is on; the others take their
|
|
114
|
+
category's colour from the active scheme (built-in Lesosai, or your own
|
|
115
|
+
palettes). The palette editor edits all 17 category colours with colour
|
|
116
|
+
pickers and a live preview, saves palettes by name, renames on save, and
|
|
117
|
+
exports/imports them as JSON. *Apply colours to model* repaints every
|
|
118
|
+
materialsdb material in the open Bonsai model — choosing the target model and
|
|
119
|
+
showing the listener's result — without touching the material data.
|
|
120
|
+
|
|
110
121
|
# Construction maker :
|
|
111
122
|
Compose thermal constructions from materialsdb materials and compute their
|
|
112
123
|
U-value (ISO 6946 / SIA 180 surface resistance presets):
|
|
@@ -152,7 +163,11 @@ constructions become typed elements (`IfcWallType`/`IfcSlabType`/
|
|
|
152
163
|
visible in the outliner and revertible with Ctrl+Z. Each pushed type
|
|
153
164
|
also carries its computed U-value as `ThermalTransmittance` in
|
|
154
165
|
`Pset_WallCommon`/`Pset_SlabCommon`/`Pset_RoofCommon` (per the element
|
|
155
|
-
type).
|
|
166
|
+
type). The picker flags materials whose producer data changed since you
|
|
167
|
+
pushed them, with a changed-field report and opt-in *Update*/*Replace*
|
|
168
|
+
actions (in-place updates keep the entity and never rewrite layer
|
|
169
|
+
thicknesses); *force update used materials* refreshes every materialsdb
|
|
170
|
+
material used by walls, slabs and roofs in one go. Round-trip: select
|
|
156
171
|
the wall (or its type) in Bonsai and hit *Send type to composer* in the
|
|
157
172
|
materialsdb panel — the construction appears under *incoming from model*
|
|
158
173
|
on the constructions page for editing. Any layer's material can be
|
|
@@ -80,6 +80,17 @@ a standalone `.ifc`, or open one of your own `.ifc` files and append the
|
|
|
80
80
|
selected materials into it. The same HTTP API powers future BIM software
|
|
81
81
|
plugins (all mutating calls require a per-launch token).
|
|
82
82
|
|
|
83
|
+
# Colour schemes & settings :
|
|
84
|
+
The Settings page (top navigation) holds language and country, the active
|
|
85
|
+
colour scheme and an *always use category colours* switch. Materials with a
|
|
86
|
+
producer colour keep it unless the switch is on; the others take their
|
|
87
|
+
category's colour from the active scheme (built-in Lesosai, or your own
|
|
88
|
+
palettes). The palette editor edits all 17 category colours with colour
|
|
89
|
+
pickers and a live preview, saves palettes by name, renames on save, and
|
|
90
|
+
exports/imports them as JSON. *Apply colours to model* repaints every
|
|
91
|
+
materialsdb material in the open Bonsai model — choosing the target model and
|
|
92
|
+
showing the listener's result — without touching the material data.
|
|
93
|
+
|
|
83
94
|
# Construction maker :
|
|
84
95
|
Compose thermal constructions from materialsdb materials and compute their
|
|
85
96
|
U-value (ISO 6946 / SIA 180 surface resistance presets):
|
|
@@ -125,7 +136,11 @@ constructions become typed elements (`IfcWallType`/`IfcSlabType`/
|
|
|
125
136
|
visible in the outliner and revertible with Ctrl+Z. Each pushed type
|
|
126
137
|
also carries its computed U-value as `ThermalTransmittance` in
|
|
127
138
|
`Pset_WallCommon`/`Pset_SlabCommon`/`Pset_RoofCommon` (per the element
|
|
128
|
-
type).
|
|
139
|
+
type). The picker flags materials whose producer data changed since you
|
|
140
|
+
pushed them, with a changed-field report and opt-in *Update*/*Replace*
|
|
141
|
+
actions (in-place updates keep the entity and never rewrite layer
|
|
142
|
+
thicknesses); *force update used materials* refreshes every materialsdb
|
|
143
|
+
material used by walls, slabs and roofs in one go. Round-trip: select
|
|
129
144
|
the wall (or its type) in Bonsai and hit *Send type to composer* in the
|
|
130
145
|
materialsdb panel — the construction appears under *incoming from model*
|
|
131
146
|
on the constructions page for editing. Any layer's material can be
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-materialsdb"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "A library to work with materialsdb.org open standard for building materials."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "GPL-3.0-or-later"
|
|
@@ -93,7 +93,7 @@ class Guid(str):
|
|
|
93
93
|
|
|
94
94
|
class Brackguid(str):
|
|
95
95
|
xs_type: str = "simpleType"
|
|
96
|
-
xml_pattern:str = "
|
|
96
|
+
xml_pattern:str = "\\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\}"
|
|
97
97
|
xml_name: str = "Brackguid"
|
|
98
98
|
|
|
99
99
|
|
|
@@ -50,6 +50,23 @@ def set_country(country: str):
|
|
|
50
50
|
set_param("country", country)
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
def get_scheme() -> str:
|
|
54
|
+
return str(get_base_config().get("scheme") or "")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def set_scheme(name: str) -> None:
|
|
58
|
+
set_param("scheme", str(name))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def get_ignore_producer_color() -> bool:
|
|
62
|
+
value = get_base_config().get("ignore_producer_color", "false")
|
|
63
|
+
return str(value).strip().lower() in ("true", "1", "yes", "on")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def set_ignore_producer_color(value: bool) -> None:
|
|
67
|
+
set_param("ignore_producer_color", "true" if value else "false")
|
|
68
|
+
|
|
69
|
+
|
|
53
70
|
def main():
|
|
54
71
|
lang = get_lang()
|
|
55
72
|
set_lang(lang)
|
|
@@ -6,6 +6,7 @@ maps the payload onto its open file without importing this library."""
|
|
|
6
6
|
|
|
7
7
|
from materialsdb import config, utils
|
|
8
8
|
from materialsdb.ifc.material_builder import PSETS, get_value, style_for
|
|
9
|
+
from materialsdb.store import FINGERPRINT_SCHEME
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def _resolved_psets(layer, country) -> dict:
|
|
@@ -45,6 +46,7 @@ def build_add_materials_payload(store_, items, country=None, lang=None):
|
|
|
45
46
|
if summary is None or material is None:
|
|
46
47
|
missing.append(material_id)
|
|
47
48
|
continue
|
|
49
|
+
fingerprint = store_.material_fingerprint(material_id)
|
|
48
50
|
wanted = {str(g) for g in item.get("layer_ids") or []} or None
|
|
49
51
|
name = str(utils.get_material_name(material, lang))
|
|
50
52
|
description = str(utils.get_material_description(material, lang))
|
|
@@ -53,7 +55,12 @@ def build_add_materials_payload(store_, items, country=None, lang=None):
|
|
|
53
55
|
color = int(color) if color else None
|
|
54
56
|
# Resolve the surface style server-side: the add-on runs in Blender's
|
|
55
57
|
# interpreter without access to the materialsdb colour scheme.
|
|
56
|
-
style_name, style_rgb = style_for(
|
|
58
|
+
style_name, style_rgb = style_for(
|
|
59
|
+
color,
|
|
60
|
+
category,
|
|
61
|
+
scheme=config.get_scheme(),
|
|
62
|
+
ignore_producer_color=config.get_ignore_producer_color(),
|
|
63
|
+
)
|
|
57
64
|
entries = []
|
|
58
65
|
for layer in utils.get_material_layers(material):
|
|
59
66
|
if wanted is not None and str(layer.id) not in wanted:
|
|
@@ -74,7 +81,13 @@ def build_add_materials_payload(store_, items, country=None, lang=None):
|
|
|
74
81
|
"material_id": material_id,
|
|
75
82
|
"company_id": str(summary.company_id or ""),
|
|
76
83
|
"company": str(summary.company or ""),
|
|
84
|
+
"fingerprint": fingerprint,
|
|
85
|
+
"fingerprint_scheme": FINGERPRINT_SCHEME,
|
|
77
86
|
},
|
|
87
|
+
"mode": item.get("mode", "skip"),
|
|
88
|
+
"replaces": item.get("replaces"),
|
|
89
|
+
"update": item.get("update"),
|
|
90
|
+
"force": bool(item.get("force")),
|
|
78
91
|
"psets": _resolved_psets(layer, country),
|
|
79
92
|
"layer": {"layer_id": str(layer.id), "thick_m": thick / 1000} if thick else None,
|
|
80
93
|
}
|
|
@@ -86,6 +99,55 @@ def build_add_materials_payload(store_, items, country=None, lang=None):
|
|
|
86
99
|
return {"action": "add_materials", "materials": materials}, missing
|
|
87
100
|
|
|
88
101
|
|
|
102
|
+
def _layer_thick_m(layer, country) -> float | None:
|
|
103
|
+
"""The layer's thickness in metres for `country`, or None when absent."""
|
|
104
|
+
thick = getattr(utils.get_by_country(layer.geometry or (), country), "thick", None)
|
|
105
|
+
return thick / 1000 if thick is not None else None
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _resolve_construction_layer(material, design_thickness_m, country, lang) -> tuple[object | None, str | None]:
|
|
109
|
+
"""Map a construction layer's design thickness onto a materialsdb Layer.
|
|
110
|
+
|
|
111
|
+
Exact thickness match wins; a single-layer material resolves to its only
|
|
112
|
+
layer whatever the design thickness; multi-layer mismatches fall back to
|
|
113
|
+
the first layer with a warning. Returns (layer_or_None, warning_or_None)."""
|
|
114
|
+
layers = list(utils.get_material_layers(material))
|
|
115
|
+
if not layers:
|
|
116
|
+
name = str(utils.get_material_name(material, lang))
|
|
117
|
+
return None, f"{name}: material has no layer"
|
|
118
|
+
for layer in layers:
|
|
119
|
+
thick_m = _layer_thick_m(layer, country)
|
|
120
|
+
if thick_m is not None and abs(thick_m - design_thickness_m) <= utils.THICKNESS_EPS_M:
|
|
121
|
+
return layer, None
|
|
122
|
+
if len(layers) == 1:
|
|
123
|
+
return layers[0], None
|
|
124
|
+
name = str(utils.get_material_name(material, lang))
|
|
125
|
+
return layers[0], f"{name}: design thickness {round(design_thickness_m * 1000)} mm matches no layer"
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _raw_decision_layer(raw_layers, material_id, thickness_m) -> dict:
|
|
129
|
+
"""The raw body layer carrying the decision for this validated layer.
|
|
130
|
+
|
|
131
|
+
``validate_construction`` can drop or reorder malformed layers, so the
|
|
132
|
+
validated index does not address ``raw_layers``. Match on the pair
|
|
133
|
+
(material_id, thickness) instead; when no exact match is unambiguous the
|
|
134
|
+
decision fields are omitted, i.e. the layer is treated as ``skip`` rather
|
|
135
|
+
than inheriting another layer's mode/update/replaces."""
|
|
136
|
+
matches = []
|
|
137
|
+
for raw in raw_layers:
|
|
138
|
+
if not isinstance(raw, dict):
|
|
139
|
+
continue
|
|
140
|
+
if str(raw.get("material_id")) != str(material_id):
|
|
141
|
+
continue
|
|
142
|
+
try:
|
|
143
|
+
raw_thickness = float(raw.get("thickness_m"))
|
|
144
|
+
except (TypeError, ValueError):
|
|
145
|
+
continue
|
|
146
|
+
if abs(raw_thickness - thickness_m) <= utils.THICKNESS_EPS_M:
|
|
147
|
+
matches.append(raw)
|
|
148
|
+
return matches[0] if len(matches) == 1 else {}
|
|
149
|
+
|
|
150
|
+
|
|
89
151
|
_DESIGN_USAGE_TO_TYPES = {
|
|
90
152
|
"consDesignForWall": ["IfcWallType"],
|
|
91
153
|
"consDesignForFloor": ["IfcSlabType"],
|
|
@@ -97,8 +159,9 @@ GENERIC_TYPES = ["IfcWallType", "IfcSlabType", "IfcRoofType"]
|
|
|
97
159
|
def build_add_construction_payload(store_, body, country=None, lang=None):
|
|
98
160
|
"""Resolve a construction body into a self-sufficient add_construction
|
|
99
161
|
payload (or (None, problems) when validation fails). Materials travel
|
|
100
|
-
|
|
101
|
-
find-or-create on the add-on side keys on
|
|
162
|
+
resolved — identity/name/category/style plus their layer's materialsdb
|
|
163
|
+
psets — and find-or-create on the add-on side keys on
|
|
164
|
+
(material_id, org_layer layer_id)."""
|
|
102
165
|
from materialsdb import construction as cm
|
|
103
166
|
|
|
104
167
|
body = dict(body or {})
|
|
@@ -109,7 +172,11 @@ def build_add_construction_payload(store_, body, country=None, lang=None):
|
|
|
109
172
|
return None, problems
|
|
110
173
|
country = country or config.get_country()
|
|
111
174
|
lang = lang or config.get_lang()
|
|
175
|
+
raw_layers: list = []
|
|
176
|
+
if isinstance(body.get("layers"), list):
|
|
177
|
+
raw_layers = body["layers"]
|
|
112
178
|
layers = []
|
|
179
|
+
warnings = []
|
|
113
180
|
for layer in construction.layers:
|
|
114
181
|
if layer.placeholder is not None:
|
|
115
182
|
layers.append(
|
|
@@ -125,28 +192,46 @@ def build_add_construction_payload(store_, body, country=None, lang=None):
|
|
|
125
192
|
if summary is None or material is None:
|
|
126
193
|
problems.append(f"unknown material id: {layer.material_id}")
|
|
127
194
|
continue
|
|
195
|
+
resolved_layer, warning = _resolve_construction_layer(material, layer.thickness_m, country, lang)
|
|
196
|
+
if warning is not None:
|
|
197
|
+
warnings.append(warning)
|
|
198
|
+
raw_layer = _raw_decision_layer(raw_layers, layer.material_id, layer.thickness_m)
|
|
128
199
|
color = getattr(material.information, "color", None)
|
|
129
200
|
color = int(color) if color else None
|
|
130
201
|
category = str(getattr(material.information, "group", "") or "")
|
|
131
|
-
style_name, style_rgb = style_for(
|
|
202
|
+
style_name, style_rgb = style_for(
|
|
203
|
+
color,
|
|
204
|
+
category,
|
|
205
|
+
scheme=config.get_scheme(),
|
|
206
|
+
ignore_producer_color=config.get_ignore_producer_color(),
|
|
207
|
+
)
|
|
208
|
+
material_entry = {
|
|
209
|
+
"source_id": layer.material_id,
|
|
210
|
+
"name": str(utils.get_material_name(material, lang)),
|
|
211
|
+
"description": str(utils.get_material_description(material, lang)),
|
|
212
|
+
"category": category,
|
|
213
|
+
"color": color,
|
|
214
|
+
"style_name": style_name,
|
|
215
|
+
"style_color": [round(component, 6) for component in style_rgb],
|
|
216
|
+
"identity": {
|
|
217
|
+
"material_id": layer.material_id,
|
|
218
|
+
"company_id": str(summary.company_id or ""),
|
|
219
|
+
"company": str(summary.company or ""),
|
|
220
|
+
"fingerprint": store_.material_fingerprint(layer.material_id),
|
|
221
|
+
"fingerprint_scheme": FINGERPRINT_SCHEME,
|
|
222
|
+
},
|
|
223
|
+
"mode": raw_layer.get("mode", "skip"),
|
|
224
|
+
"replaces": raw_layer.get("replaces"),
|
|
225
|
+
"update": raw_layer.get("update"),
|
|
226
|
+
"force": bool(raw_layer.get("force")),
|
|
227
|
+
}
|
|
228
|
+
if resolved_layer is not None:
|
|
229
|
+
material_entry["psets"] = _resolved_psets(resolved_layer, country)
|
|
132
230
|
layers.append(
|
|
133
231
|
{
|
|
134
232
|
"material_id": layer.material_id,
|
|
135
233
|
"thickness_m": layer.thickness_m,
|
|
136
|
-
"material":
|
|
137
|
-
"source_id": layer.material_id,
|
|
138
|
-
"name": str(utils.get_material_name(material, lang)),
|
|
139
|
-
"description": str(utils.get_material_description(material, lang)),
|
|
140
|
-
"category": category,
|
|
141
|
-
"color": color,
|
|
142
|
-
"style_name": style_name,
|
|
143
|
-
"style_color": [round(component, 6) for component in style_rgb],
|
|
144
|
-
"identity": {
|
|
145
|
-
"material_id": layer.material_id,
|
|
146
|
-
"company_id": str(summary.company_id or ""),
|
|
147
|
-
"company": str(summary.company or ""),
|
|
148
|
-
},
|
|
149
|
-
},
|
|
234
|
+
"material": material_entry,
|
|
150
235
|
}
|
|
151
236
|
)
|
|
152
237
|
if problems:
|
|
@@ -162,5 +247,6 @@ def build_add_construction_payload(store_, body, country=None, lang=None):
|
|
|
162
247
|
cls: u for cls, u in cm.u_values_by_type(construction, store_, types).items() if u is not None
|
|
163
248
|
},
|
|
164
249
|
"layers": layers,
|
|
250
|
+
"warnings": warnings,
|
|
165
251
|
},
|
|
166
252
|
}, []
|