mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 15:07:38 +00:00
Stroke-generated walls now auto-join likely butt joints and t-junctions
This commit is contained in:
@@ -343,29 +343,69 @@ class DumbWallGenerator:
|
|||||||
|
|
||||||
def derive_from_sketch(self):
|
def derive_from_sketch(self):
|
||||||
objs = []
|
objs = []
|
||||||
|
strokes = []
|
||||||
layer = bpy.context.scene.grease_pencil.layers[0]
|
layer = bpy.context.scene.grease_pencil.layers[0]
|
||||||
|
|
||||||
for stroke in layer.active_frame.strokes:
|
for stroke in layer.active_frame.strokes:
|
||||||
if len(stroke.points) == 1:
|
if len(stroke.points) == 1:
|
||||||
continue
|
continue
|
||||||
direction = stroke.points[-1].co - stroke.points[0].co
|
coords = (stroke.points[0].co, stroke.points[-1].co)
|
||||||
self.length = direction.length
|
direction = coords[1] - coords[0]
|
||||||
if self.length < 0.1:
|
length = direction.length
|
||||||
|
if length < 0.1:
|
||||||
continue
|
continue
|
||||||
|
data = {"coords": coords}
|
||||||
|
|
||||||
# Round to nearest 50mm (yes, metric for now)
|
# Round to nearest 50mm (yes, metric for now)
|
||||||
self.length = 0.05 * round(self.length / 0.05)
|
self.length = 0.05 * round(length / 0.05)
|
||||||
# self.length = round(self.length, 2)
|
|
||||||
self.rotation = math.atan2(direction[1], direction[0])
|
self.rotation = math.atan2(direction[1], direction[0])
|
||||||
# Round to nearest 15 degrees
|
# Round to nearest 5 degrees
|
||||||
nearest_degree = (math.pi / 4) / 3
|
nearest_degree = (math.pi / 180) * 5
|
||||||
self.rotation = nearest_degree * round(self.rotation / nearest_degree)
|
self.rotation = nearest_degree * round(self.rotation / nearest_degree)
|
||||||
self.location = stroke.points[0].co
|
self.location = coords[0]
|
||||||
obj = self.create_wall()
|
data["obj"] = self.create_wall()
|
||||||
objs.append(obj)
|
strokes.append(data)
|
||||||
if len(objs) > 1:
|
objs.append(data["obj"])
|
||||||
DumbWallJoiner(obj, objs[-2]).join_T()
|
|
||||||
|
if len(objs) < 2:
|
||||||
|
return objs
|
||||||
|
|
||||||
|
l_joins = set()
|
||||||
|
for stroke in strokes:
|
||||||
|
if not stroke["obj"]:
|
||||||
|
continue
|
||||||
|
for stroke2 in strokes:
|
||||||
|
if stroke2 == stroke or not stroke2["obj"]:
|
||||||
|
continue
|
||||||
|
if self.has_nearby_ends(stroke, stroke2):
|
||||||
|
wall_join = "-JOIN-".join(sorted([stroke["obj"].name, stroke2["obj"].name]))
|
||||||
|
if wall_join not in l_joins:
|
||||||
|
l_joins.add(wall_join)
|
||||||
|
DumbWallJoiner(stroke["obj"], stroke2["obj"]).join_L()
|
||||||
|
elif self.has_end_near_stroke(stroke, stroke2):
|
||||||
|
DumbWallJoiner(stroke["obj"], stroke2["obj"]).join_T()
|
||||||
bpy.context.scene.grease_pencil.layers.remove(layer)
|
bpy.context.scene.grease_pencil.layers.remove(layer)
|
||||||
return objs
|
return objs
|
||||||
|
|
||||||
|
def has_end_near_stroke(self, stroke, stroke2):
|
||||||
|
point, distance = mathutils.geometry.intersect_point_line(stroke["coords"][0], *stroke2["coords"])
|
||||||
|
if distance > 0 and distance < 1 and self.is_near(point, stroke["coords"][0]):
|
||||||
|
return True
|
||||||
|
point, distance = mathutils.geometry.intersect_point_line(stroke["coords"][1], *stroke2["coords"])
|
||||||
|
if distance > 0 and distance < 1 and self.is_near(point, stroke["coords"][1]):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def has_nearby_ends(self, stroke, stroke2):
|
||||||
|
return (
|
||||||
|
self.is_near(stroke["coords"][0], stroke2["coords"][0])
|
||||||
|
or self.is_near(stroke["coords"][0], stroke2["coords"][1])
|
||||||
|
or self.is_near(stroke["coords"][1], stroke2["coords"][0])
|
||||||
|
or self.is_near(stroke["coords"][1], stroke2["coords"][1])
|
||||||
|
)
|
||||||
|
|
||||||
|
def is_near(self, point1, point2):
|
||||||
|
return (point1 - point2).length < 0.1
|
||||||
|
|
||||||
def derive_from_cursor(self):
|
def derive_from_cursor(self):
|
||||||
self.location = bpy.context.scene.cursor.location
|
self.location = bpy.context.scene.cursor.location
|
||||||
if self.collection:
|
if self.collection:
|
||||||
|
|||||||
@@ -27,12 +27,11 @@ class BIM_PT_authoring_architectural(Panel):
|
|||||||
bl_parent_id = "BIM_PT_authoring"
|
bl_parent_id = "BIM_PT_authoring"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
row = self.layout.row()
|
row = self.layout.row(align=True)
|
||||||
row.operator("bim.join_wall").join_type = "T"
|
row.operator("bim.join_wall", icon="MOD_SKIN", text="T").join_type = "T"
|
||||||
row.operator("bim.join_wall").join_type = "L"
|
row.operator("bim.join_wall", icon="MOD_SKIN", text="L").join_type = "L"
|
||||||
row.operator("bim.join_wall").join_type = "V"
|
row.operator("bim.join_wall", icon="MOD_SKIN", text="V").join_type = "V"
|
||||||
row.operator("bim.join_wall").join_type = "V"
|
row.operator("bim.join_wall", icon="X", text="").join_type = ""
|
||||||
row.operator("bim.join_wall").join_type = ""
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_misc_utilities(Panel):
|
class BIM_PT_misc_utilities(Panel):
|
||||||
|
|||||||
Reference in New Issue
Block a user