├── .gitignore ├── .idea ├── inspectionProfiles │ └── profiles_settings.xml └── vcs.xml ├── LICENSE ├── MANIFEST ├── README.md ├── dotbimpy ├── __init__.py ├── file.py ├── other │ ├── DotbimToTrimeshScene.ipynb │ ├── Truss.ipynb │ └── WallsWithBeams.ipynb └── tests │ ├── __init__.py │ ├── test_helper.py │ └── unittests │ ├── __init__.py │ ├── test_color.py │ ├── test_element.py │ ├── test_file.py │ ├── test_files │ ├── BricksRotated.bim │ ├── Cubes.bim │ ├── CubesWithFaceColorsAndWithout.bim │ ├── MulticolorHouse.bim │ ├── MultipleMeshes.bim │ ├── Pyramid.bim │ ├── Truss.bim │ └── WallsWithBeams.bim │ ├── test_mesh.py │ ├── test_rotation.py │ ├── test_vector.py │ └── text_files │ └── plotly_multiple_meshes.txt ├── setup.cfg └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 105 | __pypackages__/ 106 | 107 | # Celery stuff 108 | celerybeat-schedule 109 | celerybeat.pid 110 | 111 | # SageMath parsed files 112 | *.sage.py 113 | 114 | # Environments 115 | .env 116 | .venv 117 | env/ 118 | venv/ 119 | ENV/ 120 | env.bak/ 121 | venv.bak/ 122 | 123 | # Spyder project settings 124 | .spyderproject 125 | .spyproject 126 | 127 | # Rope project settings 128 | .ropeproject 129 | 130 | # mkdocs documentation 131 | /site 132 | 133 | # mypy 134 | .mypy_cache/ 135 | .dmypy.json 136 | dmypy.json 137 | 138 | # Pyre type checker 139 | .pyre/ 140 | 141 | # pytype static type analyzer 142 | .pytype/ 143 | 144 | # Cython debug symbols 145 | cython_debug/ -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Wojciech Radaczyński 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | # file GENERATED by distutils, do NOT edit 2 | setup.cfg 3 | setup.py 4 | dotbimpy\__init__.py 5 | dotbimpy\file.py 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dotbimpy (Version 0.1.0) 2 | 3 | ## Description 4 | 5 | Open-source Python library for dotbim file format. 6 | 7 | Read more about dotbim here: https://github.com/paireks/dotbim 8 | 9 | dotbim's website: https://dotbim.net/ 10 | 11 | Here you can find small manual for developers regarding development of tools that will work with .bim file format: https://github.com/paireks/dotbim/blob/master/DeveloperTips.md 12 | 13 | ## Installation 14 | 15 | ### Python 16 | 17 | ```cmd 18 | pip install dotbimpy 19 | ``` 20 | 21 | ### JupyterLab / Jupyter Notebooks 22 | 23 | To display models inside notebooks additional steps are required, as displaying of models is based on plotly. Check out them there: 24 | - JupyterLab: https://plotly.com/python/getting-started/#jupyterlab-support 25 | - Jupyter Notebooks: https://plotly.com/python/getting-started/#jupyter-notebook-support 26 | 27 | ### Google colab 28 | 29 | To use it in Google colab add this line at the beggining of the notebook: 30 | 31 | ```cmd 32 | !pip install dotbimpy 33 | ``` 34 | 35 | ## Examples 36 | 37 | ### Pyramid example 38 | 39 | ![2022-02-18_16h09_04](https://user-images.githubusercontent.com/47977819/154712470-aa4b5b44-3e23-4306-8a53-46d37494a52d.png) 40 | 41 | ```python 42 | # Mesh properties 43 | coordinates = [ 44 | # Base 45 | 0.0, 0.0, 0.0, 46 | 10.0, 0.0, 0.0, 47 | 10.0, 10.0, 0.0, 48 | 0.0, 10.0, 0.0, 49 | 50 | # Top 51 | 5.0, 5.0, 4.0 52 | ] 53 | 54 | indices = [ 55 | # Base faces 56 | 0, 1, 2, 57 | 0, 2, 3, 58 | 59 | # Side faces 60 | 0, 1, 4, 61 | 1, 2, 4, 62 | 2, 3, 4, 63 | 3, 0, 4 64 | ] 65 | 66 | # Instantiate Mesh object 67 | mesh = Mesh(mesh_id=0, coordinates=coordinates, indices=indices) 68 | 69 | # Element properties 70 | color = Color(r=255, g=255, b=0, a=255) 71 | guid = "76e051c1-1bd7-44fc-8e2e-db2b64055068" 72 | info = {"Name": "Pyramid"} 73 | rotation = Rotation(qx=0, qy=0, qz=0, qw=1.0) 74 | type = "Structure" 75 | vector = Vector(x=0, y=0, z=0) 76 | 77 | # Instantiate Element object 78 | element = Element(mesh_id=0, 79 | vector=vector, 80 | guid=guid, 81 | info=info, 82 | rotation=rotation, 83 | type=type, 84 | color=color) 85 | 86 | # File meta data 87 | file_info = { 88 | "Author": "John Doe", 89 | "Date": "28.09.1999" 90 | } 91 | 92 | # Instantiate and save File object 93 | file = File("1.0.0", meshes=[mesh], elements=[element], info=file_info) 94 | file.save("Pyramid.bim") 95 | ``` 96 | 97 | ### 3 cubes example 98 | 99 | ![Cubes](https://user-images.githubusercontent.com/47977819/154802229-63284101-d12b-45eb-8b4a-ff7b4e8bdfe6.png) 100 | 101 | ```python 102 | from dotbimpy import * 103 | 104 | 105 | coordinates = [ 106 | 0.0, 0.0, 0.0, 107 | 10.0, 0.0, 0.0, 108 | 10.0, 0.0, 20.0, 109 | 0.0, 0.0, 20.0, 110 | 0.0, 30.0, 0.0, 111 | 10.0, 30.0, 0.0, 112 | 10.0, 30.0, 20.0, 113 | 0.0, 30.0, 20.0 114 | ] 115 | 116 | faces_ids = [ 117 | # Front side 118 | 0, 1, 2, 119 | 0, 2, 3, 120 | 121 | # Bottom side 122 | 0, 1, 4, 123 | 1, 4, 5, 124 | 125 | # Left side 126 | 0, 4, 3, 127 | 4, 3, 7, 128 | 129 | # Right side 130 | 1, 2, 5, 131 | 2, 5, 6, 132 | 133 | # Top side 134 | 2, 3, 7, 135 | 2, 6, 7, 136 | 137 | # Back side 138 | 4, 5, 7, 139 | 5, 6, 7 140 | ] 141 | 142 | mesh = Mesh(mesh_id=0, coordinates=coordinates, indices=faces_ids) 143 | 144 | red_cube = Element(mesh_id=0, 145 | color=Color(255, 0, 0, 255), 146 | vector=Vector(x=-100.0, y=-100.0, z=-100.0), 147 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 148 | guid="9f61b565-06a2-4bef-8b72-f37091ab54d6", 149 | info={"Name": "Red Cube"}, 150 | type="Brick") 151 | 152 | green_cube = Element(mesh_id=0, 153 | color=Color(0, 255, 0, 126), 154 | vector=Vector(x=-0.0, y=0.0, z=0.0), 155 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 156 | guid="4d00c967-791a-42a6-a5e8-cf05831bc11d", 157 | info={"Name": "Green Cube"}, 158 | type="Brick") 159 | 160 | blue_cube = Element(mesh_id=0, 161 | color=Color(0, 0, 255, 10), 162 | vector=Vector(x=100.0, y=100.0, z=100.0), 163 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 164 | guid="8501a5e3-4709-47d8-bd5d-33d745a435d5", 165 | info={"Name": "Blue Cube"}, 166 | type="Brick") 167 | 168 | file_info = {"Author": "John Doe"} 169 | 170 | file = File(schema_version="1.0.0", 171 | meshes=[mesh], 172 | elements=[red_cube, green_cube, blue_cube], 173 | info=file_info) 174 | 175 | file.save("Cubes.bim") 176 | ``` 177 | 178 | ### Read file 179 | 180 | ```python 181 | read_file = File.read("Pyramid.bim") 182 | ``` 183 | 184 | And then you can get all of the properties from it: 185 | 186 | ```python 187 | version = read_file.schema_version 188 | ``` 189 | 190 | ### View file 191 | 192 | #### Default 193 | 194 | If you want to view your file: 195 | 196 | ```python 197 | file.view() 198 | ``` 199 | ![2022-02-23_23h49_52](https://user-images.githubusercontent.com/47977819/155422920-9f0a9aa0-d3d6-442b-a0b0-084acb7e0ea7.png) 200 | 201 | #### Customize 202 | 203 | You can customize the plot that represents the .bim file. You can do it by using: 204 | 205 | ```python 206 | figure = file.create_plotly_figure() 207 | ``` 208 | 209 | Then you get plotly's figure, which can be edited. E.g. 210 | 211 | - adding text tag: 212 | 213 | ![2022-04-22_22h26_02](https://user-images.githubusercontent.com/47977819/164789418-fa632494-d0dd-4ad3-88de-7e4d14a2d8b3.png) 214 | 215 | ```python 216 | from dotbimpy import * 217 | 218 | bim_file = File.read(r"Teapot.bim") 219 | figure = bim_file.create_plotly_figure() 220 | 221 | figure.update_layout( 222 | scene=dict( 223 | annotations=[ 224 | dict( 225 | showarrow=False, 226 | x=0, 227 | y=0, 228 | z=1.5, 229 | text="My Teapot!" 230 | )] 231 | ), 232 | ) 233 | 234 | figure.show() 235 | ``` 236 | 237 | - combining model view with charts: 238 | 239 | ![image](https://user-images.githubusercontent.com/47977819/166078209-f2d381cd-00db-45a6-8539-23fc9ace32c4.png) 240 | 241 | ### Merge files 242 | 243 | If you want to merge two files together: 244 | 245 | ```python 246 | merged_file = file_a + file_b 247 | ``` 248 | 249 | ### dotbimpy + trimesh 250 | 251 | There is a wonderful library called trimesh: https://github.com/mikedh/trimesh, that has a lot of features regarding meshes. Because .bim files relies on meshes only, therefore you can find this library really helpful for many tasks related dotbim, like: 252 | 253 | - converting dotbim's geometries from and to different file formats 254 | - faster preview of .bim files: https://trimsh.org/trimesh.scene.html 255 | - clash detection: https://trimsh.org/trimesh.collision.html?highlight=collision#module-trimesh.collision 256 | ![2022-04-07_23h32_50](https://user-images.githubusercontent.com/47977819/162323603-8d722656-dda9-4c7a-add9-b10142223b1d.png) 257 | - convertion of .bim files to single separate .html file with the 3d model: https://trimsh.org/trimesh.viewer.html#trimesh.viewer.scene_to_html 258 | ![2022-04-13_19h35_29](https://user-images.githubusercontent.com/47977819/163238086-a866206b-3a76-4be9-b0d0-3930a380fd52.png) 259 | 260 | Example notebook: https://github.com/paireks/dotbimpy/blob/master/dotbimpy/other/DotbimToTrimeshScene.ipynb 261 | 262 | ### dotbimpy + cadquery 263 | 264 | Sometimes it's much easier to create B-REP and then convert it into mesh. For this purpose you can try cadquery: https://github.com/CadQuery/cadquery 265 | 266 | Example notebook 1: https://github.com/paireks/dotbimpy/blob/master/dotbimpy/other/WallsWithBeams.ipynb 267 | 268 | ![2022-03-14_00h07_13](https://user-images.githubusercontent.com/47977819/158083248-5d2fb3c8-bf0f-439f-ae74-95035bc5cbff.png) 269 | 270 | Example notebook 2: https://github.com/paireks/dotbimpy/blob/master/dotbimpy/other/Truss.ipynb 271 | 272 | ![2022-03-20_13h18_47](https://user-images.githubusercontent.com/47977819/159161776-a752df76-cd83-4bef-9404-8961f1043003.png) 273 | 274 | ## Libraries used 275 | 276 | - For json serialization it uses jsonpickle: [Repo](https://github.com/jsonpickle/jsonpickle) [License](https://github.com/jsonpickle/jsonpickle/blob/main/LICENSE) 277 | - For math is uses numpy: [Repo](https://github.com/numpy/numpy) [License](https://github.com/numpy/numpy/blob/main/LICENSE.txt) 278 | - For quaternions it uses pyquaternion: [Repo](https://github.com/KieranWynn/pyquaternion) [License](https://github.com/KieranWynn/pyquaternion/blob/master/LICENSE.txt) 279 | - For plotting it uses plotly: [Repo](https://github.com/plotly/plotly.py) [License](https://github.com/plotly/plotly.py/blob/master/LICENSE.txt) 280 | -------------------------------------------------------------------------------- /dotbimpy/__init__.py: -------------------------------------------------------------------------------- 1 | from dotbimpy.file import * 2 | -------------------------------------------------------------------------------- /dotbimpy/file.py: -------------------------------------------------------------------------------- 1 | import jsonpickle 2 | import json 3 | import plotly.graph_objects as go 4 | import pyquaternion 5 | import numpy as np 6 | import copy 7 | 8 | 9 | class File: 10 | def __init__(self, schema_version, meshes, elements, info): 11 | self.schema_version = schema_version 12 | self.meshes = meshes 13 | self.elements = elements 14 | self.info = info 15 | 16 | def __eq__(self, other): 17 | if not isinstance(other, File): 18 | return NotImplemented 19 | 20 | return self.schema_version == other.schema_version \ 21 | and self.meshes == other.meshes \ 22 | and self.elements == other.elements \ 23 | and self.info == other.info 24 | 25 | def __add__(self, other): 26 | if not isinstance(other, File): 27 | return NotImplemented 28 | 29 | new_meshes = [] 30 | new_elements = [] 31 | new_schema_version = self.schema_version 32 | new_file_info = self.info.copy() 33 | 34 | max_mesh_id = 0 35 | for i in self.meshes: 36 | if max_mesh_id < i.mesh_id: 37 | max_mesh_id = i.mesh_id 38 | new_meshes.append(copy.deepcopy(i)) 39 | 40 | for i in self.elements: 41 | new_elements.append(copy.deepcopy(i)) 42 | 43 | for i in other.meshes: 44 | new_id = i.mesh_id + max_mesh_id + 1 45 | new_meshes.append(Mesh(new_id, i.coordinates.copy(), i.indices.copy())) 46 | 47 | for i in other.elements: 48 | new_id = i.mesh_id + max_mesh_id + 1 49 | new_element = Element(mesh_id=new_id, 50 | color=copy.deepcopy(i.color), 51 | rotation=copy.deepcopy(i.rotation), 52 | vector=copy.deepcopy(i.vector), 53 | info=i.info.copy(), 54 | type=i.type, 55 | guid=i.guid) 56 | if i.check_if_has_face_colors(): 57 | new_element.face_colors = copy.deepcopy(i.face_colors) 58 | new_elements.append(new_element) 59 | 60 | return File(schema_version=new_schema_version, 61 | info=new_file_info, 62 | meshes=new_meshes, 63 | elements=new_elements) 64 | 65 | def save(self, path): 66 | if path[-4:] != ".bim": 67 | raise Exception("Path should end up with .bim extension") 68 | 69 | with open(path, "w") as bim_file: 70 | bim_file.write(jsonpickle.encode(self, indent=4, unpicklable=False)) 71 | 72 | def view(self): 73 | figure = self.create_plotly_figure() 74 | figure.show() 75 | 76 | def create_plotly_figure(self): 77 | geometries = [] 78 | for i in self.elements: 79 | mesh = next((x for x in self.meshes if x.mesh_id == i.mesh_id), None) 80 | geometries.extend(mesh.convert_to_plotly_meshes_with_face_colors(element=i)) 81 | 82 | layout = go.Layout(scene=dict(aspectmode='data')) 83 | figure = go.Figure(data=[], layout=layout) 84 | for i in geometries: 85 | figure.add_trace(i) 86 | 87 | return figure 88 | 89 | @staticmethod 90 | def read(path): 91 | if path[-4:] != ".bim": 92 | raise Exception("Path should end up with .bim extension") 93 | 94 | with open(path, "r") as bim_file: 95 | json_dictionary = json.loads(bim_file.read()) 96 | file = File.__convert_JSON_to_file(json_dictionary) 97 | 98 | return file 99 | 100 | @staticmethod 101 | def __convert_JSON_to_file(json_dictionary): 102 | 103 | schema_version = json_dictionary["schema_version"] 104 | elements = json_dictionary["elements"] 105 | meshes = json_dictionary["meshes"] 106 | created_info = json_dictionary["info"] 107 | 108 | created_meshes = [] 109 | for i in meshes: 110 | created_meshes.append(Mesh( 111 | mesh_id=i["mesh_id"], 112 | coordinates=i["coordinates"], 113 | indices=i["indices"] 114 | )) 115 | 116 | created_elements = [] 117 | for i in elements: 118 | new_element = Element( 119 | mesh_id=i["mesh_id"], 120 | vector=Vector(x=i["vector"]["x"], 121 | y=i["vector"]["y"], 122 | z=i["vector"]["z"]), 123 | rotation=Rotation(qx=i["rotation"]["qx"], 124 | qy=i["rotation"]["qy"], 125 | qz=i["rotation"]["qz"], 126 | qw=i["rotation"]["qw"]), 127 | info=i["info"], 128 | color=Color(r=i["color"]["r"], 129 | g=i["color"]["g"], 130 | b=i["color"]["b"], 131 | a=i["color"]["a"]), 132 | type=i["type"], 133 | guid=i["guid"] 134 | ) 135 | try: 136 | new_element.face_colors = i["face_colors"] 137 | except KeyError as e: 138 | if str(e) == "'face_colors'": 139 | pass 140 | else: 141 | raise 142 | created_elements.append(new_element) 143 | 144 | file = File(schema_version=schema_version, meshes=created_meshes, elements=created_elements, info=created_info) 145 | 146 | return file 147 | 148 | 149 | class Element: 150 | def __init__(self, mesh_id, vector, rotation, guid, type, color, info, face_colors=None): 151 | self.info = info 152 | self.color = color 153 | self.guid = guid 154 | self.rotation = rotation 155 | self.vector = vector 156 | self.type = type 157 | self.mesh_id = mesh_id 158 | if face_colors is not None: 159 | self.face_colors = face_colors 160 | 161 | def __eq__(self, other): 162 | if not isinstance(other, Element): 163 | return NotImplemented 164 | 165 | return self.info == other.info \ 166 | and self.color == other.color \ 167 | and self.guid == other.guid \ 168 | and self.rotation == other.rotation \ 169 | and self.vector == other.vector \ 170 | and self.type == other.type \ 171 | and self.mesh_id == other.mesh_id \ 172 | and Element.__check_if_both_elements_have_the_same_face_colors(self, other) 173 | 174 | def equals_without_mesh_id(self, other): 175 | if not isinstance(other, Element): 176 | return NotImplemented 177 | 178 | return self.info == other.info \ 179 | and self.color == other.color \ 180 | and self.guid == other.guid \ 181 | and self.rotation == other.rotation \ 182 | and self.vector == other.vector \ 183 | and self.type == other.type \ 184 | and Element.__check_if_both_elements_have_the_same_face_colors(self, other) 185 | 186 | def check_if_has_face_colors(self): 187 | try: 188 | self.face_colors 189 | except AttributeError as e: 190 | if str(e) == "'Element' object has no attribute 'face_colors'": 191 | return False 192 | else: 193 | raise 194 | return True 195 | 196 | @staticmethod 197 | def __check_if_both_elements_have_the_same_face_colors(first_element, second_element): 198 | if first_element.check_if_has_face_colors() and second_element.check_if_has_face_colors(): 199 | return first_element.face_colors == second_element.face_colors 200 | if not first_element.check_if_has_face_colors() and not second_element.check_if_has_face_colors(): 201 | return True 202 | else: 203 | return False 204 | 205 | 206 | class Color: 207 | def __init__(self, r, g, b, a): 208 | self.r = r 209 | self.g = g 210 | self.b = b 211 | self.a = a 212 | 213 | def __eq__(self, other): 214 | if not isinstance(other, Color): 215 | return NotImplemented 216 | 217 | return self.r == other.r and self.g == other.g and self.b == other.b and self.a == other.a 218 | 219 | 220 | class Mesh: 221 | def __init__(self, mesh_id, coordinates, indices): 222 | self.mesh_id = mesh_id 223 | self.coordinates = coordinates 224 | self.indices = indices 225 | 226 | def __eq__(self, other): 227 | if not isinstance(other, Mesh): 228 | return NotImplemented 229 | 230 | return self.mesh_id == other.mesh_id and self.coordinates == other.coordinates and self.indices == other.indices 231 | 232 | def equals_without_mesh_id(self, other): 233 | if not isinstance(other, Mesh): 234 | return NotImplemented 235 | 236 | return self.coordinates == other.coordinates and self.indices == other.indices 237 | 238 | def __convert_to_plotly(self, element): 239 | color_hex = '#%02x%02x%02x' % (element.color.r, element.color.g, element.color.b) 240 | opacity = element.color.a / 255 241 | 242 | x, y, z = self.__repack_mesh_vertices_to_xyz_lists(element) 243 | i, j, k = self.__repack_mesh_indices_to_ijk_lists() 244 | 245 | return go.Mesh3d(x=x, y=y, z=z, i=i, j=j, k=k, color=color_hex, opacity=opacity, name=element.type, 246 | showscale=True) 247 | 248 | def convert_to_plotly_meshes_with_face_colors(self, element): 249 | if not Element.check_if_has_face_colors(element): 250 | return [self.__convert_to_plotly(element)] 251 | else: 252 | plotly_meshes = [] 253 | face_colors_counter = 0 254 | indices_counter = 0 255 | while face_colors_counter < len(element.face_colors): 256 | color_hex = '#%02x%02x%02x' % (element.face_colors[face_colors_counter], 257 | element.face_colors[face_colors_counter + 1], 258 | element.face_colors[face_colors_counter + 2]) 259 | opacity = element.face_colors[face_colors_counter + 3] / 255 260 | 261 | i = [self.indices[indices_counter]] 262 | j = [self.indices[indices_counter + 1]] 263 | k = [self.indices[indices_counter + 2]] 264 | x, y, z = self.__repack_mesh_vertices_to_xyz_lists(element) 265 | 266 | plotly_meshes.append(go.Mesh3d(x=x, y=y, z=z, i=i, j=j, k=k, color=color_hex, opacity=opacity, 267 | name=element.type, showscale=True)) 268 | 269 | face_colors_counter += 4 270 | indices_counter += 3 271 | 272 | return plotly_meshes 273 | 274 | def __repack_mesh_indices_to_ijk_lists(self): 275 | i = [] 276 | j = [] 277 | k = [] 278 | counter = 0 279 | while counter < len(self.indices): 280 | i.append(self.indices[counter]) 281 | j.append(self.indices[counter + 1]) 282 | k.append(self.indices[counter + 2]) 283 | counter += 3 284 | 285 | return i, j, k 286 | 287 | def __repack_mesh_vertices_to_xyz_lists(self, element): 288 | 289 | x = [] 290 | y = [] 291 | z = [] 292 | counter = 0 293 | while counter < len(self.coordinates): 294 | point = np.array([ 295 | self.coordinates[counter], 296 | self.coordinates[counter + 1], 297 | self.coordinates[counter + 2]]) 298 | 299 | rotation = pyquaternion.Quaternion( 300 | a=element.rotation.qw, 301 | b=element.rotation.qx, 302 | c=element.rotation.qy, 303 | d=element.rotation.qz) 304 | 305 | point_rotated = rotation.rotate(point) 306 | 307 | x.append(point_rotated[0] + element.vector.x) 308 | y.append(point_rotated[1] + element.vector.y) 309 | z.append(point_rotated[2] + element.vector.z) 310 | counter += 3 311 | 312 | return x, y, z 313 | 314 | 315 | class Rotation: 316 | def __init__(self, qx, qy, qz, qw): 317 | self.qx = qx 318 | self.qy = qy 319 | self.qz = qz 320 | self.qw = qw 321 | 322 | def __eq__(self, other): 323 | if not isinstance(other, Rotation): 324 | return NotImplemented 325 | 326 | return self.qx == other.qx and self.qy == other.qy and self.qz == other.qz and self.qw == other.qw 327 | 328 | 329 | class Vector: 330 | def __init__(self, x, y, z): 331 | self.x = x 332 | self.y = y 333 | self.z = z 334 | 335 | def __eq__(self, other): 336 | if not isinstance(other, Vector): 337 | return NotImplemented 338 | 339 | return self.x == other.x and self.y == other.y and self.z == other.z 340 | -------------------------------------------------------------------------------- /dotbimpy/other/DotbimToTrimeshScene.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "d27419f9", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "from dotbimpy import *\n", 11 | "import trimesh\n", 12 | "\n", 13 | "# Warning: trimesh currently has some problems with face_colors. Check manually if conversion was done correctly.\n", 14 | "\n", 15 | "def divide_to_chunks(list_to_divide, chunk_size):\n", 16 | " for i in range(0, len(list_to_divide), chunk_size):\n", 17 | " yield list_to_divide[i:i + chunk_size]\n", 18 | "\n", 19 | "def convert_dotbim_mesh_to_trimesh(mesh_to_convert, element):\n", 20 | " faces = list(divide_to_chunks(mesh_to_convert.indices, 3))\n", 21 | "\n", 22 | " vertices = []\n", 23 | " counter = 0\n", 24 | " while counter < len(mesh_to_convert.coordinates):\n", 25 | " point = np.array([\n", 26 | " mesh_to_convert.coordinates[counter],\n", 27 | " mesh_to_convert.coordinates[counter + 1],\n", 28 | " mesh_to_convert.coordinates[counter + 2]])\n", 29 | "\n", 30 | " rotation = pyquaternion.Quaternion(\n", 31 | " a=element.rotation.qw,\n", 32 | " b=element.rotation.qx,\n", 33 | " c=element.rotation.qy,\n", 34 | " d=element.rotation.qz)\n", 35 | " \n", 36 | " point_rotated = rotation.rotate(point)\n", 37 | " vertices.append([point_rotated[0] + element.vector.x, point_rotated[1] + element.vector.y, point_rotated[2] + element.vector.z])\n", 38 | " counter += 3\n", 39 | "\n", 40 | " mesh = trimesh.Trimesh(vertices=vertices, faces=faces)\n", 41 | " dotbim_face_colors = []\n", 42 | " if element.check_if_has_face_colors():\n", 43 | " i = 0\n", 44 | " while i < len(element.face_colors):\n", 45 | " current_list = [element.face_colors[i], element.face_colors[i+1], element.face_colors[i+2], element.face_colors[i+3]]\n", 46 | " dotbim_face_colors.append(current_list)\n", 47 | " i+=4\n", 48 | " else:\n", 49 | " dotbim_face_colors = [element.color.r, element.color.g, element.color.b, element.color.a]\n", 50 | "\n", 51 | " mesh.visual.face_colors = dotbim_face_colors\n", 52 | " mesh.visual.kind == 'face'\n", 53 | "\n", 54 | " return mesh\n", 55 | "\n", 56 | "def convert_file_to_trimesh_scene(file):\n", 57 | " scene = trimesh.scene.Scene()\n", 58 | " for i in file.elements:\n", 59 | " mesh = next((x for x in file.meshes if x.mesh_id == i.mesh_id), None)\n", 60 | " trimesh_mesh = convert_dotbim_mesh_to_trimesh(mesh_to_convert=mesh, element=i)\n", 61 | " scene.add_geometry(trimesh_mesh)\n", 62 | " \n", 63 | " return scene" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "id": "f6e72805", 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "file = File.read(\"MulticolorHouse.bim\")\n", 74 | "scene = convert_file_to_trimesh_scene(file)\n", 75 | "scene.show(smooth=False)" 76 | ] 77 | } 78 | ], 79 | "metadata": { 80 | "kernelspec": { 81 | "display_name": "Python 3 (ipykernel)", 82 | "language": "python", 83 | "name": "python3" 84 | }, 85 | "language_info": { 86 | "codemirror_mode": { 87 | "name": "ipython", 88 | "version": 3 89 | }, 90 | "file_extension": ".py", 91 | "mimetype": "text/x-python", 92 | "name": "python", 93 | "nbconvert_exporter": "python", 94 | "pygments_lexer": "ipython3", 95 | "version": "3.7.11" 96 | } 97 | }, 98 | "nbformat": 4, 99 | "nbformat_minor": 5 100 | } 101 | -------------------------------------------------------------------------------- /dotbimpy/other/Truss.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "9d95439c-243c-46b9-981e-c1ebb4b358b8", 6 | "metadata": {}, 7 | "source": [ 8 | "# Cadquery + ipywidget + dotbimpy" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "00596700-6ddc-4bf0-b437-325cc942bd3a", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "from dotbimpy import *\n", 19 | "from ipywidgets import interact\n", 20 | "import cadquery\n", 21 | "import uuid" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "id": "ce601b01-9982-4e1e-a055-003b9f5129c1", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "def cadquery_mesh_to_dotbim_mesh(cadquery_mesh, mesh_id):\n", 32 | " vertices, triangles = cadquery_mesh\n", 33 | " coordinates = []\n", 34 | " for i in vertices:\n", 35 | " coordinates.extend([i.x, i.y, i.z])\n", 36 | " indices = [item for sublist in triangles for item in sublist]\n", 37 | " return Mesh(mesh_id=mesh_id, coordinates=coordinates, indices=indices)" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 3, 43 | "id": "0db56e56-dde0-4abb-8339-1f93ffa7abc4", 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "def create_mesh_tube(plane, face, l, h, t, mesh_id):\n", 48 | " workplane = cadquery.Workplane(plane).circle(h).extrude(l).faces(face).workplane().circle(h-t).cutThruAll()\n", 49 | " mesh_cq = workplane.val().tessellate(0.1)\n", 50 | " mesh = cadquery_mesh_to_dotbim_mesh(mesh_cq, mesh_id)\n", 51 | " return mesh\n", 52 | "\n", 53 | "def create_tube_element(vector, rotation, color, mesh_id, type_name):\n", 54 | " return Element(mesh_id=mesh_id,vector=vector,guid=str(uuid.uuid4()),\n", 55 | " info={\"Material\": \"Steel\"},rotation=rotation,type=type_name,color=color)" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 10, 61 | "id": "bc39f142-8f1f-4d65-9d01-6fda00b1aebc", 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "def f(length):\n", 66 | " meshes = []\n", 67 | " elements = []\n", 68 | " \n", 69 | " # Creating chords\n", 70 | " meshes.append(create_mesh_tube('YZ', '>X', length, 0.03, 0.01, 0))\n", 71 | " elements.append(create_tube_element(Vector(0,0.25,0.25), Rotation(0,0,0,1), Color(0,0,255,255), 0, \"Top Chord\"))\n", 72 | " elements.append(create_tube_element(Vector(0,-0.25,0.25), Rotation(0,0,0,1), Color(0,0,255,255), 0, \"Top Chord\"))\n", 73 | " elements.append(create_tube_element(Vector(0,0.25,-0.25), Rotation(0,0,0,1), Color(0,0,255,255), 0, \"Bottom Chord\"))\n", 74 | " elements.append(create_tube_element(Vector(0,-0.25,-0.25), Rotation(0,0,0,1), Color(0,0,255,255), 0, \"Bottom Chord\"))\n", 75 | " \n", 76 | " # Creating posts\n", 77 | " meshes.append(create_mesh_tube('XY', '>Z', 0.46, 0.02, 0.005, 1))\n", 78 | " elements.append(create_tube_element(Vector(0.25,0.25,-0.23), Rotation(0,0,0,1), Color(0,255,0,255), 1, \"Post\"))\n", 79 | " elements.append(create_tube_element(Vector(0.25,-0.25,-0.23), Rotation(0,0,0,1), Color(0,255,0,255), 1, \"Post\"))\n", 80 | " elements.append(create_tube_element(Vector(length-0.25,0.25,-0.23), Rotation(0,0,0,1), Color(0,255,0,255), 1, \"Post\"))\n", 81 | " elements.append(create_tube_element(Vector(length-0.25,-0.25,-0.23), Rotation(0,0,0,1), Color(0,255,0,255), 1, \"Post\"))\n", 82 | " \n", 83 | " # Creating girder\n", 84 | " meshes.append(create_mesh_tube('XZ', '>Y', 0.46, 0.02, 0.005, 2))\n", 85 | " elements.append(create_tube_element(Vector(0.25,0.23,0.25), Rotation(0,0,0,1), Color(222,49,99,255), 2, \"Girder\"))\n", 86 | " elements.append(create_tube_element(Vector(0.25,0.23,-0.25), Rotation(0,0,0,1), Color(222,49,99,255), 2, \"Girder\"))\n", 87 | " elements.append(create_tube_element(Vector(length-0.25,0.23,0.25), Rotation(0,0,0,1), Color(222,49,99,255), 2, \"Girder\"))\n", 88 | " elements.append(create_tube_element(Vector(length-0.25,0.23,-0.25), Rotation(0,0,0,1), Color(222,49,99,255), 2, \"Girder\"))\n", 89 | " \n", 90 | " # Creating webs\n", 91 | " length_to_fill = length - 0.5\n", 92 | " number_of_gaps = int(length_to_fill / 0.5)\n", 93 | " meshes.append(create_mesh_tube('YZ', '>X', 1.41421*0.5, 0.015, 0.005, 3))\n", 94 | " for i in range(number_of_gaps):\n", 95 | " if i % 2 == 0:\n", 96 | " elements.append(create_tube_element(Vector(i*0.5+0.25,0.25,0.5/2.0), Rotation(0,0.382683,0,0.92388), Color(255,165,0,255), 3, \"Web\"))\n", 97 | " elements.append(create_tube_element(Vector(i*0.5+0.25,-0.25,-0.5/2.0), Rotation(0,-0.382683,0,0.92388), Color(255,165,0,255), 3, \"Web\"))\n", 98 | " elements.append(create_tube_element(Vector(i*0.5+0.25,0.25,0.5/2.0), Rotation(0,0,-0.382683,0.92388), Color(255,165,0,255), 3, \"Web\"))\n", 99 | " elements.append(create_tube_element(Vector(i*0.5+0.25,-0.25,-0.5/2.0), Rotation(0,0,0.382683,0.92388), Color(255,165,0,255), 3, \"Web\"))\n", 100 | " else:\n", 101 | " elements.append(create_tube_element(Vector(i*0.5+0.25,0.25,-0.5/2.0), Rotation(0,-0.382683,0,0.92388), Color(255,165,0,255), 3, \"Web\"))\n", 102 | " elements.append(create_tube_element(Vector(i*0.5+0.25,-0.25,0.5/2.0), Rotation(0,0.382683,0,0.92388), Color(255,165,0,255), 3, \"Web\"))\n", 103 | " elements.append(create_tube_element(Vector(i*0.5+0.25,-0.25,0.5/2.0), Rotation(0,0,0.382683,0.92388), Color(255,165,0,255), 3, \"Web\"))\n", 104 | " elements.append(create_tube_element(Vector(i*0.5+0.25,0.25,-0.5/2.0), Rotation(0,0,-0.382683,0.92388), Color(255,165,0,255), 3, \"Web\"))\n", 105 | " \n", 106 | " # Creating webs on ends\n", 107 | " meshes.append(create_mesh_tube('XZ', '>Y', 1.41421*0.5, 0.015, 0.005, 4))\n", 108 | " elements.append(create_tube_element(Vector(0.25,0.25,0.5/2.0), Rotation(0.382683,0,0,0.92388), Color(255,105,180,255), 4, \"Web\"))\n", 109 | " elements.append(create_tube_element(Vector(length-0.25,0.25,-0.5/2.0), Rotation(-0.382683,0,0,0.92388), Color(255,105,180,255), 4, \"Web\"))\n", 110 | " \n", 111 | " file = File(\"1.0.0\", meshes=meshes, elements=elements, info={\"Author\": \"John Doe\"})\n", 112 | " file.view()\n", 113 | " file.save(\"Truss.bim\")" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 12, 119 | "id": "04180879-ccdb-490d-a297-a62e304a5bf2", 120 | "metadata": { 121 | "tags": [] 122 | }, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "application/vnd.jupyter.widget-view+json": { 127 | "model_id": "bc9cebdf52454b6ba0cb0f7099b7d8c3", 128 | "version_major": 2, 129 | "version_minor": 0 130 | }, 131 | "text/plain": [ 132 | "interactive(children=(FloatSlider(value=6.0, description='length', max=10.0, min=2.0, step=1.0), Output()), _d…" 133 | ] 134 | }, 135 | "metadata": {}, 136 | "output_type": "display_data" 137 | }, 138 | { 139 | "data": { 140 | "text/plain": [ 141 | "" 142 | ] 143 | }, 144 | "execution_count": 12, 145 | "metadata": {}, 146 | "output_type": "execute_result" 147 | } 148 | ], 149 | "source": [ 150 | "interact(f, length=(2.0, 10.0, 1.00))" 151 | ] 152 | } 153 | ], 154 | "metadata": { 155 | "kernelspec": { 156 | "display_name": "Anaconda (base)", 157 | "language": "python", 158 | "name": "anaconda-base" 159 | }, 160 | "language_info": { 161 | "codemirror_mode": { 162 | "name": "ipython", 163 | "version": 3 164 | }, 165 | "file_extension": ".py", 166 | "mimetype": "text/x-python", 167 | "name": "python", 168 | "nbconvert_exporter": "python", 169 | "pygments_lexer": "ipython3", 170 | "version": "3.7.11" 171 | } 172 | }, 173 | "nbformat": 4, 174 | "nbformat_minor": 5 175 | } 176 | -------------------------------------------------------------------------------- /dotbimpy/other/WallsWithBeams.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "12f1c758-795e-4d5c-a490-de0b4397a318", 6 | "metadata": {}, 7 | "source": [ 8 | "# Cadquery + dotbimpy example" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "id": "d024fc2a-eb3f-45ab-8ba9-abb2e164b968", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "from dotbimpy import *\n", 19 | "import cadquery\n", 20 | "import uuid" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "9bcf4d8e-d5d8-46b7-b598-c026cf91e08d", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "def cadquery_mesh_to_dotbim_mesh(cadquery_mesh, mesh_id):\n", 31 | " vertices, triangles = cadquery_mesh\n", 32 | " coordinates = []\n", 33 | " for i in vertices:\n", 34 | " coordinates.extend([i.x, i.y, i.z])\n", 35 | " indices = [item for sublist in triangles for item in sublist]\n", 36 | " return Mesh(mesh_id=mesh_id, coordinates=coordinates, indices=indices)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "id": "44d911a0-b4eb-49b4-8d71-7980f6b51b86", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "meshes = []\n", 47 | "elements = []\n", 48 | "\n", 49 | "(L,H,W,t) = (6.000, 0.300, 0.200, 0.010)\n", 50 | "pts = [(0,H/2.0),(W/2.0,H/2.0),(W/2.0,(H/2.0 - t)),(t/2.0,(H/2.0-t)),(t/2.0,(t - H/2.0)),(W/2.0,(t -H/2.0)),(W/2.0,H/-2.0),(0,H/-2.0)]\n", 51 | "beam_workplane = cadquery.Workplane(\"XZ\").polyline(pts).mirrorY().extrude(L)\n", 52 | "beam_mesh_cq = beam_workplane.val().tessellate(0.1)\n", 53 | "meshes.append(cadquery_mesh_to_dotbim_mesh(beam_mesh_cq, 0))\n", 54 | "\n", 55 | "(number_of_beams,spacing,wall_height) = (5,2.000,3.000)\n", 56 | "for i in range(number_of_beams):\n", 57 | " elements.append(Element(mesh_id=0,\n", 58 | " vector=Vector(x=i*spacing, y=0, z=wall_height+H/2),\n", 59 | " guid=str(uuid.uuid4()),\n", 60 | " info={\"Material\": \"Steel\"},\n", 61 | " rotation=Rotation(qx=0, qy=0, qz=0, qw=1.0),\n", 62 | " type=\"Beam\",\n", 63 | " color=Color(r=0, g=0, b=255, a=255)))\n", 64 | "\n", 65 | "wall_workplane = cadquery.Workplane(\"front\").moveTo((spacing*(number_of_beams-1))/2.0,0).box(spacing*(number_of_beams-1)+W, 0.200, wall_height)\n", 66 | "wall_mesh_cq = wall_workplane.val().tessellate(0.1)\n", 67 | "meshes.append(cadquery_mesh_to_dotbim_mesh(wall_mesh_cq, 1))\n", 68 | "\n", 69 | "for i in range(2):\n", 70 | " elements.append(Element(mesh_id=1,\n", 71 | " vector=Vector(x=0, y=-i*L, z=wall_height/2.0),\n", 72 | " guid=str(uuid.uuid4()),\n", 73 | " info={\"Material\": \"Concrete\"},\n", 74 | " rotation=Rotation(qx=0, qy=0, qz=0, qw=1.0),\n", 75 | " type=\"Wall\",\n", 76 | " color=Color(r=255, g=215, b=0, a=255)))\n", 77 | "\n", 78 | "\n", 79 | "file_info = {\"Author\": \"John Doe\"}\n", 80 | "file = File(\"1.0.0\", meshes=meshes, elements=elements, info=file_info)\n", 81 | "file.view()\n", 82 | "file.save(\"WallsWithBeams.bim\")" 83 | ] 84 | } 85 | ], 86 | "metadata": { 87 | "kernelspec": { 88 | "display_name": "Anaconda (base)", 89 | "language": "python", 90 | "name": "anaconda-base" 91 | }, 92 | "language_info": { 93 | "codemirror_mode": { 94 | "name": "ipython", 95 | "version": 3 96 | }, 97 | "file_extension": ".py", 98 | "mimetype": "text/x-python", 99 | "name": "python", 100 | "nbconvert_exporter": "python", 101 | "pygments_lexer": "ipython3", 102 | "version": "3.7.11" 103 | } 104 | }, 105 | "nbformat": 4, 106 | "nbformat_minor": 5 107 | } 108 | -------------------------------------------------------------------------------- /dotbimpy/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paireks/dotbimpy/2a8bdf9abb23421bbf2892e1fdb48ef4ebb5f0d4/dotbimpy/tests/__init__.py -------------------------------------------------------------------------------- /dotbimpy/tests/test_helper.py: -------------------------------------------------------------------------------- 1 | from dotbimpy import * 2 | 3 | 4 | def create_pyramid_mesh(): 5 | coordinates = [ 6 | # Base 7 | 0.0, 0.0, 0.0, 8 | 10.0, 0.0, 0.0, 9 | 10.0, 10.0, 0.0, 10 | 0.0, 10.0, 0.0, 11 | 12 | # Top 13 | 5.0, 5.0, 4.0 14 | ] 15 | 16 | indices = [ 17 | # Base faces 18 | 0, 1, 2, 19 | 0, 2, 3, 20 | 21 | # Side faces 22 | 0, 1, 4, 23 | 1, 2, 4, 24 | 2, 3, 4, 25 | 3, 0, 4 26 | ] 27 | 28 | return Mesh(mesh_id=0, coordinates=coordinates, indices=indices) 29 | 30 | 31 | def create_cube_mesh(): 32 | coordinates = [ 33 | 0.0, 0.0, 0.0, 34 | 10.0, 0.0, 0.0, 35 | 10.0, 0.0, 20.0, 36 | 0.0, 0.0, 20.0, 37 | 0.0, 30.0, 0.0, 38 | 10.0, 30.0, 0.0, 39 | 10.0, 30.0, 20.0, 40 | 0.0, 30.0, 20.0 41 | ] 42 | 43 | faces_ids = [ 44 | # Front side 45 | 0, 1, 2, 46 | 0, 2, 3, 47 | 48 | # Bottom side 49 | 0, 1, 4, 50 | 1, 4, 5, 51 | 52 | # Left side 53 | 0, 4, 3, 54 | 4, 3, 7, 55 | 56 | # Right side 57 | 1, 2, 5, 58 | 2, 5, 6, 59 | 60 | # Top side 61 | 2, 3, 7, 62 | 2, 6, 7, 63 | 64 | # Back side 65 | 4, 5, 7, 66 | 5, 6, 7 67 | ] 68 | 69 | return Mesh(mesh_id=0, coordinates=coordinates, indices=faces_ids) 70 | 71 | 72 | def create_pyramid_element(): 73 | color = Color(r=255, g=255, b=0, a=255) 74 | guid = "76e051c1-1bd7-44fc-8e2e-db2b64055068" 75 | info = {"Name": "Pyramid"} 76 | rotation = Rotation(qx=0, qy=0, qz=0, qw=1.0) 77 | type = "Structure" 78 | vector = Vector(x=0, y=0, z=0) 79 | return Element(mesh_id=0, 80 | vector=vector, 81 | guid=guid, 82 | info=info, 83 | rotation=rotation, 84 | type=type, 85 | color=color) 86 | 87 | 88 | def create_red_cube_element(): 89 | return Element(mesh_id=0, 90 | color=Color(255, 0, 0, 255), 91 | vector=Vector(x=-100.0, y=-100.0, z=-100.0), 92 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 93 | guid="9f61b565-06a2-4bef-8b72-f37091ab54d6", 94 | info={"Name": "Red Cube"}, 95 | type="Brick") 96 | 97 | 98 | def create_green_cube_element(): 99 | return Element(mesh_id=0, 100 | color=Color(0, 255, 0, 126), 101 | vector=Vector(x=-0.0, y=0.0, z=0.0), 102 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 103 | guid="4d00c967-791a-42a6-a5e8-cf05831bc11d", 104 | info={"Name": "Green Cube"}, 105 | type="Brick") 106 | 107 | 108 | def create_blue_cube_element(): 109 | return Element(mesh_id=0, 110 | color=Color(0, 0, 255, 10), 111 | vector=Vector(x=100.0, y=100.0, z=100.0), 112 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 113 | guid="8501a5e3-4709-47d8-bd5d-33d745a435d5", 114 | info={"Name": "Blue Cube"}, 115 | type="Brick") 116 | 117 | 118 | def create_multicolor_cube_element(): 119 | return Element(mesh_id=0, 120 | color=Color(0, 255, 0, 126), 121 | face_colors=[ 122 | # Front side 123 | 255, 105, 180, 150, # Hot pink with transparency 124 | 255, 192, 203, 255, # Pink 125 | 126 | # Bottom side 127 | 53, 57, 53, 255, # Onyx 128 | 0, 0, 0, 255, # Black 129 | 130 | # Left side 131 | 243, 229, 171, 255, # Vanilla 132 | 255, 255, 0, 255, # Yellow 133 | 134 | # Right side 135 | 9, 121, 105, 255, # Cadmium Green 136 | 0, 128, 0, 255, # Green 137 | 138 | # Top side 139 | 0, 255, 255, 255, # Cyan 140 | 0, 0, 255, 255, # Blue 141 | 142 | # Back side 143 | 226, 223, 210, 255, # Pearl 144 | 255, 255, 255, 255, # White 145 | ], 146 | vector=Vector(x=-0.0, y=0.0, z=0.0), 147 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 148 | guid="4d00c967-791a-42a6-a5e8-cf05831bc11d", 149 | info={"Name": "Multicolor Cube"}, 150 | type="Brick") 151 | 152 | 153 | def create_file_with_pyramid(): 154 | mesh = create_pyramid_mesh() 155 | element = create_pyramid_element() 156 | file_info = { 157 | "Author": "John Doe", 158 | "Date": "28.09.1999" 159 | } 160 | 161 | return File("1.0.0", meshes=[mesh], elements=[element], info=file_info) 162 | 163 | 164 | def create_file_with_cubes(): 165 | mesh = create_cube_mesh() 166 | red_cube = create_red_cube_element() 167 | green_cube = create_green_cube_element() 168 | blue_cube = create_blue_cube_element() 169 | file_info = {"Author": "John Doe"} 170 | 171 | file = File(schema_version="1.0.0", 172 | meshes=[mesh], 173 | elements=[red_cube, green_cube, blue_cube], 174 | info=file_info) 175 | return file 176 | 177 | 178 | def create_file_with_cubes_with_face_colors_and_without(): 179 | mesh = create_cube_mesh() 180 | red_cube = create_red_cube_element() 181 | multicolor_cube = create_multicolor_cube_element() 182 | blue_cube = create_blue_cube_element() 183 | file_info = {"Author": "John Doe"} 184 | 185 | file = File(schema_version="1.1.0", 186 | meshes=[mesh], 187 | elements=[red_cube, multicolor_cube, blue_cube], 188 | info=file_info) 189 | return file 190 | -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paireks/dotbimpy/2a8bdf9abb23421bbf2892e1fdb48ef4ebb5f0d4/dotbimpy/tests/unittests/__init__.py -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_color.py: -------------------------------------------------------------------------------- 1 | from dotbimpy import * 2 | import pytest 3 | 4 | 5 | def test_init(): 6 | color = Color(31, 30, 50, 4) 7 | 8 | assert color.r == 31 9 | assert color.g == 30 10 | assert color.b == 50 11 | assert color.a == 4 12 | 13 | 14 | @pytest.mark.parametrize("r, g, b, a, expected", 15 | [(31, 30, 50, 4, True), 16 | (32, 30, 50, 4, False), 17 | (31, 29, 50, 4, False), 18 | (31, 30, 51, 4, False), 19 | (31, 30, 50, 5, False), 20 | (32, 29, 51, 5, False)]) 21 | def test_eq(r, g, b, a, expected): 22 | original = Color(31, 30, 50, 4) 23 | other = Color(r, g, b, a) 24 | 25 | assert original.__eq__(other) == expected 26 | assert other.__eq__(original) == expected 27 | 28 | 29 | def test_eq_with_other_object(): 30 | original = Color(31, 30, 50, 4) 31 | other = 2 32 | 33 | assert original.__eq__(other) is NotImplemented 34 | -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_element.py: -------------------------------------------------------------------------------- 1 | from dotbimpy import * 2 | import pytest 3 | 4 | 5 | def test_init(): 6 | element = Element(mesh_id=0, 7 | color=Color(31, 30, 50, 4), 8 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 9 | vector=Vector(5, 3, 2), 10 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 11 | -0.750877077691500), 12 | type="Beam", 13 | info={"Name": "Pyramid"}) 14 | 15 | assert element.type == "Beam" 16 | assert element.info == {"Name": "Pyramid"} 17 | assert element.mesh_id == 0 18 | assert element.rotation == Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, -0.750877077691500) 19 | assert element.vector == Vector(5, 3, 2) 20 | assert element.color == Color(31, 30, 50, 4) 21 | assert element.guid == "8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb" 22 | 23 | 24 | def test_init_with_face_colors(): 25 | element = Element(mesh_id=0, 26 | color=Color(31, 30, 50, 4), 27 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 28 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 29 | vector=Vector(5, 3, 2), 30 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 31 | -0.750877077691500), 32 | type="Beam", 33 | info={"Name": "Pyramid"}) 34 | 35 | assert element.type == "Beam" 36 | assert element.info == {"Name": "Pyramid"} 37 | assert element.mesh_id == 0 38 | assert element.rotation == Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, -0.750877077691500) 39 | assert element.vector == Vector(5, 3, 2) 40 | assert element.color == Color(31, 30, 50, 4) 41 | assert element.face_colors == [255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255] 42 | assert element.guid == "8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb" 43 | 44 | 45 | @pytest.mark.parametrize("other, expected", 46 | [(Element(mesh_id=0, 47 | color=Color(31, 30, 50, 4), 48 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 49 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 50 | vector=Vector(5, 3, 2), 51 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 52 | -0.750877077691500), 53 | type="Beam", 54 | info={"Name": "Pyramid"}), True), 55 | (Element(mesh_id=4, 56 | color=Color(31, 30, 50, 4), 57 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 58 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 59 | vector=Vector(5, 3, 2), 60 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 61 | -0.750877077691500), 62 | type="Beam", 63 | info={"Name": "Pyramid"}), False), 64 | (Element(mesh_id=0, 65 | color=Color(31, 30, 51, 4), 66 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 67 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 68 | vector=Vector(5, 3, 2), 69 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 70 | -0.750877077691500), 71 | type="Beam", 72 | info={"Name": "Pyramid"}), False), 73 | (Element(mesh_id=0, 74 | color=Color(31, 30, 50, 4), 75 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 76 | guid="b38c62c9-4bd5-4dea-a408-0bcbd902cb0f", 77 | vector=Vector(5, 3, 2), 78 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 79 | -0.750877077691500), 80 | type="Beam", 81 | info={"Name": "Pyramid"}), False), 82 | (Element(mesh_id=0, 83 | color=Color(31, 30, 50, 4), 84 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 85 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 86 | vector=Vector(1, 3, 2), 87 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 88 | -0.750877077691500), 89 | type="Beam", 90 | info={"Name": "Pyramid"}), False), 91 | (Element(mesh_id=0, 92 | color=Color(31, 30, 50, 4), 93 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 94 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 95 | vector=Vector(5, 3, 2), 96 | rotation=Rotation(0, 0, 0, 1.0), 97 | type="Beam", 98 | info={"Name": "Pyramid"}), False), 99 | (Element(mesh_id=0, 100 | color=Color(31, 30, 50, 4), 101 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 102 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 103 | vector=Vector(5, 3, 2), 104 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 105 | -0.750877077691500), 106 | type="Column", 107 | info={"Name": "Pyramid"}), False), 108 | (Element(mesh_id=0, 109 | color=Color(31, 30, 50, 4), 110 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 111 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 112 | vector=Vector(5, 3, 2), 113 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 114 | -0.750877077691500), 115 | type="Beam", 116 | info={"Name": "Another Pyramid"}), False), 117 | (Element(mesh_id=0, 118 | color=Color(31, 30, 50, 4), 119 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 120 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 121 | vector=Vector(5, 3, 2), 122 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 123 | -0.750877077691500), 124 | type="Beam", 125 | info={"Another name": "Pyramid"}), False), 126 | (Element(mesh_id=0, 127 | color=Color(31, 30, 50, 4), 128 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 129 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 130 | vector=Vector(5, 3, 2), 131 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 132 | -0.750877077691500), 133 | type="Beam", 134 | info={"Name": "Pyramid", "Another name": "Another Pyramid"}), False), 135 | (Element(mesh_id=0, 136 | color=Color(31, 30, 50, 4), 137 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 251], 138 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 139 | vector=Vector(5, 3, 2), 140 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 141 | -0.750877077691500), 142 | type="Beam", 143 | info={"Name": "Pyramid"}), False), 144 | (Element(mesh_id=0, 145 | color=Color(31, 30, 50, 4), 146 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 147 | vector=Vector(5, 3, 2), 148 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 149 | -0.750877077691500), 150 | type="Beam", 151 | info={"Name": "Pyramid"}), False), 152 | ]) 153 | def test_eq(other, expected): 154 | original = Element(mesh_id=0, 155 | color=Color(31, 30, 50, 4), 156 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 157 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 158 | vector=Vector(5, 3, 2), 159 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 160 | -0.750877077691500), 161 | type="Beam", 162 | info={"Name": "Pyramid"}) 163 | 164 | assert original.__eq__(other) == expected 165 | assert other.__eq__(original) == expected 166 | 167 | 168 | @pytest.mark.parametrize("other, expected", 169 | [(Element(mesh_id=0, 170 | color=Color(31, 30, 50, 4), 171 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 172 | vector=Vector(5, 3, 2), 173 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 174 | -0.750877077691500), 175 | type="Beam", 176 | info={"Name": "Pyramid"}), True), 177 | (Element(mesh_id=0, 178 | color=Color(31, 30, 50, 4), 179 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 180 | vector=Vector(1, 0, 0), 181 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 182 | -0.750877077691500), 183 | type="Beam", 184 | info={"Name": "Pyramid"}), False), 185 | ]) 186 | def test_eq_both_without_face_colors(other, expected): 187 | original = Element(mesh_id=0, 188 | color=Color(31, 30, 50, 4), 189 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 190 | vector=Vector(5, 3, 2), 191 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 192 | -0.750877077691500), 193 | type="Beam", 194 | info={"Name": "Pyramid"}) 195 | 196 | assert original.__eq__(other) == expected 197 | assert other.__eq__(original) == expected 198 | 199 | 200 | def test_eq_with_other_object(): 201 | original = Element(mesh_id=0, 202 | color=Color(31, 30, 50, 4), 203 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 204 | vector=Vector(5, 3, 2), 205 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 206 | -0.750877077691500), 207 | type="Beam", 208 | info={"Name": "Pyramid"}) 209 | other = 2 210 | 211 | assert original.__eq__(other) is NotImplemented 212 | 213 | 214 | @pytest.mark.parametrize("other, expected", 215 | [(Element(mesh_id=0, 216 | color=Color(31, 30, 50, 4), 217 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 218 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 219 | vector=Vector(5, 3, 2), 220 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 221 | -0.750877077691500), 222 | type="Beam", 223 | info={"Name": "Pyramid"}), True), 224 | (Element(mesh_id=4, 225 | color=Color(31, 30, 50, 4), 226 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 227 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 228 | vector=Vector(5, 3, 2), 229 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 230 | -0.750877077691500), 231 | type="Beam", 232 | info={"Name": "Pyramid"}), True), 233 | (Element(mesh_id=0, 234 | color=Color(31, 30, 51, 4), 235 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 236 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 237 | vector=Vector(5, 3, 2), 238 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 239 | -0.750877077691500), 240 | type="Beam", 241 | info={"Name": "Pyramid"}), False), 242 | (Element(mesh_id=0, 243 | color=Color(31, 30, 50, 4), 244 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 245 | guid="b38c62c9-4bd5-4dea-a408-0bcbd902cb0f", 246 | vector=Vector(5, 3, 2), 247 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 248 | -0.750877077691500), 249 | type="Beam", 250 | info={"Name": "Pyramid"}), False), 251 | (Element(mesh_id=0, 252 | color=Color(31, 30, 50, 4), 253 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 254 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 255 | vector=Vector(1, 3, 2), 256 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 257 | -0.750877077691500), 258 | type="Beam", 259 | info={"Name": "Pyramid"}), False), 260 | (Element(mesh_id=0, 261 | color=Color(31, 30, 50, 4), 262 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 263 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 264 | vector=Vector(5, 3, 2), 265 | rotation=Rotation(0, 0, 0, 1.0), 266 | type="Beam", 267 | info={"Name": "Pyramid"}), False), 268 | (Element(mesh_id=0, 269 | color=Color(31, 30, 50, 4), 270 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 271 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 272 | vector=Vector(5, 3, 2), 273 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 274 | -0.750877077691500), 275 | type="Column", 276 | info={"Name": "Pyramid"}), False), 277 | (Element(mesh_id=0, 278 | color=Color(31, 30, 50, 4), 279 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 280 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 281 | vector=Vector(5, 3, 2), 282 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 283 | -0.750877077691500), 284 | type="Beam", 285 | info={"Name": "Another Pyramid"}), False), 286 | (Element(mesh_id=0, 287 | color=Color(31, 30, 50, 4), 288 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 289 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 290 | vector=Vector(5, 3, 2), 291 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 292 | -0.750877077691500), 293 | type="Beam", 294 | info={"Another name": "Pyramid"}), False), 295 | (Element(mesh_id=0, 296 | color=Color(31, 30, 50, 4), 297 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 298 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 299 | vector=Vector(5, 3, 2), 300 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 301 | -0.750877077691500), 302 | type="Beam", 303 | info={"Name": "Pyramid", "Another name": "Another Pyramid"}), False), 304 | (Element(mesh_id=0, 305 | color=Color(31, 30, 50, 4), 306 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 251], 307 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 308 | vector=Vector(5, 3, 2), 309 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 310 | -0.750877077691500), 311 | type="Beam", 312 | info={"Name": "Pyramid"}), False), 313 | (Element(mesh_id=0, 314 | color=Color(31, 30, 50, 4), 315 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 316 | vector=Vector(5, 3, 2), 317 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 318 | -0.750877077691500), 319 | type="Beam", 320 | info={"Name": "Pyramid"}), False), 321 | ]) 322 | def test_equals_without_mesh_id(other, expected): 323 | original = Element(mesh_id=0, 324 | color=Color(31, 30, 50, 4), 325 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 326 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 327 | vector=Vector(5, 3, 2), 328 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 329 | -0.750877077691500), 330 | type="Beam", 331 | info={"Name": "Pyramid"}) 332 | 333 | assert original.equals_without_mesh_id(other) == expected 334 | assert other.equals_without_mesh_id(original) == expected 335 | 336 | 337 | @pytest.mark.parametrize("other, expected", 338 | [(Element(mesh_id=5, 339 | color=Color(31, 30, 50, 4), 340 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 341 | vector=Vector(5, 3, 2), 342 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 343 | -0.750877077691500), 344 | type="Beam", 345 | info={"Name": "Pyramid"}), True), 346 | (Element(mesh_id=5, 347 | color=Color(31, 30, 50, 4), 348 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 349 | vector=Vector(1, 0, 0), 350 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 351 | -0.750877077691500), 352 | type="Beam", 353 | info={"Name": "Pyramid"}), False), 354 | ]) 355 | def test_equals_without_mesh_id_both_without_face_colors(other, expected): 356 | original = Element(mesh_id=0, 357 | color=Color(31, 30, 50, 4), 358 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 359 | vector=Vector(5, 3, 2), 360 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 361 | -0.750877077691500), 362 | type="Beam", 363 | info={"Name": "Pyramid"}) 364 | 365 | assert original.equals_without_mesh_id(other) == expected 366 | assert other.equals_without_mesh_id(original) == expected 367 | 368 | 369 | def test_equals_without_mesh_id_with_other_object(): 370 | original = Element(mesh_id=0, 371 | color=Color(31, 30, 50, 4), 372 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 373 | vector=Vector(5, 3, 2), 374 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 375 | -0.750877077691500), 376 | type="Beam", 377 | info={"Name": "Pyramid"}) 378 | other = 2 379 | 380 | assert original.equals_without_mesh_id(other) is NotImplemented 381 | 382 | 383 | @pytest.mark.parametrize("element, expected", 384 | [(Element(mesh_id=0, 385 | color=Color(31, 30, 50, 4), 386 | face_colors=[255, 0, 0, 255, 135, 206, 235, 255, 255, 255, 255, 255], 387 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 388 | vector=Vector(5, 3, 2), 389 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 390 | -0.750877077691500), 391 | type="Beam", 392 | info={"Name": "Pyramid"}), True), 393 | (Element(mesh_id=0, 394 | color=Color(31, 30, 50, 4), 395 | guid="8f6bc6d0-4f24-4bd0-917a-82ab1c22a5bb", 396 | vector=Vector(5, 3, 2), 397 | rotation=Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, 398 | -0.750877077691500), 399 | type="Beam", 400 | info={"Name": "Pyramid"}), False), 401 | ]) 402 | def test_check_if_has_face_colors(element, expected): 403 | assert element.check_if_has_face_colors() == expected 404 | -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_file.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ..test_helper import * 4 | import pytest 5 | 6 | 7 | def test_init_pyramid(): 8 | file = create_file_with_pyramid() 9 | 10 | assert file.schema_version == "1.0.0" 11 | assert file.info == { 12 | "Author": "John Doe", 13 | "Date": "28.09.1999" 14 | } 15 | 16 | assert len(file.elements) == 1 17 | assert file.elements[0].type == "Structure" 18 | assert file.elements[0].info == {"Name": "Pyramid"} 19 | assert file.elements[0].mesh_id == 0 20 | assert file.elements[0].rotation == Rotation(qx=0, qy=0, qz=0, qw=1.0) 21 | assert file.elements[0].vector == Vector(x=0, y=0, z=0) 22 | assert file.elements[0].color == Color(r=255, g=255, b=0, a=255) 23 | assert file.elements[0].guid == "76e051c1-1bd7-44fc-8e2e-db2b64055068" 24 | 25 | assert len(file.meshes) == 1 26 | assert file.meshes[0].mesh_id == 0 27 | assert file.meshes[0].coordinates == [ 28 | # Base 29 | 0.0, 0.0, 0.0, 30 | 10.0, 0.0, 0.0, 31 | 10.0, 10.0, 0.0, 32 | 0.0, 10.0, 0.0, 33 | 34 | # Top 35 | 5.0, 5.0, 4.0 36 | ] 37 | assert file.meshes[0].indices == [ 38 | # Base faces 39 | 0, 1, 2, 40 | 0, 2, 3, 41 | 42 | # Side faces 43 | 0, 1, 4, 44 | 1, 2, 4, 45 | 2, 3, 4, 46 | 3, 0, 4 47 | ] 48 | 49 | 50 | def test_init_cubes(): 51 | file = create_file_with_cubes() 52 | 53 | assert file.schema_version == "1.0.0" 54 | assert file.info == {"Author": "John Doe"} 55 | 56 | red_cube = Element(mesh_id=0, 57 | color=Color(255, 0, 0, 255), 58 | vector=Vector(x=-100.0, y=-100.0, z=-100.0), 59 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 60 | guid="9f61b565-06a2-4bef-8b72-f37091ab54d6", 61 | info={"Name": "Red Cube"}, 62 | type="Brick") 63 | 64 | green_cube = Element(mesh_id=0, 65 | color=Color(0, 255, 0, 126), 66 | vector=Vector(x=-0.0, y=0.0, z=0.0), 67 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 68 | guid="4d00c967-791a-42a6-a5e8-cf05831bc11d", 69 | info={"Name": "Green Cube"}, 70 | type="Brick") 71 | 72 | blue_cube = Element(mesh_id=0, 73 | color=Color(0, 0, 255, 10), 74 | vector=Vector(x=100.0, y=100.0, z=100.0), 75 | rotation=Rotation(qx=0.0, qy=0.0, qz=0.0, qw=1.0), 76 | guid="8501a5e3-4709-47d8-bd5d-33d745a435d5", 77 | info={"Name": "Blue Cube"}, 78 | type="Brick") 79 | 80 | assert len(file.elements) == 3 81 | assert file.elements[0] == red_cube 82 | assert file.elements[1] == green_cube 83 | assert file.elements[2] == blue_cube 84 | 85 | assert len(file.meshes) == 1 86 | assert file.meshes[0].mesh_id == 0 87 | assert file.meshes[0].coordinates == [ 88 | 0.0, 0.0, 0.0, 89 | 10.0, 0.0, 0.0, 90 | 10.0, 0.0, 20.0, 91 | 0.0, 0.0, 20.0, 92 | 0.0, 30.0, 0.0, 93 | 10.0, 30.0, 0.0, 94 | 10.0, 30.0, 20.0, 95 | 0.0, 30.0, 20.0 96 | ] 97 | assert file.meshes[0].indices == [ 98 | # Front side 99 | 0, 1, 2, 100 | 0, 2, 3, 101 | 102 | # Bottom side 103 | 0, 1, 4, 104 | 1, 4, 5, 105 | 106 | # Left side 107 | 0, 4, 3, 108 | 4, 3, 7, 109 | 110 | # Right side 111 | 1, 2, 5, 112 | 2, 5, 6, 113 | 114 | # Top side 115 | 2, 3, 7, 116 | 2, 6, 7, 117 | 118 | # Back side 119 | 4, 5, 7, 120 | 5, 6, 7 121 | ] 122 | 123 | 124 | def test_init_cubes_with_face_colors_and_without(): 125 | file = create_file_with_cubes_with_face_colors_and_without() 126 | 127 | assert file.schema_version == "1.1.0" 128 | assert file.info == {"Author": "John Doe"} 129 | 130 | red_cube = create_red_cube_element() 131 | multicolor_cube = create_multicolor_cube_element() 132 | blue_cube = create_blue_cube_element() 133 | 134 | assert len(file.elements) == 3 135 | assert file.elements[0] == red_cube 136 | assert file.elements[1] == multicolor_cube 137 | assert file.elements[2] == blue_cube 138 | 139 | assert len(file.meshes) == 1 140 | assert file.meshes[0].mesh_id == 0 141 | assert file.meshes[0].coordinates == [ 142 | 0.0, 0.0, 0.0, 143 | 10.0, 0.0, 0.0, 144 | 10.0, 0.0, 20.0, 145 | 0.0, 0.0, 20.0, 146 | 0.0, 30.0, 0.0, 147 | 10.0, 30.0, 0.0, 148 | 10.0, 30.0, 20.0, 149 | 0.0, 30.0, 20.0 150 | ] 151 | assert file.meshes[0].indices == [ 152 | # Front side 153 | 0, 1, 2, 154 | 0, 2, 3, 155 | 156 | # Bottom side 157 | 0, 1, 4, 158 | 1, 4, 5, 159 | 160 | # Left side 161 | 0, 4, 3, 162 | 4, 3, 7, 163 | 164 | # Right side 165 | 1, 2, 5, 166 | 2, 5, 6, 167 | 168 | # Top side 169 | 2, 3, 7, 170 | 2, 6, 7, 171 | 172 | # Back side 173 | 4, 5, 7, 174 | 5, 6, 7 175 | ] 176 | 177 | 178 | @pytest.mark.parametrize("other, expected", 179 | [(File("1.0.0", meshes=[create_pyramid_mesh()], elements=[create_pyramid_element()], 180 | info={"Author": "John Doe", "Date": "28.09.1999"}), True), 181 | (File("1.0.1", meshes=[create_pyramid_mesh()], elements=[create_pyramid_element()], 182 | info={"Author": "John Doe", "Date": "28.09.1999"}), False), 183 | (File("1.0.0", meshes=[create_cube_mesh()], elements=[create_pyramid_element()], 184 | info={"Author": "John Doe", "Date": "28.09.1999"}), False), 185 | (File("1.0.0", meshes=[create_pyramid_mesh(), create_pyramid_mesh()], 186 | elements=[create_pyramid_element()], 187 | info={"Author": "John Doe", "Date": "28.09.1999"}), False), 188 | (File("1.0.0", meshes=[create_pyramid_mesh()], elements=[create_blue_cube_element()], 189 | info={"Author": "John Doe", "Date": "28.09.1999"}), False), 190 | (File("1.0.0", meshes=[create_pyramid_mesh()], 191 | elements=[create_pyramid_element(), create_pyramid_element()], 192 | info={"Author": "John Doe", "Date": "28.09.1999"}), False), 193 | (File("1.0.0", meshes=[create_pyramid_mesh()], elements=[create_pyramid_element()], 194 | info={"Author": "John Doe", "Another": "28.09.1999"}), False)]) 195 | def test_eq(other, expected): 196 | original = create_file_with_pyramid() 197 | assert original.__eq__(other) == expected 198 | assert other.__eq__(original) == expected 199 | 200 | 201 | def test_eq_with_other_object(): 202 | original = create_file_with_pyramid() 203 | other = 2 204 | 205 | assert original.__eq__(other) is NotImplemented 206 | 207 | 208 | def test_save_read_pyramid(): 209 | file = create_file_with_pyramid() 210 | file.save("Pyramid.bim") 211 | 212 | read_file = File.read("Pyramid.bim") 213 | 214 | assert read_file.schema_version == "1.0.0" 215 | assert read_file.info == file.info 216 | 217 | assert len(read_file.elements) == 1 218 | read_element = read_file.elements[0] 219 | assert read_element.type == file.elements[0].type 220 | assert read_element.info == file.elements[0].info 221 | assert read_element.mesh_id == file.elements[0].mesh_id 222 | assert read_element.rotation == file.elements[0].rotation 223 | assert read_element.vector == file.elements[0].vector 224 | assert read_element.color == file.elements[0].color 225 | assert read_element.guid == file.elements[0].guid 226 | 227 | read_mesh = read_file.meshes[0] 228 | assert read_mesh.mesh_id == file.meshes[0].mesh_id 229 | assert read_mesh.coordinates == file.meshes[0].coordinates 230 | assert read_mesh.indices == file.meshes[0].indices 231 | 232 | assert read_file == file 233 | os.remove("Pyramid.bim") 234 | 235 | 236 | def test_save_read_cubes(): 237 | file = create_file_with_cubes() 238 | file.save("Cubes.bim") 239 | read_file = File.read("Cubes.bim") 240 | 241 | assert read_file == file 242 | os.remove("Cubes.bim") 243 | 244 | 245 | def test_save_read_cubes_with_face_colors_and_without(): 246 | file = create_file_with_cubes_with_face_colors_and_without() 247 | file.save("CubesWithFaceColorsAndWithout.bim") 248 | read_file = File.read("CubesWithFaceColorsAndWithout.bim") 249 | 250 | assert read_file == file 251 | os.remove("CubesWithFaceColorsAndWithout.bim") 252 | 253 | 254 | def test_save_exceptions(): 255 | file = create_file_with_cubes() 256 | with pytest.raises(Exception): 257 | file.save("Wrong.path") 258 | 259 | 260 | def test_add_pyramid_cubes(): 261 | file_a = create_file_with_pyramid() 262 | file_b = create_file_with_cubes() 263 | 264 | file_result = file_a + file_b 265 | 266 | assert file_result.schema_version == file_a.schema_version 267 | assert file_result.info == file_a.info 268 | 269 | # Check meshes 270 | assert file_result.meshes[0] == file_a.meshes[0] 271 | assert file_result.meshes[1].equals_without_mesh_id(file_b.meshes[0]) 272 | assert file_result.meshes[1].mesh_id == 1 273 | 274 | # Check elements 275 | assert file_result.elements[0] == file_a.elements[0] 276 | assert file_result.elements[1].equals_without_mesh_id(file_b.elements[0]) and file_result.elements[ 277 | 1].mesh_id == 1 278 | assert file_result.elements[2].equals_without_mesh_id(file_b.elements[1]) and file_result.elements[ 279 | 2].mesh_id == 1 280 | assert file_result.elements[3].equals_without_mesh_id(file_b.elements[2]) and file_result.elements[ 281 | 3].mesh_id == 1 282 | 283 | 284 | def test_add_cubes_pyramid(): 285 | file_a = create_file_with_cubes() 286 | file_b = create_file_with_pyramid() 287 | 288 | file_result = file_a + file_b 289 | 290 | assert file_result.schema_version == file_a.schema_version 291 | assert file_result.info == file_a.info 292 | assert file_result.meshes[1].mesh_id == 1 293 | 294 | # Check meshes 295 | assert file_result.meshes[0] == file_a.meshes[0] 296 | assert file_result.meshes[1].equals_without_mesh_id(file_b.meshes[0]) 297 | 298 | # Check elements 299 | assert file_result.elements[0] == file_a.elements[0] 300 | assert file_result.elements[1] == file_a.elements[1] 301 | assert file_result.elements[2] == file_a.elements[2] 302 | assert file_result.elements[3].equals_without_mesh_id(file_b.elements[0]) and file_result.elements[3].mesh_id == 1 303 | 304 | 305 | def test_add_multicolor_cubes_pyramid(): 306 | file_a = create_file_with_cubes_with_face_colors_and_without() 307 | file_b = create_file_with_pyramid() 308 | 309 | file_result = file_a + file_b 310 | 311 | assert file_result.schema_version == file_a.schema_version 312 | assert file_result.info == file_a.info 313 | assert file_result.meshes[1].mesh_id == 1 314 | 315 | # Check meshes 316 | assert file_result.meshes[0] == file_a.meshes[0] 317 | assert file_result.meshes[1].equals_without_mesh_id(file_b.meshes[0]) 318 | 319 | # Check elements 320 | assert file_result.elements[0] == file_a.elements[0] 321 | assert file_result.elements[1] == file_a.elements[1] 322 | assert file_result.elements[2] == file_a.elements[2] 323 | assert file_result.elements[3].equals_without_mesh_id(file_b.elements[0]) and file_result.elements[3].mesh_id == 1 324 | 325 | 326 | def test_add_multicolor_pyramid_cubes(): 327 | file_a = create_file_with_pyramid() 328 | file_b = create_file_with_cubes_with_face_colors_and_without() 329 | 330 | file_result = file_a + file_b 331 | 332 | assert file_result.schema_version == file_a.schema_version 333 | assert file_result.info == file_a.info 334 | assert file_result.meshes[1].mesh_id == 1 335 | 336 | # Check meshes 337 | assert file_result.meshes[0] == file_a.meshes[0] 338 | assert file_result.meshes[1].equals_without_mesh_id(file_b.meshes[0]) 339 | 340 | # Check elements 341 | assert file_result.elements[0] == file_a.elements[0] 342 | assert file_result.elements[1].equals_without_mesh_id(file_b.elements[0]) and file_result.elements[1].mesh_id == 1 343 | assert file_result.elements[2].equals_without_mesh_id(file_b.elements[1]) and file_result.elements[2].mesh_id == 1 344 | assert file_result.elements[3].equals_without_mesh_id(file_b.elements[2]) and file_result.elements[3].mesh_id == 1 345 | 346 | 347 | def test_add_walls_truss__check_if_originals_changed(): 348 | file_a = File.read("test_files/WallsWithBeams.bim") 349 | file_b = File.read("test_files/Truss.bim") 350 | file_a_copy = copy.deepcopy(file_a) 351 | file_b_copy = copy.deepcopy(file_b) 352 | 353 | file_result = file_a + file_b 354 | 355 | assert file_a == file_a_copy 356 | assert file_b == file_b_copy 357 | 358 | 359 | def test_add_walls_truss(): 360 | file_a = File.read("test_files/WallsWithBeams.bim") 361 | file_b = File.read("test_files/Truss.bim") 362 | 363 | file_result = file_a + file_b 364 | 365 | assert file_result.schema_version == file_a.schema_version 366 | assert file_result.info == file_a.info 367 | 368 | # Check meshes 369 | assert file_result.meshes[0] == file_a.meshes[0] 370 | assert file_result.meshes[1] == file_a.meshes[1] 371 | for i in range(5): 372 | assert file_result.meshes[i + 2].equals_without_mesh_id(file_b.meshes[i]) 373 | 374 | # Check elements 375 | for i in range(7): 376 | assert file_result.elements[i] == file_a.elements[i] 377 | 378 | for i in range(7, len(file_result.elements)): 379 | assert file_result.elements[i].equals_without_mesh_id(file_b.elements[i - 7]) 380 | 381 | 382 | def test_create_plotly_figure(): 383 | bim_file = File.read(os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_files\\MultipleMeshes.bim")) 384 | figure = bim_file.create_plotly_figure() 385 | actual = str(figure.to_json()) 386 | 387 | with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), "text_files\\plotly_multiple_meshes.txt")) as f: 388 | expected = f.read() 389 | 390 | bim_file.view() 391 | 392 | assert actual == expected 393 | 394 | 395 | def test_view(): 396 | file = File.read("../unittests/test_files/BricksRotated.bim") 397 | file.view() 398 | 399 | 400 | def test_view_multicolor(): 401 | file = File.read("../unittests/test_files/MulticolorHouse.bim") 402 | file.view() 403 | 404 | 405 | def test_view_with_face_colors_and_without(): 406 | file = File.read("../unittests/test_files/CubesWithFaceColorsAndWithout.bim") 407 | file.view() 408 | 409 | -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_files/BricksRotated.bim: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "1.0.0", 3 | "meshes": [ 4 | { 5 | "mesh_id": 0, 6 | "coordinates": [ 7 | -1.0, 8 | -2.0, 9 | -5.0, 10 | -1.0, 11 | 2.0, 12 | -5.0, 13 | 1.0, 14 | -2.0, 15 | -5.0, 16 | 1.0, 17 | 2.0, 18 | -5.0, 19 | -1.0, 20 | -2.0, 21 | -5.0, 22 | 1.0, 23 | -2.0, 24 | -5.0, 25 | -1.0, 26 | -2.0, 27 | 5.0, 28 | 1.0, 29 | -2.0, 30 | 5.0, 31 | 1.0, 32 | -2.0, 33 | -5.0, 34 | 1.0, 35 | 2.0, 36 | -5.0, 37 | 1.0, 38 | -2.0, 39 | 5.0, 40 | 1.0, 41 | 2.0, 42 | 5.0, 43 | 1.0, 44 | 2.0, 45 | -5.0, 46 | -1.0, 47 | 2.0, 48 | -5.0, 49 | 1.0, 50 | 2.0, 51 | 5.0, 52 | -1.0, 53 | 2.0, 54 | 5.0, 55 | -1.0, 56 | 2.0, 57 | -5.0, 58 | -1.0, 59 | -2.0, 60 | -5.0, 61 | -1.0, 62 | 2.0, 63 | 5.0, 64 | -1.0, 65 | -2.0, 66 | 5.0, 67 | -1.0, 68 | -2.0, 69 | 5.0, 70 | 1.0, 71 | -2.0, 72 | 5.0, 73 | -1.0, 74 | 2.0, 75 | 5.0, 76 | 1.0, 77 | 2.0, 78 | 5.0 79 | ], 80 | "indices": [ 81 | 0, 82 | 1, 83 | 3, 84 | 4, 85 | 5, 86 | 7, 87 | 8, 88 | 9, 89 | 11, 90 | 12, 91 | 13, 92 | 15, 93 | 16, 94 | 17, 95 | 19, 96 | 20, 97 | 21, 98 | 23, 99 | 0, 100 | 3, 101 | 2, 102 | 4, 103 | 7, 104 | 6, 105 | 8, 106 | 11, 107 | 10, 108 | 12, 109 | 15, 110 | 14, 111 | 16, 112 | 19, 113 | 18, 114 | 20, 115 | 23, 116 | 22 117 | ] 118 | } 119 | ], 120 | "elements": [ 121 | { 122 | "mesh_id": 0, 123 | "vector": { 124 | "x": 7.5186233686734392, 125 | "y": 7.3149022009468743, 126 | "z": 0.0 127 | }, 128 | "rotation": { 129 | "qx": 0.600880009474762, 130 | "qy": 0.2440724512578174, 131 | "qz": -0.28644964837820153, 132 | "qw": -0.7052080910586711 133 | }, 134 | "guid": "91d1ebcf-9daa-4eca-af97-e8ca9e69245f", 135 | "type": "Brick", 136 | "color": { 137 | "r": 80, 138 | "g": 55, 139 | "b": 25, 140 | "a": 255 141 | }, 142 | "info": { 143 | "Z Level": "0" 144 | } 145 | }, 146 | { 147 | "mesh_id": 0, 148 | "vector": { 149 | "x": -0.89918940074297848, 150 | "y": 10.451264391707763, 151 | "z": 1.4925566402060673 152 | }, 153 | "rotation": { 154 | "qx": -0.64775556845880278, 155 | "qy": -0.032254344171358529, 156 | "qz": 0.76066942352000422, 157 | "qw": -0.027466505682983818 158 | }, 159 | "guid": "08fbe145-ecbd-479f-a178-0750b996f08b", 160 | "type": "Brick", 161 | "color": { 162 | "r": 80, 163 | "g": 55, 164 | "b": 25, 165 | "a": 255 166 | }, 167 | "info": { 168 | "Z Level": "1.492557" 169 | } 170 | }, 171 | { 172 | "mesh_id": 0, 173 | "vector": { 174 | "x": -8.657570403831798, 175 | "y": 5.9231613892626749, 176 | "z": 2.9851121525476176 177 | }, 178 | "rotation": { 179 | "qx": -0.1916549160742082, 180 | "qy": -0.61959363487473629, 181 | "qz": 0.727171278562898, 182 | "qw": 0.22493121704312308 183 | }, 184 | "guid": "3cb06912-72da-41a9-931c-3fae9d8e7dc4", 185 | "type": "Brick", 186 | "color": { 187 | "r": 81, 188 | "g": 55, 189 | "b": 25, 190 | "a": 255 191 | }, 192 | "info": { 193 | "Z Level": "2.985112" 194 | } 195 | }, 196 | { 197 | "mesh_id": 0, 198 | "vector": { 199 | "x": -10.066897450053197, 200 | "y": -2.9486996166159622, 201 | "z": 4.4776677454205043 202 | }, 203 | "rotation": { 204 | "qx": 0.092101639726421741, 205 | "qy": -0.64198542407714376, 206 | "qz": 0.75345068572860519, 207 | "qw": -0.10809286473809833 208 | }, 209 | "guid": "949ea549-c670-4a6c-9b72-467914069d2e", 210 | "type": "Brick", 211 | "color": { 212 | "r": 81, 213 | "g": 55, 214 | "b": 25, 215 | "a": 255 216 | }, 217 | "info": { 218 | "Z Level": "4.477668" 219 | } 220 | }, 221 | { 222 | "mesh_id": 0, 223 | "vector": { 224 | "x": -4.0936436136211345, 225 | "y": -9.6581169320316231, 226 | "z": 5.9702233378676759 227 | }, 228 | "rotation": { 229 | "qx": 0.5407226640127073, 230 | "qy": 0.35811606488526876, 231 | "qz": 0.42029416699591693, 232 | "qw": 0.63460593905454366 233 | }, 234 | "guid": "039068c0-bdca-4a29-bc86-a8861120a288", 235 | "type": "Brick", 236 | "color": { 237 | "r": 82, 238 | "g": 55, 239 | "b": 25, 240 | "a": 255 241 | }, 242 | "info": { 243 | "Z Level": "5.970223" 244 | } 245 | }, 246 | { 247 | "mesh_id": 0, 248 | "vector": { 249 | "x": 4.8816862781562795, 250 | "y": -9.2847285658602825, 251 | "z": 7.4627788886495914 252 | }, 253 | "rotation": { 254 | "qx": 0.33531203831599304, 255 | "qy": 0.5551522783376992, 256 | "qz": 0.65154076972655517, 257 | "qw": 0.39353069791436096 258 | }, 259 | "guid": "53583884-5fcc-4028-87f5-2c53446f3077", 260 | "type": "Brick", 261 | "color": { 262 | "r": 84, 263 | "g": 55, 264 | "b": 25, 265 | "a": 255 266 | }, 267 | "info": { 268 | "Z Level": "7.462779" 269 | } 270 | }, 271 | { 272 | "mesh_id": 0, 273 | "vector": { 274 | "x": 10.277015083831376, 275 | "y": -2.1023658389805524, 276 | "z": 8.9553344114270885 277 | }, 278 | "rotation": { 279 | "qx": 0.64526101499183275, 280 | "qy": -0.06531848991469244, 281 | "qz": 0.076659422956692022, 282 | "qw": -0.757294559784316 283 | }, 284 | "guid": "ed9da469-7ec9-4a94-ae57-97d997834a3c", 285 | "type": "Brick", 286 | "color": { 287 | "r": 85, 288 | "g": 56, 289 | "b": 25, 290 | "a": 255 291 | }, 292 | "info": { 293 | "Z Level": "8.955334" 294 | } 295 | }, 296 | { 297 | "mesh_id": 0, 298 | "vector": { 299 | "x": 8.1356706900053872, 300 | "y": 6.6217685209953352, 301 | "z": 10.447889934204586 302 | }, 303 | "rotation": { 304 | "qx": 0.61108792305967663, 305 | "qy": 0.21725528607968822, 306 | "qz": -0.25497625531825974, 307 | "qw": -0.717188120499023 308 | }, 309 | "guid": "63e0d631-0753-42ef-9e87-bb7e570e22da", 310 | "type": "Brick", 311 | "color": { 312 | "r": 87, 313 | "g": 56, 314 | "b": 25, 315 | "a": 255 316 | }, 317 | "info": { 318 | "Z Level": "10.44789" 319 | } 320 | }, 321 | { 322 | "mesh_id": 0, 323 | "vector": { 324 | "x": 0.028013753595962351, 325 | "y": 10.489813537113465, 326 | "z": 11.940445456982081 327 | }, 328 | "rotation": { 329 | "qx": -0.64855784154036367, 330 | "qy": 0.0010087176755824816, 331 | "qz": 0.76116422008984341, 332 | "qw": 0.00085948832214179473 333 | }, 334 | "guid": "1e596675-436f-4725-8f3e-4f04c4a3ca73", 335 | "type": "Brick", 336 | "color": { 337 | "r": 89, 338 | "g": 56, 339 | "b": 25, 340 | "a": 255 341 | }, 342 | "info": { 343 | "Z Level": "11.940445" 344 | } 345 | }, 346 | { 347 | "mesh_id": 0, 348 | "vector": { 349 | "x": -8.1001898030378268, 350 | "y": 6.6651297774692457, 351 | "z": 13.43300097975958 352 | }, 353 | "rotation": { 354 | "qx": -0.21889443174509274, 355 | "qy": -0.61050262845960168, 356 | "qz": 0.71650131790102922, 357 | "qw": 0.25690003861618782 358 | }, 359 | "guid": "03bdd50e-40db-4144-8663-d974e7e0b93a", 360 | "type": "Brick", 361 | "color": { 362 | "r": 92, 363 | "g": 57, 364 | "b": 26, 365 | "a": 255 366 | }, 367 | "info": { 368 | "Z Level": "13.433001" 369 | } 370 | }, 371 | { 372 | "mesh_id": 0, 373 | "vector": { 374 | "x": -10.288103979130945, 375 | "y": -2.047446279131921, 376 | "z": 14.925556502537081 377 | }, 378 | "rotation": { 379 | "qx": 0.063588216303858719, 380 | "qy": -0.64543371157070417, 381 | "qz": 0.75749746666604312, 382 | "qw": -0.074628752568200479 383 | }, 384 | "guid": "1ec7f19a-0c68-46b5-8f25-bebcef821861", 385 | "type": "Brick", 386 | "color": { 387 | "r": 94, 388 | "g": 57, 389 | "b": 26, 390 | "a": 255 391 | }, 392 | "info": { 393 | "Z Level": "14.925557" 394 | } 395 | }, 396 | { 397 | "mesh_id": 0, 398 | "vector": { 399 | "x": -4.931212060553908, 400 | "y": -9.2585300186728912, 401 | "z": 16.418112025314574 402 | }, 403 | "rotation": { 404 | "qx": 0.55604776568133762, 405 | "qy": 0.3338246596642645, 406 | "qz": 0.39178522866359566, 407 | "qw": 0.6525919961827944 408 | }, 409 | "guid": "5b848282-cc37-4170-849b-7e93e8fea45f", 410 | "type": "Brick", 411 | "color": { 412 | "r": 97, 413 | "g": 57, 414 | "b": 26, 415 | "a": 255 416 | }, 417 | "info": { 418 | "Z Level": "16.418112" 419 | } 420 | }, 421 | { 422 | "mesh_id": 0, 423 | "vector": { 424 | "x": 4.0420032779954216, 425 | "y": -9.6798530092342112, 426 | "z": 17.910667633877488 427 | }, 428 | "rotation": { 429 | "qx": 0.35955897937986542, 430 | "qy": 0.53976406096748708, 431 | "qz": 0.633481176341599, 432 | "qw": 0.42198779372875267 433 | }, 434 | "guid": "76c7aabf-087e-45dd-ae29-90392329b7c6", 435 | "type": "Brick", 436 | "color": { 437 | "r": 100, 438 | "g": 58, 439 | "b": 26, 440 | "a": 255 441 | }, 442 | "info": { 443 | "Z Level": "17.910668" 444 | } 445 | }, 446 | { 447 | "mesh_id": 0, 448 | "vector": { 449 | "x": 10.051012776705354, 450 | "y": -3.0024294339125754, 451 | "z": 19.403223255261917 452 | }, 453 | "rotation": { 454 | "qx": 0.64173768818248489, 455 | "qy": -0.0938111952602709, 456 | "qz": 0.11009928756548468, 457 | "qw": -0.75316023931671516 458 | }, 459 | "guid": "0d88515c-3f44-4453-a974-c01ce554e00a", 460 | "type": "Brick", 461 | "color": { 462 | "r": 103, 463 | "g": 58, 464 | "b": 26, 465 | "a": 255 466 | }, 467 | "info": { 468 | "Z Level": "19.403223" 469 | } 470 | }, 471 | { 472 | "mesh_id": 0, 473 | "vector": { 474 | "x": 8.6890887054400174, 475 | "y": 5.8768382136583543, 476 | "z": 20.895778876646343 477 | }, 478 | "rotation": { 479 | "qx": 0.620100052908974, 480 | "qy": 0.190009665691818, 481 | "qz": -0.223000367941983, 482 | "qw": -0.72776581894433012 483 | }, 484 | "guid": "b949a31b-0be5-4d43-927e-5b53c654c849", 485 | "type": "Brick", 486 | "color": { 487 | "r": 107, 488 | "g": 58, 489 | "b": 26, 490 | "a": 255 491 | }, 492 | "info": { 493 | "Z Level": "20.895779" 494 | } 495 | }, 496 | { 497 | "mesh_id": 0, 498 | "vector": { 499 | "x": 0.95499876780429782, 500 | "y": 10.446312494675, 501 | "z": 22.388334516585434 502 | }, 503 | "rotation": { 504 | "qx": -0.64765348603315342, 505 | "qy": 0.034245209889500978, 506 | "qz": 0.76060629842579719, 507 | "qw": 0.029159671187019565 508 | }, 509 | "guid": "fd393a8a-939d-4e24-ae72-82e6c36c4b24", 510 | "type": "Brick", 511 | "color": { 512 | "r": 110, 513 | "g": 59, 514 | "b": 27, 515 | "a": 255 516 | }, 517 | "info": { 518 | "Z Level": "22.388335" 519 | } 520 | }, 521 | { 522 | "mesh_id": 0, 523 | "vector": { 524 | "x": -7.4794380104632783, 525 | "y": 7.3549570841358944, 526 | "z": 23.880890111742872 527 | }, 528 | "rotation": { 529 | "qx": -0.24566532154042547, 530 | "qy": -0.60023029495039948, 531 | "qz": 0.70444598877205988, 532 | "qw": 0.28831925311909129 533 | }, 534 | "guid": "9e09ee01-80a9-4fdc-b938-fd28924e1681", 535 | "type": "Brick", 536 | "color": { 537 | "r": 113, 538 | "g": 59, 539 | "b": 27, 540 | "a": 255 541 | }, 542 | "info": { 543 | "Z Level": "23.88089" 544 | } 545 | }, 546 | { 547 | "mesh_id": 0, 548 | "vector": { 549 | "x": -10.428806021618687, 550 | "y": -1.1301689583179584, 551 | "z": 25.373445704191102 552 | }, 553 | "rotation": { 554 | "qx": -0.42901220535878026, 555 | "qy": -0.48639130343985792, 556 | "qz": 0.51324799068099236, 557 | "qw": -0.56209298843980948 558 | }, 559 | "guid": "d9ccabfb-55f0-40d0-8464-c1b60c9925de", 560 | "type": "Brick", 561 | "color": { 562 | "r": 117, 563 | "g": 60, 564 | "b": 27, 565 | "a": 255 566 | }, 567 | "info": { 568 | "Z Level": "25.373446" 569 | } 570 | }, 571 | { 572 | "mesh_id": 0, 573 | "vector": { 574 | "x": -5.7301851766755743, 575 | "y": -8.78647484724444, 576 | "z": 26.866001296639329 577 | }, 578 | "rotation": { 579 | "qx": 0.57025688493128557, 580 | "qy": 0.30892584505399984, 581 | "qz": 0.36256328465200693, 582 | "qw": 0.66926808684449191 583 | }, 584 | "guid": "e16d5bf1-89e5-42ce-9619-d4bb32695ad7", 585 | "type": "Brick", 586 | "color": { 587 | "r": 120, 588 | "g": 60, 589 | "b": 27, 590 | "a": 255 591 | }, 592 | "info": { 593 | "Z Level": "26.866001" 594 | } 595 | }, 596 | { 597 | "mesh_id": 0, 598 | "vector": { 599 | "x": 3.17067385638157, 600 | "y": -9.9991944516441613, 601 | "z": 28.358556861356632 602 | }, 603 | "rotation": { 604 | "qx": 0.3830637822648727, 605 | "qy": 0.52334533164541874, 606 | "qz": 0.61421135413211436, 607 | "qw": 0.44957337000435349 608 | }, 609 | "guid": "c6357128-9bd8-4a5b-b812-8af8e8a78247", 610 | "type": "Brick", 611 | "color": { 612 | "r": 124, 613 | "g": 61, 614 | "b": 27, 615 | "a": 255 616 | }, 617 | "info": { 618 | "Z Level": "28.358557" 619 | } 620 | }, 621 | { 622 | "mesh_id": 0, 623 | "vector": { 624 | "x": 9.7463058262319553, 625 | "y": -3.8789836064498306, 626 | "z": 29.851112384134122 627 | }, 628 | "rotation": { 629 | "qx": 0.63696329314963029, 630 | "qy": -0.12209027550025678, 631 | "qz": 0.14328822176429251, 632 | "qw": -0.74755616064070829 633 | }, 634 | "guid": "1a81daa5-f054-4756-a031-9d5db396c5a1", 635 | "type": "Brick", 636 | "color": { 637 | "r": 127, 638 | "g": 61, 639 | "b": 27, 640 | "a": 255 641 | }, 642 | "info": { 643 | "Z Level": "29.851112" 644 | } 645 | }, 646 | { 647 | "mesh_id": 0, 648 | "vector": { 649 | "x": 9.1744606930851518, 650 | "y": 5.085885234062415, 651 | "z": 31.343667906911605 652 | }, 653 | "rotation": { 654 | "qx": 0.62789743389885766, 655 | "qy": 0.16239802880355325, 656 | "qz": -0.19059440234599209, 657 | "qw": -0.73691618691566541 658 | }, 659 | "guid": "0dbb4d23-535a-4a9f-b27b-c60b13c4a05b", 660 | "type": "Brick", 661 | "color": { 662 | "r": 131, 663 | "g": 61, 664 | "b": 28, 665 | "a": 255 666 | }, 667 | "info": { 668 | "Z Level": "31.343668" 669 | } 670 | }, 671 | { 672 | "mesh_id": 0, 673 | "vector": { 674 | "x": 1.8745042370279232, 675 | "y": 10.321007700545927, 676 | "z": 32.8362234296891 677 | }, 678 | "rotation": { 679 | "qx": -0.41560726179835977, 680 | "qy": 0.49789446906266294, 681 | "qz": 0.58434145530661219, 682 | "qw": -0.48776712192134186 683 | }, 684 | "guid": "de0cde39-0d94-4115-928d-025f09f237de", 685 | "type": "Brick", 686 | "color": { 687 | "r": 134, 688 | "g": 62, 689 | "b": 28, 690 | "a": 255 691 | }, 692 | "info": { 693 | "Z Level": "32.836223" 694 | } 695 | }, 696 | { 697 | "mesh_id": 0, 698 | "vector": { 699 | "x": -6.8001262510269953, 700 | "y": 7.9871959052911841, 701 | "z": 34.3287789524666 702 | }, 703 | "rotation": { 704 | "qx": 0.58876803627259888, 705 | "qy": -0.27199346701285015, 706 | "qz": -0.31921839887521525, 707 | "qw": 0.69099302976627874 708 | }, 709 | "guid": "f9f8f60c-6662-48e3-9cd4-e3f60fb31dc9", 710 | "type": "Brick", 711 | "color": { 712 | "r": 137, 713 | "g": 62, 714 | "b": 28, 715 | "a": 255 716 | }, 717 | "info": { 718 | "Z Level": "34.328779" 719 | } 720 | }, 721 | { 722 | "mesh_id": 0, 723 | "vector": { 724 | "x": -10.487872247340368, 725 | "y": -0.20404743604201567, 726 | "z": 35.821334475244086 727 | }, 728 | "rotation": { 729 | "qx": -0.45341209572337188, 730 | "qy": -0.46373012608008063, 731 | "qz": 0.533811174635519, 732 | "qw": -0.54260249856754217 733 | }, 734 | "guid": "59d3fef4-c3fd-49a5-a270-8f6fab8b0f4c", 735 | "type": "Brick", 736 | "color": { 737 | "r": 140, 738 | "g": 63, 739 | "b": 28, 740 | "a": 255 741 | }, 742 | "info": { 743 | "Z Level": "35.821334" 744 | } 745 | }, 746 | { 747 | "mesh_id": 0, 748 | "vector": { 749 | "x": -6.484312926310837, 750 | "y": -8.2456590584545335, 751 | "z": 37.313889998021573 752 | }, 753 | "rotation": { 754 | "qx": 0.583375294811449, 755 | "qy": 0.28337485900380993, 756 | "qz": 0.33257602519024615, 757 | "qw": 0.684664255060013 758 | }, 759 | "guid": "cbc1c587-12ab-414a-b3da-2310dd7cb0c6", 760 | "type": "Brick", 761 | "color": { 762 | "r": 143, 763 | "g": 63, 764 | "b": 28, 765 | "a": 255 766 | }, 767 | "info": { 768 | "Z Level": "37.31389" 769 | } 770 | }, 771 | { 772 | "mesh_id": 0, 773 | "vector": { 774 | "x": 2.2745389647843108, 775 | "y": -10.240302492169631, 776 | "z": 38.806445586861344 777 | }, 778 | "rotation": { 779 | "qx": 0.40585672795722078, 780 | "qy": 0.50587373996634832, 781 | "qz": 0.59370658359977957, 782 | "qw": 0.47632401595405166 783 | }, 784 | "guid": "c6e3df0c-4191-4b41-80b5-c8bb7ffc8602", 785 | "type": "Brick", 786 | "color": { 787 | "r": 146, 788 | "g": 63, 789 | "b": 28, 790 | "a": 255 791 | }, 792 | "info": { 793 | "Z Level": "38.806446" 794 | } 795 | }, 796 | { 797 | "mesh_id": 0, 798 | "vector": { 799 | "x": 9.3653600016201359, 800 | "y": -4.7251937530470256, 801 | "z": 40.29900120824577 802 | }, 803 | "rotation": { 804 | "qx": 0.63093517147747546, 805 | "qy": -0.15016200382498174, 806 | "qz": 0.17623407324570656, 807 | "qw": -0.74048209527792208 808 | }, 809 | "guid": "3bfcc532-c7ca-4018-b787-d36986ec76fe", 810 | "type": "Brick", 811 | "color": { 812 | "r": 148, 813 | "g": 64, 814 | "b": 28, 815 | "a": 255 816 | }, 817 | "info": { 818 | "Z Level": "40.299001" 819 | } 820 | }, 821 | { 822 | "mesh_id": 0, 823 | "vector": { 824 | "x": 9.5880738784670623, 825 | "y": 4.2551526952399232, 826 | "z": 41.791556829630196 827 | }, 828 | "rotation": { 829 | "qx": 0.634466952726975, 830 | "qy": 0.13445980655709416, 831 | "qz": -0.157805582775897, 832 | "qw": -0.74462718481313506 833 | }, 834 | "guid": "aa4f14ef-465a-4a2f-8650-dbc11629e108", 835 | "type": "Brick", 836 | "color": { 837 | "r": 151, 838 | "g": 64, 839 | "b": 29, 840 | "a": 255 841 | }, 842 | "info": { 843 | "Z Level": "41.791557" 844 | } 845 | }, 846 | { 847 | "mesh_id": 0, 848 | "vector": { 849 | "x": 2.7793487075857155, 850 | "y": 10.11497396532827, 851 | "z": 43.284112464930374 852 | }, 853 | "rotation": { 854 | "qx": -0.39318371869231483, 855 | "qy": 0.51578515394483826, 856 | "qz": 0.60533907905132966, 857 | "qw": -0.46145079661722349 858 | }, 859 | "guid": "1358113a-da04-428e-91d8-212ed3cbc508", 860 | "type": "Brick", 861 | "color": { 862 | "r": 153, 863 | "g": 64, 864 | "b": 29, 865 | "a": 255 866 | }, 867 | "info": { 868 | "Z Level": "43.284112" 869 | } 870 | }, 871 | { 872 | "mesh_id": 0, 873 | "vector": { 874 | "x": -6.06761594980289, 875 | "y": 8.55695288524671, 876 | "z": 44.776668070514475 877 | }, 878 | "rotation": { 879 | "qx": 0.57616917013029312, 880 | "qy": -0.29775312637938839, 881 | "qz": -0.349450879147071, 882 | "qw": 0.6762072509120326 883 | }, 884 | "guid": "6156ed80-21ab-413c-a14a-fd2fd44da05f", 885 | "type": "Brick", 886 | "color": { 887 | "r": 154, 888 | "g": 64, 889 | "b": 29, 890 | "a": 255 891 | }, 892 | "info": { 893 | "Z Level": "44.776668" 894 | } 895 | }, 896 | { 897 | "mesh_id": 0, 898 | "vector": { 899 | "x": -10.464874429447043, 900 | "y": 0.72367335479947181, 901 | "z": 46.269223662962723 902 | }, 903 | "rotation": { 904 | "qx": -0.47656586240841575, 905 | "qy": -0.43990104229887678, 906 | "qz": 0.55361274640705471, 907 | "qw": -0.52238393810197015 908 | }, 909 | "guid": "18ecbc8f-d6c2-4122-ab0d-c6d50fa2c9f6", 910 | "type": "Brick", 911 | "color": { 912 | "r": 156, 913 | "g": 65, 914 | "b": 29, 915 | "a": 255 916 | }, 917 | "info": { 918 | "Z Level": "46.269224" 919 | } 920 | }, 921 | { 922 | "mesh_id": 0, 923 | "vector": { 924 | "x": -7.1876917216520759, 925 | "y": -7.6403057794131728, 926 | "z": 47.761779255410971 927 | }, 928 | "rotation": { 929 | "qx": 0.59532815290393815, 930 | "qy": 0.25731781814375321, 931 | "qz": 0.30199479685650882, 932 | "qw": 0.69869240263317578 933 | }, 934 | "guid": "6ade03e2-697b-42d5-838c-3e72f67e47b8", 935 | "type": "Brick", 936 | "color": { 937 | "r": 157, 938 | "g": 65, 939 | "b": 29, 940 | "a": 255 941 | }, 942 | "info": { 943 | "Z Level": "47.761779" 944 | } 945 | }, 946 | { 947 | "mesh_id": 0, 948 | "vector": { 949 | "x": 1.360595858605399, 950 | "y": -10.401243165356043, 951 | "z": 49.254334834063684 952 | }, 953 | "rotation": { 954 | "qx": 0.64671400603737028, 955 | "qy": 0.048879165968223885, 956 | "qz": 0.76002759941666886, 957 | "qw": -0.041591701747854017 958 | }, 959 | "guid": "bad6e106-19af-43e0-9b4a-657963c066d4", 960 | "type": "Brick", 961 | "color": { 962 | "r": 158, 963 | "g": 65, 964 | "b": 29, 965 | "a": 255 966 | }, 967 | "info": { 968 | "Z Level": "49.254335" 969 | } 970 | }, 971 | { 972 | "mesh_id": 0, 973 | "vector": { 974 | "x": 8.9110805643143269, 975 | "y": -5.5344056327528222, 976 | "z": 50.746890356841163 977 | }, 978 | "rotation": { 979 | "qx": 0.62368060987877116, 980 | "qy": -0.17790659641189108, 981 | "qz": 0.20879566667769883, 982 | "qw": -0.73196728710441417 983 | }, 984 | "guid": "6784c08c-4ab0-43c0-a8e8-0c2feadb52d2", 985 | "type": "Brick", 986 | "color": { 987 | "r": 159, 988 | "g": 65, 989 | "b": 29, 990 | "a": 255 991 | }, 992 | "info": { 993 | "Z Level": "50.74689" 994 | } 995 | }, 996 | { 997 | "mesh_id": 0, 998 | "vector": { 999 | "x": 9.9266016462536122, 1000 | "y": 3.3910972817343494, 1001 | "z": 52.239445879618685 1002 | }, 1003 | "rotation": { 1004 | "qx": 0.63979295771454925, 1005 | "qy": 0.10626982147910254, 1006 | "qz": -0.12472093047736807, 1007 | "qw": -0.7508770776915008 1008 | }, 1009 | "guid": "1ce43219-e8fc-41f1-b50d-a4b59a187498", 1010 | "type": "Brick", 1011 | "color": { 1012 | "r": 159, 1013 | "g": 65, 1014 | "b": 29, 1015 | "a": 255 1016 | }, 1017 | "info": { 1018 | "Z Level": "52.239446" 1019 | } 1020 | }, 1021 | { 1022 | "mesh_id": 0, 1023 | "vector": { 1024 | "x": 3.662427161625319, 1025 | "y": 9.8297298184349717, 1026 | "z": 53.732001402396172 1027 | }, 1028 | "rotation": { 1029 | "qx": -0.36997771504410204, 1030 | "qy": 0.532677007265208, 1031 | "qz": 0.62516310901198557, 1032 | "qw": -0.43421513496444958 1033 | }, 1034 | "guid": "857c97db-1e4d-4da4-a9a1-b5dfdbbc59d9", 1035 | "type": "Brick", 1036 | "color": { 1037 | "r": 159, 1038 | "g": 65, 1039 | "b": 29, 1040 | "a": 255 1041 | }, 1042 | "info": { 1043 | "Z Level": "53.732001" 1044 | } 1045 | }, 1046 | { 1047 | "mesh_id": 0, 1048 | "vector": { 1049 | "x": -5.2875980757694832, 1050 | "y": 9.0597080041692255, 1051 | "z": 55.224556925173687 1052 | }, 1053 | "rotation": { 1054 | "qx": 0.56242567532079424, 1055 | "qy": -0.32296380590619828, 1056 | "qz": -0.37903846471690111, 1057 | "qw": 0.660076951634873 1058 | }, 1059 | "guid": "10acc2c6-2cca-4a76-9523-d980f71157e5", 1060 | "type": "Brick", 1061 | "color": { 1062 | "r": 159, 1063 | "g": 65, 1064 | "b": 29, 1065 | "a": 255 1066 | }, 1067 | "info": { 1068 | "Z Level": "55.224557" 1069 | } 1070 | }, 1071 | { 1072 | "mesh_id": 0, 1073 | "vector": { 1074 | "x": -10.359954879774119, 1075 | "y": 1.6457263942046605, 1076 | "z": 56.7171124479512 1077 | }, 1078 | "rotation": { 1079 | "qx": -0.49854157655040132, 1080 | "qy": -0.41483065812577874, 1081 | "qz": 0.572639087976828, 1082 | "qw": -0.50145418180591561 1083 | }, 1084 | "guid": "b5232956-ba49-4c84-b8d9-e414ea8ee034", 1085 | "type": "Brick", 1086 | "color": { 1087 | "r": 159, 1088 | "g": 66, 1089 | "b": 30, 1090 | "a": 255 1091 | }, 1092 | "info": { 1093 | "Z Level": "56.717112" 1094 | } 1095 | }, 1096 | { 1097 | "mesh_id": 0, 1098 | "vector": { 1099 | "x": -7.8348160412249017, 1100 | "y": -6.9751589436058365, 1101 | "z": 58.209667970728709 1102 | }, 1103 | "rotation": { 1104 | "qx": 0.23070735224600489, 1105 | "qy": -0.60613710230768669, 1106 | "qz": 0.71137806312473506, 1107 | "qw": -0.27076407097430644 1108 | }, 1109 | "guid": "34464a24-882a-4380-bf6b-b46d4a069be0", 1110 | "type": "Brick", 1111 | "color": { 1112 | "r": 159, 1113 | "g": 67, 1114 | "b": 31, 1115 | "a": 255 1116 | }, 1117 | "info": { 1118 | "Z Level": "58.209668" 1119 | } 1120 | }, 1121 | { 1122 | "mesh_id": 0, 1123 | "vector": { 1124 | "x": 0.43600874386992389, 1125 | "y": -10.480801320683454, 1126 | "z": 59.702223539845342 1127 | }, 1128 | "rotation": { 1129 | "qx": 0.64837056116428682, 1130 | "qy": 0.015606525699358696, 1131 | "qz": 0.76104879699261174, 1132 | "qw": -0.013295877827419124 1133 | }, 1134 | "guid": "ddee9448-f558-4489-b8c0-4f66bbe63070", 1135 | "type": "Brick", 1136 | "color": { 1137 | "r": 160, 1138 | "g": 69, 1139 | "b": 33, 1140 | "a": 255 1141 | }, 1142 | "info": { 1143 | "Z Level": "59.702224" 1144 | } 1145 | }, 1146 | { 1147 | "mesh_id": 0, 1148 | "vector": { 1149 | "x": 8.3870936708216934, 1150 | "y": -6.3003226704263806, 1151 | "z": 61.194779161229775 1152 | }, 1153 | "rotation": { 1154 | "qx": 0.61519458825690132, 1155 | "qy": -0.20533741854996179, 1156 | "qz": 0.24098938038569639, 1157 | "qw": -0.72200850525736715 1158 | }, 1159 | "guid": "b33c8b2b-1bec-4b3f-8bd9-bd7547cfa78b", 1160 | "type": "Brick", 1161 | "color": { 1162 | "r": 160, 1163 | "g": 71, 1164 | "b": 35, 1165 | "a": 255 1166 | }, 1167 | "info": { 1168 | "Z Level": "61.194779" 1169 | } 1170 | }, 1171 | { 1172 | "mesh_id": 0, 1173 | "vector": { 1174 | "x": 10.187486755324098, 1175 | "y": 2.5005181798485463, 1176 | "z": 62.687334782614215 1177 | }, 1178 | "rotation": { 1179 | "qx": 0.64386795135472075, 1180 | "qy": 0.077857709270564582, 1181 | "qz": -0.0913758638968763, 1182 | "qw": -0.7556604328814065 1183 | }, 1184 | "guid": "fbc65a41-b0fe-4b60-85be-d1abbeb3b421", 1185 | "type": "Brick", 1186 | "color": { 1187 | "r": 160, 1188 | "g": 73, 1189 | "b": 37, 1190 | "a": 255 1191 | }, 1192 | "info": { 1193 | "Z Level": "62.687335" 1194 | } 1195 | }, 1196 | { 1197 | "mesh_id": 0, 1198 | "vector": { 1199 | "x": 4.5168600990873378, 1200 | "y": 9.46760054100345, 1201 | "z": 64.179890413275444 1202 | }, 1203 | "rotation": { 1204 | "qx": -0.34605854209437009, 1205 | "qy": 0.5485173097775119, 1206 | "qz": 0.6437544121807891, 1207 | "qw": -0.40614345140076635 1208 | }, 1209 | "guid": "8297f8d0-1fc3-4c6e-858d-f447fd756478", 1210 | "type": "Brick", 1211 | "color": { 1212 | "r": 161, 1213 | "g": 76, 1214 | "b": 40, 1215 | "a": 255 1216 | }, 1217 | "info": { 1218 | "Z Level": "64.17989" 1219 | } 1220 | }, 1221 | { 1222 | "mesh_id": 0, 1223 | "vector": { 1224 | "x": -4.4662155216744237, 1225 | "y": 9.4915932739303113, 1226 | "z": 65.672446029286249 1227 | }, 1228 | "rotation": { 1229 | "qx": 0.54759854268490016, 1230 | "qy": -0.34751065314524693, 1231 | "qz": -0.40784763348950365, 1232 | "qw": 0.64267603802923057 1233 | }, 1234 | "guid": "d633f947-d6e1-4972-bafd-c7e4144ba1a2", 1235 | "type": "Brick", 1236 | "color": { 1237 | "r": 161, 1238 | "g": 79, 1239 | "b": 42, 1240 | "a": 255 1241 | }, 1242 | "info": { 1243 | "Z Level": "65.672446" 1244 | } 1245 | }, 1246 | { 1247 | "mesh_id": 0, 1248 | "vector": { 1249 | "x": -10.173975672261475, 1250 | "y": 2.5549054099564636, 1251 | "z": 67.16500162173449 1252 | }, 1253 | "rotation": { 1254 | "qx": -0.079569284393240611, 1255 | "qy": -0.64365880200358394, 1256 | "qz": 0.75541471744907385, 1257 | "qw": 0.0933845824844483 1258 | }, 1259 | "guid": "5c279a47-6209-4bef-83d9-917cf7187e7c", 1260 | "type": "Brick", 1261 | "color": { 1262 | "r": 161, 1263 | "g": 82, 1264 | "b": 46, 1265 | "a": 255 1266 | }, 1267 | "info": { 1268 | "Z Level": "67.165002" 1269 | } 1270 | }, 1271 | { 1272 | "mesh_id": 0, 1273 | "vector": { 1274 | "x": -8.420624519739528, 1275 | "y": -6.2554208597243894, 1276 | "z": 68.657557214182717 1277 | }, 1278 | "rotation": { 1279 | "qx": 0.20369586992557528, 1280 | "qy": -0.61574023572194059, 1281 | "qz": 0.72264858239738217, 1282 | "qw": -0.23906271362846607 1283 | }, 1284 | "guid": "58136b05-1ec6-44fa-b9f8-e755046f90b1", 1285 | "type": "Brick", 1286 | "color": { 1287 | "r": 162, 1288 | "g": 85, 1289 | "b": 49, 1290 | "a": 255 1291 | }, 1292 | "info": { 1293 | "Z Level": "68.657557" 1294 | } 1295 | }, 1296 | { 1297 | "mesh_id": 0, 1298 | "vector": { 1299 | "x": -0.49199322895998931, 1300 | "y": -10.478312950810187, 1301 | "z": 70.150112806630972 1302 | }, 1303 | "rotation": { 1304 | "qx": 0.64831923748738152, 1305 | "qy": -0.01761603492640364, 1306 | "qz": 0.76101683444709867, 1307 | "qw": 0.01500730839855159 1308 | }, 1309 | "guid": "19012a30-2205-4e43-b0b9-aba6f4b7c1c3", 1310 | "type": "Brick", 1311 | "color": { 1312 | "r": 163, 1313 | "g": 89, 1314 | "b": 53, 1315 | "a": 255 1316 | }, 1317 | "info": { 1318 | "Z Level": "70.150113" 1319 | } 1320 | }, 1321 | { 1322 | "mesh_id": 0, 1323 | "vector": { 1324 | "x": 7.7974352373060549, 1325 | "y": -7.0169095176769405, 1326 | "z": 71.642668329548314 1327 | }, 1328 | "rotation": { 1329 | "qx": 0.60551690757933174, 1330 | "qy": -0.23233062921123243, 1331 | "qz": 0.27266909121369648, 1332 | "qw": -0.71064992792694537 1333 | }, 1334 | "guid": "235c425e-417b-4aab-9474-49b647b51e07", 1335 | "type": "Brick", 1336 | "color": { 1337 | "r": 163, 1338 | "g": 93, 1339 | "b": 57, 1340 | "a": 255 1341 | }, 1342 | "info": { 1343 | "Z Level": "71.642668" 1344 | } 1345 | }, 1346 | { 1347 | "mesh_id": 0, 1348 | "vector": { 1349 | "x": 10.3685934775335, 1350 | "y": 1.5903569998415135, 1351 | "z": 73.135223852325836 1352 | }, 1353 | "rotation": { 1354 | "qx": 0.41638360725506435, 1355 | "qy": 0.49724540218291619, 1356 | "qz": 0.50273950511964938, 1357 | "qw": -0.57151088494381286 1358 | }, 1359 | "guid": "bf98a183-e876-41a5-ad20-b00bbe280371", 1360 | "type": "Brick", 1361 | "color": { 1362 | "r": 164, 1363 | "g": 97, 1364 | "b": 61, 1365 | "a": 255 1366 | }, 1367 | "info": { 1368 | "Z Level": "73.135224" 1369 | } 1370 | }, 1371 | { 1372 | "mesh_id": 0, 1373 | "vector": { 1374 | "x": 5.3359202608618679, 1375 | "y": 9.0313295030561367, 1376 | "z": 74.627779375103316 1377 | }, 1378 | "rotation": { 1379 | "qx": -0.32145269377679697, 1380 | "qy": 0.56329075344768675, 1381 | "qz": 0.66109216528890924, 1382 | "qw": -0.37726494899155372 1383 | }, 1384 | "guid": "a22e90a6-7ef0-4d78-8e93-dbea7086babc", 1385 | "type": "Brick", 1386 | "color": { 1387 | "r": 164, 1388 | "g": 101, 1389 | "b": 65, 1390 | "a": 255 1391 | }, 1392 | "info": { 1393 | "Z Level": "74.627779" 1394 | } 1395 | }, 1396 | { 1397 | "mesh_id": 0, 1398 | "vector": { 1399 | "x": -3.609863077059507, 1400 | "y": 9.8491562908990691, 1401 | "z": 76.120334897880824 1402 | }, 1403 | "rotation": { 1404 | "qx": 0.53168171147060561, 1405 | "qy": -0.37140655605320966, 1406 | "qz": -0.43589208682199226, 1407 | "qw": 0.62399504521618654 1408 | }, 1409 | "guid": "eb9a2459-fa4c-4d69-a665-4e6563a9348e", 1410 | "type": "Brick", 1411 | "color": { 1412 | "r": 165, 1413 | "g": 106, 1414 | "b": 69, 1415 | "a": 255 1416 | }, 1417 | "info": { 1418 | "Z Level": "76.120335" 1419 | } 1420 | }, 1421 | { 1422 | "mesh_id": 0, 1423 | "vector": { 1424 | "x": -9.9083486134776226, 1425 | "y": 3.4440804490217078, 1426 | "z": 77.612890420658331 1427 | }, 1428 | "rotation": { 1429 | "qx": -0.10798624081943518, 1430 | "qy": -0.63950540985327131, 1431 | "qz": 0.75053976793106614, 1432 | "qw": 0.12673539093744779 1433 | }, 1434 | "guid": "a46903aa-e6be-4239-9f26-fbc4e7fd1010", 1435 | "type": "Brick", 1436 | "color": { 1437 | "r": 166, 1438 | "g": 110, 1439 | "b": 73, 1440 | "a": 255 1441 | }, 1442 | "info": { 1443 | "Z Level": "77.61289" 1444 | } 1445 | }, 1446 | { 1447 | "mesh_id": 0, 1448 | "vector": { 1449 | "x": -8.9405260078849658, 1450 | "y": -5.4867255355647622, 1451 | "z": 79.105445943435825 1452 | }, 1453 | "rotation": { 1454 | "qx": 0.1762343363803538, 1455 | "qy": -0.62415506986197378, 1456 | "qz": 0.73252437723952446, 1457 | "qw": -0.20683313128224362 1458 | }, 1459 | "guid": "8b5d0df8-8ef2-45e5-b3c6-01a4c924246c", 1460 | "type": "Brick", 1461 | "color": { 1462 | "r": 166, 1463 | "g": 114, 1464 | "b": 78, 1465 | "a": 255 1466 | }, 1467 | "info": { 1468 | "Z Level": "79.105446" 1469 | } 1470 | }, 1471 | { 1472 | "mesh_id": 0, 1473 | "vector": { 1474 | "x": -1.4161438703184455, 1475 | "y": -10.393835358001917, 1476 | "z": 80.5980014928293 1477 | }, 1478 | "rotation": { 1479 | "qx": 0.64655883770079747, 1480 | "qy": -0.050888523263466968, 1481 | "qz": 0.75993252332029393, 1482 | "qw": 0.043296507839643526 1483 | }, 1484 | "guid": "05f450e9-51a2-482c-b87d-d168562d6cf3", 1485 | "type": "Brick", 1486 | "color": { 1487 | "r": 167, 1488 | "g": 119, 1489 | "b": 82, 1490 | "a": 255 1491 | }, 1492 | "info": { 1493 | "Z Level": "80.598001" 1494 | } 1495 | }, 1496 | { 1497 | "mesh_id": 0, 1498 | "vector": { 1499 | "x": 7.1467790482411635, 1500 | "y": -7.67860247033455, 1501 | "z": 82.090557114213723 1502 | }, 1503 | "rotation": { 1504 | "qx": 0.25890561724776218, 1505 | "qy": 0.59463916667286487, 1506 | "qz": 0.69788409424426223, 1507 | "qw": 0.30385841080513437 1508 | }, 1509 | "guid": "9306b656-8932-4934-a2cd-a6b43cf24c04", 1510 | "type": "Brick", 1511 | "color": { 1512 | "r": 168, 1513 | "g": 123, 1514 | "b": 87, 1515 | "a": 255 1516 | }, 1517 | "info": { 1518 | "Z Level": "82.090557" 1519 | } 1520 | }, 1521 | { 1522 | "mesh_id": 0, 1523 | "vector": { 1524 | "x": 10.46859914260558, 1525 | "y": 0.66775697255763489, 1526 | "z": 83.583112735598149 1527 | }, 1528 | "rotation": { 1529 | "qx": 0.44136890398609924, 1530 | "qy": 0.47520654768776732, 1531 | "qz": 0.52362079507471215, 1532 | "qw": -0.55244320123801816 1533 | }, 1534 | "guid": "0dfe1800-34f6-4bbc-b12d-6088120a4f16", 1535 | "type": "Brick", 1536 | "color": { 1537 | "r": 168, 1538 | "g": 128, 1539 | "b": 91, 1540 | "a": 255 1541 | }, 1542 | "info": { 1543 | "Z Level": "83.583113" 1544 | } 1545 | }, 1546 | { 1547 | "mesh_id": 0, 1548 | "vector": { 1549 | "x": 6.1132456344015331, 1550 | "y": 8.5244189088751, 1551 | "z": 85.075668361620473 1552 | }, 1553 | "rotation": { 1554 | "qx": -0.29622468704359967, 1555 | "qy": 0.57695639649799624, 1556 | "qz": 0.67713128296437664, 1557 | "qw": -0.34765712556624745 1558 | }, 1559 | "guid": "48f1b355-a6f1-4c2e-ad5d-459106ff095c", 1560 | "type": "Brick", 1561 | "color": { 1562 | "r": 169, 1563 | "g": 132, 1564 | "b": 95, 1565 | "a": 255 1566 | }, 1567 | "info": { 1568 | "Z Level": "85.075668" 1569 | } 1570 | }, 1571 | { 1572 | "mesh_id": 0, 1573 | "vector": { 1574 | "x": -2.7252712753264574, 1575 | "y": 10.129676047088726, 1576 | "z": 86.568223988057909 1577 | }, 1578 | "rotation": { 1579 | "qx": 0.51474199070471782, 1580 | "qy": -0.39454845557337903, 1581 | "qz": -0.46305245070345008, 1582 | "qw": 0.60411474663968823 1583 | }, 1584 | "guid": "34e933dc-4b09-482a-8213-1ac6f7a60ef3", 1585 | "type": "Brick", 1586 | "color": { 1587 | "r": 170, 1588 | "g": 136, 1589 | "b": 99, 1590 | "a": 255 1591 | }, 1592 | "info": { 1593 | "Z Level": "86.568224" 1594 | } 1595 | }, 1596 | { 1597 | "mesh_id": 0, 1598 | "vector": { 1599 | "x": -9.5651985949369251, 1600 | "y": 4.30631171877097, 1601 | "z": 88.060779580506107 1602 | }, 1603 | "rotation": { 1604 | "qx": -0.13614498356638588, 1605 | "qy": -0.634107597032559, 1606 | "qz": 0.7442052102828195, 1607 | "qw": 0.15978330270465249 1608 | }, 1609 | "guid": "3f24d440-9635-4acb-a34c-a940ec3e6af8", 1610 | "type": "Brick", 1611 | "color": { 1612 | "r": 170, 1613 | "g": 140, 1614 | "b": 103, 1615 | "a": 255 1616 | }, 1617 | "info": { 1618 | "Z Level": "88.06078" 1619 | } 1620 | }, 1621 | { 1622 | "mesh_id": 0, 1623 | "vector": { 1624 | "x": -9.3904614669293949, 1625 | "y": -4.6750897243936596, 1626 | "z": 89.5533351729543 1627 | }, 1628 | "rotation": { 1629 | "qx": 0.14847965003898217, 1630 | "qy": -0.631333362529868, 1631 | "qz": 0.74094911397673913, 1632 | "qw": -0.17425954601718888 1633 | }, 1634 | "guid": "eb41b690-72f9-494b-b7bd-8c0619413bb3", 1635 | "type": "Brick", 1636 | "color": { 1637 | "r": 171, 1638 | "g": 144, 1639 | "b": 107, 1640 | "a": 255 1641 | }, 1642 | "info": { 1643 | "Z Level": "89.553335" 1644 | } 1645 | }, 1646 | { 1647 | "mesh_id": 0, 1648 | "vector": { 1649 | "x": -2.3292107643856013, 1650 | "y": -10.227995745317909, 1651 | "z": 91.0458907654025 1652 | }, 1653 | "rotation": { 1654 | "qx": 0.50695686911502358, 1655 | "qy": 0.4045032387285839, 1656 | "qz": 0.47473531844088263, 1657 | "qw": 0.59497751229774454 1658 | }, 1659 | "guid": "2af233e3-b272-4d7b-aca4-8d077d8e9b0e", 1660 | "type": "Brick", 1661 | "color": { 1662 | "r": 171, 1663 | "g": 147, 1664 | "b": 111, 1665 | "a": 255 1666 | }, 1667 | "info": { 1668 | "Z Level": "91.045891" 1669 | } 1670 | }, 1671 | { 1672 | "mesh_id": 0, 1673 | "vector": { 1674 | "x": 6.4401648050561544, 1675 | "y": -8.280175546405161, 1676 | "z": 92.538446302255224 1677 | }, 1678 | "rotation": { 1679 | "qx": 0.2849364449023859, 1680 | "qy": 0.58261432695365656, 1681 | "qz": 0.6837709022538343, 1682 | "qw": 0.334408614760004 1683 | }, 1684 | "guid": "cc16ee74-b510-49cf-b99b-60dc91dccf34", 1685 | "type": "Brick", 1686 | "color": { 1687 | "r": 172, 1688 | "g": 151, 1689 | "b": 114, 1690 | "a": 255 1691 | }, 1692 | "info": { 1693 | "Z Level": "92.538446" 1694 | } 1695 | }, 1696 | { 1697 | "mesh_id": 0, 1698 | "vector": { 1699 | "x": 10.486626479127636, 1700 | "y": -0.2600728762683977, 1701 | "z": 94.031001825032675 1702 | }, 1703 | "rotation": { 1704 | "qx": 0.46513730702814859, 1705 | "qy": 0.45196855747444925, 1706 | "qz": 0.54380550112560044, 1707 | "qw": -0.5325854725868906 1708 | }, 1709 | "guid": "89d9521c-96db-479f-bc62-082b7d5d9ee0", 1710 | "type": "Brick", 1711 | "color": { 1712 | "r": 172, 1713 | "g": 154, 1714 | "b": 117, 1715 | "a": 255 1716 | }, 1717 | "info": { 1718 | "Z Level": "94.031002" 1719 | } 1720 | }, 1721 | { 1722 | "mesh_id": 0, 1723 | "vector": { 1724 | "x": 6.8426965403869184, 1725 | "y": 7.9507521642951584, 1726 | "z": 95.523557347810168 1727 | }, 1728 | "rotation": { 1729 | "qx": -0.270411957237645, 1730 | "qy": 0.58949612587518474, 1731 | "qz": 0.69184744552152033, 1732 | "qw": -0.31736225844671795 1733 | }, 1734 | "guid": "1a7240b6-fc9f-4834-beb9-f780b60ac8a9", 1735 | "type": "Brick", 1736 | "color": { 1737 | "r": 173, 1738 | "g": 157, 1739 | "b": 120, 1740 | "a": 255 1741 | }, 1742 | "info": { 1743 | "Z Level": "95.523557" 1744 | } 1745 | }, 1746 | { 1747 | "mesh_id": 0, 1748 | "vector": { 1749 | "x": -1.8193408058941063, 1750 | "y": 10.330875092959223, 1751 | "z": 97.016112870587619 1752 | }, 1753 | "rotation": { 1754 | "qx": 0.49677675599738563, 1755 | "qy": -0.41694260671418787, 1756 | "qz": -0.489334332109029, 1757 | "qw": 0.58302969806563276 1758 | }, 1759 | "guid": "8cc36725-aca3-4d0b-a298-d15e40709dc5", 1760 | "type": "Brick", 1761 | "color": { 1762 | "r": 173, 1763 | "g": 159, 1764 | "b": 122, 1765 | "a": 255 1766 | }, 1767 | "info": { 1768 | "Z Level": "97.016113" 1769 | } 1770 | }, 1771 | { 1772 | "mesh_id": 0, 1773 | "vector": { 1774 | "x": -9.147163591975545, 1775 | "y": 5.1348265483722786, 1776 | "z": 98.508668393365085 1777 | }, 1778 | "rotation": { 1779 | "qx": -0.16408259600363556, 1780 | "qy": -0.62745925514862166, 1781 | "qz": 0.7364020684484639, 1782 | "qw": 0.1925714890680042 1783 | }, 1784 | "guid": "4ee3b509-d280-4a23-8613-9b30d39eb92d", 1785 | "type": "Brick", 1786 | "color": { 1787 | "r": 173, 1788 | "g": 161, 1789 | "b": 124, 1790 | "a": 255 1791 | }, 1792 | "info": { 1793 | "Z Level": "98.508668" 1794 | } 1795 | }, 1796 | { 1797 | "mesh_id": 0, 1798 | "vector": { 1799 | "x": -9.76689581339353, 1800 | "y": -3.8268638437443707, 1801 | "z": 100.00122391614258 1802 | }, 1803 | "rotation": { 1804 | "qx": 0.12038213521910773, 1805 | "qy": -0.637288205465847, 1806 | "qz": 0.747937726665425, 1807 | "qw": -0.14128355079330665 1808 | }, 1809 | "guid": "7f82b103-0a37-4f7d-b0b6-2fa6ca9428ef", 1810 | "type": "Brick", 1811 | "color": { 1812 | "r": 174, 1813 | "g": 163, 1814 | "b": 126, 1815 | "a": 255 1816 | }, 1817 | "info": { 1818 | "Z Level": "100.001224" 1819 | } 1820 | }, 1821 | { 1822 | "mesh_id": 0, 1823 | "vector": { 1824 | "x": -3.2240497580898611, 1825 | "y": -9.98212186141011, 1826 | "z": 101.49377944581174 1827 | }, 1828 | "rotation": { 1829 | "qx": 0.52436857426968131, 1830 | "qy": 0.38166162380626062, 1831 | "qz": 0.44792794569494943, 1832 | "qw": 0.61541251100172845 1833 | }, 1834 | "guid": "3358abf1-8644-41e1-9196-909797919f72", 1835 | "type": "Brick", 1836 | "color": { 1837 | "r": 174, 1838 | "g": 164, 1839 | "b": 127, 1840 | "a": 255 1841 | }, 1842 | "info": { 1843 | "Z Level": "101.493779" 1844 | } 1845 | }, 1846 | { 1847 | "mesh_id": 0, 1848 | "vector": { 1849 | "x": 5.6831688962715772, 1850 | "y": -8.8169698557350014, 1851 | "z": 102.98633506762286 1852 | }, 1853 | "rotation": { 1854 | "qx": 0.31044736288273811, 1855 | "qy": 0.56942981491306466, 1856 | "qz": 0.66829770878104378, 1857 | "qw": 0.36434913641345951 1858 | }, 1859 | "guid": "20de6ce2-55c1-46cf-9251-6bfbf19a5c0c", 1860 | "type": "Brick", 1861 | "color": { 1862 | "r": 174, 1863 | "g": 165, 1864 | "b": 128, 1865 | "a": 255 1866 | }, 1867 | "info": { 1868 | "Z Level": "102.986335" 1869 | } 1870 | }, 1871 | { 1872 | "mesh_id": 0, 1873 | "vector": { 1874 | "x": 10.422628559377285, 1875 | "y": -1.1858679846562494, 1876 | "z": 104.47889059061174 1877 | }, 1878 | "rotation": { 1879 | "qx": 0.48771331537853085, 1880 | "qy": 0.42750829370879917, 1881 | "qz": 0.56323765748588861, 1882 | "qw": -0.51199191595422866 1883 | }, 1884 | "guid": "997a017d-0d06-4966-ba43-7d7983f804db", 1885 | "type": "Brick", 1886 | "color": { 1887 | "r": 174, 1888 | "g": 166, 1889 | "b": 129, 1890 | "a": 255 1891 | }, 1892 | "info": { 1893 | "Z Level": "104.478891" 1894 | } 1895 | }, 1896 | { 1897 | "mesh_id": 0, 1898 | "vector": { 1899 | "x": 7.5186233686734392, 1900 | "y": 7.3149022009468743, 1901 | "z": 105.9714472336252 1902 | }, 1903 | "rotation": { 1904 | "qx": 0.6008800094747585, 1905 | "qy": 0.24407245125781549, 1906 | "qz": -0.28644964837820225, 1907 | "qw": -0.70520809105867444 1908 | }, 1909 | "guid": "45255b3c-e672-4467-a891-c329c95fe35d", 1910 | "type": "Brick", 1911 | "color": { 1912 | "r": 174, 1913 | "g": 166, 1914 | "b": 129, 1915 | "a": 255 1916 | }, 1917 | "info": { 1918 | "Z Level": "105.971447" 1919 | } 1920 | } 1921 | ], 1922 | "info": { 1923 | "Author": "John Doe" 1924 | } 1925 | } -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_files/Cubes.bim: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "1.0.0", 3 | "meshes": [ 4 | { 5 | "mesh_id": 0, 6 | "coordinates": [ 7 | 0.0, 8 | 0.0, 9 | 0.0, 10 | 10.0, 11 | 0.0, 12 | 0.0, 13 | 10.0, 14 | 0.0, 15 | 20.0, 16 | 0.0, 17 | 0.0, 18 | 20.0, 19 | 0.0, 20 | 30.0, 21 | 0.0, 22 | 10.0, 23 | 30.0, 24 | 0.0, 25 | 10.0, 26 | 30.0, 27 | 20.0, 28 | 0.0, 29 | 30.0, 30 | 20.0 31 | ], 32 | "indices": [ 33 | 0, 34 | 1, 35 | 2, 36 | 0, 37 | 2, 38 | 3, 39 | 0, 40 | 1, 41 | 4, 42 | 1, 43 | 4, 44 | 5, 45 | 0, 46 | 4, 47 | 3, 48 | 4, 49 | 3, 50 | 7, 51 | 1, 52 | 2, 53 | 5, 54 | 2, 55 | 5, 56 | 6, 57 | 2, 58 | 3, 59 | 7, 60 | 2, 61 | 6, 62 | 7, 63 | 4, 64 | 5, 65 | 7, 66 | 5, 67 | 6, 68 | 7 69 | ] 70 | } 71 | ], 72 | "elements": [ 73 | { 74 | "info": { 75 | "Name": "Red Cube" 76 | }, 77 | "color": { 78 | "r": 255, 79 | "g": 0, 80 | "b": 0, 81 | "a": 255 82 | }, 83 | "guid": "9f61b565-06a2-4bef-8b72-f37091ab54d6", 84 | "rotation": { 85 | "qx": 0.0, 86 | "qy": 0.0, 87 | "qz": 0.0, 88 | "qw": 1.0 89 | }, 90 | "vector": { 91 | "x": -100.0, 92 | "y": -100.0, 93 | "z": -100.0 94 | }, 95 | "type": "Brick", 96 | "mesh_id": 0 97 | }, 98 | { 99 | "info": { 100 | "Name": "Green Cube" 101 | }, 102 | "color": { 103 | "r": 0, 104 | "g": 255, 105 | "b": 0, 106 | "a": 126 107 | }, 108 | "guid": "4d00c967-791a-42a6-a5e8-cf05831bc11d", 109 | "rotation": { 110 | "qx": 0.0, 111 | "qy": 0.0, 112 | "qz": 0.0, 113 | "qw": 1.0 114 | }, 115 | "vector": { 116 | "x": -0.0, 117 | "y": 0.0, 118 | "z": 0.0 119 | }, 120 | "type": "Brick", 121 | "mesh_id": 0 122 | }, 123 | { 124 | "info": { 125 | "Name": "Blue Cube" 126 | }, 127 | "color": { 128 | "r": 0, 129 | "g": 0, 130 | "b": 255, 131 | "a": 10 132 | }, 133 | "guid": "8501a5e3-4709-47d8-bd5d-33d745a435d5", 134 | "rotation": { 135 | "qx": 0.0, 136 | "qy": 0.0, 137 | "qz": 0.0, 138 | "qw": 1.0 139 | }, 140 | "vector": { 141 | "x": 100.0, 142 | "y": 100.0, 143 | "z": 100.0 144 | }, 145 | "type": "Brick", 146 | "mesh_id": 0 147 | } 148 | ], 149 | "info": { 150 | "Author": "John Doe" 151 | } 152 | } -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_files/CubesWithFaceColorsAndWithout.bim: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "1.1.0", 3 | "meshes": [ 4 | { 5 | "mesh_id": 0, 6 | "coordinates": [ 7 | 0.0, 8 | 0.0, 9 | 0.0, 10 | 10.0, 11 | 0.0, 12 | 0.0, 13 | 10.0, 14 | 0.0, 15 | 20.0, 16 | 0.0, 17 | 0.0, 18 | 20.0, 19 | 0.0, 20 | 30.0, 21 | 0.0, 22 | 10.0, 23 | 30.0, 24 | 0.0, 25 | 10.0, 26 | 30.0, 27 | 20.0, 28 | 0.0, 29 | 30.0, 30 | 20.0 31 | ], 32 | "indices": [ 33 | 0, 34 | 1, 35 | 2, 36 | 0, 37 | 2, 38 | 3, 39 | 0, 40 | 1, 41 | 4, 42 | 1, 43 | 4, 44 | 5, 45 | 0, 46 | 4, 47 | 3, 48 | 4, 49 | 3, 50 | 7, 51 | 1, 52 | 2, 53 | 5, 54 | 2, 55 | 5, 56 | 6, 57 | 2, 58 | 3, 59 | 7, 60 | 2, 61 | 6, 62 | 7, 63 | 4, 64 | 5, 65 | 7, 66 | 5, 67 | 6, 68 | 7 69 | ] 70 | } 71 | ], 72 | "elements": [ 73 | { 74 | "info": { 75 | "Name": "Red Cube" 76 | }, 77 | "color": { 78 | "r": 255, 79 | "g": 0, 80 | "b": 0, 81 | "a": 255 82 | }, 83 | "guid": "9f61b565-06a2-4bef-8b72-f37091ab54d6", 84 | "rotation": { 85 | "qx": 0.0, 86 | "qy": 0.0, 87 | "qz": 0.0, 88 | "qw": 1.0 89 | }, 90 | "vector": { 91 | "x": -100.0, 92 | "y": -100.0, 93 | "z": -100.0 94 | }, 95 | "type": "Brick", 96 | "mesh_id": 0 97 | }, 98 | { 99 | "info": { 100 | "Name": "Multicolor Cube" 101 | }, 102 | "color": { 103 | "r": 0, 104 | "g": 255, 105 | "b": 0, 106 | "a": 126 107 | }, 108 | "guid": "4d00c967-791a-42a6-a5e8-cf05831bc11d", 109 | "rotation": { 110 | "qx": 0.0, 111 | "qy": 0.0, 112 | "qz": 0.0, 113 | "qw": 1.0 114 | }, 115 | "vector": { 116 | "x": -0.0, 117 | "y": 0.0, 118 | "z": 0.0 119 | }, 120 | "type": "Brick", 121 | "mesh_id": 0, 122 | "face_colors": [ 123 | 255, 124 | 105, 125 | 180, 126 | 150, 127 | 255, 128 | 192, 129 | 203, 130 | 255, 131 | 53, 132 | 57, 133 | 53, 134 | 255, 135 | 0, 136 | 0, 137 | 0, 138 | 255, 139 | 243, 140 | 229, 141 | 171, 142 | 255, 143 | 255, 144 | 255, 145 | 0, 146 | 255, 147 | 9, 148 | 121, 149 | 105, 150 | 255, 151 | 0, 152 | 128, 153 | 0, 154 | 255, 155 | 0, 156 | 255, 157 | 255, 158 | 255, 159 | 0, 160 | 0, 161 | 255, 162 | 255, 163 | 226, 164 | 223, 165 | 210, 166 | 255, 167 | 255, 168 | 255, 169 | 255, 170 | 255 171 | ] 172 | }, 173 | { 174 | "info": { 175 | "Name": "Blue Cube" 176 | }, 177 | "color": { 178 | "r": 0, 179 | "g": 0, 180 | "b": 255, 181 | "a": 10 182 | }, 183 | "guid": "8501a5e3-4709-47d8-bd5d-33d745a435d5", 184 | "rotation": { 185 | "qx": 0.0, 186 | "qy": 0.0, 187 | "qz": 0.0, 188 | "qw": 1.0 189 | }, 190 | "vector": { 191 | "x": 100.0, 192 | "y": 100.0, 193 | "z": 100.0 194 | }, 195 | "type": "Brick", 196 | "mesh_id": 0 197 | } 198 | ], 199 | "info": { 200 | "Author": "John Doe" 201 | } 202 | } -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_files/MulticolorHouse.bim: -------------------------------------------------------------------------------- 1 | {"schema_version":"1.1.0","meshes":[{"mesh_id":0,"coordinates":[9.75,7.75,3.0,10.0,7.75,3.0,10.0,8.0,3.0,0.0,8.0,3.0,0.0,7.75,3.0,0.25,7.75,3.0,0.25,7.7,3.0,9.75,7.7,3.0,9.75,7.75,0.0,10.0,7.75,0.0,10.0,8.0,0.0,0.0,8.0,0.0,0.0,7.75,0.0,0.25,7.75,0.0,0.25,7.7,0.0,9.75,7.7,0.0],"indices":[5,0,1,5,1,2,5,2,3,5,3,4,0,5,6,0,6,7,0,8,9,0,9,1,9,10,2,9,2,1,2,10,11,2,11,3,3,11,12,3,12,4,13,5,4,13,4,12,5,13,14,5,14,6,15,7,6,15,6,14,8,0,7,8,7,15,8,13,12,8,12,11,8,11,10,8,10,9,13,8,15,13,15,14]},{"mesh_id":1,"coordinates":[9.75,7.7,3.0,9.75,7.75,3.0,9.75,7.75,0.0,9.75,7.7,0.0,9.7,7.7,0.0,9.7,7.7,3.0,9.75,0.25,3.0,9.75,0.0,3.0,10.0,0.0,3.0,10.0,7.75,3.0,10.0,7.75,0.0,9.9999999999,0.0,0.0,9.7499999999,0.0,0.0,9.7499999999,0.25,0.0,9.7,0.25,0.0,9.7,0.25,3.0],"indices":[3,0,1,3,1,2,0,3,4,0,4,5,0,6,7,0,7,8,0,8,9,0,9,1,9,10,2,9,2,1,13,3,2,13,2,10,13,10,11,13,11,12,3,13,14,3,14,4,14,15,5,14,5,4,6,0,5,6,5,15,6,13,12,6,12,7,12,11,8,12,8,7,8,11,10,8,10,9,13,6,15,13,15,14]},{"mesh_id":2,"coordinates":[0.2499999999,7.7,3.0,0.2499999999,7.75,3.0,-0.0,7.75,3.0,-0.0,0.25,3.0,0.2499999999,0.25,3.0,0.2499999999,0.2999999999,3.0,0.2999999999,0.2999999999,3.0,0.2999999999,7.7,3.0,0.25,7.7,0.0,0.25,7.75,0.0,0.0,7.75,0.0,0.0,0.25,0.0,0.25,0.25,0.0,0.25,0.2999999999,0.0,0.3,0.2999999999,0.0,0.3,7.7,0.0],"indices":[5,0,1,5,1,2,5,2,3,5,3,4,0,5,6,0,6,7,0,8,9,0,9,1,9,10,2,9,2,1,2,10,11,2,11,3,3,11,12,3,12,4,13,5,4,13,4,12,5,13,14,5,14,6,15,7,6,15,6,14,8,0,7,8,7,15,8,13,12,8,12,11,8,11,10,8,10,9,13,8,15,13,15,14]},{"mesh_id":3,"coordinates":[9.7,7.7,0.0,9.7,7.7,0.1,9.7,0.2999999999,0.1,9.7,0.2999999999,0.0,3.1466552997,0.3,0.0,3.1466552997,0.0,0.0,10.0,0.0,0.0,10.0,8.0,0.0,0.0,8.0,0.0,0.0,0.0,0.0,2.2466552997,0.0,0.0,2.2466552997,0.3,0.0,0.2999999999,0.2999999999,0.0,0.2999999999,7.7,0.0,0.2999999999,7.7,0.1,0.2999999999,0.2999999999,0.1,2.2466552997,0.3,0.1,2.2466552997,0.0,0.1,3.1466552997,0.0,0.1,3.1466552997,0.3,0.1,0.0,0.0,-0.1999999999,10.0,0.0,-0.1999999999,10.0,8.0,-0.1999999999,0.0,8.0,-0.1999999999],"indices":[3,0,1,3,1,2,12,13,8,12,8,9,11,12,10,10,12,9,8,13,0,3,4,5,7,8,0,7,0,6,6,0,3,6,3,5,0,13,14,0,14,1,14,15,16,16,17,18,16,18,19,14,16,19,1,14,19,1,19,2,4,3,2,4,2,19,5,4,19,5,19,18,5,10,9,5,9,20,5,20,21,5,21,6,6,21,22,6,22,7,7,22,23,7,23,8,8,23,20,8,20,9,11,10,17,11,17,16,12,11,16,12,16,15,13,12,15,13,15,14,10,5,18,10,18,17,21,20,23,21,23,22]},{"mesh_id":4,"coordinates":[2.2466552997,0.115,0.0999999999,2.2466552997,0.3,0.0999999999,2.2716552997,0.115,0.0999999999,2.2716552997,0.3,0.0999999999,2.2716552997,0.115,2.175,2.2716552997,0.3,2.175,2.2466552997,0.115,2.2,2.2466552997,0.3,2.2,3.1466552997,0.115,2.2,3.1466552997,0.3,2.2,3.1216552997,0.115,2.175,3.1216552997,0.3,2.175,3.1216552997,0.115,0.0999999999,3.1216552997,0.3,0.0999999999,3.1466552997,0.115,0.0999999999,3.1466552997,0.3,0.0999999999,2.2716552997,0.115,2.175,2.2716552997,0.3,2.175,3.1216552997,0.115,2.175,3.1216552997,0.3,2.175,3.1466552997,0.115,2.2,3.1466552997,0.3,2.2,2.2466552997,0.115,2.2,2.2466552997,0.3,2.2,2.2096552997,0.319,0.0999999999,2.2096552997,0.3,0.0999999999,2.2596552997,0.319,0.0999999999,2.2596552997,0.3,0.0999999999,2.2596552997,0.319,2.187,2.2596552997,0.3,2.187,2.2096552997,0.319,2.237,2.2096552997,0.3,2.237,3.1836552997,0.319,2.237,3.1836552997,0.3,2.237,3.1336552997,0.319,2.187,3.1336552997,0.3,2.187,3.1336552997,0.319,0.0999999999,3.1336552997,0.3,0.0999999999,3.1836552997,0.319,0.0999999999,3.1836552997,0.3,0.0999999999,2.2096552997,0.319,2.237,2.2096552997,0.3,2.237,2.2596552997,0.319,2.187,2.2596552997,0.3,2.187,3.1336552997,0.319,2.187,3.1336552997,0.3,2.187,3.1836552997,0.319,2.237,3.1836552997,0.3,2.237,2.2096552997,-0.0189999999,0.0999999999,2.2096552997,0.0,0.0999999999,2.2596552997,-0.0189999999,0.0999999999,2.2596552997,0.0,0.0999999999,2.2596552997,-0.0189999999,2.187,2.2596552997,0.0,2.187,2.2096552997,-0.0189999999,2.237,2.2096552997,0.0,2.237,3.1836552997,-0.0189999999,2.237,3.1836552997,0.0,2.237,3.1336552997,-0.0189999999,2.187,3.1336552997,0.0,2.187,3.1336552997,-0.0189999999,0.0999999999,3.1336552997,0.0,0.0999999999,3.1836552997,-0.0189999999,0.0999999999,3.1836552997,0.0,0.0999999999,2.2096552997,-0.0189999999,2.237,2.2096552997,0.0,2.237,2.2596552997,-0.0189999999,2.187,2.2596552997,0.0,2.187,3.1336552997,-0.0189999999,2.187,3.1336552997,0.0,2.187,3.1836552997,-0.0189999999,2.237,3.1836552997,0.0,2.237,2.2866552997,0.04,2.16,2.2866552997,0.115,2.16,2.2866552997,0.115,0.1,2.2866552997,0.04,0.0999999999,2.2746552997,0.04,0.0999999999,2.2746552997,0.04,2.16,2.2746552997,0.0,2.16,2.2466552997,0.0,2.16,2.2466552997,0.115,2.16,2.2466552997,0.115,0.1,2.2466552997,0.0,0.0999999999,2.2746552997,0.0,0.0999999999,3.1066552997,0.04,2.16,3.1066552997,0.115,2.16,3.1466552997,0.115,2.16,3.1466552997,0.0,2.16,3.1186552997,0.0,2.16,3.1186552997,0.04,2.16,3.1186552997,0.04,0.0999999999,3.1066552997,0.04,0.0999999999,3.1066552997,0.115,0.1,3.1466552997,0.115,0.1,3.1466552997,0.0,0.0999999999,3.1186552997,0.0,0.0999999999,2.2746552997,0.0,2.16,2.2466552997,0.0,2.16,2.2466552997,0.0,2.2,3.1466552997,0.0,2.2,3.1466552997,0.0,2.16,3.1186552997,0.0,2.16,3.1186552997,0.0,2.172,2.2746552997,0.0,2.172,2.2746552997,0.04,2.172,2.2746552997,0.04,2.16,2.2866552997,0.04,2.16,2.2866552997,0.115,2.16,2.2466552997,0.115,2.16,2.2466552997,0.115,2.2,3.1466552997,0.115,2.2,3.1466552997,0.115,2.16,3.1066552997,0.115,2.16,3.1066552997,0.04,2.16,3.1186552997,0.04,2.16,3.1186552997,0.04,2.172,3.1186552997,-0.0000999999,0.0999999999,3.0681267942,-0.0000999999,0.1620231418,3.0365464782,-0.0000999999,0.2007876055,2.9860179727,-0.0000999999,0.2628107474,2.9544376567,-0.0000999999,0.301575211,2.9039091512,-0.0000999999,0.3635983529,2.8723288352,-0.0000999999,0.4023628166,2.8218003296,-0.0000999999,0.4643859585,2.7902200137,-0.0000999999,0.5031504221,2.7396915081,-0.0000999999,0.565173564,2.7081111922,-0.0000999999,0.6039380277,2.6575826866,-0.0000999999,0.6659611695,2.6260023707,-0.0000999999,0.7047256332,2.5754738651,-0.0000999999,0.7667487751,2.5438935492,-0.0000999999,0.8055132388,2.4933650436,-0.0000999999,0.8675363806,2.4617847277,-0.0000999999,0.9063008443,2.4112562221,-0.0000999999,0.9683239862,2.3796759062,-0.0000999999,1.0070884498,2.3291474006,-0.0000999999,1.0691115917,2.3251838052,-0.0000999999,1.0739768581,2.2746552997,-0.0000999999,1.136,3.1186552997,-0.0000999999,2.172,3.0681267942,-0.0000999999,2.1099768581,3.0365464782,-0.0000999999,2.0712123944,2.9860179727,-0.0000999999,2.0091892525,2.9544376567,-0.0000999999,1.9704247889,2.9039091512,-0.0000999999,1.908401647,2.8723288352,-0.0000999999,1.8696371833,2.8218003296,-0.0000999999,1.8076140414,2.7902200137,-0.0000999999,1.7688495778,2.7396915081,-0.0000999999,1.7068264359,2.7081111922,-0.0000999999,1.6680619722,2.6575826866,-0.0000999999,1.6060388304,2.6260023707,-0.0000999999,1.5672743667,2.5754738651,-0.0000999999,1.5052512248,2.5438935492,-0.0000999999,1.4664867611,2.4933650436,-0.0000999999,1.4044636193,2.4617847277,-0.0000999999,1.3656991556,2.4112562221,-0.0000999999,1.3036760137,2.3796759062,-0.0000999999,1.2649115501,2.3291474006,-0.0000999999,1.2028884082,2.3251838052,-0.0000999999,1.1980231418,2.2746552997,-0.0000999999,1.136,3.1186552997,0.0401,0.0999999999,2.2746552997,0.0401,1.136,3.1186552997,0.0401,2.172,2.2746552997,0.0401,1.136,3.1186552997,0.0,0.3,3.1186552997,0.04,0.3,3.0186552997,0.0,0.3,3.0186552997,0.04,0.3,3.0186552997,0.0,2.072,3.0186552997,0.04,2.072,3.1186552997,0.0,2.072,3.1186552997,0.04,2.072,2.2746552997,0.0,0.3,2.2746552997,0.04,0.3,2.2746552997,0.0,2.072,2.2746552997,0.04,2.072,2.3746552997,0.0,2.072,2.3746552997,0.04,2.072,2.3746552997,0.0,0.3,2.3746552997,0.04,0.3,3.1186552997,0.0,0.0999999999,3.1186552997,0.04,0.0999999999,2.2746552997,0.0,0.0999999999,2.2746552997,0.04,0.0999999999,2.2746552997,0.0,0.3,2.2746552997,0.04,0.3,2.3746552997,0.0,0.3,2.3746552997,0.04,0.3,3.0186552997,0.0,0.3,3.0186552997,0.04,0.3,3.1186552997,0.0,0.3,3.1186552997,0.04,0.3,3.1186552997,0.0,2.172,3.1186552997,0.04,2.172,3.1186552997,0.0,2.072,3.1186552997,0.04,2.072,3.0186552997,0.0,2.072,3.0186552997,0.04,2.072,2.3746552997,0.0,2.072,2.3746552997,0.04,2.072,2.2746552997,0.0,2.072,2.2746552997,0.04,2.072,2.2746552997,0.0,2.172,2.2746552997,0.04,2.172,3.0186552997,0.014,0.3,3.0186552997,0.026,0.3,2.3746552997,0.014,0.3,2.3746552997,0.026,0.3,2.3746552997,0.014,2.072,2.3746552997,0.026,2.072,3.0186552997,0.014,2.072,3.0186552997,0.026,2.072],"indices":[0,1,3,0,3,2,2,3,5,2,5,4,4,5,7,4,7,6,6,7,1,6,1,0,0,2,4,0,4,6,1,7,5,1,5,3,8,9,11,8,11,10,10,11,13,10,13,12,12,13,15,12,15,14,14,15,9,14,9,8,8,10,12,8,12,14,9,15,13,9,13,11,16,17,19,16,19,18,18,19,21,18,21,20,20,21,23,20,23,22,22,23,17,22,17,16,16,18,20,16,20,22,17,23,21,17,21,19,24,26,27,24,27,25,26,28,29,26,29,27,28,30,31,28,31,29,30,24,25,30,25,31,24,30,28,24,28,26,25,27,29,25,29,31,32,34,35,32,35,33,34,36,37,34,37,35,36,38,39,36,39,37,38,32,33,38,33,39,32,38,36,32,36,34,33,35,37,33,37,39,40,42,43,40,43,41,42,44,45,42,45,43,44,46,47,44,47,45,46,40,41,46,41,47,40,46,44,40,44,42,41,43,45,41,45,47,48,49,51,48,51,50,50,51,53,50,53,52,52,53,55,52,55,54,54,55,49,54,49,48,48,50,52,48,52,54,49,55,53,49,53,51,56,57,59,56,59,58,58,59,61,58,61,60,60,61,63,60,63,62,62,63,57,62,57,56,56,58,60,56,60,62,57,63,61,57,61,59,64,65,67,64,67,66,66,67,69,66,69,68,68,69,71,68,71,70,70,71,65,70,65,64,64,66,68,64,68,70,65,71,69,65,69,67,75,74,73,75,73,72,77,76,75,77,75,72,77,72,73,77,73,80,78,77,79,79,77,80,74,81,80,74,80,73,81,74,75,81,75,76,82,81,76,82,76,83,78,83,76,78,76,77,78,79,82,78,82,83,82,79,80,82,80,81,86,85,84,86,84,89,87,86,89,87,89,88,84,91,90,84,90,89,84,85,92,84,92,91,86,93,92,86,92,85,87,94,93,87,93,86,95,94,87,95,87,88,89,90,95,89,95,88,90,91,92,90,92,93,95,90,94,94,90,93,102,101,100,102,100,99,103,102,99,97,96,103,97,103,98,98,103,99,96,105,104,96,104,103,108,107,106,108,106,105,97,108,105,97,105,96,97,98,109,97,109,108,98,99,110,98,110,109,99,100,111,99,111,110,114,113,112,114,112,111,101,114,100,100,114,111,102,115,114,102,114,101,103,104,115,103,115,102,114,115,104,114,104,105,114,105,106,114,106,113,106,107,112,106,112,113,112,107,108,112,108,109,112,109,110,112,110,111,164,166,167,164,167,165,166,168,169,166,169,167,168,170,171,168,171,169,170,164,165,170,165,171,164,170,168,164,168,166,165,167,169,165,169,171,172,174,175,172,175,173,174,176,177,174,177,175,176,178,179,176,179,177,178,172,173,178,173,179,172,178,176,172,176,174,173,175,177,173,177,179,180,182,183,180,183,181,182,184,185,182,185,183,184,186,187,184,187,185,186,188,189,186,189,187,188,190,191,188,191,189,190,180,181,190,181,191,180,190,188,180,188,186,180,186,184,180,184,182,181,183,185,181,185,187,181,187,189,181,189,191,192,194,195,192,195,193,194,196,197,194,197,195,196,198,199,196,199,197,198,200,201,198,201,199,200,202,203,200,203,201,202,192,193,202,193,203,192,202,200,192,200,198,192,198,196,192,196,194,193,195,197,193,197,199,193,199,201,193,201,203,204,210,208,204,208,206,205,207,209,205,209,211]},{"mesh_id":5,"coordinates":[10.4292893215,8.4292893217,2.5535533908,10.4999999997,8.4999999997,2.6242640689,10.4999999997,-0.5000000002,2.6242640689,10.4292893215,-0.429289322,2.5535533908,10.2878679652,-0.2878679658,2.4121320349,10.2878679652,8.2878679657,2.4121320349,-0.4292893221,8.4292893216,2.5535533907,-0.5000000002,8.4999999997,2.6242640689,5.9999999996,3.9999999994,7.124264069,-0.5000000002,-0.5000000002,2.6242640689,-0.4292893221,-0.429289322,2.5535533907,-0.287867966,-0.2878679659,2.4121320345,5.9999999994,3.999999999,6.7000000007,-0.287867966,8.2878679655,2.4121320345,3.9999999996,3.9999999994,7.1242640687,3.9999999997,3.9999999997,6.7000000003],"indices":[3,0,1,3,1,2,0,3,4,0,4,5,0,6,7,0,7,1,2,1,8,10,3,2,10,2,9,3,10,11,3,11,4,4,12,5,6,0,5,6,5,13,6,10,9,6,9,7,14,8,1,14,1,7,9,2,8,9,8,14,10,6,13,10,13,11,15,12,4,15,4,11,13,5,12,13,12,15,7,9,14,11,13,15]},{"mesh_id":6,"coordinates":[2.2466552997,0.2999999999,0.1,2.2466552997,0.2999999999,0.0,0.25,0.3,0.0,0.25,0.3,3.0,9.7,0.2999999999,3.0,9.7,0.2999999999,0.0,3.1466552997,0.3,0.0,3.1466552997,0.2999999999,0.1,3.1466552997,0.3,2.2,2.2466552997,0.3,2.2,6.0452122769,0.2999999999,2.2115036285,5.1452122769,0.2999999999,2.2115036285,5.1452122769,0.2999999999,0.7115036285,6.0452122769,0.2999999999,0.7115036285,2.2466552997,0.0,2.2,2.2466552997,0.0,0.1,2.2466552997,0.25,0.1,2.2466552997,0.25,0.0,0.25,0.25,0.0,0.25,0.25,3.0,9.7,0.25,3.0,9.7,0.25,0.0,3.1466552997,0.25,0.0,3.1466552997,0.25,0.1,3.1466552997,0.0,0.1,3.1466552997,0.0,2.2,6.0452122769,-0.0,0.7115036285,6.0452122769,-0.0,2.2115036285,5.1452122769,-0.0,2.2115036285,5.1452122769,-0.0,0.7115036285,3.1466552997,0.0,0.0,9.75,0.0,0.0,9.75,0.0,3.0,0.0,0.0,3.0,0.0,0.0,0.0,2.2466552997,0.0,0.0,0.0,0.25,0.0,0.0,0.25,3.0,9.75,0.25,3.0,9.75,0.25,0.0],"indices":[10,11,3,10,3,4,8,9,11,3,11,9,8,11,12,13,10,4,2,3,9,2,9,1,6,8,12,6,12,5,5,12,13,5,13,4,0,9,14,0,14,15,0,15,16,0,16,17,0,17,1,2,1,17,2,17,18,3,2,18,3,18,19,4,3,19,4,19,20,5,4,20,5,20,21,6,5,21,6,21,22,23,7,6,23,6,22,8,7,23,8,23,24,8,24,25,9,8,25,9,25,14,13,26,27,13,27,10,10,27,28,10,28,11,11,28,29,11,29,12,12,29,26,12,26,13,28,27,32,28,32,33,14,25,28,14,28,33,32,27,26,29,28,25,31,32,26,31,26,30,30,26,29,30,29,25,35,14,34,34,14,33,16,15,35,16,35,17,36,18,17,36,17,35,36,35,34,36,37,19,36,19,18,20,19,37,20,37,33,20,33,32,20,32,38,38,39,21,38,21,20,30,22,21,30,21,39,30,39,31,24,23,22,24,22,30,31,39,38,31,38,32,34,33,37,34,37,36]},{"mesh_id":7,"coordinates":[5.1702122769,0.025,2.1615036285,5.1952122769,0.025,2.1615036285,5.1952122769,0.05,2.1615036285,5.1452122769,0.05,2.1615036285,5.1452122769,0.0,2.1615036285,5.1702122769,0.0,2.1615036285,5.1702122769,0.0,0.7615036285,5.1702122769,0.025,0.7615036285,5.1952122769,0.025,0.7615036285,5.1952122769,0.05,0.7615036285,5.1452122769,0.05,0.7615036285,5.1452122769,0.0,0.7615036285,6.0202122769,0.025,2.1615036285,6.0202122769,0.0,2.1615036285,6.0452122769,0.0,2.1615036285,6.0452122769,0.05,2.1615036285,5.9952122769,0.05,2.1615036285,5.9952122769,0.025,2.1615036285,5.9952122769,0.025,0.7615036285,6.0202122769,0.025,0.7615036285,6.0202122769,0.0,0.7615036285,6.0452122769,0.0,0.7615036285,6.0452122769,0.05,0.7615036285,5.9952122769,0.05,0.7615036285,6.0202122769,0.025,0.7615036285,6.0202122769,0.0,0.7615036285,6.0452122769,0.0,0.7615036285,6.0452122769,0.05,0.7615036285,5.9952122769,0.05,0.7615036285,5.9952122769,0.025,0.7615036285,5.1952122769,0.025,0.7615036285,5.1702122769,0.025,0.7615036285,5.1702122769,0.025,0.7365036285,6.0202122769,0.025,0.7365036285,6.0202122769,0.0,0.7365036285,5.1702122769,0.0,0.7615036285,5.1452122769,0.0,0.7615036285,5.1452122769,0.0,0.7115036285,6.0452122769,0.0,0.7115036285,5.1702122769,0.0,0.7365036285,6.0452122769,0.05,0.7115036285,5.1952122769,0.05,0.7615036285,5.1452122769,0.05,0.7115036285,5.1452122769,0.05,0.7615036285,5.1702122769,0.0,2.1865036285,6.0202122769,0.0,2.1865036285,6.0202122769,0.0,2.1615036285,6.0452122769,0.0,2.1615036285,6.0452122769,0.0,2.2115036285,5.1452122769,0.0,2.2115036285,5.1452122769,0.0,2.1615036285,5.1702122769,0.0,2.1615036285,5.1702122769,0.025,2.1615036285,5.1702122769,0.025,2.1865036285,6.0202122769,0.025,2.1865036285,6.0202122769,0.025,2.1615036285,5.9952122769,0.025,2.1615036285,5.9952122769,0.05,2.1615036285,6.0452122769,0.05,2.1615036285,6.0452122769,0.05,2.2115036285,5.1452122769,0.05,2.2115036285,5.1452122769,0.05,2.1615036285,5.1952122769,0.05,2.1615036285,5.1952122769,0.025,2.1615036285,5.2202122769,0.025,2.1365036285,5.2202122769,-0.0249999999,2.1365036285,5.1702122769,0.025,2.1365036285,5.1702122769,-0.0249999999,2.1365036285,5.1702122769,0.025,0.7865036285,5.1702122769,-0.0249999999,0.7865036285,5.2202122769,0.025,0.7865036285,5.2202122769,-0.0249999999,0.7865036285,5.9702122769,0.025,0.7865036285,5.9702122769,-0.0249999999,0.7865036285,6.0202122769,0.025,0.7865036285,6.0202122769,-0.0249999999,0.7865036285,6.0202122769,0.025,2.1365036285,6.0202122769,-0.0249999999,2.1365036285,5.9702122769,0.025,2.1365036285,5.9702122769,-0.0249999999,2.1365036285,6.0202122769,0.025,0.7365036285,6.0202122769,-0.0249999999,0.7365036285,6.0202122769,0.025,0.7865036285,6.0202122769,-0.0249999999,0.7865036285,5.9702122769,0.025,0.7865036285,5.9702122769,-0.0249999999,0.7865036285,5.2202122769,0.025,0.7865036285,5.2202122769,-0.0249999999,0.7865036285,5.1702122769,0.025,0.7865036285,5.1702122769,-0.0249999999,0.7865036285,5.1702122769,0.025,0.7365036285,5.1702122769,-0.0249999999,0.7365036285,5.1702122769,0.025,2.1865036285,5.1702122769,-0.0249999999,2.1865036285,5.1702122769,0.025,2.1365036285,5.1702122769,-0.0249999999,2.1365036285,5.2202122769,0.025,2.1365036285,5.2202122769,-0.0249999999,2.1365036285,5.9702122769,0.025,2.1365036285,5.9702122769,-0.0249999999,2.1365036285,6.0202122769,0.025,2.1365036285,6.0202122769,-0.0249999999,2.1365036285,6.0202122769,0.025,2.1865036285,6.0202122769,-0.0249999999,2.1865036285,5.2202122769,0.01,0.7865036285,5.2202122769,-0.0099999999,0.7865036285,5.9702122769,0.01,0.7865036285,5.9702122769,-0.0099999999,0.7865036285,5.9702122769,0.01,2.1365036285,5.9702122769,-0.0099999999,2.1365036285,5.2202122769,0.01,2.1365036285,5.2202122769,-0.0099999999,2.1365036285,6.0202122769,0.025,0.7365036285,5.1702122769,0.025,1.4615036285,6.0202122769,0.025,2.1865036285,5.1702122769,0.025,1.4615036285,6.0202122769,-0.0249999999,0.7365036285,5.9593455607,-0.0249999999,0.788419357,5.9213038631,-0.0249999999,0.8208666873,5.8604371469,-0.0249999999,0.8727824157,5.8223954493,-0.0249999999,0.9052297461,5.7615287332,-0.0249999999,0.9571454745,5.7234870356,-0.0249999999,0.9895928048,5.6626203194,-0.0249999999,1.0415085333,5.6245786218,-0.0249999999,1.0739558636,5.5637119057,-0.0249999999,1.1258715921,5.5256702081,-0.0249999999,1.1583189224,5.4648034919,-0.0249999999,1.2102346509,5.4267617943,-0.0249999999,1.2426819812,5.3658950782,-0.0249999999,1.2945977097,5.3278533806,-0.0249999999,1.32704504,5.2669866644,-0.0249999999,1.3789607685,5.231078993,-0.0249999999,1.4095879,5.1702122769,-0.0249999999,1.4615036285,6.0202122769,-0.0249999999,2.1865036285,5.9593455607,-0.0249999999,2.1345879,5.9213038631,-0.0249999999,2.1021405697,5.8604371469,-0.0249999999,2.0502248412,5.8223954493,-0.0249999999,2.0177775109,5.7615287332,-0.0249999999,1.9658617824,5.7234870356,-0.0249999999,1.9334144521,5.6626203194,-0.0249999999,1.8814987236,5.6245786218,-0.0249999999,1.8490513933,5.5637119057,-0.0249999999,1.7971356648,5.5256702081,-0.0249999999,1.7646883345,5.4648034919,-0.0249999999,1.712772606,5.4267617943,-0.0249999999,1.6803252757,5.3658950782,-0.0249999999,1.6284095472,5.3278533806,-0.0249999999,1.5959622169,5.2669866644,-0.0249999999,1.5440464884,5.231078993,-0.0249999999,1.513419357,5.1702122769,-0.0249999999,1.4615036285],"indices":[0,1,2,0,2,3,5,0,4,4,0,3,0,5,6,0,6,7,8,1,0,8,0,7,1,8,9,1,9,2,3,2,9,3,9,10,4,3,10,4,10,11,6,5,4,6,4,11,10,9,8,10,8,7,11,10,7,11,7,6,15,16,17,15,17,12,14,15,12,14,12,13,12,17,18,12,18,19,20,13,12,20,12,19,13,20,21,13,21,14,21,22,15,21,15,14,22,23,16,22,16,15,18,17,16,18,16,23,19,18,23,19,23,22,20,19,21,21,19,22,27,28,29,27,29,24,26,27,24,26,24,25,24,29,30,24,30,31,24,31,32,24,32,33,34,25,24,34,24,33,38,26,25,38,25,34,38,34,39,37,38,39,37,39,36,36,39,35,38,40,27,38,27,26,43,41,28,43,28,27,43,27,40,43,40,42,30,29,28,30,28,41,31,30,41,31,41,43,35,31,36,36,31,43,31,35,39,31,39,32,39,34,33,39,33,32,36,43,42,36,42,37,37,42,40,37,40,38,45,46,47,45,47,48,44,45,48,50,51,44,50,44,49,49,44,48,44,51,52,44,52,53,45,44,53,45,53,54,46,45,54,46,54,55,55,56,57,55,57,58,46,55,47,47,55,58,47,58,59,47,59,48,48,59,60,48,60,49,49,60,61,49,61,50,61,62,63,61,63,52,50,61,52,50,52,51,56,55,54,56,54,53,56,53,52,56,52,63,56,63,62,56,62,57,58,57,62,58,62,61,58,61,60,58,60,59,64,66,67,64,67,65,66,68,69,66,69,67,68,70,71,68,71,69,70,64,65,70,65,71,64,70,68,64,68,66,65,67,69,65,69,71,72,74,75,72,75,73,74,76,77,74,77,75,76,78,79,76,79,77,78,72,73,78,73,79,72,78,76,72,76,74,73,75,77,73,77,79,80,82,83,80,83,81,82,84,85,82,85,83,84,86,87,84,87,85,86,88,89,86,89,87,88,90,91,88,91,89,90,80,81,90,81,91,80,90,88,80,88,86,80,86,84,80,84,82,81,83,85,81,85,87,81,87,89,81,89,91,92,94,95,92,95,93,94,96,97,94,97,95,96,98,99,96,99,97,98,100,101,98,101,99,100,102,103,100,103,101,102,92,93,102,93,103,92,102,100,92,100,98,92,98,96,92,96,94,93,95,97,93,97,99,93,99,101,93,101,103,104,110,108,104,108,106,105,107,109,105,109,111]}],"elements":[{"mesh_id":0,"vector":{"x":0.0,"y":0.0,"z":0.0},"rotation":{"qx":0.0,"qy":0.0,"qz":0.0,"qw":1.0},"color":{"r":200,"g":200,"b":200,"a":255},"face_colors":[168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255],"guid":"F277F65E-9EBE-4595-9CC8-A32A19E36552","type":"Wall","info":{"ID":"SW - 001","Position":"Undefined","Renovation Status":"New","Show On Renovation Filter":"All Relevant Filters","Structural Function":"Undefined","Fire Resistance Rating (GENERAL RATINGS)":"","Combustible (GENERAL RATINGS)":"","Thermal Transmittance (GENERAL RATINGS)":"","Sound Transmission Class (GENERAL RATINGS)":"","Construction Type (MAIN CONSTRUCTION)":"","Technology (MAIN CONSTRUCTION)":"","Concrete Cover at Main Bars (MAIN CONSTRUCTION)":"","Lifting Weight (MAIN CONSTRUCTION)":"","Life Cycle Environmental (ENVIRONMENTAL)":"","Environmental Class (ENVIRONMENTAL)":"","Service Life (ENVIRONMENTAL)":"","Stored Energy (ENVIRONMENTAL)":"","Brick type and measures (NUMBER OF BRICKS (Expression))":"","Brick H size (NUMBER OF BRICKS (Expression))":"","Brick W size (NUMBER OF BRICKS (Expression))":"","Brick L size (NUMBER OF BRICKS (Expression))":"","Mortar thickness (NUMBER OF BRICKS (Expression))":"","Brick volume (NUMBER OF BRICKS (Expression))":"","No. of bricks to purchase (NUMBER OF BRICKS (Expression))":"","Sub Ceiling thickness (SUSPENDED CEILING LEVEL (Expression))":"","Sub Floor Thickness (SUSPENDED CEILING LEVEL (Expression))":"","Suspended Ceiling level (SUSPENDED CEILING LEVEL (Expression))":"","Raised Floor Level (SUSPENDED CEILING LEVEL (Expression))":"","Interior height (SUSPENDED CEILING LEVEL (Expression))":"","Interior height detailed (SUSPENDED CEILING LEVEL (Expression))":"","Cost Per Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (USD) (COST OF STRUCTURE (Expression))":"","Total Cost of Volume ($) (COST OF STRUCTURE (Expression))":"","Dynamic ID by Classification (PRODUCT DESCRIPTION (Expression))":"Wall - 001","Classification ID (PRODUCT DESCRIPTION (Expression))":"Wall","Classification Name (PRODUCT DESCRIPTION (Expression))":"Wall","Strength Grade (STRUCTURAL ANALYSIS DATA)":""}},{"mesh_id":1,"vector":{"x":0.0,"y":0.0,"z":0.0},"rotation":{"qx":0.0,"qy":0.0,"qz":0.0,"qw":1.0},"color":{"r":200,"g":200,"b":200,"a":255},"face_colors":[168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255],"guid":"5CD0E206-FAE0-42D1-BA44-C5A4399C0B3E","type":"Wall","info":{"ID":"SW - 002","Position":"Undefined","Renovation Status":"New","Show On Renovation Filter":"All Relevant Filters","Structural Function":"Undefined","Fire Resistance Rating (GENERAL RATINGS)":"","Combustible (GENERAL RATINGS)":"","Thermal Transmittance (GENERAL RATINGS)":"","Sound Transmission Class (GENERAL RATINGS)":"","Construction Type (MAIN CONSTRUCTION)":"","Technology (MAIN CONSTRUCTION)":"","Concrete Cover at Main Bars (MAIN CONSTRUCTION)":"","Lifting Weight (MAIN CONSTRUCTION)":"","Life Cycle Environmental (ENVIRONMENTAL)":"","Environmental Class (ENVIRONMENTAL)":"","Service Life (ENVIRONMENTAL)":"","Stored Energy (ENVIRONMENTAL)":"","Brick type and measures (NUMBER OF BRICKS (Expression))":"","Brick H size (NUMBER OF BRICKS (Expression))":"","Brick W size (NUMBER OF BRICKS (Expression))":"","Brick L size (NUMBER OF BRICKS (Expression))":"","Mortar thickness (NUMBER OF BRICKS (Expression))":"","Brick volume (NUMBER OF BRICKS (Expression))":"","No. of bricks to purchase (NUMBER OF BRICKS (Expression))":"","Sub Ceiling thickness (SUSPENDED CEILING LEVEL (Expression))":"","Sub Floor Thickness (SUSPENDED CEILING LEVEL (Expression))":"","Suspended Ceiling level (SUSPENDED CEILING LEVEL (Expression))":"","Raised Floor Level (SUSPENDED CEILING LEVEL (Expression))":"","Interior height (SUSPENDED CEILING LEVEL (Expression))":"","Interior height detailed (SUSPENDED CEILING LEVEL (Expression))":"","Cost Per Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (USD) (COST OF STRUCTURE (Expression))":"","Total Cost of Volume ($) (COST OF STRUCTURE (Expression))":"","Dynamic ID by Classification (PRODUCT DESCRIPTION (Expression))":"Wall - 002","Classification ID (PRODUCT DESCRIPTION (Expression))":"Wall","Classification Name (PRODUCT DESCRIPTION (Expression))":"Wall","Strength Grade (STRUCTURAL ANALYSIS DATA)":""}},{"mesh_id":2,"vector":{"x":0.0,"y":0.0,"z":0.0},"rotation":{"qx":0.0,"qy":0.0,"qz":0.0,"qw":1.0},"color":{"r":200,"g":200,"b":200,"a":255},"face_colors":[168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,211,199,171,255,211,199,171,255],"guid":"2159AD82-6835-45B9-9C09-1056861D08BC","type":"Wall","info":{"ID":"SW - 004","Position":"Undefined","Renovation Status":"New","Show On Renovation Filter":"All Relevant Filters","Structural Function":"Undefined","Fire Resistance Rating (GENERAL RATINGS)":"","Combustible (GENERAL RATINGS)":"","Thermal Transmittance (GENERAL RATINGS)":"","Sound Transmission Class (GENERAL RATINGS)":"","Construction Type (MAIN CONSTRUCTION)":"","Technology (MAIN CONSTRUCTION)":"","Concrete Cover at Main Bars (MAIN CONSTRUCTION)":"","Lifting Weight (MAIN CONSTRUCTION)":"","Life Cycle Environmental (ENVIRONMENTAL)":"","Environmental Class (ENVIRONMENTAL)":"","Service Life (ENVIRONMENTAL)":"","Stored Energy (ENVIRONMENTAL)":"","Brick type and measures (NUMBER OF BRICKS (Expression))":"","Brick H size (NUMBER OF BRICKS (Expression))":"","Brick W size (NUMBER OF BRICKS (Expression))":"","Brick L size (NUMBER OF BRICKS (Expression))":"","Mortar thickness (NUMBER OF BRICKS (Expression))":"","Brick volume (NUMBER OF BRICKS (Expression))":"","No. of bricks to purchase (NUMBER OF BRICKS (Expression))":"","Sub Ceiling thickness (SUSPENDED CEILING LEVEL (Expression))":"","Sub Floor Thickness (SUSPENDED CEILING LEVEL (Expression))":"","Suspended Ceiling level (SUSPENDED CEILING LEVEL (Expression))":"","Raised Floor Level (SUSPENDED CEILING LEVEL (Expression))":"","Interior height (SUSPENDED CEILING LEVEL (Expression))":"","Interior height detailed (SUSPENDED CEILING LEVEL (Expression))":"","Cost Per Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (USD) (COST OF STRUCTURE (Expression))":"","Total Cost of Volume ($) (COST OF STRUCTURE (Expression))":"","Dynamic ID by Classification (PRODUCT DESCRIPTION (Expression))":"Wall - 004","Classification ID (PRODUCT DESCRIPTION (Expression))":"Wall","Classification Name (PRODUCT DESCRIPTION (Expression))":"Wall","Strength Grade (STRUCTURAL ANALYSIS DATA)":""}},{"mesh_id":3,"vector":{"x":0.0,"y":0.0,"z":0.0},"rotation":{"qx":0.0,"qy":0.0,"qz":0.0,"qw":1.0},"color":{"r":200,"g":200,"b":200,"a":255},"face_colors":[204,140,50,255,204,140,50,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,204,140,50,255,168,168,168,255,168,168,168,255],"guid":"2AD6083A-FC61-4190-AAE6-F0E5316E96ED","type":"Slab","info":{"ID":"SLA - 001","Position":"Undefined","Renovation Status":"New","Show On Renovation Filter":"All Relevant Filters","Structural Function":"Undefined","Fire Resistance Rating (GENERAL RATINGS)":"","Combustible (GENERAL RATINGS)":"","Thermal Transmittance (GENERAL RATINGS)":"","Sound Transmission Class (GENERAL RATINGS)":"","Construction Type (MAIN CONSTRUCTION)":"","Technology (MAIN CONSTRUCTION)":"","Concrete Cover at Main Bars (MAIN CONSTRUCTION)":"","Class of Surface (MAIN CONSTRUCTION)":"","Lifting Weight (MAIN CONSTRUCTION)":"","Life Cycle Environmental (ENVIRONMENTAL)":"","Environmental Class (ENVIRONMENTAL)":"","Service Life (ENVIRONMENTAL)":"","Stored Energy (ENVIRONMENTAL)":"","Fragility rating (FLOORINGS)":"","Tile dimensions (FLOORINGS)":"","Anti-static Surface (FLOORINGS)":"","Non-skid Surface (FLOORINGS)":"","Cost Per Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (USD) (COST OF STRUCTURE (Expression))":"","Total Cost of Volume ($) (COST OF STRUCTURE (Expression))":"","Dynamic ID by Classification (PRODUCT DESCRIPTION (Expression))":"Slab - 001","Classification ID (PRODUCT DESCRIPTION (Expression))":"Slab","Classification Name (PRODUCT DESCRIPTION (Expression))":"Slab","Strength Grade (STRUCTURAL ANALYSIS DATA)":""}},{"mesh_id":4,"vector":{"x":0.0,"y":0.0,"z":0.0},"rotation":{"qx":0.0,"qy":0.0,"qz":0.0,"qw":1.0},"color":{"r":200,"g":200,"b":200,"a":255},"face_colors":[218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,240,247,243,79,240,247,243,79,240,247,243,79,240,247,243,79],"guid":"5CA2E551-F8FF-49FE-8CEA-FF10BC9D3CB0","type":"Door","info":{"ID":"DOO - 001","Position":"Undefined","Renovation Status":"New","Show On Renovation Filter":"All Relevant Filters","Structural Function":"Undefined","Fire Resistance Rating (GENERAL RATINGS)":"","Combustible (GENERAL RATINGS)":"","Thermal Transmittance (GENERAL RATINGS)":"","Sound Transmission Class (GENERAL RATINGS)":"","Model (PRODUCT INFO)":"","Serial No. (PRODUCT INFO)":"","Barcode (PRODUCT INFO)":"","Acquisition Date (PRODUCT INFO)":"","Purchase Price (PRODUCT INFO)":"","Manufacturer (MANUFACTURING)":"","Production Date (MANUFACTURING)":"","Country of Origin (MANUFACTURING)":"","Product Website (MANUFACTURING)":"www.graphisoft.com","Life Cycle Environmental (ENVIRONMENTAL)":"","Environmental Class (ENVIRONMENTAL)":"","Service Life (ENVIRONMENTAL)":"","Stored Energy (ENVIRONMENTAL)":"","Fire Exit (OPENINGS)":"","Handicap Accessible (OPENINGS)":"","Self Closing (OPENINGS)":"","Smoke Stop (OPENINGS)":"","Security Rating (OPENINGS)":"","Coated (GLAZING)":"","Laminated (GLAZING)":"","Tempered (GLAZING)":"","Wired (GLAZING)":"","Context ID (PRODUCT DESCRIPTION (Expression))":"","Dynamic ID by Classification (PRODUCT DESCRIPTION (Expression))":"Door - 001","Hotlinked Door Context ID (PRODUCT DESCRIPTION (Expression))":" 001","Stair Subelements - Numerical IDs (PRODUCT DESCRIPTION (Expression))":" 001","Classification ID (PRODUCT DESCRIPTION (Expression))":"Door","Classification Name (PRODUCT DESCRIPTION (Expression))":"Door","Strength Grade (STRUCTURAL ANALYSIS DATA)":""}},{"mesh_id":5,"vector":{"x":0.0,"y":0.0,"z":0.0},"rotation":{"qx":0.0,"qy":0.0,"qz":0.0,"qw":1.0},"color":{"r":200,"g":200,"b":200,"a":255},"face_colors":[254,180,135,255,254,180,135,255,168,168,168,255,168,168,168,255,254,180,135,255,254,180,135,255,254,180,135,255,254,180,135,255,254,180,135,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,254,180,135,255,254,180,135,255,254,180,135,255,254,180,135,255,254,180,135,255,254,180,135,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,254,180,135,255,168,168,168,255],"guid":"59728024-B6D3-449E-884E-76C54A1E512B","type":"Roof","info":{"ID":"RT - 001","Position":"Undefined","Renovation Status":"New","Show On Renovation Filter":"All Relevant Filters","Structural Function":"Undefined","Fire Resistance Rating (GENERAL RATINGS)":"","Combustible (GENERAL RATINGS)":"","Thermal Transmittance (GENERAL RATINGS)":"","Sound Transmission Class (GENERAL RATINGS)":"","Construction Type (MAIN CONSTRUCTION)":"","Technology (MAIN CONSTRUCTION)":"","Concrete Cover at Main Bars (MAIN CONSTRUCTION)":"","Lifting Weight (MAIN CONSTRUCTION)":"","Life Cycle Environmental (ENVIRONMENTAL)":"","Environmental Class (ENVIRONMENTAL)":"","Service Life (ENVIRONMENTAL)":"","Stored Energy (ENVIRONMENTAL)":"","Dynamic ID by Classification (PRODUCT DESCRIPTION (Expression))":"Roof - 001","Classification ID (PRODUCT DESCRIPTION (Expression))":"Roof","Classification Name (PRODUCT DESCRIPTION (Expression))":"Roof","Strength Grade (STRUCTURAL ANALYSIS DATA)":""}},{"mesh_id":6,"vector":{"x":0.0,"y":0.0,"z":0.0},"rotation":{"qx":0.0,"qy":0.0,"qz":0.0,"qw":1.0},"color":{"r":200,"g":200,"b":200,"a":255},"face_colors":[211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,211,199,171,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255,168,168,168,255],"guid":"745BB805-A3B4-4461-AC8A-EA83556B473A","type":"Wall","info":{"ID":"SW - 003","Position":"Undefined","Renovation Status":"New","Show On Renovation Filter":"All Relevant Filters","Structural Function":"Undefined","Fire Resistance Rating (GENERAL RATINGS)":"","Combustible (GENERAL RATINGS)":"","Thermal Transmittance (GENERAL RATINGS)":"","Sound Transmission Class (GENERAL RATINGS)":"","Construction Type (MAIN CONSTRUCTION)":"","Technology (MAIN CONSTRUCTION)":"","Concrete Cover at Main Bars (MAIN CONSTRUCTION)":"","Lifting Weight (MAIN CONSTRUCTION)":"","Life Cycle Environmental (ENVIRONMENTAL)":"","Environmental Class (ENVIRONMENTAL)":"","Service Life (ENVIRONMENTAL)":"","Stored Energy (ENVIRONMENTAL)":"","Brick type and measures (NUMBER OF BRICKS (Expression))":"","Brick H size (NUMBER OF BRICKS (Expression))":"","Brick W size (NUMBER OF BRICKS (Expression))":"","Brick L size (NUMBER OF BRICKS (Expression))":"","Mortar thickness (NUMBER OF BRICKS (Expression))":"","Brick volume (NUMBER OF BRICKS (Expression))":"","No. of bricks to purchase (NUMBER OF BRICKS (Expression))":"","Sub Ceiling thickness (SUSPENDED CEILING LEVEL (Expression))":"","Sub Floor Thickness (SUSPENDED CEILING LEVEL (Expression))":"","Suspended Ceiling level (SUSPENDED CEILING LEVEL (Expression))":"","Raised Floor Level (SUSPENDED CEILING LEVEL (Expression))":"","Interior height (SUSPENDED CEILING LEVEL (Expression))":"","Interior height detailed (SUSPENDED CEILING LEVEL (Expression))":"","Cost Per Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (COST OF STRUCTURE (Expression))":"","Total Cost of Volume (USD) (COST OF STRUCTURE (Expression))":"","Total Cost of Volume ($) (COST OF STRUCTURE (Expression))":"","Dynamic ID by Classification (PRODUCT DESCRIPTION (Expression))":"Wall - 003","Classification ID (PRODUCT DESCRIPTION (Expression))":"Wall","Classification Name (PRODUCT DESCRIPTION (Expression))":"Wall","Strength Grade (STRUCTURAL ANALYSIS DATA)":""}},{"mesh_id":7,"vector":{"x":0.0,"y":0.0,"z":0.0},"rotation":{"qx":0.0,"qy":0.0,"qz":0.0,"qw":1.0},"color":{"r":200,"g":200,"b":200,"a":255},"face_colors":[218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,218,202,173,255,240,247,243,79,240,247,243,79,240,247,243,79,240,247,243,79],"guid":"95781538-89E9-474A-9834-6CBDE1D1D4D8","type":"Window","info":{"ID":"WD - 001","Position":"Undefined","Renovation Status":"New","Show On Renovation Filter":"All Relevant Filters","Structural Function":"Undefined","Fire Resistance Rating (GENERAL RATINGS)":"","Combustible (GENERAL RATINGS)":"","Thermal Transmittance (GENERAL RATINGS)":"","Sound Transmission Class (GENERAL RATINGS)":"","Model (PRODUCT INFO)":"","Serial No. (PRODUCT INFO)":"","Barcode (PRODUCT INFO)":"","Acquisition Date (PRODUCT INFO)":"","Purchase Price (PRODUCT INFO)":"","Manufacturer (MANUFACTURING)":"","Production Date (MANUFACTURING)":"","Country of Origin (MANUFACTURING)":"","Product Website (MANUFACTURING)":"www.graphisoft.com","Life Cycle Environmental (ENVIRONMENTAL)":"","Environmental Class (ENVIRONMENTAL)":"","Service Life (ENVIRONMENTAL)":"","Stored Energy (ENVIRONMENTAL)":"","Fire Exit (OPENINGS)":"","Self Closing (OPENINGS)":"","Smoke Stop (OPENINGS)":"","Security Rating (OPENINGS)":"","Coated (GLAZING)":"","Laminated (GLAZING)":"","Tempered (GLAZING)":"","Wired (GLAZING)":"","Context ID (PRODUCT DESCRIPTION (Expression))":"","Dynamic ID by Classification (PRODUCT DESCRIPTION (Expression))":"Window - 001","Hotlinked Door Context ID (PRODUCT DESCRIPTION (Expression))":" 001","Stair Subelements - Numerical IDs (PRODUCT DESCRIPTION (Expression))":" 001","Classification ID (PRODUCT DESCRIPTION (Expression))":"Window","Classification Name (PRODUCT DESCRIPTION (Expression))":"Window","Strength Grade (STRUCTURAL ANALYSIS DATA)":""}}],"info":{"Project Name":"Untitled","Generated By":"https://github.com/kovacsv/dotbim-archicad"}} -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_files/Pyramid.bim: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "1.0.0", 3 | "meshes": [ 4 | { 5 | "mesh_id": 0, 6 | "coordinates": [ 7 | 0.0, 8 | 0.0, 9 | 0.0, 10 | 10.0, 11 | 0.0, 12 | 0.0, 13 | 10.0, 14 | 10.0, 15 | 0.0, 16 | 0.0, 17 | 10.0, 18 | 0.0, 19 | 5.0, 20 | 5.0, 21 | 4.0 22 | ], 23 | "indices": [ 24 | 0, 25 | 1, 26 | 2, 27 | 0, 28 | 2, 29 | 3, 30 | 0, 31 | 1, 32 | 4, 33 | 1, 34 | 2, 35 | 4, 36 | 2, 37 | 3, 38 | 4, 39 | 3, 40 | 0, 41 | 4 42 | ] 43 | } 44 | ], 45 | "elements": [ 46 | { 47 | "info": { 48 | "Name": "Pyramid" 49 | }, 50 | "color": { 51 | "r": 255, 52 | "g": 255, 53 | "b": 0, 54 | "a": 255 55 | }, 56 | "guid": "76e051c1-1bd7-44fc-8e2e-db2b64055068", 57 | "rotation": { 58 | "qx": 0, 59 | "qy": 0, 60 | "qz": 0, 61 | "qw": 1.0 62 | }, 63 | "vector": { 64 | "x": 0, 65 | "y": 0, 66 | "z": 0 67 | }, 68 | "type": "Structure", 69 | "mesh_id": 0 70 | } 71 | ], 72 | "info": { 73 | "Author": "John Doe", 74 | "Date": "28.09.1999" 75 | } 76 | } -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_files/WallsWithBeams.bim: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "1.0.0", 3 | "meshes": [ 4 | { 5 | "mesh_id": 0, 6 | "coordinates": [ 7 | 0.1, 8 | 0.0, 9 | 0.15, 10 | 0.1, 11 | -6.0, 12 | 0.15, 13 | -0.1, 14 | 0.0, 15 | 0.15, 16 | -0.1, 17 | -6.0, 18 | 0.15, 19 | 0.1, 20 | 0.0, 21 | 0.15, 22 | 0.1, 23 | -6.0, 24 | 0.15, 25 | 0.1, 26 | -6.0, 27 | 0.13999999999999999, 28 | 0.1, 29 | 0.0, 30 | 0.13999999999999999, 31 | 0.1, 32 | 0.0, 33 | 0.13999999999999999, 34 | 0.1, 35 | -6.0, 36 | 0.13999999999999999, 37 | 0.005, 38 | -6.0, 39 | 0.13999999999999999, 40 | 0.005, 41 | 0.0, 42 | 0.13999999999999999, 43 | 0.005, 44 | 0.0, 45 | 0.13999999999999999, 46 | 0.005, 47 | -6.0, 48 | 0.13999999999999999, 49 | 0.005, 50 | -6.0, 51 | -0.13999999999999999, 52 | 0.005, 53 | 0.0, 54 | -0.13999999999999999, 55 | 0.005, 56 | 0.0, 57 | -0.13999999999999999, 58 | 0.005, 59 | -6.0, 60 | -0.13999999999999999, 61 | 0.1, 62 | -6.0, 63 | -0.13999999999999999, 64 | 0.1, 65 | 0.0, 66 | -0.13999999999999999, 67 | 0.1, 68 | 0.0, 69 | -0.13999999999999999, 70 | 0.1, 71 | -6.0, 72 | -0.13999999999999999, 73 | 0.1, 74 | -6.0, 75 | -0.15, 76 | 0.1, 77 | 0.0, 78 | -0.15, 79 | 0.1, 80 | 0.0, 81 | -0.15, 82 | 0.1, 83 | -6.0, 84 | -0.15, 85 | -0.1, 86 | -6.0, 87 | -0.15, 88 | -0.1, 89 | 0.0, 90 | -0.15, 91 | -0.1, 92 | 0.0, 93 | -0.13999999999999999, 94 | -0.1, 95 | -6.0, 96 | -0.13999999999999999, 97 | -0.1, 98 | -6.0, 99 | -0.15, 100 | -0.1, 101 | 0.0, 102 | -0.15, 103 | -0.005, 104 | 0.0, 105 | -0.13999999999999999, 106 | -0.005, 107 | -6.0, 108 | -0.13999999999999999, 109 | -0.1, 110 | -6.0, 111 | -0.13999999999999999, 112 | -0.1, 113 | 0.0, 114 | -0.13999999999999999, 115 | -0.005, 116 | 0.0, 117 | 0.13999999999999999, 118 | -0.005, 119 | -6.0, 120 | 0.13999999999999999, 121 | -0.005, 122 | -6.0, 123 | -0.13999999999999999, 124 | -0.005, 125 | 0.0, 126 | -0.13999999999999999, 127 | -0.1, 128 | 0.0, 129 | 0.13999999999999999, 130 | -0.1, 131 | -6.0, 132 | 0.13999999999999999, 133 | -0.005, 134 | -6.0, 135 | 0.13999999999999999, 136 | -0.005, 137 | 0.0, 138 | 0.13999999999999999, 139 | -0.1, 140 | 0.0, 141 | 0.15, 142 | -0.1, 143 | -6.0, 144 | 0.15, 145 | -0.1, 146 | -6.0, 147 | 0.13999999999999999, 148 | -0.1, 149 | 0.0, 150 | 0.13999999999999999, 151 | 0.1, 152 | 0.0, 153 | 0.15, 154 | -0.1, 155 | 0.0, 156 | 0.15, 157 | 0.1, 158 | 0.0, 159 | 0.13999999999999999, 160 | 0.005, 161 | 0.0, 162 | 0.13999999999999999, 163 | 0.005, 164 | 0.0, 165 | -0.13999999999999999, 166 | 0.1, 167 | 0.0, 168 | -0.13999999999999999, 169 | 0.1, 170 | 0.0, 171 | -0.15, 172 | -0.1, 173 | 0.0, 174 | -0.15, 175 | -0.1, 176 | 0.0, 177 | -0.13999999999999999, 178 | -0.005, 179 | 0.0, 180 | -0.13999999999999999, 181 | -0.005, 182 | 0.0, 183 | 0.13999999999999999, 184 | -0.1, 185 | 0.0, 186 | 0.13999999999999999, 187 | 0.1, 188 | -6.0, 189 | 0.15, 190 | 0.1, 191 | -6.0, 192 | 0.13999999999999999, 193 | 0.005, 194 | -6.0, 195 | 0.13999999999999999, 196 | 0.005, 197 | -6.0, 198 | -0.13999999999999999, 199 | 0.1, 200 | -6.0, 201 | -0.13999999999999999, 202 | 0.1, 203 | -6.0, 204 | -0.15, 205 | -0.1, 206 | -6.0, 207 | -0.15, 208 | -0.1, 209 | -6.0, 210 | -0.13999999999999999, 211 | -0.005, 212 | -6.0, 213 | -0.13999999999999999, 214 | -0.005, 215 | -6.0, 216 | 0.13999999999999999, 217 | -0.1, 218 | -6.0, 219 | 0.13999999999999999, 220 | -0.1, 221 | -6.0, 222 | 0.15 223 | ], 224 | "indices": [ 225 | 0, 226 | 2, 227 | 3, 228 | 0, 229 | 3, 230 | 1, 231 | 7, 232 | 4, 233 | 5, 234 | 7, 235 | 5, 236 | 6, 237 | 11, 238 | 8, 239 | 9, 240 | 11, 241 | 9, 242 | 10, 243 | 15, 244 | 12, 245 | 13, 246 | 15, 247 | 13, 248 | 14, 249 | 19, 250 | 16, 251 | 17, 252 | 19, 253 | 17, 254 | 18, 255 | 23, 256 | 20, 257 | 21, 258 | 23, 259 | 21, 260 | 22, 261 | 27, 262 | 24, 263 | 25, 264 | 27, 265 | 25, 266 | 26, 267 | 31, 268 | 29, 269 | 28, 270 | 31, 271 | 30, 272 | 29, 273 | 35, 274 | 33, 275 | 32, 276 | 35, 277 | 34, 278 | 33, 279 | 39, 280 | 37, 281 | 36, 282 | 39, 283 | 38, 284 | 37, 285 | 43, 286 | 41, 287 | 40, 288 | 43, 289 | 42, 290 | 41, 291 | 47, 292 | 45, 293 | 44, 294 | 47, 295 | 46, 296 | 45, 297 | 57, 298 | 55, 299 | 56, 300 | 53, 301 | 54, 302 | 52, 303 | 58, 304 | 59, 305 | 49, 306 | 51, 307 | 57, 308 | 58, 309 | 51, 310 | 52, 311 | 57, 312 | 48, 313 | 50, 314 | 51, 315 | 49, 316 | 48, 317 | 51, 318 | 49, 319 | 51, 320 | 58, 321 | 54, 322 | 55, 323 | 57, 324 | 54, 325 | 57, 326 | 52, 327 | 68, 328 | 67, 329 | 66, 330 | 64, 331 | 63, 332 | 65, 333 | 69, 334 | 71, 335 | 70, 336 | 62, 337 | 69, 338 | 68, 339 | 62, 340 | 68, 341 | 63, 342 | 60, 343 | 62, 344 | 61, 345 | 65, 346 | 68, 347 | 66, 348 | 65, 349 | 63, 350 | 68, 351 | 71, 352 | 62, 353 | 60, 354 | 71, 355 | 69, 356 | 62 357 | ] 358 | }, 359 | { 360 | "mesh_id": 1, 361 | "coordinates": [ 362 | -0.09999999999999964, 363 | -0.1, 364 | -1.5, 365 | -0.09999999999999964, 366 | -0.1, 367 | 1.5, 368 | -0.09999999999999964, 369 | 0.1, 370 | -1.5, 371 | -0.09999999999999964, 372 | 0.1, 373 | 1.5, 374 | 8.1, 375 | -0.1, 376 | -1.5, 377 | 8.1, 378 | -0.1, 379 | 1.5, 380 | 8.1, 381 | 0.1, 382 | -1.5, 383 | 8.1, 384 | 0.1, 385 | 1.5, 386 | -0.09999999999999964, 387 | -0.1, 388 | -1.5, 389 | 8.1, 390 | -0.1, 391 | -1.5, 392 | -0.09999999999999964, 393 | -0.1, 394 | 1.5, 395 | 8.1, 396 | -0.1, 397 | 1.5, 398 | -0.09999999999999964, 399 | 0.1, 400 | -1.5, 401 | 8.1, 402 | 0.1, 403 | -1.5, 404 | -0.09999999999999964, 405 | 0.1, 406 | 1.5, 407 | 8.1, 408 | 0.1, 409 | 1.5, 410 | -0.09999999999999964, 411 | -0.1, 412 | -1.5, 413 | -0.09999999999999964, 414 | 0.1, 415 | -1.5, 416 | 8.1, 417 | -0.1, 418 | -1.5, 419 | 8.1, 420 | 0.1, 421 | -1.5, 422 | -0.09999999999999964, 423 | -0.1, 424 | 1.5, 425 | -0.09999999999999964, 426 | 0.1, 427 | 1.5, 428 | 8.1, 429 | -0.1, 430 | 1.5, 431 | 8.1, 432 | 0.1, 433 | 1.5 434 | ], 435 | "indices": [ 436 | 1, 437 | 2, 438 | 0, 439 | 1, 440 | 3, 441 | 2, 442 | 5, 443 | 4, 444 | 6, 445 | 5, 446 | 6, 447 | 7, 448 | 11, 449 | 8, 450 | 9, 451 | 11, 452 | 10, 453 | 8, 454 | 15, 455 | 13, 456 | 12, 457 | 15, 458 | 12, 459 | 14, 460 | 19, 461 | 16, 462 | 17, 463 | 19, 464 | 18, 465 | 16, 466 | 23, 467 | 21, 468 | 20, 469 | 23, 470 | 20, 471 | 22 472 | ] 473 | } 474 | ], 475 | "elements": [ 476 | { 477 | "info": { 478 | "Material": "Steel" 479 | }, 480 | "color": { 481 | "r": 0, 482 | "g": 0, 483 | "b": 255, 484 | "a": 255 485 | }, 486 | "guid": "5af2f96d-6d07-4453-aef1-7751deb4693e", 487 | "rotation": { 488 | "qx": 0, 489 | "qy": 0, 490 | "qz": 0, 491 | "qw": 1.0 492 | }, 493 | "vector": { 494 | "x": 0.0, 495 | "y": 0, 496 | "z": 3.15 497 | }, 498 | "type": "Beam", 499 | "mesh_id": 0 500 | }, 501 | { 502 | "info": { 503 | "Material": "Steel" 504 | }, 505 | "color": { 506 | "r": 0, 507 | "g": 0, 508 | "b": 255, 509 | "a": 255 510 | }, 511 | "guid": "93ed1739-282a-42ae-b935-d78237e2e099", 512 | "rotation": { 513 | "qx": 0, 514 | "qy": 0, 515 | "qz": 0, 516 | "qw": 1.0 517 | }, 518 | "vector": { 519 | "x": 2.0, 520 | "y": 0, 521 | "z": 3.15 522 | }, 523 | "type": "Beam", 524 | "mesh_id": 0 525 | }, 526 | { 527 | "info": { 528 | "Material": "Steel" 529 | }, 530 | "color": { 531 | "r": 0, 532 | "g": 0, 533 | "b": 255, 534 | "a": 255 535 | }, 536 | "guid": "a91d2ca5-dbda-4825-bbfa-7751a2bde926", 537 | "rotation": { 538 | "qx": 0, 539 | "qy": 0, 540 | "qz": 0, 541 | "qw": 1.0 542 | }, 543 | "vector": { 544 | "x": 4.0, 545 | "y": 0, 546 | "z": 3.15 547 | }, 548 | "type": "Beam", 549 | "mesh_id": 0 550 | }, 551 | { 552 | "info": { 553 | "Material": "Steel" 554 | }, 555 | "color": { 556 | "r": 0, 557 | "g": 0, 558 | "b": 255, 559 | "a": 255 560 | }, 561 | "guid": "24afc5e3-0d28-48e0-a946-c6309c6c921b", 562 | "rotation": { 563 | "qx": 0, 564 | "qy": 0, 565 | "qz": 0, 566 | "qw": 1.0 567 | }, 568 | "vector": { 569 | "x": 6.0, 570 | "y": 0, 571 | "z": 3.15 572 | }, 573 | "type": "Beam", 574 | "mesh_id": 0 575 | }, 576 | { 577 | "info": { 578 | "Material": "Steel" 579 | }, 580 | "color": { 581 | "r": 0, 582 | "g": 0, 583 | "b": 255, 584 | "a": 255 585 | }, 586 | "guid": "28bff0b4-4e05-46aa-ba49-5b07f3469dac", 587 | "rotation": { 588 | "qx": 0, 589 | "qy": 0, 590 | "qz": 0, 591 | "qw": 1.0 592 | }, 593 | "vector": { 594 | "x": 8.0, 595 | "y": 0, 596 | "z": 3.15 597 | }, 598 | "type": "Beam", 599 | "mesh_id": 0 600 | }, 601 | { 602 | "info": { 603 | "Material": "Concrete" 604 | }, 605 | "color": { 606 | "r": 255, 607 | "g": 215, 608 | "b": 0, 609 | "a": 255 610 | }, 611 | "guid": "c59ea8b6-c788-44e3-b0d9-ac713038d1ee", 612 | "rotation": { 613 | "qx": 0, 614 | "qy": 0, 615 | "qz": 0, 616 | "qw": 1.0 617 | }, 618 | "vector": { 619 | "x": 0, 620 | "y": 0.0, 621 | "z": 1.5 622 | }, 623 | "type": "Wall", 624 | "mesh_id": 1 625 | }, 626 | { 627 | "info": { 628 | "Material": "Concrete" 629 | }, 630 | "color": { 631 | "r": 255, 632 | "g": 215, 633 | "b": 0, 634 | "a": 255 635 | }, 636 | "guid": "11009c85-dc88-49e3-9662-aa012625109c", 637 | "rotation": { 638 | "qx": 0, 639 | "qy": 0, 640 | "qz": 0, 641 | "qw": 1.0 642 | }, 643 | "vector": { 644 | "x": 0, 645 | "y": -6.0, 646 | "z": 1.5 647 | }, 648 | "type": "Wall", 649 | "mesh_id": 1 650 | } 651 | ], 652 | "info": { 653 | "Author": "John Doe" 654 | } 655 | } -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_mesh.py: -------------------------------------------------------------------------------- 1 | from dotbimpy import * 2 | import pytest 3 | 4 | 5 | def test_init(): 6 | mesh = Mesh(4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2]) 7 | 8 | assert mesh.mesh_id == 4 9 | assert mesh.coordinates == [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0] 10 | assert mesh.indices == [0, 1, 2] 11 | 12 | 13 | @pytest.mark.parametrize("mesh_id, coordinates, indices, expected", 14 | [(4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2], True), 15 | (3, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2], False), 16 | (4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.1, 0.0, 20.0], [0, 1, 2], False), 17 | (4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 2, 1], False), 18 | (3, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.1, 0.0, 20.0], [0, 2, 1], False)]) 19 | def test_eq(mesh_id, coordinates, indices, expected): 20 | original = Mesh(4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2]) 21 | other = Mesh(mesh_id, coordinates, indices) 22 | 23 | assert original.__eq__(other) == expected 24 | assert other.__eq__(original) == expected 25 | 26 | 27 | def test_eq_with_other_object(): 28 | original = Mesh(4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2]) 29 | other = 2 30 | 31 | assert original.__eq__(other) is NotImplemented 32 | 33 | 34 | @pytest.mark.parametrize("mesh_id, coordinates, indices, expected", 35 | [(4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2], True), 36 | (3, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2], True), 37 | (4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.1, 0.0, 20.0], [0, 1, 2], False), 38 | (4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 2, 1], False), 39 | (3, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.1, 0.0, 20.0], [0, 2, 1], False)]) 40 | def test_equals_without_mesh_id(mesh_id, coordinates, indices, expected): 41 | original = Mesh(4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2]) 42 | other = Mesh(mesh_id, coordinates, indices) 43 | 44 | assert original.equals_without_mesh_id(other) == expected 45 | assert other.equals_without_mesh_id(original) == expected 46 | 47 | 48 | def test_equals_without_mesh_id_with_other_object(): 49 | original = Mesh(4, [0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 10.0, 0.0, 20.0], [0, 1, 2]) 50 | other = 2 51 | 52 | assert original.equals_without_mesh_id(other) is NotImplemented 53 | -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_rotation.py: -------------------------------------------------------------------------------- 1 | from dotbimpy import * 2 | import pytest 3 | 4 | 5 | def test_init(): 6 | rotation = Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, -0.750877077691500) 7 | 8 | assert rotation.qx == 0.6397929577145492 9 | assert rotation.qy == 0.1062698214791025 10 | assert rotation.qz == -0.1247209304773680 11 | assert rotation.qw == -0.750877077691500 12 | 13 | 14 | @pytest.mark.parametrize("qx, qy, qz, qw, expected", 15 | [(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, -0.750877077691500, True), 16 | (0.6397929578145492, 0.1062698214791025, -0.1247209304773680, -0.750877077691500, False), 17 | (0.6397929577145492, -0.1062698214791025, -0.1247209304773680, -0.750877077691500, False), 18 | (0.6397929577145492, 0.1062698214791025, -0.1447209304773680, -0.750877077691500, False), 19 | (0.5397929577145492, 0.1162698214791025, -0.1447209304773680, -0.750877077691500, False)]) 20 | def test_eq(qx, qy, qz, qw, expected): 21 | original = Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, -0.750877077691500) 22 | other = Rotation(qx, qy, qz, qw) 23 | 24 | assert original.__eq__(other) == expected 25 | assert other.__eq__(original) == expected 26 | 27 | 28 | def test_eq_with_other_object(): 29 | original = Rotation(0.6397929577145492, 0.1062698214791025, -0.1247209304773680, -0.750877077691500) 30 | other = 2 31 | 32 | assert original.__eq__(other) is NotImplemented 33 | -------------------------------------------------------------------------------- /dotbimpy/tests/unittests/test_vector.py: -------------------------------------------------------------------------------- 1 | from dotbimpy import * 2 | import pytest 3 | 4 | 5 | def test_init(): 6 | vector = Vector(9.9266016462536, 3.3910972817343, 52.239445879618) 7 | 8 | assert vector.x == 9.9266016462536 9 | assert vector.y == 3.3910972817343 10 | assert vector.z == 52.239445879618 11 | 12 | 13 | @pytest.mark.parametrize("x, y, z, expected", 14 | [(9.9266016462536, 3.3910972817343, 52.239445879618, True), 15 | (9.0266016462536, 3.3910972817343, 52.239445879618, False), 16 | (9.9266016462536, 3.4910972817343, 52.239445879618, False), 17 | (9.9266016462536, 3.3910972817343, 52.539445879618, False), 18 | (9.9266016462536, 3.3810972817343, 52.539445879618, False)]) 19 | def test_eq(x, y, z, expected): 20 | original = Vector(9.9266016462536, 3.3910972817343, 52.239445879618) 21 | other = Vector(x, y, z) 22 | 23 | assert original.__eq__(other) == expected 24 | assert other.__eq__(original) == expected 25 | 26 | 27 | def test_eq_with_other_object(): 28 | original = Vector(9.9266016462536, 3.3910972817343, 52.239445879618) 29 | other = 2 30 | 31 | assert original.__eq__(other) is NotImplemented 32 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | setup( 3 | name='dotbimpy', 4 | packages=['dotbimpy'], 5 | version='0.1.0', 6 | license='MIT', 7 | description='Python library for dotbim', 8 | author='Wojciech', 9 | author_email='w.radaczynski@gmail.com', 10 | url='https://github.com/paireks/dotbimpy', 11 | download_url='https://github.com/paireks/dotbimpy/archive/refs/tags/v_0_1_0.tar.gz', 12 | keywords=[], 13 | install_requires=[ 14 | 'jsonpickle', 15 | 'plotly', 16 | 'pyquaternion', 17 | 'numpy' 18 | ], 19 | classifiers=[ 20 | 'Development Status :: 3 - Alpha', 21 | 'Intended Audience :: Developers', 22 | 'Topic :: Software Development :: Build Tools', 23 | 'License :: OSI Approved :: MIT License', 24 | 'Programming Language :: Python :: 3.6', 25 | 'Programming Language :: Python :: 3.7', 26 | 'Programming Language :: Python :: 3.8', 27 | 'Programming Language :: Python :: 3.9', 28 | 'Programming Language :: Python :: 3.10' 29 | ], 30 | ) --------------------------------------------------------------------------------