Update blender_path behavior to require exact path to executable instead of trying to guess it
This commit is contained in:
parent
17e7f85c06
commit
ad106a283b
@ -495,7 +495,7 @@
|
||||
<member name="filesystem/file_dialog/thumbnail_size" type="int" setter="" getter="">
|
||||
The thumbnail size to use in the editor's file dialogs (in pixels). See also [member docks/filesystem/thumbnail_size].
|
||||
</member>
|
||||
<member name="filesystem/import/blender/blender3_path" type="String" setter="" getter="">
|
||||
<member name="filesystem/import/blender/blender_path" type="String" setter="" getter="">
|
||||
The path to the directory containing the Blender executable used for converting the Blender 3D scene files [code].blend[/code] to glTF 2.0 format during import. Blender 3.0 or later is required.
|
||||
To enable this feature for your specific project, use [member ProjectSettings.filesystem/import/blender/enabled].
|
||||
</member>
|
||||
|
@ -943,7 +943,7 @@
|
||||
</member>
|
||||
<member name="filesystem/import/blender/enabled" type="bool" setter="" getter="" default="true">
|
||||
If [code]true[/code], Blender 3D scene files with the [code].blend[/code] extension will be imported by converting them to glTF 2.0.
|
||||
This requires configuring a path to a Blender executable in the editor settings at [code]filesystem/import/blender/blender3_path[/code]. Blender 3.0 or later is required.
|
||||
This requires configuring a path to a Blender executable in the editor settings at [code]filesystem/import/blender/blender_path[/code]. Blender 3.0 or later is required.
|
||||
</member>
|
||||
<member name="filesystem/import/blender/enabled.android" type="bool" setter="" getter="" default="false">
|
||||
Override for [member filesystem/import/blender/enabled] on Android where Blender can't easily be accessed from Godot.
|
||||
|
@ -520,7 +520,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
||||
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "filesystem/file_dialog/thumbnail_size", 64, "32,128,16")
|
||||
|
||||
// Import (for glft module)
|
||||
EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_DIR, "filesystem/import/blender/blender3_path", "", "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
|
||||
EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "filesystem/import/blender/blender_path", "", "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
|
||||
EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_RANGE, "filesystem/import/blender/rpc_port", 6011, "0,65535,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
|
||||
EDITOR_SETTING_USAGE(Variant::FLOAT, PROPERTY_HINT_RANGE, "filesystem/import/blender/rpc_server_uptime", 5, "0,300,1,or_greater,suffix:s", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
|
||||
EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "filesystem/import/fbx/fbx2gltf_path", "", "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
|
||||
|
@ -5,7 +5,7 @@
|
||||
</brief_description>
|
||||
<description>
|
||||
Imports Blender scenes in the [code].blend[/code] file format through the glTF 2.0 3D import pipeline. This importer requires Blender to be installed by the user, so that it can be used to export the scene as glTF 2.0.
|
||||
The location of the Blender binary is set via the [code]filesystem/import/blender/blender3_path[/code] editor setting.
|
||||
The location of the Blender binary is set via the [code]filesystem/import/blender/blender_path[/code] editor setting.
|
||||
This importer is only used if [member ProjectSettings.filesystem/import/blender/enabled] is enabled, otherwise [code].blend[/code] files present in the project folder are not imported.
|
||||
Blend import requires Blender 3.0.
|
||||
Internally, the EditorSceneFormatImporterBlend uses the Blender glTF "Use Original" mode to reference external textures.
|
||||
|
@ -153,13 +153,7 @@ String dict_to_xmlrpc(const Dictionary &p_dict) {
|
||||
}
|
||||
|
||||
Error EditorImportBlendRunner::start_blender(const String &p_python_script, bool p_blocking) {
|
||||
String blender_path = EDITOR_GET("filesystem/import/blender/blender3_path");
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
blender_path = blender_path.path_join("blender.exe");
|
||||
#else
|
||||
blender_path = blender_path.path_join("blender");
|
||||
#endif
|
||||
String blender_path = EDITOR_GET("filesystem/import/blender/blender_path");
|
||||
|
||||
List<String> args;
|
||||
args.push_back("--background");
|
||||
|
@ -55,20 +55,7 @@
|
||||
#endif
|
||||
|
||||
static bool _get_blender_version(const String &p_path, int &r_major, int &r_minor, String *r_err = nullptr) {
|
||||
String path = p_path;
|
||||
#ifdef WINDOWS_ENABLED
|
||||
path = path.path_join("blender.exe");
|
||||
#else
|
||||
path = path.path_join("blender");
|
||||
#endif
|
||||
|
||||
#if defined(MACOS_ENABLED)
|
||||
if (!FileAccess::exists(path)) {
|
||||
path = p_path.path_join("Blender");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!FileAccess::exists(path)) {
|
||||
if (!FileAccess::exists(p_path)) {
|
||||
if (r_err) {
|
||||
*r_err = TTR("Path does not contain a Blender installation.");
|
||||
}
|
||||
@ -77,7 +64,7 @@ static bool _get_blender_version(const String &p_path, int &r_major, int &r_mino
|
||||
List<String> args;
|
||||
args.push_back("--version");
|
||||
String pipe;
|
||||
Error err = OS::get_singleton()->execute(path, args, &pipe);
|
||||
Error err = OS::get_singleton()->execute(p_path, args, &pipe);
|
||||
if (err != OK) {
|
||||
if (r_err) {
|
||||
*r_err = TTR("Can't execute Blender binary.");
|
||||
@ -87,7 +74,7 @@ static bool _get_blender_version(const String &p_path, int &r_major, int &r_mino
|
||||
int bl = pipe.find("Blender ");
|
||||
if (bl == -1) {
|
||||
if (r_err) {
|
||||
*r_err = vformat(TTR("Unexpected --version output from Blender binary at: %s."), path);
|
||||
*r_err = vformat(TTR("Unexpected --version output from Blender binary at: %s."), p_path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -126,7 +113,7 @@ void EditorSceneFormatImporterBlend::get_extensions(List<String> *r_extensions)
|
||||
Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_t p_flags,
|
||||
const HashMap<StringName, Variant> &p_options,
|
||||
List<String> *r_missing_deps, Error *r_err) {
|
||||
String blender_path = EDITOR_GET("filesystem/import/blender/blender3_path");
|
||||
String blender_path = EDITOR_GET("filesystem/import/blender/blender_path");
|
||||
|
||||
if (blender_major_version == -1 || blender_minor_version == -1) {
|
||||
_get_blender_version(blender_path, blender_major_version, blender_minor_version, nullptr);
|
||||
@ -369,7 +356,7 @@ static bool _test_blender_path(const String &p_path, String *r_err = nullptr) {
|
||||
bool EditorFileSystemImportFormatSupportQueryBlend::is_active() const {
|
||||
bool blend_enabled = GLOBAL_GET("filesystem/import/blender/enabled");
|
||||
|
||||
if (blend_enabled && !_test_blender_path(EDITOR_GET("filesystem/import/blender/blender3_path").operator String())) {
|
||||
if (blend_enabled && !_test_blender_path(EDITOR_GET("filesystem/import/blender/blender_path").operator String())) {
|
||||
// Intending to import Blender, but blend not configured.
|
||||
return true;
|
||||
}
|
||||
@ -409,11 +396,59 @@ void EditorFileSystemImportFormatSupportQueryBlend::_validate_path(String p_path
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorFileSystemImportFormatSupportQueryBlend::_autodetect_path(String p_path) {
|
||||
if (_test_blender_path(p_path)) {
|
||||
auto_detected_path = p_path;
|
||||
return true;
|
||||
bool EditorFileSystemImportFormatSupportQueryBlend::_autodetect_path() {
|
||||
// Autodetect
|
||||
auto_detected_path = "";
|
||||
|
||||
#if defined(MACOS_ENABLED)
|
||||
Vector<String> find_paths = {
|
||||
"/opt/homebrew/bin/blender",
|
||||
"/opt/local/bin/blender",
|
||||
"/usr/local/bin/blender",
|
||||
"/usr/local/opt/blender",
|
||||
"/Applications/Blender.app/Contents/MacOS/Blender",
|
||||
};
|
||||
{
|
||||
List<String> mdfind_args;
|
||||
mdfind_args.push_back("kMDItemCFBundleIdentifier=org.blenderfoundation.blender");
|
||||
|
||||
String output;
|
||||
Error err = OS::get_singleton()->execute("mdfind", mdfind_args, &output);
|
||||
if (err == OK) {
|
||||
for (const String &find_path : output.split("\n")) {
|
||||
find_paths.push_back(find_path.path_join("Contents/MacOS/Blender"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(WINDOWS_ENABLED)
|
||||
Vector<String> find_paths = {
|
||||
"C:\\Program Files\\Blender Foundation\\blender.exe",
|
||||
"C:\\Program Files (x86)\\Blender Foundation\\blender.exe",
|
||||
};
|
||||
{
|
||||
char blender_opener_path[MAX_PATH];
|
||||
DWORD path_len = MAX_PATH;
|
||||
HRESULT res = AssocQueryString(0, ASSOCSTR_EXECUTABLE, ".blend", "open", blender_opener_path, &path_len);
|
||||
if (res == S_OK) {
|
||||
find_paths.push_back(String(blender_opener_path).get_base_dir().path_join("blender.exe"));
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(UNIX_ENABLED)
|
||||
Vector<String> find_paths = {
|
||||
"/usr/bin/blender",
|
||||
"/usr/local/bin/blender",
|
||||
"/opt/blender/bin/blender",
|
||||
};
|
||||
#endif
|
||||
|
||||
for (const String &find_path : find_paths) {
|
||||
if (_test_blender_path(find_path)) {
|
||||
auto_detected_path = find_path;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -427,7 +462,7 @@ void EditorFileSystemImportFormatSupportQueryBlend::_select_install(String p_pat
|
||||
}
|
||||
void EditorFileSystemImportFormatSupportQueryBlend::_browse_install() {
|
||||
if (blender_path->get_text() != String()) {
|
||||
browse_dialog->set_current_dir(blender_path->get_text());
|
||||
browse_dialog->set_current_file(blender_path->get_text());
|
||||
}
|
||||
|
||||
browse_dialog->popup_centered_ratio();
|
||||
@ -479,76 +514,10 @@ bool EditorFileSystemImportFormatSupportQueryBlend::query() {
|
||||
EditorNode::get_singleton()->get_gui_base()->add_child(browse_dialog);
|
||||
}
|
||||
|
||||
String path = EDITOR_GET("filesystem/import/blender/blender3_path");
|
||||
String path = EDITOR_GET("filesystem/import/blender/blender_path");
|
||||
|
||||
if (path == "") {
|
||||
// Autodetect
|
||||
auto_detected_path = "";
|
||||
|
||||
#if defined(MACOS_ENABLED)
|
||||
|
||||
{
|
||||
Vector<String> mdfind_paths;
|
||||
{
|
||||
List<String> mdfind_args;
|
||||
mdfind_args.push_back("kMDItemCFBundleIdentifier=org.blenderfoundation.blender");
|
||||
|
||||
String output;
|
||||
Error err = OS::get_singleton()->execute("mdfind", mdfind_args, &output);
|
||||
if (err == OK) {
|
||||
mdfind_paths = output.split("\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (const String &found_path : mdfind_paths) {
|
||||
found = _autodetect_path(found_path.path_join("Contents/MacOS"));
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
found = _autodetect_path("/opt/homebrew/bin");
|
||||
}
|
||||
if (!found) {
|
||||
found = _autodetect_path("/opt/local/bin");
|
||||
}
|
||||
if (!found) {
|
||||
found = _autodetect_path("/usr/local/bin");
|
||||
}
|
||||
if (!found) {
|
||||
found = _autodetect_path("/usr/local/opt");
|
||||
}
|
||||
if (!found) {
|
||||
found = _autodetect_path("/Applications/Blender.app/Contents/MacOS");
|
||||
}
|
||||
}
|
||||
#elif defined(WINDOWS_ENABLED)
|
||||
{
|
||||
char blender_opener_path[MAX_PATH];
|
||||
DWORD path_len = MAX_PATH;
|
||||
HRESULT res = AssocQueryString(0, ASSOCSTR_EXECUTABLE, ".blend", "open", blender_opener_path, &path_len);
|
||||
if (res == S_OK && _autodetect_path(String(blender_opener_path).get_base_dir())) {
|
||||
// Good.
|
||||
} else if (_autodetect_path("C:\\Program Files\\Blender Foundation")) {
|
||||
// Good.
|
||||
} else {
|
||||
_autodetect_path("C:\\Program Files (x86)\\Blender Foundation");
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(UNIX_ENABLED)
|
||||
if (_autodetect_path("/usr/bin")) {
|
||||
// Good.
|
||||
} else if (_autodetect_path("/usr/local/bin")) {
|
||||
// Good
|
||||
} else {
|
||||
_autodetect_path("/opt/blender/bin");
|
||||
}
|
||||
#endif
|
||||
if (auto_detected_path != "") {
|
||||
path = auto_detected_path;
|
||||
}
|
||||
if (path.is_empty() && _autodetect_path()) {
|
||||
path = auto_detected_path;
|
||||
}
|
||||
|
||||
blender_path->set_text(path);
|
||||
@ -569,7 +538,7 @@ bool EditorFileSystemImportFormatSupportQueryBlend::query() {
|
||||
|
||||
if (confirmed) {
|
||||
// Can only confirm a valid path.
|
||||
EditorSettings::get_singleton()->set("filesystem/import/blender/blender3_path", blender_path->get_text());
|
||||
EditorSettings::get_singleton()->set("filesystem/import/blender/blender_path", blender_path->get_text());
|
||||
EditorSettings::get_singleton()->save();
|
||||
} else {
|
||||
// Disable Blender import
|
||||
|
@ -95,7 +95,7 @@ class EditorFileSystemImportFormatSupportQueryBlend : public EditorFileSystemImp
|
||||
String auto_detected_path;
|
||||
void _validate_path(String p_path);
|
||||
|
||||
bool _autodetect_path(String p_path);
|
||||
bool _autodetect_path();
|
||||
|
||||
void _path_confirmed();
|
||||
|
||||
|
@ -55,23 +55,39 @@ static void _editor_init() {
|
||||
|
||||
// Blend to glTF importer.
|
||||
|
||||
bool blend_enabled = GLOBAL_GET("filesystem/import/blender/enabled");
|
||||
String blender3_path = EDITOR_GET("filesystem/import/blender/blender3_path");
|
||||
if (blend_enabled) {
|
||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
if (blender3_path.is_empty()) {
|
||||
WARN_PRINT(TTR("Blend file import is enabled in the project settings, but no Blender path is configured in the editor settings. Blend files will not be imported."));
|
||||
} else if (!da->dir_exists(blender3_path)) {
|
||||
WARN_PRINT(TTR("Blend file import is enabled, but the Blender path doesn't point to an accessible directory. Blend files will not be imported."));
|
||||
} else {
|
||||
Ref<EditorSceneFormatImporterBlend> importer;
|
||||
importer.instantiate();
|
||||
ResourceImporterScene::add_scene_importer(importer);
|
||||
String blender_path = EDITOR_GET("filesystem/import/blender/blender_path");
|
||||
if (blender_path.is_empty() && EditorSettings::get_singleton()->has_setting("filesystem/import/blender/blender3_path")) {
|
||||
blender_path = EditorSettings::get_singleton()->get("filesystem/import/blender/blender3_path");
|
||||
|
||||
Ref<EditorFileSystemImportFormatSupportQueryBlend> blend_import_query;
|
||||
blend_import_query.instantiate();
|
||||
EditorFileSystem::get_singleton()->add_import_format_support_query(blend_import_query);
|
||||
if (!blender_path.is_empty()) {
|
||||
#if defined(MACOS_ENABLED)
|
||||
if (blender_path.contains(".app")) {
|
||||
blender_path += "/Contents/MacOS/Blender";
|
||||
} else {
|
||||
blender_path += "/blender";
|
||||
}
|
||||
#elif defined(WINDOWS_ENABLED)
|
||||
blender_path += "\\blender.exe";
|
||||
#elif defined(UNIX_ENABLED)
|
||||
blender_path += "/blender";
|
||||
#endif
|
||||
|
||||
EditorSettings::get_singleton()->set("filesystem/import/blender/blender_path", blender_path);
|
||||
}
|
||||
|
||||
EditorSettings::get_singleton()->erase("filesystem/import/blender/blender3_path");
|
||||
EditorSettings::get_singleton()->save();
|
||||
}
|
||||
|
||||
bool blend_enabled = GLOBAL_GET("filesystem/import/blender/enabled");
|
||||
if (blend_enabled) {
|
||||
Ref<EditorSceneFormatImporterBlend> importer;
|
||||
importer.instantiate();
|
||||
ResourceImporterScene::add_scene_importer(importer);
|
||||
|
||||
Ref<EditorFileSystemImportFormatSupportQueryBlend> blend_import_query;
|
||||
blend_import_query.instantiate();
|
||||
EditorFileSystem::get_singleton()->add_import_format_support_query(blend_import_query);
|
||||
}
|
||||
memnew(EditorImportBlendRunner);
|
||||
EditorNode::get_singleton()->add_child(EditorImportBlendRunner::get_singleton());
|
||||
|
Loading…
Reference in New Issue
Block a user