mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 23:36:20 +00:00
ShapeBuilder to use IfcPolyline of IfcIndexedPolyCurve to support ifc2x3
needed it to add suport for window/door modifiers in ifc2x3 in the next commit
This commit is contained in:
@@ -38,8 +38,11 @@ class ShapeBuilder:
|
|||||||
def polyline(self, points, closed=False, position_offset=None, arc_points=[]):
|
def polyline(self, points, closed=False, position_offset=None, arc_points=[]):
|
||||||
# > points - list of points formatted like ( (x0, y0), (x1, y1) )
|
# > points - list of points formatted like ( (x0, y0), (x1, y1) )
|
||||||
# < IfcIndexedPolyCurve
|
# < IfcIndexedPolyCurve
|
||||||
segments = []
|
|
||||||
|
|
||||||
|
if arc_points and self.file.schema == "IFC2X3":
|
||||||
|
raise Exception("Arcs are not supported for IFC2X3.")
|
||||||
|
|
||||||
|
segments = []
|
||||||
cur_i = 0
|
cur_i = 0
|
||||||
while cur_i < len(points) - 1:
|
while cur_i < len(points) - 1:
|
||||||
cur_i_ifc = cur_i + 1
|
cur_i_ifc = cur_i + 1
|
||||||
@@ -55,30 +58,34 @@ class ShapeBuilder:
|
|||||||
if position_offset:
|
if position_offset:
|
||||||
points = [Vector(p) + position_offset for p in points]
|
points = [Vector(p) + position_offset for p in points]
|
||||||
|
|
||||||
dimensions = len(points[0])
|
if self.file.schema == "IFC2X3":
|
||||||
if dimensions == 2:
|
points = [self.file.createIfcCartesianPoint(p) for p in points]
|
||||||
ifc_points = self.file.createIfcCartesianPointList2D(points)
|
ifc_curve = self.file.createIfcPolyline(Points=points)
|
||||||
elif dimensions == 3:
|
else:
|
||||||
ifc_points = self.file.createIfcCartesianPointList3D(points)
|
dimensions = len(points[0])
|
||||||
|
if dimensions == 2:
|
||||||
|
ifc_points = self.file.createIfcCartesianPointList2D(points)
|
||||||
|
elif dimensions == 3:
|
||||||
|
ifc_points = self.file.createIfcCartesianPointList3D(points)
|
||||||
|
|
||||||
ifc_segments = []
|
ifc_segments = []
|
||||||
# because IfcLineIndex support 2+ points
|
# because IfcLineIndex support 2+ points
|
||||||
# we merge neighbor line segments into one
|
# we merge neighbor line segments into one
|
||||||
current_line_segment = []
|
current_line_segment = []
|
||||||
last_segment = len(segments) - 1
|
last_segment = len(segments) - 1
|
||||||
for seg_i, segment in enumerate(segments):
|
for seg_i, segment in enumerate(segments):
|
||||||
if len(segment) == 2:
|
if len(segment) == 2:
|
||||||
current_line_segment += segment
|
current_line_segment += segment
|
||||||
|
|
||||||
if current_line_segment and (len(segment) == 3 or seg_i == last_segment):
|
if current_line_segment and (len(segment) == 3 or seg_i == last_segment):
|
||||||
ifc_segments.append(self.file.createIfcLineIndex(current_line_segment))
|
ifc_segments.append(self.file.createIfcLineIndex(current_line_segment))
|
||||||
current_line_segment = []
|
current_line_segment = []
|
||||||
|
|
||||||
if len(segment) == 3:
|
if len(segment) == 3:
|
||||||
ifc_segments.append(self.file.createIfcArcIndex(segment))
|
ifc_segments.append(self.file.createIfcArcIndex(segment))
|
||||||
|
|
||||||
# NOTE: IfcIndexPolyCurve support only consequtive segments
|
# NOTE: IfcIndexPolyCurve support only consequtive segments
|
||||||
ifc_curve = self.file.createIfcIndexedPolyCurve(Points=ifc_points, Segments=ifc_segments)
|
ifc_curve = self.file.createIfcIndexedPolyCurve(Points=ifc_points, Segments=ifc_segments)
|
||||||
return ifc_curve
|
return ifc_curve
|
||||||
|
|
||||||
def get_rectangle_coords(self, size: Vector = Vector((1.0, 1.0)).freeze(), position: Vector = None):
|
def get_rectangle_coords(self, size: Vector = Vector((1.0, 1.0)).freeze(), position: Vector = None):
|
||||||
@@ -251,9 +258,10 @@ class ShapeBuilder:
|
|||||||
if create_copy:
|
if create_copy:
|
||||||
c = ifcopenshell.util.element.copy_deep(self.file, c)
|
c = ifcopenshell.util.element.copy_deep(self.file, c)
|
||||||
|
|
||||||
if c.is_a("IfcIndexedPolyCurve"):
|
if c.is_a() in ("IfcIndexedPolyCurve", "IfcPolyline"):
|
||||||
coords = [Vector(co) + translation for co in c.Points.CoordList]
|
coords = self.get_polyline_coords(c)
|
||||||
c.Points.CoordList = coords
|
coords = [Vector(co) + translation for co in coords]
|
||||||
|
self.set_polyline_coords(c, coords)
|
||||||
|
|
||||||
elif c.is_a("IfcCircle") or c.is_a("IfcExtrudedAreaSolid") or c.is_a("IfcEllipse"):
|
elif c.is_a("IfcCircle") or c.is_a("IfcExtrudedAreaSolid") or c.is_a("IfcEllipse"):
|
||||||
base_position = Vector(c.Position.Location.Coordinates)
|
base_position = Vector(c.Position.Location.Coordinates)
|
||||||
@@ -312,11 +320,12 @@ class ShapeBuilder:
|
|||||||
if create_copy:
|
if create_copy:
|
||||||
c = ifcopenshell.util.element.copy_deep(self.file, c)
|
c = ifcopenshell.util.element.copy_deep(self.file, c)
|
||||||
|
|
||||||
if c.is_a("IfcIndexedPolyCurve"):
|
if c.is_a() in ("IfcIndexedPolyCurve", "IfcPolyline"):
|
||||||
|
original_coords = self.get_polyline_coords(c)
|
||||||
coords = [
|
coords = [
|
||||||
self.rotate_2d_point(Vector(co), angle, pivot_point, counter_clockwise) for co in c.Points.CoordList
|
self.rotate_2d_point(Vector(co), angle, pivot_point, counter_clockwise) for co in original_coords
|
||||||
]
|
]
|
||||||
c.Points.CoordList = coords
|
self.set_polyline_coords(c, coords)
|
||||||
|
|
||||||
elif c.is_a("IfcCircle"):
|
elif c.is_a("IfcCircle"):
|
||||||
base_position = Vector(c.Position.Location.Coordinates)
|
base_position = Vector(c.Position.Location.Coordinates)
|
||||||
@@ -408,10 +417,11 @@ class ShapeBuilder:
|
|||||||
else curve_or_item_el
|
else curve_or_item_el
|
||||||
)
|
)
|
||||||
|
|
||||||
if c.is_a("IfcIndexedPolyCurve"):
|
if c.is_a() in ("IfcIndexedPolyCurve", "IfcPolyline"):
|
||||||
|
original_coords = self.get_polyline_coords(c)
|
||||||
inverted_placement_matrix = placement_matrix.inverted() if placement_matrix else None
|
inverted_placement_matrix = placement_matrix.inverted() if placement_matrix else None
|
||||||
coords = []
|
coords = []
|
||||||
for co in c.Points.CoordList:
|
for co in original_coords:
|
||||||
co_base = Vector(co)
|
co_base = Vector(co)
|
||||||
if placement_matrix:
|
if placement_matrix:
|
||||||
# TODO: add support for Z-axis too
|
# TODO: add support for Z-axis too
|
||||||
@@ -424,7 +434,7 @@ class ShapeBuilder:
|
|||||||
|
|
||||||
coords.append(co)
|
coords.append(co)
|
||||||
|
|
||||||
c.Points.CoordList = coords
|
self.set_polyline_coords(c, coords)
|
||||||
|
|
||||||
elif c.is_a("IfcCircle") or c.is_a("IfcEllipse"):
|
elif c.is_a("IfcCircle") or c.is_a("IfcEllipse"):
|
||||||
base_position = Vector(c.Position.Location.Coordinates)
|
base_position = Vector(c.Position.Location.Coordinates)
|
||||||
@@ -594,3 +604,20 @@ class ShapeBuilder:
|
|||||||
kwargs["position_x_axis"].rotate(rot)
|
kwargs["position_x_axis"].rotate(rot)
|
||||||
kwargs["position_z_axis"].rotate(rot)
|
kwargs["position_z_axis"].rotate(rot)
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
def get_polyline_coords(self, polyline):
|
||||||
|
"""polyline should be either `IfcIndexedPolyCurve` or `IfcPolyline`"""
|
||||||
|
coords = None
|
||||||
|
if polyline.is_a("IfcIndexedPolyCurve"):
|
||||||
|
coords = polyline.Points.CoordList
|
||||||
|
elif polyline.is_a("IfcPolyline"):
|
||||||
|
coords = [p.Coordinates for p in polyline.Points]
|
||||||
|
return coords
|
||||||
|
|
||||||
|
def set_polyline_coords(self, polyline, coords):
|
||||||
|
"""polyline should be either `IfcIndexedPolyCurve` or `IfcPolyline`"""
|
||||||
|
if polyline.is_a("IfcIndexedPolyCurve"):
|
||||||
|
polyline.Points.CoordList = coords
|
||||||
|
elif polyline.is_a("IfcPolyline"):
|
||||||
|
for i, co in enumerate(coords):
|
||||||
|
polyline.Points[i].Coordinates = co
|
||||||
|
|||||||
Reference in New Issue
Block a user