88 lines
3.6 KiB
JavaScript
88 lines
3.6 KiB
JavaScript
const { spawn } = require("child_process");
|
|
const PathResolver = require("./PathResolver.js");
|
|
|
|
const STR_SCENE_MARKER = "SCENE_JSON:";
|
|
|
|
const STR_PYTHON_EXPR = [
|
|
"import bpy, json, sys",
|
|
"\ns=bpy.context.scene",
|
|
"\ncams=[o.name for o in bpy.data.objects if o.type=='CAMERA']",
|
|
"\ncols=[]",
|
|
"\ndef _wlc(lc,d):",
|
|
"\n for c in lc.children:",
|
|
"\n cols.append({'str_name':c.name,'nb_depth':d,'is_hide_render':bpy.data.collections[c.name].hide_render,'is_exclude':c.exclude})",
|
|
"\n _wlc(c,d+1)",
|
|
"\n_wlc(bpy.context.view_layer.layer_collection,0)",
|
|
"\nrs={'str_engine':s.render.engine,'nb_resolution_percentage':s.render.resolution_percentage,'is_film_transparent':s.render.film_transparent}",
|
|
"\ntry:\n rs['nb_cycles_samples']=s.cycles.samples;rs['str_cycles_device']=s.cycles.device;rs['is_cycles_denoise']=s.cycles.use_denoising",
|
|
"\nexcept:pass",
|
|
"\ntry:\n rs['nb_eevee_samples']=s.eevee.taa_render_samples",
|
|
"\nexcept:",
|
|
"\n try:\n rs['nb_eevee_samples']=s.eevee.samples",
|
|
"\n except:pass",
|
|
"\ninfo={'list_cameras':cams,'obj_scene':{'nb_resolution_x':s.render.resolution_x,'nb_resolution_y':s.render.resolution_y,'nb_frame_start':s.frame_start,'nb_frame_end':s.frame_end,'nb_frame_step':s.frame_step},'obj_render_settings':rs,'list_collections':cols}",
|
|
"\nsys.stdout.write('SCENE_JSON:' + json.dumps(info) + '\\n')",
|
|
"\nsys.stdout.flush()",
|
|
].join("");
|
|
|
|
const CameraParser = {
|
|
list_cameras: (str_blend_path) => {
|
|
return new Promise((resolve, reject) => {
|
|
let str_stdout = "";
|
|
let str_stderr = "";
|
|
|
|
let obj_process = spawn(PathResolver.get_blender_path(), [
|
|
"-b", str_blend_path,
|
|
"--python-expr", STR_PYTHON_EXPR,
|
|
]);
|
|
|
|
obj_process.stdout.on("data", (obj_data) => {
|
|
str_stdout += obj_data.toString();
|
|
});
|
|
|
|
obj_process.stderr.on("data", (obj_data) => {
|
|
str_stderr += obj_data.toString();
|
|
});
|
|
|
|
obj_process.on("close", (nb_code) => {
|
|
if (nb_code !== 0) {
|
|
reject(new Error("Blender a quitte avec le code " + nb_code + " : " + str_stderr));
|
|
return;
|
|
}
|
|
|
|
let obj_result = CameraParser._parse_scene_output(str_stdout);
|
|
if (obj_result === null) {
|
|
console.error("[CameraParser] Stdout Blender:\n" + str_stdout.substring(str_stdout.length - 2000));
|
|
reject(new Error("Impossible de parser les cameras. Verifiez que le fichier .blend contient des cameras."));
|
|
return;
|
|
}
|
|
|
|
resolve(obj_result);
|
|
});
|
|
|
|
obj_process.on("error", (obj_err) => {
|
|
reject(new Error("Impossible de lancer Blender. Verifiez qu'il est installe et accessible dans le PATH. " + obj_err.message));
|
|
});
|
|
});
|
|
},
|
|
|
|
_parse_scene_output: (str_stdout) => {
|
|
let list_lines = str_stdout.split("\n");
|
|
for (let str_line of list_lines) {
|
|
let nb_index = str_line.indexOf(STR_SCENE_MARKER);
|
|
if (nb_index !== -1) {
|
|
let str_json = str_line.substring(nb_index + STR_SCENE_MARKER.length).trim();
|
|
try {
|
|
return JSON.parse(str_json);
|
|
} catch (obj_err) {
|
|
console.error("[CameraParser] JSON parse error:", obj_err.message, "raw:", str_json);
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
};
|
|
|
|
module.exports = CameraParser;
|