-1
$\begingroup$

trying to understand how to make a python script that render, save the picture with the name of the Blender file, export a JSON file that according to the name of the Blender file assign some properties that I decide.

For example if the file name is AA3_CC6 I would like that the Json file contains something like: Shape: Cube Color: Red

Where "Shape: Cube" is represented by AA3 and "Color: Red" is represented by CC6

Any idea about the code or how to deal with this?

$\endgroup$
2

2 Answers 2

2
$\begingroup$

I wasn't sure if I should answer since it's mostly a Python question, but it has a few small Blender specific aspects...

import bpy, json
from pathlib import Path

C = bpy.context 

# define what identifiers mean:

shapes = {
    "AA1": "Sphere",
    "AA2": "Cylinder",
    "AA3": "Cube",
    "AA4": "Torus",
}

colors = {
    "CC1": "White",
    "CC2": "Blue",
    "CC3": "Cyan",
    "CC4": "Green",
    "CC5": "Yellow",
    "CC6": "Red",
    "CC7": "Black",
}

blendpath = Path(C.blend_data.filepath)  # create Path object based on absolute path to current .blend file
JSONpath = blendpath.with_suffix(".txt")  # where JSON will be saved
fileformat = C.scene.render.image_settings.file_format.lower()
renderpath = blendpath.with_suffix(f".{fileformat}")  # where render will be saved
if renderpath.exists() or JSONpath.exists():
    raise FileExistsError("I don't want to override something!")

shapeid, colorid = blendpath.stem.split("_")  # assumes only one underscore
shape = shapes[shapeid]  # translate AA3 to Cube
color = colors[colorid]  # translate CC6 to Red
output_dict = {"Shape": shape, "Color": color}  # create a structure to be converted to JSON

# using "x" instead of "w" to error if the file already exists, though very unlikely due to line 29
with open(JSONpath, "x") as f:
    json.dump(output_dict, f)

C.scene.render.filepath = str(renderpath)  # Blender gets confused without explicitly converting to str
# thanks to "INVOKE_DEFAULT" the script will finish before the render is done and so will not hang the interface
bpy.ops.render.render("INVOKE_DEFAULT", write_still=True) 

Quick way to get current opened filename in a script?

Is it possible to make a sequence of renders and give the user the option to cancel the process through the UI at any given time?

$\endgroup$
2
  • $\begingroup$ from pathlib import upvote sice the file can't exist (error thrown in code above), could use JSONpath.write_text(json.dumpa(output_dictt) Inclined to close as dupe (first in borcker's comment below question), Thoughts? $\endgroup$
    – batFINGER
    Commented Sep 11, 2021 at 13:26
  • $\begingroup$ @batFINGER I trust your judgement, and I don't mind in the slightest if you close. Thanks for the tip, I didn't know about .write_text(). $\endgroup$ Commented Sep 11, 2021 at 15:00
2
$\begingroup$

i used this base code to resolve this

# 1 - Export data as JSON file

# dict with all your data
dict = {
    "description": "description", 
    "external_url": "external_url", 
    "image": "image", 
    "name": "name",
    "attributes": [ "a", "b", "c" ],
}

# encode dict as JSON 
data = json.dumps(dict, indent=1, ensure_ascii=True)

# set output path and file name (set your own)
save_path = 'YOUR PATH'
file_name = os.path.join(save_path, "test.json")

# write JSON file
with open(file_name, 'w') as outfile:
    outfile.write(data + '\n')


# 2 - Import data from JSON file

# read JSON file
#with open(file_name, 'r') as fp:
#    data_file = json.load(fp)

# get data
name = data_file['name']
attributes = data_file['attributes']
description = data_file['description']
image = data_file['image']
url = data_file['external_url']



print({
  "description": description, 
  "external_url": url, 
  "image": image, 
  "name": name,
  "attributes": attributes, 
})
$\endgroup$

Not the answer you're looking for? Browse other questions tagged .