Difference between revisions of "BlenderBIM Add-on/Bonsai QuantityTakeoff"

From Wiki.OSArch
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
=Quantity Take-off (QTO)=
 
=Quantity Take-off (QTO)=
With Bonsai is possible to perform the Quantity take-off with the operator located under the "Costing and Schedulng" tab (for the december 2024 version). By clicking on "Perform Quantity Take-off" button is possible to perform the quantity dimension calculation and assign these values to the standard Quantity Set defined by the schema for that specific class.
+
With Bonsai it is possible to perform Quantity take-off with the operator located under the "Costing and Scheduling" tab (as of the December 2024 version). By clicking on the "Perform Quantity Take-off" button it is possible to perform the quantity dimension calculation and assign these values to the standard Quantity Set defined by the schema for that specific class.
  
 
By default, it is possible to choose between these two "ruleset":
 
By default, it is possible to choose between these two "ruleset":
Line 10: Line 10:
 
In simple words, the main difference between these two rulesets is that the first one uses the IfcOpenShell geometry processor and the second one uses Blender (TODO: explain this concept better).
 
In simple words, the main difference between these two rulesets is that the first one uses the IfcOpenShell geometry processor and the second one uses Blender (TODO: explain this concept better).
  
These two rulesets are enought for the majority of usecase but sometimes an user could want to modify or add new rulesets in order to perform custom calculations.
+
These two rulesets are enough for the majority of use case but sometimes a user may want to modify or add new rulesets in order to perform custom calculations.
  
 
At the moment it is not possible to simply add a new ruleset without modifying the code, but modify the code is not so difficult to add a new one and this is a perfect example for the Free Software Foundation "red shoes example" (don't you know it? https://u.fsf.org/shoetool)
 
At the moment it is not possible to simply add a new ruleset without modifying the code, but modify the code is not so difficult to add a new one and this is a perfect example for the Free Software Foundation "red shoes example" (don't you know it? https://u.fsf.org/shoetool)
  
First of all you need to find where are the folders that contains the files that Bosai actually uses. If you are not sure where they are located you can look at the installation scripts located into this folder
+
First of all you need to find where are the folders containing the files that Bosai actually uses. If you are not sure where they are located you can look at the installation scripts located into this folder:
  
 
/src/bonsai/scripts/installation/
 
/src/bonsai/scripts/installation/
  
For example, in linux, the folder is
+
In Linux, the folder is at:<br>
 
"$HOME/.config/blender/4.3/extensions/.local/lib/python3.11/site-packages"
 
"$HOME/.config/blender/4.3/extensions/.local/lib/python3.11/site-packages"
  
Pay attention that this actually modifies the files that allows to Bonsai to work so create a backup is always a good advice.
+
In Windows the folder is at:<br>
 +
"C:\Users\username\AppData\Roaming\Blender Foundation\Blender\4.3\extensions\.local\lib\python3.11\site-packages"
  
There are the three files that are interesting
+
Pay attention that, since this actually modifies the files that allows Bonsai to work, it's always a good advice to make a backup.
  
- ifc5d folder .json file
+
There are the three files that are interesting:
  
In this folder there are the .json files that maps all the classes and properties with the calculating functions. So for example let's open IFC4QtoBaseQuantitiesBlender.json.
+
1. ifc5d folder > *.json file
  
The first four lines contains infos about the ruleset (Name, Description) and the type of the "calculator" (Blender in this case).
+
[[File:Folder01.png|720px|frameless|center|patht to file]]
  
The other lines map the object property standard class with the blender calculating function. If there is a null instead of the calculating function name, this means that there is no mapping and the calculation are not performed.
+
In this folder there are the .json files that map all the classes and properties with the calculating functions. So for example let's open "IFC4QtoBaseQuantitiesBlender.json":
  
For example, "IfcActuator": {Qto_ActuatorBaseQuantities": {"GrossWeight": null}} will not performed but "IfcWall": {"Qto_WallBaseQuantities": {"GrossVolume": "get_gross_volume"}} will be performed.
+
The first four lines contain infos about the ruleset (Name, Description) and the type of the "calculator" (Blender in this case).
 +
 
 +
[[File:Jsonfile.png|1000px|frameless|center|json file]]
 +
 
 +
The other lines map the object property standard class with the blender calculating function. If there is a <code>Null</code> instead of the calculating function name, it means that there is no mapping and the calculation is not performed.
 +
 
 +
For example, "IfcActuator": {Qto_ActuatorBaseQuantities": {"GrossWeight": null}} will not perform but "IfcWall": {"Qto_WallBaseQuantities": {"GrossVolume": "get_gross_volume"}} will.
 +
 
 +
[[File:IfcWall.png|600px|frameless|center|IfcWall calculation]]
  
 
In this case, this means that, for every IfcWall object, there will be created a new Quantity Set called "Qto_WallBaseQuantities", with the "GrossVolume" property and the function "get_gross_volume" will be used to calculate the (gross) volume.
 
In this case, this means that, for every IfcWall object, there will be created a new Quantity Set called "Qto_WallBaseQuantities", with the "GrossVolume" property and the function "get_gross_volume" will be used to calculate the (gross) volume.
Line 39: Line 48:
 
So, where are these functions? Because this ruleset uses the Blender calculator, the calculating functions are stored here:
 
So, where are these functions? Because this ruleset uses the Blender calculator, the calculating functions are stored here:
  
- /bonsai/bim/qto/calculator.py
+
2. /bonsai/bim/module/qto/calculator.py
 +
 
 +
[[File:Calculator.png|800px|frameless|center|calculator py]]
 +
 
 +
This file contains the calculating functions so, for example, if you open it you will find the "get_gross_volume" function and you can see what the function actually does in order to perform the calculation:
 +
 
 +
[[File:Get gross volume.png|450px|frameless|center|get_gross_volume_function]]
 +
 
 +
3. /ifc5d/qto.py
 +
 
 +
[[File:Qto.png|720px|frameless|center|qto.py path]]
 +
 
 +
In this file there is the RULE_SET variable definition that is a list of all the available rulesets. It needs to correspond with the .json file name located in the folder.
  
This files contains the calculating functions so for example if you open it you will find the "get_gross_volume" function and you can see what the function actually does in order to perform the calculation
+
[[File:Ruleset.png|640px|frameless|center|rule_set function]]
  
- /ifc5d/qto.py
+
This file also contains the correct definition of the calculating function so, if we add new calculating functions, it is necessary to also add new lines there.
  
In this file there is the RULE_SET variable definition that is a list of all the available rulesets. It needs to correspond with the .json file names located in the folder.
+
=Step-by-step to create a new ruleset=
 +
Let's play a little with creating a new ruleset. In this example we create a new calculator to perform the rebar weight calculation automatically, multiplying the gross volume times a constant value.
  
This file also contain the correct definition of the calculating function so, if we add new calculating functions, it is necessary to add also new lines here.
+
'''1'''. Copy/paste an existing .json file in the ifc5d folder (for simplicity let's copy "IFC4QtoBaseQuantitiesBlender.json") and rename it as you want (like "IFC4QtoBaseQuantitiesBlenderRebar.json")
  
=How to create a new ruleset=
+
'''2'''. Add the same file name string into the "/ifc5d/qto.py" RULE_SET variable so it should be like this:
So let's play a little creating a new ruleset. This could be useful for example in order to perform the rebar weight calculation automatically, multiplying the gross volume with a constant value.
 
  
First of all, copy an existing .json file (for simplicity let's copy IFC4QtoBaseQuantitiesBlender.json) and rename it as you want (IFC4QtoBaseQuantitiesBlenderRebar.json) and add the same string into the /ifc5d/qto.py RULE_SET variable so it should be like this
+
RULE_SET = Literal["IFC4QtoBaseQuantities", "IFC4QtoBaseQuantitiesBlender", "'''IFC4QtoBaseQuantitiesBlenderRebar'''"]
  
RULE_SET = Literal["IFC4QtoBaseQuantities", "IFC4QtoBaseQuantitiesBlender", "IFC4QtoBaseQuantitiesBlenderRebar"]
+
If you now run Blender, you will already see the new ruleset under the "Costing and Scheduling" tab, but of course right now it does the same things as the Blender one.
  
If you run now Blender, you will already see the new ruleset under the costing and scheduling tab, but of course right now it does the same things of the Blender one.
+
'''3'''. Open the "IFC4QtoBaseQuantitiesBlenderRebar.json" file with a text editor to do some customization.
So let's open the IFC4QtoBaseQuantitiesBlenderRebar.json file and do some customization.
 
  
First of all, let's change the name in the second line into something like "My Ruleset - Rebar" and the description "This ruleset quantifies rebar weight starting from the object gross volume". Let's keep the blender calculation and focus on the mapping.
+
'''4'''. Change "name" in the second line into something like "My Ruleset - Rebar" and "description" to "This ruleset quantifies rebar weight starting from the object gross volume". Let's keep the blender calculation and focus on the mapping.
  
For simplicity, just keep only IfcBeam and IfcSlab objects and delete the others. For the rebar purpose, it is good because beams and slabs have different rebar weight constant. After the modification, the file should look like this
+
'''5'''. Keep only '''IfcBeam''' and '''IfcSlab''' objects and delete the others since, for calculation purposes, beams and slabs have different rebar weight/concrete volume ratio. After the modification, the file should look like this:
  
 
     {
 
     {
Line 82: Line 102:
 
     }
 
     }
  
Let's notice that we haven't yet defined the new calculating functions "get_rebar_beam_weight" and "get_rebar_slab_weight" so let's open the file
 
 
    /bonsai/bim/qto/calculator.py
 
 
and define them.
 
  
We can look at the other functions and copy past the new functions, maybe at the and of the file. The new functions should look like these:
+
'''6'''. Open the file: "/bonsai/bim/module/qto/calculator.py", notice that we haven't yet defined the new calculating functions "get_rebar_beam_weight" and "get_rebar_slab_weight", add new ones by copy/paste an existing one and modify them like:
  
 
     def get_rebar_beam_weight(o: bpy.types.Object) -> float:
 
     def get_rebar_beam_weight(o: bpy.types.Object) -> float:
Line 98: Line 113:
 
         return constant_slab_rebar * get_gross_volume(o)
 
         return constant_slab_rebar * get_gross_volume(o)
  
The last step is to define these new functions also in the /ifc5d/qto.py file in order to correctly add the new calculating function.
+
'''7'''. Define the new functions in the "/ifc5d/qto.py" file in order to correctly add the new calculating function by adding the following lines under #IfcMassMeasure section under Blender class
  
These lines should be added right under # IfcMassMeasure section under Blender class
+
[[File:Massmeasure.png|720px|frameless|center|add new functions]]
  
 
     # Rebar
 
     # Rebar
Line 106: Line 121:
 
     "get_rebar_slab_weight": Function("IfcMassMeasure", "Slab Rebar Weight", ""),
 
     "get_rebar_slab_weight": Function("IfcMassMeasure", "Slab Rebar Weight", ""),
  
Et voila, now it should be possible to perform the Quantity Take-off custom method with the defined custom ruleset.
+
''Et voilà'', now it should be possible to perform the Quantity Take-off method with a custom defined ruleset.

Latest revision as of 09:16, 5 January 2025

Quantity Take-off (QTO)[edit]

With Bonsai it is possible to perform Quantity take-off with the operator located under the "Costing and Scheduling" tab (as of the December 2024 version). By clicking on the "Perform Quantity Take-off" button it is possible to perform the quantity dimension calculation and assign these values to the standard Quantity Set defined by the schema for that specific class.

By default, it is possible to choose between these two "ruleset":

- IFC4 Base Quantities - IfcOpenShell

- IFC4 Base Quantities - Blender

In simple words, the main difference between these two rulesets is that the first one uses the IfcOpenShell geometry processor and the second one uses Blender (TODO: explain this concept better).

These two rulesets are enough for the majority of use case but sometimes a user may want to modify or add new rulesets in order to perform custom calculations.

At the moment it is not possible to simply add a new ruleset without modifying the code, but modify the code is not so difficult to add a new one and this is a perfect example for the Free Software Foundation "red shoes example" (don't you know it? https://u.fsf.org/shoetool)

First of all you need to find where are the folders containing the files that Bosai actually uses. If you are not sure where they are located you can look at the installation scripts located into this folder:

/src/bonsai/scripts/installation/

In Linux, the folder is at:
"$HOME/.config/blender/4.3/extensions/.local/lib/python3.11/site-packages"

In Windows the folder is at:
"C:\Users\username\AppData\Roaming\Blender Foundation\Blender\4.3\extensions\.local\lib\python3.11\site-packages"

Pay attention that, since this actually modifies the files that allows Bonsai to work, it's always a good advice to make a backup.

There are the three files that are interesting:

1. ifc5d folder > *.json file

patht to file

In this folder there are the .json files that map all the classes and properties with the calculating functions. So for example let's open "IFC4QtoBaseQuantitiesBlender.json":

The first four lines contain infos about the ruleset (Name, Description) and the type of the "calculator" (Blender in this case).

json file

The other lines map the object property standard class with the blender calculating function. If there is a Null instead of the calculating function name, it means that there is no mapping and the calculation is not performed.

For example, "IfcActuator": {Qto_ActuatorBaseQuantities": {"GrossWeight": null}} will not perform but "IfcWall": {"Qto_WallBaseQuantities": {"GrossVolume": "get_gross_volume"}} will.

IfcWall calculation

In this case, this means that, for every IfcWall object, there will be created a new Quantity Set called "Qto_WallBaseQuantities", with the "GrossVolume" property and the function "get_gross_volume" will be used to calculate the (gross) volume.

So, where are these functions? Because this ruleset uses the Blender calculator, the calculating functions are stored here:

2. /bonsai/bim/module/qto/calculator.py

calculator py

This file contains the calculating functions so, for example, if you open it you will find the "get_gross_volume" function and you can see what the function actually does in order to perform the calculation:

get_gross_volume_function

3. /ifc5d/qto.py

qto.py path

In this file there is the RULE_SET variable definition that is a list of all the available rulesets. It needs to correspond with the .json file name located in the folder.

rule_set function

This file also contains the correct definition of the calculating function so, if we add new calculating functions, it is necessary to also add new lines there.

Step-by-step to create a new ruleset[edit]

Let's play a little with creating a new ruleset. In this example we create a new calculator to perform the rebar weight calculation automatically, multiplying the gross volume times a constant value.

1. Copy/paste an existing .json file in the ifc5d folder (for simplicity let's copy "IFC4QtoBaseQuantitiesBlender.json") and rename it as you want (like "IFC4QtoBaseQuantitiesBlenderRebar.json")

2. Add the same file name string into the "/ifc5d/qto.py" RULE_SET variable so it should be like this:

RULE_SET = Literal["IFC4QtoBaseQuantities", "IFC4QtoBaseQuantitiesBlender", "IFC4QtoBaseQuantitiesBlenderRebar"]

If you now run Blender, you will already see the new ruleset under the "Costing and Scheduling" tab, but of course right now it does the same things as the Blender one.

3. Open the "IFC4QtoBaseQuantitiesBlenderRebar.json" file with a text editor to do some customization.

4. Change "name" in the second line into something like "My Ruleset - Rebar" and "description" to "This ruleset quantifies rebar weight starting from the object gross volume". Let's keep the blender calculation and focus on the mapping.

5. Keep only IfcBeam and IfcSlab objects and delete the others since, for calculation purposes, beams and slabs have different rebar weight/concrete volume ratio. After the modification, the file should look like this:

   {
       "name": "My Ruleset - Rebar",
       "description": "This ruleset quantifies rebar weight starting from the object gross volume",
       "calculators": {
           "Blender": {
               "IfcBeam": {
                   "Qto_BeamRebarQuantities": {
                       "RebarWeight": "get_rebar_beam_weight"
                   }
               },
               "IfcSlab": {
                   "Qto_SlabRebarQuantities": {
                       "RebarWeight": "get_rebar_slab_weight"
                   }
              }
           }
       }
   }


6. Open the file: "/bonsai/bim/module/qto/calculator.py", notice that we haven't yet defined the new calculating functions "get_rebar_beam_weight" and "get_rebar_slab_weight", add new ones by copy/paste an existing one and modify them like:

   def get_rebar_beam_weight(o: bpy.types.Object) -> float:
       constant_beam_rebar = 250
       return constant_beam_rebar * get_gross_volume(o)
   def get_rebar_slab_weight(o: bpy.types.Object) -> float:
       constant_slab_rebar = 100
       return constant_slab_rebar * get_gross_volume(o)

7. Define the new functions in the "/ifc5d/qto.py" file in order to correctly add the new calculating function by adding the following lines under #IfcMassMeasure section under Blender class

add new functions
   # Rebar
   "get_rebar_beam_weight": Function("IfcMassMeasure", "Beam Rebar Weight", ""),
   "get_rebar_slab_weight": Function("IfcMassMeasure", "Slab Rebar Weight", ""),

Et voilà, now it should be possible to perform the Quantity Take-off method with a custom defined ruleset.