mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +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,
|
||||
mep.FitFlowSegments,
|
||||
mep.RegenerateDistributionElement,
|
||||
prop.SnapVertex,
|
||||
prop.SnapMousePoint,
|
||||
prop.PolylinePoint,
|
||||
prop.BIMModelProperties,
|
||||
prop.BIMArrayProperties,
|
||||
prop.BIMStairProperties,
|
||||
|
||||
@@ -337,9 +337,26 @@ class WallPolylineDecorator:
|
||||
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
||||
gpu.state.point_size_set(10)
|
||||
|
||||
snap_prop = context.scene.BIMModelProperties.snap_vertex[0]
|
||||
points = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
|
||||
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
|
||||
point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
|
||||
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:
|
||||
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")
|
||||
|
||||
|
||||
class SnapVertex(PropertyGroup):
|
||||
class SnapMousePoint(PropertyGroup):
|
||||
x: bpy.props.FloatProperty(name="X")
|
||||
y: bpy.props.FloatProperty(name="Y")
|
||||
z: bpy.props.FloatProperty(name="Z")
|
||||
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):
|
||||
@@ -197,7 +202,8 @@ class BIMModelProperties(PropertyGroup):
|
||||
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")
|
||||
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):
|
||||
|
||||
@@ -338,7 +338,7 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
return (obj, bbox_2d)
|
||||
|
||||
|
||||
def main(self, context, event):
|
||||
def snaping_movement(self, context, event):
|
||||
scene = context.scene
|
||||
region = context.region
|
||||
rv3d = context.region_data
|
||||
@@ -506,35 +506,27 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
obj, hit, face_index = cast_rays_and_get_best_object()
|
||||
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:
|
||||
original_obj = obj.original
|
||||
|
||||
snap_points = get_snap_points(obj, face_index)
|
||||
snap_point = select_snap_point(snap_points, hit, snap_threshold)
|
||||
snap_points = tool.Snaping.get_snap_points_on_raycasted_obj(obj, face_index)
|
||||
snap_point = tool.Snaping.select_snap_point(snap_points, hit, snap_threshold)
|
||||
|
||||
if snap_point:
|
||||
snap_vertex.x = snap_point[0][0]
|
||||
snap_vertex.y = snap_point[0][1]
|
||||
snap_vertex.z = snap_point[0][2]
|
||||
snap_vertex.snap_type = snap_point[1]
|
||||
tool.Snaping.update_snaping_point(snap_point[0], snap_point[1])
|
||||
|
||||
else:
|
||||
snap_vertex.x = hit[0]
|
||||
snap_vertex.y = hit[1]
|
||||
snap_vertex.z = hit[2]
|
||||
snap_vertex.snap_type = "Face"
|
||||
tool.Snaping.update_snaping_point(hit, "Face")
|
||||
|
||||
else:
|
||||
snap_vertex.x = intersection[0]
|
||||
snap_vertex.y = intersection[1]
|
||||
snap_vertex.z = intersection[2]
|
||||
snap_vertex.snap_type = "Plane"
|
||||
tool.Snaping.update_snaping_point(intersection, "Plane")
|
||||
|
||||
|
||||
def draw_polyline(self, context):
|
||||
tool.Snaping.insert_polyline_point()
|
||||
|
||||
|
||||
def modal(self, context, event):
|
||||
|
||||
if event.type == 'MOUSEMOVE':
|
||||
@@ -551,16 +543,20 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
|
||||
if self.mousemove_count > 3:
|
||||
start_time = time()
|
||||
self.main(context, event)
|
||||
self.snaping_movement(context, event)
|
||||
operator_time = time() - start_time
|
||||
print(f"main function was finished in {operator_time:.2f} seconds")
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
if event.type == 'LEFTMOUSE':
|
||||
self.draw_polyline(context)
|
||||
|
||||
if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
|
||||
return {'PASS_THROUGH'}
|
||||
|
||||
if event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||
WallPolylineDecorator.uninstall()
|
||||
tool.Snaping.clear_polyline()
|
||||
tool.Blender.update_viewport()
|
||||
print("CANCELLED")
|
||||
return {'CANCELLED'}
|
||||
|
||||
@@ -934,6 +934,10 @@ class Spatial:
|
||||
class Covering:
|
||||
def get_z_from_ceiling_height(cls): pass
|
||||
|
||||
@interface
|
||||
class Snaping:
|
||||
pass
|
||||
|
||||
@interface
|
||||
class Structural:
|
||||
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.root import Root
|
||||
from blenderbim.tool.sequence import Sequence
|
||||
from blenderbim.tool.snaping import Snaping
|
||||
from blenderbim.tool.spatial import Spatial
|
||||
from blenderbim.tool.covering import Covering
|
||||
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