mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 18:43:26 +00:00
Merge remote-tracking branch 'origin/v0.8.0' into datamodel-v1.0
This commit is contained in:
@@ -18,14 +18,15 @@
|
||||
|
||||
import numpy
|
||||
import pytest
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.unit
|
||||
import ifcopenshell.api.spatial
|
||||
import ifcopenshell.api.geometry
|
||||
|
||||
import ifcopenshell.api.aggregate
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.spatial
|
||||
import ifcopenshell.api.unit
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignObject(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.aggregate
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUnassignObject(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
from ifcopenshell.api.alignment._add_segment_to_layout import _add_segment_to_layout
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.util
|
||||
import ifcopenshell.util.unit
|
||||
import pytest
|
||||
import math
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.unit
|
||||
import ifcopenshell.util
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
|
||||
def test_create_as_offset_curve():
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
import math
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
import math
|
||||
|
||||
|
||||
def _test_horizontal() -> ifcopenshell.file:
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
from ifcopenshell.api.alignment._map_alignment_cant_segment import _map_alignment_cant_segment
|
||||
from ifcopenshell.api.alignment._map_alignment_cant_segment import (
|
||||
_map_alignment_cant_segment,
|
||||
)
|
||||
|
||||
|
||||
def _BlossCurve_100_0_300_1000_1_Meter(file):
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
# for horizontal alignment.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.unit
|
||||
from ifcopenshell.api.alignment._map_alignment_horizontal_segment import _map_alignment_horizontal_segment
|
||||
from ifcopenshell.api.alignment._map_alignment_horizontal_segment import (
|
||||
_map_alignment_horizontal_segment,
|
||||
)
|
||||
|
||||
|
||||
def _BlossCurve_100_0_300_1000_1_Meter(file):
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
# for vertical alignment.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
from ifcopenshell.api.alignment._map_alignment_vertical_segment import _map_alignment_vertical_segment
|
||||
from ifcopenshell.api.alignment._map_alignment_vertical_segment import (
|
||||
_map_alignment_vertical_segment,
|
||||
)
|
||||
|
||||
|
||||
def _CircularArc_100_0_10_0_0_0_0_5_1_Meter(file):
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
from pytest import fixture
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
+4
-2
@@ -16,10 +16,12 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
from ifcopenshell.api.alignment._update_curve_segment_transition_code import _update_curve_segment_transition_code
|
||||
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
from ifcopenshell.api.alignment._update_curve_segment_transition_code import (
|
||||
_update_curve_segment_transition_code,
|
||||
)
|
||||
|
||||
|
||||
def _test1():
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.unit
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.boundary
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestCopyBoundary(test.bootstrap.IFC4):
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2026 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/>.
|
||||
# This file was generated with the assistance of an AI coding tool.
|
||||
|
||||
import ifcopenshell.api.boundary
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditAttributes(test.bootstrap.IFC4):
|
||||
def setup_boundary(self):
|
||||
space = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcSpace")
|
||||
wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
boundary = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcRelSpaceBoundary")
|
||||
return boundary, space, wall
|
||||
|
||||
def test_sets_relating_space_and_building_element(self):
|
||||
boundary, space, wall = self.setup_boundary()
|
||||
ifcopenshell.api.boundary.edit_attributes(
|
||||
self.file, entity=boundary, relating_space=space, related_building_element=wall
|
||||
)
|
||||
assert boundary.RelatingSpace == space
|
||||
assert boundary.RelatedBuildingElement == wall
|
||||
|
||||
def test_defaults_enums_to_notdefined(self):
|
||||
boundary, space, wall = self.setup_boundary()
|
||||
ifcopenshell.api.boundary.edit_attributes(
|
||||
self.file, entity=boundary, relating_space=space, related_building_element=wall
|
||||
)
|
||||
assert boundary.PhysicalOrVirtualBoundary == "NOTDEFINED"
|
||||
assert boundary.InternalOrExternalBoundary == "NOTDEFINED"
|
||||
|
||||
def test_sets_physical_or_virtual(self):
|
||||
boundary, space, wall = self.setup_boundary()
|
||||
ifcopenshell.api.boundary.edit_attributes(
|
||||
self.file,
|
||||
entity=boundary,
|
||||
relating_space=space,
|
||||
related_building_element=wall,
|
||||
physical_or_virtual="PHYSICAL",
|
||||
)
|
||||
assert boundary.PhysicalOrVirtualBoundary == "PHYSICAL"
|
||||
|
||||
def test_sets_internal_or_external(self):
|
||||
boundary, space, wall = self.setup_boundary()
|
||||
ifcopenshell.api.boundary.edit_attributes(
|
||||
self.file,
|
||||
entity=boundary,
|
||||
relating_space=space,
|
||||
related_building_element=wall,
|
||||
internal_or_external="EXTERNAL",
|
||||
)
|
||||
assert boundary.InternalOrExternalBoundary == "EXTERNAL"
|
||||
|
||||
def test_sets_all_enum_variants(self):
|
||||
boundary, space, wall = self.setup_boundary()
|
||||
for value in ("PHYSICAL", "VIRTUAL", "NOTDEFINED"):
|
||||
ifcopenshell.api.boundary.edit_attributes(
|
||||
self.file,
|
||||
entity=boundary,
|
||||
relating_space=space,
|
||||
related_building_element=wall,
|
||||
physical_or_virtual=value,
|
||||
)
|
||||
assert boundary.PhysicalOrVirtualBoundary == value
|
||||
|
||||
for value in ("INTERNAL", "EXTERNAL", "EXTERNAL_EARTH", "EXTERNAL_WATER", "EXTERNAL_FIRE", "NOTDEFINED"):
|
||||
ifcopenshell.api.boundary.edit_attributes(
|
||||
self.file,
|
||||
entity=boundary,
|
||||
relating_space=space,
|
||||
related_building_element=wall,
|
||||
internal_or_external=value,
|
||||
)
|
||||
assert boundary.InternalOrExternalBoundary == value
|
||||
|
||||
|
||||
class TestEditAttributesIFC2X3(test.bootstrap.IFC2X3, TestEditAttributes):
|
||||
def test_sets_all_enum_variants(self):
|
||||
boundary, space, wall = self.setup_boundary()
|
||||
for value in ("PHYSICAL", "VIRTUAL", "NOTDEFINED"):
|
||||
ifcopenshell.api.boundary.edit_attributes(
|
||||
self.file,
|
||||
entity=boundary,
|
||||
relating_space=space,
|
||||
related_building_element=wall,
|
||||
physical_or_virtual=value,
|
||||
)
|
||||
assert boundary.PhysicalOrVirtualBoundary == value
|
||||
|
||||
# IFC2X3 only has INTERNAL, EXTERNAL, NOTDEFINED
|
||||
for value in ("INTERNAL", "EXTERNAL", "NOTDEFINED"):
|
||||
ifcopenshell.api.boundary.edit_attributes(
|
||||
self.file,
|
||||
entity=boundary,
|
||||
relating_space=space,
|
||||
related_building_element=wall,
|
||||
internal_or_external=value,
|
||||
)
|
||||
assert boundary.InternalOrExternalBoundary == value
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.boundary
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveBoundary(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.classification
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddClassification(test.bootstrap.IFC4):
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
|
||||
import ifcopenshell.api.classification
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.classification
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddReference(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.classification
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveClassification(test.bootstrap.IFC4):
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
|
||||
import ifcopenshell.api.classification
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.classification
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveReference(test.bootstrap.IFC4):
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.aggregate
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.cogo
|
||||
import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_add_survey_point():
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.aggregate
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.cogo
|
||||
import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_assign_survey_point():
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.cogo
|
||||
import math
|
||||
|
||||
|
||||
def test_bearing2dd():
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
|
||||
import ifcopenshell.api.aggregate
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.cogo
|
||||
import ifcopenshell.api.context
|
||||
|
||||
|
||||
def test_edit_survey_point():
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.constraint
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.constraint
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignConstraint(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.constraint
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.constraint
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUnassignConstraint(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.context
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddContext(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.context
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditContext(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveContext(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.cost
|
||||
import ifcopenshell.api.control
|
||||
import ifcopenshell.api.cost
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignControl(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.cost
|
||||
import ifcopenshell.api.control
|
||||
import ifcopenshell.api.cost
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUnassignControl(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.cost
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddCostItem(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.control
|
||||
import ifcopenshell.api.cost
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.control
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddCostItemQuantity(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.cost
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddCostSchedule(test.bootstrap.IFC4):
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 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/>.
|
||||
|
||||
import ifcopenshell.api.cost
|
||||
import ifcopenshell.api.unit
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditCostValue(test.bootstrap.IFC4):
|
||||
def test_editing_applied_value(self):
|
||||
schedule = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
||||
item = ifcopenshell.api.cost.add_cost_item(self.file, cost_schedule=schedule)
|
||||
value = ifcopenshell.api.cost.add_cost_value(self.file, parent=item)
|
||||
ifcopenshell.api.cost.edit_cost_value(self.file, cost_value=value, attributes={"AppliedValue": 42.0})
|
||||
assert value.AppliedValue.wrappedValue == 42.0
|
||||
|
||||
def test_editing_unit_basis_removes_old_deeply(self):
|
||||
schedule = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
||||
item = ifcopenshell.api.cost.add_cost_item(self.file, cost_schedule=schedule)
|
||||
value = ifcopenshell.api.cost.add_cost_value(self.file, parent=item)
|
||||
unit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT")
|
||||
ifcopenshell.api.cost.edit_cost_value(
|
||||
self.file,
|
||||
cost_value=value,
|
||||
attributes={"UnitBasis": {"ValueComponent": 1.0, "UnitComponent": unit}},
|
||||
)
|
||||
old_basis = value.UnitBasis
|
||||
assert old_basis is not None
|
||||
old_basis_id = old_basis.id()
|
||||
# Now change to a new unit basis — the old one should be deeply removed.
|
||||
ifcopenshell.api.cost.edit_cost_value(
|
||||
self.file,
|
||||
cost_value=value,
|
||||
attributes={"UnitBasis": {"ValueComponent": 2.0, "UnitComponent": unit}},
|
||||
)
|
||||
assert value.UnitBasis is not None
|
||||
assert value.UnitBasis.id() != old_basis_id
|
||||
|
||||
def test_clearing_unit_basis(self):
|
||||
schedule = ifcopenshell.api.cost.add_cost_schedule(self.file)
|
||||
item = ifcopenshell.api.cost.add_cost_item(self.file, cost_schedule=schedule)
|
||||
value = ifcopenshell.api.cost.add_cost_value(self.file, parent=item)
|
||||
unit = ifcopenshell.api.unit.add_si_unit(self.file, unit_type="LENGTHUNIT")
|
||||
ifcopenshell.api.cost.edit_cost_value(
|
||||
self.file,
|
||||
cost_value=value,
|
||||
attributes={"UnitBasis": {"ValueComponent": 1.0, "UnitComponent": unit}},
|
||||
)
|
||||
assert value.UnitBasis is not None
|
||||
ifcopenshell.api.cost.edit_cost_value(self.file, cost_value=value, attributes={"UnitBasis": None})
|
||||
assert value.UnitBasis is None
|
||||
|
||||
|
||||
class TestEditCostValueIFC4X3(test.bootstrap.IFC4X3, TestEditCostValue):
|
||||
pass
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.cost
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveCostItem(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.cost
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveCostSchedule(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.document
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddInformation(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.document
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddReference(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.document
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignDocument(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.document
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveInformation(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.document
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveReference(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.document
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUnassignDocument(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.drawing
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignProduct(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.drawing
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditTextLiteral(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.drawing
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUnassignProduct(test.bootstrap.IFC4):
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import numpy
|
||||
import test.bootstrap
|
||||
|
||||
import ifcopenshell.api.feature
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.unit
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.util.placement
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddFeature(test.bootstrap.IFC4X3):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.feature
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddFilling(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.feature
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveFeature(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.shape_builder
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddBoolean(test.bootstrap.IFC4):
|
||||
@@ -42,7 +42,7 @@ class TestAddBoolean(test.bootstrap.IFC4):
|
||||
assert boolean.FirstOperand == first
|
||||
assert boolean.SecondOperand == second
|
||||
assert boolean.Operator == "DIFFERENCE"
|
||||
assert set(rep.Items) == {boolean}
|
||||
assert set(rep.Items) == {boolean, second}
|
||||
|
||||
def test_adding_multiple_booleans_from_three_top_level_items(self):
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
@@ -58,13 +58,14 @@ class TestAddBoolean(test.bootstrap.IFC4):
|
||||
|
||||
booleans = ifcopenshell.api.geometry.add_boolean(self.file, first, [second1, second2])
|
||||
assert len(booleans) == 2
|
||||
assert len(rep.Items) == 1
|
||||
assert rep.Items[0].FirstOperand.is_a("IfcBooleanResult")
|
||||
assert rep.Items[0].SecondOperand == second2
|
||||
assert rep.Items[0].Operator == "DIFFERENCE"
|
||||
assert rep.Items[0].FirstOperand.FirstOperand == first
|
||||
assert rep.Items[0].FirstOperand.SecondOperand == second1
|
||||
assert rep.Items[0].FirstOperand.Operator == "DIFFERENCE"
|
||||
final_boolean = booleans[-1]
|
||||
assert final_boolean.FirstOperand.is_a("IfcBooleanResult")
|
||||
assert final_boolean.SecondOperand == second2
|
||||
assert final_boolean.Operator == "DIFFERENCE"
|
||||
assert final_boolean.FirstOperand.FirstOperand == first
|
||||
assert final_boolean.FirstOperand.SecondOperand == second1
|
||||
assert final_boolean.FirstOperand.Operator == "DIFFERENCE"
|
||||
assert set(rep.Items) == {final_boolean, second1, second2}
|
||||
|
||||
def test_adding_a_boolean_to_an_existing_operand_from_a_top_level_item(self):
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
@@ -78,14 +79,16 @@ class TestAddBoolean(test.bootstrap.IFC4):
|
||||
second2 = builder.block()
|
||||
rep = builder.get_representation(body, [first, second1])
|
||||
booleans = ifcopenshell.api.geometry.add_boolean(self.file, first, [second1])
|
||||
# second1 stays in Items, add second2 as well
|
||||
rep.Items = list(rep.Items) + [second2]
|
||||
booleans = ifcopenshell.api.geometry.add_boolean(self.file, first, [second2])
|
||||
assert len(booleans) == 1
|
||||
assert len(rep.Items) == 1
|
||||
assert rep.Items[0].FirstOperand.is_a("IfcBooleanResult")
|
||||
assert rep.Items[0].SecondOperand == second2
|
||||
assert rep.Items[0].FirstOperand.FirstOperand == first
|
||||
assert rep.Items[0].FirstOperand.SecondOperand == second1
|
||||
final_boolean = booleans[0]
|
||||
assert final_boolean.FirstOperand.is_a("IfcBooleanResult")
|
||||
assert final_boolean.SecondOperand == second2
|
||||
assert final_boolean.FirstOperand.FirstOperand == first
|
||||
assert final_boolean.FirstOperand.SecondOperand == second1
|
||||
assert set(rep.Items) == {final_boolean, second1, second2}
|
||||
|
||||
def test_adding_a_boolean_to_an_existing_operand_from_another_operand(self):
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
@@ -104,7 +107,7 @@ class TestAddBoolean(test.bootstrap.IFC4):
|
||||
booleans = ifcopenshell.api.geometry.add_boolean(self.file, first1, [second2])
|
||||
|
||||
assert len(booleans) == 1
|
||||
assert len(rep.Items) == 2
|
||||
assert len(rep.Items) == 4
|
||||
|
||||
assert self.file.get_total_inverses(first1) == 1
|
||||
result = next(iter(self.file.get_inverse(first1)))
|
||||
@@ -132,14 +135,15 @@ class TestAddBoolean(test.bootstrap.IFC4):
|
||||
rep = builder.get_representation(body, [first, second])
|
||||
ifcopenshell.api.geometry.add_boolean(self.file, first, [second])
|
||||
ifcopenshell.api.geometry.add_boolean(self.file, first, [second])
|
||||
assert len(rep.Items) == 1
|
||||
assert rep.Items[0].FirstOperand == first
|
||||
assert rep.Items[0].SecondOperand == second
|
||||
assert set(rep.Items) == {self.file.by_type("IfcBooleanResult")[0], second}
|
||||
boolean = self.file.by_type("IfcBooleanResult")[0]
|
||||
assert boolean.FirstOperand == first
|
||||
assert boolean.SecondOperand == second
|
||||
ifcopenshell.api.geometry.add_boolean(self.file, second, [second])
|
||||
ifcopenshell.api.geometry.add_boolean(self.file, second, [first])
|
||||
assert len(rep.Items) == 1
|
||||
assert rep.Items[0].FirstOperand == first
|
||||
assert rep.Items[0].SecondOperand == second
|
||||
assert set(rep.Items) == {boolean, second}
|
||||
assert boolean.FirstOperand == first
|
||||
assert boolean.SecondOperand == second
|
||||
assert len(self.file.by_type("IfcBooleanResult")) == 1
|
||||
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.unit
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.unit
|
||||
import test.bootstrap
|
||||
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.shape_builder
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddShapeAspect(test.bootstrap.IFC4):
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2026 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/>.
|
||||
# This file was generated with the assistance of an AI coding tool.
|
||||
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddTopologyRepresentation(test.bootstrap.IFC4):
|
||||
def setup_context(self):
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
model = ifcopenshell.api.context.add_context(self.file, context_type="Model")
|
||||
return ifcopenshell.api.context.add_context(
|
||||
self.file,
|
||||
context_type="Model",
|
||||
context_identifier="Reference",
|
||||
target_view="GRAPH_VIEW",
|
||||
parent=model,
|
||||
)
|
||||
|
||||
def test_creates_topology_representation(self):
|
||||
context = self.setup_context()
|
||||
face = self.file.create_entity("IfcFaceSurface")
|
||||
rep = ifcopenshell.api.geometry.add_topology_representation(self.file, context=context, item=face)
|
||||
assert rep.is_a("IfcTopologyRepresentation")
|
||||
assert rep.ContextOfItems == context
|
||||
assert face in rep.Items
|
||||
|
||||
def test_infers_face_representation_type(self):
|
||||
context = self.setup_context()
|
||||
face = self.file.create_entity("IfcFaceSurface")
|
||||
rep = ifcopenshell.api.geometry.add_topology_representation(self.file, context=context, item=face)
|
||||
assert rep.RepresentationType == "Face"
|
||||
|
||||
def test_infers_edge_representation_type(self):
|
||||
context = self.setup_context()
|
||||
edge = self.file.create_entity("IfcEdge")
|
||||
rep = ifcopenshell.api.geometry.add_topology_representation(self.file, context=context, item=edge)
|
||||
assert rep.RepresentationType == "Edge"
|
||||
|
||||
def test_defaults_representation_identifier_to_context_identifier(self):
|
||||
context = self.setup_context()
|
||||
face = self.file.create_entity("IfcFaceSurface")
|
||||
rep = ifcopenshell.api.geometry.add_topology_representation(self.file, context=context, item=face)
|
||||
assert rep.RepresentationIdentifier == context.ContextIdentifier
|
||||
|
||||
def test_custom_representation_identifier(self):
|
||||
context = self.setup_context()
|
||||
face = self.file.create_entity("IfcFaceSurface")
|
||||
rep = ifcopenshell.api.geometry.add_topology_representation(
|
||||
self.file, context=context, item=face, representation_identifier="Body"
|
||||
)
|
||||
assert rep.RepresentationIdentifier == "Body"
|
||||
|
||||
def test_custom_representation_type_overrides_inferred(self):
|
||||
context = self.setup_context()
|
||||
face = self.file.create_entity("IfcFaceSurface")
|
||||
rep = ifcopenshell.api.geometry.add_topology_representation(
|
||||
self.file, context=context, item=face, representation_type="Undefined"
|
||||
)
|
||||
assert rep.RepresentationType == "Undefined"
|
||||
|
||||
|
||||
class TestAddTopologyRepresentationIFC2X3(test.bootstrap.IFC2X3, TestAddTopologyRepresentation):
|
||||
pass
|
||||
@@ -16,12 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.material
|
||||
import ifcopenshell.api.type
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.material
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.type
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignRepresentation(test.bootstrap.IFC4):
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2026 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/>.
|
||||
|
||||
import json
|
||||
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.shape_builder
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestClipSolid(test.bootstrap.IFC4):
|
||||
def make_extrusion(self):
|
||||
builder = ifcopenshell.util.shape_builder.ShapeBuilder(self.file)
|
||||
rect = builder.rectangle(size=(1.0, 1.0))
|
||||
return builder.extrude(rect, magnitude=4.0)
|
||||
|
||||
def test_returns_boolean_clipping_result(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
)
|
||||
assert result.is_a("IfcBooleanClippingResult")
|
||||
assert result.Operator == "DIFFERENCE"
|
||||
|
||||
def test_first_operand_is_the_item(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
)
|
||||
assert result.FirstOperand == extrusion
|
||||
|
||||
def test_second_operand_is_half_space_solid(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
)
|
||||
assert result.SecondOperand.is_a("IfcHalfSpaceSolid")
|
||||
|
||||
def test_clip_plane_location_matches(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
)
|
||||
plane = result.SecondOperand.BaseSurface
|
||||
coords = plane.Position.Location.Coordinates
|
||||
assert list(coords) == [0.0, 0.0, 3.0]
|
||||
|
||||
def test_chaining_two_clips(self):
|
||||
extrusion = self.make_extrusion()
|
||||
first_clip = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
)
|
||||
second_clip = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=first_clip,
|
||||
location=[0.0, 0.0, 1.0],
|
||||
normal=[0.0, 0.0, -1.0],
|
||||
)
|
||||
assert second_clip.is_a("IfcBooleanClippingResult")
|
||||
assert second_clip.FirstOperand == first_clip
|
||||
assert first_clip.FirstOperand == extrusion
|
||||
|
||||
def test_angled_clip_plane(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.26],
|
||||
normal=[0.419, 0.0, 0.908],
|
||||
)
|
||||
assert result.is_a("IfcBooleanClippingResult")
|
||||
assert result.SecondOperand.is_a("IfcHalfSpaceSolid")
|
||||
|
||||
def test_element_registers_result_in_bbim_boolean(self):
|
||||
extrusion = self.make_extrusion()
|
||||
wall = self.file.createIfcWall()
|
||||
result = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
element=wall,
|
||||
)
|
||||
pset = ifcopenshell.util.element.get_pset(wall, "BBIM_Boolean")
|
||||
assert pset is not None
|
||||
assert result.id() in json.loads(pset["Data"])
|
||||
|
||||
def test_element_appends_to_existing_bbim_boolean(self):
|
||||
extrusion = self.make_extrusion()
|
||||
wall = self.file.createIfcWall()
|
||||
first = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
element=wall,
|
||||
)
|
||||
second = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=first,
|
||||
location=[0.0, 0.0, 1.0],
|
||||
normal=[0.0, 0.0, -1.0],
|
||||
element=wall,
|
||||
)
|
||||
pset = ifcopenshell.util.element.get_pset(wall, "BBIM_Boolean")
|
||||
ids = json.loads(pset["Data"])
|
||||
assert first.id() in ids
|
||||
assert second.id() in ids
|
||||
|
||||
def test_no_element_does_not_create_pset(self):
|
||||
extrusion = self.make_extrusion()
|
||||
wall = self.file.createIfcWall()
|
||||
ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
)
|
||||
assert ifcopenshell.util.element.get_pset(wall, "BBIM_Boolean") is None
|
||||
|
||||
|
||||
class TestClipSolidIFC2X3(test.bootstrap.IFC2X3, TestClipSolid):
|
||||
pass
|
||||
@@ -0,0 +1,179 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2026 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/>.
|
||||
|
||||
import json
|
||||
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.shape_builder
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestClipSolidBounded(test.bootstrap.IFC4):
|
||||
def make_extrusion(self):
|
||||
builder = ifcopenshell.util.shape_builder.ShapeBuilder(self.file)
|
||||
rect = builder.rectangle(size=(4.0, 1.0))
|
||||
return builder.extrude(rect, magnitude=3.0)
|
||||
|
||||
def test_returns_boolean_clipping_result(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
assert result.is_a("IfcBooleanClippingResult")
|
||||
assert result.Operator == "DIFFERENCE"
|
||||
|
||||
def test_first_operand_is_the_item(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
assert result.FirstOperand == extrusion
|
||||
|
||||
def test_second_operand_is_polygonal_bounded_half_space(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
assert result.SecondOperand.is_a("IfcPolygonalBoundedHalfSpace")
|
||||
|
||||
def test_agreement_flag_is_false(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
assert result.SecondOperand.AgreementFlag is False
|
||||
|
||||
def test_clip_plane_location_matches(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
plane = result.SecondOperand.BaseSurface
|
||||
coords = plane.Position.Location.Coordinates
|
||||
assert list(coords) == [2.5, 0.0, 2.0]
|
||||
|
||||
def test_boundary_is_closed_polyline(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
boundary = result.SecondOperand.PolygonalBoundary
|
||||
assert boundary.is_a("IfcPolyline")
|
||||
pts = [list(p.Coordinates) for p in boundary.Points]
|
||||
assert pts[0] == pts[-1], "polygon should be closed"
|
||||
assert len(pts) == 5 # 4 unique + closing repeat
|
||||
|
||||
def test_boundary_position_defaults_to_origin(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
pos = result.SecondOperand.Position
|
||||
assert list(pos.Location.Coordinates) == [0.0, 0.0, 0.0]
|
||||
|
||||
def test_custom_boundary_position(self):
|
||||
extrusion = self.make_extrusion()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
boundary_position=[1.0, 2.0, 3.0],
|
||||
)
|
||||
pos = result.SecondOperand.Position
|
||||
assert list(pos.Location.Coordinates) == [1.0, 2.0, 3.0]
|
||||
|
||||
def test_chaining_with_clip_solid(self):
|
||||
extrusion = self.make_extrusion()
|
||||
first_clip = ifcopenshell.api.geometry.clip_solid(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[0.0, 0.0, 3.0],
|
||||
normal=[0.0, 0.0, 1.0],
|
||||
)
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=first_clip,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
assert result.is_a("IfcBooleanClippingResult")
|
||||
assert result.FirstOperand == first_clip
|
||||
assert first_clip.FirstOperand == extrusion
|
||||
|
||||
def test_element_registers_result_in_bbim_boolean(self):
|
||||
extrusion = self.make_extrusion()
|
||||
wall = self.file.createIfcWall()
|
||||
result = ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
element=wall,
|
||||
)
|
||||
pset = ifcopenshell.util.element.get_pset(wall, "BBIM_Boolean")
|
||||
assert pset is not None
|
||||
assert result.id() in json.loads(pset["Data"])
|
||||
|
||||
def test_no_element_does_not_create_pset(self):
|
||||
extrusion = self.make_extrusion()
|
||||
wall = self.file.createIfcWall()
|
||||
ifcopenshell.api.geometry.clip_solid_bounded(
|
||||
self.file,
|
||||
item=extrusion,
|
||||
location=[2.5, 0.0, 2.0],
|
||||
normal=[0.6, 0.0, 0.8],
|
||||
boundary_points=[[2.0, 0.0], [3.0, 0.0], [3.0, 2.0], [2.0, 2.0]],
|
||||
)
|
||||
assert ifcopenshell.util.element.get_pset(wall, "BBIM_Boolean") is None
|
||||
|
||||
|
||||
class TestClipSolidBoundedIFC2X3(test.bootstrap.IFC2X3, TestClipSolidBounded):
|
||||
pass
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestConnectElement(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestConnectPath(test.bootstrap.IFC4):
|
||||
@@ -33,6 +33,18 @@ class TestConnectPath(test.bootstrap.IFC4):
|
||||
assert rel.RelatedConnectionType == "ATEND"
|
||||
assert rel.Description == "MITRE"
|
||||
|
||||
def test_storing_connection_geometry(self):
|
||||
wall1 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
geometry = self.file.create_entity("IfcConnectionPointGeometry")
|
||||
rel = ifcopenshell.api.geometry.connect_path(
|
||||
self.file,
|
||||
relating_element=wall1,
|
||||
related_element=wall2,
|
||||
connection_geometry=geometry,
|
||||
)
|
||||
assert rel.ConnectionGeometry == geometry
|
||||
|
||||
def test_doing_nothing_if_the_element_is_already_connected(self):
|
||||
wall1 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2026 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/>.
|
||||
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.representation
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestCopyRepresentation(test.bootstrap.IFC4):
|
||||
def _body_context(self):
|
||||
body = ifcopenshell.util.representation.get_context(self.file, "Model", "Body", "MODEL_VIEW")
|
||||
if body is None:
|
||||
model = self.file.createIfcGeometricRepresentationContext(
|
||||
ContextType="Model",
|
||||
CoordinateSpaceDimension=3,
|
||||
Precision=1e-5,
|
||||
WorldCoordinateSystem=self.file.createIfcAxis2Placement3D(
|
||||
self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
||||
),
|
||||
)
|
||||
body = self.file.createIfcGeometricRepresentationSubContext(
|
||||
ContextIdentifier="Body",
|
||||
ContextType="Model",
|
||||
TargetView="MODEL_VIEW",
|
||||
ParentContext=model,
|
||||
)
|
||||
return body
|
||||
|
||||
def _add_body_rep(self, element):
|
||||
body = self._body_context()
|
||||
rep = ifcopenshell.api.geometry.add_wall_representation(
|
||||
self.file, context=body, length=5.0, height=3.0, thickness=0.2
|
||||
)
|
||||
ifcopenshell.api.geometry.assign_representation(self.file, product=element, representation=rep)
|
||||
return rep
|
||||
|
||||
def test_copy_to_empty_target(self):
|
||||
wall_a = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall_b = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
self._add_body_rep(wall_a)
|
||||
|
||||
result = ifcopenshell.api.geometry.copy_representation(self.file, source=wall_a, target=wall_b)
|
||||
|
||||
assert result is not None
|
||||
assert result.is_a("IfcShapeRepresentation")
|
||||
target_rep = ifcopenshell.util.representation.get_representation(wall_b, "Model", "Body")
|
||||
assert target_rep is not None
|
||||
assert target_rep == result
|
||||
|
||||
def test_source_rep_entities_are_distinct(self):
|
||||
wall_a = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall_b = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
source_rep = self._add_body_rep(wall_a)
|
||||
|
||||
new_rep = ifcopenshell.api.geometry.copy_representation(self.file, source=wall_a, target=wall_b)
|
||||
|
||||
assert new_rep.id() != source_rep.id()
|
||||
assert new_rep.Items[0].id() != source_rep.Items[0].id()
|
||||
|
||||
def test_context_is_shared_not_copied(self):
|
||||
wall_a = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall_b = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
source_rep = self._add_body_rep(wall_a)
|
||||
|
||||
new_rep = ifcopenshell.api.geometry.copy_representation(self.file, source=wall_a, target=wall_b)
|
||||
|
||||
assert new_rep.ContextOfItems.id() == source_rep.ContextOfItems.id()
|
||||
|
||||
def test_replaces_existing_target_rep(self):
|
||||
wall_a = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall_b = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
self._add_body_rep(wall_a)
|
||||
old_rep = self._add_body_rep(wall_b)
|
||||
old_rep_id = old_rep.id()
|
||||
|
||||
ifcopenshell.api.geometry.copy_representation(self.file, source=wall_a, target=wall_b)
|
||||
|
||||
try:
|
||||
self.file.by_id(old_rep_id)
|
||||
assert False, "old representation still exists"
|
||||
except RuntimeError:
|
||||
pass # entity was removed, as expected
|
||||
|
||||
def test_source_unchanged_after_copy(self):
|
||||
wall_a = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall_b = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
source_rep = self._add_body_rep(wall_a)
|
||||
source_rep_id = source_rep.id()
|
||||
|
||||
ifcopenshell.api.geometry.copy_representation(self.file, source=wall_a, target=wall_b)
|
||||
|
||||
assert self.file.by_id(source_rep_id) is not None # source must still exist
|
||||
assert ifcopenshell.util.representation.get_representation(wall_a, "Model", "Body") is not None
|
||||
|
||||
def test_returns_none_when_no_matching_rep(self):
|
||||
wall_a = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall_b = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
|
||||
result = ifcopenshell.api.geometry.copy_representation(self.file, source=wall_a, target=wall_b)
|
||||
|
||||
assert result is None
|
||||
|
||||
def test_custom_context_identifier(self):
|
||||
wall_a = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
wall_b = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
|
||||
self._add_body_rep(wall_a)
|
||||
|
||||
# "Axis" doesn't exist on wall_a, so should return None
|
||||
result = ifcopenshell.api.geometry.copy_representation(
|
||||
self.file, source=wall_a, target=wall_b, context_identifier="Axis"
|
||||
)
|
||||
|
||||
assert result is None
|
||||
|
||||
|
||||
class TestCopyRepresentationIFC2X3(test.bootstrap.IFC2X3, TestCopyRepresentation):
|
||||
pass
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestDisconnectElement(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestDisconnectPath(test.bootstrap.IFC4):
|
||||
|
||||
@@ -18,16 +18,17 @@
|
||||
|
||||
import numpy
|
||||
import pytest
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.feature
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.unit
|
||||
import ifcopenshell.api.system
|
||||
import ifcopenshell.api.spatial
|
||||
import ifcopenshell.api.geometry
|
||||
|
||||
import ifcopenshell.api.aggregate
|
||||
import ifcopenshell.api.feature
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.spatial
|
||||
import ifcopenshell.api.system
|
||||
import ifcopenshell.api.unit
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.placement
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditObjectPlacement(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.shape_builder
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveBoolean(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.geometry
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveRepresentation(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.util.placement
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUnassignRepresentation(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.shape_builder
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestValidateType(test.bootstrap.IFC4):
|
||||
@@ -76,7 +76,7 @@ class TestValidateType(test.bootstrap.IFC4):
|
||||
|
||||
booleans = ifcopenshell.api.geometry.add_boolean(self.file, first, [second1])
|
||||
assert len(booleans) == 1
|
||||
assert len(rep.Items) == 3
|
||||
assert len(rep.Items) == 4
|
||||
assert ifcopenshell.api.geometry.validate_type(self.file, rep) is True
|
||||
assert len(rep.Items) == 1
|
||||
assert rep.RepresentationType == "CSG"
|
||||
@@ -96,9 +96,9 @@ class TestValidateType(test.bootstrap.IFC4):
|
||||
|
||||
booleans = ifcopenshell.api.geometry.add_boolean(self.file, first, [second1])
|
||||
assert len(booleans) == 1
|
||||
assert len(rep.Items) == 2
|
||||
assert len(rep.Items) == 3 # boolean replaced first, but second1 stays in Items
|
||||
assert ifcopenshell.api.geometry.validate_type(self.file, rep) is False
|
||||
assert len(rep.Items) == 2
|
||||
assert len(rep.Items) == 2 # validate_type unioned second1 into the boolean
|
||||
assert rep.RepresentationType is None
|
||||
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.georeference
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddGeoreferencing(test.bootstrap.IFC4):
|
||||
@@ -51,6 +51,38 @@ class TestAddGeoreferencing(test.bootstrap.IFC4):
|
||||
assert len(self.file.by_type("IfcMapConversion")) == 1
|
||||
assert len(self.file.by_type("IfcProjectedCRS")) == 1
|
||||
|
||||
def test_recovering_from_orphan_projected_crs(self):
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
ifcopenshell.api.context.add_context(self.file, "Model")
|
||||
self.file.create_entity("IfcProjectedCRS", Name="EPSG:1234")
|
||||
assert len(self.file.by_type("IfcProjectedCRS")) == 1
|
||||
assert len(self.file.by_type("IfcCoordinateOperation")) == 0
|
||||
ifcopenshell.api.georeference.add_georeferencing(self.file)
|
||||
assert len(self.file.by_type("IfcMapConversion")) == 1
|
||||
assert len(self.file.by_type("IfcProjectedCRS")) == 1
|
||||
|
||||
def test_recovering_from_orphan_coordinate_operation(self):
|
||||
ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject")
|
||||
context = ifcopenshell.api.context.add_context(self.file, "Model")
|
||||
self.file.create_entity(
|
||||
"IfcMapConversion",
|
||||
SourceCRS=context,
|
||||
TargetCRS=self.file.create_entity("IfcProjectedCRS", Name="EPSG:1234"),
|
||||
)
|
||||
ifcopenshell.api.georeference.remove_georeferencing(self.file)
|
||||
# Simulate orphan by re-adding just a conversion without CRS
|
||||
self.file.create_entity(
|
||||
"IfcMapConversion",
|
||||
SourceCRS=context,
|
||||
TargetCRS=self.file.create_entity("IfcProjectedCRS", Name="EPSG:1234"),
|
||||
)
|
||||
self.file.remove(self.file.by_type("IfcProjectedCRS")[0])
|
||||
assert len(self.file.by_type("IfcProjectedCRS")) == 0
|
||||
assert len(self.file.by_type("IfcCoordinateOperation")) == 1
|
||||
ifcopenshell.api.georeference.add_georeferencing(self.file)
|
||||
assert len(self.file.by_type("IfcMapConversion")) == 1
|
||||
assert len(self.file.by_type("IfcProjectedCRS")) == 1
|
||||
|
||||
|
||||
class TestAddGeoreferencingIFC2X3(test.bootstrap.IFC2X3):
|
||||
def test_adding_georeferencing(self):
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.georeference
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditGeoreferencing(test.bootstrap.IFC4):
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import numpy as np
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.georeference
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.geolocation
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditTrueNorth(test.bootstrap.IFC4):
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import numpy as np
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.georeference
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.geolocation
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditWCS(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.context
|
||||
import ifcopenshell.api.georeference
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveGeoreferencing(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.grid
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestCreateGridAxis(test.bootstrap.IFC4):
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 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/>.
|
||||
|
||||
import ifcopenshell.api.grid
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveGridAxis(test.bootstrap.IFC4):
|
||||
def test_removing_an_axis_removes_its_curve(self):
|
||||
grid = self.file.createIfcGrid()
|
||||
axis = ifcopenshell.api.grid.create_grid_axis(
|
||||
self.file, axis_tag="A", same_sense=True, uvw_axes="UAxes", grid=grid
|
||||
)
|
||||
axis.AxisCurve = self.file.createIfcPolyline([self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))])
|
||||
axis2 = ifcopenshell.api.grid.create_grid_axis(
|
||||
self.file, axis_tag="B", same_sense=True, uvw_axes="UAxes", grid=grid
|
||||
)
|
||||
axis2.AxisCurve = self.file.createIfcPolyline([self.file.createIfcCartesianPoint((1.0, 0.0, 0.0))])
|
||||
ifcopenshell.api.grid.remove_grid_axis(self.file, axis=axis2)
|
||||
assert grid.UAxes == (axis,)
|
||||
assert len(self.file.by_type("IfcGridAxis")) == 1
|
||||
# The curve should be removed since it was only used by the removed axis.
|
||||
assert len(self.file.by_type("IfcPolyline")) == 1
|
||||
|
||||
def test_removing_an_axis_preserves_shared_curve(self):
|
||||
grid = self.file.createIfcGrid()
|
||||
shared_curve = self.file.createIfcPolyline([self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))])
|
||||
axis = ifcopenshell.api.grid.create_grid_axis(
|
||||
self.file, axis_tag="A", same_sense=True, uvw_axes="UAxes", grid=grid
|
||||
)
|
||||
axis.AxisCurve = shared_curve
|
||||
axis2 = ifcopenshell.api.grid.create_grid_axis(
|
||||
self.file, axis_tag="B", same_sense=True, uvw_axes="UAxes", grid=grid
|
||||
)
|
||||
axis2.AxisCurve = shared_curve
|
||||
ifcopenshell.api.grid.remove_grid_axis(self.file, axis=axis2)
|
||||
assert grid.UAxes == (axis,)
|
||||
# The shared curve should be preserved since it's still used by axis.
|
||||
assert shared_curve in self.file
|
||||
assert axis.AxisCurve == shared_curve
|
||||
|
||||
|
||||
class TestRemoveGridAxisIFC2X3(test.bootstrap.IFC2X3, TestRemoveGridAxis):
|
||||
pass
|
||||
@@ -16,9 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.group
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddGroup(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.group
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignGroup(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.group
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.group
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveGroup(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.group
|
||||
import ifcopenshell.api.root
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignGroup(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.api.group
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUpdateGroupProductsIFC2X3(test.bootstrap.IFC2X3):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.layer
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddLayer(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.layer
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddLayerWithStyle(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.layer
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignLayer(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.layer
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUnassignLayer(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.library
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddLibrary(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.library
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAddReference(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.library
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestAssignReference(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import datetime
|
||||
|
||||
import ifcopenshell.api.library
|
||||
import ifcopenshell.util.date
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditLibrary(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.library
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestEditReference(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.library
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveLibrary(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.library
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestRemoveReference(test.bootstrap.IFC4):
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api.library
|
||||
import ifcopenshell.util.element
|
||||
import test.bootstrap
|
||||
|
||||
|
||||
class TestUnassignReference(test.bootstrap.IFC4):
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user