mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 17:20:04 +00:00
Merge branch 'v0.6.0' of github.com:IfcOpenShell/IfcOpenShell into v0.6.0
This commit is contained in:
+12
-5
@@ -79,7 +79,7 @@ ch.setLevel(logging.INFO)
|
|||||||
logger.addHandler(ch)
|
logger.addHandler(ch)
|
||||||
|
|
||||||
PROJECT_NAME="IfcOpenShell"
|
PROJECT_NAME="IfcOpenShell"
|
||||||
PYTHON_VERSIONS=["2.7.16", "3.2.6", "3.3.6", "3.4.6", "3.5.3", "3.6.2", "3.7.3", "3.8.2"]
|
PYTHON_VERSIONS=["2.7.16", "3.2.6", "3.3.6", "3.4.6", "3.5.3", "3.6.2", "3.7.3", "3.8.6", "3.9.1"]
|
||||||
JSON_VERSION="v3.6.1"
|
JSON_VERSION="v3.6.1"
|
||||||
OCE_VERSION="0.18"
|
OCE_VERSION="0.18"
|
||||||
# OCCT_VERSION="7.1.0"
|
# OCCT_VERSION="7.1.0"
|
||||||
@@ -87,7 +87,7 @@ OCE_VERSION="0.18"
|
|||||||
# OCCT_VERSION="7.2.0"
|
# OCCT_VERSION="7.2.0"
|
||||||
# OCCT_HASH="88af392"
|
# OCCT_HASH="88af392"
|
||||||
OCCT_VERSION="7.3.0p3"
|
OCCT_VERSION="7.3.0p3"
|
||||||
BOOST_VERSION="1.59.0"
|
BOOST_VERSION="1.71.0"
|
||||||
#PCRE_VERSION="8.39"
|
#PCRE_VERSION="8.39"
|
||||||
PCRE_VERSION="8.41"
|
PCRE_VERSION="8.41"
|
||||||
#LIBXML2_VERSION="2.9.3"
|
#LIBXML2_VERSION="2.9.3"
|
||||||
@@ -157,6 +157,13 @@ TOOLSET = None
|
|||||||
if get_os() == "Darwin":
|
if get_os() == "Darwin":
|
||||||
# C++11 features used in OCCT 7+ need a more recent stdlib
|
# C++11 features used in OCCT 7+ need a more recent stdlib
|
||||||
TOOLSET = "10.9" if USE_OCCT else "10.6"
|
TOOLSET = "10.9" if USE_OCCT else "10.6"
|
||||||
|
|
||||||
|
# python 3.4 doesn't seem to build anymore on recent versions of clang
|
||||||
|
if get_os() == "Darwin":
|
||||||
|
try:
|
||||||
|
PYTHON_VERSIONS.remove("3.4.6")
|
||||||
|
except ValueError as e:
|
||||||
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
IFCOS_NUM_BUILD_PROCS = os.environ["IFCOS_NUM_BUILD_PROCS"]
|
IFCOS_NUM_BUILD_PROCS = os.environ["IFCOS_NUM_BUILD_PROCS"]
|
||||||
@@ -303,7 +310,7 @@ def run(cmds, cwd=None):
|
|||||||
BOOST_VERSION_UNDERSCORE=BOOST_VERSION.replace(".", "_")
|
BOOST_VERSION_UNDERSCORE=BOOST_VERSION.replace(".", "_")
|
||||||
|
|
||||||
OCE_LOCATION="https://github.com/tpaviot/oce/archive/OCE-%s.tar.gz" % (OCE_VERSION,)
|
OCE_LOCATION="https://github.com/tpaviot/oce/archive/OCE-%s.tar.gz" % (OCE_VERSION,)
|
||||||
BOOST_LOCATION="http://downloads.sourceforge.net/project/boost/boost/%s/boost_%s.tar.bz2" % (BOOST_VERSION, BOOST_VERSION_UNDERSCORE)
|
BOOST_LOCATION="https://dl.bintray.com/boostorg/release/%s/source/" % (BOOST_VERSION,)
|
||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
|
|
||||||
@@ -580,7 +587,7 @@ if "OpenCOLLADA" in targets:
|
|||||||
download_url="https://github.com/KhronosGroup/OpenCOLLADA.git",
|
download_url="https://github.com/KhronosGroup/OpenCOLLADA.git",
|
||||||
download_name="OpenCOLLADA",
|
download_name="OpenCOLLADA",
|
||||||
download_tool=download_tool_git,
|
download_tool=download_tool_git,
|
||||||
patch="./patches/opencollada/pr622.patch",
|
patch="./patches/opencollada/pr622_and_disable_subdirs.patch",
|
||||||
revision=OPENCOLLADA_VERSION
|
revision=OPENCOLLADA_VERSION
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -644,7 +651,7 @@ if "boost" in targets:
|
|||||||
list(map(str_concat("cxxflags"), CXXFLAGS.strip().split(' '))) + \
|
list(map(str_concat("cxxflags"), CXXFLAGS.strip().split(' '))) + \
|
||||||
list(map(str_concat("linkflags"), LDFLAGS.strip().split(' '))) + \
|
list(map(str_concat("linkflags"), LDFLAGS.strip().split(' '))) + \
|
||||||
["stage", "-s", "NO_BZIP2=1"],
|
["stage", "-s", "NO_BZIP2=1"],
|
||||||
download_url="http://downloads.sourceforge.net/project/boost/boost/{BOOST_VERSION}/".format(**locals()),
|
download_url=BOOST_LOCATION,
|
||||||
download_name="boost_{BOOST_VERSION_UNDERSCORE}.tar.bz2".format(**locals())
|
download_name="boost_{BOOST_VERSION_UNDERSCORE}.tar.bz2".format(**locals())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
index 95abbe21..293c951c 100644
|
||||||
|
--- a/CMakeLists.txt
|
||||||
|
+++ b/CMakeLists.txt
|
||||||
|
@@ -284,10 +284,10 @@ add_subdirectory(COLLADASaxFrameworkLoader)
|
||||||
|
add_subdirectory(COLLADAStreamWriter)
|
||||||
|
|
||||||
|
# building COLLADAValidator app
|
||||||
|
-add_subdirectory(COLLADAValidator)
|
||||||
|
+# add_subdirectory(COLLADAValidator)
|
||||||
|
|
||||||
|
# DAE validator app
|
||||||
|
-add_subdirectory(DAEValidator)
|
||||||
|
+# add_subdirectory(DAEValidator)
|
||||||
|
|
||||||
|
# Library export
|
||||||
|
install(EXPORT LibraryExport DESTINATION ${OPENCOLLADA_INST_CMAKECONFIG} FILE OpenCOLLADATargets.cmake)
|
||||||
|
diff --git a/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp b/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
|
||||||
|
index 1f9a3eef..dd6f5c59 100644
|
||||||
|
--- a/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
|
||||||
|
+++ b/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
|
||||||
|
#include "GeneratedSaxParserUtils.h"
|
||||||
|
#include <math.h>
|
||||||
|
+#include <cmath>
|
||||||
|
#include <memory>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits>
|
||||||
@@ -345,7 +345,7 @@ class BcfXml:
|
|||||||
|
|
||||||
def write_viewpoint(self, viewpoint, topic):
|
def write_viewpoint(self, viewpoint, topic):
|
||||||
document = minidom.Document()
|
document = minidom.Document()
|
||||||
root = self._create_element(document, "VisualizationInfo", { "Guid": viewpoint.guid })
|
root = self._create_element(document, "VisualizationInfo", {"Guid": viewpoint.guid})
|
||||||
self.write_viewpoint_components(viewpoint, root)
|
self.write_viewpoint_components(viewpoint, root)
|
||||||
self.write_viewpoint_orthogonal_camera(viewpoint, root)
|
self.write_viewpoint_orthogonal_camera(viewpoint, root)
|
||||||
self.write_viewpoint_perspective_camera(viewpoint, root)
|
self.write_viewpoint_perspective_camera(viewpoint, root)
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import os
|
|||||||
import bpy
|
import bpy
|
||||||
import bcf
|
import bcf
|
||||||
from . import bcfstore
|
from . import bcfstore
|
||||||
|
from math import radians, degrees, atan, tan, cos, sin
|
||||||
|
from mathutils import Vector, Matrix, Euler, geometry
|
||||||
|
|
||||||
class NewBcfProject(bpy.types.Operator):
|
class NewBcfProject(bpy.types.Operator):
|
||||||
bl_idname = "bim.new_bcf_project"
|
bl_idname = "bim.new_bcf_project"
|
||||||
|
|||||||
@@ -18,32 +18,37 @@ bcfviewpoints_enum = None
|
|||||||
|
|
||||||
|
|
||||||
def updateBcfReferenceLink(self, context):
|
def updateBcfReferenceLink(self, context):
|
||||||
bpy.ops.bim.edit_bcf_reference_links()
|
if bpy.context.scene.BCFProperties.is_loaded:
|
||||||
|
bpy.ops.bim.edit_bcf_reference_links()
|
||||||
|
|
||||||
|
|
||||||
def updateBcfLabel(self, context):
|
def updateBcfLabel(self, context):
|
||||||
bpy.ops.bim.edit_bcf_labels()
|
if bpy.context.scene.BCFProperties.is_loaded:
|
||||||
|
bpy.ops.bim.edit_bcf_labels()
|
||||||
|
|
||||||
|
|
||||||
def updateBcfProjectName(self, context):
|
def updateBcfProjectName(self, context):
|
||||||
bpy.ops.bim.edit_bcf_project_name()
|
if bpy.context.scene.BCFProperties.is_loaded:
|
||||||
|
bpy.ops.bim.edit_bcf_project_name()
|
||||||
|
|
||||||
|
|
||||||
def updateBcfAuthor(self, context):
|
def updateBcfAuthor(self, context):
|
||||||
bpy.ops.bim.edit_bcf_author()
|
if bpy.context.scene.BCFProperties.is_loaded:
|
||||||
|
bpy.ops.bim.edit_bcf_author()
|
||||||
|
|
||||||
|
|
||||||
def updateBcfTopicName(self, context):
|
def updateBcfTopicName(self, context):
|
||||||
bpy.ops.bim.edit_bcf_topic_name()
|
if bpy.context.scene.BCFProperties.is_loaded:
|
||||||
|
bpy.ops.bim.edit_bcf_topic_name()
|
||||||
|
|
||||||
|
|
||||||
def updateBcfTopicIsEditable(self, context):
|
def updateBcfTopicIsEditable(self, context):
|
||||||
if not self.is_editable:
|
if bpy.context.scene.BCFProperties.is_loaded and not self.is_editable:
|
||||||
bpy.ops.bim.edit_bcf_topic()
|
bpy.ops.bim.edit_bcf_topic()
|
||||||
|
|
||||||
|
|
||||||
def updateBcfCommentIsEditable(self, context):
|
def updateBcfCommentIsEditable(self, context):
|
||||||
if not self.is_editable:
|
if bpy.context.scene.BCFProperties.is_loaded and not self.is_editable:
|
||||||
bpy.ops.bim.edit_bcf_comment(comment_guid = self.name)
|
bpy.ops.bim.edit_bcf_comment(comment_guid = self.name)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1568,11 +1568,12 @@ class SelectSmartGroupedClashesPath(bpy.types.Operator):
|
|||||||
class ExecuteIfcClash(bpy.types.Operator):
|
class ExecuteIfcClash(bpy.types.Operator):
|
||||||
bl_idname = "bim.execute_ifc_clash"
|
bl_idname = "bim.execute_ifc_clash"
|
||||||
bl_label = "Execute IFC Clash"
|
bl_label = "Execute IFC Clash"
|
||||||
filename_ext = ".json"
|
filename_ext = ".bcf"
|
||||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".json")
|
if ".json" not in bpy.data.filepath:
|
||||||
|
self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".bcf")
|
||||||
WindowManager = context.window_manager
|
WindowManager = context.window_manager
|
||||||
WindowManager.fileselect_add(self)
|
WindowManager.fileselect_add(self)
|
||||||
return {"RUNNING_MODAL"}
|
return {"RUNNING_MODAL"}
|
||||||
@@ -1581,7 +1582,8 @@ class ExecuteIfcClash(bpy.types.Operator):
|
|||||||
import ifcclash
|
import ifcclash
|
||||||
|
|
||||||
settings = ifcclash.IfcClashSettings()
|
settings = ifcclash.IfcClashSettings()
|
||||||
self.filepath = bpy.path.ensure_ext(self.filepath, ".json")
|
if ".json" not in self.filepath:
|
||||||
|
self.filepath = bpy.path.ensure_ext(self.filepath, ".bcf")
|
||||||
settings.output = self.filepath
|
settings.output = self.filepath
|
||||||
settings.logger = logging.getLogger("Clash")
|
settings.logger = logging.getLogger("Clash")
|
||||||
settings.logger.setLevel(logging.DEBUG)
|
settings.logger.setLevel(logging.DEBUG)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import sys
|
|||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class Mesh:
|
class Mesh:
|
||||||
faces: []
|
faces: []
|
||||||
vertices: []
|
vertices: []
|
||||||
@@ -153,6 +154,64 @@ class IfcClasher:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def export(self):
|
def export(self):
|
||||||
|
if len(self.settings.output) > 4 and self.settings.output[-4:] == ".bcf":
|
||||||
|
return self.export_bcfxml()
|
||||||
|
self.export_json()
|
||||||
|
|
||||||
|
def export_bcfxml(self):
|
||||||
|
import bcf
|
||||||
|
import bcf.bcfxml
|
||||||
|
|
||||||
|
for i, clash_set in enumerate(self.clash_sets):
|
||||||
|
bcfxml = bcf.bcfxml.BcfXml()
|
||||||
|
bcfxml.new_project()
|
||||||
|
bcfxml.project.name = clash_set["name"]
|
||||||
|
bcfxml.edit_project()
|
||||||
|
for key, clash in clash_set["clashes"].items():
|
||||||
|
topic = bcf.data.Topic()
|
||||||
|
topic.title = "{}/{} and {}/{}".format(
|
||||||
|
clash["a_ifc_class"], clash["a_name"], clash["b_ifc_class"], clash["b_name"]
|
||||||
|
)
|
||||||
|
topic = bcfxml.add_topic(topic)
|
||||||
|
viewpoint = bcf.data.Viewpoint()
|
||||||
|
viewpoint.perspective_camera = bcf.data.PerspectiveCamera()
|
||||||
|
position = np.array(clash["position"])
|
||||||
|
point = position + np.array((5, 5, 5)) # Dumb, but works!
|
||||||
|
viewpoint.perspective_camera.camera_view_point.x = point[0]
|
||||||
|
viewpoint.perspective_camera.camera_view_point.y = point[1]
|
||||||
|
viewpoint.perspective_camera.camera_view_point.z = point[2]
|
||||||
|
mat = self.get_track_to_matrix(point, position)
|
||||||
|
viewpoint.perspective_camera.camera_direction.x = mat[0][2] * -1
|
||||||
|
viewpoint.perspective_camera.camera_direction.y = mat[1][2] * -1
|
||||||
|
viewpoint.perspective_camera.camera_direction.z = mat[2][2] * -1
|
||||||
|
viewpoint.perspective_camera.camera_up_vector.x = mat[0][1]
|
||||||
|
viewpoint.perspective_camera.camera_up_vector.y = mat[1][1]
|
||||||
|
viewpoint.perspective_camera.camera_up_vector.z = mat[2][1]
|
||||||
|
bcfxml.add_viewpoint(topic, viewpoint)
|
||||||
|
if i == 0:
|
||||||
|
bcfxml.save_project(self.settings.output)
|
||||||
|
else:
|
||||||
|
bcfxml.save_project(self.settings.output + f".{i}")
|
||||||
|
|
||||||
|
# https://blender.stackexchange.com/questions/68834/recreate-to-track-quat-with-two-vectors-using-python/141706#141706
|
||||||
|
def get_track_to_matrix(self, camera_position, target_position):
|
||||||
|
camera_direction = camera_position - target_position
|
||||||
|
camera_direction = camera_direction / np.linalg.norm(camera_direction)
|
||||||
|
camera_right = np.cross(np.array([0.0, 0.0, 1.0]), camera_direction)
|
||||||
|
camera_right = camera_right / np.linalg.norm(camera_right)
|
||||||
|
camera_up = np.cross(camera_direction, camera_right)
|
||||||
|
camera_up = camera_up / np.linalg.norm(camera_up)
|
||||||
|
rotation_transform = np.zeros((4, 4))
|
||||||
|
rotation_transform[0, :3] = camera_right
|
||||||
|
rotation_transform[1, :3] = camera_up
|
||||||
|
rotation_transform[2, :3] = camera_direction
|
||||||
|
rotation_transform[-1, -1] = 1
|
||||||
|
translation_transform = np.eye(4)
|
||||||
|
translation_transform[:3, -1] = - camera_position
|
||||||
|
look_at_transform = np.matmul(rotation_transform, translation_transform)
|
||||||
|
return np.linalg.inv(look_at_transform)
|
||||||
|
|
||||||
|
def export_json(self):
|
||||||
results = self.clash_sets.copy()
|
results = self.clash_sets.copy()
|
||||||
for result in results:
|
for result in results:
|
||||||
del result["a_cm"]
|
del result["a_cm"]
|
||||||
@@ -269,14 +328,14 @@ class IfcClasher:
|
|||||||
def smart_group_clashes(self, clash_sets, max_clustering_distance):
|
def smart_group_clashes(self, clash_sets, max_clustering_distance):
|
||||||
from sklearn.cluster import OPTICS
|
from sklearn.cluster import OPTICS
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
count_of_input_clashes = 0
|
count_of_input_clashes = 0
|
||||||
count_of_clash_sets = 0
|
count_of_clash_sets = 0
|
||||||
count_of_smart_groups = 0
|
count_of_smart_groups = 0
|
||||||
count_of_final_clash_sets = 0
|
count_of_final_clash_sets = 0
|
||||||
|
|
||||||
count_of_clash_sets = len(clash_sets)
|
count_of_clash_sets = len(clash_sets)
|
||||||
|
|
||||||
for clash_set in clash_sets:
|
for clash_set in clash_sets:
|
||||||
if not "clashes" in clash_set.keys():
|
if not "clashes" in clash_set.keys():
|
||||||
print(f"Skipping clash set [{clash_set['name']}] since it contains no clash results.")
|
print(f"Skipping clash set [{clash_set['name']}] since it contains no clash results.")
|
||||||
@@ -324,14 +383,14 @@ class IfcClasher:
|
|||||||
if not "clashes" in clash_set.keys():
|
if not "clashes" in clash_set.keys():
|
||||||
continue
|
continue
|
||||||
smart_groups = defaultdict(list)
|
smart_groups = defaultdict(list)
|
||||||
for clash_id, content in clash_set['clashes'].items():
|
for clash_id, content in clash_set["clashes"].items():
|
||||||
if "smart_group" in content:
|
if "smart_group" in content:
|
||||||
object_id_list = list()
|
object_id_list = list()
|
||||||
# Clash has been grouped, let's extract it.
|
# Clash has been grouped, let's extract it.
|
||||||
object_id_list.append(content['a_global_id'])
|
object_id_list.append(content["a_global_id"])
|
||||||
object_id_list.append(content['b_global_id'])
|
object_id_list.append(content["b_global_id"])
|
||||||
smart_groups[content['smart_group']].append(object_id_list)
|
smart_groups[content["smart_group"]].append(object_id_list)
|
||||||
count_of_smart_groups += len(smart_groups)
|
count_of_smart_groups += len(smart_groups)
|
||||||
output_clash_sets[clash_set["name"]].append(smart_groups)
|
output_clash_sets[clash_set["name"]].append(smart_groups)
|
||||||
|
|
||||||
# Rename the clash groups to something more sensible
|
# Rename the clash groups to something more sensible
|
||||||
@@ -346,8 +405,10 @@ class IfcClasher:
|
|||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
count_of_final_clash_sets = len(output_clash_sets)
|
count_of_final_clash_sets = len(output_clash_sets)
|
||||||
print(f"Took {count_of_input_clashes} clashes in {count_of_clash_sets} clash sets and turned",
|
print(
|
||||||
f"them into {count_of_smart_groups} smart groups in {count_of_final_clash_sets} clash sets")
|
f"Took {count_of_input_clashes} clashes in {count_of_clash_sets} clash sets and turned",
|
||||||
|
f"them into {count_of_smart_groups} smart groups in {count_of_final_clash_sets} clash sets",
|
||||||
|
)
|
||||||
|
|
||||||
return output_clash_sets
|
return output_clash_sets
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user