From 054c0a9a2733a84c04e0c12efe08760a26f11a52 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 11 Apr 2022 14:08:44 +0200 Subject: [PATCH 01/11] Improve faceset logging --- src/ifcgeom/IfcGeomFunctions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index f0e233dde6..130f919425 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -5646,8 +5646,8 @@ IfcGeom::Kernel::faceset_helper::faceset_helper( } } - if (loops_removed || (non_manifold && should_be_closed)) { - Logger::Warning(boost::lexical_cast(duplicate_faces) + " duplicate faces removed, " + boost::lexical_cast(loops_removed) + " loops removed and " + boost::lexical_cast(non_manifold) + " non-manifold edges"); + if (duplicates_.size() || loops_removed || (non_manifold && should_be_closed)) { + Logger::Warning(boost::lexical_cast(duplicate_faces) + " duplicate faces removed, " + boost::lexical_cast(loops_removed) + " degenerate loops eliminated and " + boost::lexical_cast(non_manifold) + " non-manifold edges"); } } From 460fd5ca87bac666ab0b14d3133e9444899a15ec Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 11 Apr 2022 14:12:17 +0200 Subject: [PATCH 02/11] #2133 faceset helper: compare index vectors by address instead of value --- src/ifcgeom/IfcGeom.h | 18 +++++++++++++++--- src/ifcgeom/IfcGeomFunctions.cpp | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 687a437c4c..69a04f1339 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -111,6 +111,18 @@ public: std::map Shape; }; +namespace util { + template + typename std::enable_if::value, T&>::type conditional_address_of(T& t) { + return t; + } + + template + typename std::enable_if::value, T*>::type conditional_address_of(T& t) { + return &t; + } +} + class IFC_GEOM_API MAKE_TYPE_NAME(Kernel) : public IfcGeom::Kernel { private: @@ -126,7 +138,7 @@ private: class faceset_helper { private: MAKE_TYPE_NAME(Kernel)* kernel_; - std::set duplicates_; + std::set::value, LP, const LP*>::type> duplicates_; std::map vertex_mapping_; std::map, TopoDS_Edge> edges_; // not always in use @@ -225,8 +237,8 @@ private: return true; } - bool wire(LP loop, TopoDS_Wire& wire) { - if (duplicates_.find(loop) != duplicates_.end()) { + bool wire(const LP& loop, TopoDS_Wire& wire) { + if (duplicates_.find(util::conditional_address_of(loop)) != duplicates_.end()) { return false; } BRep_Builder builder; diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 130f919425..f156692b0d 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -5613,7 +5613,7 @@ IfcGeom::Kernel::faceset_helper::faceset_helper( if (edge_sets.find(segment_set) != edge_sets.end()) { duplicate_faces++; - duplicates_.insert(*ps); + duplicates_.insert(util::conditional_address_of(*ps)); continue; } edge_sets.insert(segment_set); From f0c7ff1e57034707148f840a7211ac9b760b8ca9 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 12 Apr 2022 08:29:07 +1000 Subject: [PATCH 03/11] #1153. Titleblock revision / data is are derived from IfcDocumentInformation --- .../bim/data/templates/titleblocks/A1.svg | 4 +- .../bim/data/templates/titleblocks/A2.svg | 4 +- .../bim/data/templates/titleblocks/A3.svg | 4 +- .../blenderbim/bim/module/drawing/operator.py | 5 +- .../blenderbim/bim/module/drawing/sheeter.py | 74 ++++++++++--------- 5 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/data/templates/titleblocks/A1.svg b/src/blenderbim/blenderbim/bim/data/templates/titleblocks/A1.svg index de252c4203..ec48691774 100644 --- a/src/blenderbim/blenderbim/bim/data/templates/titleblocks/A1.svg +++ b/src/blenderbim/blenderbim/bim/data/templates/titleblocks/A1.svg @@ -173,7 +173,7 @@ style="stroke-width:0.999999px" y="1036.1166" x="3030.9653" - id="tspan2527">{{revision}} + id="tspan2527">{{Revision}} {{number}} + style="stroke-width:0.999999px">{{Identification}} - {{Name}} {{revision}} + id="tspan2527">{{Revision}} {{number}} + style="stroke-width:0.264583px">{{Identification}} - {{Name}} {{revision}} + style="stroke-width:0.264583px">{{Revision}} {{number}} + id="tspan2531">{{Identification}} - {{Name}} Date: Tue, 12 Apr 2022 18:07:39 +1000 Subject: [PATCH 04/11] Update installation docs to distinguish between package from source and developer setups --- .../docs/blenderbim/installation.rst | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/blenderbim/docs/blenderbim/installation.rst b/src/blenderbim/docs/blenderbim/installation.rst index 0dc22f574b..0c225e7f25 100644 --- a/src/blenderbim/docs/blenderbim/installation.rst +++ b/src/blenderbim/docs/blenderbim/installation.rst @@ -9,7 +9,8 @@ There are different methods of installation, depending on your situation. 2. **Daily build installation** is recommended for power users helping with testing. 3. **Unpackaged installation** is recommended for package managers. 4. **Distro installation** is recommended for those who use a Linux package manager. -5. **Source installation** is recommended for developers. +5. **Source installation: packaged** is recommended for distributing a build from source. +6. **Source installation: live** is recommended for developers who are actively coding. Packaged installation --------------------- @@ -128,8 +129,8 @@ Distro installation Those on Arch Linux can check out this `AUR package `__. -Source installation -------------------- +Source installation: packaged +----------------------------- It is possible to run the latest bleeding edge version of BlenderBIM without having to wait for an official release, since BlenderBIM is coded in Python and @@ -142,18 +143,27 @@ compile IfcOpenShell is out of scope of this document. You can create your own package by using the Makefile as shown below. You can choose between a ``PLATFORM`` of ``linux``, ``macos``, and ``win``. You can -choose between a ``PYVERSION`` of ``py39`` and ``py37``. +choose between a ``PYVERSION`` of ``py39``, ``py37``, or ``py310``. :: $ cd src/blenderbim $ make dist PLATFORM=linux PYVERSION=py39 $ ls dist/ -However, creating a build, uninstalling the old add-on, and installing a new -build is a slow process. You can do this, but we do not recommend it. A more -rapid approach is to follow the **Daily build installation** method, as this -provides all dependencies for you out of the box. Then, we can replace certain -Python files that tend to be updated frequently with those from the Git +This will give you a fully packaged Blender add-on zip that you can distribute +and install. + +Source installation: live +------------------------- + +One option for developers who want to install a build from source is to follow +the instructions from the **Source installation: packaged**. However, creating a +build, uninstalling the old add-on, and installing a new build is a slow +process. Although it works, it is very slow, so do not recommend it. + +A more rapid approach is to follow the **Daily build installation** method, as +this provides all dependencies for you out of the box. Then, we can replace +certain Python files that tend to be updated frequently with those from the Git repository. We're going to use symlinks (Windows users can use ``mklink``), so we can code in our Git repository, and see the changes in our Blender installation. From a243cdd6c607d404ea16af6041f6a1880b17cea9 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 12 Apr 2022 18:09:45 +1000 Subject: [PATCH 05/11] Minor fix --- src/blenderbim/docs/blenderbim/installation.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/blenderbim/docs/blenderbim/installation.rst b/src/blenderbim/docs/blenderbim/installation.rst index 0c225e7f25..f29995b9c0 100644 --- a/src/blenderbim/docs/blenderbim/installation.rst +++ b/src/blenderbim/docs/blenderbim/installation.rst @@ -35,8 +35,9 @@ follow the same instructions as a packaged installation. You will need to choose which daily build to download. +- If you are on Blender >=3.1, choose py310 +- If you are on Blender >=2.93 and <3.1, choose py39 - If you are on Blender <2.93, choose py37 -- If you are on Blender >=2.93, choose py39 - Choose linux, macos, or win depending on your operating system Daily builds are not always stable. Sometimes, a build may be delayed, or @@ -147,7 +148,7 @@ choose between a ``PYVERSION`` of ``py39``, ``py37``, or ``py310``. :: $ cd src/blenderbim - $ make dist PLATFORM=linux PYVERSION=py39 + $ make dist PLATFORM=linux PYVERSION=py310 $ ls dist/ This will give you a fully packaged Blender add-on zip that you can distribute From 029b402d11cb13eaadcc870f40d4f14b12cc8acb Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 12 Apr 2022 18:30:03 +1000 Subject: [PATCH 06/11] Minor fix --- .../docs/blenderbim/installation.rst | 272 +++++++++--------- 1 file changed, 135 insertions(+), 137 deletions(-) diff --git a/src/blenderbim/docs/blenderbim/installation.rst b/src/blenderbim/docs/blenderbim/installation.rst index f29995b9c0..dd13288af0 100644 --- a/src/blenderbim/docs/blenderbim/installation.rst +++ b/src/blenderbim/docs/blenderbim/installation.rst @@ -5,15 +5,14 @@ Installation There are different methods of installation, depending on your situation. -1. **Packaged installation** is recommended for regular users. -2. **Daily build installation** is recommended for power users helping with testing. -3. **Unpackaged installation** is recommended for package managers. -4. **Distro installation** is recommended for those who use a Linux package manager. -5. **Source installation: packaged** is recommended for distributing a build from source. -6. **Source installation: live** is recommended for developers who are actively coding. +1. **Stable installation** is recommended for regular users. +2. **Unstable installation** is recommended for power users helping with testing. +3. **Building from source** is recommended for distributing a build from source. +4. **Live development environment** is recommended for developers who are actively coding. +5. **Distro installation** is recommended for those who use a Linux package manager. -Packaged installation ---------------------- +Stable installation +------------------- The BlenderBIM Add-on is packaged like a regular Blender add-on, so installation is the same as any other Blender add-on. The full instructions for end-user @@ -25,26 +24,129 @@ Like all Blender add-ons, they can be installed using ``Edit > Preferences > Addons > Install > Choose Downloaded ZIP > Enable Add-on Checkbox``. You can enable add-ons permanently by using ``Save User Settings`` from the Addons menu. -Daily build installation ------------------------- +Unstable installation +--------------------- -Daily builds are almost the same as **Packaged installation**, except that they -are typically updated every day. Simply download a daily build from the `Github -releases page `__, then -follow the same instructions as a packaged installation. +**Unstable installation** is almost the same as **Stable installation**, except +that they are typically updated every day. Simply download a daily build from +the `Github releases page +`__, then follow the same +instructions as a packaged installation. -You will need to choose which daily build to download. +You will need to choose which build to download. - If you are on Blender >=3.1, choose py310 - If you are on Blender >=2.93 and <3.1, choose py39 - If you are on Blender <2.93, choose py37 - Choose linux, macos, or win depending on your operating system -Daily builds are not always stable. Sometimes, a build may be delayed, or -contain broken code. We try to avoid this, but it happens. +Sometimes, a build may be delayed, or contain broken code. We try to avoid this, +but it happens. -Unpackaged installation ------------------------ +Building from source +-------------------- + +It is possible to run the latest bleeding edge version of BlenderBIM without +having to wait for an official release, since BlenderBIM is coded in Python and +doesn't require any compilation. + +Note that the BlenderBIM Add-on does depend on IfcOpenShell, and IfcOpenShell +does require compilation. The following instructions will use a pre-built +IfcOpenShell (using an IfcOpenBot build) for convenience. Instructions on how to +compile IfcOpenShell is out of scope of this document. + +You can create your own package by using the Makefile as shown below. You can +choose between a ``PLATFORM`` of ``linux``, ``macos``, and ``win``. You can +choose between a ``PYVERSION`` of ``py39``, ``py37``, or ``py310``. +:: + + $ cd src/blenderbim + $ make dist PLATFORM=linux PYVERSION=py310 + $ ls dist/ + +This will give you a fully packaged Blender add-on zip that you can distribute +and install. + +Live development environment +---------------------------- + +One option for developers who want to actively develop from source is to follow +the instructions from **Building from source**. However, creating a build, +uninstalling the old add-on, and installing a new build is a slow process. +Although it works, it is very slow, so we do not recommend it. + +A more rapid approach is to follow the **Unstable installation** method, as this +provides all dependencies for you out of the box. Then, we can replace certain +Python files that tend to be updated frequently with those from the Git +repository. We're going to use symlinks (Windows users can use ``mklink``), so +we can code in our Git repository, and see the changes in our Blender +installation (you will need to restart Blender to see changes). + +In addition, we're also going to replace the Python code of the IfcOpenShell +dependency with our Git repository, since most of the BlenderBIM Add-on +functionality is agnostic of Blender, and is actually part of IfcOpenShell. +Therefore, we need to keep this dependency highly updated as well. + +The downside with this approach is that if a new dependency is added, or a +compiled dependency version requirement has changed, or the build system +changes, you'll need to fix your setup manually. But this is relatively rare. + +:: + + $ git clone https://github.com/IfcOpenShell/IfcOpenShell.git + $ cd IfcOpenShell + + # Remove the Blender add-on Python code + $ rm -r /path/to/blender/X.XX/scripts/addons/blenderbim/bim/ + + # Replace them with links to the Git repository + $ ln -s src/blenderbim/blenderbim/bim /path/to/blender/X.XX/scripts/addons/blenderbim/bim + + # Remove the IfcOpenShell dependency Python code + $ rm -r /path/to/blender/X.XX/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api + $ rm -r /path/to/blender/X.XX/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/util + + # Replace them with links to the Git repository + $ ln -s src/ifcopenshell-python/ifcopenshell/api /path/to/blender/X.XX/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api + $ ln -s src/ifcopenshell-python/ifcopenshell/util /path/to/blender/X.XX/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/util + +On Windows: + +:: + + $ git clone https://github.com/IfcOpenShell/IfcOpenShell.git + $ cd IfcOpenShell + + # Remove the Blender add-on Python code + $ rd /S /Q "\path\to\blender\X.XX\scripts\addons\blenderbim\bim\" + + # Replace them with links to the Git repository + $ mklink /D "\path\to\blender\X.XX\scripts\addons\blenderbim\bim" "src\blenderbim\blenderbim\bim" + + # Remove the IfcOpenShell dependency Python code + $ rd \S \Q "\path\to\blender\X.XX\scripts\addons\blenderbim\libs\site\packages\ifcopenshell\api" + $ rd \S \Q "\path\to\blender\X.XX\scripts\addons\blenderbim\libs\site\packages\ifcopenshell\util" + + # Replace them with links to the Git repository + $ mklink \D "\path\to\blender\X.XX\scripts\addons\blenderbim\libs\site\packages\ifcopenshell\api" "src\ifcopenshell-python\ifcopenshell\api" + $ mklink \D "\path\to\blender\X.XX\scripts\addons\blenderbim\libs\site\packages\ifcopenshell\util" "src\ifcopenshell-python\ifcopenshell\util" + + +After you modify your code in the Git repository, you will need to restart +Blender for the changes to take effect. In ``Edit > Preferences > Add-ons`` you +will see that the version number of the BlenderBIM Add-on has changed to +``0.0.999999``, which represents an un-versioned BlenderBIM Add-on. + +Distro installation +------------------- + +Those on Arch Linux can check out this `AUR package `__. + +Tips for package managers +------------------------- + +If you are interested in packaging the BlenderBIM Add-on for a packaging +manager, read on. The BlenderBIM Add-on is fully contained in the ``blenderbim/`` subfolder of the Blender add-ons directory. This is typically distributed as a zipfile as per @@ -60,9 +162,8 @@ This corresponds to the structure found in the source code `here `__. The BlenderBIM Add-on is complex, and requires many dependencies, including -Python modules, binaries, and static assets. These dependencies are bundled with -the add-on for convenience in the **Packaged installation** and **Daily build -installation** methods. +Python modules, binaries, and static assets. When packaged for users, these +dependencies are bundled with the add-on for convenience. If you choose to install the BlenderBIM Add-on and use your own system dependencies, the source of truth for how dependencies are bundled are found in @@ -94,7 +195,7 @@ Required Python modules to be stored in ``libs/site/packages/`` are: elementpath six lark-parser - fcl + hppfcl behave parse parse_type @@ -110,14 +211,8 @@ Required Python modules to be stored in ``libs/site/packages/`` are: Notes: 1. ``ifcopenshell`` almost always requires the latest version due to the fast paced nature of the add-on development. -2. ``fcl`` is not bundled for MacOS, due to lack of maintained community build. This is required for clash detection. -3. ``behave`` requires `patches `__. -4. ``ifcjson`` can be found `here `__. - -Required binaries are: -:: - - libs/IfcConvert +2. ``behave`` requires `patches `__. +3. ``ifcjson`` can be found `here `__. Required static assets are: :: @@ -125,130 +220,31 @@ Required static assets are: bim/data/gantt/jsgantt.js (from jsgantt-improved) bim/data/gantt/jsgantt.css (from jsgantt-improved) -Distro installation -------------------- - -Those on Arch Linux can check out this `AUR package `__. - -Source installation: packaged ------------------------------ - -It is possible to run the latest bleeding edge version of BlenderBIM without -having to wait for an official release, since BlenderBIM is coded in Python and -doesn't require any compilation. - -Note that the BlenderBIM Add-on does depend on IfcOpenShell, and IfcOpenShell -does require compilation. The following instructions will use a pre-built -IfcOpenShell (using an IfcOpenBot build) for convenience. Instructions on how to -compile IfcOpenShell is out of scope of this document. - -You can create your own package by using the Makefile as shown below. You can -choose between a ``PLATFORM`` of ``linux``, ``macos``, and ``win``. You can -choose between a ``PYVERSION`` of ``py39``, ``py37``, or ``py310``. -:: - - $ cd src/blenderbim - $ make dist PLATFORM=linux PYVERSION=py310 - $ ls dist/ - -This will give you a fully packaged Blender add-on zip that you can distribute -and install. - -Source installation: live -------------------------- - -One option for developers who want to install a build from source is to follow -the instructions from the **Source installation: packaged**. However, creating a -build, uninstalling the old add-on, and installing a new build is a slow -process. Although it works, it is very slow, so do not recommend it. - -A more rapid approach is to follow the **Daily build installation** method, as -this provides all dependencies for you out of the box. Then, we can replace -certain Python files that tend to be updated frequently with those from the Git -repository. We're going to use symlinks (Windows users can use ``mklink``), so -we can code in our Git repository, and see the changes in our Blender -installation. - -In addition, we're also going to replace the Python code of the IfcOpenShell -dependency with our Git repository, since most of the BlenderBIM Add-on -functionality is agnostic of Blender, and is actually part of IfcOpenShell. -Therefore, we need to keep this dependency highly updated as well. - -The downside with this approach is that if a new dependency is added, or a -compiled dependency version requirement has changed, or the build system -changes, you'll need to fix your setup manually. But this is relatively rare. - -:: - - $ git clone https://github.com/IfcOpenShell/IfcOpenShell.git - $ cd IfcOpenShell - - # Remove the Blender add-on Python code - $ rm -r /path/to/blender/2.XX/scripts/addons/blenderbim/bim/ - - # Replace them with links to the Git repository - $ ln -s src/blenderbim/blenderbim/bim /path/to/blender/2.XX/scripts/addons/blenderbim/bim - - # Remove the IfcOpenShell dependency Python code - $ rm -r /path/to/blender/2.XX/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api - $ rm -r /path/to/blender/2.XX/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/util - - # Replace them with links to the Git repository - $ ln -s src/ifcopenshell-python/ifcopenshell/api /path/to/blender/2.XX/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api - $ ln -s src/ifcopenshell-python/ifcopenshell/util /path/to/blender/2.XX/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/util - -On Windows: - -:: - - $ git clone https://github.com/IfcOpenShell/IfcOpenShell.git - $ cd IfcOpenShell - - # Remove the Blender add-on Python code - $ rd /S /Q "\path\to\blender\2.XX\scripts\addons\blenderbim\bim\" - - # Replace them with links to the Git repository - $ mklink /D "\path\to\blender\2.XX\scripts\addons\blenderbim\bim" "src\blenderbim\blenderbim\bim" - - # Remove the IfcOpenShell dependency Python code - $ rd \S \Q "\path\to\blender\2.XX\scripts\addons\blenderbim\libs\site\packages\ifcopenshell\api" - $ rd \S \Q "\path\to\blender\2.XX\scripts\addons\blenderbim\libs\site\packages\ifcopenshell\util" - - # Replace them with links to the Git repository - $ mklink \D "\path\to\blender\2.XX\scripts\addons\blenderbim\libs\site\packages\ifcopenshell\api" "src\ifcopenshell-python\ifcopenshell\api" - $ mklink \D "\path\to\blender\2.XX\scripts\addons\blenderbim\libs\site\packages\ifcopenshell\util" "src\ifcopenshell-python\ifcopenshell\util" - - -After you modify your code in the Git repository, you will need to restart -Blender for the changes to take effect. In ``Edit > Preferences > Add-ons`` you -will see that the version number of BlenderBIM has changed to ``0.0.999999``, -which represents an un-versioned BlenderBIM. - Where is the BlenderBIM Add-on installed? ----------------------------------------- If you downloaded Blender as a ``.zip`` file without running an installer, you will find the BlenderBIM Add-on installed in the following directory, where -``2.XX`` is the Blender version: +``X.XX`` is the Blender version: :: - /path/to/blender/2.XX/scripts/addons/ + /path/to/blender/X.XX/scripts/addons/ Otherwise, if you installed Blender using an installation package, the add-ons folder depends on which operating system you use. On Linux: :: - ~/.config/blender/2.XX/scripts/addons/ + ~/.config/blender/X.XX/scripts/addons/ On Mac: :: - /Users/{YOUR_USER}/Library/Application Support/Blender/2.XX/ + /Users/{YOUR_USER}/Library/Application Support/Blender/X.XX/ On Windows: :: - C:\Users\{YOUR_USER}\AppData\Roaming\Blender Foundation\2.XX\scripts\addons + C:\Users\{YOUR_USER}\AppData\Roaming\Blender Foundation\X.XX\scripts\addons Upon installation, the BlenderBIM Add-on is stored in the ``blenderbim/`` directory. @@ -275,8 +271,10 @@ FAQ 1. I get an error similar to "ImportError: IfcOpenShell not built for 'linux/64bit/python3.7'" -If you are using Blender <2.93, then you need to use a daily build. See the -instructions above for a daily build installation. +Check which BlenderBIM Add-on build you are using. The zip will have either +``py37``, ``py39``, or ``py310`` in the name. See the instructions in the +**Unstable installation** section to check that you have installed the correct +version. 2. I am on Ubuntu and get an error similar to "ImportError: /lib/x86_64-linux-gnu/libm.so.6: version GLIBC_2.29 not found" From c099a6cb75543de361a230edd5ee4ed2cb512489 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 13 Apr 2022 12:21:18 +1000 Subject: [PATCH 07/11] #1153 Drawing titles now display IFC scale and identification data --- .../bim/data/templates/view-title.svg | 6 ++-- .../blenderbim/bim/module/drawing/prop.py | 10 ++++-- .../blenderbim/bim/module/drawing/sheeter.py | 24 ++++++++------ src/blenderbim/blenderbim/core/drawing.py | 2 +- src/blenderbim/blenderbim/tool/drawing.py | 31 +++++++++++++------ 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/data/templates/view-title.svg b/src/blenderbim/blenderbim/bim/data/templates/view-title.svg index 302826ec61..9bfad5dc85 100644 --- a/src/blenderbim/blenderbim/bim/data/templates/view-title.svg +++ b/src/blenderbim/blenderbim/bim/data/templates/view-title.svg @@ -70,7 +70,7 @@ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.96055365px;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:center;text-anchor:middle;stroke-width:0.26458332px" y="103.10933" x="32.822662" - id="tspan857">{{no}} + id="tspan857">{{Identification}} {{name}} + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.54325247px;font-family:'OpenGost Type B TT';-inkscape-font-specification:'OpenGost Type B TT';text-align:start;text-anchor:start;stroke-width:0.26458329px">{{Name}} {{scale}} + id="tspan865">{{Scale}} diff --git a/src/blenderbim/blenderbim/bim/module/drawing/prop.py b/src/blenderbim/blenderbim/bim/module/drawing/prop.py index 07e5b9b626..a0935d6ac7 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/prop.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/prop.py @@ -72,8 +72,10 @@ def update_diagram_scale(self, context): scale = self.diagram_scale if scale == "CUSTOM": scale = self.custom_diagram_scale - scale = scale.split("|")[1] - element = tool.Ifc.get_entity(context.scene.camera) + if "|" not in scale: + return + human_scale, scale = scale.split("|") + element = tool.Ifc.get_entity(context.scene.active_object) if not element: return pset = ifcopenshell.util.element.get_psets(element).get("EPset_Drawing") @@ -81,7 +83,9 @@ def update_diagram_scale(self, context): pset = tool.Ifc.get().by_id(pset["id"]) else: pset = ifcopenshell.api.run("pset.add_pset", tool.Ifc.get(), product=element, name="EPset_Drawing") - ifcopenshell.api.run("pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Scale": scale}) + ifcopenshell.api.run( + "pset.edit_pset", tool.Ifc.get(), pset=pset, properties={"Scale": scale, "HumanScale": human_scale} + ) def get_diagram_scales(self, context): diff --git a/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py b/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py index 3c5779d3a0..95dc0b8da7 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py @@ -180,7 +180,7 @@ class SheetBuilder: root = tree.getroot() self.build_titleblock(root, sheet) - self.build_drawings(root, sheet_name) + self.build_drawings(root, sheet) self.build_schedules(root.findall('{http://www.w3.org/2000/svg}g[@data-type="schedule"]')) with open(os.path.join(self.data_dir, "build", sheet_name, f"{sheet_name}.svg"), "wb") as output: @@ -192,8 +192,15 @@ class SheetBuilder: titleblock.append(self.parse_embedded_svg(image, sheet.get_info())) titleblock.remove(image) - def build_drawings(self, root, sheet_name): + def build_drawings(self, root, sheet): + sheet_name = tool.Drawing.get_sheet_filename(sheet) + references = tool.Drawing.get_document_references(sheet) + drawing_references = {tool.Drawing.get_reference_element(r): r for r in references} + for view in root.findall('{http://www.w3.org/2000/svg}g[@data-type="drawing"]'): + drawing = [d for d in drawing_references.keys() if d and d.GlobalId == view.attrib["data-guid"]][0] + reference = drawing_references[drawing] + images = view.findall("{http://www.w3.org/2000/svg}image") background = None @@ -208,8 +215,6 @@ class SheetBuilder: elif image.attrib["data-type"] == "view-title": view_title = image - self.scale = "NTS" - if foreground is not None: view.append(self.parse_embedded_svg(foreground, {})) @@ -219,12 +224,11 @@ class SheetBuilder: if view_title is not None: foreground_path = self.get_href(foreground) - view.append( - self.parse_embedded_svg( - view_title, - {"no": 1, "name": ntpath.basename(foreground_path)[0:-4], "scale": self.scale}, - ) - ) + data = reference.get_info() + if not data["Name"]: + data["Name"] = ntpath.basename(foreground_path)[0:-4] + data["Scale"] = tool.Drawing.get_drawing_human_scale(drawing) + view.append(self.parse_embedded_svg(view_title, data)) for image in images: view.remove(image) diff --git a/src/blenderbim/blenderbim/core/drawing.py b/src/blenderbim/blenderbim/core/drawing.py index ac43fd3323..845d35ed89 100644 --- a/src/blenderbim/blenderbim/core/drawing.py +++ b/src/blenderbim/blenderbim/core/drawing.py @@ -115,7 +115,7 @@ def add_drawing(ifc, collector, drawing, target_view=None, location_hint=None): ifc.run("group.assign_group", group=group, product=element) collector.assign(camera) pset = ifc.run("pset.add_pset", product=element, name="EPset_Drawing") - ifc.run("pset.edit_pset", pset=pset, properties={"TargetView": target_view, "Scale": "1/100"}) + ifc.run("pset.edit_pset", pset=pset, properties={"TargetView": target_view, "Scale": "1/100", "HumanScale": "1:100"}) drawing.import_drawings() diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index 5dd7d8022a..e01bd58bea 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -291,24 +291,17 @@ class Drawing(blenderbim.core.tool.Drawing): if not new.is_expanded: continue - if tool.Ifc.get_schema() == "IFC2X3": - references = sheet.DocumentReferences or [] - else: - references = sheet.HasDocumentReferences or [] - - for reference in references: + for reference in cls.get_document_references(sheet): new = props.sheets.add() new.ifc_definition_id = reference.id() new.is_sheet = False if tool.Ifc.get_schema() == "IFC2X3": new.identification = reference.ItemReference or "X" - element = [ - r for r in tool.Ifc.by_type("IfcRelAssociatesDocument") if r.RelatingDocument == reference - ][0].RelatedObjects[0] else: new.identification = reference.Identification or "X" - element = reference.DocumentRefForObjects[0].RelatedObjects[0] + + element = cls.get_reference_element(reference) new.name = element.Name new.reference_type = "DRAWING" @@ -720,3 +713,21 @@ class Drawing(blenderbim.core.tool.Drawing): if grid_obj.matrix_world != obj.matrix_world: bpy.ops.bim.update_representation(obj=obj.name) tool.Geometry.record_object_position(obj) + + @classmethod + def get_document_references(cls, document): + if tool.Ifc.get_schema() == "IFC2X3": + return document.DocumentReferences or [] + return document.HasDocumentReferences or [] + + @classmethod + def get_reference_element(cls, reference): + if tool.Ifc.get_schema() == "IFC2X3": + return [ + r for r in tool.Ifc.by_type("IfcRelAssociatesDocument") if r.RelatingDocument == reference + ][0].RelatedObjects[0] + return reference.DocumentRefForObjects[0].RelatedObjects[0] + + @classmethod + def get_drawing_human_scale(cls, drawing): + return ifcopenshell.util.element.get_psets(drawing)["EPset_Drawing"]["HumanScale"] From 4aa91cfa7fb9e9a299dd079be7c36f8381981742 Mon Sep 17 00:00:00 2001 From: Jesusbill Date: Wed, 13 Apr 2022 18:28:48 +0200 Subject: [PATCH 08/11] add feature to toggle wireframe visibility for linked models - no testcases --- .../blenderbim/bim/module/project/__init__.py | 1 + .../blenderbim/bim/module/project/operator.py | 21 +++++++++++++++++++ .../blenderbim/bim/module/project/prop.py | 1 + .../blenderbim/bim/module/project/ui.py | 2 ++ 4 files changed, 25 insertions(+) diff --git a/src/blenderbim/blenderbim/bim/module/project/__init__.py b/src/blenderbim/blenderbim/bim/module/project/__init__.py index 9ef8ba8b39..7898d1ddf0 100644 --- a/src/blenderbim/blenderbim/bim/module/project/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/project/__init__.py @@ -28,6 +28,7 @@ classes = ( operator.UnlinkIfc, operator.UnloadLink, operator.LoadLink, + operator.ToggleLinkVisibility, operator.SelectLibraryFile, operator.ChangeLibraryElement, operator.RefreshLibrary, diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index f536698149..17ddfdc7bc 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -685,10 +685,31 @@ class LoadLink(bpy.types.Operator): continue bpy.data.scenes[0].collection.children.link(child) link = context.scene.BIMProjectProperties.links.get(filepath) + link.collection_name = child.name link.is_loaded = True return {"FINISHED"} +class ToggleLinkVisibility(bpy.types.Operator): + bl_idname = "bim.toggle_link_visibility" + bl_label = "Toggle Link Visibility" + bl_options = {"REGISTER", "UNDO"} + bl_description = "Toggle visibility between SOLID and WIREFRAME" + collection_name: bpy.props.StringProperty() + + def execute(self, context): + collection_name = self.collection_name + objs = filter(lambda obj: "IfcOpeningElement" not in obj.name, bpy.data.collections[collection_name].all_objects) + for i,obj in enumerate(objs): + if i == 0: + if obj.display_type == "WIRE": + display_type = "TEXTURED" + else: + display_type = "WIRE" + obj.display_type = display_type + return {"FINISHED"} + + class ExportIFC(bpy.types.Operator): bl_idname = "export_ifc.bim" bl_label = "Export IFC" diff --git a/src/blenderbim/blenderbim/bim/module/project/prop.py b/src/blenderbim/blenderbim/bim/module/project/prop.py index c04121aea8..fe49738432 100644 --- a/src/blenderbim/blenderbim/bim/module/project/prop.py +++ b/src/blenderbim/blenderbim/bim/module/project/prop.py @@ -85,6 +85,7 @@ class FilterCategory(PropertyGroup): class Link(PropertyGroup): name: StringProperty(name="Name") + collection_name: StringProperty(name="Collection Name") is_loaded: BoolProperty(name="Is Loaded", default=False) diff --git a/src/blenderbim/blenderbim/bim/module/project/ui.py b/src/blenderbim/blenderbim/bim/module/project/ui.py index 271ce2de55..e90c818113 100644 --- a/src/blenderbim/blenderbim/bim/module/project/ui.py +++ b/src/blenderbim/blenderbim/bim/module/project/ui.py @@ -286,6 +286,8 @@ class BIM_UL_links(UIList): row = layout.row(align=True) if item.is_loaded: row.label(text=item.name) + op = row.operator("bim.toggle_link_visibility", text="", icon="HIDE_OFF") + op.collection_name = item.collection_name op = row.operator("bim.unload_link", text="", icon="UNLINKED") op.filepath = item.name else: From 78811d331bc82f4c7a01ded9c6e44c8c9aeb2c33 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 14 Apr 2022 15:18:42 +1000 Subject: [PATCH 09/11] #2136 Minor fix --- src/blenderbim/blenderbim/bim/module/drawing/prop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/prop.py b/src/blenderbim/blenderbim/bim/module/drawing/prop.py index a0935d6ac7..c56e6b9262 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/prop.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/prop.py @@ -75,7 +75,7 @@ def update_diagram_scale(self, context): if "|" not in scale: return human_scale, scale = scale.split("|") - element = tool.Ifc.get_entity(context.scene.active_object) + element = tool.Ifc.get_entity(context.active_object) if not element: return pset = ifcopenshell.util.element.get_psets(element).get("EPset_Drawing") From 5b1b8e8f50df9dbd4b8918e5a8d4c748fcabc9f0 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 14 Apr 2022 15:19:59 +1000 Subject: [PATCH 10/11] #1153 Annotation reference and sheet IDs now implemented in SVG. --- .../blenderbim/bim/module/drawing/operator.py | 10 +---- .../bim/module/drawing/svgwriter.py | 44 ++++++++++++++++++- src/blenderbim/blenderbim/tool/drawing.py | 18 ++++++++ 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index a1913c4ff2..aeadfaff80 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -635,14 +635,8 @@ class RemoveDrawingFromSheet(bpy.types.Operator): def execute(self, context): reference = tool.Ifc.get().by_id(self.reference) - if tool.Ifc.get_schema() == "IFC2X3": - sheet = reference.ReferenceToDocument[0] - drawing = [r for r in tool.Ifc.by_type("IfcRelAssociatesDocument") if r.RelatingDocument == reference][ - 0 - ].RelatedObjects[0] - else: - sheet = reference.ReferencedDocument - drawing = reference.DocumentRefForObjects[0].RelatedObjects[0] + sheet = tool.Drawing.get_reference_sheet(reference) + drawing = tool.Drawing.get_reference_element(reference) tool.Ifc.run("document.unassign_document", product=drawing, document=reference) tool.Ifc.run("document.remove_reference", reference=reference) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py index b13656735c..2fe5bc6944 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py @@ -453,9 +453,23 @@ class SvgWriter: (symbol_position * self.scale)[1], ) - self.svg.add(self.svg.use("#section-arrow", insert=tuple(symbol_position * self.scale), transform=transform)) + self.svg.add( + self.svg.use("#section-arrow", insert=tuple(symbol_position * self.scale), transform=transform) + ) self.svg.add(self.svg.use("#section-tag", insert=tuple(symbol_position * self.scale))) + reference_id, sheet_id = self.get_reference_and_sheet_id_from_annotation(tool.Ifc.get_entity(obj)) + text_position = list(symbol_position * self.scale) + text_style = { + "font-size": annotation.Annotator.get_svg_text_size(2.5), + "font-family": "OpenGost Type B TT", + "text-anchor": "middle", + "alignment-baseline": "middle", + "dominant-baseline": "middle", + } + self.svg.add(self.svg.text(reference_id, insert=(text_position[0], text_position[1] - 2.5), **text_style)) + self.svg.add(self.svg.text(sheet_id, insert=(text_position[0], text_position[1] + 2.5), **text_style)) + def draw_elevation_annotation(self, obj): x_offset = self.raw_width / 2 y_offset = self.raw_height / 2 @@ -475,6 +489,34 @@ class SvgWriter: self.svg.add(self.svg.use("#elevation-arrow", insert=tuple(symbol_position * self.scale), transform=transform)) self.svg.add(self.svg.use("#elevation-tag", insert=tuple(symbol_position * self.scale))) + reference_id, sheet_id = self.get_reference_and_sheet_id_from_annotation(tool.Ifc.get_entity(obj)) + text_position = list(symbol_position * self.scale) + text_style = { + "font-size": annotation.Annotator.get_svg_text_size(2.5), + "font-family": "OpenGost Type B TT", + "text-anchor": "middle", + "alignment-baseline": "middle", + "dominant-baseline": "middle", + } + self.svg.add(self.svg.text(reference_id, insert=(text_position[0], text_position[1] - 2.5), **text_style)) + self.svg.add(self.svg.text(sheet_id, insert=(text_position[0], text_position[1] + 2.5), **text_style)) + + def get_reference_and_sheet_id_from_annotation(self, element): + reference_id = "-" + sheet_id = "-" + drawing = tool.Drawing.get_annotation_element(element) + reference = tool.Drawing.get_drawing_reference(drawing) + if reference: + sheet = tool.Drawing.get_reference_sheet(reference) + if sheet: + if tool.Ifc.get_schema() == "IFC2X3": + reference_id = reference.ItemReference or "-" + sheet_id = sheet.DocumentId or "-" + else: + reference_id = reference.Identification or "-" + sheet_id = sheet.Identification or "-" + return (reference_id, sheet_id) + return ("-", "-") def draw_text_annotation(self, text_obj, position): x_offset = self.raw_width / 2 diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index e01bd58bea..66640599c7 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -731,3 +731,21 @@ class Drawing(blenderbim.core.tool.Drawing): @classmethod def get_drawing_human_scale(cls, drawing): return ifcopenshell.util.element.get_psets(drawing)["EPset_Drawing"]["HumanScale"] + + @classmethod + def get_annotation_element(cls, element): + for rel in element.HasAssignments: + if rel.is_a("IfcRelAssignsToProduct"): + return rel.RelatingProduct + + @classmethod + def get_drawing_reference(cls, drawing): + for rel in drawing.HasAssociations: + if rel.is_a("IfcRelAssociatesDocument"): + return rel.RelatingDocument + + @classmethod + def get_reference_sheet(cls, reference): + if tool.Ifc.get_schema() == "IFC2X3": + return reference.ReferenceToDocument[0] + return reference.ReferencedDocument From 1ba79775870595a06e8b0a02f7f24b23ff153200 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 14 Apr 2022 21:08:06 +1000 Subject: [PATCH 11/11] #1153 Fix newlines in text literals and smart tags in SVGs --- .../blenderbim/bim/module/drawing/sheeter.py | 2 +- .../blenderbim/bim/module/drawing/svgwriter.py | 14 +++++++++----- src/blenderbim/blenderbim/tool/drawing.py | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py b/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py index 95dc0b8da7..2a8229b660 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/sheeter.py @@ -67,7 +67,7 @@ class SheetBuilder: drawing_dir = os.path.join(self.data_dir, "diagrams") sheet_path = os.path.join(sheet_dir, sheet_name + ".svg") drawing_path = os.path.join(drawing_dir, filename + ".svg") - underlay_path = os.path.join(drawing_dir, filename + ".png") + underlay_path = os.path.join(drawing_dir, filename + "-underlay.png") if not os.path.isfile(sheet_path): raise FileNotFoundError diff --git a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py index 2fe5bc6944..b7e3b80a6e 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/svgwriter.py @@ -544,7 +544,7 @@ class SvgWriter: if text_obj.BIMTextProperties.symbol != "None": self.svg.add( - self.svg.use("#{}".format(text_obj.BIMTextProperties.symbol), insert=tuple(text_position * self.scale)) + self.svg.use(f"#{text_obj.BIMTextProperties.symbol}", insert=tuple(text_position * self.scale)) ) if text_literal.BoxAlignment == "top-left": @@ -575,11 +575,15 @@ class SvgWriter: alignment_baseline = "baseline" text_anchor = "end" - text_body = text_literal.Literal - if text_obj.name in self.annotations.get("template_variables", {}): - text_body = pystache.render(text_body, self.annotations["template_variables"][text_obj.name]) + literal = text_literal.Literal - for line_number, text_line in enumerate(text_body.split("\n")): + product = tool.Drawing.get_text_product(element) + selector = ifcopenshell.util.selector.Selector + variables = {} + for variable in re.findall("{{.*?}}", literal): + literal = literal.replace(variable, selector.get_element_value(product, variable[2:-2]) or "") + + for line_number, text_line in enumerate(literal.replace("\\n", "\n").split("\n")): self.svg.add( self.svg.text( text_line, diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index 66640599c7..8926ae9b39 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -201,7 +201,7 @@ class Drawing(blenderbim.core.tool.Drawing): name = document.Identification or "X" else: name = document.DocumentId or "X" - name += " - " + document.Name or "Unnamed" + name += " - " + (document.Name or "Unnamed") return name @classmethod