ifctrano 0.3.0__py3-none-any.whl → 0.7.0__py3-none-any.whl
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.
- ifctrano/__init__.py +5 -0
- ifctrano/base.py +5 -0
- ifctrano/bounding_box.py +11 -3
- ifctrano/building.py +20 -4
- ifctrano/construction.py +5 -5
- ifctrano/exceptions.py +4 -0
- ifctrano/main.py +13 -8
- ifctrano/space_boundary.py +118 -4
- ifctrano/types.py +7 -1
- ifctrano/utils.py +8 -0
- {ifctrano-0.3.0.dist-info → ifctrano-0.7.0.dist-info}/METADATA +103 -30
- ifctrano-0.7.0.dist-info/RECORD +16 -0
- {ifctrano-0.3.0.dist-info → ifctrano-0.7.0.dist-info}/WHEEL +1 -1
- ifctrano-0.3.0.dist-info/RECORD +0 -16
- {ifctrano-0.3.0.dist-info → ifctrano-0.7.0.dist-info}/entry_points.txt +0 -0
- {ifctrano-0.3.0.dist-info → ifctrano-0.7.0.dist-info/licenses}/LICENSE +0 -0
ifctrano/__init__.py
CHANGED
ifctrano/base.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import json
|
2
2
|
import math
|
3
|
+
import sys
|
3
4
|
from itertools import combinations
|
4
5
|
from multiprocessing import Process
|
5
6
|
from pathlib import Path
|
@@ -54,6 +55,9 @@ class BaseShow(BaseModel):
|
|
54
55
|
def description(self) -> Any: ... # noqa: ANN401
|
55
56
|
|
56
57
|
def show(self, interactive: bool = True) -> None:
|
58
|
+
if sys.platform == "win32":
|
59
|
+
_show(self.lines(), interactive)
|
60
|
+
return
|
57
61
|
p = Process(target=_show, args=(self.lines(), interactive))
|
58
62
|
p.start()
|
59
63
|
|
@@ -394,6 +398,7 @@ class CommonSurface(BaseShow):
|
|
394
398
|
main_vertices: FaceVertices
|
395
399
|
common_vertices: FaceVertices
|
396
400
|
exterior: bool = True
|
401
|
+
polygon: str
|
397
402
|
|
398
403
|
def __hash__(self) -> int:
|
399
404
|
return hash(
|
ifctrano/bounding_box.py
CHANGED
@@ -14,7 +14,7 @@ from pydantic import (
|
|
14
14
|
Field,
|
15
15
|
ConfigDict,
|
16
16
|
)
|
17
|
-
from scipy.spatial import ConvexHull # type: ignore
|
17
|
+
from scipy.spatial import ConvexHull, QhullError # type: ignore
|
18
18
|
from vedo import Line # type: ignore
|
19
19
|
|
20
20
|
from ifctrano.base import (
|
@@ -78,6 +78,7 @@ class ExtendCommonSurface(CommonSurface):
|
|
78
78
|
orientation=self.orientation,
|
79
79
|
main_vertices=self.main_vertices,
|
80
80
|
common_vertices=self.common_vertices,
|
81
|
+
polygon=self.polygon,
|
81
82
|
)
|
82
83
|
|
83
84
|
|
@@ -137,6 +138,7 @@ class OrientedBoundingBox(BaseShow):
|
|
137
138
|
common_vertices=projected_face_1.common_vertices(
|
138
139
|
intersection
|
139
140
|
),
|
141
|
+
polygon=intersection.wkt,
|
140
142
|
)
|
141
143
|
)
|
142
144
|
|
@@ -190,8 +192,14 @@ class OrientedBoundingBox(BaseShow):
|
|
190
192
|
entity_shape, entity_shape.geometry # type: ignore
|
191
193
|
)
|
192
194
|
vertices_ = Vertices.from_arrays(np.asarray(vertices))
|
193
|
-
|
194
|
-
|
195
|
+
try:
|
196
|
+
hull = ConvexHull(vertices_.to_array())
|
197
|
+
vertices_ = Vertices.from_arrays(vertices_.to_array()[hull.vertices])
|
198
|
+
|
199
|
+
except QhullError:
|
200
|
+
logger.error(
|
201
|
+
f"Convex hull failed for {entity.GlobalId} ({entity.is_a()}).... Continuing without it."
|
202
|
+
)
|
195
203
|
points_ = open3d.utility.Vector3dVector(vertices_.to_array())
|
196
204
|
aab = open3d.geometry.AxisAlignedBoundingBox.create_from_points(points_)
|
197
205
|
return cls.from_vertices(aab.get_box_points(), entity)
|
ifctrano/building.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import logging
|
1
2
|
import re
|
2
3
|
from pathlib import Path
|
3
4
|
from typing import List, Tuple, Any, Optional, Set
|
@@ -12,7 +13,11 @@ from trano.topology import Network # type: ignore
|
|
12
13
|
from vedo import Line # type: ignore
|
13
14
|
|
14
15
|
from ifctrano.base import BaseModelConfig, Libraries, Vector, BaseShow, CommonSurface
|
15
|
-
from ifctrano.exceptions import
|
16
|
+
from ifctrano.exceptions import (
|
17
|
+
IfcFileNotFoundError,
|
18
|
+
NoIfcSpaceFoundError,
|
19
|
+
NoSpaceBoundariesError,
|
20
|
+
)
|
16
21
|
from ifctrano.space_boundary import (
|
17
22
|
SpaceBoundaries,
|
18
23
|
initialize_tree,
|
@@ -20,6 +25,8 @@ from ifctrano.space_boundary import (
|
|
20
25
|
)
|
21
26
|
from ifctrano.construction import Constructions, default_construction
|
22
27
|
|
28
|
+
logger = logging.getLogger(__name__)
|
29
|
+
|
23
30
|
|
24
31
|
def get_spaces(ifcopenshell_file: file) -> List[entity_instance]:
|
25
32
|
return ifcopenshell_file.by_type("IfcSpace")
|
@@ -180,9 +187,18 @@ class Building(BaseShow):
|
|
180
187
|
]
|
181
188
|
if not spaces:
|
182
189
|
raise NoIfcSpaceFoundError("No IfcSpace found in the file.")
|
183
|
-
space_boundaries = [
|
184
|
-
|
185
|
-
|
190
|
+
space_boundaries = []
|
191
|
+
for space in spaces:
|
192
|
+
try:
|
193
|
+
space_boundaries.append(
|
194
|
+
SpaceBoundaries.from_space_entity(ifc_file, tree, space)
|
195
|
+
)
|
196
|
+
except Exception as e: # noqa: PERF203
|
197
|
+
logger.error(f"Cannot process space {space.id()}. Reason {e}")
|
198
|
+
continue
|
199
|
+
if not space_boundaries:
|
200
|
+
raise NoSpaceBoundariesError("No valid space boundaries found.")
|
201
|
+
|
186
202
|
return cls(
|
187
203
|
space_boundaries=space_boundaries,
|
188
204
|
ifc_file=ifc_file,
|
ifctrano/construction.py
CHANGED
@@ -189,9 +189,9 @@ class Constructions(BaseModel):
|
|
189
189
|
def get_construction(self, entity: entity_instance) -> Construction:
|
190
190
|
construction_id = self._get_construction_id(entity)
|
191
191
|
if construction_id is None:
|
192
|
-
logger.
|
193
|
-
f"Construction ID not found for {entity.GlobalId} ({entity.is_a()}) "
|
194
|
-
f"
|
192
|
+
logger.warning(
|
193
|
+
f"Construction ID not found for {entity.GlobalId} ({entity.is_a()}). "
|
194
|
+
f"Using default construction."
|
195
195
|
)
|
196
196
|
return default_construction
|
197
197
|
constructions = [
|
@@ -210,11 +210,11 @@ class Constructions(BaseModel):
|
|
210
210
|
if association.is_a() == "IfcRelAssociatesMaterial"
|
211
211
|
]
|
212
212
|
if not associates_materials:
|
213
|
-
logger.
|
213
|
+
logger.warning(f"Associate materials not found for {entity.GlobalId}.")
|
214
214
|
return None
|
215
215
|
relating_material = associates_materials[0].RelatingMaterial
|
216
216
|
if relating_material.is_a() == "IfcMaterialList":
|
217
|
-
logger.
|
217
|
+
logger.warning(
|
218
218
|
f"Material list found for {entity.GlobalId}, but no construction ID available."
|
219
219
|
)
|
220
220
|
return None
|
ifctrano/exceptions.py
CHANGED
ifctrano/main.py
CHANGED
@@ -15,6 +15,7 @@ from trano.utils.utils import is_success # type: ignore
|
|
15
15
|
from ifctrano.base import Libraries
|
16
16
|
from ifctrano.building import Building
|
17
17
|
from ifctrano.exceptions import InvalidLibraryError
|
18
|
+
from rich import print
|
18
19
|
|
19
20
|
app = typer.Typer()
|
20
21
|
CHECKMARK = "[green]✔[/green]"
|
@@ -34,11 +35,11 @@ def create(
|
|
34
35
|
show_space_boundaries: Annotated[
|
35
36
|
bool,
|
36
37
|
typer.Option(help="Show computed space boundaries."),
|
37
|
-
] =
|
38
|
+
] = False,
|
38
39
|
simulate_model: Annotated[
|
39
40
|
bool,
|
40
41
|
typer.Option(help="Simulate the generated model."),
|
41
|
-
] =
|
42
|
+
] = False,
|
42
43
|
) -> None:
|
43
44
|
with Progress(
|
44
45
|
SpinnerColumn(),
|
@@ -66,12 +67,16 @@ def create(
|
|
66
67
|
print(f"{CHECKMARK} Model generated at {modelica_model_path}")
|
67
68
|
if simulate_model:
|
68
69
|
print("Simulating...")
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
try:
|
71
|
+
results = simulate(
|
72
|
+
modelica_model_path.parent,
|
73
|
+
building.create_network(
|
74
|
+
library=library # type: ignore
|
75
|
+
), # TODO: cannot use the network after creating he model
|
76
|
+
)
|
77
|
+
except Exception as e:
|
78
|
+
print(f"{CROSS_MARK} Simulation failed: {e}")
|
79
|
+
return
|
75
80
|
if not is_success(results):
|
76
81
|
print(f"{CROSS_MARK} Simulation failed. See logs for more information.")
|
77
82
|
return
|
ifctrano/space_boundary.py
CHANGED
@@ -5,7 +5,8 @@ import ifcopenshell
|
|
5
5
|
import ifcopenshell.geom
|
6
6
|
import ifcopenshell.util.shape
|
7
7
|
from ifcopenshell import entity_instance, file
|
8
|
-
from pydantic import Field, BeforeValidator, BaseModel
|
8
|
+
from pydantic import Field, BeforeValidator, BaseModel, ConfigDict
|
9
|
+
from shapely import wkt # type: ignore
|
9
10
|
from trano.data_models.conversion import SpaceParameter # type: ignore
|
10
11
|
from trano.elements import Space as TranoSpace, ExternalWall, Window, BaseWall, ExternalDoor # type: ignore
|
11
12
|
from trano.elements.system import Occupancy # type: ignore
|
@@ -24,7 +25,12 @@ from ifctrano.base import (
|
|
24
25
|
from ifctrano.bounding_box import OrientedBoundingBox
|
25
26
|
from ifctrano.construction import glass, Constructions
|
26
27
|
from ifctrano.exceptions import HasWindowsWithoutWallsError
|
27
|
-
from ifctrano.utils import
|
28
|
+
from ifctrano.utils import (
|
29
|
+
remove_non_alphanumeric,
|
30
|
+
_round,
|
31
|
+
get_building_elements,
|
32
|
+
short_uuid,
|
33
|
+
)
|
28
34
|
|
29
35
|
ROOF_VECTOR = Vector(x=0, y=0, z=1)
|
30
36
|
|
@@ -175,7 +181,10 @@ class SpaceBoundary(BaseModelConfig):
|
|
175
181
|
return hash(self.common_surface)
|
176
182
|
|
177
183
|
def boundary_name(self) -> str:
|
178
|
-
return
|
184
|
+
return (
|
185
|
+
f"{remove_non_alphanumeric(self.entity.Name) or self.entity.is_a().lower()}_"
|
186
|
+
f"__{remove_non_alphanumeric(self.entity.GlobalId)}{short_uuid()}"
|
187
|
+
)
|
179
188
|
|
180
189
|
def model_element( # noqa: PLR0911
|
181
190
|
self,
|
@@ -332,4 +341,109 @@ class SpaceBoundaries(BaseShow):
|
|
332
341
|
)
|
333
342
|
if space_boundary:
|
334
343
|
space_boundaries.append(space_boundary)
|
335
|
-
|
344
|
+
merged_boundaries = MergedSpaceBoundaries.from_boundaries(space_boundaries)
|
345
|
+
space_boundaries_ = merged_boundaries.merge_boundaries_from_part()
|
346
|
+
space_boundaries__ = remove_duplicate_boundaries(space_boundaries_)
|
347
|
+
return cls(space=space_, boundaries=space_boundaries__)
|
348
|
+
|
349
|
+
|
350
|
+
def remove_duplicate_boundaries(
|
351
|
+
boundaries: List[SpaceBoundary],
|
352
|
+
) -> List[SpaceBoundary]:
|
353
|
+
types = ["IfcRoof", "IfcSlab"]
|
354
|
+
boundaries = sorted(boundaries, key=lambda b: b.entity.GlobalId)
|
355
|
+
boundaries_without_types = [
|
356
|
+
sp for sp in boundaries if sp.entity.is_a() not in types
|
357
|
+
]
|
358
|
+
new_boundaries = []
|
359
|
+
for type_ in types:
|
360
|
+
references = [sp for sp in boundaries if sp.entity.is_a() == type_]
|
361
|
+
while True:
|
362
|
+
reference = next(iter(references), None)
|
363
|
+
if not reference:
|
364
|
+
break
|
365
|
+
others = [p_ for p_ in references if p_ != reference]
|
366
|
+
intersecting = [
|
367
|
+
o
|
368
|
+
for o in others
|
369
|
+
if (
|
370
|
+
wkt.loads(o.common_surface.polygon).intersects(
|
371
|
+
wkt.loads(reference.common_surface.polygon)
|
372
|
+
)
|
373
|
+
and o.common_surface.orientation
|
374
|
+
== reference.common_surface.orientation
|
375
|
+
)
|
376
|
+
and (
|
377
|
+
wkt.loads(o.common_surface.polygon).intersection(
|
378
|
+
wkt.loads(reference.common_surface.polygon)
|
379
|
+
)
|
380
|
+
).area
|
381
|
+
> 0
|
382
|
+
]
|
383
|
+
current_group = sorted(
|
384
|
+
[*intersecting, reference], key=lambda p: p.entity.GlobalId
|
385
|
+
)
|
386
|
+
new_boundaries.append(next(iter(current_group)))
|
387
|
+
references = [p_ for p_ in references if p_ not in current_group]
|
388
|
+
return [*boundaries_without_types, *new_boundaries]
|
389
|
+
|
390
|
+
|
391
|
+
class MergedSpaceBoundary(BaseModel):
|
392
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
393
|
+
parent: entity_instance
|
394
|
+
related_boundaries: List[SpaceBoundary]
|
395
|
+
|
396
|
+
def get_new_boundary(self) -> Optional[SpaceBoundary]:
|
397
|
+
related_boundaries = sorted(
|
398
|
+
self.related_boundaries, key=lambda b: b.entity.GlobalId
|
399
|
+
)
|
400
|
+
boundary = next(iter(related_boundaries), None)
|
401
|
+
if boundary:
|
402
|
+
return SpaceBoundary.model_validate(
|
403
|
+
boundary.model_dump() | {"entity": self.parent}
|
404
|
+
)
|
405
|
+
return None
|
406
|
+
|
407
|
+
|
408
|
+
class MergedSpaceBoundaries(BaseModel):
|
409
|
+
part_boundaries: List[MergedSpaceBoundary]
|
410
|
+
original_boundaries: List[SpaceBoundary]
|
411
|
+
|
412
|
+
@classmethod
|
413
|
+
def from_boundaries(
|
414
|
+
cls, space_boundaries: List[SpaceBoundary]
|
415
|
+
) -> "MergedSpaceBoundaries":
|
416
|
+
building_element_part_boundaries = [
|
417
|
+
boundary
|
418
|
+
for boundary in space_boundaries
|
419
|
+
if boundary.entity.is_a() in ["IfcBuildingElementPart"]
|
420
|
+
]
|
421
|
+
existing_parent_entities = {
|
422
|
+
decompose.RelatingObject
|
423
|
+
for b in building_element_part_boundaries
|
424
|
+
for decompose in b.entity.Decomposes
|
425
|
+
}
|
426
|
+
part_boundaries = [
|
427
|
+
MergedSpaceBoundary(
|
428
|
+
parent=parent,
|
429
|
+
related_boundaries=[
|
430
|
+
b
|
431
|
+
for b in building_element_part_boundaries
|
432
|
+
for decompose in b.entity.Decomposes
|
433
|
+
if decompose.RelatingObject == parent
|
434
|
+
],
|
435
|
+
)
|
436
|
+
for parent in existing_parent_entities
|
437
|
+
]
|
438
|
+
return cls(
|
439
|
+
part_boundaries=part_boundaries, original_boundaries=space_boundaries
|
440
|
+
)
|
441
|
+
|
442
|
+
def merge_boundaries_from_part(self) -> List[SpaceBoundary]:
|
443
|
+
new_boundaries = [b.get_new_boundary() for b in self.part_boundaries]
|
444
|
+
new_boundaries_ = [nb for nb in new_boundaries if nb is not None]
|
445
|
+
return [
|
446
|
+
b
|
447
|
+
for b in self.original_boundaries
|
448
|
+
if b.entity.is_a() not in ["IfcBuildingElementPart"]
|
449
|
+
] + new_boundaries_
|
ifctrano/types.py
CHANGED
ifctrano/utils.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
import random
|
1
2
|
import re
|
3
|
+
import string
|
2
4
|
import uuid
|
3
5
|
from typing import get_args
|
4
6
|
|
@@ -13,6 +15,12 @@ def remove_non_alphanumeric(text: str) -> str:
|
|
13
15
|
return re.sub(r"[^a-zA-Z0-9_]", "", text).lower()
|
14
16
|
|
15
17
|
|
18
|
+
def short_uuid() -> str:
|
19
|
+
return "".join(
|
20
|
+
random.choices(string.ascii_letters + string.digits, k=3) # noqa: S311
|
21
|
+
)
|
22
|
+
|
23
|
+
|
16
24
|
def generate_alphanumeric_uuid() -> str:
|
17
25
|
return str(uuid.uuid4().hex).lower()
|
18
26
|
|
@@ -1,8 +1,9 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: ifctrano
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.7.0
|
4
4
|
Summary: Package for generating building energy simulation model from IFC
|
5
5
|
License: GPL V3
|
6
|
+
License-File: LICENSE
|
6
7
|
Keywords: BIM,IFC,energy simulation,modelica,building energy simulation,buildings,ideas
|
7
8
|
Author: Ando Andriamamonjy
|
8
9
|
Author-email: andoludovic.andriamamonjy@gmail.com
|
@@ -15,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
15
16
|
Requires-Dist: ifcopenshell (>=0.8.1.post1,<0.9.0)
|
16
17
|
Requires-Dist: open3d (>=0.19.0,<0.20.0)
|
17
18
|
Requires-Dist: shapely (>=2.0.7,<3.0.0)
|
18
|
-
Requires-Dist: trano (>=0.
|
19
|
+
Requires-Dist: trano (>=0.10.0,<0.11.0)
|
19
20
|
Requires-Dist: typer (>=0.12.5,<0.13.0)
|
20
21
|
Requires-Dist: vedo (>=2025.5.3,<2026.0.0)
|
21
22
|
Project-URL: Repository, https://github.com/andoludo/ifctrano
|
@@ -23,33 +24,11 @@ Description-Content-Type: text/markdown
|
|
23
24
|
|
24
25
|
# ifctrano - IFC to Energy Simulation Tool
|
25
26
|
|
27
|
+
---
|
26
28
|
📖 **Full Documentation:** 👉 [ifctrano Docs](https://andoludo.github.io/ifctrano/)
|
29
|
+
---
|
27
30
|
|
28
|
-
|
29
|
-
pip install ifctrano
|
30
|
-
```
|
31
|
-
|
32
|
-
To check the installation, run the following commands:
|
33
|
-
|
34
|
-
```bash
|
35
|
-
ifctrano --help
|
36
|
-
|
37
|
-
ifctrano verify
|
38
|
-
```
|
39
|
-
|
40
|
-
# ⚠️ WARNING ⚠️
|
41
|
-
|
42
|
-
**This package is still under construction and is largely a work in progress.**
|
43
|
-
There are still several aspects that need further development, including:
|
44
|
-
|
45
|
-
- Material and construction extraction
|
46
|
-
- Slab and roof boundaries
|
47
|
-
- Systems integration
|
48
|
-
- Additional validation
|
49
|
-
- Bug fixes
|
50
|
-
- ...
|
51
|
-
-
|
52
|
-
Help and contribution are more than appreciated! 🚧
|
31
|
+
Generate Modelica building models directly from IFC files — with support for simulation, visualization, and multiple libraries.
|
53
32
|
|
54
33
|
## Overview
|
55
34
|
ifctrano is yet another **IFC to energy simulation** tool designed to translate **Industry Foundation Classes (IFC)** models into energy simulation models in **Modelica**.
|
@@ -79,10 +58,104 @@ ifctrano has been tested using open-source IFC files from various repositories:
|
|
79
58
|
- 🕸️ [Ifc2Graph Test Files](https://github.com/JBjoernskov/Ifc2Graph/tree/main/test_ifc_files)
|
80
59
|
- 🔓 [Open Source BIM](https://github.com/opensourceBIM)
|
81
60
|
|
82
|
-
## Installation
|
83
|
-
|
61
|
+
## 🚀 Installation
|
62
|
+
|
63
|
+
### 📦 Install `ifctrano`
|
64
|
+
|
65
|
+
!!! warning
|
66
|
+
Trano requires python 3.9 or higher and docker to be installed on the system.
|
67
|
+
|
68
|
+
|
69
|
+
ifctrano is a Python package that can be installed via pip.
|
70
|
+
|
71
|
+
```bash
|
72
|
+
pip install ifctrano
|
73
|
+
```
|
74
|
+
|
75
|
+
### ✅ Verify Installation
|
76
|
+
|
77
|
+
Run the following commands to ensure everything is working:
|
78
|
+
|
79
|
+
```bash
|
80
|
+
ifctrano --help
|
81
|
+
ifctrano verify
|
82
|
+
```
|
83
|
+
|
84
|
+
---
|
85
|
+
|
86
|
+
## 🔧 Optional Dependencies
|
87
|
+
|
88
|
+
### 🐳 Docker (for simulation)
|
89
|
+
|
90
|
+
To enable model simulation using the official OpenModelica Docker image, install Docker Desktop:
|
91
|
+
|
92
|
+
👉 [https://docs.docker.com/desktop/](https://docs.docker.com/desktop/)
|
93
|
+
|
94
|
+
Required for using the `--simulate-model` flag.
|
95
|
+
|
96
|
+
---
|
84
97
|
|
98
|
+
### 🧠 Graphviz (for layout visualization)
|
99
|
+
|
100
|
+
`ifctrano` leverages Graphviz to optimize component layout in generated Modelica models. It is optional, but **recommended**.
|
101
|
+
|
102
|
+
#### 📥 Install on Windows
|
103
|
+
|
104
|
+
- Download and install from: [https://graphviz.org/download/](https://graphviz.org/download/)
|
105
|
+
- Add the Graphviz `bin` folder to your **system `PATH`**.
|
106
|
+
|
107
|
+
#### 🐧 Install on Linux
|
108
|
+
|
109
|
+
```bash
|
110
|
+
sudo apt update
|
111
|
+
sudo apt install graphviz
|
112
|
+
```
|
113
|
+
|
114
|
+
---
|
115
|
+
|
116
|
+
## ⚙️ Usage
|
117
|
+
|
118
|
+
### 📁 Generate Modelica models from IFC
|
119
|
+
|
120
|
+
#### 🏢 Using the **Buildings** library
|
121
|
+
|
122
|
+
```bash
|
123
|
+
ifctrano create /path/to/your.ifc
|
124
|
+
```
|
125
|
+
|
126
|
+
#### 🏫 Using the **IDEAS** library
|
127
|
+
|
128
|
+
```bash
|
129
|
+
ifctrano create /path/to/your.ifc IDEAS
|
130
|
+
```
|
131
|
+
|
132
|
+
#### 🧮 Using the **Reduced Order** library
|
133
|
+
|
134
|
+
```bash
|
135
|
+
ifctrano create /path/to/your.ifc reduced_order
|
136
|
+
```
|
137
|
+
|
138
|
+
---
|
139
|
+
|
140
|
+
### 🧱 Show Space Boundaries
|
141
|
+
|
142
|
+
To visualize the computed space boundaries:
|
143
|
+
|
144
|
+
```bash
|
145
|
+
ifctrano create /path/to/your.ifc --show-space-boundaries
|
146
|
+
```
|
147
|
+
|
148
|
+
---
|
149
|
+
|
150
|
+
### 🔁 Simulate the Model
|
151
|
+
|
152
|
+
Run a full simulation after model generation:
|
153
|
+
|
154
|
+
```bash
|
155
|
+
ifctrano create /path/to/your.ifc --simulate-model
|
156
|
+
```
|
85
157
|
|
158
|
+
Make sure Docker is installed and running before simulating.
|
86
159
|
|
87
160
|
---
|
88
161
|
💡 **ifctrano** aims to make energy simulation model generation from IFC files **simpler, more accessible, and less reliant on incomplete IFC attributes**. 🚀
|
@@ -0,0 +1,16 @@
|
|
1
|
+
ifctrano/__init__.py,sha256=6wK0Qa_5Xe0KSk5Spn98AjTNCTIXtenZ3C0k8ZaVcn8,191
|
2
|
+
ifctrano/base.py,sha256=s8BSnQqd6v_NFvkQFRriHCine6iylUBQai2FduC4IFk,14352
|
3
|
+
ifctrano/bounding_box.py,sha256=64jlzY60ZDUX4ipR34WkOICpPhxLP-5w-FP42yBONRs,7729
|
4
|
+
ifctrano/building.py,sha256=tBctMyrsvwRiDk5bDhAdfgRlbyvnbCCeA8rcdUjMbU8,9355
|
5
|
+
ifctrano/construction.py,sha256=Lyh_o37znrDyxtKgw7dOqVsQk1S3btCPDh2YTJ8h6T0,7234
|
6
|
+
ifctrano/example/verification.ifc,sha256=tQ9QcubT_wrbb-sc1WRRwYpb2cbkWm3dnRfXdP5GTTg,131
|
7
|
+
ifctrano/exceptions.py,sha256=JDy_0HV7_FLfr92DkrN8F59zUHl9KdMa_lfIcfBJG6I,540
|
8
|
+
ifctrano/main.py,sha256=YTp7RaWRMKt_UC2DRt_oXXLGTLCAc9FPg6Tsqg1zgpk,4979
|
9
|
+
ifctrano/space_boundary.py,sha256=PmiKhcJo6iyxXKNab5NCphQgBQwatoNsqsi-BYHOONs,16055
|
10
|
+
ifctrano/types.py,sha256=FBSWrD66EL7uHvv0GveCXmYyLtCr8gGRlT7-5j7aZD8,181
|
11
|
+
ifctrano/utils.py,sha256=zLQUGVo15RSQQ-vfOuHsJBkHy4QhpxKSAH7Au72s0s0,873
|
12
|
+
ifctrano-0.7.0.dist-info/METADATA,sha256=VAynLl3eaecRmVSgvU3XVSmO-_weipMqdfbw-pq3Blw,4884
|
13
|
+
ifctrano-0.7.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
14
|
+
ifctrano-0.7.0.dist-info/entry_points.txt,sha256=_2daDejazkphufyEu0m3lOeTio53WYmjol3KmSN0JM4,46
|
15
|
+
ifctrano-0.7.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
16
|
+
ifctrano-0.7.0.dist-info/RECORD,,
|
ifctrano-0.3.0.dist-info/RECORD
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
ifctrano/__init__.py,sha256=UT1-izHuXPq06nSeKzgs6qoVRfc6RqIhabf-ZKgAXf4,76
|
2
|
-
ifctrano/base.py,sha256=BQpMZwSq0tiUN0g56CfzF11lIlijwi7VuLjC2XY4mx0,14224
|
3
|
-
ifctrano/bounding_box.py,sha256=k74UIutxaNxfdfAjSqvr6Jj3gu6OP4sbQB_kTnZlltw,7431
|
4
|
-
ifctrano/building.py,sha256=MUaSqWQP_4kZbH6-yrjRahm8poxLBHiBlMjOFNUV88o,8910
|
5
|
-
ifctrano/construction.py,sha256=KGiJJ6L0D7mK254GYl6CO7TKoTNoUSJeZCSHzbkhslo,7244
|
6
|
-
ifctrano/example/verification.ifc,sha256=tQ9QcubT_wrbb-sc1WRRwYpb2cbkWm3dnRfXdP5GTTg,131
|
7
|
-
ifctrano/exceptions.py,sha256=SKFiFEhn0bW2Dm4fVHeMGIQ1C84nlLhapxy8y46SkfM,488
|
8
|
-
ifctrano/main.py,sha256=cXev3w-uC_wgi4lxtvn4zrAogX-6pUSR0GNav3s0Z5g,4793
|
9
|
-
ifctrano/space_boundary.py,sha256=lDhq05FC8BMZ07vGhU9smXj-gnOy-zoqIpkoW0QFCeI,11922
|
10
|
-
ifctrano/types.py,sha256=wxKVb2R4Dz58YzN4PzgXhuuVw-UYobSh9fnYWQrYlqQ,130
|
11
|
-
ifctrano/utils.py,sha256=AjQrIqbKAk4CWCcfeRHSZtWT6AAxQLyj-uDWPdUU6UU,712
|
12
|
-
ifctrano-0.3.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
13
|
-
ifctrano-0.3.0.dist-info/METADATA,sha256=5hdAUTbC0kirbMFK_uvxKk76HGHHf-f8sHKJxkhkaWs,3533
|
14
|
-
ifctrano-0.3.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
15
|
-
ifctrano-0.3.0.dist-info/entry_points.txt,sha256=_2daDejazkphufyEu0m3lOeTio53WYmjol3KmSN0JM4,46
|
16
|
-
ifctrano-0.3.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|