mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
fix rebase conflict
This commit is contained in:
@@ -404,6 +404,7 @@ class CadOffset(bpy.types.Operator):
|
|||||||
|
|
||||||
# Create loops from edges
|
# Create loops from edges
|
||||||
loop_edges = set(edges)
|
loop_edges = set(edges)
|
||||||
|
print("L1", loop_edges)
|
||||||
loops = []
|
loops = []
|
||||||
while loop_edges:
|
while loop_edges:
|
||||||
edge = loop_edges.pop()
|
edge = loop_edges.pop()
|
||||||
@@ -423,6 +424,7 @@ class CadOffset(bpy.types.Operator):
|
|||||||
has_found_connected_edge = True
|
has_found_connected_edge = True
|
||||||
loops.append(loop)
|
loops.append(loop)
|
||||||
|
|
||||||
|
print("L2", loops)
|
||||||
for loop in loops:
|
for loop in loops:
|
||||||
all_verts = {v.index for e in loop for v in e.verts}
|
all_verts = {v.index for e in loop for v in e.verts}
|
||||||
possible_v1s = []
|
possible_v1s = []
|
||||||
@@ -461,6 +463,7 @@ class CadOffset(bpy.types.Operator):
|
|||||||
|
|
||||||
v1 = start
|
v1 = start
|
||||||
|
|
||||||
|
print("V1", v1)
|
||||||
new_verts = []
|
new_verts = []
|
||||||
processed_verts = set()
|
processed_verts = set()
|
||||||
# [v0] --> v1 --> v2
|
# [v0] --> v1 --> v2
|
||||||
@@ -495,6 +498,8 @@ class CadOffset(bpy.types.Operator):
|
|||||||
|
|
||||||
normals = []
|
normals = []
|
||||||
v1co = (wp.inverted() @ mw @ v1.co).to_2d()
|
v1co = (wp.inverted() @ mw @ v1.co).to_2d()
|
||||||
|
|
||||||
|
print("V1CO", v1co)
|
||||||
if v2:
|
if v2:
|
||||||
v2co = (wp.inverted() @ mw @ v2.co).to_2d()
|
v2co = (wp.inverted() @ mw @ v2.co).to_2d()
|
||||||
direction = (v2co - v1co).normalized()
|
direction = (v2co - v1co).normalized()
|
||||||
@@ -531,8 +536,11 @@ class CadOffset(bpy.types.Operator):
|
|||||||
if is_closed:
|
if is_closed:
|
||||||
bm.edges.new((new_verts[len(new_verts) - 1], new_verts[0]))
|
bm.edges.new((new_verts[len(new_verts) - 1], new_verts[0]))
|
||||||
|
|
||||||
|
print("OP", new_verts)
|
||||||
bm.verts.index_update()
|
bm.verts.index_update()
|
||||||
bm.edges.index_update()
|
bm.edges.index_update()
|
||||||
|
print(bm.verts)
|
||||||
|
print(bm.edges)
|
||||||
bmesh.update_edit_mesh(obj.data)
|
bmesh.update_edit_mesh(obj.data)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ classes = (
|
|||||||
prop.BIMDoorProperties,
|
prop.BIMDoorProperties,
|
||||||
prop.BIMRailingProperties,
|
prop.BIMRailingProperties,
|
||||||
prop.BIMRoofProperties,
|
prop.BIMRoofProperties,
|
||||||
|
prop.BIMPolylineProperties,
|
||||||
ui.BIM_PT_array,
|
ui.BIM_PT_array,
|
||||||
ui.BIM_PT_stair,
|
ui.BIM_PT_stair,
|
||||||
ui.BIM_PT_sverchok,
|
ui.BIM_PT_sverchok,
|
||||||
@@ -203,6 +204,7 @@ def register():
|
|||||||
bpy.utils.register_tool(workspace.CableTool, after={"bim.cable_carrier_tool"}, separator=False, group=False)
|
bpy.utils.register_tool(workspace.CableTool, after={"bim.cable_carrier_tool"}, separator=False, group=False)
|
||||||
|
|
||||||
bpy.types.Scene.BIMModelProperties = bpy.props.PointerProperty(type=prop.BIMModelProperties)
|
bpy.types.Scene.BIMModelProperties = bpy.props.PointerProperty(type=prop.BIMModelProperties)
|
||||||
|
bpy.types.Scene.BIMPolylineProperties = bpy.props.PointerProperty(type=prop.BIMPolylineProperties)
|
||||||
bpy.types.Object.BIMArrayProperties = bpy.props.PointerProperty(type=prop.BIMArrayProperties)
|
bpy.types.Object.BIMArrayProperties = bpy.props.PointerProperty(type=prop.BIMArrayProperties)
|
||||||
bpy.types.Object.BIMStairProperties = bpy.props.PointerProperty(type=prop.BIMStairProperties)
|
bpy.types.Object.BIMStairProperties = bpy.props.PointerProperty(type=prop.BIMStairProperties)
|
||||||
bpy.types.Object.BIMSverchokProperties = bpy.props.PointerProperty(type=prop.BIMSverchokProperties)
|
bpy.types.Object.BIMSverchokProperties = bpy.props.PointerProperty(type=prop.BIMSverchokProperties)
|
||||||
@@ -233,6 +235,7 @@ def unregister():
|
|||||||
bpy.utils.unregister_tool(workspace.BimTool)
|
bpy.utils.unregister_tool(workspace.BimTool)
|
||||||
|
|
||||||
del bpy.types.Scene.BIMModelProperties
|
del bpy.types.Scene.BIMModelProperties
|
||||||
|
del bpy.types.Scene.BIMPolylineProperties
|
||||||
del bpy.types.Object.BIMArrayProperties
|
del bpy.types.Object.BIMArrayProperties
|
||||||
del bpy.types.Object.BIMStairProperties
|
del bpy.types.Object.BIMStairProperties
|
||||||
del bpy.types.Object.BIMSverchokProperties
|
del bpy.types.Object.BIMSverchokProperties
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ class PolylineDecorator:
|
|||||||
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_measurements, (context,), "WINDOW", "POST_PIXEL"))
|
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_measurements, (context,), "WINDOW", "POST_PIXEL"))
|
||||||
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_input_ui, (context,), "WINDOW", "POST_PIXEL"))
|
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_input_ui, (context,), "WINDOW", "POST_PIXEL"))
|
||||||
cls.handlers.append(SpaceView3D.draw_handler_add(handler, (context,), "WINDOW", "POST_VIEW"))
|
cls.handlers.append(SpaceView3D.draw_handler_add(handler, (context,), "WINDOW", "POST_VIEW"))
|
||||||
|
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_product_preview, (context,), "WINDOW", "POST_VIEW"))
|
||||||
cls.is_installed = True
|
cls.is_installed = True
|
||||||
|
|
||||||
|
|
||||||
@@ -365,6 +366,31 @@ class PolylineDecorator:
|
|||||||
shader.uniform_float("color", color)
|
shader.uniform_float("color", color)
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
|
def draw_product_preview(self, context):
|
||||||
|
polyline = context.scene.BIMPolylineProperties.polyline_point
|
||||||
|
prop = context.scene.BIMPolylineProperties.product_preview
|
||||||
|
points = []
|
||||||
|
edges = []
|
||||||
|
for i in range(len(prop)):
|
||||||
|
print(prop[i].x, prop[i].y, prop[i].z)
|
||||||
|
points.append(Vector((
|
||||||
|
prop[i].x,
|
||||||
|
prop[i].y,
|
||||||
|
prop[i].z
|
||||||
|
)))
|
||||||
|
n = len(points) // 2
|
||||||
|
bottom_loop = [[i, (i + 1) % (n)] for i in range(n)]
|
||||||
|
edges.extend(bottom_loop)
|
||||||
|
upper_loop = [[i + n for i in edges] for edges in bottom_loop]
|
||||||
|
edges.extend(upper_loop)
|
||||||
|
print(bottom_loop)
|
||||||
|
print(upper_loop)
|
||||||
|
connections = [[i, j] for i, j in zip(range(n), range(n, n*2))]
|
||||||
|
edges.extend(connections)
|
||||||
|
if len(points) > 1:
|
||||||
|
self.draw_batch("LINES", points, (0.0, 0.0, 0.0, 1.0), edges)
|
||||||
|
|
||||||
|
|
||||||
def draw_input_ui(self, context):
|
def draw_input_ui(self, context):
|
||||||
texts = {
|
texts = {
|
||||||
"D": "Distance: ",
|
"D": "Distance: ",
|
||||||
@@ -405,7 +431,7 @@ class PolylineDecorator:
|
|||||||
def draw_measurements(self, context):
|
def draw_measurements(self, context):
|
||||||
region = context.region
|
region = context.region
|
||||||
rv3d = region.data
|
rv3d = region.data
|
||||||
measurement_prop = context.scene.BIMModelProperties.polyline_measurement
|
measurement_prop = context.scene.BIMPolylineProperties.polyline_measurement
|
||||||
|
|
||||||
self.addon_prefs = tool.Blender.get_addon_preferences()
|
self.addon_prefs = tool.Blender.get_addon_preferences()
|
||||||
self.font_id = 1
|
self.font_id = 1
|
||||||
@@ -454,12 +480,12 @@ class PolylineDecorator:
|
|||||||
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_mouse_point[0]
|
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
||||||
# Point related to the mouse
|
# Point related to the mouse
|
||||||
mouse_point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
|
mouse_point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
snap_ref = context.scene.BIMModelProperties.snap_mouse_ref[0]
|
snap_ref = context.scene.BIMPolylineProperties.snap_mouse_ref[0]
|
||||||
ref_point = [Vector((snap_ref.x, snap_ref.y, snap_ref.z))]
|
ref_point = [Vector((snap_ref.x, snap_ref.y, snap_ref.z))]
|
||||||
except:
|
except:
|
||||||
ref_point = None
|
ref_point = None
|
||||||
@@ -477,7 +503,7 @@ class PolylineDecorator:
|
|||||||
self.draw_batch("LINES", mouse_point + projection_point, (1.0, 0.6, 0.0, 1.0), edges)
|
self.draw_batch("LINES", mouse_point + projection_point, (1.0, 0.6, 0.0, 1.0), edges)
|
||||||
|
|
||||||
# Create polyline with selected points
|
# Create polyline with selected points
|
||||||
polyline_data = context.scene.BIMModelProperties.polyline_point
|
polyline_data = context.scene.BIMPolylineProperties.polyline_point
|
||||||
polyline_points = []
|
polyline_points = []
|
||||||
polyline_edges = []
|
polyline_edges = []
|
||||||
for point_prop in polyline_data:
|
for point_prop in polyline_data:
|
||||||
@@ -524,6 +550,9 @@ class PolylineDecorator:
|
|||||||
|
|
||||||
# Draw polyline with selected points
|
# Draw polyline with selected points
|
||||||
self.line_shader.uniform_float("lineWidth", 2.0)
|
self.line_shader.uniform_float("lineWidth", 2.0)
|
||||||
|
print("PP", polyline_points)
|
||||||
self.draw_batch("POINTS", polyline_points, decorator_color_selected)
|
self.draw_batch("POINTS", polyline_points, decorator_color_selected)
|
||||||
if len(polyline_points) > 1:
|
if len(polyline_points) > 1:
|
||||||
self.draw_batch("LINES", polyline_points, decorator_color_selected, polyline_edges)
|
self.draw_batch("LINES", polyline_points, decorator_color_selected, polyline_edges)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ class PolylineOperator:
|
|||||||
is_valid = self.recalculate_inputs(context)
|
is_valid = self.recalculate_inputs(context)
|
||||||
if is_valid:
|
if is_valid:
|
||||||
tool.Snap.insert_polyline_point(self.input_ui)
|
tool.Snap.insert_polyline_point(self.input_ui)
|
||||||
|
|
||||||
self.tool_state.mode = "Mouse"
|
self.tool_state.mode = "Mouse"
|
||||||
self.tool_state.is_input_on = False
|
self.tool_state.is_input_on = False
|
||||||
self.input_type = None
|
self.input_type = None
|
||||||
|
|||||||
@@ -99,25 +99,6 @@ 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 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 PolylineMeasurement(PropertyGroup):
|
|
||||||
dim: bpy.props.StringProperty(name="Dimension")
|
|
||||||
angle: bpy.props.StringProperty(name="Angle")
|
|
||||||
position: bpy.props.FloatVectorProperty(name="Decorator Position", size=3)
|
|
||||||
|
|
||||||
|
|
||||||
class BIMModelProperties(PropertyGroup):
|
class BIMModelProperties(PropertyGroup):
|
||||||
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="Construction Class", update=update_ifc_class)
|
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="Construction Class", update=update_ifc_class)
|
||||||
relating_type_id: bpy.props.EnumProperty(
|
relating_type_id: bpy.props.EnumProperty(
|
||||||
@@ -209,10 +190,7 @@ 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_mouse_point: bpy.props.CollectionProperty(type=SnapMousePoint)
|
|
||||||
snap_mouse_ref: bpy.props.CollectionProperty(type=SnapMousePoint)
|
|
||||||
polyline_point: bpy.props.CollectionProperty(type=PolylinePoint)
|
|
||||||
polyline_measurement: bpy.props.CollectionProperty(type=PolylineMeasurement)
|
|
||||||
|
|
||||||
|
|
||||||
class BIMArrayProperties(PropertyGroup):
|
class BIMArrayProperties(PropertyGroup):
|
||||||
@@ -796,3 +774,30 @@ class BIMRoofProperties(PropertyGroup):
|
|||||||
|
|
||||||
def update_percentage(self):
|
def update_percentage(self):
|
||||||
self.percentage = math.tan(self.angle) * 100
|
self.percentage = math.tan(self.angle) * 100
|
||||||
|
|
||||||
|
|
||||||
|
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 PolylineMeasurement(PropertyGroup):
|
||||||
|
dim: bpy.props.StringProperty(name="Dimension")
|
||||||
|
angle: bpy.props.StringProperty(name="Angle")
|
||||||
|
position: bpy.props.FloatVectorProperty(name="Decorator Position", size=3)
|
||||||
|
|
||||||
|
|
||||||
|
class BIMPolylineProperties(PropertyGroup):
|
||||||
|
snap_mouse_point: bpy.props.CollectionProperty(type=SnapMousePoint)
|
||||||
|
snap_mouse_ref: bpy.props.CollectionProperty(type=SnapMousePoint)
|
||||||
|
polyline_point: bpy.props.CollectionProperty(type=PolylinePoint)
|
||||||
|
polyline_measurement: bpy.props.CollectionProperty(type=PolylineMeasurement)
|
||||||
|
product_preview: bpy.props.CollectionProperty(type=PolylinePoint)
|
||||||
|
|||||||
@@ -322,7 +322,11 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
|||||||
DumbWallJoiner().join_V(wall1["obj"], wall2["obj"])
|
DumbWallJoiner().join_V(wall1["obj"], wall2["obj"])
|
||||||
|
|
||||||
def modal(self, context, event):
|
def modal(self, context, event):
|
||||||
super().modal(context, event)
|
PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0])
|
||||||
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
|
if event.type in {"MIDDLEMOUSE", "WHEELUPMOUSE", "WHEELDOWNMOUSE"}:
|
||||||
|
return {"PASS_THROUGH"}
|
||||||
|
|
||||||
self.handle_instructions(context)
|
self.handle_instructions(context)
|
||||||
|
|
||||||
@@ -348,6 +352,11 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
|||||||
|
|
||||||
self.handle_inserting_polyline(context, event)
|
self.handle_inserting_polyline(context, event)
|
||||||
|
|
||||||
|
if event.type in {"LEFTMOUSE", "RIGHTMOUSE", "ENTER", "NUMPAD_ENTER"}:
|
||||||
|
tool.Polyline.offset_polyline(context)
|
||||||
|
# tool.Polyline.create_wall_preview(context)
|
||||||
|
print(context.scene.BIMPolylineProperties.product_preview)
|
||||||
|
|
||||||
result = self.handle_cancelation(context, event)
|
result = self.handle_cancelation(context, event)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
@@ -511,7 +520,7 @@ class DumbWallGenerator:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def derive_from_polyline(self):
|
def derive_from_polyline(self):
|
||||||
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
polyline_data = bpy.context.scene.BIMPolylineProperties.polyline_point
|
||||||
is_polyline_closed = False
|
is_polyline_closed = False
|
||||||
if len(polyline_data) > 3:
|
if len(polyline_data) > 3:
|
||||||
first_vec = Vector((polyline_data[0].x, polyline_data[0].y, polyline_data[0].z))
|
first_vec = Vector((polyline_data[0].x, polyline_data[0].y, polyline_data[0].z))
|
||||||
|
|||||||
@@ -626,3 +626,159 @@ class Cad:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_basis_vector(cls, object, axis_i):
|
def get_basis_vector(cls, object, axis_i):
|
||||||
return object.matrix_world.col[axis_i].normalized().to_3d()
|
return object.matrix_world.col[axis_i].normalized().to_3d()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def offset_edges(cls, bm, distance, mw=Matrix.Identity(4), wp=Matrix.Identity(4)):
|
||||||
|
|
||||||
|
bm.verts.ensure_lookup_table()
|
||||||
|
bm.edges.ensure_lookup_table()
|
||||||
|
|
||||||
|
edges = [e for e in bm.edges]
|
||||||
|
|
||||||
|
# if len(edges) < 1:
|
||||||
|
# return self.cancel_message("NO_EDGES")
|
||||||
|
|
||||||
|
verts = set()
|
||||||
|
[verts.update(e.verts) for e in edges]
|
||||||
|
print("V", verts)
|
||||||
|
print("E", edges)
|
||||||
|
|
||||||
|
rotation = Matrix.Rotation(math.pi / 2, 2, "Z")
|
||||||
|
rotation_i = Matrix.Rotation(-math.pi / 2, 2, "Z")
|
||||||
|
|
||||||
|
# Create loops from edges
|
||||||
|
loop_edges = set(edges)
|
||||||
|
print("L1", loop_edges)
|
||||||
|
loops = []
|
||||||
|
while loop_edges:
|
||||||
|
edge = loop_edges.pop()
|
||||||
|
loop = [edge]
|
||||||
|
has_found_connected_edge = True
|
||||||
|
while has_found_connected_edge:
|
||||||
|
has_found_connected_edge = False
|
||||||
|
for edge in loop_edges.copy():
|
||||||
|
edge_verts = set(edge.verts)
|
||||||
|
if edge_verts & set(loop[0].verts):
|
||||||
|
loop.insert(0, edge)
|
||||||
|
loop_edges.remove(edge)
|
||||||
|
has_found_connected_edge = True
|
||||||
|
elif edge_verts & set(loop[-1].verts):
|
||||||
|
loop.append(edge)
|
||||||
|
loop_edges.remove(edge)
|
||||||
|
has_found_connected_edge = True
|
||||||
|
loops.append(loop)
|
||||||
|
|
||||||
|
print("L2", loops)
|
||||||
|
for loop in loops:
|
||||||
|
all_verts = {v.index for e in loop for v in e.verts}
|
||||||
|
possible_v1s = []
|
||||||
|
is_closed = True
|
||||||
|
for edge in loop:
|
||||||
|
# If we have an open loop, start at either end instead
|
||||||
|
v = edge.verts[0]
|
||||||
|
if len(v.link_edges) == 1:
|
||||||
|
possible_v1s.append(v)
|
||||||
|
is_closed = False
|
||||||
|
else:
|
||||||
|
for link_edge in v.link_edges:
|
||||||
|
if link_edge.other_vert(v).index not in all_verts:
|
||||||
|
possible_v1s.append(v)
|
||||||
|
is_closed = False
|
||||||
|
break
|
||||||
|
v = edge.verts[1]
|
||||||
|
if len(v.link_edges) == 1:
|
||||||
|
possible_v1s.append(v)
|
||||||
|
is_closed = False
|
||||||
|
else:
|
||||||
|
for link_edge in v.link_edges:
|
||||||
|
if link_edge.other_vert(v).index not in all_verts:
|
||||||
|
possible_v1s.append(v)
|
||||||
|
is_closed = False
|
||||||
|
break
|
||||||
|
|
||||||
|
# Always start at the same vertex, so that when the operator is
|
||||||
|
# refreshed with new parameters the axes don't randomly get flipped.
|
||||||
|
if is_closed:
|
||||||
|
bm.verts.ensure_lookup_table()
|
||||||
|
bm.edges.ensure_lookup_table()
|
||||||
|
start = bm.verts[min(all_verts)]
|
||||||
|
else:
|
||||||
|
start = possible_v1s[0] if possible_v1s[0].index < possible_v1s[1].index else possible_v1s[1]
|
||||||
|
|
||||||
|
v1 = start
|
||||||
|
|
||||||
|
print("V1", v1)
|
||||||
|
new_verts = []
|
||||||
|
processed_verts = set()
|
||||||
|
# [v0] --> v1 --> v2
|
||||||
|
while v1:
|
||||||
|
if v1.index in processed_verts:
|
||||||
|
break
|
||||||
|
|
||||||
|
link_verts = []
|
||||||
|
if len(v1.link_edges) == 1:
|
||||||
|
v = v1.link_edges[0].other_vert(v1)
|
||||||
|
link_verts.append(v) if v.index in all_verts else None
|
||||||
|
else:
|
||||||
|
v = v1.link_edges[0].other_vert(v1)
|
||||||
|
link_verts.append(v) if v.index in all_verts else None
|
||||||
|
v = v1.link_edges[1].other_vert(v1)
|
||||||
|
link_verts.append(v) if v.index in all_verts else None
|
||||||
|
|
||||||
|
if len(link_verts) == 1:
|
||||||
|
v2 = link_verts[0]
|
||||||
|
v0 = None if v2.index not in processed_verts else v2
|
||||||
|
v2 = None if v2.index in processed_verts else v2
|
||||||
|
else:
|
||||||
|
v2 = link_verts[0]
|
||||||
|
v0 = link_verts[1]
|
||||||
|
if v2.index in processed_verts:
|
||||||
|
if is_closed and v0.index in processed_verts:
|
||||||
|
v3 = start
|
||||||
|
v0 = v0 if v2 == v3 else v2
|
||||||
|
v2 = v3
|
||||||
|
else:
|
||||||
|
v0, v2 = v2, v0
|
||||||
|
|
||||||
|
normals = []
|
||||||
|
v1co = (wp.inverted() @ mw @ v1.co).to_2d()
|
||||||
|
print("V1CO", v1co)
|
||||||
|
if v2:
|
||||||
|
v2co = (wp.inverted() @ mw @ v2.co).to_2d()
|
||||||
|
direction = (v2co - v1co).normalized()
|
||||||
|
local_direction = (rotation @ direction).normalized()
|
||||||
|
normals.append(local_direction)
|
||||||
|
|
||||||
|
if v0:
|
||||||
|
v0co = (wp.inverted() @ mw @ v0.co).to_2d()
|
||||||
|
direction = (v0co - v1co).normalized()
|
||||||
|
local_direction = (rotation_i @ direction).normalized()
|
||||||
|
normals.append(local_direction)
|
||||||
|
|
||||||
|
if len(normals) == 2:
|
||||||
|
# https://stackoverflow.com/a/54042831/9627415
|
||||||
|
new_normal = (normals[0].lerp(normals[1], 0.5)).normalized()
|
||||||
|
offset_length = distance / math.sqrt((1 + normals[0].dot(normals[1])) / 2)
|
||||||
|
offset = mw.inverted().to_quaternion() @ (wp.to_quaternion() @ (new_normal * offset_length).to_3d())
|
||||||
|
new_vert = v1.co + offset
|
||||||
|
new_verts.append(bm.verts.new(new_vert))
|
||||||
|
else:
|
||||||
|
normal = (normals[0] * distance).to_3d()
|
||||||
|
offset = mw.inverted().to_quaternion() @ (wp.to_quaternion() @ normal)
|
||||||
|
new_vert = v1.co + offset
|
||||||
|
new_verts.append(bm.verts.new(new_vert))
|
||||||
|
|
||||||
|
processed_verts.add(v1.index)
|
||||||
|
|
||||||
|
if v2 in processed_verts:
|
||||||
|
break
|
||||||
|
|
||||||
|
v1 = v2
|
||||||
|
print("INSIDE1", new_verts)
|
||||||
|
|
||||||
|
print("INSIDE2", new_verts)
|
||||||
|
return new_verts
|
||||||
|
# [bm.edges.new((new_verts[i], new_verts[i + 1])) for i in range(len(new_verts) - 1)]
|
||||||
|
# if is_closed:
|
||||||
|
# bm.edges.new((new_verts[len(new_verts) - 1], new_verts[0]))
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
# 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 bpy
|
||||||
|
import bmesh
|
||||||
import bonsai.core.tool
|
import bonsai.core.tool
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
from bonsai.bim.module.drawing.helper import format_distance
|
from bonsai.bim.module.drawing.helper import format_distance
|
||||||
@@ -117,14 +118,14 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
def calculate_distance_and_angle(cls, context, input_ui, tool_state):
|
def calculate_distance_and_angle(cls, context, input_ui, tool_state):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
polyline_data = context.scene.BIMModelProperties.polyline_point
|
polyline_data = context.scene.BIMPolylineProperties.polyline_point
|
||||||
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
||||||
last_point_data = polyline_data[len(polyline_data) - 1]
|
last_point_data = polyline_data[len(polyline_data) - 1]
|
||||||
except:
|
except:
|
||||||
default_container_elevation = 0
|
default_container_elevation = 0
|
||||||
last_point_data = None
|
last_point_data = None
|
||||||
|
|
||||||
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
|
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
||||||
|
|
||||||
if last_point_data:
|
if last_point_data:
|
||||||
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
|
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
|
||||||
@@ -181,7 +182,7 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def calculate_area(cls, context, input_ui):
|
def calculate_area(cls, context, input_ui):
|
||||||
try:
|
try:
|
||||||
polyline_data = context.scene.BIMModelProperties.polyline_point
|
polyline_data = context.scene.BIMPolylineProperties.polyline_point
|
||||||
except:
|
except:
|
||||||
return input_ui
|
return input_ui
|
||||||
|
|
||||||
@@ -224,7 +225,7 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def calculate_x_y_and_z(cls, context, input_ui, tool_state):
|
def calculate_x_y_and_z(cls, context, input_ui, tool_state):
|
||||||
try:
|
try:
|
||||||
polyline_data = context.scene.BIMModelProperties.polyline_point
|
polyline_data = context.scene.BIMPolylineProperties.polyline_point
|
||||||
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
||||||
last_point_data = polyline_data[len(polyline_data) - 1]
|
last_point_data = polyline_data[len(polyline_data) - 1]
|
||||||
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
|
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
|
||||||
@@ -232,7 +233,7 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
default_container_elevation = 0
|
default_container_elevation = 0
|
||||||
last_point = Vector((0, 0, 0))
|
last_point = Vector((0, 0, 0))
|
||||||
|
|
||||||
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
|
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
||||||
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
||||||
|
|
||||||
if tool_state.use_default_container:
|
if tool_state.use_default_container:
|
||||||
@@ -277,6 +278,58 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def offset_polyline(cls, context):
|
||||||
|
vertices = []
|
||||||
|
polyline_data = context.scene.BIMPolylineProperties.polyline_point
|
||||||
|
if len(polyline_data) < 2:
|
||||||
|
return
|
||||||
|
for point in polyline_data:
|
||||||
|
vertices.append(
|
||||||
|
Vector((point.x, point.y, point.z))
|
||||||
|
)
|
||||||
|
bm = bmesh.new()
|
||||||
|
|
||||||
|
new_verts = [bm.verts.new(v) for v in vertices]
|
||||||
|
new_edges = [bm.edges.new((new_verts[i], new_verts[i + 1])) for i in range(len(new_verts) - 1)]
|
||||||
|
|
||||||
|
# bm.verts.ensure_lookup_table()
|
||||||
|
# bm.edges.ensure_lookup_table()
|
||||||
|
bm.verts.index_update()
|
||||||
|
bm.edges.index_update()
|
||||||
|
print("LEN", len(vertices), len(bm.verts), len(polyline_data))
|
||||||
|
|
||||||
|
|
||||||
|
new_verts = tool.Cad.offset_edges(bm, .15) # TODO Change to Wall Thickness
|
||||||
|
print("NV", new_verts)
|
||||||
|
if new_verts is not None:
|
||||||
|
context.scene.BIMPolylineProperties.product_preview.clear()
|
||||||
|
for v in vertices:
|
||||||
|
prop = context.scene.BIMPolylineProperties.product_preview.add()
|
||||||
|
prop.x = v.x
|
||||||
|
prop.y = v.y
|
||||||
|
prop.z = v.z
|
||||||
|
|
||||||
|
for v in new_verts[::-1]:
|
||||||
|
prop = context.scene.BIMPolylineProperties.product_preview.add()
|
||||||
|
prop.x = v.co.x
|
||||||
|
prop.y = v.co.y
|
||||||
|
prop.z = v.co.z
|
||||||
|
|
||||||
|
for v in vertices:
|
||||||
|
prop = context.scene.BIMPolylineProperties.product_preview.add()
|
||||||
|
prop.x = v.x
|
||||||
|
prop.y = v.y
|
||||||
|
prop.z = 3 # TODO Change to Wall Height
|
||||||
|
|
||||||
|
for v in new_verts[::-1]:
|
||||||
|
prop = context.scene.BIMPolylineProperties.product_preview.add()
|
||||||
|
prop.x = v.co.x
|
||||||
|
prop.y = v.co.y
|
||||||
|
prop.z = 3 # TODO Change to Wall Height
|
||||||
|
# return new_verts
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_input(cls, input_number, input_type):
|
def validate_input(cls, input_number, input_type):
|
||||||
|
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
except:
|
except:
|
||||||
loc = Vector((0, 0, 0))
|
loc = Vector((0, 0, 0))
|
||||||
|
|
||||||
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
polyline_data = bpy.context.scene.BIMPolylineProperties.polyline_point
|
||||||
polyline_data = polyline_data[
|
polyline_data = polyline_data[
|
||||||
: len(polyline_data) - 1
|
: len(polyline_data) - 1
|
||||||
] # It doesn't make sense to snap to the last point created
|
] # It doesn't make sense to snap to the last point created
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def update_snapping_point(cls, snap_point, snap_type):
|
def update_snapping_point(cls, snap_point, snap_type):
|
||||||
try:
|
try:
|
||||||
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point[0]
|
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
||||||
except:
|
except:
|
||||||
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point.add()
|
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_point.add()
|
||||||
|
|
||||||
snap_vertex.x = snap_point[0]
|
snap_vertex.x = snap_point[0]
|
||||||
snap_vertex.y = snap_point[1]
|
snap_vertex.y = snap_point[1]
|
||||||
@@ -96,14 +96,14 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_snapping_point(cls):
|
def clear_snapping_point(cls):
|
||||||
bpy.context.scene.BIMModelProperties.snap_mouse_point.clear()
|
bpy.context.scene.BIMPolylineProperties.snap_mouse_point.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_snapping_ref(cls, snap_point, snap_type):
|
def update_snapping_ref(cls, snap_point, snap_type):
|
||||||
try:
|
try:
|
||||||
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_ref[0]
|
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_ref[0]
|
||||||
except:
|
except:
|
||||||
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_ref.add()
|
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_ref.add()
|
||||||
|
|
||||||
snap_vertex.x = snap_point[0]
|
snap_vertex.x = snap_point[0]
|
||||||
snap_vertex.y = snap_point[1]
|
snap_vertex.y = snap_point[1]
|
||||||
@@ -112,7 +112,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_snapping_ref(cls):
|
def clear_snapping_ref(cls):
|
||||||
bpy.context.scene.BIMModelProperties.snap_mouse_ref.clear()
|
bpy.context.scene.BIMPolylineProperties.snap_mouse_ref.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def insert_polyline_point(cls, input_ui):
|
def insert_polyline_point(cls, input_ui):
|
||||||
@@ -125,7 +125,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
d = input_ui.get_formatted_value("D")
|
d = input_ui.get_formatted_value("D")
|
||||||
a = input_ui.get_formatted_value("A")
|
a = input_ui.get_formatted_value("A")
|
||||||
|
|
||||||
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point[0]
|
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
||||||
if cls.tool_state.use_default_container:
|
if cls.tool_state.use_default_container:
|
||||||
z = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
z = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
||||||
|
|
||||||
@@ -135,44 +135,44 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
z = snap_vertex.z
|
z = snap_vertex.z
|
||||||
|
|
||||||
# Avoids creating two points at the same location
|
# Avoids creating two points at the same location
|
||||||
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
polyline_data = bpy.context.scene.BIMPolylineProperties.polyline_point
|
||||||
if polyline_data:
|
if polyline_data:
|
||||||
last_point = polyline_data[len(polyline_data) - 1]
|
last_point = polyline_data[len(polyline_data) - 1]
|
||||||
if (x, y, z) == (round(last_point.x, 4), round(last_point.y, 4), round(last_point.z, 4)):
|
if (x, y, z) == (round(last_point.x, 4), round(last_point.y, 4), round(last_point.z, 4)):
|
||||||
return
|
return
|
||||||
|
|
||||||
polyline_point = bpy.context.scene.BIMModelProperties.polyline_point.add()
|
polyline_point = bpy.context.scene.BIMPolylineProperties.polyline_point.add()
|
||||||
polyline_point.x = x
|
polyline_point.x = x
|
||||||
polyline_point.y = y
|
polyline_point.y = y
|
||||||
polyline_point.z = z
|
polyline_point.z = z
|
||||||
|
|
||||||
polyline_measurement = bpy.context.scene.BIMModelProperties.polyline_measurement.add()
|
polyline_measurement = bpy.context.scene.BIMPolylineProperties.polyline_measurement.add()
|
||||||
polyline_measurement.dim = d
|
polyline_measurement.dim = d
|
||||||
polyline_measurement.angle = a
|
polyline_measurement.angle = a
|
||||||
polyline_measurement.position = Vector((x, y, z))
|
polyline_measurement.position = Vector((x, y, z))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def close_polyline(cls):
|
def close_polyline(cls):
|
||||||
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
polyline_data = bpy.context.scene.BIMPolylineProperties.polyline_point
|
||||||
if len(polyline_data) > 2:
|
if len(polyline_data) > 2:
|
||||||
first_point = polyline_data[0]
|
first_point = polyline_data[0]
|
||||||
last_point = polyline_data[-1]
|
last_point = polyline_data[-1]
|
||||||
if not (first_point.x == last_point.x and first_point.y == last_point.y and first_point.z == last_point.z):
|
if not (first_point.x == last_point.x and first_point.y == last_point.y and first_point.z == last_point.z):
|
||||||
polyline_point = bpy.context.scene.BIMModelProperties.polyline_point.add()
|
polyline_point = bpy.context.scene.BIMPolylineProperties.polyline_point.add()
|
||||||
polyline_point.x = first_point.x
|
polyline_point.x = first_point.x
|
||||||
polyline_point.y = first_point.y
|
polyline_point.y = first_point.y
|
||||||
polyline_point.z = first_point.z
|
polyline_point.z = first_point.z
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_polyline(cls):
|
def clear_polyline(cls):
|
||||||
bpy.context.scene.BIMModelProperties.polyline_point.clear()
|
bpy.context.scene.BIMPolylineProperties.polyline_point.clear()
|
||||||
bpy.context.scene.BIMModelProperties.polyline_measurement.clear()
|
bpy.context.scene.BIMPolylineProperties.polyline_measurement.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def remove_last_polyline_point(cls):
|
def remove_last_polyline_point(cls):
|
||||||
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
polyline_data = bpy.context.scene.BIMPolylineProperties.polyline_point
|
||||||
polyline_data.remove(len(polyline_data) - 1)
|
polyline_data.remove(len(polyline_data) - 1)
|
||||||
polyline_measurement = bpy.context.scene.BIMModelProperties.polyline_measurement
|
polyline_measurement = bpy.context.scene.BIMPolylineProperties.polyline_measurement
|
||||||
polyline_measurement.remove(len(polyline_measurement) - 1)
|
polyline_measurement.remove(len(polyline_measurement) - 1)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -210,7 +210,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
return (v1, v2, v3, v4)
|
return (v1, v2, v3, v4)
|
||||||
|
|
||||||
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
||||||
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
polyline_data = bpy.context.scene.BIMPolylineProperties.polyline_point
|
||||||
if polyline_data:
|
if polyline_data:
|
||||||
last_point_data = polyline_data[-1]
|
last_point_data = polyline_data[-1]
|
||||||
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
|
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
|
||||||
@@ -383,7 +383,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
break
|
break
|
||||||
# Polyline
|
# Polyline
|
||||||
try:
|
try:
|
||||||
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
polyline_data = bpy.context.scene.BIMPolylineProperties.polyline_point
|
||||||
last_polyline_point = polyline_data[len(polyline_data) - 1]
|
last_polyline_point = polyline_data[len(polyline_data) - 1]
|
||||||
except:
|
except:
|
||||||
last_polyline_point = None
|
last_polyline_point = None
|
||||||
|
|||||||
Reference in New Issue
Block a user