Licensing and black for BIMTester and IfcBlender. See #1082.

This commit is contained in:
Dion Moult
2022-01-19 11:07:43 +11:00
parent 07264dafb1
commit 5b281260f8
44 changed files with 966 additions and 322 deletions
+7
View File
@@ -0,0 +1,7 @@
.PHONY: license
license:
copyright-header --license LGPL3 --copyright-holder "Dion Moult <dion@thinkmoult.com>" --copyright-year "2021" --copyright-software "BIMTester" --copyright-software-description "OpenBIM Auditing Tool" -a ./ -o ./
.PHONY: qa
qa:
black .
+18
View File
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from os.path import dirname
from os.path import realpath
+18
View File
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import os
from pathlib import Path
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import os
from behave.model import Scenario
@@ -24,19 +42,14 @@ def before_all(context):
Scenario.continue_after_failed_step = continue_after_failed
# context.ifc_path = userdata.get("ifc", "")
context.ifcfile_basename = os.path.basename(
os.path.splitext(userdata["ifc"])[0]
)
context.ifcfile_basename = os.path.basename(os.path.splitext(userdata["ifc"])[0])
context.outpath = os.path.join(this_path, "..")
context.create_log = False
context.create_smartview = False
if context.create_log is True:
# set up log file
context.thelogfile = os.path.join(
context.outpath,
context.ifcfile_basename + ".log"
)
context.thelogfile = os.path.join(context.outpath, context.ifcfile_basename + ".log")
create_logfile(
context.thelogfile,
context.ifcfile_basename,
@@ -61,10 +74,7 @@ def before_feature(context, feature):
# TODO: refactor zoom smart view support into a decoupled module
if context.create_smartview is True:
smartview_name = context.ifcfile_basename + "_" + feature.name
context.smview_file = os.path.join(
context.outpath,
smartview_name + ".bcsv"
)
context.smview_file = os.path.join(context.outpath, smartview_name + ".bcsv")
# print("SmartView file: {}".format(context.smview_file))
create_zoom_set_of_smartviews(
context.smview_file,
@@ -77,14 +87,6 @@ def after_step(context, step):
if step.status == "failed" and context.create_log is True:
append_logfile(context, step)
if (
step.status == "failed"
and context.create_smartview is True
and hasattr(context, "falseguids")
):
if step.status == "failed" and context.create_smartview is True and hasattr(context, "falseguids"):
# print(context.falseguids)
add_smartview(
context.smview_file,
step.name,
context.falseguids
)
add_smartview(context.smview_file, step.name, context.falseguids)
+20 -6
View File
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import json
@@ -20,11 +38,7 @@ def append_logfile(thecontext, step):
logfile = open(thecontext.thelogfile, "a")
logfile.write("\n\nStep '{}' failed\n".format(step.name))
if hasattr(thecontext, "falseelems"):
logfile.write("{}\n".format(
json.dumps(thecontext.falseelems, indent=4)
))
logfile.write("{}\n".format(json.dumps(thecontext.falseelems, indent=4)))
if hasattr(thecontext, "falseprops"):
logfile.write("{}\n".format(
json.dumps(thecontext.falseprops, indent=4)
))
logfile.write("{}\n".format(json.dumps(thecontext.falseprops, indent=4)))
logfile.close()
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step, given, when, then, use_step_matcher
from bimtester import util
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
use_step_matcher("parse")
from bimtester.features.steps.aggregation import en
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
from bimtester.ifc import IfcStore
@@ -8,10 +26,9 @@ from bimtester.lang import _
def step_impl(context, fullname):
real_fullname = IfcStore.file.by_type("IfcApplication")[0].ApplicationFullName
assert real_fullname == fullname , (
assert real_fullname == fullname, (
"The IFC file was not exported by application full name {} "
"instead it was exported by application full name {}"
.format(fullname, real_fullname)
"instead it was exported by application full name {}".format(fullname, real_fullname)
)
@@ -19,10 +36,10 @@ def step_impl(context, fullname):
def step_impl(context, identifier):
real_identifier = IfcStore.file.by_type("IfcApplication")[0].ApplicationIdentifier
assert real_identifier == identifier , (
"The IFC file was not exported by application identifier {} "
"instead it was exported by identifier {}"
.format(identifier, real_identifier)
assert (
real_identifier == identifier
), "The IFC file was not exported by application identifier {} " "instead it was exported by identifier {}".format(
identifier, real_identifier
)
@@ -30,18 +47,21 @@ def step_impl(context, identifier):
def step_impl(context, version):
real_version = IfcStore.file.by_type("IfcApplication")[0].Version
assert real_version == version , (
"The IFC file was not exported by application version {} "
"instead it was exported by version {}"
.format(version, real_version)
assert (
real_version == version
), "The IFC file was not exported by application version {} " "instead it was exported by version {}".format(
version, real_version
)
@step('IFC data header must have a file description of "{header_file_description}" such as the new Allplan IFC exporter creates it')
@step(
'IFC data header must have a file description of "{header_file_description}" such as the new Allplan IFC exporter creates it'
)
def step_impl(context, header_file_description):
is_header_file_description = IfcStore.file.wrapped_data.header.file_description.description
assert str(is_header_file_description) == header_file_description , (
"The file was not exported by the new ifc exporter in Allplan. File description header: {}"
.format(is_header_file_description)
assert (
str(is_header_file_description) == header_file_description
), "The file was not exported by the new ifc exporter in Allplan. File description header: {}".format(
is_header_file_description
)
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.util.element as eleutils
from behave import step
@@ -9,50 +27,32 @@ from bimtester.lang import _
@step('There are exclusively "{ifc_classes}" elements only')
def step_impl(context, ifc_classes):
only_eleclasses(
context,
ifc_classes
)
only_eleclasses(context, ifc_classes)
@step('There are no "{ifc_class}" elements')
def step_impl(context, ifc_class):
no_eleclass(
context,
ifc_class
)
no_eleclass(context, ifc_class)
@step('There are no "{ifc_class}" elements because "{reason}"')
def step_impl(context, ifc_class, reason):
no_eleclass(
context,
ifc_class
)
no_eleclass(context, ifc_class)
@step('All "{ifc_class}" elements class attributes have a value')
def step_impl(context, ifc_class):
eleclass_have_class_attributes_with_a_value(
context,
ifc_class
)
eleclass_have_class_attributes_with_a_value(context, ifc_class)
@step('All "{ifc_class}" elements have a name given')
def step_impl(context, ifc_class):
eleclass_has_name_with_a_value(
context,
ifc_class
)
eleclass_has_name_with_a_value(context, ifc_class)
@step('All "{ifc_class}" elements have a description given')
def step_impl(context, ifc_class):
eleclass_has_description_with_a_value(
context,
ifc_class
)
eleclass_has_description_with_a_value(context, ifc_class)
@step('All "{ifc_class}" elements have a name matching the pattern "{pattern}"')
@@ -76,15 +76,13 @@ def step_impl(context, ifc_class, attribute_name, attribute_value):
# ************************************************************************************************
# helper
def only_eleclasses(
context, ifc_classes
):
def only_eleclasses(context, ifc_classes):
context.falseelems = []
context.falseguids = []
# get the list of ifc_classes
target_ifc_classes = ifc_classes.replace(" ","").split(",")
target_ifc_classes = ifc_classes.replace(" ", "").split(",")
# ToDo test if they exist in ifc standard, should be possible with ifcos
all_elements = IfcStore.file.by_type("IfcBuildingElement")
@@ -105,13 +103,13 @@ def only_eleclasses(
context.falsecount,
context.falseelems,
message_all_falseelems=_("All {elemcount} elements in the file are not {ifc_class} elements."),
message_some_falseelems=_("{falsecount} of {elemcount} false_elements are not {ifc_class} elements: {falseelems}"),
message_some_falseelems=_(
"{falsecount} of {elemcount} false_elements are not {ifc_class} elements: {falseelems}"
),
)
def no_eleclass(
context, ifc_class
):
def no_eleclass(context, ifc_class):
context.falseelems = []
context.falseguids = []
@@ -134,11 +132,10 @@ def no_eleclass(
)
def eleclass_have_class_attributes_with_a_value(
context, ifc_class
):
def eleclass_have_class_attributes_with_a_value(context, ifc_class):
from ifcopenshell.ifcopenshell_wrapper import schema_by_name
# schema = schema_by_name("IFC2X3")
schema = schema_by_name(IfcStore.file.schema)
class_attributes = []
@@ -172,10 +169,14 @@ def eleclass_have_class_attributes_with_a_value(
context.elemcount,
context.falsecount,
context.falseelems,
message_all_falseelems=_("For all {elemcount} {ifc_class} elements at least one of these class attributes {parameter} has no value."),
message_some_falseelems=_("For the following {falsecount} out of {elemcount} {ifc_class} elements at least one of these class attributes {parameter} has no value: {falseelems}"),
message_all_falseelems=_(
"For all {elemcount} {ifc_class} elements at least one of these class attributes {parameter} has no value."
),
message_some_falseelems=_(
"For the following {falsecount} out of {elemcount} {ifc_class} elements at least one of these class attributes {parameter} has no value: {falseelems}"
),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
parameter=failed_attribs
parameter=failed_attribs,
)
@@ -190,7 +191,7 @@ def eleclass_has_name_with_a_value(context, ifc_class):
if not elem.Name:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
util.assert_elements(
@@ -199,14 +200,14 @@ def eleclass_has_name_with_a_value(context, ifc_class):
context.falsecount,
context.falseelems,
message_all_falseelems=_("The name of all {elemcount} elements is not set."),
message_some_falseelems=_("The name of {falsecount} out of {elemcount} {ifc_class} elements is not set: {falseelems}"),
message_some_falseelems=_(
"The name of {falsecount} out of {elemcount} {ifc_class} elements is not set: {falseelems}"
),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
)
def eleclass_has_description_with_a_value(
context, ifc_class
):
def eleclass_has_description_with_a_value(context, ifc_class):
context.falseelems = []
context.falseguids = []
@@ -217,7 +218,7 @@ def eleclass_has_description_with_a_value(
if not elem.Description:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
util.assert_elements(
@@ -226,8 +227,8 @@ def eleclass_has_description_with_a_value(
context.falsecount,
context.falseelems,
message_all_falseelems=_("The description of all {elemcount} elements is not set."),
message_some_falseelems=_("The description of {falsecount} out of {elemcount} {ifc_class} elements is not set: {falseelems}"),
message_some_falseelems=_(
"The description of {falsecount} out of {elemcount} {ifc_class} elements is not set: {falseelems}"
),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
)
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
from behave import use_step_matcher
@@ -8,12 +26,7 @@ from bimtester.lang import _
@step('All "{ifc_class}" elements have an "{aproperty}" property in the "{pset}" pset')
def step_impl(context, ifc_class, aproperty, pset):
eleclass_has_property_in_pset(
context,
ifc_class,
aproperty,
pset
)
eleclass_has_property_in_pset(context, ifc_class, aproperty, pset)
# ------------------------------------------------------------------------
@@ -25,16 +38,13 @@ use_step_matcher("re")
@step(r"All (?P<ifc_class>.*) elements have an? (?P<property_path>.*\..*) property")
def step_impl(context, ifc_class, property_path):
import re
pset, aproperty = property_path.split(".")
eleclass_has_property_in_pset(
context,
ifc_class,
aproperty,
pset
)
eleclass_has_property_in_pset(context, ifc_class, aproperty, pset)
@step(r'All (?P<ifc_class>.*) elements have an? (?P<property_path>.*\..*) property value matching the pattern "(?P<pattern>.*)"'
@step(
r'All (?P<ifc_class>.*) elements have an? (?P<property_path>.*\..*) property value matching the pattern "(?P<pattern>.*)"'
)
def step_impl(context, ifc_class, property_path, pattern):
import re
@@ -46,13 +56,13 @@ def step_impl(context, ifc_class, property_path, pattern):
psets = get_psets(element)
if not pset_name in psets:
if not pset_name in psets:
assert False
pset = psets[pset_name]
if not property_name in pset:
assert False
prop = pset[property_name]
# get_psets returns just strings
@@ -60,9 +70,7 @@ def step_impl(context, ifc_class, property_path, pattern):
assert False
def eleclass_has_property_in_pset(
context, ifc_class, aproperty, pset
):
def eleclass_has_property_in_pset(context, ifc_class, aproperty, pset):
context.falseelems = []
context.falseguids = []
context.falseprops = {}
@@ -84,9 +92,13 @@ def eleclass_has_property_in_pset(
context.falsecount,
context.falseelems,
# TODO: Translate these messages into other languages
message_all_falseelems=_("All {elemcount} {ifc_class} elements are missing the property {parameter} in the pset."),
message_some_falseelems=_("The following {falsecount} of {elemcount} {ifc_class} elements are missing the property {parameter} in the pset: {falseelems}"),
message_all_falseelems=_(
"All {elemcount} {ifc_class} elements are missing the property {parameter} in the pset."
),
message_some_falseelems=_(
"The following {falsecount} of {elemcount} {ifc_class} elements are missing the property {parameter} in the pset: {falseelems}"
),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
parameter=aproperty
parameter=aproperty,
)
# the pset name is missing in the failing message, but it is in the step test name
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
# from bimtester import util
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import json
from behave import step
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
from bimtester import util
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step, use_step_matcher
from bimtester import util
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import math
import numpy as np
import ifcopenshell
@@ -244,6 +262,6 @@ def step_impl(context, guid):
util.assert_type(site, "IfcSite")
if not site.ObjectPlacement:
assert False, _("The site has no object placement")
site_placement = ifcopenshell.util.placement.get_local_placement(site.ObjectPlacement)[:,3][0:3]
site_placement = ifcopenshell.util.placement.get_local_placement(site.ObjectPlacement)[:, 3][0:3]
origin = np.array([0, 0, 0])
assert np.allclose(origin, site_placement), _('The site location is at "{}" instead of "{}"')
@@ -1,6 +1,26 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
@step('Alle "{ifc_class}" Bauteile müssen eine geometrische Repräsentation der Klasse "{representation_class}" verwenden')
@step(
'Alle "{ifc_class}" Bauteile müssen eine geometrische Repräsentation der Klasse "{representation_class}" verwenden'
)
def step_impl(context, ifc_class, representation_class):
context.execute_steps(f'* All {ifc_class} elements have an "{representation_class}" representation')
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
from bimtester import util
@@ -32,21 +50,12 @@ def step_impl(context, number):
@step('All "{ifc_class}" elements have an "{representation_class}" representation')
def step_impl(context, ifc_class, representation_class):
eleclass_has_geometric_representation_of_specific_class(
context,
ifc_class,
representation_class
)
eleclass_has_geometric_representation_of_specific_class(context, ifc_class, representation_class)
# ************************************************************************************************
# helper
def eleclass_has_geometric_representation_of_specific_class(
context,
ifc_class,
representation_class
):
def eleclass_has_geometric_representation_of_specific_class(context, ifc_class, representation_class):
def is_item_a_representation(item, representation):
if "/" in representation:
for cls in representation.split("/"):
@@ -90,7 +99,9 @@ def eleclass_has_geometric_representation_of_specific_class(
context.falsecount,
context.falseelems,
message_all_falseelems=_("All {elemcount} {ifc_class} elements are not a {parameter} representation."),
message_some_falseelems=_("The following {falsecount} of {elemcount} {ifc_class} elements are not a {parameter} representation: {falseelems}"),
message_some_falseelems=_(
"The following {falsecount} of {elemcount} {ifc_class} elements are not a {parameter} representation: {falseelems}"
),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
parameter=representation_class
parameter=representation_class,
)
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.util.geolocation
import ifcopenshell.util.placement
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
from bimtester import util
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
@@ -1,10 +1,28 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
from bimtester.ifc import IfcStore
from bimtester.lang import _
@step('All buildings have an address')
@step("All buildings have an address")
def step_impl(context):
for building in IfcStore.file.by_type("IfcBuilding"):
if not building.BuildingAddress:
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import fileinput
import uuid
@@ -38,20 +56,12 @@ def add_smartview(sm_file, smartview_name, guids):
# build the smartview string
smview_string = " <SMARTVIEW>\n"
smview_string += (
" <TITLE>GUID filter, {}</TITLE>\n"
.format(smartview_name)
)
smview_string += " <TITLE>GUID filter, {}</TITLE>\n".format(smartview_name)
smview_string += "{}\n".format(each_smartview_string_before1)
smview_string += str(uuid.uuid4()) # create and add a smart view guid
smview_string += "{}\n".format(each_smartview_string_before2)
for guid in guids:
smview_string += (
"{}{}{}\n".format(
rule_string_before,
guid,
rule_string_after)
)
smview_string += "{}{}{}\n".format(rule_string_before, guid, rule_string_after)
smview_string += "{}\n".format(each_smartview_string_after)
# insert smartview string into file
+26 -29
View File
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import os
import json
import sys
@@ -47,9 +65,7 @@ class GuiWidgetBimTester(QtWidgets.QWidget):
def _setup_ui(self):
package_path = os.path.dirname(os.path.realpath(__file__))
iconpath = os.path.join(
package_path, "resources", "icons", "bimtester.ico"
)
iconpath = os.path.join(package_path, "resources", "icons", "bimtester.ico")
"""
# as svg
@@ -87,14 +103,8 @@ class GuiWidgetBimTester(QtWidgets.QWidget):
_ifcfile_browse_btn.clicked.connect(self.select_ifcfile)
# buttons
self.run_button = QtWidgets.QPushButton(
QtGui.QIcon.fromTheme("document-new"),
"Run"
)
self.close_button = QtWidgets.QPushButton(
QtGui.QIcon.fromTheme("window-close"),
"Close"
)
self.run_button = QtWidgets.QPushButton(QtGui.QIcon.fromTheme("document-new"), "Run")
self.close_button = QtWidgets.QPushButton(QtGui.QIcon.fromTheme("window-close"), "Close")
self.run_button.clicked.connect(self.run_bimtester)
self.close_button.clicked.connect(self.close_widget)
_buttons = QtWidgets.QHBoxLayout()
@@ -121,9 +131,7 @@ class GuiWidgetBimTester(QtWidgets.QWidget):
self.setLayout(layout)
def select_ifcfile(self):
ifcfile = QtWidgets.QFileDialog.getOpenFileName(
self, dir=self.get_ifcfile()
)[0]
ifcfile = QtWidgets.QFileDialog.getOpenFileName(self, dir=self.get_ifcfile())[0]
self.set_ifcfile(ifcfile)
def set_ifcfile(self, a_file):
@@ -135,9 +143,7 @@ class GuiWidgetBimTester(QtWidgets.QWidget):
return " ".join(self.ifcfile_text.text().split())
def select_featurefile(self):
featurefile = QtWidgets.QFileDialog.getOpenFileName(
self, dir=self.get_ifcfile()
)[0]
featurefile = QtWidgets.QFileDialog.getOpenFileName(self, dir=self.get_ifcfile())[0]
self.set_featurefile(featurefile)
def set_featurefile(self, a_file):
@@ -176,24 +182,15 @@ class GuiWidgetBimTester(QtWidgets.QWidget):
if has_feature_file is True and has_ifc_file is True:
print("Args passed from BIMtester GUI:")
print(json.dumps(self.args, indent=4))
report_json = bimtester.run.TestRunner(
self.args["ifc"],
self.args["schema_file"]
).run(self.args)
report_json = bimtester.run.TestRunner(self.args["ifc"], self.args["schema_file"]).run(self.args)
else:
print("Missing files, BIMTester can not run.")
report_json = ""
# create html report
if os.path.isfile(report_json):
report_html = os.path.join(
os.path.dirname(os.path.realpath(report_json)),
"report.html"
)
bimtester.reports.ReportGenerator().generate(
report_json,
report_html
)
report_html = os.path.join(os.path.dirname(os.path.realpath(report_json)), "report.html")
bimtester.reports.ReportGenerator().generate(report_json, report_html)
print("HTML report generated: {}".format(report_html))
elif report_json == "":
report_html = ""
+19
View File
@@ -1,3 +1,22 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
class IfcStore:
path = ""
file = None
+21 -6
View File
@@ -1,7 +1,26 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import gettext
translation = None
def _(message):
if translation:
return translation(message)
@@ -14,15 +33,11 @@ def switch_locale(locale_dir, locale_id):
# https://docs.python.org/3/library/gettext.html
mo_file = gettext.find(domain, localedir=locale_dir, languages=[locale_id])
if mo_file is not None:
print(
"Locale will be switched to language '{}'. Translation file found {}"
.format(locale_id, mo_file)
)
print("Locale will be switched to language '{}'. Translation file found {}".format(locale_id, mo_file))
newlang = gettext.translation(domain, localedir=locale_dir, languages=[locale_id])
newlang.install()
translation = newlang.gettext
else:
print(
"Locale can not be switched to '{}'. Translation file (*.mo) not found in {}"
.format(locale_id, locale_dir)
"Locale can not be switched to '{}'. Translation file (*.mo) not found in {}".format(locale_id, locale_dir)
)
+19
View File
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import datetime
import json
import os
@@ -55,6 +73,7 @@ class ReportGenerator:
# get language and switch locale
the_lang = self.get_feature_lang(feature.get("keyword", None))
from bimtester.lang import switch_locale
switch_locale(os.path.join(self.base_path, "locale"), the_lang)
data["_lang"] = the_lang
@@ -1,3 +1,22 @@
<!--
BIMTester - OpenBIM Auditing Tool
Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
This file is part of BIMTester.
BIMTester 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.
BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
-->
<!DOCTYPE html>
<html lang={{_lang}}>
<head>
+34 -18
View File
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
import json
@@ -19,6 +37,7 @@ from behave.__main__ import main as behave_main
# TODO: refactor when this isn't super experimental
from logging import StreamHandler
class IDSHandler(StreamHandler):
def __init__(self):
StreamHandler.__init__(self)
@@ -27,13 +46,8 @@ class IDSHandler(StreamHandler):
"status": "passed",
"location": "filename.xml",
"elements": [
{
"keyword": "Scenario",
"name": "Checking IDS specifications",
"status": "passed",
"steps": []
}
]
{"keyword": "Scenario", "name": "Checking IDS specifications", "status": "passed", "steps": []}
],
}
def emit(self, record):
@@ -43,17 +57,19 @@ class IDSHandler(StreamHandler):
if is_fail:
self.results["status"] = "failed"
self.results["elements"][0]["status"] = "failed"
self.results["elements"][0]["steps"].append({
"keyword": "*",
"match": {},
"name": msg,
"result": {
"duration": 0.0,
"error_message": "Assertion Failed",
"status": "failed" if is_fail else "passed"
},
"step_type": "given"
})
self.results["elements"][0]["steps"].append(
{
"keyword": "*",
"match": {},
"name": msg,
"result": {
"duration": 0.0,
"error_message": "Assertion Failed",
"status": "failed" if is_fail else "passed",
},
"step_type": "given",
}
)
class TestRunner:
+19 -1
View File
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from collections import defaultdict
@@ -16,4 +34,4 @@ class TableModel:
return len(self.rows)
def get_count_distinct_values(self):
return len(set(item for sublist in self.rows.values() for item in sublist))
return len(set(item for sublist in self.rows.values() for item in sublist))
+33 -30
View File
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.validate
@@ -95,7 +113,7 @@ def assert_elements(
message_all_falseelems,
message_some_falseelems,
message_no_elems="",
parameter=None
parameter=None,
):
out_falseelems = "\n"
for e in falseelems:
@@ -112,42 +130,27 @@ def assert_elements(
# )
# )
if falsecount == 0:
return # test ok for elemcount == 0 and elemcount > 0
return # test ok for elemcount == 0 and elemcount > 0
elif falsecount == elemcount:
if parameter is None:
assert False, (
message_all_falseelems.format(
elemcount=elemcount,
ifc_class=ifc_class
)
)
assert False, message_all_falseelems.format(elemcount=elemcount, ifc_class=ifc_class)
else:
assert False, (
message_all_falseelems.format(
elemcount=elemcount,
ifc_class=ifc_class,
parameter=parameter
)
)
assert False, message_all_falseelems.format(elemcount=elemcount, ifc_class=ifc_class, parameter=parameter)
elif falsecount > 0 and falsecount < elemcount:
if parameter is None:
assert False, (
message_some_falseelems.format(
falsecount=falsecount,
elemcount=elemcount,
ifc_class=ifc_class,
falseelems=out_falseelems,
)
assert False, message_some_falseelems.format(
falsecount=falsecount,
elemcount=elemcount,
ifc_class=ifc_class,
falseelems=out_falseelems,
)
else:
assert False, (
message_some_falseelems.format(
falsecount=falsecount,
elemcount=elemcount,
ifc_class=ifc_class,
falseelems=out_falseelems,
parameter=parameter
)
assert False, message_some_falseelems.format(
falsecount=falsecount,
elemcount=elemcount,
ifc_class=ifc_class,
falseelems=out_falseelems,
parameter=parameter,
)
else:
assert False, _("Error in falsecount calculation, something went wrong.")
+19
View File
@@ -1,5 +1,24 @@
#!/usr/bin/env python3
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
import os
import argparse
import bimtester.clean
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step, given, when, then, use_step_matcher
use_step_matcher("parse")
@@ -1,3 +1,21 @@
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from behave import step
from utils import IfcFile
+19
View File
@@ -1,5 +1,24 @@
#!/usr/bin/env python3
# BIMTester - OpenBIM Auditing Tool
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BIMTester.
#
# BIMTester 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.
#
# BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
from bimtester.guiwidget import run
+19
View File
@@ -1,3 +1,22 @@
<!--
BIMTester - OpenBIM Auditing Tool
Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
This file is part of BIMTester.
BIMTester 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.
BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
-->
<!doctype html>
<html class="no-js" lang="">
+20
View File
@@ -1,3 +1,23 @@
/*
* BIMTester - OpenBIM Auditing Tool
* Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
*
* This file is part of BIMTester.
*
* BIMTester 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.
*
* BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
*/
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@300;400&display=swap');
* {
+20
View File
@@ -1,3 +1,23 @@
/*
* BIMTester - OpenBIM Auditing Tool
* Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
*
* This file is part of BIMTester.
*
* BIMTester 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.
*
* BIMTester 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 BIMTester. If not, see <http://www.gnu.org/licenses/>.
*/
/* Hacky mockup */
let elements = document.getElementsByTagName('input');
for (let i=0; i<elements.length; i++) {
+7
View File
@@ -0,0 +1,7 @@
.PHONY: license
license:
copyright-header --license LGPL3 --copyright-holder "Thomas Krijnen <thomas@aecgeeks.com>" --copyright-year "2019" --copyright-software "IfcBlender" --copyright-software-description "Blender IFC Importer" -a ./ -o ./
.PHONY: qa
qa:
black .
+77 -100
View File
@@ -1,21 +1,20 @@
###############################################################################
# #
# This file is part of IfcOpenShell. #
# #
# IfcOpenShell is free software: you can redistribute it and/or modify #
# it under the terms of the Lesser GNU General Public License as published by #
# the Free Software Foundation, either version 3.0 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 #
# Lesser GNU General Public License for more details. #
# #
# You should have received a copy of the Lesser GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
# IfcBlender - Blender IFC Importer
# Copyright (C) 2019 Thomas Krijnen <thomas@aecgeeks.com>
#
# This file is part of IfcBlender.
#
# IfcBlender 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.
#
# IfcBlender 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 IfcBlender. If not, see <http://www.gnu.org/licenses/>.
# <pep8 compliant>
@@ -27,17 +26,17 @@
bl_info = {
"name": "IfcBlender",
"description": "Import files in the "
"Industry Foundation Classes (.ifc) file format",
"description": "Import files in the " "Industry Foundation Classes (.ifc) file format",
"author": "Thomas Krijnen, IfcOpenShell",
"blender": (2, 80, 0),
"location": "File > Import",
"tracker_url": "https://sourceforge.net/p/ifcopenshell/"
"_list/tickets?source=navbar",
"category": "Import-Export"}
"tracker_url": "https://sourceforge.net/p/ifcopenshell/" "_list/tickets?source=navbar",
"category": "Import-Export",
}
if "bpy" in locals():
import importlib
if "ifcopenshell" in locals():
importlib.reload(ifcopenshell)
@@ -56,18 +55,11 @@ import os
major, minor = bpy.app.version[0:2]
transpose_matrices = minor >= 62
bpy.types.Object.ifc_id = IntProperty(
name="IFC Entity ID",
description="The STEP entity instance name")
bpy.types.Object.ifc_guid = StringProperty(
name="IFC Entity GUID",
description="The IFC Globally Unique Identifier")
bpy.types.Object.ifc_name = StringProperty(
name="IFC Entity Name",
description="The optional name attribute")
bpy.types.Object.ifc_type = StringProperty(
name="IFC Entity Type",
description="The STEP Datatype keyword")
bpy.types.Object.ifc_id = IntProperty(name="IFC Entity ID", description="The STEP entity instance name")
bpy.types.Object.ifc_guid = StringProperty(name="IFC Entity GUID", description="The IFC Globally Unique Identifier")
bpy.types.Object.ifc_name = StringProperty(name="IFC Entity Name", description="The optional name attribute")
bpy.types.Object.ifc_type = StringProperty(name="IFC Entity Type", description="The STEP Datatype keyword")
def _get_parent(instance):
"""This is based on ifcopenshell.app.geom"""
@@ -88,10 +80,10 @@ def _get_parent(instance):
return decompositions[0].RelatingObject
def import_ifc(filename, use_names, process_relations, blender_booleans):
from . import ifcopenshell
from .ifcopenshell import geom as ifcopenshell_geom
print(f"Reading {bpy.path.basename(filename)}...")
settings = ifcopenshell_geom.settings()
settings.set(settings.DISABLE_OPENING_SUBTRACTIONS, blender_booleans)
@@ -111,9 +103,8 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
root_collection = bpy.data.collections.new(f"{bpy.path.basename(filename)}")
bpy.context.scene.collection.children.link(root_collection)
collections = {
0: root_collection
}
collections = {0: root_collection}
def get_collection(cid):
if cid == 0:
return root_collection
@@ -131,10 +122,10 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
ifc_parent_object = _get_parent(ifc_object)
parent_id = ifc_parent_object.id() if ifc_parent_object is not None else 0
parent_collection = get_collection(parent_id)
name = ifc_object.Name or f'{ifc_object.is_a()}[{cid}]'
name = ifc_object.Name or f"{ifc_object.is_a()}[{cid}]"
else:
parent_collection = get_collection(0)
name = f'unresolved_{cid}'
name = f"unresolved_{cid}"
collection = bpy.data.collections.new(name)
parent_collection.children.link(collection)
@@ -142,7 +133,7 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
return collection
if process_relations:
if process_relations:
rel_collection = bpy.data.collections.new("Relations")
collection.children.link(rel_collection)
@@ -160,14 +151,12 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
nm = ob.name if len(ob.name) and use_names else ob.guid
# MESH CREATION
# Depending on version, geometry.id will be either int or str
mesh_name = f'mesh-{ob.geometry.id}'
mesh_name = f"mesh-{ob.geometry.id}"
me = project_meshes.get(mesh_name)
if me is None:
verts = [[v[i], v[i + 1], v[i + 2]]
for i in range(0, len(v), 3)]
faces = [[f[i], f[i + 1], f[i + 2]]
for i in range(0, len(f), 3)]
verts = [[v[i], v[i + 1], v[i + 2]] for i in range(0, len(v), 3)]
faces = [[f[i], f[i + 1], f[i + 2]] for i in range(0, len(f), 3)]
me = bpy.data.meshes.new(mesh_name)
project_meshes[mesh_name] = me
@@ -182,8 +171,8 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
else:
mat = bpy.data.materials.new(mname)
for k, v in props.items():
if k == 'transparency':
mat.blend_method = 'HASHED'
if k == "transparency":
mat.blend_method = "HASHED"
mat.use_screen_refraction = True
mat.refraction_depth = 0.1
mat.use_nodes = True
@@ -199,10 +188,10 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
for mat in mats:
props = {}
if mat.has_diffuse:
alpha = 1.
alpha = 1.0
if mat.has_transparency and mat.transparency > 0:
alpha = 1. - mat.transparency
props['diffuse_color'] = mat.diffuse + (alpha,)
alpha = 1.0 - mat.transparency
props["diffuse_color"] = mat.diffuse + (alpha,)
# @todo
# if mat.has_specular:
# props['specular_color'] = mat.specular
@@ -210,17 +199,16 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
# props['specular_intensity'] = mat.specularity
add_material(mat.name, props)
faces = me.polygons if hasattr(me, 'polygons') else me.faces
faces = me.polygons if hasattr(me, "polygons") else me.faces
if len(faces) == len(matids):
for face, matid in zip(faces, matids):
face.material_index = matid + (1 if needs_default else 0)
# OBJECT CREATION
bob = bpy.data.objects.new(nm, me)
mat = mathutils.Matrix(([m[0], m[1], m[2], 0],
[m[3], m[4], m[5], 0],
[m[6], m[7], m[8], 0],
[m[9], m[10], m[11], 1]))
mat = mathutils.Matrix(
([m[0], m[1], m[2], 0], [m[3], m[4], m[5], 0], [m[6], m[7], m[8], 0], [m[9], m[10], m[11], 1])
)
if transpose_matrices:
mat.transpose()
@@ -232,24 +220,23 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
get_collection(ob.parent_id).objects.link(bob)
bpy.context.view_layer.objects.active = bob
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.normals_make_consistent()
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode="OBJECT")
bob.ifc_id, bob.ifc_guid, bob.ifc_name, bob.ifc_type = \
ob.id, ob.guid, ob.name, ob.type
bob.ifc_id, bob.ifc_guid, bob.ifc_name, bob.ifc_type = ob.id, ob.guid, ob.name, ob.type
if ob.type == 'IfcSpace' or ob.type == 'IfcOpeningElement':
if not (ob.type == 'IfcOpeningElement' and blender_booleans):
if ob.type == "IfcSpace" or ob.type == "IfcOpeningElement":
if not (ob.type == "IfcOpeningElement" and blender_booleans):
bob.hide_viewport = bob.hide_render = True
bob.display_type = 'WIRE'
bob.display_type = "WIRE"
id_to_object[ob.id].append(bob)
if ob.parent_id > 0:
id_to_parent[ob.id] = ob.parent_id
if blender_booleans and ob.type == 'IfcOpeningElement':
if blender_booleans and ob.type == "IfcOpeningElement":
openings.append(ob.id)
progress = iterator.progress() // 2
@@ -276,15 +263,12 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
bob = None
else:
m = parent_ob.transformation.matrix.data
nm = parent_ob.name if len(parent_ob.name) and use_names \
else parent_ob.guid
nm = parent_ob.name if len(parent_ob.name) and use_names else parent_ob.guid
bob = bpy.data.objects.new(nm, None)
mat = mathutils.Matrix((
[m[0], m[1], m[2], 0],
[m[3], m[4], m[5], 0],
[m[6], m[7], m[8], 0],
[m[9], m[10], m[11], 1]))
mat = mathutils.Matrix(
([m[0], m[1], m[2], 0], [m[3], m[4], m[5], 0], [m[6], m[7], m[8], 0], [m[9], m[10], m[11], 1])
)
if transpose_matrices:
mat.transpose()
id_to_matrix[parent_ob.id] = mat
@@ -292,8 +276,7 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
rel_collection.objects.link(bob)
bob.ifc_id = parent_ob.id
bob.ifc_name, bob.ifc_type, bob.ifc_guid = \
parent_ob.name, parent_ob.type, parent_ob.guid
bob.ifc_name, bob.ifc_type, bob.ifc_guid = parent_ob.name, parent_ob.type, parent_ob.guid
if parent_ob.parent_id > 0:
id_to_parent[parent_id] = parent_ob.parent_id
@@ -327,7 +310,7 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
mod.operation = "DIFFERENCE"
mod.object = opening_ob
if hasattr(iterator, 'getLog'):
if hasattr(iterator, "getLog"):
# @todo
txt = bpy.data.texts.new(f"{bpy.path.basename(filename)}.log")
txt.from_string(iterator.getLog())
@@ -340,39 +323,33 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
bl_label = "Import .ifc file"
filename_ext = ".ifc"
filter_glob: StringProperty(default="*.ifc", options={'HIDDEN'})
filter_glob: StringProperty(default="*.ifc", options={"HIDDEN"})
use_names: BoolProperty(name="Use entity names",
description="Use entity names rather than "
"GlobalIds for objects",
default=True)
process_relations: BoolProperty(name="Process relations",
description="Convert containment and "
"aggregation relations to parenting"
" (warning: may be slow on large files)",
default=False)
blender_booleans: BoolProperty(name="Use Blender booleans",
description="Use Blender boolean modifiers "
"for opening elements",
default=False)
use_names: BoolProperty(
name="Use entity names", description="Use entity names rather than " "GlobalIds for objects", default=True
)
process_relations: BoolProperty(
name="Process relations",
description="Convert containment and "
"aggregation relations to parenting"
" (warning: may be slow on large files)",
default=False,
)
blender_booleans: BoolProperty(
name="Use Blender booleans", description="Use Blender boolean modifiers " "for opening elements", default=False
)
def execute(self, context):
if not import_ifc(self.filepath, self.use_names,
self.process_relations, self.blender_booleans):
self.report({'ERROR'},
'Unable to parse .ifc file or no geometrical entities found'
)
return {'FINISHED'}
if not import_ifc(self.filepath, self.use_names, self.process_relations, self.blender_booleans):
self.report({"ERROR"}, "Unable to parse .ifc file or no geometrical entities found")
return {"FINISHED"}
def menu_func_import(self, context):
self.layout.operator(ImportIFC.bl_idname,
text="Industry Foundation Classes (.ifc)")
self.layout.operator(ImportIFC.bl_idname, text="Industry Foundation Classes (.ifc)")
classes = (
ImportIFC,
)
classes = (ImportIFC,)
def register():