From a44357dad503d141bfbf64762886137b2b1ab01f Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 25 Jan 2024 16:24:43 +0500 Subject: [PATCH] shape builder polyline example and tests --- .../ifcopenshell/util/shape_builder.py | 20 +++++++++- .../test/util/test_shape_builder.py | 39 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py b/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py index 82acdf8a88..3344956598 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py +++ b/src/ifcopenshell-python/ifcopenshell/util/shape_builder.py @@ -63,12 +63,28 @@ class ShapeBuilder: :param position_offset: offset to be applied to all points :param type: Vector, optional :param arc_points: Indices of the middle points for arcs. For creating an arc segment, - provide 3 points: `arc_start`, `arc_middle` and `arc_end` and add the `arc_middle` - point's index to this list + provide 3 points: `arc_start`, `arc_middle` and `arc_end` to `points` and add the `arc_middle` + point's index to `arc_points` :param type: List[int] :return: IfcIndexedPolyCurve :rtype: ifcopenshell.entity_instance + + Example: + + .. code:: python + + # rectangle + points = Vector((0, 0)), Vector((1, 0)), Vector((1, 1)), Vector((0, 1)) + position = Vector((2, 0)) + # #2=IfcIndexedPolyCurve(#1,(IfcLineIndex((1,2,3,4,1))),$) + polyline = builder.polyline(points, closed=True, position_offset=position) + + # arc between points (1,0) and (0,1). Second point in the arc should be it's middle + points = Vector((1, 0)), Vector((0.707, 0.707)), Vector((0, 1)), Vector((0,2)) + arc_points = (1,) # point with index 1 is a middle of the arc + # 4=IfcIndexedPolyCurve(#3,(IfcArcIndex((1,2,3)),IfcLineIndex((3,4,1))),$) + curved_polyline = builder.polyline(points, closed=False, position_offset=position, arc_points=arc_points) """ if arc_points and self.file.schema == "IFC2X3": diff --git a/src/ifcopenshell-python/test/util/test_shape_builder.py b/src/ifcopenshell-python/test/util/test_shape_builder.py index c3b1b29fc5..c472471c88 100644 --- a/src/ifcopenshell-python/test/util/test_shape_builder.py +++ b/src/ifcopenshell-python/test/util/test_shape_builder.py @@ -19,11 +19,50 @@ import pytest import test.bootstrap import ifcopenshell.api +import numpy as np from ifcopenshell.util.shape_builder import ShapeBuilder, V, is_x from math import degrees, radians, tan from mathutils import Vector +class TestCreatePolyline(test.bootstrap.IFC4): + def test_simple_polyline(self): + builder = ShapeBuilder(self.file) + + # rectangle + points = Vector((0, 0)), Vector((1, 0)), Vector((1, 1)), Vector((0, 1)) + position = Vector((2, 0)) + polyline = builder.polyline(points, closed=True, position_offset=position) + + points = [p + position for p in points] + assert np.allclose(np.array(points), np.array(polyline.Points.CoordList)) + # use 1 line index if there are no arcs + assert len(polyline.Segments) == 1 + segment = polyline.Segments[0] + assert segment.is_a("IfcLineIndex") + assert segment.wrappedValue == (1, 2, 3, 4, 1) + + def test_polyline_with_arc(self): + builder = ShapeBuilder(self.file) + + points = Vector((1, 0)), Vector((0.707, 0.707)), Vector((0, 1)), Vector((0, 2)) + position = Vector((2, 0)) + arc_points = (1,) + # 4=IfcIndexedPolyCurve(#3,(IfcArcIndex((1,2,3)),IfcLineIndex((3,4,1))),$) + polyline = builder.polyline(points, closed=False, position_offset=position, arc_points=arc_points) + points = [p + position for p in points] + assert np.allclose(np.array(points), np.array(polyline.Points.CoordList)) + assert len(polyline.Segments) == 2 + + segment = polyline.Segments[0] + assert segment.is_a("IfcArcIndex") + assert segment.wrappedValue == (1, 2, 3) + + segment = polyline.Segments[1] + assert segment.is_a("IfcLineIndex") + assert segment.wrappedValue == (3, 4) + + class TestCalculateTransitions(test.bootstrap.IFC4): def calculate_and_test(self, params, length): end_profile = params["end_profile"]