import bpy
import ifcopenshell
from ifcopenshell.api import run
import numpy
import numpy as np
from mathutils import Matrix
# Create a blank model
model = ifcopenshell.file()
# All projects must have one IFC Project element
project = run("root.create_entity", model, ifc_class="IfcProject", name="My Project")
# Geometry is optional in IFC, but because we want to use geometry in this example, let's define units
# Assigning without arguments defaults to metric units
run("unit.assign_unit", model)
# Let's create a modeling geometry context, so we can store 3D geometry (note: IFC supports 2D too!)
context = run("context.add_context", model, context_type="Model")
# In particular, in this example we want to store the 3D "body" geometry of objects, i.e. the body shape
body = run("context.add_context", model, context_type="Model",
context_identifier="Body", target_view="MODEL_VIEW", parent=context)
# Create a site, building, and storey. Many hierarchies are possible.
site = run("root.create_entity", model, ifc_class="IfcSite", name="My Site")
building = run("root.create_entity", model, ifc_class="IfcBuilding", name="Building A")
storey = run("root.create_entity", model, ifc_class="IfcBuildingStorey", name="Ground Floor")
# Since the site is our top level location, assign it to the project
# Then place our building on the site, and our storey in the building
run("aggregate.assign_object", model, relating_object=project, product=site)
run("aggregate.assign_object", model, relating_object=site, product=building)
run("aggregate.assign_object", model, relating_object=building, product=storey)
# in this part we define some values for our position matrix
x=1
y=2
z=0
rot = 90
# opening offset o and the elevation zw
o=1
zw = 0
# Geometry properties - length, height, tickness, window/opening length, window/heigth length,
l=5
h=0.5
t=0.25
lw=0.9
hw =2.1
# Create a 4x4 identity matrix. This matrix is at the origin with no rotation.
#matrix = numpy.eye(4)
def construieste_matrice_pozitie_rotatie(obiect_selectat):
# Verifică dacă există un obiect selectat
if obiect_selectat is not None:
# Obține locația obiectului și rotația sub formă de unghiuri Euler
locatie = obiect_selectat.location
rotatie_euler = obiect_selectat.rotation_euler
# Construiește matricea de rotație folosind unghiurile Euler
matrice_rotatie = Matrix.Rotation(rotatie_euler[2], 4, 'Z') @ \
Matrix.Rotation(rotatie_euler[1], 4, 'Y') @ \
Matrix.Rotation(rotatie_euler[0], 4, 'X')
# Construiește matricea de translatare
matrice_translatie = Matrix.Translation(locatie)
# Construiește matricea de poziție și rotație combinată
matrice_pozitie_rotatie = matrice_translatie @ matrice_rotatie
# Converteste matricea de poziție și rotație într-un array NumPy
matrice_numpy = np.array(matrice_pozitie_rotatie)
# Afișează matricea de poziție și rotație
print("Matricea de poziție și rotație:")
print(matrice_numpy)
else:
print("Nu este selectat niciun obiect.")
return matrice_numpy
def get_selected_objects():
selected_objects_list = []
# Obține obiectele selectate din contextul curent
selected_objects = bpy.context.selected_objects
# Verificăm dacă sunt obiecte selectate
if not selected_objects:
print("Nu există obiecte selectate.")
return []
else:
selected_objects_list.append(selected_objects)
return selected_objects_list
selected_objects=get_selected_objects()
# Apelarea funcției
matrix_list = []
for o in selected_objects[0]:
matrix = construieste_matrice_pozitie_rotatie(o)
column = run("root.create_entity", model, ifc_class="IfcColumn", name="ColumnE")
#Just for show
XD = 500
YD = 500
# Rectangles (or squares) are typically used for concrete columns and beams
profile = model.create_entity("IfcRectangleProfileDef", ProfileName=str(XD)+"x"+str(YD), ProfileType="AREA",
XDim=XD, YDim=YD)
# A profile-based representation, 1 meter long
representation = run("geometry.add_profile_representation", model, context=body, profile=profile, depth=2.8)
# Assign our new body geometry back to our column
run("geometry.assign_representation", model, product=column, representation=representation)
# Assign the column to our coordinates defined by the matrix
run("geometry.edit_object_placement", model, product=column, matrix=matrix, is_si=True)
# Let's prepare a concrete material. Note that our concrete material
# does not have any colours (styles) at this point.
concrete = ifcopenshell.api.run("material.add_material", model, name="CON01", category="concrete")
# Assign our concrete material to our beam
ifcopenshell.api.run("material.assign_material", model, product=column, type="IfcMaterial", material=concrete)
# Create a new surface style
style = ifcopenshell.api.run("style.add_style", model)
# Create a simple pink column shading colour and transparency.
ifcopenshell.api.run("style.add_surface_style", model,
style=style, ifc_class="IfcSurfaceStyleShading", attributes={
"SurfaceColour": { "Name": None, "Red": 0.50, "Green": 0.1, "Blue": 0.80},
"Transparency": 0.5, # 0 is opaque, 1 is transparent
})
# Now any element (like our column) with a concrete material will have
# a pink colour applied.
ifcopenshell.api.run("style.assign_material_style", model, material=concrete, style=style, context=body)
# Assign the column to the spacial structure (storey)
rel_contained_in_spatial_structure = model.createIfcRelContainedInSpatialStructure(GlobalId = ifcopenshell.guid.new(), RelatedElements = [column], RelatingStructure=storey)
model.write("C:\\Users\\ionut.ciuntuc\\Desktop\\ifcOpenShellTest.ifc")
bpy.ops.bim.load_project(filepath="C:\\Users\\ionut.ciuntuc\\Desktop\\ifcOpenShellTest.ifc", use_relative_path=False, should_start_fresh_session=False)
This part reads the py scripts from a folder and it runs it.
import bpy
import os
import numpy as np
from mathutils import Matrix
# Define the path to the folder containing Python scripts
SCRIPTS_FOLDER = "C:\\Users\\ionut.ciuntuc\\Desktop\\scripts"
def list_python_scripts(folder_path):
# Verificăm dacă folderul există
if not os.path.exists(folder_path):
print(f"Folderul '{folder_path}' nu există.")
return []
# Creăm o listă pentru scripturile Python
python_scripts = []
# Parcurgem toate fișierele din folder
for filename in os.listdir(folder_path):
# Verificăm dacă obiectul este un fișier și are extensia ".py"
if os.path.isfile(os.path.join(folder_path, filename)) and filename.endswith(".py"):
python_scripts.append(filename)
return python_scripts
class OBJECT_OT_RunScript(bpy.types.Operator):
"""Run the selected script"""
bl_idname = "object.run_script"
bl_label = "Run Script"
def execute(self, context):
selected_script = context.scene.selected_script
# Construim calea către scriptul selectat
script_path = os.path.join(SCRIPTS_FOLDER, selected_script)
# Verificăm dacă fișierul există
if os.path.exists(script_path):
# Executăm scriptul
with open(script_path, "r") as file:
script_code = file.read()
exec(script_code)
else:
self.report({'ERROR'}, f"Scriptul '{selected_script}' nu a fost găsit.")
return {'FINISHED'}
class OBJECT_PT_ScriptRunnerPanel(bpy.types.Panel):
"""Creates a Panel in the Object properties window"""
bl_label = "Script Runner"
bl_idname = "OBJECT_PT_ScriptRunnerPanel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Script Runner'
def draw(self, context):
layout = self.layout
# Dropdown menu for selecting a script
layout.prop(context.scene, "selected_script")
# Run script button
layout.operator("object.run_script")
def register():
bpy.types.Scene.selected_script = bpy.props.EnumProperty(
items=[(script, script, "") for script in list_python_scripts(SCRIPTS_FOLDER)],
name="Select Script",
description="Select a Python script to run"
)
bpy.utils.register_class(OBJECT_OT_RunScript)
bpy.utils.register_class(OBJECT_PT_ScriptRunnerPanel)
def unregister():
bpy.utils.unregister_class(OBJECT_OT_RunScript)
bpy.utils.unregister_class(OBJECT_PT_ScriptRunnerPanel)
del bpy.types.Scene.selected_script
if __name__ == "__main__":
register()