mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
Handle slab arc segments for wall generation
This commit is contained in:
committed by
GitHub
parent
6d3bed1f7d
commit
0a9d709111
@@ -1297,6 +1297,51 @@ class DumbWallGenerator:
|
||||
walls.append(self.create_wall_from_2_points(coords))
|
||||
return walls, is_polyline_closed
|
||||
|
||||
def _curve_has_arc_segments(self, curve: ifcopenshell.entity_instance) -> bool:
|
||||
if not curve.is_a("IfcIndexedPolyCurve"):
|
||||
return False
|
||||
segments = getattr(curve, "Segments", None) or ()
|
||||
for segment in segments:
|
||||
if (hasattr(segment, "is_a") and segment.is_a("IfcArcIndex")) or len(segment[0]) == 3:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _world_xy_point(self, slab_obj: bpy.types.Object, elevation: float, coord: Any) -> Vector:
|
||||
return slab_obj.matrix_world @ Vector((coord[0] * self.unit_scale, coord[1] * self.unit_scale, elevation))
|
||||
|
||||
def _derive_points_from_arc_segments(
|
||||
self, slab_obj: bpy.types.Object, elevation: float, curve: ifcopenshell.entity_instance
|
||||
) -> list[Vector]:
|
||||
points: list[Vector] = []
|
||||
coord_list = curve.Points.CoordList
|
||||
arc_resolution = 24
|
||||
precision = 1e-6
|
||||
|
||||
def append_point(point: Vector) -> None:
|
||||
if points and (points[-1] - point).length < precision:
|
||||
return
|
||||
points.append(point)
|
||||
|
||||
for segment in curve.Segments:
|
||||
segment_indices = [i - 1 for i in segment[0]]
|
||||
if len(segment_indices) == 3:
|
||||
p1 = self._world_xy_point(slab_obj, elevation, coord_list[segment_indices[0]])
|
||||
p2 = self._world_xy_point(slab_obj, elevation, coord_list[segment_indices[1]])
|
||||
p3 = self._world_xy_point(slab_obj, elevation, coord_list[segment_indices[2]])
|
||||
arc_points, _ = tool.Cad.create_arc_segments([p1, p2, p3], num_verts=arc_resolution + 1)
|
||||
arc_points = [Vector(arc_point) for arc_point in arc_points]
|
||||
if arc_points and (arc_points[0] - p1).length > (arc_points[-1] - p1).length:
|
||||
arc_points.reverse()
|
||||
for arc_point in arc_points:
|
||||
append_point(arc_point)
|
||||
elif len(segment_indices) >= 2:
|
||||
append_point(self._world_xy_point(slab_obj, elevation, coord_list[segment_indices[0]]))
|
||||
append_point(self._world_xy_point(slab_obj, elevation, coord_list[segment_indices[1]]))
|
||||
|
||||
if points and (points[0] - points[-1]).length >= precision:
|
||||
points.append(points[0].copy())
|
||||
return points
|
||||
|
||||
def derive_from_slab(self):
|
||||
slab_obj = bpy.context.active_object
|
||||
slab = tool.Ifc.get_entity(slab_obj)
|
||||
@@ -1305,10 +1350,17 @@ class DumbWallGenerator:
|
||||
elevation = self.container_obj.location.z
|
||||
representation = ifcopenshell.util.representation.get_representation(slab, "Model", "Body", "MODEL_VIEW")
|
||||
extrusion = tool.Model.get_extrusion(representation)
|
||||
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
|
||||
polyline_points = builder.get_polyline_coords(extrusion.SweptArea.OuterCurve)
|
||||
polyline_points = [[(v * self.unit_scale) for v in p] for p in polyline_points]
|
||||
polyline_points = [slab_obj.matrix_world @ Vector((p[0], p[1], elevation)) for p in polyline_points]
|
||||
outer_curve = extrusion.SweptArea.OuterCurve
|
||||
if self._curve_has_arc_segments(outer_curve):
|
||||
polyline_points = self._derive_points_from_arc_segments(slab_obj, elevation, outer_curve)
|
||||
else:
|
||||
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
|
||||
polyline_points = builder.get_polyline_coords(outer_curve)
|
||||
polyline_points = [[(v * self.unit_scale) for v in p] for p in polyline_points]
|
||||
polyline_points = [slab_obj.matrix_world @ Vector((p[0], p[1], elevation)) for p in polyline_points]
|
||||
|
||||
if len(polyline_points) < 3:
|
||||
return []
|
||||
if not tool.Cad.is_counter_clockwise_order(polyline_points[0], polyline_points[1], polyline_points[2]):
|
||||
polyline_points = polyline_points[::-1]
|
||||
walls = []
|
||||
|
||||
Reference in New Issue
Block a user