mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 12:07:59 +00:00
Basic polyline implementation
This commit is contained in:
committed by
Bruno Perdigão
parent
056df7758b
commit
10035662dd
@@ -117,7 +117,8 @@ classes = (
|
|||||||
space.ToggleHideSpaces,
|
space.ToggleHideSpaces,
|
||||||
mep.FitFlowSegments,
|
mep.FitFlowSegments,
|
||||||
mep.RegenerateDistributionElement,
|
mep.RegenerateDistributionElement,
|
||||||
prop.SnapVertex,
|
prop.SnapMousePoint,
|
||||||
|
prop.PolylinePoint,
|
||||||
prop.BIMModelProperties,
|
prop.BIMModelProperties,
|
||||||
prop.BIMArrayProperties,
|
prop.BIMArrayProperties,
|
||||||
prop.BIMStairProperties,
|
prop.BIMStairProperties,
|
||||||
|
|||||||
@@ -337,9 +337,26 @@ class WallPolylineDecorator:
|
|||||||
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
||||||
gpu.state.point_size_set(10)
|
gpu.state.point_size_set(10)
|
||||||
|
|
||||||
snap_prop = context.scene.BIMModelProperties.snap_vertex[0]
|
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
|
||||||
points = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
|
point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
|
||||||
if snap_prop.snap_type in ["Face", "Plane"]:
|
if snap_prop.snap_type in ["Face", "Plane"]:
|
||||||
self.draw_batch("POINTS", points, decorator_color_special)
|
self.draw_batch("POINTS", point, decorator_color_special)
|
||||||
else:
|
else:
|
||||||
self.draw_batch("POINTS", points, decorator_color_selected)
|
self.draw_batch("POINTS", point, decorator_color_selected)
|
||||||
|
|
||||||
|
polyline_data = context.scene.BIMModelProperties.polyline_point
|
||||||
|
polyline_points = []
|
||||||
|
polyline_edges = []
|
||||||
|
for point_prop in polyline_data:
|
||||||
|
point = Vector((point_prop.x, point_prop.y, point_prop.z))
|
||||||
|
polyline_points.append(point)
|
||||||
|
|
||||||
|
for i in range(len(polyline_points) - 1):
|
||||||
|
polyline_edges.append([i, i+1])
|
||||||
|
|
||||||
|
self.draw_batch("POINTS", polyline_points, decorator_color_selected)
|
||||||
|
if len(polyline_points) > 1:
|
||||||
|
self.draw_batch("LINES", polyline_points, decorator_color_selected, polyline_edges)
|
||||||
|
|
||||||
|
self.line_shader.uniform_float("lineWidth", 2.0)
|
||||||
|
|
||||||
|
|||||||
@@ -99,11 +99,16 @@ def is_object_array_applicable(self, obj):
|
|||||||
return ifcopenshell.util.element.get_pset(element, "BBIM_Array")
|
return ifcopenshell.util.element.get_pset(element, "BBIM_Array")
|
||||||
|
|
||||||
|
|
||||||
class SnapVertex(PropertyGroup):
|
class SnapMousePoint(PropertyGroup):
|
||||||
x: bpy.props.FloatProperty(name="X")
|
x: bpy.props.FloatProperty(name="X")
|
||||||
y: bpy.props.FloatProperty(name="Y")
|
y: bpy.props.FloatProperty(name="Y")
|
||||||
z: bpy.props.FloatProperty(name="Z")
|
z: bpy.props.FloatProperty(name="Z")
|
||||||
snap_type: bpy.props.StringProperty(name="Snap Type")
|
snap_type: bpy.props.StringProperty(name="Snap Type")
|
||||||
|
|
||||||
|
class PolylinePoint(PropertyGroup):
|
||||||
|
x: bpy.props.FloatProperty(name="X")
|
||||||
|
y: bpy.props.FloatProperty(name="Y")
|
||||||
|
z: bpy.props.FloatProperty(name="Z")
|
||||||
|
|
||||||
|
|
||||||
class BIMModelProperties(PropertyGroup):
|
class BIMModelProperties(PropertyGroup):
|
||||||
@@ -197,7 +202,8 @@ class BIMModelProperties(PropertyGroup):
|
|||||||
type_predefined_type: bpy.props.EnumProperty(items=get_type_predefined_type, name="Predefined Type", default=None)
|
type_predefined_type: bpy.props.EnumProperty(items=get_type_predefined_type, name="Predefined Type", default=None)
|
||||||
type_name: bpy.props.StringProperty(name="Name", default="TYPEX")
|
type_name: bpy.props.StringProperty(name="Name", default="TYPEX")
|
||||||
boundary_class: bpy.props.EnumProperty(items=get_boundary_class, name="Boundary Class")
|
boundary_class: bpy.props.EnumProperty(items=get_boundary_class, name="Boundary Class")
|
||||||
snap_vertex: bpy.props.CollectionProperty(type=SnapVertex)
|
snap_mouse_point: bpy.props.CollectionProperty(type=SnapMousePoint)
|
||||||
|
polyline_point: bpy.props.CollectionProperty(type=PolylinePoint)
|
||||||
|
|
||||||
|
|
||||||
class BIMArrayProperties(PropertyGroup):
|
class BIMArrayProperties(PropertyGroup):
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ class DrawPolylineWall(bpy.types.Operator):
|
|||||||
return (obj, bbox_2d)
|
return (obj, bbox_2d)
|
||||||
|
|
||||||
|
|
||||||
def main(self, context, event):
|
def snaping_movement(self, context, event):
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
region = context.region
|
region = context.region
|
||||||
rv3d = context.region_data
|
rv3d = context.region_data
|
||||||
@@ -506,35 +506,27 @@ class DrawPolylineWall(bpy.types.Operator):
|
|||||||
obj, hit, face_index = cast_rays_and_get_best_object()
|
obj, hit, face_index = cast_rays_and_get_best_object()
|
||||||
intersection = ray_cast_to_plane(context, plane_origin, plane_normal)
|
intersection = ray_cast_to_plane(context, plane_origin, plane_normal)
|
||||||
|
|
||||||
try:
|
|
||||||
snap_vertex = context.scene.BIMModelProperties.snap_vertex[0]
|
|
||||||
except:
|
|
||||||
snap_vertex = context.scene.BIMModelProperties.snap_vertex.add()
|
|
||||||
|
|
||||||
if obj is not None:
|
if obj is not None:
|
||||||
original_obj = obj.original
|
original_obj = obj.original
|
||||||
|
|
||||||
snap_points = get_snap_points(obj, face_index)
|
snap_points = tool.Snaping.get_snap_points_on_raycasted_obj(obj, face_index)
|
||||||
snap_point = select_snap_point(snap_points, hit, snap_threshold)
|
snap_point = tool.Snaping.select_snap_point(snap_points, hit, snap_threshold)
|
||||||
|
|
||||||
if snap_point:
|
if snap_point:
|
||||||
snap_vertex.x = snap_point[0][0]
|
tool.Snaping.update_snaping_point(snap_point[0], snap_point[1])
|
||||||
snap_vertex.y = snap_point[0][1]
|
|
||||||
snap_vertex.z = snap_point[0][2]
|
|
||||||
snap_vertex.snap_type = snap_point[1]
|
|
||||||
else:
|
else:
|
||||||
snap_vertex.x = hit[0]
|
tool.Snaping.update_snaping_point(hit, "Face")
|
||||||
snap_vertex.y = hit[1]
|
|
||||||
snap_vertex.z = hit[2]
|
|
||||||
snap_vertex.snap_type = "Face"
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
snap_vertex.x = intersection[0]
|
tool.Snaping.update_snaping_point(intersection, "Plane")
|
||||||
snap_vertex.y = intersection[1]
|
|
||||||
snap_vertex.z = intersection[2]
|
|
||||||
snap_vertex.snap_type = "Plane"
|
|
||||||
|
|
||||||
|
|
||||||
|
def draw_polyline(self, context):
|
||||||
|
tool.Snaping.insert_polyline_point()
|
||||||
|
|
||||||
|
|
||||||
def modal(self, context, event):
|
def modal(self, context, event):
|
||||||
|
|
||||||
if event.type == 'MOUSEMOVE':
|
if event.type == 'MOUSEMOVE':
|
||||||
@@ -551,16 +543,20 @@ class DrawPolylineWall(bpy.types.Operator):
|
|||||||
|
|
||||||
if self.mousemove_count > 3:
|
if self.mousemove_count > 3:
|
||||||
start_time = time()
|
start_time = time()
|
||||||
self.main(context, event)
|
self.snaping_movement(context, event)
|
||||||
operator_time = time() - start_time
|
operator_time = time() - start_time
|
||||||
print(f"main function was finished in {operator_time:.2f} seconds")
|
print(f"main function was finished in {operator_time:.2f} seconds")
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
if event.type == 'LEFTMOUSE':
|
||||||
|
self.draw_polyline(context)
|
||||||
|
|
||||||
if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
|
if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
|
||||||
return {'PASS_THROUGH'}
|
return {'PASS_THROUGH'}
|
||||||
|
|
||||||
if event.type in {'RIGHTMOUSE', 'ESC'}:
|
if event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||||
WallPolylineDecorator.uninstall()
|
WallPolylineDecorator.uninstall()
|
||||||
|
tool.Snaping.clear_polyline()
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
print("CANCELLED")
|
print("CANCELLED")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|||||||
@@ -934,6 +934,10 @@ class Spatial:
|
|||||||
class Covering:
|
class Covering:
|
||||||
def get_z_from_ceiling_height(cls): pass
|
def get_z_from_ceiling_height(cls): pass
|
||||||
|
|
||||||
|
@interface
|
||||||
|
class Snaping:
|
||||||
|
pass
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
class Structural:
|
class Structural:
|
||||||
def disable_editing_structural_analysis_model(cls): pass
|
def disable_editing_structural_analysis_model(cls): pass
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ from blenderbim.tool.qto import Qto
|
|||||||
from blenderbim.tool.resource import Resource
|
from blenderbim.tool.resource import Resource
|
||||||
from blenderbim.tool.root import Root
|
from blenderbim.tool.root import Root
|
||||||
from blenderbim.tool.sequence import Sequence
|
from blenderbim.tool.sequence import Sequence
|
||||||
|
from blenderbim.tool.snaping import Snaping
|
||||||
from blenderbim.tool.spatial import Spatial
|
from blenderbim.tool.spatial import Spatial
|
||||||
from blenderbim.tool.covering import Covering
|
from blenderbim.tool.covering import Covering
|
||||||
from blenderbim.tool.structural import Structural
|
from blenderbim.tool.structural import Structural
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2022 Cyril Waechter <cyril@biminsight.ch>
|
||||||
|
#
|
||||||
|
# This file is part of BlenderBIM Add-on.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import blenderbim.core.tool
|
||||||
|
import mathutils
|
||||||
|
from mathutils import Matrix, Vector
|
||||||
|
|
||||||
|
|
||||||
|
class Snaping(blenderbim.core.tool.Snaping):
|
||||||
|
@classmethod
|
||||||
|
def get_snap_points_on_raycasted_obj(cls, obj, face_index):
|
||||||
|
snap_points = {}
|
||||||
|
matrix = obj.matrix_world.copy()
|
||||||
|
face = obj.data.polygons[face_index]
|
||||||
|
vertices = []
|
||||||
|
for i in face.vertices:
|
||||||
|
vertices.append(matrix @ obj.data.vertices[i].co)
|
||||||
|
|
||||||
|
edges_center = []
|
||||||
|
for v1, v2 in zip(vertices, vertices[1:] + [vertices[0]]):
|
||||||
|
middle_dist = (v2-v1) / 2
|
||||||
|
edges_center.append(v1 + middle_dist)
|
||||||
|
|
||||||
|
snap_points.update({tuple(vertex): "Vertices" for vertex in vertices})
|
||||||
|
snap_points.update({tuple(edge_center): "Edge Center" for edge_center in edges_center})
|
||||||
|
|
||||||
|
return snap_points
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def select_snap_point(cls, snap_points, hit, threshold):
|
||||||
|
shortest_distance = None
|
||||||
|
snap_point = None
|
||||||
|
for point, snap_type in snap_points.items():
|
||||||
|
point = Vector(point)
|
||||||
|
distance = (point - hit).length
|
||||||
|
if distance > threshold:
|
||||||
|
continue
|
||||||
|
if shortest_distance and distance < shortest_distance:
|
||||||
|
shortest_distance = distance
|
||||||
|
snap_point = (point, snap_type)
|
||||||
|
|
||||||
|
elif not shortest_distance:
|
||||||
|
shortest_distance = distance
|
||||||
|
snap_point = (point, snap_type)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return snap_point
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_snaping_point(cls, snap_point, snap_type):
|
||||||
|
try:
|
||||||
|
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point[0]
|
||||||
|
except:
|
||||||
|
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point.add()
|
||||||
|
|
||||||
|
snap_vertex.x = snap_point[0]
|
||||||
|
snap_vertex.y = snap_point[1]
|
||||||
|
snap_vertex.z = snap_point[2]
|
||||||
|
snap_vertex.snap_type = snap_type
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def insert_polyline_point(cls):
|
||||||
|
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point[0]
|
||||||
|
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
||||||
|
print(len(polyline_data))
|
||||||
|
if len(polyline_data) > 0:
|
||||||
|
print("X", snap_vertex.x, polyline_data[-1].x)
|
||||||
|
if snap_vertex.x == polyline_data[-1].x and\
|
||||||
|
snap_vertex.y == polyline_data[-1].y and\
|
||||||
|
snap_vertex.z == polyline_data[-1].z:
|
||||||
|
return
|
||||||
|
|
||||||
|
polyline_point = bpy.context.scene.BIMModelProperties.polyline_point.add()
|
||||||
|
polyline_point.x = snap_vertex.x
|
||||||
|
polyline_point.y = snap_vertex.y
|
||||||
|
polyline_point.z = 0 # TODO Update to the the default container height
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def clear_polyline(cls):
|
||||||
|
bpy.context.scene.BIMModelProperties.polyline_point.clear()
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user