Files
2026-05-31 10:17:09 +07:00

65 lines
2.3 KiB
Python

# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2025 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
import numpy as np
import ifcopenshell
import ifcopenshell.api.geometry
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import ifcopenshell.util.shape_builder
def connect_wall(
file: ifcopenshell.file,
wall1: ifcopenshell.entity_instance,
wall2: ifcopenshell.entity_instance,
is_atpath: bool = False,
) -> Optional[ifcopenshell.entity_instance]:
matrix1i = np.linalg.inv(ifcopenshell.util.placement.get_local_placement(wall1.ObjectPlacement))
matrix2 = ifcopenshell.util.placement.get_local_placement(wall2.ObjectPlacement)
axis1 = ifcopenshell.util.representation.get_reference_line(wall1)
axis2 = ifcopenshell.util.representation.get_reference_line(wall2)
axis2[0] = (matrix1i @ matrix2 @ np.concatenate((axis2[0], (0, 1))))[:2]
axis2[1] = (matrix1i @ matrix2 @ np.concatenate((axis2[1], (0, 1))))[:2]
midx = (axis1[0][0] + axis1[1][0]) / 2
starty = axis2[0][1]
endy = axis2[1][1]
y = axis1[0][1]
if (x := ifcopenshell.util.shape_builder.intersect_x_axis_2d(*axis2, y=y)) is None:
return
wall1_end = "ATEND" if x > midx else "ATSTART"
if is_atpath:
wall2_end = "ATPATH"
elif abs(y - starty) < abs(y - endy):
wall2_end = "ATSTART"
else:
wall2_end = "ATEND"
return ifcopenshell.api.geometry.connect_path(
file,
relating_element=wall1,
related_element=wall2,
relating_connection=wall1_end,
related_connection=wall2_end,
)