New cmake for doc

This commit is contained in:
johltn
2020-09-09 20:45:42 +02:00
parent cba30f0831
commit a70429d2c8
29 changed files with 5074 additions and 2 deletions
+16 -1
View File
@@ -23,6 +23,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # not necessary, but encouraged
project (IfcOpenShell)
#set(Boost_DEBUG 1)
foreach(max_year RANGE 2014 2030)
set(max_sdk "$ENV{ADSK_3DSMAX_SDK_${max_year}}")
if (NOT "${max_sdk}" STREQUAL "")
@@ -104,6 +108,17 @@ MACRO(UNIFY_ENVVARS_AND_CACHE VAR)
ENDIF()
ENDMACRO()
UNIFY_ENVVARS_AND_CACHE(BOOST_ROOT)
UNIFY_ENVVARS_AND_CACHE(BOOST_LIBRARYDIR)
UNIFY_ENVVARS_AND_CACHE(BOOST_ROOT)
UNIFY_ENVVARS_AND_CACHE(BOOST_LIBRARYDIR)
message(STATUS "BOOST_ROOT ${BOOST_ROOT}")
message(STATUS "BOOST_LIBRARYDIR ${BOOST_LIBRARYDIR}")
UNIFY_ENVVARS_AND_CACHE(OCC_INCLUDE_DIR)
UNIFY_ENVVARS_AND_CACHE(OCC_LIBRARY_DIR)
UNIFY_ENVVARS_AND_CACHE(OPENCOLLADA_INCLUDE_DIR)
@@ -208,7 +223,7 @@ function(add_debug_variants NAME LIBRARIES POSTFIX)
endfunction()
if(BUILD_IFCGEOM)
MESSAGE(STATUS "OCC_INCLUDE_DIR ${OCC_INCLUDE_DIR}")
# Find Open CASCADE
IF("${OCC_INCLUDE_DIR}" STREQUAL "")
SET(OCC_INCLUDE_DIR "/usr/include/oce/" CACHE FILEPATH "Open CASCADE header files")
+78
View File
@@ -0,0 +1,78 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
if hasattr(os, 'uname'):
platform_system = os.uname()[0].lower()
else:
platform_system = 'windows'
if sys.maxsize == (1 << 31) - 1:
platform_architecture = '32bit'
else:
platform_architecture = '64bit'
python_version_tuple = tuple(sys.version.split(' ')[0].split('.'))
python_distribution = os.path.join(platform_system,
platform_architecture,
'python%s.%s' % python_version_tuple[:2])
sys.path.append(os.path.abspath(os.path.join(
os.path.dirname(__file__),
'lib', python_distribution)))
try:
from . import ifcopenshell_wrapper
except Exception as e:
if int(python_version_tuple[0]) == 2:
# Only for py2, as py3 has exception chaining
import traceback
traceback.print_exc()
print('-' * 64)
raise ImportError("IfcOpenShell not built for '%s'" % python_distribution)
from . import guid
from .file import file
from .entity_instance import entity_instance
def open(fn):
f = ifcopenshell_wrapper.open(os.path.abspath(fn))
if f.good():
return file(f)
else:
raise IOError("Unable to open file for reading")
def create_entity(type, *args, **kwargs):
e = entity_instance(type)
attrs = list(enumerate(args)) + \
[(e.wrapped_data.get_argument_index(name), arg) for name, arg in kwargs.items()]
for idx, arg in attrs:
e[idx] = arg
return e
from .main import *
Binary file not shown.
+254
View File
@@ -0,0 +1,254 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import functools
import numbers
import itertools
from . import ifcopenshell_wrapper
try:
import logging
except ImportError as e:
logging = type('logger', (object,), {'exception': staticmethod(lambda s: print(s))})
class entity_instance(object):
"""This is the base Python class for all IFC objects.
An instantiated entity_instance will have methods of Python and the IFC class itself.
Example::
ifc_file = ifcopenshell.open(file_path)
products = ifc_file.by_type("IfcProduct")
print(products[0].__class__)
>>> <class 'ifcopenshell.entity_instance.entity_instance'>
print(products[0].Representation)
>>> #423=IfcProductDefinitionShape($,$,(#409,#421))
"""
def __init__(self, e):
if isinstance(e, tuple):
e = ifcopenshell_wrapper.new_IfcBaseClass(*e)
super(entity_instance, self).__setattr__('wrapped_data', e)
def __getattr__(self, name):
INVALID, FORWARD, INVERSE = range(3)
attr_cat = self.wrapped_data.get_attribute_category(name)
if attr_cat == FORWARD:
return entity_instance.wrap_value(
self.wrapped_data.get_argument(self.wrapped_data.get_argument_index(name)))
elif attr_cat == INVERSE:
return entity_instance.wrap_value(self.wrapped_data.get_inverse(name))
else:
raise AttributeError(
"entity instance of type '%s' has no attribute '%s'" % (self.wrapped_data.is_a(), name))
@staticmethod
def walk(f, g, value):
if isinstance(value, (tuple, list)):
return tuple(map(functools.partial(entity_instance.walk, f, g), value))
elif f(value):
return g(value)
else:
return value
@staticmethod
def wrap_value(v):
def wrap(e): return entity_instance(e)
def is_instance(e): return isinstance(e, ifcopenshell_wrapper.entity_instance)
return entity_instance.walk(is_instance, wrap, v)
@staticmethod
def unwrap_value(v):
def unwrap(e): return e.wrapped_data
def is_instance(e): return isinstance(e, entity_instance)
return entity_instance.walk(is_instance, unwrap, v)
def attribute_type(self, attr):
"""Return the data type of a positional attribute of the element
:param attr: The index of the attribute
:type attr: int
:rtype: string
"""
attr_idx = attr if isinstance(attr, numbers.Integral) else self.wrapped_data.get_argument_index(attr)
return self.wrapped_data.get_argument_type(attr_idx)
def attribute_name(self, attr_idx):
"""Return the name of a positional attribute of the element
:param attr_idx: The index of the attribute
:type attr_idx: int
:rtype: string
"""
return self.wrapped_data.get_argument_name(attr_idx)
def __setattr__(self, key, value):
self[self.wrapped_data.get_argument_index(key)] = value
def __getitem__(self, key):
if key < 0 or key >= len(self):
raise IndexError("Attribute index {} out of range for instance of type {}".format(key, self.is_a()))
return entity_instance.wrap_value(self.wrapped_data.get_argument(key))
def __setitem__(self, idx, value):
attr_type = real_attr_type = self.attribute_type(idx).title().replace(' ', '')
real_attr_type = real_attr_type.replace('Derived', 'None')
attr_type = attr_type.replace('Binary', 'String')
attr_type = attr_type.replace('Enumeration', 'String')
if value is None:
if attr_type != "Derived":
self.wrapped_data.setArgumentAsNull(idx)
else:
valid = attr_type != "Derived"
if valid:
try:
if isinstance(value, unicode):
value = value.encode("utf-8")
except BaseException:
pass
try:
if attr_type != "Derived":
getattr(self.wrapped_data, "setArgumentAs%s" % attr_type)(idx, entity_instance.unwrap_value(value))
except BaseException as e:
valid = False
if not valid:
raise ValueError("Expected %s for attribute %s.%s, got %r" % (
real_attr_type, self.is_a(), self.attribute_name(idx), value))
return value
def __len__(self):
return len(self.wrapped_data)
def __repr__(self):
return repr(self.wrapped_data)
def is_a(self, *args):
"""Return the IFC class name of an instance, or checks if an instance belongs to a class.
The check will also return true if a parent class name is provided.
:param args: If specified, is a case insensitive IFC class name to check
:type args: string
:returns: Either the name of the class, or a boolean if it passes the check
:rtype: string|bool
Example::
f = ifcopenshell.file()
f.create_entity('IfcPerson')
f.is_a()
>>> 'IfcPerson'
f.is_a('IfcPerson')
>>> True
"""
return self.wrapped_data.is_a(*args)
def id(self):
"""Return the STEP numerical identifier
:rtype: int
"""
return self.wrapped_data.id()
def __eq__(self, other):
if not isinstance(self, type(other)):
return False
return self.wrapped_data == other.wrapped_data
def __hash__(self):
return hash((self.id(), self.wrapped_data.file_pointer()))
def __dir__(self):
return sorted(set(itertools.chain(
dir(type(self)),
map(str, self.wrapped_data.get_attribute_names()),
map(str, self.wrapped_data.get_inverse_attribute_names())
)))
def get_info(self, include_identifier=True, recursive=False, return_type=dict, ignore=()):
"""Return a dictionary of the entity_instance's properties (Python and IFC) and their values.
:param include_identifier: Whether or not to include the STEP numerical identifier
:type include_identifier: bool
:param recursive: Whether or not to convert referenced IFC elements into dictionaries too. All attributes also apply recursively
:type recursive: bool
:param return_type: The return data type to be casted into
:type return_type: dict|list|other
:param ignore: A list of attribute names to ignore
:type ignore: set|list
:returns: A dictionary of properties and their corresponding values
:rtype: dict
Example::
ifc_file = ifcopenshell.open(file_path)
products = ifc_file.by_type("IfcProduct")
obj_info = products[0].get_info()
print(obj_info.keys())
>>> dict_keys(['Description', 'Name', 'BuildingAddress', 'LongName', 'GlobalId', 'ObjectPlacement', 'OwnerHistory', 'ObjectType',
>>> ...'ElevationOfTerrain', 'CompositionType', 'id', 'Representation', 'type', 'ElevationOfRefHeight'])
"""
def _():
try:
if include_identifier:
yield "id", self.id()
yield "type", self.is_a()
except BaseException:
logging.exception("unhandled exception while getting id / type info on {}".format(self))
for i in range(len(self)):
try:
if self.wrapped_data.get_attribute_names()[i] in ignore:
continue
attr_value = self[i]
if recursive:
def is_instance(e): return isinstance(e, entity_instance)
def get_info_(inst):
# for ty in ignore:
# if inst.is_a(ty):
# return None
return entity_instance.get_info(inst,
include_identifier=include_identifier,
recursive=recursive,
return_type=return_type,
ignore=ignore
)
attr_value = entity_instance.walk(is_instance, get_info_, attr_value)
yield self.attribute_name(i), attr_value
except BaseException:
logging.exception("unhandled exception occurred setting attribute name for {}".format(self))
return return_type(_())
__dict__ = property(get_info)
+184
View File
@@ -0,0 +1,184 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numbers
import functools
from . import ifcopenshell_wrapper
from .entity_instance import entity_instance
try:
# Python 2
basestring
except NameError:
# Python 3 or newer
basestring = (str, bytes)
class file(object):
"""Base class for containing IFC files.
Class has instance methods for filtering by element Id, Type, etc.
Instantiated objects can be subscripted by Id or Guid
Example::
ifc_file = ifcopenshell.open(file_path)
products = ifc_file.by_type("IfcProduct")
print(products[0].id(), products[0].GlobalId)
>>> 122 2XQ$n5SLP5MBLyL442paFx
# Subscripting
print(products[0] == ifc_file[122] == ifc_file['2XQ$n5SLP5MBLyL442paFx'])
>>> True
"""
def __init__(self, f=None, schema=None):
if f is not None:
self.wrapped_data = f
else:
args = filter(None, [schema])
args = map(ifcopenshell_wrapper.schema_by_name, args)
self.wrapped_data = ifcopenshell_wrapper.file(*args)
def create_entity(self, type, *args, **kwargs):
"""Create a new IFC entity in the file.
:param type: Case insensitive name of the IFC class
:type type: string
:param args: The positional arguments of the IFC class
:param kwargs: The keyword arguments of the IFC class
:returns: An entity instance
:rtype: ifcopenshell.entity_instance.entity_instance
Example::
f = ifcopenshell.file()
f.create_entity('IfcPerson')
>>> #1=IfcPerson($,$,$,$,$,$,$,$)
f.create_entity('IfcPerson', 'Foobar')
>>> #2=IfcPerson('Foobar',$,$,$,$,$,$,$)
f.create_entity('IfcPerson', Identification='Foobar')
>>> #3=IfcPerson('Foobar',$,$,$,$,$,$,$)
"""
e = entity_instance((self.schema, type))
self.wrapped_data.add(e.wrapped_data)
e.wrapped_data.this.disown()
attrs = list(enumerate(args)) + \
[(e.wrapped_data.get_argument_index(name), arg) for name, arg in kwargs.items()]
for idx, arg in attrs:
e[idx] = arg
return e
def __getattr__(self, attr):
if attr[0:6] == 'create':
return functools.partial(self.create_entity, attr[6:])
else:
return getattr(self.wrapped_data, attr)
def __getitem__(self, key):
if isinstance(key, numbers.Integral):
return entity_instance(self.wrapped_data.by_id(key))
elif isinstance(key, basestring):
return entity_instance(self.wrapped_data.by_guid(str(key)))
def by_id(self, id):
"""Return an IFC entity instance filtered by IFC ID.
:param id: STEP numerical identifier
:type id: int
:returns: An ifcopenshell.entity_instance.entity_instance
:rtype: ifcopenshell.entity_instance.entity_instance
"""
return self[id]
def by_guid(self, guid):
"""Return an IFC entity instance filtered by IFC GUID.
:param guid: GlobalId value in 22-character encoded form
:type guid: string
:returns: An ifcopenshell.entity_instance.entity_instance
:rtype: ifcopenshell.entity_instance.entity_instance
"""
return self[guid]
def add(self, inst):
"""Adds an entity including any dependent entities to an IFC file.
If the entity already exists, it is not re-added."""
inst.wrapped_data.this.disown()
return entity_instance(self.wrapped_data.add(inst.wrapped_data))
def by_type(self, type):
"""Return IFC objects filtered by IFC Type and wrapped with the entity_instance class.
If an IFC type class has subclasses, all entities of those subclasses are also returned.
:param type: The case insensitive type of IFC class to return.
:type type: string
:returns: A list of ifcopenshell.entity_instance.entity_instance objects
:rtype: list
"""
return [entity_instance(e) for e in self.wrapped_data.by_type(type)]
def traverse(self, inst, max_levels=None):
"""Get a list of all referenced instances for a particular instance including itself
:param inst: The entity instance to get all sub instances
:type inst: ifcopenshell.entity_instance.entity_instance
:param max_levels: How far deep to recursively fetch sub instances. None or -1 means infinite.
:type max_levels: None|int
:returns: A list of ifcopenshell.entity_instance.entity_instance objects
:rtype: list
"""
if max_levels is None:
max_levels = -1
return [entity_instance(e) for e in self.wrapped_data.traverse(inst.wrapped_data, max_levels)]
def get_inverse(self, inst):
"""Return a list of entities that reference this entity
:param inst: The entity instance to get inverse relationships
:type inst: ifcopenshell.entity_instance.entity_instance
:returns: A list of ifcopenshell.entity_instance.entity_instance objects
:rtype: list
"""
return [entity_instance(e) for e in self.wrapped_data.get_inverse(inst.wrapped_data)]
def remove(self, inst):
"""Deletes an IFC object in the file.
Attribute values in other entity instances that reference the deleted
object will be set to null. In the case of a list or set of references,
the reference to the deleted will be removed from the aggregate.
:param inst: The entity instance to delete
:type inst: ifcopenshell.entity_instance.entity_instance
:rtype: None
"""
return self.wrapped_data.remove(inst.wrapped_data)
def __iter__(self):
return iter(self[id] for id in self.wrapped_data.entity_names())
@staticmethod
def from_string(s):
return file(ifcopenshell_wrapper.read(s))
+45
View File
@@ -0,0 +1,45 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
def _has_occ():
try:
import OCC.Core.BRepTools
return True
except ImportError:
pass
try:
import OCC.BRepTools
return True
except ImportError:
pass
return False
has_occ = _has_occ()
if has_occ:
from . import occ_utils as utils
from .main import *
+647
View File
@@ -0,0 +1,647 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
import time
import operator
import functools
import multiprocessing
import OCC.AIS
from collections import defaultdict, Iterable, OrderedDict
try:
QString = unicode
except NameError:
# Python 3
QString = str
os.environ['QT_API'] = 'pyqt5'
try:
from pyqode.qt import QtCore
except BaseException:
pass
from PyQt5 import QtCore, QtGui, QtWidgets
from .code_editor_pane import code_edit
try:
from OCC.Display.pyqt5Display import qtViewer3d
except BaseException:
import OCC.Display
try:
import OCC.Display.backend
except BaseException:
pass
try:
OCC.Display.backend.get_backend("qt-pyqt5")
except BaseException:
OCC.Display.backend.load_backend("qt-pyqt5")
from OCC.Display.qtDisplay import qtViewer3d
from .main import settings, iterator
from .occ_utils import display_shape
from .. import open as open_ifc_file
from .. import version as ifcopenshell_version
if ifcopenshell_version < "0.6":
# not yet ported
from .. import get_supertype
class geometry_creation_signals(QtCore.QObject):
completed = QtCore.pyqtSignal('PyQt_PyObject')
progress = QtCore.pyqtSignal('PyQt_PyObject')
class geometry_creation_thread(QtCore.QThread):
def __init__(self, signals, settings, f):
QtCore.QThread.__init__(self)
self.signals = signals
self.settings = settings
self.f = f
def run(self):
t0 = time.time()
# detect concurrency from hardware, we need to have
# at least two threads because otherwise the interface
# is different
# is different
it = iterator(self.settings, self.f, max(2, multiprocessing.cpu_count()))
if not it.initialize():
self.signals.completed.emit([])
return
def _():
old_progress = -1
while True:
shape = it.get()
if shape:
yield shape
if not it.next():
break
self.signals.completed.emit((it, self.f, list(_())))
class configuration(object):
def __init__(self):
try:
import ConfigParser
Cfg = ConfigParser.RawConfigParser
except BaseException:
import configparser
def Cfg():
return configparser.ConfigParser(interpolation=None)
conf_file = os.path.expanduser(os.path.join("~", ".ifcopenshell", "app", "snippets.conf"))
if conf_file.startswith("~"):
conf_file = None
return
self.config_encode = lambda s: s.replace("\\", "\\\\").replace("\n", "\n|")
self.config_decode = lambda s: s.replace("\n|", "\n").replace("\\\\", "\\")
if not os.path.exists(os.path.dirname(conf_file)):
os.makedirs(os.path.dirname(conf_file))
if not os.path.exists(conf_file):
config = Cfg()
config.add_section("snippets")
config.set("snippets", "print all wall ids", self.config_encode("""
###########################################################################
# A simple script that iterates over all walls in the current model #
# and prints their Globally unique IDs (GUIDS) to the console window #
###########################################################################
for wall in model.by_type("IfcWall"):
print ("wall with global id: "+str(wall.GlobalId))
""".lstrip()))
config.set("snippets", "print properties of current selection", self.config_encode("""
###########################################################################
# A simple script that iterates over all IfcPropertySets of the currently #
# selected object and prints them to the console #
###########################################################################
# check if something is selected
if selection:
#get the IfcProduct that is stored in the global variable 'selection'
obj = selection
for relDefinesByProperties in obj.IsDefinedBy:
print("[{0}]".format(relDefinesByProperties.RelatingPropertyDefinition.Name))
for prop in relDefinesByProperties.RelatingPropertyDefinition.HasProperties:
print ("{:<20} :{}".format(prop.Name,prop.NominalValue.wrappedValue))
print ("\\n")
""".lstrip()))
with open(conf_file, 'w') as configfile:
config.write(configfile)
self.config = Cfg()
self.config.read(conf_file)
def options(self, s):
return OrderedDict([(k, self.config_decode(self.config.get(s, k))) for k in self.config.options(s)])
class application(QtWidgets.QApplication):
"""A pythonOCC, PyQt based IfcOpenShell application
with two tree views and a graphical 3d view"""
class abstract_treeview(QtWidgets.QTreeWidget):
"""Base class for the two treeview controls"""
instanceSelected = QtCore.pyqtSignal([object])
instanceVisibilityChanged = QtCore.pyqtSignal([object, int])
instanceDisplayModeChanged = QtCore.pyqtSignal([object, int])
def __init__(self):
QtWidgets.QTreeView.__init__(self)
self.setColumnCount(len(self.ATTRIBUTES))
self.setHeaderLabels(self.ATTRIBUTES)
self.children = defaultdict(list)
def get_children(self, inst):
c = [inst]
i = 0
while i < len(c):
c.extend(self.children[c[i]])
i += 1
return c
def contextMenuEvent(self, event):
menu = QtWidgets.QMenu(self)
visibility = [menu.addAction("Show"), menu.addAction("Hide")]
displaymode = [menu.addAction("Solid"), menu.addAction("Wireframe")]
action = menu.exec_(self.mapToGlobal(event.pos()))
index = self.selectionModel().currentIndex()
inst = index.data(QtCore.Qt.UserRole)
if hasattr(inst, 'toPyObject'):
inst = inst
if action in visibility:
self.instanceVisibilityChanged.emit(inst, visibility.index(action))
elif action in displaymode:
self.instanceDisplayModeChanged.emit(inst, displaymode.index(action))
def clicked_(self, index):
inst = index.data(QtCore.Qt.UserRole)
if hasattr(inst, 'toPyObject'):
inst = inst
if inst:
self.instanceSelected.emit(inst)
def select(self, product):
itm = self.product_to_item.get(product)
if itm is None:
return
self.selectionModel().setCurrentIndex(itm,
QtCore.QItemSelectionModel.SelectCurrent | QtCore.QItemSelectionModel.Rows)
class decomposition_treeview(abstract_treeview):
"""Treeview with typical IFC decomposition relationships"""
ATTRIBUTES = ['Entity', 'GlobalId', 'Name']
def parent(self, instance):
if instance.is_a("IfcOpeningElement"):
return instance.VoidsElements[0].RelatingBuildingElement
if instance.is_a("IfcElement"):
fills = instance.FillsVoids
if len(fills):
return fills[0].RelatingOpeningElement
containments = instance.ContainedInStructure
if len(containments):
return containments[0].RelatingStructure
if instance.is_a("IfcObjectDefinition"):
decompositions = instance.Decomposes
if len(decompositions):
return decompositions[0].RelatingObject
def load_file(self, f, **kwargs):
products = list(f.by_type("IfcProduct")) + list(f.by_type("IfcProject"))
parents = list(map(self.parent, products))
items = {}
skipped = 0
ATTRS = self.ATTRIBUTES
while len(items) + skipped < len(products):
for product, parent in zip(products, parents):
if parent is None and not product.is_a("IfcProject"):
skipped += 1
continue
if (parent is None or parent in items) and product not in items:
sl = []
for attr in ATTRS:
if attr == 'Entity':
sl.append(product.is_a())
else:
sl.append(getattr(product, attr) or '')
itm = items[product] = QtWidgets.QTreeWidgetItem(items.get(parent, self), sl)
itm.setData(0, QtCore.Qt.UserRole, product)
self.children[parent].append(product)
self.product_to_item = dict(zip(items.keys(), map(self.indexFromItem, items.values())))
self.clicked.connect(self.clicked_)
self.expandAll()
class type_treeview(abstract_treeview):
"""Treeview with typical IFC decomposition relationships"""
ATTRIBUTES = ['Name']
def load_file(self, f, **kwargs):
products = list(f.by_type("IfcProduct"))
types = set(map(lambda i: i.is_a(), products))
items = {}
for t in types:
def add(t):
s = get_supertype(t)
if s:
add(s)
s2, t2 = map(QString, (s, t))
if t2 not in items:
itm = items[t2] = QtWidgets.QTreeWidgetItem(items.get(s2, self), [t2])
itm.setData(0, QtCore.Qt.UserRole, t2)
self.children[s2].append(t2)
if ifcopenshell_version < "0.6":
add(t)
for p in products:
t = QString(p.is_a())
itm = items[p] = QtWidgets.QTreeWidgetItem(items.get(t, self), [p.Name or '<no name>'])
itm.setData(0, QtCore.Qt.UserRole, t)
self.children[t].append(p)
self.product_to_item = dict(zip(items.keys(), map(self.indexFromItem, items.values())))
self.clicked.connect(self.clicked)
self.expandAll()
class property_table(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.layout = QtWidgets.QVBoxLayout(self)
self.setLayout(self.layout)
self.scroll = QtWidgets.QScrollArea(self)
self.layout.addWidget(self.scroll)
self.scroll.setWidgetResizable(True)
self.scrollContent = QtWidgets.QWidget(self.scroll)
self.scrollLayout = QtWidgets.QVBoxLayout(self.scrollContent)
self.scrollContent.setLayout(self.scrollLayout)
self.scroll.setWidget(self.scrollContent)
self.prop_dict = {}
# triggered by selection event in either component of parent
def select(self, product):
# Clear the old contents if any
while self.scrollLayout.count():
child = self.scrollLayout.takeAt(0)
if child is not None:
if child.widget() is not None:
child.widget().deleteLater()
self.scroll = QtWidgets.QScrollArea()
self.scroll.setWidgetResizable(True)
prop_sets = self.prop_dict.get(str(product))
if prop_sets is not None:
for k, v in prop_sets:
group_box = QtWidgets.QGroupBox()
group_box.setTitle(k)
group_layout = QtWidgets.QVBoxLayout()
group_box.setLayout(group_layout)
for name, value in v.items():
prop_name = str(name)
value_str = value
if hasattr(value_str, "wrappedValue"):
value_str = value_str.wrappedValue
if isinstance(value_str, unicode):
value_str = value_str.encode('utf-8')
else:
value_str = str(value_str)
if hasattr(value, "is_a"):
type_str = " <i>(%s)</i>" % value.is_a()
else:
type_str = ""
label = QtWidgets.QLabel("<b>%s</b>: %s%s" % (prop_name, value_str, type_str))
group_layout.addWidget(label)
group_layout.addStretch()
self.scrollLayout.addWidget(group_box)
self.scrollLayout.addStretch()
else:
label = QtWidgets.QLabel("No IfcPropertySets asscociated with selected entity instance")
self.scrollLayout.addWidget(label)
def load_file(self, f, **kwargs):
for p in f.by_type("IfcProduct"):
propsets = []
def process_pset(prop_def):
if prop_def is not None:
prop_set_name = prop_def.Name
props = {}
if prop_def.is_a("IfcElementQuantity"):
for q in prop_def.Quantities:
if q.is_a("IfcPhysicalSimpleQuantity"):
props[q.Name] = q[3]
elif prop_def.is_a("IfcPropertySet"):
for prop in prop_def.HasProperties:
if prop.is_a("IfcPropertySingleValue"):
props[prop.Name] = prop.NominalValue
else:
# Entity introduced in IFC4
# prop_def.is_a("IfcPreDefinedPropertySet"):
for prop in range(4, len(prop_def)):
props[prop_def.attribute_name(prop)] = prop_def[prop]
return prop_set_name, props
try:
for is_def_by in p.IsDefinedBy:
if is_def_by.is_a("IfcRelDefinesByProperties"):
propsets.append(process_pset(is_def_by.RelatingPropertyDefinition))
elif is_def_by.is_a("IfcRelDefinesByType"):
type_psets = is_def_by.RelatingType.HasPropertySets
if type_psets is None:
continue
for propset in type_psets:
propsets.append(process_pset(propset))
except Exception as e:
import traceback
print("failed to load properties: {}".format(e))
traceback.print_exc()
if len(propsets):
self.prop_dict[str(p)] = propsets
print("property set dictionary has {} entries".format(len(self.prop_dict)))
class viewer(qtViewer3d):
instanceSelected = QtCore.pyqtSignal([object])
@staticmethod
def ais_to_key(ais_handle):
def yield_shapes():
ais = ais_handle.GetObject()
if hasattr(ais, 'Shape'):
yield ais.Shape()
return
shp = OCC.AIS.Handle_AIS_Shape.DownCast(ais_handle)
if not shp.IsNull():
yield shp.Shape()
return
mult = ais_handle
if mult.IsNull():
shp = OCC.AIS.Handle_AIS_Shape.DownCast(ais_handle)
if not shp.IsNull():
yield shp
else:
li = mult.GetObject().ConnectedTo()
for i in range(li.Length()):
shp = OCC.AIS.Handle_AIS_Shape.DownCast(li.Value(i + 1))
if not shp.IsNull():
yield shp
return tuple(shp.HashCode(1 << 24) for shp in yield_shapes())
def __init__(self, widget):
qtViewer3d.__init__(self, widget)
self.ais_to_product = {}
self.product_to_ais = {}
self.counter = 0
self.window = widget
self.thread = None
def initialize(self):
self.InitDriver()
self._display.Select = self.HandleSelection
def finished(self, file_shapes):
it, f, shapes = file_shapes
v = self._display
t = {0: time.time()}
def update(dt=None):
t1 = time.time()
if dt is None or t1 - t[0] > dt:
v.FitAll()
v.Repaint()
t[0] = t1
for shape in shapes:
ais = display_shape(shape, viewer_handle=v)
product = f[shape.data.id]
ais.GetObject().SetSelectionPriority(self.counter)
self.ais_to_product[self.counter] = product
self.product_to_ais[product] = ais
self.counter += 1
QtWidgets.QApplication.processEvents()
if product.is_a() in {'IfcSpace', 'IfcOpeningElement'}:
v.Context.Erase(ais, True)
update(1.)
update()
self.thread = None
def load_file(self, f, setting=None):
if self.thread is not None:
return
if setting is None:
setting = settings()
setting.set(setting.INCLUDE_CURVES, True)
setting.set(setting.USE_PYTHON_OPENCASCADE, True)
self.signals = geometry_creation_signals()
thread = self.thread = geometry_creation_thread(self.signals, setting, f)
self.window.window_closed.connect(lambda *args: thread.terminate())
self.signals.completed.connect(self.finished)
self.thread.start()
def select(self, product):
ais = self.product_to_ais.get(product)
if ais is None:
return
v = self._display.Context
v.ClearSelected(False)
v.SetSelected(ais, True)
def toggle(self, product_or_products, fn):
if not isinstance(product_or_products, Iterable):
product_or_products = [product_or_products]
aiss = list(filter(None, map(self.product_to_ais.get, product_or_products)))
last = len(aiss) - 1
for i, ais in enumerate(aiss):
fn(ais, i == last)
def toggle_visibility(self, product_or_products, flag):
v = self._display.Context
if flag:
def visibility(ais, last):
v.Erase(ais, last)
else:
def visibility(ais, last):
v.Display(ais, last)
self.toggle(product_or_products, visibility)
def toggle_wireframe(self, product_or_products, flag):
v = self._display.Context
if flag:
def wireframe(ais, last):
if v.IsDisplayed(ais):
v.SetDisplayMode(ais, 0, last)
else:
def wireframe(ais, last):
if v.IsDisplayed(ais):
v.SetDisplayMode(ais, 1, last)
self.toggle(product_or_products, wireframe)
def HandleSelection(self, X, Y):
v = self._display.Context
v.Select()
v.InitSelected()
if v.MoreSelected():
ais = v.SelectedInteractive()
inst = self.ais_to_product[ais.GetObject().SelectionPriority()]
self.instanceSelected.emit(inst)
class window(QtWidgets.QMainWindow):
TITLE = "IfcOpenShell IFC viewer"
window_closed = QtCore.pyqtSignal([])
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.setWindowTitle(self.TITLE)
self.menu = self.menuBar()
self.menus = {}
def closeEvent(self, *args):
self.window_closed.emit()
def add_menu_item(self, menu, label, callback, icon=None, shortcut=None):
m = self.menus.get(menu)
if m is None:
m = self.menu.addMenu(menu)
self.menus[menu] = m
if icon:
a = QtWidgets.QAction(QtGui.QIcon(icon), label, self)
else:
a = QtWidgets.QAction(label, self)
if shortcut:
a.setShortcut(shortcut)
a.triggered.connect(callback)
m.addAction(a)
def makeSelectionHandler(self, component):
def handler(inst):
for c in self.components:
if c != component:
c.select(inst)
return handler
def __init__(self, settings=None):
QtWidgets.QApplication.__init__(self, sys.argv)
self.window = application.window()
self.tree = application.decomposition_treeview()
self.tree2 = application.type_treeview()
self.propview = self.property_table()
self.canvas = application.viewer(self.window)
self.tabs = QtWidgets.QTabWidget()
self.window.resize(800, 600)
splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
splitter.addWidget(self.tabs)
self.tabs.addTab(self.tree, 'Decomposition')
self.tabs.addTab(self.tree2, 'Types')
self.tabs.addTab(self.propview, "Properties")
splitter2 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
splitter2.addWidget(self.canvas)
self.editor = code_edit(self.canvas, configuration().options('snippets'))
splitter2.addWidget(self.editor)
splitter.addWidget(splitter2)
splitter.setSizes([200, 600])
splitter2.setSizes([400, 200])
self.window.setCentralWidget(splitter)
self.canvas.initialize()
self.components = [self.tree, self.tree2, self.canvas, self.propview, self.editor]
self.files = {}
self.window.add_menu_item('File', '&Open', self.browse, shortcut='CTRL+O')
self.window.add_menu_item('File', '&Close', self.clear, shortcut='CTRL+W')
self.window.add_menu_item('File', '&Exit', self.window.close, shortcut='ALT+F4')
self.tree.instanceSelected.connect(self.makeSelectionHandler(self.tree))
self.tree2.instanceSelected.connect(self.makeSelectionHandler(self.tree2))
self.canvas.instanceSelected.connect(self.makeSelectionHandler(self.canvas))
for t in [self.tree, self.tree2]:
t.instanceVisibilityChanged.connect(functools.partial(self.change_visibility, t))
t.instanceDisplayModeChanged.connect(functools.partial(self.change_displaymode, t))
self.settings = settings
def change_visibility(self, tree, inst, flag):
insts = tree.get_children(inst)
self.canvas.toggle_visibility(insts, flag)
def change_displaymode(self, tree, inst, flag):
insts = tree.get_children(inst)
self.canvas.toggle_wireframe(insts, flag)
def start(self):
self.window.show()
sys.exit(self.exec_())
def browse(self):
filename = QtWidgets.QFileDialog.getOpenFileName(self.window, 'Open file', ".",
"Industry Foundation Classes (*.ifc)")[0]
self.load(filename)
def clear(self):
self.canvas._display.Context.RemoveAll()
self.tree.clear()
self.files.clear()
def load(self, fn):
if fn in self.files:
return
f = open_ifc_file(str(fn))
self.files[fn] = f
for c in self.components:
c.load_file(f, setting=self.settings)
if __name__ == "__main__":
application().start()
+103
View File
@@ -0,0 +1,103 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
"""
Rough draft of a client application for the C++ IfcGeomServer binary
"""
import os
import numpy
import subprocess
from collections import namedtuple
class message_headers(object):
HELLO = 0xff00
IFC_MODEL = HELLO + 1
GET = IFC_MODEL + 1
ENTITY = GET + 1
MORE = ENTITY + 1
NEXT = MORE + 1
BYE = NEXT + 1
GET_LOG = BYE + 1
LOG = GET_LOG + 1
DEFLECTION = LOG + 1
SETTING = DEFLECTION + 1
message = namedtuple("message", ("header", "contents"))
def process(geomserver_exe, ifc_filename):
proc = subprocess.Popen([geomserver_exe], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
def cast(data, dtype, n=None):
arr = numpy.frombuffer(data, dtype=dtype)
if n is None: return arr[0]
else: return arr
def read(dtype, n=None):
data = proc.stdout.read(dtype().nbytes * (n or 1))
return cast(data, dtype, n)
def read_message(header_assertion=None):
header, size = read(numpy.int32, 2)
assert header_assertion is None or header_assertion == header
contents = b""
if size > 0:
contents = proc.stdout.read(size)
return message(header, contents)
def write(header, contents=None):
if contents is None: contents = []
proc.stdin.write(numpy.int32(header).tobytes())
integers_as_int32 = list(map(lambda s: numpy.int32(s) if isinstance(s, int) else s, contents))
to_bytes = list(map(lambda s: s.tobytes() if hasattr(s, 'tobytes') else s, integers_as_int32))
total_length = numpy.int32(sum(map(len, to_bytes)))
proc.stdin.write(total_length.tobytes())
for b in to_bytes:
proc.stdin.write(b)
proc.stdin.flush()
read_message(message_headers.HELLO)
# @todo: no need to read the entire file in memory
s = open(ifc_filename, "rb").read()
write(message_headers.SETTING, [numpy.int32((1 << 4)), numpy.int32(1)])
write(message_headers.IFC_MODEL, [numpy.int32(len(s)), s, b"\x00" * ((4 - (len(s) % 4)) % 4)])
while True:
has_more = cast(read_message(message_headers.MORE).contents, numpy.int32) == 1
if not has_more: break
write(message_headers.GET)
print(read_message(message_headers.ENTITY).contents)
write(message_headers.NEXT)
write(message_headers.BYE)
read_message(message_headers.BYE)
proc.wait()
assert proc.returncode == 0
if __name__ == "__main__":
import sys
import platform
exe_extension = ".exe" if platform.system() == 'Windows' else ""
exe = os.environ.get("IFCGEOMSERVER") or ("IfcGeomServer" + exe_extension)
for fn in sys.argv[1:]:
process(exe, fn)
+149
View File
@@ -0,0 +1,149 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
import logging
from code import InteractiveConsole
from PyQt5 import QtCore, QtGui, QtWidgets
try:
from PyQt5 import QtWidgets
except BaseException:
QtWidgets = QtGui
try:
from pyqode.core.panels import CheckerPanel
from pyqode.core import api
from pyqode.core import modes
from pyqode.core import panels
from pyqode.core.api import CodeEdit, ColorScheme
from pyqode.python.modes import PyAutoIndentMode, PythonSH
from pyqode.python.backend import server
from pyqode.python import modes as pymodes, panels as pypanels, widgets
from pyqode.python.widgets import PyInteractiveConsole
has_pyqode = True
except BaseException:
has_pyqode = False
CodeEdit = QtWidgets.QPlainTextEdit
class StdoutRedirector(object):
"""A class for redirecting stdout to this Text widget."""
def __init__(self, widget):
self.widget = widget
self.isError = False
def write(self, myStr):
self.widget.moveCursor(QtGui.QTextCursor.End)
if self.isError:
self.widget.setTextColor(QtCore.Qt.red)
else:
self.widget.setTextColor(QtCore.Qt.white)
self.widget.insertPlainText(myStr)
self.widget.moveCursor(QtGui.QTextCursor.End)
class code_edit(QtWidgets.QWidget):
class Console(InteractiveConsole):
def __init__(*args):
InteractiveConsole.__init__(*args)
def enter(self, source):
self.runcode(source)
def runCode(self):
sys.stdout = StdoutRedirector(self.output)
sys.stderr = StdoutRedirector(self.output)
sys.stderr.isError = True
if not self.model:
print("please load a model first", file=sys.stderr)
else:
self.c.enter(str(self.editor.toPlainText()))
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
def select(self, product):
self.c = self.Console({'model': self.model, 'viewer': self.viewer, 'selection': product})
def __init__(self, viewer, snippets=None):
self.model = None
self.viewer = viewer
QtWidgets.QWidget.__init__(self)
self.layout = QtWidgets.QVBoxLayout(self)
self.setLayout(self.layout)
self.c = None
self.tools = QtWidgets.QHBoxLayout(self)
self.layout.addLayout(self.tools)
self.runbutton = QtWidgets.QPushButton("Run")
width = self.runbutton.fontMetrics().boundingRect("Run").width() + 20
self.runbutton.setMaximumWidth(width)
self.tools.addWidget(self.runbutton)
self.runbutton.clicked.connect(self.runCode)
editor = CodeEdit()
if has_pyqode:
editor.backend.start(server.__file__)
editor.panels.append(panels.FoldingPanel())
editor.panels.append(panels.LineNumberPanel())
editor.panels.append(panels.SearchAndReplacePanel(),
panels.SearchAndReplacePanel.Position.BOTTOM)
editor.panels.append(panels.EncodingPanel(), api.Panel.Position.TOP)
editor.add_separator()
editor.panels.append(pypanels.QuickDocPanel(), api.Panel.Position.BOTTOM)
sh = editor.modes.append(PythonSH(editor.document()))
editor.modes.append(modes.CaretLineHighlighterMode())
editor.modes.append(modes.CodeCompletionMode())
editor.modes.append(modes.ExtendedSelectionMode())
editor.modes.append(modes.FileWatcherMode())
editor.modes.append(modes.OccurrencesHighlighterMode())
editor.modes.append(modes.RightMarginMode())
editor.modes.append(modes.SmartBackSpaceMode())
editor.modes.append(modes.SymbolMatcherMode())
editor.modes.append(modes.ZoomMode())
editor.modes.append(pymodes.CommentsMode())
editor.modes.append(pymodes.CalltipsMode())
auto = pymodes.PyAutoCompleteMode()
auto.logger.setLevel(logging.CRITICAL)
editor.modes.append(auto)
editor.modes.append(pymodes.PyAutoIndentMode())
editor.modes.append(pymodes.PyIndenterMode())
editor.show()
else:
editor.setStyleSheet('font-size: 10pt; font-family: Consolas, Courier;')
self.editor = editor
self.snippets = snippets
if self.snippets:
self.list = QtWidgets.QComboBox(self)
self.replace_snippet(0)
for snip_name in self.snippets.keys():
self.list.addItem(snip_name)
self.tools.addWidget(self.list)
self.list.currentIndexChanged[int].connect(self.replace_snippet)
self.layout.addWidget(self.editor)
self.output = QtWidgets.QTextEdit()
self.output.setReadOnly(True)
self.output.setStyleSheet('font-size: 10pt; font-family: Consolas, Courier; background-color: #444;')
self.layout.addWidget(self.output)
def replace_snippet(self, number=None):
snip = list(self.snippets.values())[number]
if has_pyqode:
self.editor.setPlainText(snip, "", "")
else:
self.editor.setPlainText(snip)
def load_file(self, f, **kwargs):
output = []
sys.stdout = StdoutRedirector(self.output)
self.model = f
self.c = self.Console({'model': self.model, 'selection': None, 'viewer': self.viewer})
sys.stdout = sys.__stdout__
+193
View File
@@ -0,0 +1,193 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
from .. import ifcopenshell_wrapper
from ..file import file
from ..entity_instance import entity_instance
from . import has_occ
def wrap_shape_creation(settings, shape):
return shape
if has_occ:
from . import occ_utils as utils
try:
from OCC.Core import TopoDS
except ImportError:
from OCC import TopoDS
def wrap_shape_creation(settings, shape):
if getattr(settings, 'use_python_opencascade', False):
return utils.create_shape_from_serialization(shape)
else:
return shape
# Subclass the settings module to provide an additional
# setting to enable pythonOCC when available
class settings(ifcopenshell_wrapper.settings):
if has_occ:
USE_PYTHON_OPENCASCADE = -1
def set(self, *args):
setting, value = args
if setting == settings.USE_PYTHON_OPENCASCADE:
self.set(settings.USE_BREP_DATA, value)
self.set(settings.USE_WORLD_COORDS, value)
self.set(settings.DISABLE_TRIANGULATION, value)
self.use_python_opencascade = value
else:
ifcopenshell_wrapper.settings.set(self, *args)
# Assert templated precision to match Python's internal float type
assert ifcopenshell_wrapper.iterator_double_precision.mantissa_size() == sys.float_info.mant_dig
_iterator = ifcopenshell_wrapper.iterator_double_precision
# Make sure people are able to use python's platform agnostic paths
class iterator(_iterator):
def __init__(self, settings, file_or_filename, num_threads = 1):
self.settings = settings
if isinstance(file_or_filename, file):
file_or_filename = file_or_filename.wrapped_data
else:
file_or_filename = os.path.abspath(file_or_filename)
_iterator.__init__(self, settings, file_or_filename, num_threads)
if has_occ:
def get(self):
return wrap_shape_creation(self.settings, _iterator.get(self))
def __iter__(self):
if self.initialize():
while True:
yield self.get()
if not self.next(): break
class tree(ifcopenshell_wrapper.tree):
def __init__(self, file=None, settings=None):
args = [self]
if file is not None:
args.append(file.wrapped_data)
if settings is not None:
args.append(settings)
ifcopenshell_wrapper.tree.__init__(*args)
def add_file(self, file, settings):
ifcopenshell_wrapper.tree.add_file(self, file.wrapped_data, settings)
def select(self, value, **kwargs):
def unwrap(value):
if isinstance(value, entity_instance):
return value.wrapped_data
elif all(map(lambda v: hasattr(value, v), "XYZ")):
return value.X(), value.Y(), value.Z()
return value
args = [self, unwrap(value)]
if isinstance(value, entity_instance):
args.append(kwargs.get("completely_within", False))
elif has_occ:
if isinstance(value, TopoDS.TopoDS_Shape):
args[1] = utils.serialize_shape(value)
return [entity_instance(e) for e in ifcopenshell_wrapper.tree.select(*args)]
def select_box(self, value, **kwargs):
def unwrap(value):
if isinstance(value, entity_instance):
return value.wrapped_data
elif hasattr(value, "Get"):
return value.Get()[:3], value.Get()[3:]
return value
args = [self, unwrap(value)]
if "extend" in kwargs or "completely_within" in kwargs:
args.append(kwargs.get("completely_within", False))
if "extend" in kwargs:
args.append(kwargs.get("extend", -1.e-5))
return [entity_instance(e) for e in ifcopenshell_wrapper.tree.select_box(*args)]
def create_shape(settings, inst, repr=None):
"""
Return a geometric representation from STEP-based IFCREPRESENTATIONSHAPE
or
Return an OpenCASCADE BRep if settings.USE_PYTHON_OPENCASCADE == True
example:
settings = ifcopenshell.geom.settings()
settings.set(settings.USE_PYTHON_OPENCASCADE, True)
ifc_file = ifcopenshell.open(file_path)
products = ifc_file.by_type("IfcProduct")
for i, product in enumerate(products):
if product.Representation is not None:
try:
shape = geom.create_shape(settings, inst=product).geometry
shape_gpXYZ = shape.Location().Transformation().TranslationPart() # These are methods of the TopoDS_Shape class from pythonOCC
print(shape_gpXYZ.X(), shape_gpXYZ.Y(), shape_gpXYZ.Z()) # These are methods of the gpXYZ class from pythonOCC
"""
return wrap_shape_creation(
settings,
ifcopenshell_wrapper.create_shape(
settings,
inst.wrapped_data,
repr.wrapped_data if repr is not None else None
))
def iterate(settings, filename):
it = iterator(settings, filename)
if it.initialize():
while True:
yield it.get()
if not it.next():
break
def make_shape_function(fn):
def entity_instance_or_none(e):
return None if e is None else entity_instance(e)
if has_occ:
def _(schema, string_or_shape, *args):
if isinstance(string_or_shape, TopoDS.TopoDS_Shape):
string_or_shape = utils.serialize_shape(string_or_shape)
return entity_instance_or_none(fn(schema, string_or_shape, *args))
else:
def _(schema, string, *args):
return entity_instance_or_none(fn(schema, string, *args))
return _
serialise = make_shape_function(ifcopenshell_wrapper.serialise)
tesselate = make_shape_function(ifcopenshell_wrapper.tesselate)
+233
View File
@@ -0,0 +1,233 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import random
import operator
import warnings
from collections import namedtuple, Iterable
try:
from OCC.Core import V3d, TopoDS, gp, AIS, Quantity, BRepTools, Graphic3d
except ImportError:
from OCC import V3d, TopoDS, gp, AIS, Quantity, BRepTools, Graphic3d
shape_tuple = namedtuple('shape_tuple', ('data', 'geometry', 'styles'))
handle, main_loop, add_menu, add_function_to_menu = None, None, None, None
DEFAULT_STYLES = {
"DEFAULT": (.7, .7, .7),
"IfcWall": (.8, .8, .8),
"IfcSite": (.75, .8, .65),
"IfcSlab": (.4, .4, .4),
"IfcWallStandardCase": (.9, .9, .9),
"IfcWall": (.9, .9, .9),
"IfcWindow": (.75, .8, .75, .3),
"IfcDoor": (.55, .3, .15),
"IfcBeam": (.75, .7, .7),
"IfcRailing": (.65, .6, .6),
"IfcMember": (.65, .6, .6),
"IfcPlate": (.8, .8, .8)
}
def initialize_display():
import OCC.Display.SimpleGui
global handle, main_loop, add_menu, add_function_to_menu
handle, main_loop, add_menu, add_function_to_menu = OCC.Display.SimpleGui.init_display()
def setup():
viewer_handle = handle.GetViewer()
viewer = viewer_handle.GetObject() if hasattr(viewer_handle, "GetObject") else viewer_handle
def lights():
viewer.InitActiveLights()
for _ in range(2):
try:
active_light = viewer.ActiveLight()
except BaseException:
break
yield active_light
viewer.NextActiveLights()
lights = list(lights())
for l in lights:
viewer.DelLight(l)
for dir in [V3d.V3d_TypeOfOrientation_Yup_AxoRight, V3d.V3d_TypeOfOrientation_Zup_AxoRight]:
light = V3d.V3d_DirectionalLight(viewer_handle)
light.SetDirection(dir)
viewer.SetLightOn(light)
setup()
return handle
def yield_subshapes(shape):
it = TopoDS.TopoDS_Iterator(shape)
while it.More():
yield it.Value()
it.Next()
def display_shape(shape, clr=None, viewer_handle=None):
if viewer_handle is None:
viewer_handle = handle
if isinstance(shape, shape_tuple):
shape, representation = shape.geometry, shape
else:
representation = None
material = Graphic3d.Graphic3d_MaterialAspect(Graphic3d.Graphic3d_NOM_PLASTER)
if representation and not clr:
if len(set(representation.styles)) == 1:
clr = representation.styles[0]
if min(clr) < 0. or max(clr) > 1.:
clr = DEFAULT_STYLES.get(representation.data.type, DEFAULT_STYLES["DEFAULT"])
if clr:
ais = AIS.AIS_Shape(shape)
ais.SetMaterial(material)
if isinstance(clr, str):
qclr = getattr(Quantity, "Quantity_NOC_%s" % clr.upper(),
getattr(Quantity, "Quantity_NOC_%s1" % clr.upper(), None))
if qclr is None:
raise Exception("No color named '%s'" % clr.upper())
elif isinstance(clr, Iterable):
clr = tuple(clr)
if len(clr) < 3 or len(clr) > 4:
raise Exception("Need 3 or 4 color components. Got '%r'." % len(clr))
qclr = Quantity.Quantity_Color(clr[0], clr[1], clr[2], Quantity.Quantity_TOC_RGB)
elif isinstance(clr, Quantity.Quantity_Color):
qclr = clr
else:
raise Exception("Object of type %r cannot be used as a color." % type(clr))
ais.SetColor(qclr)
if isinstance(clr, tuple) and len(clr) == 4 and clr[3] < 1.:
ais.SetTransparency(1. - clr[3])
elif representation and hasattr(AIS, "AIS_MultipleConnectedShape"):
default_style_applied = None
ais = AIS.AIS_MultipleConnectedShape(shape)
subshapes = list(yield_subshapes(shape))
lens = len(representation.styles), len(subshapes)
if lens[0] != lens[1]:
warnings.warn("Unable to assign styles to subshapes. Encountered %d styles for %d shapes." % lens)
else:
for shp, stl in zip(subshapes, representation.styles):
subshape = AIS.AIS_Shape(shp)
if min(stl) < 0. or max(stl) > 1.:
default_style_applied = stl = DEFAULT_STYLES.get(representation.data.type,
DEFAULT_STYLES["DEFAULT"])
subshape.SetColor(Quantity.Quantity_Color(stl[0], stl[1], stl[2], Quantity.Quantity_TOC_RGB))
subshape.SetMaterial(material)
if len(stl) == 4 and stl[3] < 1.:
subshape.SetTransparency(1. - stl[3])
ais.Connect(subshape.GetHandle())
# For some reason it is necessary to set transparency here again
# in order for transparency to be rendered on the subshape.
applied_styles = representation.styles
if default_style_applied:
if len(default_style_applied) == 3:
default_style_applied += (1.,)
applied_styles += (default_style_applied,)
if len(applied_styles):
# The only way for this not to be true if is the entire shape is NULL
min_transp = min(map(operator.itemgetter(3), applied_styles))
if min_transp < 1.:
ais.SetTransparency(1.)
else:
ais = AIS.AIS_Shape(shape)
ais.SetMaterial(material)
def r():
return random.random() * 0.3 + 0.7
clr = Quantity.Quantity_Color(r(), r(), r(), Quantity.Quantity_TOC_RGB)
ais.SetColor(clr)
ais_handle = ais
viewer_handle.Context.Display(ais_handle, False)
return ais_handle
def set_shape_transparency(ais, t):
handle.Context.SetTransparency(ais, t)
def get_bounding_box_center(bbox):
bbmin = [0.] * 3
bbmax = [0.] * 3
bbmin[0], bbmin[1], bbmin[2], bbmax[0], bbmax[1], bbmax[2] = bbox.Get()
return gp.gp_Pnt(*map(lambda xy: (xy[0] + xy[1]) / 2., zip(bbmin, bbmax)))
def serialize_shape(shape):
shapes = BRepTools.BRepTools_ShapeSet()
shapes.Add(shape)
return shapes.WriteToString()
def create_shape_from_serialization(brep_object):
brep_data, occ_shape, styles = None, None, ()
is_product_shape = True
try:
brep_data = brep_object.geometry.brep_data
styles = brep_object.geometry.surface_styles
except BaseException:
try:
brep_data = brep_object.brep_data
styles = brep_object.surface_styles
is_product_shape = False
except BaseException:
pass
styles = tuple(styles[i:i + 4] for i in range(0, len(styles), 4))
if not brep_data:
return shape_tuple(brep_object, None, styles)
try:
ss = BRepTools.BRepTools_ShapeSet()
ss.ReadFromString(brep_data)
occ_shape = ss.Shape(ss.NbShapes())
except BaseException:
pass
if is_product_shape:
return shape_tuple(brep_object, occ_shape, styles)
else:
return occ_shape
+57
View File
@@ -0,0 +1,57 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import uuid
import string
from functools import reduce
chars = string.digits + string.ascii_uppercase + string.ascii_lowercase + '_$'
def compress(g):
bs = [int(g[i:i + 2], 16) for i in range(0, len(g), 2)]
def b64(v, l=4):
return ''.join([chars[(v // (64 ** i)) % 64] for i in range(l)][::-1])
return ''.join([b64(bs[0], 2)] + [b64((bs[i] << 16) + (bs[i + 1] << 8) + bs[i + 2]) for i in range(1, 16, 3)])
def expand(g):
def b64(v):
return reduce(lambda a, b: a * 64 + b, map(lambda c: chars.index(c), v))
bs = [b64(g[0:2])]
for i in range(5):
d = b64(g[2 + 4 * i:6 + 4 * i])
bs += [(d >> (8 * (2 - j))) % 256 for j in range(3)]
return ''.join(['%02x' % b for b in bs])
def split(g):
return '{%s-%s-%s-%s-%s}' % (g[:8], g[8:12], g[12:16], g[16:20], g[20:])
def new():
return compress(uuid.uuid4().hex)
File diff suppressed because it is too large Load Diff
+27
View File
@@ -0,0 +1,27 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from . import ifcopenshell_wrapper
version = ifcopenshell_wrapper.version()
get_log = ifcopenshell_wrapper.get_log
+86
View File
@@ -0,0 +1,86 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import time
import uuid
from .file import file
from .guid import compress
from . import main
# A quick way to setup an 'empty' IFC file, taken from:
# http://academy.ifcopenshell.org/creating-a-simple-wall-with-property-set-and-quantity-information/
TEMPLATE = """ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');
FILE_NAME('%(filename)s','%(timestring)s',('%(creator)s'),('%(organization)s'),'%(application)s','%(application)s','');
FILE_SCHEMA(('%(schema_identifier)s'));
ENDSEC;
DATA;
#1=IFCPERSON($,$,'%(creator)s',$,$,$,$,$);
#2=IFCORGANIZATION($,'%(organization)s',$,$,$);
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
#4=IFCAPPLICATION(#2,'%(application_version)s','%(application)s','');
#5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,$,#3,#4,%(timestamp)s);
#6=IFCDIRECTION((1.,0.,0.));
#7=IFCDIRECTION((0.,0.,1.));
#8=IFCCARTESIANPOINT((0.,0.,0.));
#9=IFCAXIS2PLACEMENT3D(#8,#7,#6);
#10=IFCDIRECTION((0.,1.,0.));
#11=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,#10);
#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
#13=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
#14=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#15=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#16=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16);
#18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17);
#19=IFCUNITASSIGNMENT((#13,#14,#15,#18));
#20=IFCPROJECT('%(project_globalid)s',#5,'%(project_name)s',$,$,$,$,(#11),#19);
ENDSEC;
END-ISO-10303-21;
"""
DEFAULTS = {
"application": lambda d: 'IfcOpenShell-%s' % main.version,
"application_version": lambda d: main.version,
"project_globalid": lambda d: compress(uuid.uuid4().hex),
"schema_identifier": lambda d: main.schema_identifier,
"timestamp": lambda d: int(time.time()),
"timestring": lambda d: time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(d.get('timestamp') or time.time()))
}
def create(filename=None, timestring=None, organization=None, creator=None,
schema_identifier=None, application_version=None, timestamp=None,
application=None, project_globalid=None, project_name=None):
d = dict(locals())
def _():
for var, value in d.items():
if value is None:
yield var, DEFAULTS.get(var, lambda *args: '')(d)
d.update(dict(_()))
return file.from_string(TEMPLATE % d)
View File
+35
View File
@@ -0,0 +1,35 @@
def get_psets(element):
psets = {}
try:
if element.is_a('IfcTypeObject'):
if element.HasPropertySets:
for definition in element.HasPropertySets:
psets[definition.Name] = get_properties(definition)
else:
for relationship in element.IsDefinedBy:
if relationship.is_a('IfcRelDefinesByProperties'):
definition = relationship.RelatingPropertyDefinition
psets[definition.Name] = get_properties(definition)
except Exception as e:
import traceback
print('failed to load properties: {}'.format(e))
traceback.print_exc()
return psets
def get_properties(definition):
if definition is not None:
props = {}
if definition.is_a('IfcElementQuantity'):
for q in definition.Quantities:
if q.is_a('IfcPhysicalSimpleQuantity'):
props[q.Name] = q[3]
elif definition.is_a('IfcPropertySet'):
for prop in definition.HasProperties:
if prop.is_a('IfcPropertySingleValue'):
props[prop.Name] = prop.NominalValue
else:
# Entity introduced in IFC4
# definition.is_a('IfcPreDefinedPropertySet'):
for prop in range(4, len(definition)):
props[definition.attribute_name(prop)] = definition[prop]
return props
+26
View File
@@ -0,0 +1,26 @@
import math
def dms2dd(degrees, minutes, seconds, milliseconds=0):
dd = float(degrees) + float(minutes)/60.0 + float(seconds)/(3600.0) + float(milliseconds/3600000.0)
return dd
def dd2dms(dd):
dd = float(dd)
sign = 1 if dd >= 0 else -1
dd = abs(dd)
minutes, seconds = divmod(dd*3600, 60)
degrees, minutes = divmod(minutes, 60)
if dd < 0:
degrees = -degrees
return (int(degrees) * sign, int(minutes) * sign, int(seconds) * sign)
def xyz2enh(x, y, z, eastings, northings, orthogonal_height, x_axis_abscissa, x_axis_ordinate, scale=None):
if scale is None:
scale = 1.
rotation = math.atan2(x_axis_ordinate, x_axis_abscissa)
a = scale * math.cos(rotation)
b = scale * math.sin(rotation)
eastings = (a * x) - (b * y) + eastings
northings = (b * x) + (a * y) + northings
height = z + orthogonal_height
return (eastings, northings, height)
+156
View File
@@ -0,0 +1,156 @@
import lark
class Selector():
def parse(self, ifc_file, query):
self.file = ifc_file
l = lark.Lark('''start: query (lfunction query)*
query: selector | group
group: "(" query (lfunction query)* ")"
selector: (inverse_relationship)? guid_selector | (inverse_relationship)? class_selector
guid_selector: "#" /[0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$]{22}/
class_selector: "." WORD filter ?
filter: "[" filter_key (comparison filter_value)? "]"
filter_key: WORD | pset_or_qto
filter_value: ESCAPED_STRING
pset_or_qto: /[A-Za-z0-9_]+/ "." /[A-Za-z0-9_]+/
lfunction: and | or
inverse_relationship: types | contains_elements
types: "*"
contains_elements: "@"
and: "&"
or: "|"
comparison: contains | morethanequalto | lessthanequalto | equal | morethan | lessthan
contains: "*="
morethanequalto: ">="
lessthanequalto: "<"
equal: "="
morethan: ">"
lessthan: "<"
// Embed common.lark for packaging
DIGIT: "0".."9"
HEXDIGIT: "a".."f"|"A".."F"|DIGIT
INT: DIGIT+
SIGNED_INT: ["+"|"-"] INT
DECIMAL: INT "." INT? | "." INT
_EXP: ("e"|"E") SIGNED_INT
FLOAT: INT _EXP | DECIMAL _EXP?
SIGNED_FLOAT: ["+"|"-"] FLOAT
NUMBER: FLOAT | INT
SIGNED_NUMBER: ["+"|"-"] NUMBER
_STRING_INNER: /.*?/
_STRING_ESC_INNER: _STRING_INNER /(?<!\\\\)(\\\\\\\\)*?/
ESCAPED_STRING : "\\"" _STRING_ESC_INNER "\\""
LCASE_LETTER: "a".."z"
UCASE_LETTER: "A".."Z"
LETTER: UCASE_LETTER | LCASE_LETTER
WORD: LETTER+
CNAME: ("_"|LETTER) ("_"|LETTER|DIGIT)*
WS_INLINE: (" "|/\\t/)+
WS: /[ \\t\\f\\r\\n]/+
CR : /\\r/
LF : /\\n/
NEWLINE: (CR? LF)+
%ignore WS // Disregard spaces in text
''')
start = l.parse(query)
return self.get_group(start)
def get_group(self, group):
lfunction = None
for child in group.children:
if child.data == 'query':
new_results = self.get_query(child)
if not lfunction:
results = new_results
elif lfunction == 'or':
results.extend(new_results)
elif lfunction == 'and':
results = list(set(results).intersection(new_results))
results = list(set(results))
elif child.data == 'lfunction':
lfunction = child.children[0].data
return results
def get_query(self, query):
for child in query.children:
if child.data == 'selector':
return self.get_selector(child)
elif child.data == 'group':
return self.get_group(child)
def get_selector(self, selector):
if len(selector.children) == 1:
inverse_relationship = None
class_or_guid_selector = selector.children[0]
else:
inverse_relationship = selector.children[0]
class_or_guid_selector = selector.children[1]
if class_or_guid_selector.data == 'class_selector':
results = self.get_class_selector(class_or_guid_selector)
elif class_or_guid_selector.data == 'guid_selector':
results = self.get_guid_selector(class_or_guid_selector)
if not inverse_relationship:
return results
return self.parse_inverse_relationship(results, inverse_relationship.children[0].data)
def parse_inverse_relationship(self, elements, inverse_relationship):
results = []
for element in elements:
if inverse_relationship == 'types':
if hasattr(element, 'Types') and element.Types:
results.extend(element.Types[0].RelatedObjects)
elif hasattr(element, 'ObjectTypeOf') and element.ObjectTypeOf:
results.extend(element.ObjectTypeOf[0].RelatedObjects)
elif inverse_relationship == 'contains_elements' \
and hasattr(element, 'ContainsElements'):
for relationship in element.ContainsElements:
results.extend(relationship.RelatedElements)
return results
def get_class_selector(self, class_selector):
elements = self.file.by_type(class_selector.children[0])
if len(class_selector.children) > 1 \
and class_selector.children[1].data == 'filter':
return self.filter_elements(elements, class_selector.children[1])
return elements
def filter_elements(self, elements, filter_rule):
results = []
key = filter_rule.children[0].children[0]
if not isinstance(key, str):
key = key.children[0] + '.' + key.children[1]
comparison = value = None
if len(filter_rule.children) > 1:
comparison = filter_rule.children[1].children[0].data
value = filter_rule.children[2].children[0][1:-1]
for element in elements:
element_value = IfcAttributeExtractor.get_element_key(element, key)
if not element_value:
continue
if not comparison \
or self.filter_element(element, element_value, comparison, value):
results.append(element)
return results
def filter_element(self, element, element_value, comparison, value):
if comparison == 'equal':
return str(element_value) == value
elif comparison == 'contains':
return value in str(element_value)
elif comparison == 'morethan':
return element_value > float(value)
elif comparison == 'lessthan':
return element_value < float(value)
elif comparison == 'morethanequalto':
return element_value >= float(value)
elif comparison == 'lessthanequalto':
return element_value <= float(value)
return False
def get_guid_selector(self, guid_selector):
return [self.file.by_id(guid_selector.children[0])]
+64
View File
@@ -0,0 +1,64 @@
from math import pi
prefixes = {'EXA': 1e18, 'PETA': 1e15, 'TERA': 1e12, 'GIGA': 1e9, 'MEGA':
1e6, 'KILO': 1e3, 'HECTO': 1e2, 'DECA': 1e1, 'DECI': 1e-1, 'CENTI':
1e-2, 'MILLI': 1e-3, 'MICRO': 1e-6, 'NANO': 1e-9, 'PICO': 1e-12,
'FEMTO': 1e-15, 'ATTO': 1e-18}
unit_names = ['AMPERE', 'BECQUEREL', 'CANDELA', 'COULOMB',
'CUBIC_METRE', 'DEGREE CELSIUS', 'FARAD', 'GRAM', 'GRAY', 'HENRY',
'HERTZ', 'JOULE', 'KELVIN', 'LUMEN', 'LUX', 'MOLE', 'NEWTON', 'OHM',
'PASCAL', 'RADIAN', 'SECOND', 'SIEMENS', 'SIEVERT', 'SQUARE METRE',
'METRE', 'STERADIAN', 'TESLA', 'VOLT', 'WATT', 'WEBER']
si_conversions = {
'inch': 0.0254,
'foot': 0.3048,
'yard': 0.914,
'mile': 1609,
'square inch': 0.0006452,
'square foot': 0.09290,
'square yard': 0.83612736,
'acre': 4046.86,
'square mile': 2588881,
'cubic inch': 0.00001639,
'cubic foot': 0.02832,
'cubic yard': 0.7636,
'litre': 0.001,
'fluid ounce UK': 0.0000284130625,
'fluid ounce US': 0.00002957353,
'pint UK': 0.000568,
'pint US': 0.000473,
'gallon UK': 0.004546,
'gallon US': 0.003785,
'degree': pi/180,
'ounce': 0.02835,
'pound': 0.454,
'ton UK': 1016.0469088,
'ton US': 907.18474,
'lbf': 4.4482216153,
'kip': 4448.2216153,
'psi': 6894.7572932,
'ksi': 6894757.2932,
'minute': 60,
'hour': 3600,
'day': 86400,
'btu': 1055.056}
def get_prefix(text):
for prefix in prefixes.keys():
if prefix in text.upper():
return prefix
def get_prefix_multiplier(text):
if not text:
return 1
prefix = get_prefix(text)
if prefix:
return prefixes[prefix]
return 1
def get_unit_name(text):
for name in unit_names:
if name in text.upper().replace('METER', 'METRE'):
return name
+109
View File
@@ -0,0 +1,109 @@
from __future__ import print_function
import ifcopenshell
named_type = ifcopenshell.ifcopenshell_wrapper.named_type
aggregation_type = ifcopenshell.ifcopenshell_wrapper.aggregation_type
simple_type = ifcopenshell.ifcopenshell_wrapper.simple_type
type_declaration = ifcopenshell.ifcopenshell_wrapper.type_declaration
enumeration_type = ifcopenshell.ifcopenshell_wrapper.enumeration_type
entity_type = ifcopenshell.ifcopenshell_wrapper.entity
select_type = ifcopenshell.ifcopenshell_wrapper.select_type
attribute = ifcopenshell.ifcopenshell_wrapper.attribute
class ValidationError(Exception): pass
simple_type_python_mapping = {
# @todo should include unicode for Python2
"string": str,
"integer": int,
"real": float,
"number": float,
"boolean": bool,
"logical": bool, # still not implemented in IfcOpenShell
"binary": str # maps to a str of "0" and "1"
}
def assert_valid_inverse(attr, val):
b1, b2 = attr.bound1(), attr.bound2()
invalid = len(val) < b1 or (b2 != -1 and len(val) > b2)
if invalid:
raise ValidationError("%r not valid for %s" % (val, attr))
return True
def assert_valid(attr, val):
if isinstance(attr, attribute):
attr_type = attr.type_of_attribute()
else:
attr_type = attr
type_wrappers = (named_type,)
if not isinstance(val, ifcopenshell.entity_instance):
# If val is not an entity instance we need to
# flatten the type declaration to something that
# maps to the python types
type_wrappers += (type_declaration,)
while isinstance(attr_type, type_wrappers):
attr_type = attr_type.declared_type()
if isinstance(attr_type, simple_type):
invalid = type(val) != simple_type_python_mapping[attr_type.declared_type()]
elif isinstance(attr_type, (entity_type, type_declaration)):
invalid = not isinstance(val, ifcopenshell.entity_instance) or not val.is_a(attr_type.name())
elif isinstance(attr_type, select_type):
invalid = not any(try_valid(x, val) for x in attr_type.select_list())
elif isinstance(attr_type, enumeration_type):
invalid = val not in attr_type.enumeration_items()
elif isinstance(attr_type, aggregation_type):
b1, b2 = attr_type.bound1(), attr_type.bound2()
ty = attr_type.type_of_element()
invalid = len(val) < b1 or (b2 != -1 and len(val) > b2) or not all(assert_valid(ty, v) for v in val)
else:
raise NotImplementedError("Not impl %s %s" % (type(attr_type), attr_type))
if invalid:
raise ValidationError("%r not valid for %s" % (val, attr))
return True
def try_valid(attr, val):
try:
return assert_valid(attr, val)
except ValidationError as e:
return False
def validate(f, logger):
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(f.schema)
for inst in f:
entity = schema.declaration_by_name(inst.is_a())
for attr, val, is_derived in zip(entity.all_attributes(), inst, entity.derived()):
if val is None and not (is_derived or attr.optional()):
logger.error("Attribute %s.%s not optional" % (entity, attr))
if val is not None:
attr_type = attr.type_of_attribute()
try:
assert_valid(attr, val)
except ValidationError as e:
logger.error('In {}\n{}'.format(inst, e))
for attr in entity.all_inverse_attributes():
val = getattr(inst, attr.name())
try:
assert_valid_inverse(attr, val)
except ValidationError as e:
logger.error('In {}\n{}'.format(inst, e))
if __name__ == "__main__":
import sys
import logging
for fn in sys.argv[1:]:
logger = logging.getLogger('validate')
logger.setLevel(logging.DEBUG)
print("Validating", fn)
validate(ifcopenshell.open(fn), logger)
+9
View File
@@ -50,6 +50,8 @@
#include <boost/make_shared.hpp>
#include <fstream>
#include <iostream>
#include <sstream>
#include <set>
#include <time.h>
@@ -1295,7 +1297,14 @@ namespace latebound_access {
}
void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
Logger::Status("HLEEEEEEEE");
std::ofstream outfile("test78.txt");
outfile << "my text here!" << std::endl;
outfile.close();
{
auto delete_reversed = [&f](const IfcEntityList::ptr& insts) {
if (!insts) {
return;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+177
View File
@@ -0,0 +1,177 @@
This script fetches and builds all IfcOpenShell dependencies
Generator not passed but VisualStudioVersion=15.0 environment variable detected:
using `Visual Studio 15 2017 Win64` as the generator.
build-type-cfg.cmd: Warning: BUILD_CFG not specified - using the default RelWithDebInfo
Script configuration:
* CMake Generator = `Visual Studio 15 2017 Win64`
- Passed to CMake -G option.
* Target Architecture = x64
- Whether were doing 32-bit (x86) or 64-bit (x64) build.
* Dependency Directory = C:\Users\jlutt\Documents\IfcOpenShell\deps
- The directory where IfcOpenShell dependencies are fetched and built.
* Installation Directory = C:\Users\jlutt\Documents\IfcOpenShell\deps-vs2017-x64-installed
- The directory where IfcOpenShell dependencies are installed.
* Build Config Type = RelWithDebInfo
- The used build configuration type for the dependencies.
Defaults to RelWithDebInfo if not specified.
* Build Type = Build
- The used build type for the dependencies (Build, Rebuild, Clean).
Defaults to Build if not specified. Rebuild/Clean also uninstalls Python (if it was installed by this script).
* IFCOS_USE_OCCT = TRUE
- Use the official Open CASCADE instead of the community edition.
* IFCOS_INSTALL_PYTHON = TRUE
- Download and install Python.
Set to something other than TRUE if you wish to use an already installed version of Python.
* IFCOS_USE_PYTHON2 = FALSE
- Use Python 2 instead of 3.
Set to TRUE if you wish to use Python 2 instead of 3. Has no effect if IFCOS_INSTALL_PYTHON is not TRUE.
* IFCOS_NUM_BUILD_PROCS = 8
- How many MSBuild.exe processes may be run in parallel.
Defaults to NUMBER_OF_PROCESSORS. Used also by other IfcOpenShell build scripts.
Requirements for a successful execution:
1. Install PowerShell (preinstalled in Windows >= 7) version 5 or higher and make sure 'powershell' is accessible from PATH.
- https://support.microsoft.com/en-us/kb/968929
2. Install Git and make sure 'git' is accessible from PATH.
- https://git-for-windows.github.io/
3. Install CMake and make sure 'cmake' is accessible from PATH.
- http://www.cmake.org/
4. Visual Studio 2008 or newer (2013 or newer recommended) with C++ toolset.
- https://www.visualstudio.com/
5. Run this batch script with Visual Studio environment variables set.
- https://msdn.microsoft.com/en-us/library/ms229859(v=vs.110).aspx
NB: This script needs to be ran from the directory directly containing it.
Warning: You will need roughly 8 GB of disk space to proceed (VS 2015 x64 RelWithDebInfo).
If you are not ready with the above: type 'n' in the prompt below. Build proceeds on all other inputs
>
Build started at 7:40:11.47.
Boost 1.67.0 already downloaded. Skipping.
Boost 1.67.0 already extracted into C:\Users\jlutt\Documents\IfcOpenShell\deps\boost_1_67_0. Skipping.
Building Boost 1.67.0 --with-system --with-regex --with-thread --with-program_options --with-date_time --with-iostreams --with-filesystem Please be patient this will take a while.
Performing configuration checks
- default address-model : none
- default architecture : none
- symlinks supported : no
- junctions supported : yes
- hardlinks supported : yes
- zlib : no
- bzip2 : no
- lzma : no
- has_icu builds : no
Component configuration:
- atomic : not building
- chrono : not building
- container : not building
- context : not building
- contract : not building
- coroutine : not building
- date_time : building
- exception : not building
- fiber : not building
- filesystem : building
- graph : not building
- graph_parallel : not building
- iostreams : building
- locale : not building
- log : not building
- math : not building
- mpi : not building
- program_options : building
- python : not building
- random : not building
- regex : building
- serialization : not building
- signals : not building
- stacktrace : not building
- system : building
- test : not building
- thread : building
- timer : not building
- type_erasure : not building
- wave : not building
...patience...
...patience...
...found 1696 targets...
...updating 16 targets...
...skipped <pbin.v2\libs\date_time\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>gregorian\greg_month.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\date_time\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>gregorian\greg_weekday.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\date_time\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>gregorian\date_generators.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\date_time\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_date_time-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\date_time\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>gregorian\greg_month.obj...
...skipped <pstage\vs2017-x64\lib>libboost_date_time-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\date_time\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_date_time-vc141-mt-s-1_67.lib...
...skipped <pbin.v2\libs\system\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>error_code.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\system\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_system-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\system\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>error_code.obj...
...skipped <pstage\vs2017-x64\lib>libboost_system-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\system\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_system-vc141-mt-s-1_67.lib...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>codecvt_error_category.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>operations.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>path.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>path_traits.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>portability.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>unique_path.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>utf8_codecvt_facet.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>windows_file_codecvt.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_filesystem-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>codecvt_error_category.obj...
...skipped <pstage\vs2017-x64\lib>libboost_filesystem-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\filesystem\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_filesystem-vc141-mt-s-1_67.lib...
...skipped <pbin.v2\libs\iostreams\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>file_descriptor.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\iostreams\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>mapped_file.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\iostreams\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_iostreams-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\iostreams\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>file_descriptor.obj...
...skipped <pstage\vs2017-x64\lib>libboost_iostreams-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\iostreams\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_iostreams-vc141-mt-s-1_67.lib...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>cmdline.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>config_file.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>options_description.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>parsers.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>variables_map.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>value_semantic.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>positional_options.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>utf8_codecvt_facet.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>convert.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>winmain.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>split.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_program_options-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>cmdline.obj...
...skipped <pstage\vs2017-x64\lib>libboost_program_options-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\program_options\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_program_options-vc141-mt-s-1_67.lib...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>c_regex_traits.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>cpp_regex_traits.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>cregex.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>fileiter.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>icu.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>instances.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>posix_api.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>regex.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>regex_debug.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>regex_raw_buffer.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>regex_traits_defaults.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>static_mutex.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>w32_regex_traits.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>wc_regex_traits.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>wide_posix_api.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>winstances.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>usinstances.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_regex-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>c_regex_traits.obj...
...skipped <pstage\vs2017-x64\lib>libboost_regex-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\regex\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_regex-vc141-mt-s-1_67.lib...
...skipped <pbin.v2\libs\chrono\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>chrono.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\chrono\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>thread_clock.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\chrono\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>process_cpu_clocks.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\chrono\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_chrono-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\chrono\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>chrono.obj...
...skipped <pstage\vs2017-x64\lib>libboost_chrono-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\chrono\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threading-multi>libboost_chrono-vc141-mt-s-1_67.lib...
...skipped <pbin.v2\libs\thread\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threadapi-win32\threading-multi>win32\thread.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\thread\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threadapi-win32\threading-multi>win32\tss_dll.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\thread\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threadapi-win32\threading-multi>win32\tss_pe.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\thread\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threadapi-win32\threading-multi>win32\thread_primitives.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\thread\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threadapi-win32\threading-multi>future.obj for lack of <pbin.v2\standalone\msvc\msvc-14.1\address-model-64>msvc-setup.nup...
...skipped <pbin.v2\libs\thread\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threadapi-win32\threading-multi>libboost_thread-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\thread\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threadapi-win32\threading-multi>win32\thread.obj...
...skipped <pstage\vs2017-x64\lib>libboost_thread-vc141-mt-s-1_67.lib for lack of <pbin.v2\libs\thread\build\msvc-14.1\release\address-model-64\link-static\runtime-link-static\threadapi-win32\threading-multi>libboost_thread-vc141-mt-s-1_67.lib...
...skipped 66 targets...
An error occurred
Build ended at 7:40:17.03. Time elapsed 0:00:05.56.
+4
View File
@@ -62,6 +62,10 @@ pushd ..\%BUILD_DIR%
set BOOST_VERSION=1.67.0
set BOOST_VER=%BOOST_VERSION:.=_%
echo "TEEEEEEEEEEEST"
echo %OCC_INCLUDE_DIR%
set BOOST_ROOT=%DEPS_DIR%\boost_%BOOST_VER%
set BOOST_LIBRARYDIR=%BOOST_ROOT%\stage\vs%VS_VER%-%VS_PLATFORM%\lib
if not defined OCC_INCLUDE_DIR set OCC_INCLUDE_DIR=%INSTALL_DIR%\oce\include\oce