Adds beam and columns to insertion point product preview.

This commit is contained in:
Bruno Perdigão
2024-10-21 16:29:23 -03:00
parent 5fa5b28484
commit acc9e7f706
+117 -5
View File
@@ -16,15 +16,17 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
import blf import blf
import bpy import bpy
import gpu import gpu
import gpu_extras import gpu_extras
import bmesh import bmesh
import ifcopenshell
import bonsai.tool as tool import bonsai.tool as tool
from math import sin, cos, radians, degrees, atan2, acos
from bpy.types import SpaceView3D
import math import math
from math import sin, cos, tan, radians
from bpy.types import SpaceView3D
from bpy_extras import view3d_utils from bpy_extras import view3d_utils
from mathutils import Vector, Matrix, Quaternion from mathutils import Vector, Matrix, Quaternion
from gpu_extras.batch import batch_for_shader from gpu_extras.batch import batch_for_shader
@@ -386,11 +388,13 @@ class PolylineDecorator:
bm.verts.index_update() bm.verts.index_update()
bm.edges.index_update() bm.edges.index_update()
verts = bm.verts
edges = bm.edges
tris = [[loop.vert.index for loop in triangles] for triangles in bm.calc_loop_triangles()] tris = [[loop.vert.index for loop in triangles] for triangles in bm.calc_loop_triangles()]
bm.free() bm.free()
return tris return {"verts": verts, "edges": edges, "tris": tris}
def draw_batch(self, shader_type, content_pos, color, indices=None): def draw_batch(self, shader_type, content_pos, color, indices=None):
shader = self.line_shader if shader_type == "LINES" else self.shader shader = self.line_shader if shader_type == "LINES" else self.shader
@@ -450,7 +454,7 @@ class PolylineDecorator:
height = float(model_props.extrusion_depth) height = float(model_props.extrusion_depth)
rl = float(model_props.rl1) rl = float(model_props.rl1)
x_angle = float(model_props.x_angle) x_angle = float(model_props.x_angle)
angle_distortion = height * math.tan(x_angle) angle_distortion = height * tan(x_angle)
wall_preview_data = {} wall_preview_data = {}
wall_preview_data["verts"] = [] wall_preview_data["verts"] = []
@@ -576,6 +580,106 @@ class PolylineDecorator:
data["verts"] = [tuple(rot_mat @ (Vector((v[0], v[1], (v[2] + rl)))) + mouse_point) for v in data["verts"]] data["verts"] = [tuple(rot_mat @ (Vector((v[0], v[1], (v[2] + rl)))) + mouse_point) for v in data["verts"]]
return data return data
def get_profile_preview_data(self, context, relating_type):
material = ifcopenshell.util.element.get_material(relating_type)
profile = material.MaterialProfiles[0].Profile
model_props = context.scene.BIMModelProperties
extrusion_depth = model_props.extrusion_depth
cardinal_point = model_props.cardinal_point
rot_mat = Quaternion()
if relating_type.is_a("IfcBeamType"):
y_rot = Quaternion((0.0, 1.0, 0.0), radians(90))
z_rot = Quaternion((0.0, 0.0, 1.0), radians(90))
rot_mat = y_rot @ z_rot
# Get profile data
settings = ifcopenshell.geom.settings()
settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.CURVES_SURFACES_AND_SOLIDS)
shape = ifcopenshell.geom.create_shape(settings, profile)
verts = shape.verts
if not verts:
raise RuntimeError("Profile shape has no vertices, it probably is invalid.")
edges = shape.edges
grouped_verts = [[verts[i], verts[i + 1], 0] for i in range(0, len(verts), 3)]
grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
# Create extrusion bmesh
bm = bmesh.new()
new_verts = [bm.verts.new(v) for v in grouped_verts]
new_edges = [bm.edges.new((new_verts[i], new_verts[i + 1])) for i in range(len(grouped_verts) - 1)]
bm.verts.index_update()
bm.edges.index_update()
new_faces = bmesh.ops.contextual_create(bm, geom=bm.edges)
new_faces = bmesh.ops.extrude_face_region(bm, geom=bm.faces)
new_verts = [e for e in new_faces["geom"] if isinstance(e, bmesh.types.BMVert)]
new_faces = bmesh.ops.translate(bm, verts=new_verts, vec=(0.0, 0.0, extrusion_depth))
bm.verts.index_update()
bm.edges.index_update()
tris = [[loop.vert.index for loop in triangles] for triangles in bm.calc_loop_triangles()]
# Create bounding box
verts = bm.verts
i = len(verts)
min_x = min(v.co.x for v in verts)
max_x = max(v.co.x for v in verts)
min_y = min(v.co.y for v in verts)
max_y = max(v.co.y for v in verts)
min_z = min(v.co.z for v in verts)
max_z = max(v.co.z for v in verts)
bbox_verts = [
(min_x, min_y, min_z),
(max_x, min_y, min_z),
(max_x, max_y, min_z),
(min_x, max_y, min_z),
(min_x, min_y, max_z),
(max_x, min_y, max_z),
(max_x, max_y, max_z),
(min_x, max_y, max_z),
]
bbox_edges = [
(0 + i, 3 + i),
(3 + i, 7 + i),
(7 + i, 4 + i),
(4 + i, 0 + i),
(0 + i, 1 + i),
(3 + i, 2 + i),
(7 + i, 6 + i),
(4 + i, 5 + i),
(1 + i, 2 + i),
(2 + i, 6 + i),
(6 + i, 5 + i),
(5 + i, 1 + i),
]
# Calculate rotation, mouse position, angle and cardinal point
# TODO Cardinal point
# TODO Angle
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
data = {}
verts = [tuple(v.co) for v in verts]
verts.extend(bbox_verts)
verts = [tuple(rot_mat @ Vector(v)) for v in verts]
verts = [tuple(Vector(v) + mouse_point) for v in verts]
data["verts"] = verts
data["edges"] = bbox_edges
# data["edges"] = [(edge.verts[0].index, edge.verts[1].index) for edge in bm.edges]
data["tris"] = tris
bm.free()
return data
def draw_product_preview(self, context): def draw_product_preview(self, context):
def transparent_color(color, alpha=0.1): def transparent_color(color, alpha=0.1):
color = [i for i in color] color = [i for i in color]
@@ -614,6 +718,14 @@ class PolylineDecorator:
"TRIS", product_preview_data["verts"], transparent_color(decorator_color), product_preview_data["tris"] "TRIS", product_preview_data["verts"], transparent_color(decorator_color), product_preview_data["tris"]
) )
# Profile type products
product_preview_data = self.get_profile_preview_data(context, self.relating_type)
if product_preview_data:
self.draw_batch("LINES", product_preview_data["verts"], decorator_color, product_preview_data["edges"])
self.draw_batch(
"TRIS", product_preview_data["verts"], transparent_color(decorator_color), product_preview_data["tris"]
)
def draw_input_ui(self, context): def draw_input_ui(self, context):
texts = { texts = {
"D": "Distance: ", "D": "Distance: ",
@@ -903,7 +1015,7 @@ class PolylineDecorator:
area = polyline_data.area.split(" ")[0] area = polyline_data.area.split(" ")[0]
if area: if area:
if float(area) > 0: if float(area) > 0:
tris = self.calculate_polygon(polyline_verts) tris = self.calculate_polygon(polyline_verts)["tris"]
self.draw_batch("TRIS", polyline_verts, transparent_color(decorator_color_special), tris) self.draw_batch("TRIS", polyline_verts, transparent_color(decorator_color_special), tris)
# Mouse points # Mouse points