├── .gitattributes ├── LICENSE ├── README.md ├── py ├── AddBlenderCustomPropertiesFromCSV.py └── AddBlenderCustomPropertiesFromCSVAddOn.py ├── repository ├── BodyEmbeddedData.glb ├── BodyEmbeddedData.gltf ├── ForkliftEmbeddedData.glb ├── ForkliftEmbeddedData.gltf ├── PlaneEmbeddedData.glb ├── PlaneEmbeddedData.gltf ├── ShipEmbeddedData.glb ├── ShipEmbeddedData.gltf ├── TruckEmbeddedData.glb └── TruckEmbeddedData.gltf ├── test ├── AddOnScreenShot.png ├── test.blend ├── test.csv ├── test.gltf ├── testRunOutput.txt └── testWithAddOn.blend └── vba ├── CSVFileMacro.txt ├── testMacro.csv └── testMacroOutput.csv /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Mario Delgado 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Python Script to Add Blender Custom Properties From CSV File 3 | 4 | * The Python script, [AddBlenderCustomPropertiesFromCSV.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/py/AddBlenderCustomPropertiesFromCSV.py), will read a formatted csv (comma seperated value) file and use its contents to set [Custom Properties](https://docs.blender.org/manual/en/latest/data_system/custom_properties.html?highlight=custom%20properties). 5 | 6 | * The Blender Add-on, [AddBlenderCustomPropertiesFromCSVAddOn.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/py/AddBlenderCustomPropertiesFromCSVAddOn.py), will perform the same task, but as an Add-on integrated into the 3D View Tool Panel. 7 | 8 | * The file loaded must be in a [*csv.DictReader*](https://docs.python.org/3/library/csv.html) class format readable with *QUOTE_NONNUMERIC* quoting: 9 | ```` 10 | QUOTE_NONNUMERIC 11 | ... When used with the reader, input fields that are not quoted are converted to floats. 12 | ```` 13 | * Therefore, non-numeric components (including column headers) must be enclosed within double qutoes. 14 | 15 | * The script or Add-on can be used to 'enrich' a Blender file, that will be exported to a glTF file, with embedded data. 16 | * When a Blender file is exported to a glTF file, the [Custom Properties](https://docs.blender.org/manual/en/dev/files/data_blocks.html#files-data-blocks-custom-properties) are placed in the [*extras* properties](https://docs.blender.org/manual/en/dev/addons/import_export/scene_gltf2.html?highlight=extras) associated with the mesh. 17 | 18 | ## Usage 19 | 20 | 21 | ### Option 1 22 | 23 | * [Run](https://docs.blender.org/api/2.79/info_quickstart.html#running-scripts) the [AddBlenderCustomPropertiesFromCSV.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/py/AddBlenderCustomPropertiesFromCSV.py) script from within Blender and respond to the input prompt with filename (format: [folder]/filename.csv ) that contains the data to update the Custom Properies. 24 | 25 | **Note:** 26 | * The [*input*](https://docs.python.org/3/library/functions.html#input) method awaits a response from the [system console](https://docs.blender.org/manual/en/dev/advanced/command_line/launch/windows.html?highlight=toggle%20system%20console), not the [Blender Python Interactive console](https://docs.blender.org/manual/en/dev/editors/python_console.html). 27 | 28 | ### Option 2 29 | 30 | * Alternatively [install](https://www.youtube.com/watch?v=DDt96E-xojg) [AddBlenderCustomPropertiesFromCSVAddOn.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/py/AddBlenderCustomPropertiesFromCSVAddOn.py) as a [Blender Add-on](https://docs.blender.org/manual/en/latest/advanced/scripting/addon_tutorial.html?highlight=addon) 31 | * Add-on name is '**CVS to Custom Properties**' under Object; 32 | * Then select file with file selector; 33 | * Select 'Add Custom Props' button to initiate the Python script that adds Customp Properties. 34 | * **Note**: The file [testWithAddOn.blend](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/test/testWithAddOn.blend) has the Blender add-on in a text editor window ready to be added directly for a quick-test scenario that doesn't involve [User Preferences](https://docs.blender.org/manual/en/dev/editors/preferences/addons.html?highlight=user%20preferences). 35 | 36 | ### Screen Shot of Installed Add-on: 37 | 38 | ![Screen Shot of Demonstration](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/test/AddOnScreenShot.png) 39 | 40 | 41 | #### Creating a Properly Formatted CSV Files 42 | 43 | * All text values (including column headers) must be double quoted in the .csv file. 44 | * The Python Scripts will throw an exception error if they attempt to convert an un-quoted string to a float numeric. 45 | * Microsoft Excel does not add double quotes around text values automatically with its [Save As](https://support.office.com/en-us/article/Save-a-workbook-in-another-file-format-6A16C862-4A36-48F9-A300-C2CA0065286E) option. 46 | * One option is to use the [*CVSFile* utility macro](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/vba/CSVFileMacro.txt) in the vba folder. 47 | * The video, [*How to Write Your Very First Macro in Microsft Excel*](https://youtu.be/T--ZZSQhGqU) offers a helpful tutorial. 48 | * To use the [*CVSFile* utility macro](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/vba/CSVFileMacro.txt), cut-and-paste the macro's code into the VBA editor (as per the video) and excute it on the sheet that contains the data to export. 49 | 50 | ##### Utility Macro's Text: 51 | 52 | ```` 53 | Sub CSVFile() 54 | 55 | ' Modified from: https://stackoverflow.com/questions/846839/excel-how-to-add-double-quotes-to-strings-only-in-csv-file 56 | ' Author: https://github.com/MarioDelgadoSr 57 | ' 58 | ' Macro will export selection or current sheet in a format compatible with Python's QUOTE_NONNUMERIC quoting. 59 | ' See: https://docs.python.org/3/library/csv.html 60 | 61 | Dim SrcRg As Range 62 | Dim CurrRow As Range 63 | Dim CurrCell As Range 64 | Dim CurrTextStr As String 65 | Dim ListSep As String 66 | Dim FName As Variant 67 | 68 | 'Prompt User for save file location 69 | FName = Application.GetSaveAsFilename("", "CSV File (*.csv), *.csv") 70 | 71 | If FName <> False Then 72 | 73 | 'ListSep = Application.International(xlListSeparator) 74 | ListSep = "," 75 | 76 | If Selection.Cells.Count > 1 Then 77 | 78 | Set SrcRg = Selection 79 | 80 | Else 81 | 82 | Set SrcRg = ActiveSheet.UsedRange 83 | 84 | End If 85 | 86 | Open FName For Output As #1 87 | 88 | For Each CurrRow In SrcRg.Rows 89 | 90 | CurrTextStr = "" 91 | 92 | For Each CurrCell In CurrRow.Cells 93 | 94 | ' Quote only text value 95 | DblQuoteStr = IIf(Application.IsText(CurrCell.Value), """", "") 96 | CurrTextStr = CurrTextStr & DblQuoteStr & CurrCell.Value & DblQuoteStr & ListSep 97 | 98 | Next 'CurCell 99 | 100 | While Right(CurrTextStr, 1) = ListSep 101 | 'Remove last ',' on the line 102 | CurrTextStr = Left(CurrTextStr, Len(CurrTextStr) - 1) 103 | Wend 104 | 105 | Print #1, CurrTextStr 106 | 107 | Next 'CurrRow 108 | 109 | Close #1 110 | 111 | End If 112 | 113 | End Sub 114 | 115 | ```` 116 | 117 | * Another option is to use [OpenOffice](http://www.openoffice.org/) as detailed in [this post](https://superuser.com/questions/130592/how-do-you-force-excel-to-quote-all-columns-of-a-csv-file). 118 | 119 | 120 | #### Script Workflow 121 | 122 | * Assuming a Blender object (.type = 'MESH'); 123 | * With a name == 'object1'; 124 | * The following csv file contents will assign the Blender mesh [Custom Properties](https://docs.blender.org/manual/en/latest/data_system/custom_properties.html?highlight=custom%20properties) : 125 | * A numeric float value of *prop1* to property 'propName1'; 126 | * A string value of "*prop2*" to 'propertyName2': 127 | 128 | ```` 129 | "objectName","propName1","propName2" 130 | "object1",prop1,"prop2" 131 | ```` 132 | 133 | * The *sanitize = True* option will sanitize a mesh's name to be consitent wth [Three.js naming requirements for nodes](https://discourse.threejs.org/t/issue-with-gltfloader-and-objects-with-dots-in-their-name-attribute/6726 ). 134 | 135 | ##### Contents of [AddBlenderCustomPropertiesFromCSV.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/tree/master/py): 136 | 137 | ```` 138 | # Python script to set Blender Custom Properties for a mesh (.type == 'MESH') 139 | # Author: Mario Delgado, LinkedIn: https://www.linkedin.com/in/mario-delgado-5b6195155/ 140 | # Source: http://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV 141 | # 142 | # Custom Properties: https://docs.blender.org/manual/en/latest/data_system/custom_properties.html?highlight=custom%20properties 143 | 144 | import bpy, csv 145 | 146 | # santize = True will convert Blender's duplicate object name to a Three.js sanitized name 147 | # This is only a concern when exporting Blender to glTF files with the intent of importing 148 | # them into Three.js. Any names with mesh glTF nodes with '.' in the name will have the '.' removed. 149 | # So sanitizing the names before exporting to glTF (and eventually Three.js) will provide for consitency 150 | # in any processes that depend on a consitent and accurate node name. 151 | # See Three.js sanitizing: https://discourse.threejs.org/t/issue-with-gltfloader-and-objects-with-dots-in-their-name-attribute/6726 152 | 153 | sanitize = True #True or False 154 | 155 | # input: https://docs.python.org/3/library/functions.html#input 156 | # Note: input awaits a response from the system console, not the Blender Python Interactive console 157 | # System Console: https://docs.blender.org/manual/en/dev/advanced/command_line/launch/windows.html?highlight=toggle%20system%20console 158 | # Python Interactive Console: https://docs.blender.org/manual/en/dev/editors/python_console.html 159 | 160 | filePath = input("Enter file name path (folder/filename.csv):") #Example: Type "c:/data/keys.csv" when prompted in the conole 161 | 162 | # Example of content in .csv file, line 1 contains column heading (Object Name and Properties): 163 | # 164 | # "objectName","propName1","propName2",... 165 | # "object1","prop1",prop2,... 166 | # "object2","prop1",prop2,... 167 | # 168 | # Script will assign bpy.data.objects[objectName].data[propNameN] = propN 169 | # * The quoted propNs will be treated as strings 170 | # * The un-quoted propNs will be converted to float. 171 | 172 | 173 | print("********************************Add Blender Custom Properties ********************************************") 174 | print(" ") 175 | print("Adding Custom Properties with the following options:") 176 | print(" ") 177 | print("filePath: ", filePath) 178 | print("sanitize: ", str(sanitize)) 179 | print(" ") 180 | 181 | with open( filePath ) as csvfile: # https://docs.python.org/3/library/csv.html 182 | rdr = csv.DictReader( csvfile, quoting = csv.QUOTE_NONNUMERIC ) 183 | for row in rdr: 184 | 185 | meshName = row[rdr.fieldnames[0]] 186 | 187 | print("******************************** meshName:", meshName ,"********************************************") 188 | print(" properties before assignment(s): ", bpy.data.objects[meshName].data.items()) 189 | 190 | for x in range (1, len(rdr.fieldnames)): 191 | propName = rdr.fieldnames[x] 192 | propValue = row[propName] 193 | # List Comprehension: https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions 194 | mesh = [obj for obj in bpy.data.objects if obj.name == meshName and obj.type == 'MESH'][0] 195 | 196 | if sanitize: 197 | mesh.name = mesh.name.replace(".","") 198 | print (" Mesh's name sanitized from: ",meshName, " to: ", mesh.name) 199 | meshName = mesh.name 200 | 201 | #Custom Property Assigned to Object, this assures userData on ThreeJS is assigned to groups as well 202 | mesh[propName] = propValue 203 | print(" Updated meshName: ", meshName, ", propName: ", propName, ", propValue:", mesh[propName]) 204 | 205 | print(" properties after assignment(s): ", bpy.data.objects[meshName].items()) 206 | print("") 207 | ```` 208 | 209 | #### Blender Add-on Workflow 210 | 211 | * Assuming a Blender object (.type = 'MESH'); 212 | * With a name == 'object1'; 213 | * The following csv file contents will assign the Blender mesh a [Custom Properties](https://docs.blender.org/manual/en/latest/data_system/custom_properties.html?highlight=custom%20properties) numeric float value of *prop1* to property 'propName1' and a string value of "*prop2*" to 'propertyName2': 214 | 215 | ```` 216 | "objectName","propName1","propName2" 217 | "object1",prop1,"prop2" 218 | ```` 219 | * Once [installed](https://www.youtube.com/watch?v=DDt96E-xojg) , the Blender Add-on will be registered in the Tools panel: 220 | 221 | ![Screen Shot of Demonstration](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/test/AddOnScreenShot.png) 222 | 223 | ##### Contents of [AddBlenderCustomPropertiesFromCSVAddOn.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/py/AddBlenderCustomPropertiesFromCSVAddOn.py): 224 | 225 | ```` 226 | # Add-on Tutorial: https://youtu.be/OEkrQGFqM10 227 | # Python script to set Blender Custom Properties for a mesh (.type == 'MESH') 228 | # Author: Mario Delgado, LinkedIn: https://www.linkedin.com/in/mario-delgado-5b6195155/ 229 | # Source: http://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV 230 | # 231 | # Custom Properties: https://docs.blender.org/manual/en/latest/data_system/custom_properties.html?highlight=custom%20properties 232 | # Modified from: https://blender.stackexchange.com/questions/26898/how-to-create-a-folder-dialog/26906#26906 233 | 234 | bl_info = {"name": "CVS to Custom Properties", "category": "Object"} 235 | 236 | import bpy, csv 237 | 238 | from bpy.props import (StringProperty, 239 | BoolProperty, 240 | IntProperty, 241 | FloatProperty, 242 | FloatVectorProperty, 243 | EnumProperty, 244 | PointerProperty, 245 | ) 246 | from bpy.types import (Panel, 247 | Operator, 248 | AddonPreferences, 249 | PropertyGroup, 250 | ) 251 | 252 | 253 | class addPropsSettings(PropertyGroup): 254 | 255 | path = StringProperty( 256 | name="", 257 | description="Path to Directory", 258 | default="", 259 | maxlen=1024, 260 | subtype='FILE_PATH') 261 | 262 | sanitize_bool = BoolProperty( #https://blender.stackexchange.com/questions/35007/how-can-i-add-a-checkbox-in-the-tools-ui 263 | name="Sanitize Mesh Name", 264 | description="Sanitize the Mesh Name", 265 | default = True 266 | ) 267 | 268 | 269 | class processCustom(bpy.types.Operator): 270 | 271 | bl_idname = "object.process_custom" 272 | bl_label = "" 273 | 274 | filePath = bpy.props.StringProperty() 275 | sanitize = bpy.props.BoolProperty() 276 | 277 | def execute(self, context): 278 | 279 | filePath = self.filePath 280 | sanitize = self.sanitize 281 | 282 | # santize = True will convert Blender's duplicate object name to a Three.js sanitized name 283 | # This is only a concern when exporting Blender to glTF files with the intent of importing 284 | # them into Three.js. Any names with mesh glTF nodes with '.' in the name will have the '.' removed. 285 | # So sanitizing the names before exporting to glTF (and eventually Three.js) will provide for consitency 286 | # in any processes that depend on a consitent and accurate node name. 287 | # See Three.js sanitizing: https://discourse.threejs.org/t/issue-with-gltfloader-and-objects-with-dots-in-their-name-attribute/6726 288 | #sanitize = True #True or False 289 | 290 | 291 | # input: https://docs.python.org/3/library/functions.html#input 292 | # Note: input awaits a response from the system console, not the Blender Python Interactive console 293 | # System Console: https://docs.blender.org/manual/en/dev/advanced/command_line/launch/windows.html?highlight=toggle%20system%20console 294 | # Python Interactive Console: https://docs.blender.org/manual/en/dev/editors/python_console.html 295 | #filePath = input("Enter file name path (folder/filename.csv):") #Example: Type "c:/data/keys.csv" when prompted in the conole 296 | 297 | # Example of content in .csv file, line 1 contains column heading (Object Name and Properties): 298 | # 299 | # "objectName","propName1","propName2",... 300 | # "object1","prop1",prop2,... 301 | # "object2","prop1",prop2,... 302 | # 303 | # Script will assign bpy.data.objects[objectName].data[propNameN] = propN 304 | # * The quoted propNs will be treated as strings 305 | # * The un-quoted propNs will be converted to float. 306 | 307 | print("********************************Add Blender Custom Properties ********************************************") 308 | print(" ") 309 | print("Adding Custom Properties with the following options:") 310 | print(" ") 311 | print("filePath: ", filePath) 312 | print("sanitize: ", str(sanitize)) 313 | print(" ") 314 | 315 | # https://docs.python.org/3/library/csv.html 316 | with open( filePath ) as csvfile: 317 | rdr=csv.DictReader(csvfile,quoting=csv.QUOTE_NONNUMERIC) 318 | for row in rdr: 319 | 320 | meshName = row[rdr.fieldnames[0]] 321 | 322 | print("******************************** meshName:", meshName ,"********************************************") 323 | print(" properties before assignment(s): ", bpy.data.objects[meshName].data.items()) 324 | 325 | for x in range (1, len(rdr.fieldnames)): 326 | propName = rdr.fieldnames[x] 327 | propValue = row[propName] 328 | # List Comprehension: https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions 329 | mesh = [obj for obj in bpy.data.objects if obj.name == meshName and obj.type == 'MESH'][0] 330 | 331 | if sanitize: 332 | mesh.name = mesh.name.replace(".","") 333 | print (" Mesh's name sanitized from: ",meshName, " to: ", mesh.name) 334 | meshName = mesh.name 335 | 336 | #Custom Property Assigned to Object, this assures userData on ThreeJS is assigned to groups as well 337 | mesh[propName]=propValue 338 | print(" Update meshName: ", meshName, ",propName: ", propName, ", proValue: ", mesh[propName]) 339 | 340 | print(" properties after assignment(s): ", bpy.data.objects[meshName].items()) 341 | print("") 342 | 343 | return {'FINISHED'} 344 | 345 | # --------------------------------------------------------------------------------- 346 | # Customize Tool Panel and add file selector and check box for sanitize option 347 | # --------------------------------------------------------------------------------- 348 | 349 | class addCustomProperitesPanel(Panel): 350 | bl_idname = "addCustomProperitesPanel" 351 | bl_label = "CSV to Custom Props" # scn.csv_to_custom_props 352 | bl_space_type = "VIEW_3D" 353 | bl_region_type = "TOOLS" 354 | bl_category = "Tools" 355 | bl_context = "objectmode" 356 | 357 | def draw(self, context): 358 | layout = self.layout 359 | scn = context.scene 360 | col = layout.column(align=True) 361 | col.prop(scn.csv_to_custom_props, "path", text="") #The file path selected by the user 362 | col.prop(scn.csv_to_custom_props, "sanitize_bool","Sanitize Mesh Name") #The sanitize option True/False 363 | 364 | #Passing property: https://blenderartists.org/t/how-to-pass-two-arguments-to-a-button-operator/497013/8 365 | processCustomButton = col.operator("object.process_custom", text="Add Custom Props") 366 | processCustomButton.filePath = scn.csv_to_custom_props.path 367 | processCustomButton.sanitize = scn.csv_to_custom_props.sanitize_bool 368 | 369 | # ------------------------------------------------------------------------ 370 | # register and unregister functions 371 | # ------------------------------------------------------------------------ 372 | 373 | def register(): 374 | bpy.utils.register_module(__name__) 375 | bpy.types.Scene.csv_to_custom_props = PointerProperty(type=addPropsSettings) 376 | 377 | def unregister(): 378 | bpy.utils.unregister_module(__name__) 379 | del bpy.types.Scene.csv_to_custom_props 380 | 381 | if __name__ == "__main__": 382 | register() 383 | 384 | 385 | 386 | 387 | 388 | ```` 389 | 390 | ### Running the Test(s) 391 | 392 | #### Option 1 393 | 394 | * Open [test.blend](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/test/test.blend) file in test folder. 395 | * Run [AddBlenderCustomPropertiesFromCSV.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/tree/master/py) Python script. 396 | * Reference [test.csv](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/test/test.csv) in test folder when prompted by [input](https://docs.python.org/3/library/functions.html#input) prompt. 397 | 398 | **Note:** 399 | * The [*input*](https://docs.python.org/3/library/functions.html#input) method awaits a response from the [system console](https://docs.blender.org/manual/en/dev/advanced/command_line/launch/windows.html?highlight=toggle%20system%20console), not the [Blender Python Interactive console](https://docs.blender.org/manual/en/dev/editors/python_console.html). 400 | 401 | #### Option 2 402 | 403 | * Alternatively [install](https://www.youtube.com/watch?v=DDt96E-xojg) [AddBlenderCustomPropertiesFromCSVAddOn.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/py/AddBlenderCustomPropertiesFromCSVAddOn.py) as a [Blender Add-on](https://docs.blender.org/manual/en/latest/advanced/scripting/addon_tutorial.html?highlight=addon) 404 | * Add-on name is '**CVS to Custom Properties**' under Object; 405 | * Then select file with file selector; 406 | * Select 'Add Custom Props' button to initiate the Python script that adds Customp Properties. 407 | * Note: The file [testWithAddOn.blend](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/test/testWithAddOn.blend) has the Blender Add-on ready for a quick test, without having to install via [User Preferences](https://docs.blender.org/manual/en/dev/editors/preferences/addons.html?highlight=user%20preferences). 408 | 409 | **Screen Shot of Installed Add-on** 410 | ![Screen Shot of Demonstration](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/test/AddOnScreenShot.png) 411 | 412 | #### Contents of test.csv 413 | 414 | ```` 415 | "Mesh","value" 416 | "Cube.000",10 417 | "Cube.001",20 418 | ```` 419 | 420 | 421 | #### Test Output 422 | 423 | The output is the same for either [AddBlenderCustomPropertiesFromCSV.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/tree/master/py) script or [AddBlenderCustomPropertiesFromCSVAddOn.py](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/py/AddBlenderCustomPropertiesFromCSVAddOn.py) Add-on: 424 | 425 | ```` 426 | 427 | ********************************Add Blender Custom Properties ******************************************** 428 | 429 | Adding Custom Properties with the following options: 430 | 431 | filePath: c:\temp\test.csv 432 | sanitize: True 433 | 434 | ******************************** meshName: Cube.000 ******************************************** 435 | properties before assignment(s): [] 436 | Mesh's name sanitized from: Cube.000 to: Cube000 437 | Updated meshName: Cube000 , propName: value , propValue: 10.0 438 | properties after assignment(s): [('value', 10.0)] 439 | 440 | ******************************** meshName: Cube.001 ******************************************** 441 | properties before assignment(s): [] 442 | Mesh's name sanitized from: Cube.001 to: Cube001 443 | Updated meshName: Cube001 , propName: value , propValue: 20.0 444 | properties after assignment(s): [('value', 20.0)] 445 | ```` 446 | 447 | The file [test.gltf](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/blob/master/test/test.gltf) is a [glTF file exported](https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Import_Export) after the data was added to the Blender scene. 448 | 449 | #### Repository 450 | 451 | * The [repository folder](https://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/tree/master/repository) contains several glTF files created with the Python script used to 452 | demonstrate the [*My Data Visualizer*](http://mydatavisualizer.com) application. 453 | 454 | * These Blender generated exports can simply be 'dragged-and-droped' into the visualization application. The application will read both the 3D visual and data information dynamically. 455 | 456 | 457 | ## Author 458 | 459 | * **Mario Delgado** Github: [MarioDelgadoSr](https://github.com/MarioDelgadoSr) 460 | * LinkedIn: [Mario Delgado](https://www.linkedin.com/in/mario-delgado-5b6195155/) 461 | * [My Data Visualizer](https://github.com/MarioDelgadoSr/MyDataVisualizer): A data visualization application using the [*DataVisual*](https://github.com/MarioDelgadoSr/DataVisual) design pattern. 462 | 463 | 464 | ## License 465 | 466 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 467 | 468 | -------------------------------------------------------------------------------- /py/AddBlenderCustomPropertiesFromCSV.py: -------------------------------------------------------------------------------- 1 | # Python script to set Blender Custom Properties for a mesh (.type == 'MESH') 2 | # Author: Mario Delgado, LinkedIn: https://www.linkedin.com/in/mario-delgado-5b6195155/ 3 | # Source: http://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV 4 | # 5 | # Custom Properties: https://docs.blender.org/manual/en/latest/data_system/custom_properties.html?highlight=custom%20properties 6 | 7 | import bpy, csv 8 | 9 | # santize = True will convert Blender's duplicate object name to a Three.js sanitized name 10 | # This is only a concern when exporting Blender to glTF files with the intent of importing 11 | # them into Three.js. Any names with mesh glTF nodes with '.' in the name will have the '.' removed. 12 | # So sanitizing the names before exporting to glTF (and eventually Three.js) will provide for consitency 13 | # in any processes that depend on a consitent and accurate node name. 14 | # See Three.js sanitizing: https://discourse.threejs.org/t/issue-with-gltfloader-and-objects-with-dots-in-their-name-attribute/6726 15 | 16 | sanitize = True #True or False 17 | 18 | # input: https://docs.python.org/3/library/functions.html#input 19 | # Note: input awaits a response from the system console, not the Blender Python Interactive console 20 | # System Console: https://docs.blender.org/manual/en/dev/advanced/command_line/launch/windows.html?highlight=toggle%20system%20console 21 | # Python Interactive Console: https://docs.blender.org/manual/en/dev/editors/python_console.html 22 | 23 | filePath = input("Enter file name path (folder/filename.csv):") #Example: Type "c:/data/keys.csv" when prompted in the conole 24 | 25 | # Example of content in .csv file, line 1 contains column heading (Object Name and Properties): 26 | # 27 | # "objectName","propName1","propName2",... 28 | # "object1","prop1",prop2,... 29 | # "object2","prop1",prop2,... 30 | # 31 | # Script will assign bpy.data.objects[objectName].data[propNameN] = propN 32 | # * The quoted propNs will be treated as strings 33 | # * The un-quoted propNs will be converted to float. 34 | 35 | 36 | print("********************************Add Blender Custom Properties ********************************************") 37 | print(" ") 38 | print("Adding Custom Properties with the following options:") 39 | print(" ") 40 | print("filePath: ", filePath) 41 | print("sanitize: ", str(sanitize)) 42 | print(" ") 43 | 44 | with open( filePath ) as csvfile: # https://docs.python.org/3/library/csv.html 45 | rdr = csv.DictReader( csvfile, quoting = csv.QUOTE_NONNUMERIC ) 46 | for row in rdr: 47 | 48 | meshName = row[rdr.fieldnames[0]] 49 | 50 | print("******************************** meshName:", meshName ,"********************************************") 51 | print(" properties before assignment(s): ", bpy.data.objects[meshName].data.items()) 52 | 53 | for x in range (1, len(rdr.fieldnames)): 54 | propName = rdr.fieldnames[x] 55 | propValue = row[propName] 56 | # List Comprehension: https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions 57 | mesh = [obj for obj in bpy.data.objects if obj.name == meshName and obj.type == 'MESH'][0] 58 | 59 | if sanitize: 60 | mesh.name = mesh.name.replace(".","") 61 | print (" Mesh's name sanitized from: ",meshName, " to: ", mesh.name) 62 | meshName = mesh.name 63 | 64 | #Custom Property Assigned to Object, this assures userData on ThreeJS is assigned to groups as well 65 | mesh[propName] = propValue 66 | print(" Updated meshName: ", meshName, ", propName: ", propName, ", propValue:", mesh[propName]) 67 | 68 | print(" properties after assignment(s): ", bpy.data.objects[meshName].items()) 69 | print("") -------------------------------------------------------------------------------- /py/AddBlenderCustomPropertiesFromCSVAddOn.py: -------------------------------------------------------------------------------- 1 | # Add-on Tutorial: https://youtu.be/OEkrQGFqM10 2 | # Python script to set Blender Custom Properties for a mesh (.type == 'MESH') 3 | # Author: Mario Delgado, LinkedIn: https://www.linkedin.com/in/mario-delgado-5b6195155/ 4 | # Source: http://github.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV 5 | # 6 | # Custom Properties: https://docs.blender.org/manual/en/latest/data_system/custom_properties.html?highlight=custom%20properties 7 | # Modified from: https://blender.stackexchange.com/questions/26898/how-to-create-a-folder-dialog/26906#26906 8 | 9 | bl_info = {"name": "CVS to Custom Properties", "category": "Object"} 10 | 11 | import bpy, csv 12 | 13 | from bpy.props import (StringProperty, 14 | BoolProperty, 15 | IntProperty, 16 | FloatProperty, 17 | FloatVectorProperty, 18 | EnumProperty, 19 | PointerProperty, 20 | ) 21 | from bpy.types import (Panel, 22 | Operator, 23 | AddonPreferences, 24 | PropertyGroup, 25 | ) 26 | 27 | 28 | class addPropsSettings(PropertyGroup): 29 | 30 | path = StringProperty( 31 | name="", 32 | description="Path to Directory", 33 | default="", 34 | maxlen=1024, 35 | subtype='FILE_PATH') 36 | 37 | sanitize_bool = BoolProperty( #https://blender.stackexchange.com/questions/35007/how-can-i-add-a-checkbox-in-the-tools-ui 38 | name="Sanitize Mesh Name", 39 | description="Sanitize the Mesh Name", 40 | default = True 41 | ) 42 | 43 | 44 | class processCustom(bpy.types.Operator): 45 | 46 | bl_idname = "object.process_custom" 47 | bl_label = "" 48 | 49 | filePath = bpy.props.StringProperty() 50 | sanitize = bpy.props.BoolProperty() 51 | 52 | def execute(self, context): 53 | 54 | filePath = self.filePath 55 | sanitize = self.sanitize 56 | 57 | # santize = True will convert Blender's duplicate object name to a Three.js sanitized name 58 | # This is only a concern when exporting Blender to glTF files with the intent of importing 59 | # them into Three.js. Any names with mesh glTF nodes with '.' in the name will have the '.' removed. 60 | # So sanitizing the names before exporting to glTF (and eventually Three.js) will provide for consitency 61 | # in any processes that depend on a consitent and accurate node name. 62 | # See Three.js sanitizing: https://discourse.threejs.org/t/issue-with-gltfloader-and-objects-with-dots-in-their-name-attribute/6726 63 | #sanitize = True #True or False 64 | 65 | 66 | # input: https://docs.python.org/3/library/functions.html#input 67 | # Note: input awaits a response from the system console, not the Blender Python Interactive console 68 | # System Console: https://docs.blender.org/manual/en/dev/advanced/command_line/launch/windows.html?highlight=toggle%20system%20console 69 | # Python Interactive Console: https://docs.blender.org/manual/en/dev/editors/python_console.html 70 | #filePath = input("Enter file name path (folder/filename.csv):") #Example: Type "c:/data/keys.csv" when prompted in the conole 71 | 72 | # Example of content in .csv file, line 1 contains column heading (Object Name and Properties): 73 | # 74 | # "objectName","propName1","propName2",... 75 | # "object1","prop1",prop2,... 76 | # "object2","prop1",prop2,... 77 | # 78 | # Script will assign bpy.data.objects[objectName].data[propNameN] = propN 79 | # * The quoted propNs will be treated as strings 80 | # * The un-quoted propNs will be converted to float. 81 | 82 | print("********************************Add Blender Custom Properties ********************************************") 83 | print(" ") 84 | print("Adding Custom Properties with the following options:") 85 | print(" ") 86 | print("filePath: ", filePath) 87 | print("sanitize: ", str(sanitize)) 88 | print(" ") 89 | 90 | # https://docs.python.org/3/library/csv.html 91 | with open( filePath ) as csvfile: 92 | rdr=csv.DictReader(csvfile,quoting=csv.QUOTE_NONNUMERIC) 93 | for row in rdr: 94 | 95 | meshName = row[rdr.fieldnames[0]] 96 | 97 | print("******************************** meshName:", meshName ,"********************************************") 98 | print(" properties before assignment(s): ", bpy.data.objects[meshName].data.items()) 99 | 100 | for x in range (1, len(rdr.fieldnames)): 101 | propName = rdr.fieldnames[x] 102 | propValue = row[propName] 103 | # List Comprehension: https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions 104 | mesh = [obj for obj in bpy.data.objects if obj.name == meshName and obj.type == 'MESH'][0] 105 | 106 | if sanitize: 107 | mesh.name = mesh.name.replace(".","") 108 | print (" Mesh's name sanitized from: ",meshName, " to: ", mesh.name) 109 | meshName = mesh.name 110 | 111 | #Custom Property Assigned to Object, this assures userData on ThreeJS is assigned to groups as well 112 | mesh[propName]=propValue 113 | print(" Update meshName: ", meshName, ",propName: ", propName, ", proValue: ", mesh[propName]) 114 | 115 | print(" properties after assignment(s): ", bpy.data.objects[meshName].items()) 116 | print("") 117 | 118 | return {'FINISHED'} 119 | 120 | # --------------------------------------------------------------------------------- 121 | # Customize Tool Panel and add file selector and check box for sanitize option 122 | # --------------------------------------------------------------------------------- 123 | 124 | class addCustomProperitesPanel(Panel): 125 | bl_idname = "addCustomProperitesPanel" 126 | bl_label = "CSV to Custom Props" # scn.csv_to_custom_props 127 | bl_space_type = "VIEW_3D" 128 | bl_region_type = "TOOLS" 129 | bl_category = "Tools" 130 | bl_context = "objectmode" 131 | 132 | def draw(self, context): 133 | layout = self.layout 134 | scn = context.scene 135 | col = layout.column(align=True) 136 | col.prop(scn.csv_to_custom_props, "path", text="") #The file path selected by the user 137 | col.prop(scn.csv_to_custom_props, "sanitize_bool","Sanitize Mesh Name") #The sanitize option True/False 138 | 139 | #Passing property: https://blenderartists.org/t/how-to-pass-two-arguments-to-a-button-operator/497013/8 140 | processCustomButton = col.operator("object.process_custom", text="Add Custom Props") 141 | processCustomButton.filePath = scn.csv_to_custom_props.path 142 | processCustomButton.sanitize = scn.csv_to_custom_props.sanitize_bool 143 | 144 | # ------------------------------------------------------------------------ 145 | # register and unregister functions 146 | # ------------------------------------------------------------------------ 147 | 148 | def register(): 149 | bpy.utils.register_module(__name__) 150 | bpy.types.Scene.csv_to_custom_props = PointerProperty(type=addPropsSettings) 151 | 152 | def unregister(): 153 | bpy.utils.unregister_module(__name__) 154 | del bpy.types.Scene.csv_to_custom_props 155 | 156 | if __name__ == "__main__": 157 | register() 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /repository/BodyEmbeddedData.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/707da0e594ff9a51f0c559f1b6096cb0916380c8/repository/BodyEmbeddedData.glb -------------------------------------------------------------------------------- /repository/ForkliftEmbeddedData.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/707da0e594ff9a51f0c559f1b6096cb0916380c8/repository/ForkliftEmbeddedData.glb -------------------------------------------------------------------------------- /repository/PlaneEmbeddedData.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/707da0e594ff9a51f0c559f1b6096cb0916380c8/repository/PlaneEmbeddedData.glb -------------------------------------------------------------------------------- /repository/ShipEmbeddedData.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/707da0e594ff9a51f0c559f1b6096cb0916380c8/repository/ShipEmbeddedData.glb -------------------------------------------------------------------------------- /repository/ShipEmbeddedData.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "accessors": [ 3 | { 4 | "bufferView": 10, 5 | "byteOffset": 0, 6 | "componentType": 5126, 7 | "count": 24, 8 | "max": [ 9 | 1.0, 10 | 1.0, 11 | 1.0 12 | ], 13 | "min": [ 14 | -1.0, 15 | -1.0, 16 | -1.0 17 | ], 18 | "name": "accessor_buffer_Cube.005_NORMAL_0", 19 | "type": "VEC3" 20 | }, 21 | { 22 | "bufferView": 20, 23 | "byteOffset": 0, 24 | "componentType": 5123, 25 | "count": 36, 26 | "max": [ 27 | 23 28 | ], 29 | "min": [ 30 | 0 31 | ], 32 | "name": "accessor_buffer_Cube.008_0", 33 | "type": "SCALAR" 34 | }, 35 | { 36 | "bufferView": 0, 37 | "byteOffset": 0, 38 | "componentType": 5126, 39 | "count": 24, 40 | "max": [ 41 | 0.7602092027664185, 42 | 1.3696330785751343, 43 | -15.84271240234375 44 | ], 45 | "min": [ 46 | -1.2397907972335815, 47 | -0.6303669214248657, 48 | -17.84271240234375 49 | ], 50 | "name": "accessor_buffer_Cube.001_POSITION_0", 51 | "type": "VEC3" 52 | }, 53 | { 54 | "bufferView": 28, 55 | "byteOffset": 0, 56 | "componentType": 5126, 57 | "count": 24, 58 | "max": [ 59 | 1.0, 60 | 1.0, 61 | 1.0 62 | ], 63 | "min": [ 64 | -1.0, 65 | -1.0, 66 | -1.0 67 | ], 68 | "name": "accessor_buffer_Cube.011_NORMAL_0", 69 | "type": "VEC3" 70 | }, 71 | { 72 | "bufferView": 53, 73 | "byteOffset": 0, 74 | "componentType": 5123, 75 | "count": 36, 76 | "max": [ 77 | 23 78 | ], 79 | "min": [ 80 | 0 81 | ], 82 | "name": "accessor_buffer_Cube.018_0", 83 | "type": "SCALAR" 84 | }, 85 | { 86 | "bufferView": 37, 87 | "byteOffset": 0, 88 | "componentType": 5126, 89 | "count": 24, 90 | "max": [ 91 | 1.0, 92 | 1.0, 93 | 1.0 94 | ], 95 | "min": [ 96 | -1.0, 97 | -1.0, 98 | -1.0 99 | ], 100 | "name": "accessor_buffer_Cube.013_NORMAL_0", 101 | "type": "VEC3" 102 | }, 103 | { 104 | "bufferView": 13, 105 | "byteOffset": 0, 106 | "componentType": 5126, 107 | "count": 24, 108 | "max": [ 109 | 1.0, 110 | 1.0, 111 | 1.0 112 | ], 113 | "min": [ 114 | -1.0, 115 | -1.0, 116 | -1.0 117 | ], 118 | "name": "accessor_buffer_Cube.006_NORMAL_0", 119 | "type": "VEC3" 120 | }, 121 | { 122 | "bufferView": 40, 123 | "byteOffset": 0, 124 | "componentType": 5126, 125 | "count": 24, 126 | "max": [ 127 | 1.0, 128 | 1.0, 129 | 1.0 130 | ], 131 | "min": [ 132 | -1.0, 133 | -1.0, 134 | -1.0 135 | ], 136 | "name": "accessor_buffer_Cube.014_NORMAL_0", 137 | "type": "VEC3" 138 | }, 139 | { 140 | "bufferView": 36, 141 | "byteOffset": 0, 142 | "componentType": 5126, 143 | "count": 24, 144 | "max": [ 145 | 0.7608523368835449, 146 | 1.326629877090454, 147 | 1.1212376356124878 148 | ], 149 | "min": [ 150 | -1.239147663116455, 151 | -0.6733701229095459, 152 | -0.878762423992157 153 | ], 154 | "name": "accessor_buffer_Cube.013_POSITION_0", 155 | "type": "VEC3" 156 | }, 157 | { 158 | "bufferView": 19, 159 | "byteOffset": 0, 160 | "componentType": 5126, 161 | "count": 24, 162 | "max": [ 163 | 1.0, 164 | 1.0, 165 | 1.0 166 | ], 167 | "min": [ 168 | -1.0, 169 | -1.0, 170 | -1.0 171 | ], 172 | "name": "accessor_buffer_Cube.008_NORMAL_0", 173 | "type": "VEC3" 174 | }, 175 | { 176 | "bufferView": 22, 177 | "byteOffset": 0, 178 | "componentType": 5126, 179 | "count": 24, 180 | "max": [ 181 | 1.0, 182 | 1.0, 183 | 1.0 184 | ], 185 | "min": [ 186 | -1.0, 187 | -1.0, 188 | -1.0 189 | ], 190 | "name": "accessor_buffer_Cube.009_NORMAL_0", 191 | "type": "VEC3" 192 | }, 193 | { 194 | "bufferView": 56, 195 | "byteOffset": 0, 196 | "componentType": 5123, 197 | "count": 240, 198 | "max": [ 199 | 155 200 | ], 201 | "min": [ 202 | 0 203 | ], 204 | "name": "accessor_buffer_Ship_0", 205 | "type": "SCALAR" 206 | }, 207 | { 208 | "bufferView": 54, 209 | "byteOffset": 0, 210 | "componentType": 5126, 211 | "count": 156, 212 | "max": [ 213 | 1.0000004768371582, 214 | 3.025548219680786, 215 | 1.0402048826217651 216 | ], 217 | "min": [ 218 | -1.0000004768371582, 219 | -1.0, 220 | -1.3253421783447266 221 | ], 222 | "name": "accessor_buffer_Ship_POSITION_0", 223 | "type": "VEC3" 224 | }, 225 | { 226 | "bufferView": 15, 227 | "byteOffset": 0, 228 | "componentType": 5126, 229 | "count": 24, 230 | "max": [ 231 | 0.7602092027664185, 232 | 1.3696330785751343, 233 | -7.29362678527832 234 | ], 235 | "min": [ 236 | -1.2397907972335815, 237 | -0.6303669214248657, 238 | -9.29362678527832 239 | ], 240 | "name": "accessor_buffer_Cube.007_POSITION_0", 241 | "type": "VEC3" 242 | }, 243 | { 244 | "bufferView": 4, 245 | "byteOffset": 0, 246 | "componentType": 5126, 247 | "count": 24, 248 | "max": [ 249 | 1.0, 250 | 1.0, 251 | 1.0 252 | ], 253 | "min": [ 254 | -1.0, 255 | -1.0, 256 | -1.0 257 | ], 258 | "name": "accessor_buffer_Cube.002_NORMAL_0", 259 | "type": "VEC3" 260 | }, 261 | { 262 | "bufferView": 42, 263 | "byteOffset": 0, 264 | "componentType": 5126, 265 | "count": 24, 266 | "max": [ 267 | 0.7602092027664185, 268 | 1.3696330785751343, 269 | 4.105154037475586 270 | ], 271 | "min": [ 272 | -1.2397907972335815, 273 | -0.6303669214248657, 274 | 2.105154037475586 275 | ], 276 | "name": "accessor_buffer_Cube.015_POSITION_0", 277 | "type": "VEC3" 278 | }, 279 | { 280 | "bufferView": 49, 281 | "byteOffset": 0, 282 | "componentType": 5126, 283 | "count": 24, 284 | "max": [ 285 | 1.0, 286 | 1.0, 287 | 1.0 288 | ], 289 | "min": [ 290 | -1.0, 291 | -1.0, 292 | -1.0 293 | ], 294 | "name": "accessor_buffer_Cube.017_NORMAL_0", 295 | "type": "VEC3" 296 | }, 297 | { 298 | "bufferView": 39, 299 | "byteOffset": 0, 300 | "componentType": 5126, 301 | "count": 24, 302 | "max": [ 303 | 5.239240646362305, 304 | 0.8294172286987305, 305 | 1.4258149862289429 306 | ], 307 | "min": [ 308 | 3.2392406463623047, 309 | -1.1705827713012695, 310 | -0.5741850137710571 311 | ], 312 | "name": "accessor_buffer_Cube.014_POSITION_0", 313 | "type": "VEC3" 314 | }, 315 | { 316 | "bufferView": 31, 317 | "byteOffset": 0, 318 | "componentType": 5126, 319 | "count": 24, 320 | "max": [ 321 | 1.0, 322 | 1.0, 323 | 1.0 324 | ], 325 | "min": [ 326 | -1.0, 327 | -1.0, 328 | -1.0 329 | ], 330 | "name": "accessor_buffer_Cube.003_NORMAL_0", 331 | "type": "VEC3" 332 | }, 333 | { 334 | "bufferView": 8, 335 | "byteOffset": 0, 336 | "componentType": 5123, 337 | "count": 36, 338 | "max": [ 339 | 23 340 | ], 341 | "min": [ 342 | 0 343 | ], 344 | "name": "accessor_buffer_Cube.004_0", 345 | "type": "SCALAR" 346 | }, 347 | { 348 | "bufferView": 35, 349 | "byteOffset": 0, 350 | "componentType": 5123, 351 | "count": 36, 352 | "max": [ 353 | 23 354 | ], 355 | "min": [ 356 | 0 357 | ], 358 | "name": "accessor_buffer_Cube.012_0", 359 | "type": "SCALAR" 360 | }, 361 | { 362 | "bufferView": 50, 363 | "byteOffset": 0, 364 | "componentType": 5123, 365 | "count": 36, 366 | "max": [ 367 | 23 368 | ], 369 | "min": [ 370 | 0 371 | ], 372 | "name": "accessor_buffer_Cube.017_0", 373 | "type": "SCALAR" 374 | }, 375 | { 376 | "bufferView": 25, 377 | "byteOffset": 0, 378 | "componentType": 5126, 379 | "count": 24, 380 | "max": [ 381 | 1.0, 382 | 1.0, 383 | 1.0 384 | ], 385 | "min": [ 386 | -1.0, 387 | -1.0, 388 | -1.0 389 | ], 390 | "name": "accessor_buffer_Cube.010_NORMAL_0", 391 | "type": "VEC3" 392 | }, 393 | { 394 | "bufferView": 29, 395 | "byteOffset": 0, 396 | "componentType": 5123, 397 | "count": 36, 398 | "max": [ 399 | 23 400 | ], 401 | "min": [ 402 | 0 403 | ], 404 | "name": "accessor_buffer_Cube.011_0", 405 | "type": "SCALAR" 406 | }, 407 | { 408 | "bufferView": 26, 409 | "byteOffset": 0, 410 | "componentType": 5123, 411 | "count": 36, 412 | "max": [ 413 | 23 414 | ], 415 | "min": [ 416 | 0 417 | ], 418 | "name": "accessor_buffer_Cube.010_0", 419 | "type": "SCALAR" 420 | }, 421 | { 422 | "bufferView": 11, 423 | "byteOffset": 0, 424 | "componentType": 5123, 425 | "count": 36, 426 | "max": [ 427 | 23 428 | ], 429 | "min": [ 430 | 0 431 | ], 432 | "name": "accessor_buffer_Cube.005_0", 433 | "type": "SCALAR" 434 | }, 435 | { 436 | "bufferView": 46, 437 | "byteOffset": 0, 438 | "componentType": 5126, 439 | "count": 24, 440 | "max": [ 441 | 1.0, 442 | 1.0, 443 | 1.0 444 | ], 445 | "min": [ 446 | -1.0, 447 | -1.0, 448 | -1.0 449 | ], 450 | "name": "accessor_buffer_Cube.016_NORMAL_0", 451 | "type": "VEC3" 452 | }, 453 | { 454 | "bufferView": 32, 455 | "byteOffset": 0, 456 | "componentType": 5123, 457 | "count": 36, 458 | "max": [ 459 | 23 460 | ], 461 | "min": [ 462 | 0 463 | ], 464 | "name": "accessor_buffer_Cube.003_0", 465 | "type": "SCALAR" 466 | }, 467 | { 468 | "bufferView": 2, 469 | "byteOffset": 0, 470 | "componentType": 5123, 471 | "count": 36, 472 | "max": [ 473 | 23 474 | ], 475 | "min": [ 476 | 0 477 | ], 478 | "name": "accessor_buffer_Cube.001_0", 479 | "type": "SCALAR" 480 | }, 481 | { 482 | "bufferView": 21, 483 | "byteOffset": 0, 484 | "componentType": 5126, 485 | "count": 24, 486 | "max": [ 487 | 0.7602090835571289, 488 | 1.3696330785751343, 489 | -4.443931579589844 490 | ], 491 | "min": [ 492 | -1.239790916442871, 493 | -0.6303669214248657, 494 | -6.443931579589844 495 | ], 496 | "name": "accessor_buffer_Cube.009_POSITION_0", 497 | "type": "VEC3" 498 | }, 499 | { 500 | "bufferView": 48, 501 | "byteOffset": 0, 502 | "componentType": 5126, 503 | "count": 24, 504 | "max": [ 505 | 0.7602092027664185, 506 | 1.3696330785751343, 507 | 6.9548492431640625 508 | ], 509 | "min": [ 510 | -1.2397907972335815, 511 | -0.6303669214248657, 512 | 4.9548492431640625 513 | ], 514 | "name": "accessor_buffer_Cube.017_POSITION_0", 515 | "type": "VEC3" 516 | }, 517 | { 518 | "bufferView": 52, 519 | "byteOffset": 0, 520 | "componentType": 5126, 521 | "count": 24, 522 | "max": [ 523 | 1.0, 524 | 1.0, 525 | 1.0 526 | ], 527 | "min": [ 528 | -1.0, 529 | -1.0, 530 | -1.0 531 | ], 532 | "name": "accessor_buffer_Cube.018_NORMAL_0", 533 | "type": "VEC3" 534 | }, 535 | { 536 | "bufferView": 12, 537 | "byteOffset": 0, 538 | "componentType": 5126, 539 | "count": 24, 540 | "max": [ 541 | 5.09255838394165, 542 | 0.8407930135726929, 543 | -9.960822105407715 544 | ], 545 | "min": [ 546 | 3.0925583839416504, 547 | -1.1592069864273071, 548 | -11.960822105407715 549 | ], 550 | "name": "accessor_buffer_Cube.006_POSITION_0", 551 | "type": "VEC3" 552 | }, 553 | { 554 | "bufferView": 34, 555 | "byteOffset": 0, 556 | "componentType": 5126, 557 | "count": 24, 558 | "max": [ 559 | 1.0, 560 | 1.0, 561 | 1.0 562 | ], 563 | "min": [ 564 | -1.0, 565 | -1.0, 566 | -1.0 567 | ], 568 | "name": "accessor_buffer_Cube.012_NORMAL_0", 569 | "type": "VEC3" 570 | }, 571 | { 572 | "bufferView": 24, 573 | "byteOffset": 0, 574 | "componentType": 5126, 575 | "count": 24, 576 | "max": [ 577 | 5.09255838394165, 578 | 0.8407930135726929, 579 | -7.111126899719238 580 | ], 581 | "min": [ 582 | 3.0925583839416504, 583 | -1.1592069864273071, 584 | -9.111126899719238 585 | ], 586 | "name": "accessor_buffer_Cube.010_POSITION_0", 587 | "type": "VEC3" 588 | }, 589 | { 590 | "bufferView": 7, 591 | "byteOffset": 0, 592 | "componentType": 5126, 593 | "count": 24, 594 | "max": [ 595 | 1.0, 596 | 1.0, 597 | 1.0 598 | ], 599 | "min": [ 600 | -1.0, 601 | -1.0, 602 | -1.0 603 | ], 604 | "name": "accessor_buffer_Cube.004_NORMAL_0", 605 | "type": "VEC3" 606 | }, 607 | { 608 | "bufferView": 55, 609 | "byteOffset": 0, 610 | "componentType": 5126, 611 | "count": 156, 612 | "max": [ 613 | 0.9999610781669617, 614 | 0.9994784593582153, 615 | 0.9999734163284302 616 | ], 617 | "min": [ 618 | -0.9999610781669617, 619 | -0.814764142036438, 620 | -0.999954879283905 621 | ], 622 | "name": "accessor_buffer_Ship_NORMAL_0", 623 | "type": "VEC3" 624 | }, 625 | { 626 | "bufferView": 14, 627 | "byteOffset": 0, 628 | "componentType": 5123, 629 | "count": 36, 630 | "max": [ 631 | 23 632 | ], 633 | "min": [ 634 | 0 635 | ], 636 | "name": "accessor_buffer_Cube.006_0", 637 | "type": "SCALAR" 638 | }, 639 | { 640 | "bufferView": 33, 641 | "byteOffset": 0, 642 | "componentType": 5126, 643 | "count": 24, 644 | "max": [ 645 | 5.09255838394165, 646 | 0.8407930135726929, 647 | -7.111126899719238 648 | ], 649 | "min": [ 650 | 3.0925583839416504, 651 | -1.1592069864273071, 652 | -9.111126899719238 653 | ], 654 | "name": "accessor_buffer_Cube.012_POSITION_0", 655 | "type": "VEC3" 656 | }, 657 | { 658 | "bufferView": 44, 659 | "byteOffset": 0, 660 | "componentType": 5123, 661 | "count": 36, 662 | "max": [ 663 | 23 664 | ], 665 | "min": [ 666 | 0 667 | ], 668 | "name": "accessor_buffer_Cube.015_0", 669 | "type": "SCALAR" 670 | }, 671 | { 672 | "bufferView": 18, 673 | "byteOffset": 0, 674 | "componentType": 5126, 675 | "count": 24, 676 | "max": [ 677 | 5.09255838394165, 678 | 0.8407930135726929, 679 | -7.111126899719238 680 | ], 681 | "min": [ 682 | 3.0925583839416504, 683 | -1.1592069864273071, 684 | -9.111126899719238 685 | ], 686 | "name": "accessor_buffer_Cube.008_POSITION_0", 687 | "type": "VEC3" 688 | }, 689 | { 690 | "bufferView": 47, 691 | "byteOffset": 0, 692 | "componentType": 5123, 693 | "count": 36, 694 | "max": [ 695 | 23 696 | ], 697 | "min": [ 698 | 0 699 | ], 700 | "name": "accessor_buffer_Cube.016_0", 701 | "type": "SCALAR" 702 | }, 703 | { 704 | "bufferView": 38, 705 | "byteOffset": 0, 706 | "componentType": 5123, 707 | "count": 36, 708 | "max": [ 709 | 23 710 | ], 711 | "min": [ 712 | 0 713 | ], 714 | "name": "accessor_buffer_Cube.013_0", 715 | "type": "SCALAR" 716 | }, 717 | { 718 | "bufferView": 51, 719 | "byteOffset": 0, 720 | "componentType": 5126, 721 | "count": 24, 722 | "max": [ 723 | 5.09255838394165, 724 | 0.8407930135726929, 725 | 7.137348175048828 726 | ], 727 | "min": [ 728 | 3.0925583839416504, 729 | -1.1592069864273071, 730 | 5.137348175048828 731 | ], 732 | "name": "accessor_buffer_Cube.018_POSITION_0", 733 | "type": "VEC3" 734 | }, 735 | { 736 | "bufferView": 17, 737 | "byteOffset": 0, 738 | "componentType": 5123, 739 | "count": 36, 740 | "max": [ 741 | 23 742 | ], 743 | "min": [ 744 | 0 745 | ], 746 | "name": "accessor_buffer_Cube.007_0", 747 | "type": "SCALAR" 748 | }, 749 | { 750 | "bufferView": 5, 751 | "byteOffset": 0, 752 | "componentType": 5123, 753 | "count": 36, 754 | "max": [ 755 | 23 756 | ], 757 | "min": [ 758 | 0 759 | ], 760 | "name": "accessor_buffer_Cube.002_0", 761 | "type": "SCALAR" 762 | }, 763 | { 764 | "bufferView": 45, 765 | "byteOffset": 0, 766 | "componentType": 5126, 767 | "count": 24, 768 | "max": [ 769 | 5.092557907104492, 770 | 0.8407930135726929, 771 | 4.287652969360352 772 | ], 773 | "min": [ 774 | 3.092557907104492, 775 | -1.1592069864273071, 776 | 2.2876532077789307 777 | ], 778 | "name": "accessor_buffer_Cube.016_POSITION_0", 779 | "type": "VEC3" 780 | }, 781 | { 782 | "bufferView": 16, 783 | "byteOffset": 0, 784 | "componentType": 5126, 785 | "count": 24, 786 | "max": [ 787 | 1.0, 788 | 1.0, 789 | 1.0 790 | ], 791 | "min": [ 792 | -1.0, 793 | -1.0, 794 | -1.0 795 | ], 796 | "name": "accessor_buffer_Cube.007_NORMAL_0", 797 | "type": "VEC3" 798 | }, 799 | { 800 | "bufferView": 43, 801 | "byteOffset": 0, 802 | "componentType": 5126, 803 | "count": 24, 804 | "max": [ 805 | 1.0, 806 | 1.0, 807 | 1.0 808 | ], 809 | "min": [ 810 | -1.0, 811 | -1.0, 812 | -1.0 813 | ], 814 | "name": "accessor_buffer_Cube.015_NORMAL_0", 815 | "type": "VEC3" 816 | }, 817 | { 818 | "bufferView": 23, 819 | "byteOffset": 0, 820 | "componentType": 5123, 821 | "count": 36, 822 | "max": [ 823 | 23 824 | ], 825 | "min": [ 826 | 0 827 | ], 828 | "name": "accessor_buffer_Cube.009_0", 829 | "type": "SCALAR" 830 | }, 831 | { 832 | "bufferView": 30, 833 | "byteOffset": 0, 834 | "componentType": 5126, 835 | "count": 24, 836 | "max": [ 837 | 0.7602090835571289, 838 | 1.3696330785751343, 839 | -12.993017196655273 840 | ], 841 | "min": [ 842 | -1.239790916442871, 843 | -0.6303669214248657, 844 | -14.993017196655273 845 | ], 846 | "name": "accessor_buffer_Cube.003_POSITION_0", 847 | "type": "VEC3" 848 | }, 849 | { 850 | "bufferView": 1, 851 | "byteOffset": 0, 852 | "componentType": 5126, 853 | "count": 24, 854 | "max": [ 855 | 1.0, 856 | 1.0, 857 | 1.0 858 | ], 859 | "min": [ 860 | -1.0, 861 | -1.0, 862 | -1.0 863 | ], 864 | "name": "accessor_buffer_Cube.001_NORMAL_0", 865 | "type": "VEC3" 866 | }, 867 | { 868 | "bufferView": 27, 869 | "byteOffset": 0, 870 | "componentType": 5126, 871 | "count": 24, 872 | "max": [ 873 | 0.7602090835571289, 874 | 1.3696330785751343, 875 | -1.5942363739013672 876 | ], 877 | "min": [ 878 | -1.239790916442871, 879 | -0.6303669214248657, 880 | -3.594236373901367 881 | ], 882 | "name": "accessor_buffer_Cube.011_POSITION_0", 883 | "type": "VEC3" 884 | }, 885 | { 886 | "bufferView": 9, 887 | "byteOffset": 0, 888 | "componentType": 5126, 889 | "count": 24, 890 | "max": [ 891 | 0.7602090835571289, 892 | 1.3696330785751343, 893 | -10.143322944641113 894 | ], 895 | "min": [ 896 | -1.239790916442871, 897 | -0.6303669214248657, 898 | -12.143322944641113 899 | ], 900 | "name": "accessor_buffer_Cube.005_POSITION_0", 901 | "type": "VEC3" 902 | }, 903 | { 904 | "bufferView": 3, 905 | "byteOffset": 0, 906 | "componentType": 5126, 907 | "count": 24, 908 | "max": [ 909 | 5.09255838394165, 910 | 0.8407930135726929, 911 | -15.660213470458984 912 | ], 913 | "min": [ 914 | 3.0925583839416504, 915 | -1.1592069864273071, 916 | -17.660213470458984 917 | ], 918 | "name": "accessor_buffer_Cube.002_POSITION_0", 919 | "type": "VEC3" 920 | }, 921 | { 922 | "bufferView": 6, 923 | "byteOffset": 0, 924 | "componentType": 5126, 925 | "count": 24, 926 | "max": [ 927 | 5.092557907104492, 928 | 0.8407930135726929, 929 | -12.810516357421875 930 | ], 931 | "min": [ 932 | 3.092557907104492, 933 | -1.1592069864273071, 934 | -14.810516357421875 935 | ], 936 | "name": "accessor_buffer_Cube.004_POSITION_0", 937 | "type": "VEC3" 938 | }, 939 | { 940 | "bufferView": 41, 941 | "byteOffset": 0, 942 | "componentType": 5123, 943 | "count": 36, 944 | "max": [ 945 | 23 946 | ], 947 | "min": [ 948 | 0 949 | ], 950 | "name": "accessor_buffer_Cube.014_0", 951 | "type": "SCALAR" 952 | } 953 | ], 954 | "asset": { 955 | "copyright": "", 956 | "generator": "blendergltf v1.2.0", 957 | "version": "2.0" 958 | }, 959 | "bufferViews": [ 960 | { 961 | "buffer": 0, 962 | "byteLength": 288, 963 | "byteOffset": 0, 964 | "byteStride": 12, 965 | "name": "bufferView_buffer_Cube.001_POSITION_0", 966 | "target": 34962 967 | }, 968 | { 969 | "buffer": 0, 970 | "byteLength": 288, 971 | "byteOffset": 288, 972 | "byteStride": 12, 973 | "name": "bufferView_buffer_Cube.001_NORMAL_0", 974 | "target": 34962 975 | }, 976 | { 977 | "buffer": 0, 978 | "byteLength": 76, 979 | "byteOffset": 576, 980 | "name": "bufferView_buffer_Cube.001_0", 981 | "target": 34963 982 | }, 983 | { 984 | "buffer": 0, 985 | "byteLength": 288, 986 | "byteOffset": 652, 987 | "byteStride": 12, 988 | "name": "bufferView_buffer_Cube.002_POSITION_0", 989 | "target": 34962 990 | }, 991 | { 992 | "buffer": 0, 993 | "byteLength": 288, 994 | "byteOffset": 940, 995 | "byteStride": 12, 996 | "name": "bufferView_buffer_Cube.002_NORMAL_0", 997 | "target": 34962 998 | }, 999 | { 1000 | "buffer": 0, 1001 | "byteLength": 76, 1002 | "byteOffset": 1228, 1003 | "name": "bufferView_buffer_Cube.002_0", 1004 | "target": 34963 1005 | }, 1006 | { 1007 | "buffer": 0, 1008 | "byteLength": 288, 1009 | "byteOffset": 1304, 1010 | "byteStride": 12, 1011 | "name": "bufferView_buffer_Cube.004_POSITION_0", 1012 | "target": 34962 1013 | }, 1014 | { 1015 | "buffer": 0, 1016 | "byteLength": 288, 1017 | "byteOffset": 1592, 1018 | "byteStride": 12, 1019 | "name": "bufferView_buffer_Cube.004_NORMAL_0", 1020 | "target": 34962 1021 | }, 1022 | { 1023 | "buffer": 0, 1024 | "byteLength": 76, 1025 | "byteOffset": 1880, 1026 | "name": "bufferView_buffer_Cube.004_0", 1027 | "target": 34963 1028 | }, 1029 | { 1030 | "buffer": 0, 1031 | "byteLength": 288, 1032 | "byteOffset": 1956, 1033 | "byteStride": 12, 1034 | "name": "bufferView_buffer_Cube.005_POSITION_0", 1035 | "target": 34962 1036 | }, 1037 | { 1038 | "buffer": 0, 1039 | "byteLength": 288, 1040 | "byteOffset": 2244, 1041 | "byteStride": 12, 1042 | "name": "bufferView_buffer_Cube.005_NORMAL_0", 1043 | "target": 34962 1044 | }, 1045 | { 1046 | "buffer": 0, 1047 | "byteLength": 76, 1048 | "byteOffset": 2532, 1049 | "name": "bufferView_buffer_Cube.005_0", 1050 | "target": 34963 1051 | }, 1052 | { 1053 | "buffer": 0, 1054 | "byteLength": 288, 1055 | "byteOffset": 2608, 1056 | "byteStride": 12, 1057 | "name": "bufferView_buffer_Cube.006_POSITION_0", 1058 | "target": 34962 1059 | }, 1060 | { 1061 | "buffer": 0, 1062 | "byteLength": 288, 1063 | "byteOffset": 2896, 1064 | "byteStride": 12, 1065 | "name": "bufferView_buffer_Cube.006_NORMAL_0", 1066 | "target": 34962 1067 | }, 1068 | { 1069 | "buffer": 0, 1070 | "byteLength": 76, 1071 | "byteOffset": 3184, 1072 | "name": "bufferView_buffer_Cube.006_0", 1073 | "target": 34963 1074 | }, 1075 | { 1076 | "buffer": 0, 1077 | "byteLength": 288, 1078 | "byteOffset": 3260, 1079 | "byteStride": 12, 1080 | "name": "bufferView_buffer_Cube.007_POSITION_0", 1081 | "target": 34962 1082 | }, 1083 | { 1084 | "buffer": 0, 1085 | "byteLength": 288, 1086 | "byteOffset": 3548, 1087 | "byteStride": 12, 1088 | "name": "bufferView_buffer_Cube.007_NORMAL_0", 1089 | "target": 34962 1090 | }, 1091 | { 1092 | "buffer": 0, 1093 | "byteLength": 76, 1094 | "byteOffset": 3836, 1095 | "name": "bufferView_buffer_Cube.007_0", 1096 | "target": 34963 1097 | }, 1098 | { 1099 | "buffer": 0, 1100 | "byteLength": 288, 1101 | "byteOffset": 3912, 1102 | "byteStride": 12, 1103 | "name": "bufferView_buffer_Cube.008_POSITION_0", 1104 | "target": 34962 1105 | }, 1106 | { 1107 | "buffer": 0, 1108 | "byteLength": 288, 1109 | "byteOffset": 4200, 1110 | "byteStride": 12, 1111 | "name": "bufferView_buffer_Cube.008_NORMAL_0", 1112 | "target": 34962 1113 | }, 1114 | { 1115 | "buffer": 0, 1116 | "byteLength": 76, 1117 | "byteOffset": 4488, 1118 | "name": "bufferView_buffer_Cube.008_0", 1119 | "target": 34963 1120 | }, 1121 | { 1122 | "buffer": 0, 1123 | "byteLength": 288, 1124 | "byteOffset": 4564, 1125 | "byteStride": 12, 1126 | "name": "bufferView_buffer_Cube.009_POSITION_0", 1127 | "target": 34962 1128 | }, 1129 | { 1130 | "buffer": 0, 1131 | "byteLength": 288, 1132 | "byteOffset": 4852, 1133 | "byteStride": 12, 1134 | "name": "bufferView_buffer_Cube.009_NORMAL_0", 1135 | "target": 34962 1136 | }, 1137 | { 1138 | "buffer": 0, 1139 | "byteLength": 76, 1140 | "byteOffset": 5140, 1141 | "name": "bufferView_buffer_Cube.009_0", 1142 | "target": 34963 1143 | }, 1144 | { 1145 | "buffer": 0, 1146 | "byteLength": 288, 1147 | "byteOffset": 5216, 1148 | "byteStride": 12, 1149 | "name": "bufferView_buffer_Cube.010_POSITION_0", 1150 | "target": 34962 1151 | }, 1152 | { 1153 | "buffer": 0, 1154 | "byteLength": 288, 1155 | "byteOffset": 5504, 1156 | "byteStride": 12, 1157 | "name": "bufferView_buffer_Cube.010_NORMAL_0", 1158 | "target": 34962 1159 | }, 1160 | { 1161 | "buffer": 0, 1162 | "byteLength": 76, 1163 | "byteOffset": 5792, 1164 | "name": "bufferView_buffer_Cube.010_0", 1165 | "target": 34963 1166 | }, 1167 | { 1168 | "buffer": 0, 1169 | "byteLength": 288, 1170 | "byteOffset": 5868, 1171 | "byteStride": 12, 1172 | "name": "bufferView_buffer_Cube.011_POSITION_0", 1173 | "target": 34962 1174 | }, 1175 | { 1176 | "buffer": 0, 1177 | "byteLength": 288, 1178 | "byteOffset": 6156, 1179 | "byteStride": 12, 1180 | "name": "bufferView_buffer_Cube.011_NORMAL_0", 1181 | "target": 34962 1182 | }, 1183 | { 1184 | "buffer": 0, 1185 | "byteLength": 76, 1186 | "byteOffset": 6444, 1187 | "name": "bufferView_buffer_Cube.011_0", 1188 | "target": 34963 1189 | }, 1190 | { 1191 | "buffer": 0, 1192 | "byteLength": 288, 1193 | "byteOffset": 6520, 1194 | "byteStride": 12, 1195 | "name": "bufferView_buffer_Cube.003_POSITION_0", 1196 | "target": 34962 1197 | }, 1198 | { 1199 | "buffer": 0, 1200 | "byteLength": 288, 1201 | "byteOffset": 6808, 1202 | "byteStride": 12, 1203 | "name": "bufferView_buffer_Cube.003_NORMAL_0", 1204 | "target": 34962 1205 | }, 1206 | { 1207 | "buffer": 0, 1208 | "byteLength": 76, 1209 | "byteOffset": 7096, 1210 | "name": "bufferView_buffer_Cube.003_0", 1211 | "target": 34963 1212 | }, 1213 | { 1214 | "buffer": 0, 1215 | "byteLength": 288, 1216 | "byteOffset": 7172, 1217 | "byteStride": 12, 1218 | "name": "bufferView_buffer_Cube.012_POSITION_0", 1219 | "target": 34962 1220 | }, 1221 | { 1222 | "buffer": 0, 1223 | "byteLength": 288, 1224 | "byteOffset": 7460, 1225 | "byteStride": 12, 1226 | "name": "bufferView_buffer_Cube.012_NORMAL_0", 1227 | "target": 34962 1228 | }, 1229 | { 1230 | "buffer": 0, 1231 | "byteLength": 76, 1232 | "byteOffset": 7748, 1233 | "name": "bufferView_buffer_Cube.012_0", 1234 | "target": 34963 1235 | }, 1236 | { 1237 | "buffer": 0, 1238 | "byteLength": 288, 1239 | "byteOffset": 7824, 1240 | "byteStride": 12, 1241 | "name": "bufferView_buffer_Cube.013_POSITION_0", 1242 | "target": 34962 1243 | }, 1244 | { 1245 | "buffer": 0, 1246 | "byteLength": 288, 1247 | "byteOffset": 8112, 1248 | "byteStride": 12, 1249 | "name": "bufferView_buffer_Cube.013_NORMAL_0", 1250 | "target": 34962 1251 | }, 1252 | { 1253 | "buffer": 0, 1254 | "byteLength": 76, 1255 | "byteOffset": 8400, 1256 | "name": "bufferView_buffer_Cube.013_0", 1257 | "target": 34963 1258 | }, 1259 | { 1260 | "buffer": 0, 1261 | "byteLength": 288, 1262 | "byteOffset": 8476, 1263 | "byteStride": 12, 1264 | "name": "bufferView_buffer_Cube.014_POSITION_0", 1265 | "target": 34962 1266 | }, 1267 | { 1268 | "buffer": 0, 1269 | "byteLength": 288, 1270 | "byteOffset": 8764, 1271 | "byteStride": 12, 1272 | "name": "bufferView_buffer_Cube.014_NORMAL_0", 1273 | "target": 34962 1274 | }, 1275 | { 1276 | "buffer": 0, 1277 | "byteLength": 76, 1278 | "byteOffset": 9052, 1279 | "name": "bufferView_buffer_Cube.014_0", 1280 | "target": 34963 1281 | }, 1282 | { 1283 | "buffer": 0, 1284 | "byteLength": 288, 1285 | "byteOffset": 9128, 1286 | "byteStride": 12, 1287 | "name": "bufferView_buffer_Cube.015_POSITION_0", 1288 | "target": 34962 1289 | }, 1290 | { 1291 | "buffer": 0, 1292 | "byteLength": 288, 1293 | "byteOffset": 9416, 1294 | "byteStride": 12, 1295 | "name": "bufferView_buffer_Cube.015_NORMAL_0", 1296 | "target": 34962 1297 | }, 1298 | { 1299 | "buffer": 0, 1300 | "byteLength": 76, 1301 | "byteOffset": 9704, 1302 | "name": "bufferView_buffer_Cube.015_0", 1303 | "target": 34963 1304 | }, 1305 | { 1306 | "buffer": 0, 1307 | "byteLength": 288, 1308 | "byteOffset": 9780, 1309 | "byteStride": 12, 1310 | "name": "bufferView_buffer_Cube.016_POSITION_0", 1311 | "target": 34962 1312 | }, 1313 | { 1314 | "buffer": 0, 1315 | "byteLength": 288, 1316 | "byteOffset": 10068, 1317 | "byteStride": 12, 1318 | "name": "bufferView_buffer_Cube.016_NORMAL_0", 1319 | "target": 34962 1320 | }, 1321 | { 1322 | "buffer": 0, 1323 | "byteLength": 76, 1324 | "byteOffset": 10356, 1325 | "name": "bufferView_buffer_Cube.016_0", 1326 | "target": 34963 1327 | }, 1328 | { 1329 | "buffer": 0, 1330 | "byteLength": 288, 1331 | "byteOffset": 10432, 1332 | "byteStride": 12, 1333 | "name": "bufferView_buffer_Cube.017_POSITION_0", 1334 | "target": 34962 1335 | }, 1336 | { 1337 | "buffer": 0, 1338 | "byteLength": 288, 1339 | "byteOffset": 10720, 1340 | "byteStride": 12, 1341 | "name": "bufferView_buffer_Cube.017_NORMAL_0", 1342 | "target": 34962 1343 | }, 1344 | { 1345 | "buffer": 0, 1346 | "byteLength": 76, 1347 | "byteOffset": 11008, 1348 | "name": "bufferView_buffer_Cube.017_0", 1349 | "target": 34963 1350 | }, 1351 | { 1352 | "buffer": 0, 1353 | "byteLength": 288, 1354 | "byteOffset": 11084, 1355 | "byteStride": 12, 1356 | "name": "bufferView_buffer_Cube.018_POSITION_0", 1357 | "target": 34962 1358 | }, 1359 | { 1360 | "buffer": 0, 1361 | "byteLength": 288, 1362 | "byteOffset": 11372, 1363 | "byteStride": 12, 1364 | "name": "bufferView_buffer_Cube.018_NORMAL_0", 1365 | "target": 34962 1366 | }, 1367 | { 1368 | "buffer": 0, 1369 | "byteLength": 76, 1370 | "byteOffset": 11660, 1371 | "name": "bufferView_buffer_Cube.018_0", 1372 | "target": 34963 1373 | }, 1374 | { 1375 | "buffer": 0, 1376 | "byteLength": 1872, 1377 | "byteOffset": 11736, 1378 | "byteStride": 12, 1379 | "name": "bufferView_buffer_Ship_POSITION_0", 1380 | "target": 34962 1381 | }, 1382 | { 1383 | "buffer": 0, 1384 | "byteLength": 1872, 1385 | "byteOffset": 13608, 1386 | "byteStride": 12, 1387 | "name": "bufferView_buffer_Ship_NORMAL_0", 1388 | "target": 34962 1389 | }, 1390 | { 1391 | "buffer": 0, 1392 | "byteLength": 484, 1393 | "byteOffset": 15480, 1394 | "name": "bufferView_buffer_Ship_0", 1395 | "target": 34963 1396 | } 1397 | ], 1398 | "buffers": [ 1399 | { 1400 | "byteLength": 15964, 1401 | "name": "buffer_ShipEmbeddedData", 1402 | "uri": "data:application/octet-stream;base64,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AACAvwAAAAAAAIA/AAAAAAAAAAAAAAAAAACAvwAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgL8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAgD8AAIC/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAIA/AAAAAAAAAAAAAAAAAACAvwAAAAAAAAAAAACAPwAAAAAFABUACwAFAAsACQAAAA0ADwAAAA8AEQAOAAMACAAOAAgABwAKAAwAAQAKAAEAEgAWAAQAFAAWABQABgAXABAAAgAXAAIAEwAAAAAAPfaiQDY+Vz9ajuPAeuxFQOVglL8txxHBPfaiQOVglL8txxHBeuxFQOVglL9ajuPAeuxFQDY+Vz8txxHBPfaiQDY+Vz9ajuPAPfaiQDY+Vz8txxHBPfaiQDY+Vz9ajuPAeuxFQDY+Vz8txxHBPfaiQOVglL8txxHBeuxFQOVglL9ajuPAeuxFQDY+Vz9ajuPAPfaiQOVglL8txxHBeuxFQDY+Vz9ajuPAPfaiQOVglL9ajuPAeuxFQDY+Vz9ajuPAPfaiQDY+Vz8txxHBeuxFQDY+Vz8txxHBeuxFQOVglL9ajuPAPfaiQDY+Vz8txxHBeuxFQOVglL8txxHBPfaiQOVglL9ajuPAeuxFQOVglL8txxHBPfaiQOVglL9ajuPAAAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AACAvwAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/DgAMABMADgATAAUA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" 1403 | } 1404 | ], 1405 | "cameras": [ 1406 | { 1407 | "name": "Camera.001", 1408 | "perspective": { 1409 | "aspectRatio": 1.703595982340029, 1410 | "yfov": 0.5033799409866333, 1411 | "zfar": 100.0, 1412 | "znear": 0.10000000149011612 1413 | }, 1414 | "type": "perspective" 1415 | } 1416 | ], 1417 | "materials": [ 1418 | { 1419 | "alphaMode": "OPAQUE", 1420 | "doubleSided": false, 1421 | "emissiveFactor": [ 1422 | 0.0, 1423 | 0.0, 1424 | 0.0 1425 | ], 1426 | "name": "Material.001", 1427 | "pbrMetallicRoughness": { 1428 | "baseColorFactor": [ 1429 | 0.021564489230513573, 1430 | 0.02377510443329811, 1431 | 0.6400001049041748, 1432 | 1.0 1433 | ], 1434 | "metallicFactor": 0.0, 1435 | "roughnessFactor": 1.0 1436 | } 1437 | }, 1438 | { 1439 | "alphaMode": "OPAQUE", 1440 | "doubleSided": false, 1441 | "emissiveFactor": [ 1442 | 0.0, 1443 | 0.0, 1444 | 0.0 1445 | ], 1446 | "name": "Material.002", 1447 | "pbrMetallicRoughness": { 1448 | "baseColorFactor": [ 1449 | 0.6400001049041748, 1450 | 0.013424338772892952, 1451 | 0.017599131911993027, 1452 | 1.0 1453 | ], 1454 | "metallicFactor": 0.0, 1455 | "roughnessFactor": 1.0 1456 | } 1457 | }, 1458 | { 1459 | "alphaMode": "OPAQUE", 1460 | "doubleSided": false, 1461 | "emissiveFactor": [ 1462 | 0.0, 1463 | 0.0, 1464 | 0.0 1465 | ], 1466 | "name": "Material.003", 1467 | "pbrMetallicRoughness": { 1468 | "baseColorFactor": [ 1469 | 0.08976385742425919, 1470 | 0.6400001049041748, 1471 | 0.06009329482913017, 1472 | 1.0 1473 | ], 1474 | "metallicFactor": 0.0, 1475 | "roughnessFactor": 1.0 1476 | } 1477 | }, 1478 | { 1479 | "alphaMode": "OPAQUE", 1480 | "doubleSided": false, 1481 | "emissiveFactor": [ 1482 | 0.0, 1483 | 0.0, 1484 | 0.0 1485 | ], 1486 | "name": "Material.006", 1487 | "pbrMetallicRoughness": { 1488 | "baseColorFactor": [ 1489 | 0.5218515396118164, 1490 | 0.04227364435791969, 1491 | 0.6400001049041748, 1492 | 1.0 1493 | ], 1494 | "metallicFactor": 0.0, 1495 | "roughnessFactor": 1.0 1496 | } 1497 | }, 1498 | { 1499 | "alphaMode": "OPAQUE", 1500 | "doubleSided": false, 1501 | "emissiveFactor": [ 1502 | 0.0, 1503 | 0.0, 1504 | 0.0 1505 | ], 1506 | "name": "Material.009", 1507 | "pbrMetallicRoughness": { 1508 | "baseColorFactor": [ 1509 | 0.6400001049041748, 1510 | 0.035741813480854034, 1511 | 0.3557143211364746, 1512 | 1.0 1513 | ], 1514 | "metallicFactor": 0.0, 1515 | "roughnessFactor": 1.0 1516 | } 1517 | }, 1518 | { 1519 | "alphaMode": "OPAQUE", 1520 | "doubleSided": false, 1521 | "emissiveFactor": [ 1522 | 0.0, 1523 | 0.0, 1524 | 0.0 1525 | ], 1526 | "name": "Material.005", 1527 | "pbrMetallicRoughness": { 1528 | "baseColorFactor": [ 1529 | 0.6400001049041748, 1530 | 0.33255523443222046, 1531 | 0.03057171404361725, 1532 | 1.0 1533 | ], 1534 | "metallicFactor": 0.0, 1535 | "roughnessFactor": 1.0 1536 | } 1537 | }, 1538 | { 1539 | "alphaMode": "OPAQUE", 1540 | "doubleSided": false, 1541 | "emissiveFactor": [ 1542 | 0.0, 1543 | 0.0, 1544 | 0.0 1545 | ], 1546 | "name": "Material.007", 1547 | "pbrMetallicRoughness": { 1548 | "baseColorFactor": [ 1549 | 0.009393058717250824, 1550 | 0.40776780247688293, 1551 | 0.3419612646102905, 1552 | 1.0 1553 | ], 1554 | "metallicFactor": 0.0, 1555 | "roughnessFactor": 1.0 1556 | } 1557 | }, 1558 | { 1559 | "alphaMode": "OPAQUE", 1560 | "doubleSided": false, 1561 | "emissiveFactor": [ 1562 | 0.0, 1563 | 0.0, 1564 | 0.0 1565 | ], 1566 | "name": "Material.011", 1567 | "pbrMetallicRoughness": { 1568 | "baseColorFactor": [ 1569 | 0.22355523705482483, 1570 | 0.28393545746803284, 1571 | 0.47844839096069336, 1572 | 1.0 1573 | ], 1574 | "metallicFactor": 0.0, 1575 | "roughnessFactor": 1.0 1576 | } 1577 | }, 1578 | { 1579 | "alphaMode": "OPAQUE", 1580 | "doubleSided": false, 1581 | "emissiveFactor": [ 1582 | 0.0, 1583 | 0.0, 1584 | 0.0 1585 | ], 1586 | "name": "Material.013", 1587 | "pbrMetallicRoughness": { 1588 | "baseColorFactor": [ 1589 | 0.64000004529953, 1590 | 0.64000004529953, 1591 | 0.64000004529953, 1592 | 1.0 1593 | ], 1594 | "metallicFactor": 0.0, 1595 | "roughnessFactor": 1.0 1596 | } 1597 | }, 1598 | { 1599 | "alphaMode": "OPAQUE", 1600 | "doubleSided": false, 1601 | "emissiveFactor": [ 1602 | 0.0, 1603 | 0.0, 1604 | 0.0 1605 | ], 1606 | "name": "Material.012", 1607 | "pbrMetallicRoughness": { 1608 | "baseColorFactor": [ 1609 | 0.05623451620340347, 1610 | 0.040419451892375946, 1611 | 0.47844839096069336, 1612 | 1.0 1613 | ], 1614 | "metallicFactor": 0.0, 1615 | "roughnessFactor": 1.0 1616 | } 1617 | }, 1618 | { 1619 | "alphaMode": "OPAQUE", 1620 | "doubleSided": false, 1621 | "emissiveFactor": [ 1622 | 0.0, 1623 | 0.0, 1624 | 0.0 1625 | ], 1626 | "name": "Material.017", 1627 | "pbrMetallicRoughness": { 1628 | "baseColorFactor": [ 1629 | 0.04617961496114731, 1630 | 0.15913055837154388, 1631 | 0.6400001049041748, 1632 | 1.0 1633 | ], 1634 | "metallicFactor": 0.0, 1635 | "roughnessFactor": 1.0 1636 | } 1637 | }, 1638 | { 1639 | "alphaMode": "OPAQUE", 1640 | "doubleSided": false, 1641 | "emissiveFactor": [ 1642 | 0.0, 1643 | 0.0, 1644 | 0.0 1645 | ], 1646 | "name": "Material.008", 1647 | "pbrMetallicRoughness": { 1648 | "baseColorFactor": [ 1649 | 0.47844839096069336, 1650 | 0.07706750929355621, 1651 | 0.07706750929355621, 1652 | 1.0 1653 | ], 1654 | "metallicFactor": 0.0, 1655 | "roughnessFactor": 1.0 1656 | } 1657 | }, 1658 | { 1659 | "alphaMode": "OPAQUE", 1660 | "doubleSided": false, 1661 | "emissiveFactor": [ 1662 | 0.0, 1663 | 0.0, 1664 | 0.0 1665 | ], 1666 | "name": "Material.004", 1667 | "pbrMetallicRoughness": { 1668 | "baseColorFactor": [ 1669 | 0.64000004529953, 1670 | 0.64000004529953, 1671 | 0.64000004529953, 1672 | 1.0 1673 | ], 1674 | "metallicFactor": 0.0, 1675 | "roughnessFactor": 1.0 1676 | } 1677 | }, 1678 | { 1679 | "alphaMode": "OPAQUE", 1680 | "doubleSided": false, 1681 | "emissiveFactor": [ 1682 | 0.0, 1683 | 0.0, 1684 | 0.0 1685 | ], 1686 | "name": "Material.010", 1687 | "pbrMetallicRoughness": { 1688 | "baseColorFactor": [ 1689 | 0.47844839096069336, 1690 | 0.07706750929355621, 1691 | 0.07706750929355621, 1692 | 1.0 1693 | ], 1694 | "metallicFactor": 0.0, 1695 | "roughnessFactor": 1.0 1696 | } 1697 | }, 1698 | { 1699 | "alphaMode": "OPAQUE", 1700 | "doubleSided": false, 1701 | "emissiveFactor": [ 1702 | 0.0, 1703 | 0.0, 1704 | 0.0 1705 | ], 1706 | "name": "Material.015", 1707 | "pbrMetallicRoughness": { 1708 | "baseColorFactor": [ 1709 | 0.5558028817176819, 1710 | 0.052333831787109375, 1711 | 0.32666316628456116, 1712 | 1.0 1713 | ], 1714 | "metallicFactor": 0.0, 1715 | "roughnessFactor": 1.0 1716 | } 1717 | }, 1718 | { 1719 | "alphaMode": "OPAQUE", 1720 | "doubleSided": false, 1721 | "emissiveFactor": [ 1722 | 0.0, 1723 | 0.0, 1724 | 0.0 1725 | ], 1726 | "name": "Material.016", 1727 | "pbrMetallicRoughness": { 1728 | "baseColorFactor": [ 1729 | 0.6400001049041748, 1730 | 0.5102136731147766, 1731 | 0.5809768438339233, 1732 | 1.0 1733 | ], 1734 | "metallicFactor": 0.0, 1735 | "roughnessFactor": 1.0 1736 | } 1737 | }, 1738 | { 1739 | "alphaMode": "OPAQUE", 1740 | "doubleSided": false, 1741 | "emissiveFactor": [ 1742 | 0.0, 1743 | 0.0, 1744 | 0.0 1745 | ], 1746 | "name": "Material.018", 1747 | "pbrMetallicRoughness": { 1748 | "baseColorFactor": [ 1749 | 0.64000004529953, 1750 | 0.64000004529953, 1751 | 0.64000004529953, 1752 | 1.0 1753 | ], 1754 | "metallicFactor": 0.0, 1755 | "roughnessFactor": 1.0 1756 | } 1757 | }, 1758 | { 1759 | "alphaMode": "OPAQUE", 1760 | "doubleSided": false, 1761 | "emissiveFactor": [ 1762 | 0.0, 1763 | 0.0, 1764 | 0.0 1765 | ], 1766 | "name": "Material.014", 1767 | "pbrMetallicRoughness": { 1768 | "baseColorFactor": [ 1769 | 0.17459358274936676, 1770 | 0.09626726061105728, 1771 | 0.6400001049041748, 1772 | 1.0 1773 | ], 1774 | "metallicFactor": 0.0, 1775 | "roughnessFactor": 1.0 1776 | } 1777 | }, 1778 | { 1779 | "alphaMode": "BLEND", 1780 | "doubleSided": false, 1781 | "emissiveFactor": [ 1782 | 0.0, 1783 | 0.0, 1784 | 0.0 1785 | ], 1786 | "name": "ShipMaterial", 1787 | "pbrMetallicRoughness": { 1788 | "baseColorFactor": [ 1789 | 0.011161921545863152, 1790 | 0.025630850344896317, 1791 | 0.6400001049041748, 1792 | 0.30000001192092896 1793 | ], 1794 | "metallicFactor": 0.0, 1795 | "roughnessFactor": 1.0 1796 | } 1797 | } 1798 | ], 1799 | "meshes": [ 1800 | { 1801 | "name": "Cube.001", 1802 | "primitives": [ 1803 | { 1804 | "attributes": { 1805 | "NORMAL": 51, 1806 | "POSITION": 2 1807 | }, 1808 | "indices": 28, 1809 | "material": 0, 1810 | "mode": 4 1811 | } 1812 | ] 1813 | }, 1814 | { 1815 | "name": "Cube.002", 1816 | "primitives": [ 1817 | { 1818 | "attributes": { 1819 | "NORMAL": 14, 1820 | "POSITION": 54 1821 | }, 1822 | "indices": 45, 1823 | "material": 1, 1824 | "mode": 4 1825 | } 1826 | ] 1827 | }, 1828 | { 1829 | "name": "Cube.004", 1830 | "primitives": [ 1831 | { 1832 | "attributes": { 1833 | "NORMAL": 35, 1834 | "POSITION": 55 1835 | }, 1836 | "indices": 19, 1837 | "material": 12, 1838 | "mode": 4 1839 | } 1840 | ] 1841 | }, 1842 | { 1843 | "name": "Cube.005", 1844 | "primitives": [ 1845 | { 1846 | "attributes": { 1847 | "NORMAL": 0, 1848 | "POSITION": 53 1849 | }, 1850 | "indices": 25, 1851 | "material": 5, 1852 | "mode": 4 1853 | } 1854 | ] 1855 | }, 1856 | { 1857 | "name": "Cube.006", 1858 | "primitives": [ 1859 | { 1860 | "attributes": { 1861 | "NORMAL": 6, 1862 | "POSITION": 32 1863 | }, 1864 | "indices": 37, 1865 | "material": 3, 1866 | "mode": 4 1867 | } 1868 | ] 1869 | }, 1870 | { 1871 | "name": "Cube.007", 1872 | "primitives": [ 1873 | { 1874 | "attributes": { 1875 | "NORMAL": 47, 1876 | "POSITION": 13 1877 | }, 1878 | "indices": 44, 1879 | "material": 6, 1880 | "mode": 4 1881 | } 1882 | ] 1883 | }, 1884 | { 1885 | "name": "Cube.008", 1886 | "primitives": [ 1887 | { 1888 | "attributes": { 1889 | "NORMAL": 9, 1890 | "POSITION": 40 1891 | }, 1892 | "indices": 1, 1893 | "material": 11, 1894 | "mode": 4 1895 | } 1896 | ] 1897 | }, 1898 | { 1899 | "name": "Cube.009", 1900 | "primitives": [ 1901 | { 1902 | "attributes": { 1903 | "NORMAL": 10, 1904 | "POSITION": 29 1905 | }, 1906 | "indices": 49, 1907 | "material": 4, 1908 | "mode": 4 1909 | } 1910 | ] 1911 | }, 1912 | { 1913 | "name": "Cube.010", 1914 | "primitives": [ 1915 | { 1916 | "attributes": { 1917 | "NORMAL": 22, 1918 | "POSITION": 34 1919 | }, 1920 | "indices": 24, 1921 | "material": 13, 1922 | "mode": 4 1923 | } 1924 | ] 1925 | }, 1926 | { 1927 | "name": "Cube.011", 1928 | "primitives": [ 1929 | { 1930 | "attributes": { 1931 | "NORMAL": 3, 1932 | "POSITION": 52 1933 | }, 1934 | "indices": 23, 1935 | "material": 7, 1936 | "mode": 4 1937 | } 1938 | ] 1939 | }, 1940 | { 1941 | "name": "Cube.003", 1942 | "primitives": [ 1943 | { 1944 | "attributes": { 1945 | "NORMAL": 18, 1946 | "POSITION": 50 1947 | }, 1948 | "indices": 27, 1949 | "material": 2, 1950 | "mode": 4 1951 | } 1952 | ] 1953 | }, 1954 | { 1955 | "name": "Cube.012", 1956 | "primitives": [ 1957 | { 1958 | "attributes": { 1959 | "NORMAL": 33, 1960 | "POSITION": 38 1961 | }, 1962 | "indices": 20, 1963 | "material": 9, 1964 | "mode": 4 1965 | } 1966 | ] 1967 | }, 1968 | { 1969 | "name": "Cube.013", 1970 | "primitives": [ 1971 | { 1972 | "attributes": { 1973 | "NORMAL": 5, 1974 | "POSITION": 8 1975 | }, 1976 | "indices": 42, 1977 | "material": 8, 1978 | "mode": 4 1979 | } 1980 | ] 1981 | }, 1982 | { 1983 | "name": "Cube.014", 1984 | "primitives": [ 1985 | { 1986 | "attributes": { 1987 | "NORMAL": 7, 1988 | "POSITION": 17 1989 | }, 1990 | "indices": 56, 1991 | "material": 17, 1992 | "mode": 4 1993 | } 1994 | ] 1995 | }, 1996 | { 1997 | "name": "Cube.015", 1998 | "primitives": [ 1999 | { 2000 | "attributes": { 2001 | "NORMAL": 48, 2002 | "POSITION": 15 2003 | }, 2004 | "indices": 39, 2005 | "material": 14, 2006 | "mode": 4 2007 | } 2008 | ] 2009 | }, 2010 | { 2011 | "name": "Cube.016", 2012 | "primitives": [ 2013 | { 2014 | "attributes": { 2015 | "NORMAL": 26, 2016 | "POSITION": 46 2017 | }, 2018 | "indices": 41, 2019 | "material": 15, 2020 | "mode": 4 2021 | } 2022 | ] 2023 | }, 2024 | { 2025 | "name": "Cube.017", 2026 | "primitives": [ 2027 | { 2028 | "attributes": { 2029 | "NORMAL": 16, 2030 | "POSITION": 30 2031 | }, 2032 | "indices": 21, 2033 | "material": 10, 2034 | "mode": 4 2035 | } 2036 | ] 2037 | }, 2038 | { 2039 | "name": "Cube.018", 2040 | "primitives": [ 2041 | { 2042 | "attributes": { 2043 | "NORMAL": 31, 2044 | "POSITION": 43 2045 | }, 2046 | "indices": 4, 2047 | "material": 16, 2048 | "mode": 4 2049 | } 2050 | ] 2051 | }, 2052 | { 2053 | "name": "Ship", 2054 | "primitives": [ 2055 | { 2056 | "attributes": { 2057 | "NORMAL": 36, 2058 | "POSITION": 12 2059 | }, 2060 | "indices": 11, 2061 | "material": 18, 2062 | "mode": 4 2063 | } 2064 | ] 2065 | } 2066 | ], 2067 | "nodes": [ 2068 | { 2069 | "camera": 0, 2070 | "name": "Camera", 2071 | "rotation": [ 2072 | 0.00984931830316782, 2073 | -0.6973533034324646, 2074 | 0.004520733840763569, 2075 | 0.7166455984115601 2076 | ], 2077 | "scale": [ 2078 | 1.0, 2079 | 1.0, 2080 | 1.0 2081 | ], 2082 | "translation": [ 2083 | -16.00542640686035, 2084 | 3.4683210849761963, 2085 | 1.0995675325393677 2086 | ] 2087 | }, 2088 | { 2089 | "extras": { 2090 | "COLOR_COMPLAINTS": "yellow", 2091 | "COLOR_REPAIRS": "red", 2092 | "COMPLAINTS": 4.0, 2093 | "REPAIRS": 5.0, 2094 | "REVENUE": 500.0 2095 | }, 2096 | "mesh": 0, 2097 | "name": "R001", 2098 | "rotation": [ 2099 | 0.0, 2100 | -2.781550267894062e-10, 2101 | 0.0, 2102 | 1.0 2103 | ], 2104 | "scale": [ 2105 | 0.2367301732301712, 2106 | 0.35091471672058105, 2107 | 0.0523158460855484 2108 | ], 2109 | "translation": [ 2110 | -0.4531175196170807, 2111 | 0.29518646001815796, 2112 | -0.00537625327706337 2113 | ] 2114 | }, 2115 | { 2116 | "extras": { 2117 | "COLOR_COMPLAINTS": "green", 2118 | "COLOR_REPAIRS": "green", 2119 | "COMPLAINTS": 3.0, 2120 | "REPAIRS": 0.0, 2121 | "REVENUE": 2018.0 2122 | }, 2123 | "mesh": 1, 2124 | "name": "R002", 2125 | "rotation": [ 2126 | 0.0, 2127 | -2.781550267894062e-10, 2128 | 0.0, 2129 | 1.0 2130 | ], 2131 | "scale": [ 2132 | 0.2367301732301712, 2133 | 0.35091471672058105, 2134 | 0.0523158460855484 2135 | ], 2136 | "translation": [ 2137 | -0.4358316957950592, 2138 | 0.4807642102241516, 2139 | -0.014923859387636185 2140 | ] 2141 | }, 2142 | { 2143 | "extras": { 2144 | "COLOR_COMPLAINTS": "red", 2145 | "COLOR_REPAIRS": "green", 2146 | "COMPLAINTS": 4.0, 2147 | "REPAIRS": 1.0, 2148 | "REVENUE": 1553.0 2149 | }, 2150 | "mesh": 10, 2151 | "name": "R003", 2152 | "rotation": [ 2153 | 0.0, 2154 | -2.781550267894062e-10, 2155 | 0.0, 2156 | 1.0 2157 | ], 2158 | "scale": [ 2159 | 0.2367301732301712, 2160 | 0.35091471672058105, 2161 | 0.0523158460855484 2162 | ], 2163 | "translation": [ 2164 | -0.4531174898147583, 2165 | 0.29518646001815796, 2166 | -0.005376212298870087 2167 | ] 2168 | }, 2169 | { 2170 | "extras": { 2171 | "COLOR_COMPLAINTS": "red", 2172 | "COLOR_REPAIRS": "green", 2173 | "COMPLAINTS": 5.0, 2174 | "REPAIRS": 1.0, 2175 | "REVENUE": 2950.0 2176 | }, 2177 | "mesh": 2, 2178 | "name": "R004", 2179 | "rotation": [ 2180 | 0.0, 2181 | -2.781550267894062e-10, 2182 | 0.0, 2183 | 1.0 2184 | ], 2185 | "scale": [ 2186 | 0.2367301732301712, 2187 | 0.35091471672058105, 2188 | 0.0523158460855484 2189 | ], 2190 | "translation": [ 2191 | -0.43583154678344727, 2192 | 0.4807642102241516, 2193 | -0.014923986047506332 2194 | ] 2195 | }, 2196 | { 2197 | "extras": { 2198 | "COLOR_COMPLAINTS": "green", 2199 | "COLOR_REPAIRS": "red", 2200 | "COMPLAINTS": 3.0, 2201 | "REPAIRS": 6.0, 2202 | "REVENUE": 1496.0 2203 | }, 2204 | "mesh": 3, 2205 | "name": "R005", 2206 | "rotation": [ 2207 | 0.0, 2208 | -2.781550267894062e-10, 2209 | 0.0, 2210 | 1.0 2211 | ], 2212 | "scale": [ 2213 | 0.2367301732301712, 2214 | 0.35091471672058105, 2215 | 0.0523158460855484 2216 | ], 2217 | "translation": [ 2218 | -0.4531174898147583, 2219 | 0.29518646001815796, 2220 | -0.005376212298870087 2221 | ] 2222 | }, 2223 | { 2224 | "extras": { 2225 | "COLOR_COMPLAINTS": "red", 2226 | "COLOR_REPAIRS": "red", 2227 | "COMPLAINTS": 7.0, 2228 | "REPAIRS": 6.0, 2229 | "REVENUE": 1252.0 2230 | }, 2231 | "mesh": 4, 2232 | "name": "R006", 2233 | "rotation": [ 2234 | 0.0, 2235 | -2.781550267894062e-10, 2236 | 0.0, 2237 | 1.0 2238 | ], 2239 | "scale": [ 2240 | 0.2367301732301712, 2241 | 0.35091471672058105, 2242 | 0.0523158460855484 2243 | ], 2244 | "translation": [ 2245 | -0.4358316957950592, 2246 | 0.4807642102241516, 2247 | -0.014923900365829468 2248 | ] 2249 | }, 2250 | { 2251 | "extras": { 2252 | "COLOR_COMPLAINTS": "green", 2253 | "COLOR_REPAIRS": "red", 2254 | "COMPLAINTS": 2.0, 2255 | "REPAIRS": 4.0, 2256 | "REVENUE": 2109.0 2257 | }, 2258 | "mesh": 5, 2259 | "name": "R007", 2260 | "rotation": [ 2261 | 0.0, 2262 | -2.781550267894062e-10, 2263 | 0.0, 2264 | 1.0 2265 | ], 2266 | "scale": [ 2267 | 0.2367301732301712, 2268 | 0.35091471672058105, 2269 | 0.0523158460855484 2270 | ], 2271 | "translation": [ 2272 | -0.4531175196170807, 2273 | 0.29518646001815796, 2274 | -0.00537625327706337 2275 | ] 2276 | }, 2277 | { 2278 | "extras": { 2279 | "COLOR_COMPLAINTS": "green", 2280 | "COLOR_REPAIRS": "red", 2281 | "COMPLAINTS": 2.0, 2282 | "REPAIRS": 5.0, 2283 | "REVENUE": 1032.0 2284 | }, 2285 | "mesh": 6, 2286 | "name": "R008", 2287 | "rotation": [ 2288 | 0.0, 2289 | -2.781550267894062e-10, 2290 | 0.0, 2291 | 1.0 2292 | ], 2293 | "scale": [ 2294 | 0.2367301732301712, 2295 | 0.35091471672058105, 2296 | 0.0523158460855484 2297 | ], 2298 | "translation": [ 2299 | -0.449323832988739, 2300 | 0.48076432943344116, 2301 | -0.014924798160791397 2302 | ] 2303 | }, 2304 | { 2305 | "extras": { 2306 | "COLOR_COMPLAINTS": "green", 2307 | "COLOR_REPAIRS": "green", 2308 | "COMPLAINTS": 2.0, 2309 | "REPAIRS": 1.0, 2310 | "REVENUE": 1101.0 2311 | }, 2312 | "mesh": 7, 2313 | "name": "R009", 2314 | "rotation": [ 2315 | 0.0, 2316 | -2.781550267894062e-10, 2317 | 0.0, 2318 | 1.0 2319 | ], 2320 | "scale": [ 2321 | 0.2367301732301712, 2322 | 0.35091471672058105, 2323 | 0.0523158460855484 2324 | ], 2325 | "translation": [ 2326 | -0.4531174898147583, 2327 | 0.29518646001815796, 2328 | -0.00537625327706337 2329 | ] 2330 | }, 2331 | { 2332 | "extras": { 2333 | "COLOR_COMPLAINTS": "green", 2334 | "COLOR_REPAIRS": "green", 2335 | "COMPLAINTS": 1.0, 2336 | "REPAIRS": 3.0, 2337 | "REVENUE": 1930.0 2338 | }, 2339 | "mesh": 8, 2340 | "name": "R010", 2341 | "rotation": [ 2342 | 0.0, 2343 | -2.781550267894062e-10, 2344 | 0.0, 2345 | 1.0 2346 | ], 2347 | "scale": [ 2348 | 0.2367301732301712, 2349 | 0.35091471672058105, 2350 | 0.0523158460855484 2351 | ], 2352 | "translation": [ 2353 | -0.44932398200035095, 2354 | 0.48076432943344116, 2355 | 0.13772907853126526 2356 | ] 2357 | }, 2358 | { 2359 | "extras": { 2360 | "COLOR_COMPLAINTS": "red", 2361 | "COLOR_REPAIRS": "red", 2362 | "COMPLAINTS": 4.0, 2363 | "REPAIRS": 4.0, 2364 | "REVENUE": 1193.0 2365 | }, 2366 | "mesh": 9, 2367 | "name": "R011", 2368 | "rotation": [ 2369 | 0.0, 2370 | -2.781550267894062e-10, 2371 | 0.0, 2372 | 1.0 2373 | ], 2374 | "scale": [ 2375 | 0.2367301732301712, 2376 | 0.35091471672058105, 2377 | 0.0523158460855484 2378 | ], 2379 | "translation": [ 2380 | -0.4531174898147583, 2381 | 0.29518646001815796, 2382 | -0.013029724359512329 2383 | ] 2384 | }, 2385 | { 2386 | "extras": { 2387 | "COLOR_COMPLAINTS": "red", 2388 | "COLOR_REPAIRS": "green", 2389 | "COMPLAINTS": 6.0, 2390 | "REPAIRS": 3.0, 2391 | "REVENUE": 2791.0 2392 | }, 2393 | "mesh": 11, 2394 | "name": "R012", 2395 | "rotation": [ 2396 | 0.0, 2397 | -2.781550267894062e-10, 2398 | 0.0, 2399 | 1.0 2400 | ], 2401 | "scale": [ 2402 | 0.2367301732301712, 2403 | 0.35091471672058105, 2404 | 0.0523158460855484 2405 | ], 2406 | "translation": [ 2407 | -0.44932395219802856, 2408 | 0.48076432943344116, 2409 | 0.27559104561805725 2410 | ] 2411 | }, 2412 | { 2413 | "extras": { 2414 | "COLOR_COMPLAINTS": "green", 2415 | "COLOR_REPAIRS": "red", 2416 | "COMPLAINTS": 3.0, 2417 | "REPAIRS": 5.0, 2418 | "REVENUE": 1578.0 2419 | }, 2420 | "mesh": 12, 2421 | "name": "R013", 2422 | "rotation": [ 2423 | 0.0, 2424 | -2.781550267894062e-10, 2425 | 0.0, 2426 | 1.0 2427 | ], 2428 | "scale": [ 2429 | 0.2367301732301712, 2430 | 0.35091471672058105, 2431 | 0.0523158460855484 2432 | ], 2433 | "translation": [ 2434 | -0.45326974987983704, 2435 | 0.31027692556381226, 2436 | -0.002182982861995697 2437 | ] 2438 | }, 2439 | { 2440 | "extras": { 2441 | "COLOR_COMPLAINTS": "red", 2442 | "COLOR_REPAIRS": "red", 2443 | "COMPLAINTS": 5.0, 2444 | "REPAIRS": 5.0, 2445 | "REVENUE": 2183.0 2446 | }, 2447 | "mesh": 13, 2448 | "name": "R014", 2449 | "rotation": [ 2450 | 0.0, 2451 | -2.781550267894062e-10, 2452 | 0.0, 2453 | 1.0 2454 | ], 2455 | "scale": [ 2456 | 0.2367301732301712, 2457 | 0.35091471672058105, 2458 | 0.0523158460855484 2459 | ], 2460 | "translation": [ 2461 | -0.47055578231811523, 2462 | 0.4847561717033386, 2463 | -0.018117204308509827 2464 | ] 2465 | }, 2466 | { 2467 | "extras": { 2468 | "COLOR_COMPLAINTS": "green", 2469 | "COLOR_REPAIRS": "green", 2470 | "COMPLAINTS": 3.0, 2471 | "REPAIRS": 0.0, 2472 | "REVENUE": 2007.0 2473 | }, 2474 | "mesh": 14, 2475 | "name": "R015", 2476 | "rotation": [ 2477 | 0.0, 2478 | -2.781550267894062e-10, 2479 | 0.0, 2480 | 1.0 2481 | ], 2482 | "scale": [ 2483 | 0.2367301732301712, 2484 | 0.35091471672058105, 2485 | 0.0523158460855484 2486 | ], 2487 | "translation": [ 2488 | -0.4531175196170807, 2489 | 0.29518646001815796, 2490 | -0.00537625327706337 2491 | ] 2492 | }, 2493 | { 2494 | "extras": { 2495 | "COLOR_COMPLAINTS": "red", 2496 | "COLOR_REPAIRS": "green", 2497 | "COMPLAINTS": 5.0, 2498 | "REPAIRS": 3.0, 2499 | "REVENUE": 2424.0 2500 | }, 2501 | "mesh": 15, 2502 | "name": "R016", 2503 | "rotation": [ 2504 | 0.0, 2505 | -2.781550267894062e-10, 2506 | 0.0, 2507 | 1.0 2508 | ], 2509 | "scale": [ 2510 | 0.2367301732301712, 2511 | 0.35091471672058105, 2512 | 0.0523158460855484 2513 | ], 2514 | "translation": [ 2515 | -0.43583154678344727, 2516 | 0.4807642102241516, 2517 | -0.014923859387636185 2518 | ] 2519 | }, 2520 | { 2521 | "extras": { 2522 | "COLOR_COMPLAINTS": "red", 2523 | "COLOR_REPAIRS": "green", 2524 | "COMPLAINTS": 5.0, 2525 | "REPAIRS": 2.0, 2526 | "REVENUE": 2724.0 2527 | }, 2528 | "mesh": 16, 2529 | "name": "R017", 2530 | "rotation": [ 2531 | 0.0, 2532 | -2.781550267894062e-10, 2533 | 0.0, 2534 | 1.0 2535 | ], 2536 | "scale": [ 2537 | 0.2367301732301712, 2538 | 0.35091471672058105, 2539 | 0.0523158460855484 2540 | ], 2541 | "translation": [ 2542 | -0.4531175196170807, 2543 | 0.29518646001815796, 2544 | -0.00537625327706337 2545 | ] 2546 | }, 2547 | { 2548 | "extras": { 2549 | "COLOR_COMPLAINTS": "green", 2550 | "COLOR_REPAIRS": "red", 2551 | "COMPLAINTS": 3.0, 2552 | "REPAIRS": 5.0, 2553 | "REVENUE": 1870.0 2554 | }, 2555 | "mesh": 17, 2556 | "name": "R018", 2557 | "rotation": [ 2558 | 0.0, 2559 | -2.781550267894062e-10, 2560 | 0.0, 2561 | 1.0 2562 | ], 2563 | "scale": [ 2564 | 0.2367301732301712, 2565 | 0.35091471672058105, 2566 | 0.0523158460855484 2567 | ], 2568 | "translation": [ 2569 | -0.4358316957950592, 2570 | 0.4807642102241516, 2571 | -0.014923859387636185 2572 | ] 2573 | }, 2574 | { 2575 | "children": [ 2576 | 1, 2577 | 2, 2578 | 3, 2579 | 4, 2580 | 5, 2581 | 6, 2582 | 7, 2583 | 8, 2584 | 9, 2585 | 10, 2586 | 11, 2587 | 12, 2588 | 13, 2589 | 14, 2590 | 15, 2591 | 16, 2592 | 17, 2593 | 18 2594 | ], 2595 | "mesh": 18, 2596 | "name": "Ship", 2597 | "rotation": [ 2598 | 0.0, 2599 | 0.7061503529548645, 2600 | 0.0, 2601 | 0.708061933517456 2602 | ], 2603 | "scale": [ 2604 | 1.4823403358459473, 2605 | 1.0, 2606 | 5.768738746643066 2607 | ], 2608 | "translation": [ 2609 | 0.34868693351745605, 2610 | 0.7266053557395935, 2611 | 0.06296022236347198 2612 | ] 2613 | }, 2614 | { 2615 | "name": "Sun", 2616 | "rotation": [ 2617 | 0.0, 2618 | 0.7071068286895752, 2619 | 0.7071068286895752, 2620 | 0.0 2621 | ], 2622 | "scale": [ 2623 | 1.0, 2624 | 1.0, 2625 | 1.0 2626 | ], 2627 | "translation": [ 2628 | 2.5011940002441406, 2629 | 15.717901229858398, 2630 | 1.2353296279907227 2631 | ] 2632 | } 2633 | ], 2634 | "scene": 0, 2635 | "scenes": [ 2636 | { 2637 | "extras": { 2638 | "active_camera": -1, 2639 | "background_color": [ 2640 | 0.05087608844041824, 2641 | 0.05087608844041824, 2642 | 0.05087608844041824 2643 | ], 2644 | "frames_per_second": 24 2645 | }, 2646 | "name": "Scene", 2647 | "nodes": [ 2648 | 0, 2649 | 20, 2650 | 19 2651 | ] 2652 | } 2653 | ] 2654 | } 2655 | -------------------------------------------------------------------------------- /repository/TruckEmbeddedData.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/707da0e594ff9a51f0c559f1b6096cb0916380c8/repository/TruckEmbeddedData.glb -------------------------------------------------------------------------------- /test/AddOnScreenShot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/707da0e594ff9a51f0c559f1b6096cb0916380c8/test/AddOnScreenShot.png -------------------------------------------------------------------------------- /test/test.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/707da0e594ff9a51f0c559f1b6096cb0916380c8/test/test.blend -------------------------------------------------------------------------------- /test/test.csv: -------------------------------------------------------------------------------- 1 | "Mesh","value" 2 | "Cube.000",10 3 | "Cube.001",20 -------------------------------------------------------------------------------- /test/test.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "accessors": [ 3 | { 4 | "bufferView": 4, 5 | "byteOffset": 0, 6 | "componentType": 5126, 7 | "count": 24, 8 | "max": [ 9 | 1.0, 10 | 1.0, 11 | 1.0 12 | ], 13 | "min": [ 14 | -1.0, 15 | -1.0, 16 | -1.0 17 | ], 18 | "name": "accessor_buffer_Cube.001_NORMAL_0", 19 | "type": "VEC3" 20 | }, 21 | { 22 | "bufferView": 5, 23 | "byteOffset": 0, 24 | "componentType": 5123, 25 | "count": 36, 26 | "max": [ 27 | 23 28 | ], 29 | "min": [ 30 | 0 31 | ], 32 | "name": "accessor_buffer_Cube.001_0", 33 | "type": "SCALAR" 34 | }, 35 | { 36 | "bufferView": 1, 37 | "byteOffset": 0, 38 | "componentType": 5126, 39 | "count": 24, 40 | "max": [ 41 | 1.0, 42 | 1.0, 43 | 1.0 44 | ], 45 | "min": [ 46 | -1.0, 47 | -1.0, 48 | -1.0 49 | ], 50 | "name": "accessor_buffer_Cube.000_NORMAL_0", 51 | "type": "VEC3" 52 | }, 53 | { 54 | "bufferView": 3, 55 | "byteOffset": 0, 56 | "componentType": 5126, 57 | "count": 24, 58 | "max": [ 59 | 1.0000003576278687, 60 | 1.0, 61 | 1.0000003576278687 62 | ], 63 | "min": [ 64 | -1.0000004768371582, 65 | -1.0, 66 | -1.0000005960464478 67 | ], 68 | "name": "accessor_buffer_Cube.001_POSITION_0", 69 | "type": "VEC3" 70 | }, 71 | { 72 | "bufferView": 2, 73 | "byteOffset": 0, 74 | "componentType": 5123, 75 | "count": 36, 76 | "max": [ 77 | 23 78 | ], 79 | "min": [ 80 | 0 81 | ], 82 | "name": "accessor_buffer_Cube.000_0", 83 | "type": "SCALAR" 84 | }, 85 | { 86 | "bufferView": 0, 87 | "byteOffset": 0, 88 | "componentType": 5126, 89 | "count": 24, 90 | "max": [ 91 | 1.0000003576278687, 92 | 1.0, 93 | 1.0000003576278687 94 | ], 95 | "min": [ 96 | -1.0000004768371582, 97 | -1.0, 98 | -1.0000005960464478 99 | ], 100 | "name": "accessor_buffer_Cube.000_POSITION_0", 101 | "type": "VEC3" 102 | } 103 | ], 104 | "asset": { 105 | "copyright": "", 106 | "generator": "blendergltf v1.2.0", 107 | "version": "2.0" 108 | }, 109 | "bufferViews": [ 110 | { 111 | "buffer": 0, 112 | "byteLength": 288, 113 | "byteOffset": 0, 114 | "byteStride": 12, 115 | "name": "bufferView_buffer_Cube.000_POSITION_0", 116 | "target": 34962 117 | }, 118 | { 119 | "buffer": 0, 120 | "byteLength": 288, 121 | "byteOffset": 288, 122 | "byteStride": 12, 123 | "name": "bufferView_buffer_Cube.000_NORMAL_0", 124 | "target": 34962 125 | }, 126 | { 127 | "buffer": 0, 128 | "byteLength": 76, 129 | "byteOffset": 576, 130 | "name": "bufferView_buffer_Cube.000_0", 131 | "target": 34963 132 | }, 133 | { 134 | "buffer": 0, 135 | "byteLength": 288, 136 | "byteOffset": 652, 137 | "byteStride": 12, 138 | "name": "bufferView_buffer_Cube.001_POSITION_0", 139 | "target": 34962 140 | }, 141 | { 142 | "buffer": 0, 143 | "byteLength": 288, 144 | "byteOffset": 940, 145 | "byteStride": 12, 146 | "name": "bufferView_buffer_Cube.001_NORMAL_0", 147 | "target": 34962 148 | }, 149 | { 150 | "buffer": 0, 151 | "byteLength": 76, 152 | "byteOffset": 1228, 153 | "name": "bufferView_buffer_Cube.001_0", 154 | "target": 34963 155 | } 156 | ], 157 | "buffers": [ 158 | { 159 | "byteLength": 1304, 160 | "name": "buffer_test", 161 | "uri": "data:application/octet-stream;base64,//9/PwAAgD8AAIA/AACAvwAAgL8AAIC/+v9/PwAAgL8DAIA/9f9/vwAAgD8FAIC///9/PwAAgD8AAIA///9/PwAAgD8AAIA/+v9/PwAAgL8DAIA/AACAvwAAgL///38/BACAvwAAgD/3/38/AACAvwAAgL///38/AQCAPwAAgL/9/3+/AACAvwAAgL8AAIC/9f9/vwAAgD8FAIC/AwCAPwAAgD/6/3+/AQCAPwAAgL/9/3+/AACAvwAAgL8AAIC/AwCAPwAAgD/6/3+/BACAvwAAgD/3/38/AQCAPwAAgL/9/3+/AwCAPwAAgD/6/3+/AACAvwAAgL///38/9f9/vwAAgD8FAIC/+v9/PwAAgL8DAIA/BACAvwAAgD/3/38/AACAP/3//7MAAHA0AACAv/j/vzMAAJi0AACAP/3//7MAAHA0AQCANAgA4LMAAIC/AAAAAAAAgD8AAAAAAACQtAAAYDQAAIA/AACQtAAAYDQAAIA/AACQtAAAYDQAAIA/AACAv/j/vzMAAJi0AACAv/j/vzMAAJi0AAAAAAAAgL8AAACzAAAAAAAAgL8AAACzAACAv/j/vzMAAJi0AACAP/3//7MAAHA0AACAP/3//7MAAHA0AQCANAgA4LMAAIC/AAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAQCANAgA4LMAAIC/AQCANAgA4LMAAIC/AAAAAAAAgL8AAACzAAAAAAAAgD8AAAAAAAAAAAAAgL8AAACzAACQtAAAYDQAAIA/FgAUAAsAFgALAAoAFQARAAQAFQAEABAAAQAJAAgAAQAIAAwAEgAPAAMAEgADABMAAgAOAA0AAgANAAAABQAXAAcABQAHAAYAAAAAAP//fz8AAIA/AACAPwAAgL8AAIC/AACAv/r/fz8AAIC/AwCAP/X/f78AAIA/BQCAv///fz8AAIA/AACAP///fz8AAIA/AACAP/r/fz8AAIC/AwCAPwAAgL8AAIC///9/PwQAgL8AAIA/9/9/PwAAgL8AAIC///9/PwEAgD8AAIC//f9/vwAAgL8AAIC/AACAv/X/f78AAIA/BQCAvwMAgD8AAIA/+v9/vwEAgD8AAIC//f9/vwAAgL8AAIC/AACAvwMAgD8AAIA/+v9/vwQAgL8AAIA/9/9/PwEAgD8AAIC//f9/vwMAgD8AAIA/+v9/vwAAgL8AAIC///9/P/X/f78AAIA/BQCAv/r/fz8AAIC/AwCAPwQAgL8AAIA/9/9/PwAAgD/9//+zAABwNAAAgL/4/78zAACYtAAAgD/9//+zAABwNAEAgDQIAOCzAACAvwAAAAAAAIA/AAAAAAAAkLQAAGA0AACAPwAAkLQAAGA0AACAPwAAkLQAAGA0AACAPwAAgL/4/78zAACYtAAAgL/4/78zAACYtAAAAAAAAIC/AAAAswAAAAAAAIC/AAAAswAAgL/4/78zAACYtAAAgD/9//+zAABwNAAAgD/9//+zAABwNAEAgDQIAOCzAACAvwAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAEAgDQIAOCzAACAvwEAgDQIAOCzAACAvwAAAAAAAIC/AAAAswAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAswAAkLQAAGA0AACAPxYAFAALABYACwAKABUAEQAEABUABAAQAAEACQAIAAEACAAMABIADwADABIAAwATAAIADgANAAIADQAAAAUAFwAHAAUABwAGAAAAAAA=" 162 | } 163 | ], 164 | "cameras": [ 165 | { 166 | "name": "Camera", 167 | "perspective": { 168 | "aspectRatio": 1.703595982340029, 169 | "yfov": 0.5033799409866333, 170 | "zfar": 100.0, 171 | "znear": 0.10000000149011612 172 | }, 173 | "type": "perspective" 174 | } 175 | ], 176 | "materials": [ 177 | { 178 | "alphaMode": "OPAQUE", 179 | "doubleSided": false, 180 | "emissiveFactor": [ 181 | 0.0, 182 | 0.0, 183 | 0.0 184 | ], 185 | "name": "Material", 186 | "pbrMetallicRoughness": { 187 | "baseColorFactor": [ 188 | 0.64000004529953, 189 | 0.64000004529953, 190 | 0.64000004529953, 191 | 1.0 192 | ], 193 | "metallicFactor": 0.0, 194 | "roughnessFactor": 1.0 195 | } 196 | }, 197 | { 198 | "alphaMode": "OPAQUE", 199 | "doubleSided": false, 200 | "emissiveFactor": [ 201 | 0.0, 202 | 0.0, 203 | 0.0 204 | ], 205 | "name": "Material.001", 206 | "pbrMetallicRoughness": { 207 | "baseColorFactor": [ 208 | 0.64000004529953, 209 | 0.64000004529953, 210 | 0.64000004529953, 211 | 1.0 212 | ], 213 | "metallicFactor": 0.0, 214 | "roughnessFactor": 1.0 215 | } 216 | } 217 | ], 218 | "meshes": [ 219 | { 220 | "name": "Cube.000", 221 | "primitives": [ 222 | { 223 | "attributes": { 224 | "NORMAL": 2, 225 | "POSITION": 5 226 | }, 227 | "indices": 4, 228 | "material": 0, 229 | "mode": 4 230 | } 231 | ] 232 | }, 233 | { 234 | "name": "Cube.001", 235 | "primitives": [ 236 | { 237 | "attributes": { 238 | "NORMAL": 0, 239 | "POSITION": 3 240 | }, 241 | "indices": 1, 242 | "material": 1, 243 | "mode": 4 244 | } 245 | ] 246 | } 247 | ], 248 | "nodes": [ 249 | { 250 | "camera": 0, 251 | "name": "Camera", 252 | "rotation": [ 253 | -0.09062843769788742, 254 | -0.8937962651252747, 255 | -0.2099730223417282, 256 | 0.38578000664711 257 | ], 258 | "scale": [ 259 | 1.0, 260 | 1.0, 261 | 1.0 262 | ], 263 | "translation": [ 264 | -7.481131553649902, 265 | 5.34366512298584, 266 | -6.5076398849487305 267 | ] 268 | }, 269 | { 270 | "extras": { 271 | "value": 10.0 272 | }, 273 | "mesh": 0, 274 | "name": "Cube000", 275 | "rotation": [ 276 | 0.0, 277 | 0.0, 278 | 0.0, 279 | 1.0 280 | ], 281 | "scale": [ 282 | 1.0, 283 | 1.0, 284 | 1.0 285 | ], 286 | "translation": [ 287 | 0.0, 288 | 0.0, 289 | -2.45224666595459 290 | ] 291 | }, 292 | { 293 | "extras": { 294 | "value": 20.0 295 | }, 296 | "mesh": 1, 297 | "name": "Cube001", 298 | "rotation": [ 299 | 0.0, 300 | 0.0, 301 | 0.0, 302 | 1.0 303 | ], 304 | "scale": [ 305 | 1.0, 306 | 1.0, 307 | 1.0 308 | ], 309 | "translation": [ 310 | 0.0, 311 | 0.0, 312 | 2.235616683959961 313 | ] 314 | }, 315 | { 316 | "name": "Lamp", 317 | "rotation": [ 318 | -0.34203386306762695, 319 | -0.5232755541801453, 320 | -0.2841663062572479, 321 | 0.7269423007965088 322 | ], 323 | "scale": [ 324 | 1.0, 325 | 1.0, 326 | 0.9999999403953552 327 | ], 328 | "translation": [ 329 | -4.076245307922363, 330 | 5.903861999511719, 331 | 1.0054539442062378 332 | ] 333 | } 334 | ], 335 | "scene": 0, 336 | "scenes": [ 337 | { 338 | "extras": { 339 | "active_camera": 0, 340 | "background_color": [ 341 | 0.05087608844041824, 342 | 0.05087608844041824, 343 | 0.05087608844041824 344 | ], 345 | "frames_per_second": 24 346 | }, 347 | "name": "Scene", 348 | "nodes": [ 349 | 1, 350 | 3, 351 | 0, 352 | 2 353 | ] 354 | } 355 | ] 356 | } 357 | -------------------------------------------------------------------------------- /test/testRunOutput.txt: -------------------------------------------------------------------------------- 1 | ********************************Add Blender Custom Properties ******************************************** 2 | 3 | Adding Custom Properties with the following options: 4 | 5 | filePath: c:\temp\test.csv 6 | sanitize: True 7 | 8 | ******************************** meshName: Cube.000 ******************************************** 9 | properties before assignment(s): [] 10 | Mesh's name sanitized from: Cube.000 to: Cube000 11 | Updated meshName: Cube000 , propName: value , propValue: 10.0 12 | properties after assignment(s): [('value', 10.0)] 13 | 14 | ******************************** meshName: Cube.001 ******************************************** 15 | properties before assignment(s): [] 16 | Mesh's name sanitized from: Cube.001 to: Cube001 17 | Updated meshName: Cube001 , propName: value , propValue: 20.0 18 | properties after assignment(s): [('value', 20.0)]] -------------------------------------------------------------------------------- /test/testWithAddOn.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarioDelgadoSr/AddBlenderCustomPropertiesFromCSV/707da0e594ff9a51f0c559f1b6096cb0916380c8/test/testWithAddOn.blend -------------------------------------------------------------------------------- /vba/CSVFileMacro.txt: -------------------------------------------------------------------------------- 1 | Sub CSVFile() 2 | 3 | ' Modified from: https://stackoverflow.com/questions/846839/excel-how-to-add-double-quotes-to-strings-only-in-csv-file 4 | ' Author: https://github.com/MarioDelgadoSr 5 | ' 6 | ' Macro will export selection or current sheet in a format compatible with Python's QUOTE_NONNUMERIC quoting. 7 | ' See: https://docs.python.org/3/library/csv.html 8 | 9 | Dim SrcRg As Range 10 | Dim CurrRow As Range 11 | Dim CurrCell As Range 12 | Dim CurrTextStr As String 13 | Dim ListSep As String 14 | Dim FName As Variant 15 | 16 | 'Prompt User for save file location 17 | FName = Application.GetSaveAsFilename("", "CSV File (*.csv), *.csv") 18 | 19 | If FName <> False Then 20 | 21 | 'ListSep = Application.International(xlListSeparator) 22 | ListSep = "," 23 | 24 | If Selection.Cells.Count > 1 Then 25 | 26 | Set SrcRg = Selection 27 | 28 | Else 29 | 30 | Set SrcRg = ActiveSheet.UsedRange 31 | 32 | End If 33 | 34 | Open FName For Output As #1 35 | 36 | For Each CurrRow In SrcRg.Rows 37 | 38 | CurrTextStr = "" 39 | 40 | For Each CurrCell In CurrRow.Cells 41 | 42 | ' Quote only text value 43 | DblQuoteStr = IIf(Application.IsText(CurrCell.Value), """", "") 44 | CurrTextStr = CurrTextStr & DblQuoteStr & CurrCell.Value & DblQuoteStr & ListSep 45 | 46 | Next 'CurCell 47 | 48 | While Right(CurrTextStr, 1) = ListSep 49 | 'Remove last ',' on the line 50 | CurrTextStr = Left(CurrTextStr, Len(CurrTextStr) - 1) 51 | Wend 52 | 53 | Print #1, CurrTextStr 54 | 55 | Next 'CurrRow 56 | 57 | Close #1 58 | 59 | End If 60 | 61 | End Sub 62 | -------------------------------------------------------------------------------- /vba/testMacro.csv: -------------------------------------------------------------------------------- 1 | Mesh,value 2 | Cube001,10 3 | Cube002,100 4 | Cube003,40 5 | Cube004,20 6 | Cube005,15 7 | Cube006,40 8 | Cube007,10 9 | Cube008,55 10 | Cube009,35 11 | Cube010,45 12 | -------------------------------------------------------------------------------- /vba/testMacroOutput.csv: -------------------------------------------------------------------------------- 1 | Mesh,value 2 | Cube001,10 3 | Cube002,100 4 | Cube003,40 5 | Cube004,20 6 | Cube005,15 7 | Cube006,40 8 | Cube007,10 9 | Cube008,55 10 | Cube009,35 11 | Cube010,45 12 | --------------------------------------------------------------------------------