diff --git a/src/blenderbim/blenderbim/__init__.py b/src/blenderbim/blenderbim/__init__.py index 67b03e5702..2a742ed65d 100644 --- a/src/blenderbim/blenderbim/__init__.py +++ b/src/blenderbim/blenderbim/__init__.py @@ -18,7 +18,12 @@ import os import sys -import site +import bpy +import platform +import traceback +import subprocess +import webbrowser +import addon_utils bl_info = { "name": "BlenderBIM", @@ -32,16 +37,132 @@ bl_info = { "category": "System", } +last_error = None + + +def get_debug_info(): + version = ".".join( + [ + str(x) + for x in [ + addon.bl_info.get("version", (-1, -1, -1)) + for addon in addon_utils.modules() + if addon.bl_info["name"] == "BlenderBIM" + ][0] + ] + ) + return { + "os": platform.system(), + "os_version": platform.version(), + "python_version": platform.python_version(), + "architecture": platform.architecture(), + "machine": platform.machine(), + "processor": platform.processor(), + "blender_version": bpy.app.version_string, + "blenderbim_version": version, + "last_error": last_error, + } + + if sys.modules.get("bpy", None): # Process *.pth in /libs/site/packages to setup globally importable modules # This is 3 levels deep as required by the static RPATH of ../../ from dependencies taken from Anaconda # site.addsitedir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "libs", "site", "packages")) sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), "libs", "site", "packages")) - import blenderbim.bim + try: + import blenderbim.bim - def register(): - blenderbim.bim.register() + def register(): + blenderbim.bim.register() - def unregister(): - blenderbim.bim.unregister() + def unregister(): + blenderbim.bim.unregister() + + except: + last_error = traceback.format_exc() + + print(last_error) + print(get_debug_info()) + print("\nFATAL ERROR: Unable to load the BlenderBIM Add-on") + + class BIM_PT_fatal_error(bpy.types.Panel): + bl_label = "BlenderBIM Fatal Error" + bl_idname = "SCENE_PT_error_message" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + + def draw(self, context): + layout = self.layout + layout.label(text="BlenderBIM could not load.", icon="ERROR") + layout.label(text="View the console for full logs.", icon="CONSOLE") + box = layout.box() + info = get_debug_info() + py = ".".join(info["python_version"].split(".")[0:2]) + b3d = ".".join(info["blender_version"].split(".")[0:2]) + box.label(text=f"Blender {b3d} {info['os']} {info['machine']}", icon="BLENDER") + box.label(text=f"Python {py} BBIM {info['blenderbim_version']}", icon="SCRIPTPLUGINS") + layout.operator("bim.copy_debug_information", text="Copy Error Message To Clipboard") + op = layout.operator("bim.open_uri", text="How Can I Fix This?") + op.uri = "https://docs.blenderbim.org/users/installation.html#faq" + + class OpenUri(bpy.types.Operator): + bl_idname = "bim.open_uri" + bl_label = "Open URI" + uri: bpy.props.StringProperty() + + def execute(self, context): + webbrowser.open(self.uri) + return {"FINISHED"} + + class CopyDebugInformation(bpy.types.Operator): + bl_idname = "bim.copy_debug_information" + bl_label = "Copy Debug Information" + bl_description = "Copies debugging information to your clipboard for use in bugreports" + + def execute(self, context): + info = get_debug_info() + # Format it in a readable way + text = "\n".join(f"{k}: {v}" for k, v in info.items()) + print(text) + + if platform.system() == "Windows": + command = "echo | set /p nul=" + text.strip() + elif platform.system() == "Darwin": # for MacOS + command = 'printf "' + text.strip().replace("\n", "\\n").replace('"', "") + '" | pbcopy' + else: # Linux + command = ( + 'printf "' + + text.strip().replace("\n", "\\n").replace('"', "") + + '" | xclip -selection clipboard' + ) + subprocess.run(command, shell=True, check=True) + return {"FINISHED"} + + class HiddenPanel: + @classmethod + def false_poll(cls, context): + return False + + def register(): + # Only show our error panel and nothing else in the scene tab + for item_name in dir(bpy.types): + item = getattr(bpy.types, item_name) + if not hasattr(item, "bl_rna") or not isinstance(item.bl_rna, bpy.types.Panel): + continue + if getattr(item, "bl_context", None) != "scene": + continue + + # Reregister scene panel with a new poll to hide it + item.poll = HiddenPanel.false_poll + bpy.utils.unregister_class(item) + bpy.utils.register_class(item) + bpy.utils.register_class(BIM_PT_fatal_error) + bpy.utils.register_class(CopyDebugInformation) + bpy.utils.register_class(OpenUri) + + def unregister(): + bpy.utils.unregister_class(OpenUri) + bpy.utils.unregister_class(CopyDebugInformation) + bpy.utils.unregister_class(BIM_PT_fatal_error) diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index 1476a30bff..20c39c6aa3 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -17,11 +17,11 @@ # along with BlenderBIM Add-on. If not, see . import os -from pathlib import Path import bpy import bpy.utils.previews import blenderbim import importlib +from pathlib import Path from . import handler, ui, prop, operator, helper from typing import Callable, Union diff --git a/src/blenderbim/blenderbim/bim/module/debug/operator.py b/src/blenderbim/blenderbim/bim/module/debug/operator.py index b6605d9712..7d6b4b8c94 100644 --- a/src/blenderbim/blenderbim/bim/module/debug/operator.py +++ b/src/blenderbim/blenderbim/bim/module/debug/operator.py @@ -24,7 +24,6 @@ import random import logging import platform import subprocess -import addon_utils import ifcopenshell import ifcopenshell.api import ifcopenshell.util.element @@ -34,7 +33,7 @@ import blenderbim.tool as tool import blenderbim.core.debug as core import blenderbim.bim.handler import blenderbim.bim.import_ifc as import_ifc -import blenderbim.tool as tool +from blenderbim import get_debug_info from blenderbim.bim.ifc import IfcStore @@ -44,28 +43,7 @@ class CopyDebugInformation(bpy.types.Operator): bl_description = "Copies debugging information to your clipboard for use in bugreports" def execute(self, context): - version = ".".join( - [ - str(x) - for x in [ - addon.bl_info.get("version", (-1, -1, -1)) - for addon in addon_utils.modules() - if addon.bl_info["name"] == "BlenderBIM" - ][0] - ] - ) - info = { - "os": platform.system(), - "os_version": platform.version(), - "python_version": platform.python_version(), - "architecture": platform.architecture(), - "machine": platform.machine(), - "processor": platform.processor(), - "blender_version": bpy.app.version_string, - "blenderbim_version": version, - "ifc": False, - } - + info = get_debug_info() if tool.Ifc.get(): info.update( { diff --git a/src/blenderbim/docs/devs/installation.rst b/src/blenderbim/docs/devs/installation.rst index 20e9a3c6e1..96ee05e206 100644 --- a/src/blenderbim/docs/devs/installation.rst +++ b/src/blenderbim/docs/devs/installation.rst @@ -20,7 +20,7 @@ instructions as the **Stable installation**. You will need to choose which build to download. - If you are on Blender >=4.1, choose py311 -- If you are on Blender >=3.1 and <=4.0, choose py10 +- If you are on Blender >=3.1 and <=4.0, choose py310 - If you are on Blender >=2.93 and <3.1, choose py39 - Choose ``linux``, ``macos`` (Apple Intel), ``macosm1`` (Apple Silicon), or ``win`` depending on your operating system diff --git a/src/blenderbim/docs/devs/writing_docs.rst b/src/blenderbim/docs/devs/writing_docs.rst index f888b398da..f39b5fdefe 100644 --- a/src/blenderbim/docs/devs/writing_docs.rst +++ b/src/blenderbim/docs/devs/writing_docs.rst @@ -16,9 +16,12 @@ You can press the edit button on the top right on any documentation page to quickly edit their content. You can link to `external websites -`_. -You can also link to sections on the same page, like `Writing technical -documentation`_. You can link to other pages, like :doc:`Hello +`_ +(note the space between the url and the link text). You can also link to +sections on the same page, like :ref:`devs/writing_docs:Writing technical +documentation` or with :ref:`custom text`. Traditional references like `Writing technical documentation`_ +work too but are discouraged. You can link to other pages, like :doc:`Hello World` or sections within other pages, like :ref:`devs/installation:unstable installation`. We have ``autosectionlabel`` enabled so it is not necessary to manually create labels. diff --git a/src/blenderbim/docs/users/installation.rst b/src/blenderbim/docs/users/installation.rst index c429c89012..95a6099913 100644 --- a/src/blenderbim/docs/users/installation.rst +++ b/src/blenderbim/docs/users/installation.rst @@ -106,19 +106,22 @@ On Windows: Updating -------- -First uninstall the current BlenderBIM add-on, then install the latest version. +First follow the `Uninstalling`_ section below, then install the latest version. Uninstalling ------------ Navigate to ``Edit > Preferences > Add-ons``. Due to a limitation in Blender, -you have to first disable the BlenderBIM Add-on in your Blender preferences by -pressing the checkbox next to the add-on, then restart Blender. After -restarting, you can uninstall the BlenderBIM Add-on by pressing the ``Remove`` -button in the Blender preferences window. +you have to **first disable the BlenderBIM Add-on in your Blender preferences** +by pressing the checkbox next to the add-on, then **restart Blender**. It is +critical to follow this sequence of disabling first, and then restarting. -Alternatively, you may uninstall manually by deleting the ``blenderbim/`` -directory in your Blender add-ons directory. +After restarting, you can uninstall the BlenderBIM Add-on by pressing the +``Remove`` button in the Blender preferences window. + +Alternatively, you may uninstall manually by deleting the ``blenderbim`` +directory in :ref:`your Blender add-ons directory`. .. warning:: @@ -130,12 +133,20 @@ directory in your Blender add-ons directory. FAQ --- +If you are unable to install the BlenderBIM Add-on, make sure you are using +**Blender 4.1** installed from https://blender.org/ and are installing the +latest version from https://blenderbim.org. + +Other common solutions are listed below. If none of these fix the problem, you +can `report a bug `_ or +`live chat with a developer `_. + 1. **Some other error prevents me from installing or doing basic functions with the add-on. Is it specific to my environment?** - Sometimes it is helpful to try installing and using the BlenderBIM Add-on on - a "clean environment". A clean environment is defined as a fresh Blender - installation with no other add-ons enabled with factory settings. + Try installing and using the BlenderBIM Add-on on a "clean environment". A + clean environment is a fresh Blender installation with no other add-ons + enabled with factory settings. To quickly test in a clean environment, find your Blender configuration folder based on the `where is the add-on installed`_ section. Rename the