65 lines
2.3 KiB
Python
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,
|
|
)
|