From af01f6b6c7735817acadc8486bbeac90f4e596d5 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Tue, 29 Oct 2024 12:17:27 +0500 Subject: [PATCH] geometry.create_2p_wall - document --- .../api/geometry/create_2pt_wall.py | 106 +++++++++--------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/create_2pt_wall.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/create_2pt_wall.py index 039ecb4e99..3401b29c7a 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/create_2pt_wall.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/create_2pt_wall.py @@ -19,6 +19,7 @@ import numpy as np import ifcopenshell.api.geometry import ifcopenshell.util.unit +from typing import Any def create_2pt_wall( @@ -32,57 +33,58 @@ def create_2pt_wall( thickness: float, is_si: bool = True, ) -> ifcopenshell.entity_instance: - usecase = Usecase() - usecase.file = file - usecase.settings = { - "element": element, - "context": context, - "p1": p1, - "p2": p2, - "elevation": elevation, - "height": height, - "thickness": thickness, - "is_si": is_si, - } - return usecase.execute() + """ + Create a wall between two points (p1 and p2). + A shortcut for geometry.add_wall_representation. + + :param element: Wall IFC element. + :param context: IfcGeometricRepresentationContext for the representation. + only Model/Body/MODEL_VIEW type of representations are currently supported. + :param p1: The starting point (x, y) of the wall. + :param p2: The ending point (x, y) of the wall. + :param elevation: The base elevation (z-coordinate) for the wall. + :param height: The height of the wall. + :param thickness: The thickness of the wall. + :param is_si: If True, provided arguments units are treated as SI (meters). + If False, values are converted from project units to SI. + :return: IfcShapeRepresentation. + """ + si_conversion = ifcopenshell.util.unit.calculate_unit_scale(file) + + p1_ = np.array(p1).astype(float) + p2_ = np.array(p2).astype(float) + + length = float(np.linalg.norm(p2_ - p1_)) + + if not is_si: + length = convert_unit_to_si(length, si_conversion) + height = convert_unit_to_si(height, si_conversion) + thickness = convert_unit_to_si(thickness, si_conversion) + # No need to convert p2 as length is already calculated. + p1_ = convert_unit_to_si(p1_, si_conversion) + elevation = convert_unit_to_si(elevation, si_conversion) + + representation = ifcopenshell.api.geometry.add_wall_representation( + file, + context=context, + length=length, + height=height, + thickness=thickness, + ) + + v = p2_ - p1_ + v /= float(np.linalg.norm(v)) + matrix = np.array( + [ + [v[0], -v[1], 0, p1_[0]], + [v[1], v[0], 0, p1_[1]], + [0, 0, 1, elevation], + [0, 0, 0, 1], + ] + ) + ifcopenshell.api.geometry.edit_object_placement(file, product=element, matrix=matrix) + return representation -class Usecase: - def execute(self): - self.settings["unit_scale"] = ifcopenshell.util.unit.calculate_unit_scale(self.file) - - self.settings["p1"] = np.array(self.settings["p1"]).astype(float) - self.settings["p2"] = np.array(self.settings["p2"]).astype(float) - - length = float(np.linalg.norm(self.settings["p2"] - self.settings["p1"])) - - if not self.settings["is_si"]: - length = self.convert_unit_to_si(length) - self.settings["height"] = self.convert_unit_to_si(self.settings["height"]) - self.settings["thickness"] = self.convert_unit_to_si(self.settings["thickness"]) - self.settings["p1"][0] = self.convert_unit_to_si(self.settings["p1"][0]) - self.settings["p1"][1] = self.convert_unit_to_si(self.settings["p1"][1]) - self.settings["elevation"] = self.convert_unit_to_si(self.settings["elevation"]) - - representation = ifcopenshell.api.geometry.add_wall_representation( - self.file, - context=self.settings["context"], - length=length, - height=self.settings["height"], - thickness=self.settings["thickness"], - ) - v = self.settings["p2"] - self.settings["p1"] - v /= float(np.linalg.norm(v)) - matrix = np.array( - [ - [v[0], -v[1], 0, self.settings["p1"][0]], - [v[1], v[0], 0, self.settings["p1"][1]], - [0, 0, 1, self.settings["elevation"]], - [0, 0, 0, 1], - ] - ) - ifcopenshell.api.geometry.edit_object_placement(self.file, product=self.settings["element"], matrix=matrix) - return representation - - def convert_unit_to_si(self, co): - return co * self.settings["unit_scale"] +def convert_unit_to_si(co: Any, si_conversion: float) -> Any: + return co * si_conversion