mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-20 12:12:15 +00:00
Merge developments from the python_wrapper branch into master
This commit is contained in:
@@ -62,11 +62,13 @@ bpy.types.Object.ifc_type = StringProperty(name="IFC Entity Type",
|
||||
description="The STEP Datatype keyword")
|
||||
|
||||
|
||||
def import_ifc(filename, use_names, process_relations):
|
||||
def import_ifc(filename, use_names, process_relations, blender_booleans):
|
||||
from . import ifcopenshell
|
||||
from .ifcopenshell import geom as ifcopenshell_geom
|
||||
print("Reading %s..."%bpy.path.basename(filename))
|
||||
settings = ifcopenshell.IteratorSettings()
|
||||
iterator = ifcopenshell.Iterator(settings, filename)
|
||||
settings = ifcopenshell_geom.settings()
|
||||
settings.set(settings.DISABLE_OPENING_SUBTRACTIONS, blender_booleans)
|
||||
iterator = ifcopenshell_geom.iterator(settings, filename)
|
||||
valid_file = iterator.findContext()
|
||||
if not valid_file:
|
||||
return False
|
||||
@@ -74,6 +76,7 @@ def import_ifc(filename, use_names, process_relations):
|
||||
id_to_object = {}
|
||||
id_to_parent = {}
|
||||
id_to_matrix = {}
|
||||
openings = []
|
||||
old_progress = -1
|
||||
print("Creating geometry...")
|
||||
while True:
|
||||
@@ -139,8 +142,10 @@ def import_ifc(filename, use_names, process_relations):
|
||||
bob.ifc_id, bob.ifc_guid, bob.ifc_name, bob.ifc_type = \
|
||||
ob.id, ob.guid, ob.name, ob.type
|
||||
|
||||
bob.hide = ob.type == 'IfcSpace' or ob.type == 'IfcOpeningElement'
|
||||
bob.hide_render = bob.hide
|
||||
if ob.type == 'IfcSpace' or ob.type == 'IfcOpeningElement':
|
||||
if not (ob.type == 'IfcOpeningElement' and blender_booleans):
|
||||
bob.hide = bob.hide_render = True
|
||||
bob.draw_type = 'WIRE'
|
||||
|
||||
if ob.id not in id_to_object: id_to_object[ob.id] = []
|
||||
id_to_object[ob.id].append(bob)
|
||||
@@ -148,6 +153,9 @@ def import_ifc(filename, use_names, process_relations):
|
||||
if ob.parent_id > 0:
|
||||
id_to_parent[ob.id] = ob.parent_id
|
||||
|
||||
if blender_booleans and ob.type == 'IfcOpeningElement':
|
||||
openings.append(ob.id)
|
||||
|
||||
faces = me.polygons if hasattr(me, 'polygons') else me.faces
|
||||
if len(faces) == len(matids):
|
||||
for face, matid in zip(faces, matids):
|
||||
@@ -173,11 +181,11 @@ def import_ifc(filename, use_names, process_relations):
|
||||
if parent_id in id_to_object:
|
||||
bob = id_to_object[parent_id][0]
|
||||
else:
|
||||
parent_ob = iterator.GetObject(parent_id)
|
||||
parent_ob = iterator.getObject(parent_id)
|
||||
if parent_ob.id == -1:
|
||||
bob = None
|
||||
else:
|
||||
m = parent_ob.matrix
|
||||
m = parent_ob.transformation.matrix.data
|
||||
nm = parent_ob.name if len(parent_ob.name) and use_names \
|
||||
else parent_ob.guid
|
||||
bob = bpy.data.objects.new(nm, None)
|
||||
@@ -219,7 +227,16 @@ def import_ifc(filename, use_names, process_relations):
|
||||
|
||||
if process_relations:
|
||||
print("Done processing relations")
|
||||
|
||||
|
||||
for opening_id in openings:
|
||||
parent_id = id_to_parent[opening_id]
|
||||
if parent_id in id_to_object:
|
||||
parent_ob = id_to_object[parent_id][0]
|
||||
for opening_ob in id_to_object[opening_id]:
|
||||
mod = parent_ob.modifiers.new("opening", "BOOLEAN")
|
||||
mod.operation = "DIFFERENCE"
|
||||
mod.object = opening_ob
|
||||
|
||||
txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
|
||||
txt.from_string(iterator.getLog())
|
||||
|
||||
@@ -241,9 +258,13 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
|
||||
" relations to parenting" \
|
||||
" (warning: may be slow on large files)",
|
||||
default=False)
|
||||
blender_booleans = BoolProperty(name="Use Blender booleans",
|
||||
description="Use Blender boolean modifiers for opening" \
|
||||
" elements",
|
||||
default=False)
|
||||
|
||||
def execute(self, context):
|
||||
if not import_ifc(self.filepath, self.use_names, self.process_relations):
|
||||
if not import_ifc(self.filepath, self.use_names, self.process_relations, self.blender_booleans):
|
||||
self.report({'ERROR'},
|
||||
'Unable to parse .ifc file or no geometrical entities found'
|
||||
)
|
||||
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
void write(const IfcGeom::TriangulationElement<double>* o);
|
||||
void write(const IfcGeom::ShapeModelElement<double>* o) {}
|
||||
void write(const IfcGeom::BRepElement<double>* o) {}
|
||||
void finalize();
|
||||
bool isTesselated() const { return true; }
|
||||
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
virtual bool isTesselated() const = 0;
|
||||
virtual ~GeometrySerializer() {}
|
||||
virtual void write(const IfcGeom::TriangulationElement<double>* o) = 0;
|
||||
virtual void write(const IfcGeom::ShapeModelElement<double>* o) = 0;
|
||||
virtual void write(const IfcGeom::BRepElement<double>* o) = 0;
|
||||
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
if (convert_back_units) {
|
||||
serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), context_iterator.getUnitMagnitude());
|
||||
serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast<const float>(context_iterator.getUnitMagnitude()));
|
||||
} else {
|
||||
serializer->setUnitNameAndMagnitude("METER", 1.0f);
|
||||
}
|
||||
@@ -274,7 +274,7 @@ int main(int argc, char** argv) {
|
||||
if (serializer->isTesselated()) {
|
||||
serializer->write(static_cast<const IfcGeom::TriangulationElement<double>*>(geom_object));
|
||||
} else {
|
||||
serializer->write(static_cast<const IfcGeom::ShapeModelElement<double>*>(geom_object));
|
||||
serializer->write(static_cast<const IfcGeom::BRepElement<double>*>(geom_object));
|
||||
}
|
||||
|
||||
const int progress = context_iterator.progress() / 2;
|
||||
|
||||
@@ -34,7 +34,7 @@ bool OpenCascadeBasedSerializer::ready() {
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
void OpenCascadeBasedSerializer::write(const IfcGeom::ShapeModelElement<double>* o) {
|
||||
void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement<double>* o) {
|
||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
|
||||
gp_GTrsf gtrsf = it->Placement();
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
bool ready();
|
||||
virtual void writeShape(const TopoDS_Shape& shape) = 0;
|
||||
void write(const IfcGeom::TriangulationElement<double>* o) {}
|
||||
void write(const IfcGeom::ShapeModelElement<double>* o);
|
||||
void write(const IfcGeom::BRepElement<double>* o);
|
||||
bool isTesselated() const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
void writeHeader();
|
||||
void writeMaterial(const IfcGeom::Material& style);
|
||||
void write(const IfcGeom::TriangulationElement<double>* o);
|
||||
void write(const IfcGeom::ShapeModelElement<double>* o) {}
|
||||
void write(const IfcGeom::BRepElement<double>* o) {}
|
||||
void finalize() {}
|
||||
bool isTesselated() const { return true; }
|
||||
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {}
|
||||
|
||||
@@ -170,6 +170,8 @@ import mapping
|
||||
import header
|
||||
import enum_header
|
||||
import implementation
|
||||
import latebound_header
|
||||
import latebound_implementation
|
||||
|
||||
syntax.ignore(Regex(r"\((?:\*(?:[^*]*\*+)+?\))"))
|
||||
ast = syntax.parseFile(sys.argv[1])
|
||||
@@ -179,4 +181,6 @@ mapping = mapping.Mapping(schema)
|
||||
header.Header(mapping).emit()
|
||||
enum_header.EnumHeader(mapping).emit()
|
||||
implementation.Implementation(mapping).emit()
|
||||
latebound_header.LateBoundHeader(mapping).emit()
|
||||
latebound_implementation.LateBoundImplementation(mapping).emit()
|
||||
"""%('\n'.join(statements)))
|
||||
|
||||
@@ -21,8 +21,7 @@ import templates
|
||||
|
||||
class EnumHeader:
|
||||
def __init__(self, mapping):
|
||||
selectable_simple_types = sorted(set(sum([b.values for a,b in mapping.schema.selects.items()], [])) & set(mapping.schema.types.keys()))
|
||||
enumerable_types = selectable_simple_types + [name for name, type in mapping.schema.entities.items()]
|
||||
enumerable_types = sorted(set([name for name, type in mapping.schema.types.items()] + [name for name, type in mapping.schema.entities.items()]))
|
||||
|
||||
self.str = templates.enum_header % {
|
||||
'schema_name_upper' : mapping.schema.name.upper(),
|
||||
|
||||
@@ -22,34 +22,34 @@ import documentation
|
||||
|
||||
class Header:
|
||||
def __init__(self, mapping):
|
||||
emitted_types = set(mapping.express_to_cpp_typemapping.values())
|
||||
declarations = []
|
||||
|
||||
write = lambda str, **kwargs: declarations.append(str%dict({
|
||||
'documentation': templates.multi_line_comment(documentation.description(kwargs['name']))}, **kwargs))
|
||||
|
||||
for name, type in mapping.schema.simpletypes.items():
|
||||
type_str = mapping.make_type_string(type)
|
||||
type_dep = mapping.get_type_dep(type)
|
||||
if type_dep in emitted_types:
|
||||
write(templates.simpletype, name=name, type=type_str)
|
||||
emitted_types.add(name)
|
||||
|
||||
|
||||
forward_names = list(mapping.schema.entities.keys()) + list(mapping.schema.simpletypes.keys())
|
||||
forward_definitions = "".join(["class %s; "%n for n in forward_names])
|
||||
|
||||
for name, type in mapping.schema.selects.items():
|
||||
write(templates.select, name=name)
|
||||
emitted_types.add(name)
|
||||
|
||||
for name, type in mapping.schema.simpletypes.items():
|
||||
if name not in emitted_types:
|
||||
type_str = mapping.make_type_string(type)
|
||||
write(templates.simpletype, name=name, type=type_str)
|
||||
emitted_types.add(name)
|
||||
|
||||
for name, type in mapping.schema.enumerations.items():
|
||||
short_name = name[:-4] if name.endswith("Enum") else name
|
||||
write(templates.enumeration, name=name, values=", ".join(["%s_%s"%(short_name, v) for v in type.values]))
|
||||
|
||||
forward_definitions = "".join(["class %s; "%n for n in mapping.schema.entities.keys()])
|
||||
|
||||
emitted_simpletypes = set()
|
||||
while len(emitted_simpletypes) < len(mapping.schema.simpletypes):
|
||||
for name, type in mapping.schema.simpletypes.items():
|
||||
if name in emitted_simpletypes: continue
|
||||
type_str = mapping.make_type_string(mapping.flatten_type_string(type))
|
||||
attr_type = mapping.make_argument_type(type)
|
||||
superclass = mapping.simple_type_parent(name)
|
||||
if superclass is None:
|
||||
superclass = "IfcUtil::IfcBaseType"
|
||||
elif superclass not in emitted_simpletypes:
|
||||
continue
|
||||
emitted_simpletypes.add(name)
|
||||
write(templates.simpletype, name=name, type=type_str, attr_type=attr_type, superclass=superclass)
|
||||
|
||||
class_definitions = []
|
||||
|
||||
|
||||
@@ -71,10 +71,11 @@ class Implementation:
|
||||
|
||||
def find_template(arg):
|
||||
simple = mapping.schema.is_simpletype(arg['list_instance_type'])
|
||||
select = arg['list_instance_type'] == "IfcUtil::IfcBaseClass"
|
||||
express = arg['list_instance_type'] in mapping.express_to_cpp_typemapping
|
||||
if arg['is_enum']: return templates.get_attr_stmt_enum
|
||||
elif arg['is_nested']: return templates.get_attr_stmt_nested_array
|
||||
elif arg['is_array'] and not (simple or express): return templates.get_attr_stmt_array
|
||||
elif arg['is_array'] and not (select or simple or express): return templates.get_attr_stmt_array
|
||||
elif arg['non_optional_type'].endswith('*'): return templates.get_attr_stmt_entity
|
||||
else: return templates.get_attr_stmt
|
||||
|
||||
@@ -89,8 +90,16 @@ class Implementation:
|
||||
'type' : arg['non_optional_type'].split('::')[0],
|
||||
'list_instance_type' : arg['list_instance_type']}
|
||||
)
|
||||
|
||||
def find_template(arg):
|
||||
simple = mapping.schema.is_simpletype(arg['list_instance_type'])
|
||||
select = arg['list_instance_type'] == "IfcUtil::IfcBaseClass"
|
||||
express = arg['list_instance_type'] in mapping.express_to_cpp_typemapping
|
||||
if arg['is_enum']: return templates.set_attr_stmt_enum
|
||||
elif arg['is_array'] and not (select or simple or express): return templates.set_attr_stmt_array
|
||||
else: return templates.set_attr_stmt
|
||||
|
||||
tmpl = templates.set_attr_stmt_enum if arg['is_enum'] else templates.set_attr_stmt_array if arg['is_array'] and not mapping.schema.is_simpletype(arg['list_instance_type']) and arg['list_instance_type'] not in mapping.express_to_cpp_typemapping else templates.set_attr_stmt
|
||||
tmpl = find_template(arg)
|
||||
write_attr(
|
||||
templates.function,
|
||||
class_name = name,
|
||||
@@ -142,10 +151,10 @@ class Implementation:
|
||||
)
|
||||
|
||||
selectable_simple_types = sorted(set(sum([b.values for a,b in mapping.schema.selects.items()], [])) & set(mapping.schema.types.keys()))
|
||||
schema_entity_statements += [templates.schema_simple_stmt%locals() for name in selectable_simple_types]
|
||||
schema_entity_statements += [templates.schema_entity_stmt%locals() for name, type in mapping.schema.simpletypes.items()]
|
||||
schema_entity_statements += [templates.schema_entity_stmt%locals() for name, type in mapping.schema.entities.items()]
|
||||
|
||||
enumerable_types = selectable_simple_types + [name for name, type in mapping.schema.entities.items()]
|
||||
enumerable_types = sorted(set([name for name, type in mapping.schema.types.items()] + [name for name, type in mapping.schema.entities.items()]))
|
||||
max_len = max(map(len, enumerable_types))
|
||||
type_name_strings = catc(map(stringify, enumerable_types))
|
||||
string_map_statements = [templates.string_map_statement % {
|
||||
@@ -160,9 +169,40 @@ class Implementation:
|
||||
'padding' : ' ' * (max_len - len(name))
|
||||
} for name, type in mapping.schema.entities.items() if type.supertypes and len(type.supertypes) == 1]
|
||||
|
||||
max_id = len(schema_entity_statements)
|
||||
max_id = len(enumerable_types)
|
||||
|
||||
simple_type_statements = cator("v == Type::%s"%name for name in selectable_simple_types)
|
||||
|
||||
simple_type_impl = []
|
||||
for class_name, type in mapping.schema.simpletypes.items():
|
||||
type_str = mapping.make_type_string(mapping.flatten_type_string(type))
|
||||
attr_type = mapping.make_argument_type(type)
|
||||
superclass = mapping.simple_type_parent(class_name)
|
||||
|
||||
simpletype_impl_is = templates.simpletype_impl_is_with_supertype if superclass \
|
||||
else templates.simpletype_impl_is_without_supertype
|
||||
|
||||
constructor = templates.constructor_single_initlist if superclass \
|
||||
else templates.constructor
|
||||
|
||||
def compose(params):
|
||||
class_name, attr_type, superclass, superclass_init, name, tmpl, return_type, args, body = params
|
||||
arguments = ",".join(args)
|
||||
body = body % locals()
|
||||
return tmpl % locals()
|
||||
|
||||
simple_type_impl.append(templates.simpletype_impl_comment % {'name': class_name})
|
||||
simple_type_impl.extend(map(compose, map(lambda x: (class_name, attr_type, superclass, "(IfcAbstractEntity*)0")+x, (
|
||||
('getArgumentType', templates.const_function, 'IfcUtil::ArgumentType', ('unsigned int i',), templates.simpletype_impl_argument_type ),
|
||||
('getArgument', templates.const_function, 'Argument*', ('unsigned int i',), templates.simpletype_impl_argument ),
|
||||
('is', templates.const_function, 'bool', ('Type::Enum v',), simpletype_impl_is ),
|
||||
('type', templates.const_function, 'Type::Enum', (), templates.simpletype_impl_type ),
|
||||
('Class', templates.function, 'Type::Enum', (), templates.simpletype_impl_class ),
|
||||
('', constructor, '', ('IfcAbstractEntity* e',), templates.simpletype_impl_explicit_constructor),
|
||||
('', constructor, '', ("%s v" % type_str,), templates.simpletype_impl_constructor ),
|
||||
('', templates.cast_function, type_str, (), templates.simpletype_impl_cast )
|
||||
))))
|
||||
simple_type_impl.append('')
|
||||
|
||||
self.str = templates.implementation % {
|
||||
'schema_name_upper' : mapping.schema.name.upper(),
|
||||
@@ -174,7 +214,8 @@ class Implementation:
|
||||
'string_map_statements' : catnl(string_map_statements),
|
||||
'simple_type_statement' : simple_type_statements,
|
||||
'parent_type_statements' : catnl(parent_type_statements),
|
||||
'entity_implementations' : catnl(entity_implementations)
|
||||
'entity_implementations' : catnl(entity_implementations),
|
||||
'simple_type_impl' : catnl(simple_type_impl)
|
||||
}
|
||||
|
||||
self.schema_name = mapping.schema.name.capitalize()
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# 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/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import templates
|
||||
|
||||
class LateBoundHeader:
|
||||
def __init__(self, mapping):
|
||||
self.str = templates.lb_header % {
|
||||
'schema_name_upper' : mapping.schema.name.upper(),
|
||||
'schema_name' : mapping.schema.name.capitalize()
|
||||
}
|
||||
|
||||
self.schema_name = mapping.schema.name.capitalize()
|
||||
def __repr__(self):
|
||||
return self.str
|
||||
def emit(self):
|
||||
f = open('%s-latebound.h'%self.schema_name, 'w', encoding='utf-8')
|
||||
f.write(str(self))
|
||||
f.close()
|
||||
@@ -0,0 +1,117 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# 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/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import templates
|
||||
|
||||
class LateBoundImplementation:
|
||||
def __init__(self, mapping):
|
||||
schema_name = mapping.schema.name.capitalize()
|
||||
|
||||
entity_descriptors = []
|
||||
enumeration_descriptors = []
|
||||
derived_field_statements = []
|
||||
inverse_implementations = []
|
||||
|
||||
for name, type in mapping.schema.simpletypes.items():
|
||||
entity_descriptors.append(templates.entity_descriptor % {
|
||||
'type' : name,
|
||||
'parent_statement' : '0',
|
||||
'entity_descriptor_attributes' : templates.entity_descriptor_attribute % {
|
||||
'name' : 'wrappedValue',
|
||||
'optional' : 'false',
|
||||
'type' : mapping.make_argument_type(mapping.schema.types[name].type)
|
||||
}
|
||||
})
|
||||
|
||||
emitted_entities = set()
|
||||
entities_to_emit = mapping.schema.entities.keys()
|
||||
while len(emitted_entities) < len(mapping.schema.entities):
|
||||
for name, type in mapping.schema.entities.items():
|
||||
if name in emitted_entities: continue
|
||||
if len(type.supertypes) == 0 or set(type.supertypes) < emitted_entities:
|
||||
constructor_arguments = mapping.get_assignable_arguments(type, include_derived = True)
|
||||
entity_descriptor_attributes = []
|
||||
for arg in constructor_arguments:
|
||||
if not arg['is_inherited']:
|
||||
tmpl = templates.entity_descriptor_attribute_enum if arg['argument_type_enum'] == 'IfcUtil::Argument_ENUMERATION' else templates.entity_descriptor_attribute
|
||||
entity_descriptor_attributes.append(tmpl % {
|
||||
'name' : arg['name'],
|
||||
'optional' : 'true' if arg['is_optional'] else 'false',
|
||||
'type' : arg['argument_type_enum'],
|
||||
'enum_type' : arg['argument_type']
|
||||
})
|
||||
|
||||
emitted_entities.add(name)
|
||||
parent_statement = '0' if len(type.supertypes) != 1 else templates.entity_descriptor_parent % {
|
||||
'type' : type.supertypes[0]
|
||||
}
|
||||
entity_descriptors.append(templates.entity_descriptor % {
|
||||
'type' : name,
|
||||
'parent_statement' : parent_statement,
|
||||
'entity_descriptor_attributes' : '\n'.join(entity_descriptor_attributes)
|
||||
})
|
||||
|
||||
for name, enum in mapping.schema.enumerations.items():
|
||||
enumeration_descriptor_values = '\n'.join([templates.enumeration_descriptor_value % {
|
||||
'name' : v
|
||||
} for v in enum.values])
|
||||
enumeration_descriptors.append(templates.enumeration_descriptor % {
|
||||
'type' : name,
|
||||
'enumeration_descriptor_values' : enumeration_descriptor_values
|
||||
})
|
||||
|
||||
for name, type in mapping.schema.entities.items():
|
||||
constructor_arguments = mapping.get_assignable_arguments(type, include_derived = True)
|
||||
statements = ''.join(templates.derived_field_statement_attrs % (a['index']-1) for a in constructor_arguments if a['is_derived'])
|
||||
if len(statements):
|
||||
derived_field_statements.append(templates.derived_field_statement % {
|
||||
'type' : name,
|
||||
'statements' : statements
|
||||
})
|
||||
|
||||
for name, type in mapping.schema.entities.items():
|
||||
if type.inverse:
|
||||
for attr in type.inverse.elements:
|
||||
related_entity = mapping.schema.entities[attr.entity]
|
||||
related_attrs = [a['name'] for a in mapping.get_assignable_arguments(related_entity, include_derived=True)]
|
||||
|
||||
inverse_implementations.append(templates.inverse_implementation % {
|
||||
'type' : name,
|
||||
'name' : attr.name,
|
||||
'related_type' : attr.entity,
|
||||
'index' : related_attrs.index(attr.attribute)
|
||||
})
|
||||
|
||||
self.str = templates.lb_implementation % {
|
||||
'schema_name_upper' : mapping.schema.name.upper(),
|
||||
'schema_name' : mapping.schema.name.capitalize(),
|
||||
'entity_descriptors' : '\n'.join(entity_descriptors),
|
||||
'enumeration_descriptors' : '\n'.join(enumeration_descriptors),
|
||||
'derived_field_statements' : '\n'.join(derived_field_statements),
|
||||
'inverse_implementations' : '\n'.join(inverse_implementations)
|
||||
}
|
||||
|
||||
self.schema_name = mapping.schema.name.capitalize()
|
||||
def __repr__(self):
|
||||
return self.str
|
||||
def emit(self):
|
||||
f = open('%s-latebound.cpp'%self.schema_name, 'w', encoding='utf-8')
|
||||
f.write(str(self))
|
||||
f.close()
|
||||
|
||||
@@ -33,6 +33,18 @@ class Mapping:
|
||||
|
||||
def __init__(self, schema):
|
||||
self.schema = schema
|
||||
|
||||
def flatten_type_string(self, type):
|
||||
return self.flatten_type_string(self.schema.types[type].type.type) if self.schema.is_simpletype(type) else type
|
||||
|
||||
def flatten_type(self, type):
|
||||
res = self.flatten_type(self.schema.types[type].type.type) if self.schema.is_simpletype(type) else type
|
||||
return res
|
||||
|
||||
def simple_type_parent(self, type):
|
||||
parent = self.schema.types[type].type.type
|
||||
if isinstance(parent, nodes.AggregationType): parent = None
|
||||
return None if parent in self.express_to_cpp_typemapping else parent
|
||||
|
||||
def make_type_string(self, type):
|
||||
if isinstance(type, str):
|
||||
@@ -75,7 +87,7 @@ class Mapping:
|
||||
return "%s_LIST"%ty if ty.startswith("ENTITY") else ("VECTOR_%s"%ty)
|
||||
else: raise ValueError
|
||||
supported = {'INT', 'BOOL', 'DOUBLE', 'STRING', 'VECTOR_INT', 'VECTOR_DOUBLE', 'VECTOR_STRING', 'ENTITY', 'ENTITY_LIST', 'ENTITY_LIST_LIST', 'ENUMERATION'}
|
||||
ty = _make_argument_type(attr.type)
|
||||
ty = _make_argument_type(attr.type if hasattr(attr, 'type') else attr)
|
||||
if ty not in supported: ty = 'UNKNOWN'
|
||||
return "IfcUtil::Argument_%s" % ty
|
||||
|
||||
@@ -86,31 +98,35 @@ class Mapping:
|
||||
return self.get_type_dep(type.type)
|
||||
|
||||
def get_parameter_type(self, attr, allow_optional, allow_entities, allow_pointer = True):
|
||||
type_str = self.express_to_cpp_typemapping.get(str(attr.type), attr.type)
|
||||
|
||||
attr_type = self.flatten_type(attr.type)
|
||||
type_str = self.express_to_cpp_typemapping.get(str(attr_type), attr_type)
|
||||
|
||||
is_ptr = False
|
||||
if self.schema.is_enumeration(attr.type):
|
||||
type_str = '%s::%s'%(attr.type, attr.type)
|
||||
|
||||
if self.schema.is_enumeration(attr_type):
|
||||
type_str = '%s::%s'%(attr_type, attr_type)
|
||||
elif isinstance(type_str, nodes.AggregationType):
|
||||
is_nested_list = isinstance(attr.type.type, nodes.AggregationType)
|
||||
ty = self.get_parameter_type(attr.type.type if is_nested_list else attr.type, False, allow_entities, allow_pointer=False)
|
||||
if allow_entities and self.schema.is_select(attr.type.type):
|
||||
is_nested_list = isinstance(attr_type.type, nodes.AggregationType)
|
||||
ty = self.get_parameter_type(attr_type.type if is_nested_list else attr_type, False, allow_entities, False)
|
||||
if True and self.schema.is_select(attr_type.type):
|
||||
type_str = templates.untyped_list
|
||||
elif self.schema.is_simpletype(ty) or ty in self.express_to_cpp_typemapping.values():
|
||||
type_str = templates.array_type % {
|
||||
'instance_type' : ty,
|
||||
'lower' : attr.type.bounds.lower,
|
||||
'upper' : attr.type.bounds.upper
|
||||
'lower' : attr_type.bounds.lower,
|
||||
'upper' : attr_type.bounds.upper
|
||||
}
|
||||
else:
|
||||
tmpl = templates.list_list_type if is_nested_list else templates.list_type
|
||||
type_str = tmpl % {
|
||||
'instance_type': ty
|
||||
}
|
||||
elif allow_pointer and self.schema.is_entity(type_str):
|
||||
elif allow_pointer and (self.schema.is_entity(type_str) or self.schema.is_select(type_str)):
|
||||
type_str += '*'
|
||||
is_ptr = True
|
||||
elif not allow_pointer and self.schema.is_select(type_str):
|
||||
type_str = "IfcUtil::IfcAbstractSelect"
|
||||
type_str = "IfcUtil::IfcBaseClass*"
|
||||
is_ptr = True
|
||||
if allow_optional and attr.optional and not is_ptr:
|
||||
type_str = "boost::optional< %s >"%type_str
|
||||
@@ -129,7 +145,7 @@ class Mapping:
|
||||
return c + ([str(s) for s in t.derive.elements] if t.derive else [])
|
||||
|
||||
def list_instance_type(self, attr):
|
||||
f = lambda v : 'IfcUtil::IfcAbstractSelect' if self.schema.is_select(v) else v
|
||||
f = lambda v : 'IfcUtil::IfcBaseClass' if self.schema.is_select(v) else v
|
||||
if self.is_array(attr.type):
|
||||
if not isinstance(attr.type, str) and self.is_array(attr.type.type):
|
||||
if isinstance(attr.type.type, str):
|
||||
@@ -146,7 +162,7 @@ class Mapping:
|
||||
arr = self.is_array(attr.type)
|
||||
simple = self.schema.is_simpletype(ty)
|
||||
express = ty in self.express_to_cpp_typemapping
|
||||
select = ty == 'IfcUtil::IfcAbstractSelect'
|
||||
select = ty == 'IfcUtil::IfcBaseClass'
|
||||
return arr and not simple and not express and not select
|
||||
|
||||
def get_assignable_arguments(self, t, include_derived = False):
|
||||
@@ -173,6 +189,8 @@ class Mapping:
|
||||
'is_array' : self.is_array(attr.type),
|
||||
'is_nested' : self.is_array(attr.type) and not isinstance(attr.type, str) and self.is_array(attr.type.type),
|
||||
'is_derived' : attr.name in derived,
|
||||
'is_templated_list' : self.is_templated_list(attr)
|
||||
'is_templated_list' : self.is_templated_list(attr),
|
||||
'argument_type_enum' : self.make_argument_type(attr),
|
||||
'argument_type' : attr.type
|
||||
} for i, attr in attrs if include(attr)]
|
||||
|
||||
|
||||
@@ -71,6 +71,33 @@ namespace Type {
|
||||
#endif
|
||||
"""
|
||||
|
||||
lb_header = """
|
||||
#ifndef %(schema_name_upper)sRT_H
|
||||
#define %(schema_name_upper)sRT_H
|
||||
|
||||
#define IfcSchema %(schema_name)s
|
||||
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcEntityDescriptor.h"
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
|
||||
namespace %(schema_name)s {
|
||||
namespace Type {
|
||||
int GetAttributeCount(Enum t);
|
||||
int GetAttributeIndex(Enum t, const std::string& a);
|
||||
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
|
||||
const std::string& GetAttributeName(Enum t, unsigned char a);
|
||||
bool GetAttributeOptional(Enum t, unsigned char a);
|
||||
bool GetAttributeDerived(Enum t, unsigned char a);
|
||||
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
|
||||
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
|
||||
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
|
||||
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
|
||||
}}
|
||||
|
||||
#endif
|
||||
"""
|
||||
|
||||
implementation= """
|
||||
#include "../ifcparse/%(schema_name)s.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
@@ -100,6 +127,7 @@ void %(schema_name)s::InitStringMap() {
|
||||
}
|
||||
|
||||
Type::Enum Type::FromString(const std::string& s) {
|
||||
if (string_map.empty()) InitStringMap();
|
||||
std::map<std::string,Type::Enum>::const_iterator it = string_map.find(s);
|
||||
if ( it == string_map.end() ) throw IfcException("Unable to find find keyword in schema");
|
||||
else return it->second;
|
||||
@@ -117,15 +145,173 @@ bool Type::IsSimple(Enum v) {
|
||||
|
||||
%(enumeration_functions)s
|
||||
|
||||
%(simple_type_impl)s
|
||||
|
||||
%(entity_implementations)s
|
||||
"""
|
||||
|
||||
simpletype = """%(documentation)s
|
||||
typedef %(type)s %(name)s;
|
||||
lb_implementation = """
|
||||
#include <set>
|
||||
|
||||
#include "../ifcparse/%(schema_name)s.h"
|
||||
#include "../ifcparse/%(schema_name)s-latebound.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcWrite.h"
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcEntityDescriptor.h"
|
||||
|
||||
using namespace %(schema_name)s;
|
||||
using namespace IfcParse;
|
||||
using namespace IfcWrite;
|
||||
using namespace IfcUtil;
|
||||
|
||||
std::map<Type::Enum,IfcEntityDescriptor*> entity_descriptor_map;
|
||||
std::map<Type::Enum,IfcEnumerationDescriptor*> enumeration_descriptor_map;
|
||||
std::map<std::pair<Type::Enum, std::string>, std::pair<Type::Enum, int> > inverse_map;
|
||||
std::map<Type::Enum,std::set<int> > derived_map;
|
||||
|
||||
void InitDescriptorMap() {
|
||||
IfcEntityDescriptor* current;
|
||||
%(entity_descriptors)s
|
||||
// Enumerations
|
||||
IfcEnumerationDescriptor* current_enum;
|
||||
std::vector<std::string> values;
|
||||
%(enumeration_descriptors)s
|
||||
}
|
||||
|
||||
void InitInverseMap() {
|
||||
%(inverse_implementations)s
|
||||
}
|
||||
|
||||
void InitDerivedMap() {
|
||||
%(derived_field_statements)s
|
||||
}
|
||||
|
||||
int Type::GetAttributeIndex(Enum t, const std::string& a) {
|
||||
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
|
||||
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
|
||||
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
|
||||
else return i->second->getArgumentIndex(a);
|
||||
}
|
||||
|
||||
int Type::GetAttributeCount(Enum t) {
|
||||
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
|
||||
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
|
||||
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
|
||||
else return i->second->getArgumentCount();
|
||||
}
|
||||
|
||||
ArgumentType Type::GetAttributeType(Enum t, unsigned char a) {
|
||||
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
|
||||
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
|
||||
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
|
||||
else return i->second->getArgumentType(a);
|
||||
}
|
||||
|
||||
const std::string& Type::GetAttributeName(Enum t, unsigned char a) {
|
||||
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
|
||||
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
|
||||
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
|
||||
else return i->second->getArgumentName(a);
|
||||
}
|
||||
|
||||
bool Type::GetAttributeOptional(Enum t, unsigned char a) {
|
||||
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
|
||||
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
|
||||
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
|
||||
else return i->second->getArgumentOptional(a);
|
||||
}
|
||||
|
||||
bool Type::GetAttributeDerived(Enum t, unsigned char a) {
|
||||
if (derived_map.empty()) ::InitDerivedMap();
|
||||
std::map<Type::Enum,std::set<int> >::const_iterator i = derived_map.find(t);
|
||||
return i != derived_map.end() && i->second.find(a) != i->second.end();
|
||||
}
|
||||
|
||||
std::pair<const char*, int> Type::GetEnumerationIndex(Enum t, const std::string& a) {
|
||||
if (enumeration_descriptor_map.empty()) ::InitDescriptorMap();
|
||||
std::map<Type::Enum,IfcEnumerationDescriptor*>::const_iterator i = enumeration_descriptor_map.find(t);
|
||||
if ( i == enumeration_descriptor_map.end() ) throw IfcException("Value not found");
|
||||
else return i->second->getIndex(a);
|
||||
}
|
||||
|
||||
std::pair<Type::Enum, unsigned> Type::GetInverseAttribute(Enum t, const std::string& a) {
|
||||
if (inverse_map.empty()) ::InitInverseMap();
|
||||
std::map<std::pair<Type::Enum, std::string>, std::pair<Type::Enum, int> >::const_iterator it;
|
||||
std::pair<Type::Enum, std::string> key = std::make_pair(t, a);
|
||||
while (true) {
|
||||
it = inverse_map.find(key);
|
||||
if (it != inverse_map.end()) return it->second;
|
||||
if ((key.first = Parent(key.first)) == -1) break;
|
||||
}
|
||||
throw IfcException("Attribute not found");
|
||||
}
|
||||
|
||||
Type::Enum Type::GetAttributeEnumerationClass(Enum t, unsigned char a) {
|
||||
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
|
||||
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
|
||||
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
|
||||
else {
|
||||
Type::Enum t = i->second->getArgumentEnumerationClass(a);
|
||||
if ( t == Type::ALL ) throw IfcException("Not an enumeration");
|
||||
else return t;
|
||||
}
|
||||
}
|
||||
|
||||
void Type::PopulateDerivedFields(IfcWrite::IfcWritableEntity* e) {
|
||||
std::map<Type::Enum, std::set<int> >::const_iterator i = derived_map.find(e->type());
|
||||
if (i != derived_map.end()) {
|
||||
for (std::set<int>::const_iterator it = i->second.begin(); it != i->second.end(); ++it) {
|
||||
e->setArgumentDerived(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
entity_descriptor = """ current = entity_descriptor_map[Type::%(type)s] = new IfcEntityDescriptor(Type::%(type)s,%(parent_statement)s);
|
||||
%(entity_descriptor_attributes)s"""
|
||||
|
||||
entity_descriptor_parent = "entity_descriptor_map.find(Type::%(type)s)->second"
|
||||
entity_descriptor_attribute = ' current->add("%(name)s",%(optional)s,%(type)s);'
|
||||
entity_descriptor_attribute_enum = ' current->add("%(name)s",%(optional)s,%(type)s,Type::%(enum_type)s);'
|
||||
|
||||
enumeration_descriptor = """ values.clear(); values.reserve(128);
|
||||
%(enumeration_descriptor_values)s
|
||||
current_enum = enumeration_descriptor_map[Type::%(type)s] = new IfcEnumerationDescriptor(Type::%(type)s, values);"""
|
||||
|
||||
enumeration_descriptor_value = ' values.push_back("%(name)s");'
|
||||
|
||||
derived_field_statement = ' {std::set<int> idxs; %(statements)sderived_map[Type::%(type)s] = idxs;}';
|
||||
derived_field_statement_attrs = 'idxs.insert(%d); '
|
||||
|
||||
simpletype = """%(documentation)s
|
||||
class %(name)s : public %(superclass)s {
|
||||
public:
|
||||
virtual IfcUtil::ArgumentType getArgumentType(unsigned int i) const;
|
||||
virtual Argument* getArgument(unsigned int i) const;
|
||||
bool is(Type::Enum v) const;
|
||||
Type::Enum type() const;
|
||||
static Type::Enum Class();
|
||||
explicit %(name)s (IfcAbstractEntity* e);
|
||||
%(name)s (%(type)s v);
|
||||
operator %(type)s() const;
|
||||
};
|
||||
"""
|
||||
|
||||
simpletype_impl_comment = "// Function implementations for %(name)s"
|
||||
simpletype_impl_argument_type = "if (i == 0) { return %(attr_type)s; } else { throw IfcParse::IfcException(\"argument out of range\"); }"
|
||||
simpletype_impl_argument = "return entity->getArgument(i);"
|
||||
simpletype_impl_is_with_supertype = "return v == Type::%(class_name)s || %(superclass)s::is(v);"
|
||||
simpletype_impl_is_without_supertype = "return v == %(class_name)s::Class();"
|
||||
simpletype_impl_type = "return Type::%(class_name)s;"
|
||||
simpletype_impl_class = "return Type::%(class_name)s;"
|
||||
simpletype_impl_explicit_constructor = "entity = e;"
|
||||
simpletype_impl_constructor = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v); entity = e;"
|
||||
simpletype_impl_cast = "return *entity->getArgument(0);"
|
||||
|
||||
select = """%(documentation)s
|
||||
typedef IfcUtil::IfcBaseClass* %(name)s;
|
||||
typedef IfcUtil::IfcBaseClass %(name)s;
|
||||
"""
|
||||
|
||||
enumeration = """namespace %(name)s {
|
||||
@@ -177,6 +363,9 @@ optional_attribute_description = "/// Whether the optional attribute %s is defin
|
||||
|
||||
function = "%(return_type)s %(class_name)s::%(name)s(%(arguments)s) { %(body)s }"
|
||||
const_function = "%(return_type)s %(class_name)s::%(name)s(%(arguments)s) const { %(body)s }"
|
||||
constructor = "%(class_name)s::%(class_name)s(%(arguments)s) { %(body)s }"
|
||||
constructor_single_initlist = "%(class_name)s::%(class_name)s(%(arguments)s) : %(superclass)s(%(superclass_init)s) { %(body)s }"
|
||||
cast_function = "%(class_name)s::operator %(return_type)s() const { %(body)s }"
|
||||
|
||||
array_type = "std::vector< %(instance_type)s > /*[%(lower)s:%(upper)s]*/"
|
||||
list_type = "IfcTemplatedEntityList< %(instance_type)s >::ptr"
|
||||
@@ -213,6 +402,8 @@ constructor_stmt_array = " e->setArgument(%(index)d,(%(name)s)->generalize());"
|
||||
constructor_stmt_optional = " if (%(name)s) {%(stmt)s } else { e->setArgument(%(index)d); }"
|
||||
constructor_stmt_derived = " e->setArgumentDerived(%(index)d);"
|
||||
|
||||
inverse_implementation = " inverse_map.insert(std::make_pair(std::make_pair(Type::%(type)s, \"%(name)s\"), std::make_pair(Type::%(related_type)s, %(index)d)));"
|
||||
|
||||
def multi_line_comment(li):
|
||||
return ("/// %s"%("\n/// ".join(li))) if len(li) else ""
|
||||
|
||||
|
||||
+14
-5
@@ -41,6 +41,8 @@
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
|
||||
#define IN_CACHE(T,E,t,e) std::map<int,t>::const_iterator it = cache.T.find(E->entity->id());\
|
||||
@@ -124,6 +126,13 @@ public:
|
||||
IfcSchema::IfcProductDefinitionShape* tesselate(TopoDS_Shape& shape, double deflection, IfcEntityList::ptr es);
|
||||
void remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
|
||||
|
||||
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
|
||||
|
||||
IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*);
|
||||
|
||||
template <typename P>
|
||||
IfcGeom::BRepElement<P>* create_brep_for_representation_and_product(const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*);
|
||||
|
||||
const SurfaceStyle* get_style(const IfcSchema::IfcRepresentationItem* representation_item);
|
||||
|
||||
template <typename T> std::pair<IfcSchema::IfcSurfaceStyle*, T*> get_surface_style(const IfcSchema::IfcRepresentationItem* representation_item) {
|
||||
@@ -141,14 +150,14 @@ public:
|
||||
for (IfcSchema::IfcPresentationStyleAssignment::list::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
|
||||
IfcSchema::IfcPresentationStyleAssignment* style_assignment = *kt;
|
||||
#endif
|
||||
IfcUtil::IfcAbstractSelect::list::ptr styles = style_assignment->Styles();
|
||||
for (IfcUtil::IfcAbstractSelect::list::it lt = styles->begin(); lt != styles->end(); ++lt) {
|
||||
IfcUtil::IfcAbstractSelect* style = *lt;
|
||||
IfcEntityList::ptr styles = style_assignment->Styles();
|
||||
for (IfcEntityList::it lt = styles->begin(); lt != styles->end(); ++lt) {
|
||||
IfcUtil::IfcBaseClass* style = *lt;
|
||||
if (style->is(IfcSchema::Type::IfcSurfaceStyle)) {
|
||||
IfcSchema::IfcSurfaceStyle* surface_style = (IfcSchema::IfcSurfaceStyle*) style;
|
||||
if (surface_style->Side() != IfcSchema::IfcSurfaceSide::IfcSurfaceSide_NEGATIVE) {
|
||||
IfcUtil::IfcAbstractSelect::list::ptr styles_elements = surface_style->Styles();
|
||||
for (IfcUtil::IfcAbstractSelect::list::it mt = styles_elements->begin(); mt != styles_elements->end(); ++mt) {
|
||||
IfcEntityList::ptr styles_elements = surface_style->Styles();
|
||||
for (IfcEntityList::it mt = styles_elements->begin(); mt != styles_elements->end(); ++mt) {
|
||||
if ((*mt)->is(T::Class())) {
|
||||
return std::make_pair(surface_style, (T*) *mt);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircle* l, Handle(Geom_Curve)&
|
||||
return false;
|
||||
}
|
||||
gp_Trsf trsf;
|
||||
IfcSchema::IfcAxis2Placement placement = l->Position();
|
||||
IfcSchema::IfcAxis2Placement* placement = l->Position();
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
} else {
|
||||
@@ -111,7 +111,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcEllipse* l, Handle(Geom_Curve)
|
||||
// when creating a trimmed curve off of an ellipse like this.
|
||||
const bool rotated = y > x;
|
||||
gp_Trsf trsf;
|
||||
IfcSchema::IfcAxis2Placement placement = l->Position();
|
||||
IfcSchema::IfcAxis2Placement* placement = l->Position();
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
} else {
|
||||
|
||||
@@ -87,21 +87,21 @@ namespace IfcGeom {
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class ShapeModelElement : public Element<P> {
|
||||
class BRepElement : public Element<P> {
|
||||
private:
|
||||
Representation::BRep* _geometry;
|
||||
public:
|
||||
const Representation::BRep& geometry() const { return *_geometry; }
|
||||
ShapeModelElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const gp_Trsf& trsf, Representation::BRep* geometry)
|
||||
BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const gp_Trsf& trsf, Representation::BRep* geometry)
|
||||
: Element<P>(geometry->settings(),id,parent_id,name,type,guid,trsf)
|
||||
, _geometry(geometry)
|
||||
{}
|
||||
virtual ~ShapeModelElement() {
|
||||
virtual ~BRepElement() {
|
||||
delete _geometry;
|
||||
}
|
||||
private:
|
||||
ShapeModelElement(const ShapeModelElement& other);
|
||||
ShapeModelElement& operator=(const ShapeModelElement& other);
|
||||
BRepElement(const BRepElement& other);
|
||||
BRepElement& operator=(const BRepElement& other);
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
@@ -110,7 +110,7 @@ namespace IfcGeom {
|
||||
Representation::Triangulation<P>* _geometry;
|
||||
public:
|
||||
const Representation::Triangulation<P>& geometry() const { return *_geometry; }
|
||||
TriangulationElement(const ShapeModelElement<P>& shape_model)
|
||||
TriangulationElement(const BRepElement<P>& shape_model)
|
||||
: Element<P>(shape_model)
|
||||
, _geometry(new Representation::Triangulation<P>(shape_model.geometry()))
|
||||
{}
|
||||
@@ -128,7 +128,7 @@ namespace IfcGeom {
|
||||
Representation::Serialization* _geometry;
|
||||
public:
|
||||
const Representation::Serialization& geometry() const { return *_geometry; }
|
||||
SerializedElement(const ShapeModelElement<P>& shape_model)
|
||||
SerializedElement(const BRepElement<P>& shape_model)
|
||||
: Element<P>(shape_model)
|
||||
, _geometry(new Representation::Serialization(shape_model.geometry()))
|
||||
{}
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
#include "../ifcgeom/IfcGeomUtils.h"
|
||||
|
||||
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
|
||||
BRepOffsetAPI_Sewing builder;
|
||||
@@ -815,4 +816,221 @@ void IfcGeom::Kernel::remove_redundant_points_from_loop(TColgp_SequenceOfPnt& po
|
||||
}
|
||||
if (!removed) break;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_product(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product) {
|
||||
IfcGeom::Representation::BRep* shape;
|
||||
IfcGeom::IfcRepresentationShapeItems shapes;
|
||||
|
||||
if ( !convert_shapes(representation,shapes) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parent_id = -1;
|
||||
try {
|
||||
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product);
|
||||
if (parent_object) {
|
||||
parent_id = parent_object->entity->id();
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
const std::string name = product->hasName() ? product->Name() : "";
|
||||
const std::string guid = product->GlobalId();
|
||||
|
||||
gp_Trsf trsf;
|
||||
try {
|
||||
convert(product->ObjectPlacement(),trsf);
|
||||
} catch (...) {}
|
||||
|
||||
// Does the IfcElement have any IfcOpenings?
|
||||
// Note that openings for IfcOpeningElements are not processed
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr openings;
|
||||
if ( product->is(IfcSchema::Type::IfcElement) && !product->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
|
||||
openings = element->HasOpenings();
|
||||
}
|
||||
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
|
||||
if ( product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
|
||||
IfcSchema::IfcBuildingElementPart* part = (IfcSchema::IfcBuildingElementPart*)product;
|
||||
#ifdef USE_IFC4
|
||||
IfcSchema::IfcRelAggregates::list::ptr decomposes = part->Decomposes();
|
||||
for ( IfcSchema::IfcRelAggregates::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#else
|
||||
IfcSchema::IfcRelDecomposes::list::ptr decomposes = part->Decomposes();
|
||||
for ( IfcSchema::IfcRelDecomposes::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#endif
|
||||
IfcSchema::IfcObjectDefinition* obdef = (*it)->RelatingObject();
|
||||
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)obdef;
|
||||
openings->push(element->HasOpenings());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string product_type = IfcSchema::Type::ToString(product->type());
|
||||
ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type);
|
||||
|
||||
if ( !settings.disable_opening_subtractions() && openings && openings->Size() ) {
|
||||
IfcGeom::IfcRepresentationShapeItems opened_shapes;
|
||||
try {
|
||||
if ( settings.faster_booleans() ) {
|
||||
bool succes = convert_openings_fast(product,openings,shapes,trsf,opened_shapes);
|
||||
if ( ! succes ) {
|
||||
opened_shapes.clear();
|
||||
convert_openings(product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} else {
|
||||
convert_openings(product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} catch(...) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",product->entity);
|
||||
}
|
||||
if ( settings.use_world_coords() ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
}
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), opened_shapes);
|
||||
} else if ( settings.use_world_coords() ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), shapes);
|
||||
} else {
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), shapes);
|
||||
}
|
||||
|
||||
return new BRepElement<P>(
|
||||
product->entity->id(),
|
||||
parent_id,
|
||||
name,
|
||||
product_type,
|
||||
guid,
|
||||
trsf,
|
||||
shape
|
||||
);
|
||||
}
|
||||
|
||||
IfcSchema::IfcObjectDefinition* IfcGeom::Kernel::get_decomposing_entity(IfcSchema::IfcProduct* product) {
|
||||
IfcSchema::IfcObjectDefinition* parent = 0;
|
||||
|
||||
// In case of an opening element, parent to the RelatingBuildingElement
|
||||
if ( product->is(IfcSchema::Type::IfcOpeningElement ) ) {
|
||||
IfcSchema::IfcOpeningElement* opening = (IfcSchema::IfcOpeningElement*)product;
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr voids = opening->VoidsElements();
|
||||
if ( voids->Size() ) {
|
||||
IfcSchema::IfcRelVoidsElement* ifc_void = *voids->begin();
|
||||
parent = ifc_void->RelatingBuildingElement();
|
||||
}
|
||||
} else if ( product->is(IfcSchema::Type::IfcElement ) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
|
||||
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids();
|
||||
// Incase of a RelatedBuildingElement parent to the opening element
|
||||
if ( fills->Size() ) {
|
||||
for ( IfcSchema::IfcRelFillsElement::list::it it = fills->begin(); it != fills->end(); ++ it ) {
|
||||
IfcSchema::IfcRelFillsElement* fill = *it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef = fill->RelatingOpeningElement();
|
||||
if ( product == ifc_objectdef ) continue;
|
||||
parent = ifc_objectdef;
|
||||
}
|
||||
}
|
||||
// Else simply parent to the containing structure
|
||||
if (!parent) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure::list::ptr parents = element->ContainedInStructure();
|
||||
if ( parents->Size() ) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure* container = *parents->begin();
|
||||
parent = container->RelatingStructure();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parent decompositions to the RelatingObject
|
||||
if (!parent) {
|
||||
IfcEntityList::ptr parents = product->entity->getInverse(IfcSchema::Type::IfcRelAggregates);
|
||||
parents->push(product->entity->getInverse(IfcSchema::Type::IfcRelNests));
|
||||
for ( IfcEntityList::it it = parents->begin(); it != parents->end(); ++ it ) {
|
||||
IfcSchema::IfcRelDecomposes* decompose = (IfcSchema::IfcRelDecomposes*)*it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef;
|
||||
#ifdef USE_IFC4
|
||||
if (decompose->is(IfcSchema::Type::IfcRelAggregates)) {
|
||||
ifc_objectdef = ((IfcSchema::IfcRelAggregates*)decompose)->RelatingObject();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
ifc_objectdef = decompose->RelatingObject();
|
||||
#endif
|
||||
if ( product == ifc_objectdef ) continue;
|
||||
parent = ifc_objectdef;
|
||||
}
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
template IfcGeom::BRepElement<float>* IfcGeom::Kernel::create_brep_for_representation_and_product<float>(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
||||
template IfcGeom::BRepElement<double>* IfcGeom::Kernel::create_brep_for_representation_and_product<double>(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
||||
|
||||
std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUnitAssignment* unit_assignment) {
|
||||
// Set default units, set length to meters, angles to undefined
|
||||
setValue(IfcGeom::Kernel::GV_LENGTH_UNIT, 1.0);
|
||||
setValue(IfcGeom::Kernel::GV_PLANEANGLE_UNIT, -1.0);
|
||||
|
||||
std::string unit_name = "METER";
|
||||
double unit_magnitude = 1.;
|
||||
|
||||
try {
|
||||
IfcEntityList::ptr units = unit_assignment->Units();
|
||||
if (!units || !units->Size()) {
|
||||
Logger::Message(Logger::LOG_ERROR, "No unit information found");
|
||||
} else {
|
||||
for ( IfcEntityList::it it = units->begin(); it != units->end(); ++ it ) {
|
||||
std::string current_unit_name = "";
|
||||
IfcUtil::IfcBaseClass* base = *it;
|
||||
IfcSchema::IfcSIUnit* unit = 0;
|
||||
double value = 1.f;
|
||||
if ( base->is(IfcSchema::Type::IfcConversionBasedUnit) ) {
|
||||
IfcSchema::IfcConversionBasedUnit* u = (IfcSchema::IfcConversionBasedUnit*)base;
|
||||
current_unit_name = u->Name();
|
||||
IfcSchema::IfcMeasureWithUnit* u2 = u->ConversionFactor();
|
||||
IfcSchema::IfcUnit* u3 = u2->UnitComponent();
|
||||
if ( u3->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*) u3;
|
||||
}
|
||||
IfcSchema::IfcValue* v = u2->ValueComponent();
|
||||
// Quick hack to get the numeric value from an IfcValue:
|
||||
const double f = *v->entity->getArgument(0);
|
||||
value *= f;
|
||||
} else if ( base->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*)base;
|
||||
}
|
||||
if ( unit ) {
|
||||
if ( unit->hasPrefix() ) {
|
||||
value *= IfcGeom::Utils::UnitPrefixToValue(unit->Prefix());
|
||||
}
|
||||
IfcSchema::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
|
||||
if ( type == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {
|
||||
setValue(IfcGeom::Kernel::GV_LENGTH_UNIT,value);
|
||||
if (current_unit_name.empty()) {
|
||||
if (unit->hasPrefix()) {
|
||||
current_unit_name = IfcSchema::IfcSIPrefix::ToString(unit->Prefix());
|
||||
}
|
||||
current_unit_name += IfcSchema::IfcSIUnitName::ToString(unit->Name());
|
||||
}
|
||||
unit_magnitude = value;
|
||||
unit_name = current_unit_name;
|
||||
} else if ( type == IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT ) {
|
||||
setValue(IfcGeom::Kernel::GV_PLANEANGLE_UNIT, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const IfcParse::IfcException& ex) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed to determine unit information '" << ex.what() << "'";
|
||||
Logger::Message(Logger::LOG_ERROR, ss.str());
|
||||
}
|
||||
|
||||
return std::pair<std::string, double>(unit_name, unit_magnitude);
|
||||
}
|
||||
@@ -289,7 +289,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& t
|
||||
IfcSchema::IfcLocalPlacement* current = (IfcSchema::IfcLocalPlacement*)l;
|
||||
while (1) {
|
||||
gp_Trsf trsf2;
|
||||
IfcSchema::IfcAxis2Placement relplacement = current->RelativePlacement();
|
||||
IfcSchema::IfcAxis2Placement* relplacement = current->RelativePlacement();
|
||||
if ( relplacement->is(IfcSchema::Type::IfcAxis2Placement3D) ) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)relplacement,trsf2);
|
||||
trsf.PreMultiply(trsf2);
|
||||
|
||||
+40
-246
@@ -71,10 +71,9 @@
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
#include "../ifcgeom/IfcGeomUtils.h"
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
@@ -90,16 +89,16 @@ namespace IfcGeom {
|
||||
|
||||
IfcParse::IfcFile* ifc_file;
|
||||
|
||||
// A container and iterator for IfcShapeRepresentations
|
||||
// A container and iterator for IfcRepresentations
|
||||
IfcSchema::IfcRepresentation::list::ptr representations;
|
||||
IfcSchema::IfcRepresentation::list::it shaperep_iterator;
|
||||
IfcSchema::IfcRepresentation::list::it representation_iterator;
|
||||
|
||||
// The object is fetched beforehand to be sure that get() returns a valid element
|
||||
TriangulationElement<P>* current_triangulation;
|
||||
ShapeModelElement<P>* current_shape_model;
|
||||
BRepElement<P>* current_shape_model;
|
||||
SerializedElement<P>* current_serialization;
|
||||
|
||||
// A container and iterator for IfcBuildingElements for the current IfcRepresentation referenced by *shaperep_iterator
|
||||
// A container and iterator for IfcBuildingElements for the current IfcRepresentation referenced by *representation_iterator
|
||||
IfcSchema::IfcProduct::list::ptr entities;
|
||||
IfcSchema::IfcProduct::list::it ifcproduct_iterator;
|
||||
|
||||
@@ -110,93 +109,18 @@ namespace IfcGeom {
|
||||
// double?
|
||||
P unit_magnitude;
|
||||
|
||||
// Store references to all returned non-geometric elements to be freed when the destructor is called
|
||||
std::vector<Element<P>*> returned_elements;
|
||||
|
||||
void initUnits() {
|
||||
// Set default units, set length to meters, angles to undefined
|
||||
kernel.setValue(IfcGeom::Kernel::GV_LENGTH_UNIT, 1.0);
|
||||
kernel.setValue(IfcGeom::Kernel::GV_PLANEANGLE_UNIT, -1.0);
|
||||
|
||||
IfcSchema::IfcUnitAssignment::list::ptr unit_assignments = ifc_file->EntitiesByType<IfcSchema::IfcUnitAssignment>();
|
||||
IfcUtil::IfcAbstractSelect::list::ptr units;
|
||||
try {
|
||||
if ( unit_assignments->Size() ) {
|
||||
IfcSchema::IfcUnitAssignment* unit_assignment = *unit_assignments->begin();
|
||||
units = unit_assignment->Units();
|
||||
}
|
||||
} catch (const IfcParse::IfcException&) {}
|
||||
|
||||
if (!units || !units->Size()) {
|
||||
// No units eh... Since tolerances and deflection are specified internally in meters
|
||||
// we will try to find another indication of the model size.
|
||||
IfcSchema::IfcExtrudedAreaSolid::list::ptr extrusions = ifc_file->EntitiesByType<IfcSchema::IfcExtrudedAreaSolid>();
|
||||
if ( ! extrusions->Size() ) return;
|
||||
double max_height = -1.0f;
|
||||
for ( IfcSchema::IfcExtrudedAreaSolid::list::it it = extrusions->begin(); it != extrusions->end(); ++ it ) {
|
||||
try {
|
||||
const double depth = (*it)->Depth();
|
||||
if ( depth > max_height ) max_height = depth;
|
||||
} catch (const IfcParse::IfcException&) {}
|
||||
}
|
||||
if ( max_height > 100.0f ) {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_LENGTH_UNIT, 0.001);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Guessed length unit to be in millimeters based on extrusion depth");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = units->begin(); it != units->end(); ++ it ) {
|
||||
std::string current_unit_name = "";
|
||||
IfcUtil::IfcAbstractSelect* base = *it;
|
||||
IfcSchema::IfcSIUnit* unit = 0;
|
||||
double value = 1.f;
|
||||
if ( base->is(IfcSchema::Type::IfcConversionBasedUnit) ) {
|
||||
IfcSchema::IfcConversionBasedUnit* u = (IfcSchema::IfcConversionBasedUnit*)base;
|
||||
current_unit_name = u->Name();
|
||||
IfcSchema::IfcMeasureWithUnit* u2 = u->ConversionFactor();
|
||||
IfcSchema::IfcUnit u3 = u2->UnitComponent();
|
||||
if ( u3->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*) u3;
|
||||
}
|
||||
IfcSchema::IfcValue v = u2->ValueComponent();
|
||||
IfcUtil::IfcArgumentSelect* v2 = (IfcUtil::IfcArgumentSelect*) v;
|
||||
const double f = *v2->wrappedValue();
|
||||
value *= f;
|
||||
} else if ( base->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*)base;
|
||||
}
|
||||
if ( unit ) {
|
||||
if ( unit->hasPrefix() ) {
|
||||
value *= IfcGeom::Utils::UnitPrefixToValue(unit->Prefix());
|
||||
}
|
||||
IfcSchema::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
|
||||
if ( type == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_LENGTH_UNIT,value);
|
||||
if (current_unit_name.empty()) {
|
||||
if (unit->hasPrefix()) {
|
||||
current_unit_name = IfcSchema::IfcSIPrefix::ToString(unit->Prefix());
|
||||
}
|
||||
current_unit_name += IfcSchema::IfcSIUnitName::ToString(unit->Name());
|
||||
}
|
||||
unit_magnitude = static_cast<P>(value);
|
||||
unit_name = current_unit_name;
|
||||
} else if ( type == IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT ) {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_PLANEANGLE_UNIT, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const IfcParse::IfcException& ex) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed to determine unit information '" << ex.what() << "'";
|
||||
Logger::Message(Logger::LOG_ERROR, ss.str());
|
||||
IfcSchema::IfcProject::list::ptr projects = ifc_file->EntitiesByType<IfcSchema::IfcProject>();
|
||||
if (projects->Size() == 1) {
|
||||
IfcSchema::IfcProject* project = *projects->begin();
|
||||
std::pair<std::string, double> length_unit = kernel.initializeUnits(project->UnitsInContext());
|
||||
unit_name = length_unit.first;
|
||||
unit_magnitude = static_cast<P>(length_unit.second);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool findContext() {
|
||||
|
||||
try {
|
||||
initUnits();
|
||||
} catch (...) {}
|
||||
@@ -266,7 +190,7 @@ namespace IfcGeom {
|
||||
|
||||
if (representations->Size() == 0) return false;
|
||||
|
||||
shaperep_iterator = representations->begin();
|
||||
representation_iterator = representations->begin();
|
||||
entities.reset();
|
||||
|
||||
if (!create()) {
|
||||
@@ -300,82 +224,28 @@ namespace IfcGeom {
|
||||
}
|
||||
|
||||
private:
|
||||
// Move the the next IfcRepresentation
|
||||
// Move to the next IfcRepresentation
|
||||
void _nextShape() {
|
||||
entities.reset();
|
||||
++ shaperep_iterator;
|
||||
++ representation_iterator;
|
||||
++ done;
|
||||
}
|
||||
|
||||
int _getParentId(IfcSchema::IfcProduct* ifc_product) {
|
||||
int parent_id = -1;
|
||||
// In case of an opening element, parent to the RelatingBuildingElement
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcOpeningElement ) ) {
|
||||
IfcSchema::IfcOpeningElement* opening = (IfcSchema::IfcOpeningElement*)ifc_product;
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr voids = opening->VoidsElements();
|
||||
if ( voids->Size() ) {
|
||||
IfcSchema::IfcRelVoidsElement* ifc_void = *voids->begin();
|
||||
parent_id = ifc_void->RelatingBuildingElement()->entity->id();
|
||||
}
|
||||
} else if ( ifc_product->is(IfcSchema::Type::IfcElement ) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)ifc_product;
|
||||
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids();
|
||||
// Incase of a RelatedBuildingElement parent to the opening element
|
||||
if ( fills->Size() ) {
|
||||
for ( IfcSchema::IfcRelFillsElement::list::it it = fills->begin(); it != fills->end(); ++ it ) {
|
||||
IfcSchema::IfcRelFillsElement* fill = *it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef = fill->RelatingOpeningElement();
|
||||
if ( ifc_product == ifc_objectdef ) continue;
|
||||
parent_id = ifc_objectdef->entity->id();
|
||||
}
|
||||
}
|
||||
// Else simply parent to the containing structure
|
||||
if ( parent_id == -1 ) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure::list::ptr parents = element->ContainedInStructure();
|
||||
if ( parents->Size() ) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure* parent = *parents->begin();
|
||||
parent_id = parent->RelatingStructure()->entity->id();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parent decompositions to the RelatingObject
|
||||
if ( parent_id == -1 ) {
|
||||
IfcEntityList::ptr parents = ifc_product->entity->getInverse(IfcSchema::Type::IfcRelAggregates);
|
||||
parents->push(ifc_product->entity->getInverse(IfcSchema::Type::IfcRelNests));
|
||||
for ( IfcEntityList::it it = parents->begin(); it != parents->end(); ++ it ) {
|
||||
IfcSchema::IfcRelDecomposes* decompose = (IfcSchema::IfcRelDecomposes*)*it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef;
|
||||
#ifdef USE_IFC4
|
||||
if (decompose->is(IfcSchema::Type::IfcRelAggregates)) {
|
||||
ifc_objectdef = ((IfcSchema::IfcRelAggregates*)decompose)->RelatingObject();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
ifc_objectdef = decompose->RelatingObject();
|
||||
#endif
|
||||
if ( ifc_product == ifc_objectdef ) continue;
|
||||
parent_id = ifc_objectdef->entity->id();
|
||||
}
|
||||
}
|
||||
return parent_id;
|
||||
}
|
||||
|
||||
ShapeModelElement<P>* create_shape_model_for_next_entity() {
|
||||
BRepElement<P>* create_shape_model_for_next_entity() {
|
||||
while ( true ) {
|
||||
IfcSchema::IfcRepresentation* shaperep;
|
||||
IfcSchema::IfcRepresentation* representation;
|
||||
|
||||
// Have we reached the end of our list of representations?
|
||||
if ( shaperep_iterator == representations->end() ) {
|
||||
if ( representation_iterator == representations->end() ) {
|
||||
representations.reset();
|
||||
return 0;
|
||||
}
|
||||
shaperep = *shaperep_iterator;
|
||||
representation = *representation_iterator;
|
||||
|
||||
// Has the list of IfcProducts for this representation been initialized?
|
||||
if ( ! entities ) {
|
||||
|
||||
IfcSchema::IfcProductRepresentation::list::ptr prodreps = shaperep->OfProductRepresentation();
|
||||
IfcSchema::IfcProductRepresentation::list::ptr prodreps = representation->OfProductRepresentation();
|
||||
entities = IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
|
||||
for ( IfcSchema::IfcProductRepresentation::list::it it = prodreps->begin(); it != prodreps->end(); ++it ) {
|
||||
if ( (*it)->is(IfcSchema::Type::IfcProductDefinitionShape) ) {
|
||||
@@ -406,99 +276,17 @@ namespace IfcGeom {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
|
||||
IfcGeom::Representation::BRep* shape;
|
||||
IfcGeom::IfcRepresentationShapeItems shapes;
|
||||
|
||||
if ( !kernel.convert_shapes(shaperep,shapes) ) {
|
||||
IfcSchema::IfcProduct* product = *ifcproduct_iterator;
|
||||
|
||||
BRepElement<P>* element = kernel.create_brep_for_representation_and_product<P>(settings, representation, product);
|
||||
|
||||
if ( !element ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
|
||||
IfcSchema::IfcProduct* ifc_product = *ifcproduct_iterator;
|
||||
|
||||
int parent_id = -1;
|
||||
try {
|
||||
parent_id = _getParentId(ifc_product);
|
||||
} catch (...) {}
|
||||
|
||||
const std::string name = ifc_product->hasName() ? ifc_product->Name() : "";
|
||||
const std::string guid = ifc_product->GlobalId();
|
||||
|
||||
gp_Trsf trsf;
|
||||
try {
|
||||
kernel.convert(ifc_product->ObjectPlacement(),trsf);
|
||||
} catch (...) {}
|
||||
|
||||
// Does the IfcElement have any IfcOpenings?
|
||||
// Note that openings for IfcOpeningElements are not processed
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr openings;
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)ifc_product;
|
||||
openings = element->HasOpenings();
|
||||
}
|
||||
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
|
||||
IfcSchema::IfcBuildingElementPart* part = (IfcSchema::IfcBuildingElementPart*)ifc_product;
|
||||
#ifdef USE_IFC4
|
||||
IfcSchema::IfcRelAggregates::list::ptr decomposes = part->Decomposes();
|
||||
for ( IfcSchema::IfcRelAggregates::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#else
|
||||
IfcSchema::IfcRelDecomposes::list::ptr decomposes = part->Decomposes();
|
||||
for ( IfcSchema::IfcRelDecomposes::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#endif
|
||||
IfcSchema::IfcObjectDefinition* obdef = (*it)->RelatingObject();
|
||||
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)obdef;
|
||||
openings->push(element->HasOpenings());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string product_type = IfcSchema::Type::ToString(ifc_product->type());
|
||||
ElementSettings element_settings(settings, unit_magnitude, product_type);
|
||||
|
||||
if ( !settings.disable_opening_subtractions() && openings && openings->Size() ) {
|
||||
IfcGeom::IfcRepresentationShapeItems opened_shapes;
|
||||
try {
|
||||
if ( settings.faster_booleans() ) {
|
||||
bool succes = kernel.convert_openings_fast(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
if ( ! succes ) {
|
||||
opened_shapes.clear();
|
||||
kernel.convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} else {
|
||||
kernel.convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} catch(...) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity);
|
||||
}
|
||||
if ( settings.use_world_coords() ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
}
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, shaperep->entity->id(), opened_shapes);
|
||||
} else if ( settings.use_world_coords() ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, shaperep->entity->id(), shapes);
|
||||
} else {
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, shaperep->entity->id(), shapes);
|
||||
}
|
||||
|
||||
return new ShapeModelElement<P>(
|
||||
ifc_product->entity->id(),
|
||||
parent_id,
|
||||
name,
|
||||
product_type,
|
||||
guid,
|
||||
trsf,
|
||||
shape
|
||||
);
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,6 +296,10 @@ namespace IfcGeom {
|
||||
// Free all possible representations of the current geometrical entity
|
||||
delete current_triangulation;
|
||||
current_triangulation = 0;
|
||||
delete current_serialization;
|
||||
current_serialization = 0;
|
||||
delete current_shape_model;
|
||||
current_shape_model = 0;
|
||||
|
||||
// Increment the iterator over the list of products using the current
|
||||
// shape representation
|
||||
@@ -541,8 +333,12 @@ namespace IfcGeom {
|
||||
product_guid = ifc_product->GlobalId();
|
||||
product_name = ifc_product->hasName() ? ifc_product->Name() : "";
|
||||
|
||||
parent_id = -1;
|
||||
try {
|
||||
parent_id = _getParentId(ifc_product);
|
||||
IfcSchema::IfcObjectDefinition* parent_object = kernel.get_decomposing_entity(ifc_product);
|
||||
if (parent_object) {
|
||||
parent_id = parent_object->entity->id();
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
try {
|
||||
@@ -554,7 +350,6 @@ namespace IfcGeom {
|
||||
ElementSettings element_settings(settings, unit_magnitude, instance_type);
|
||||
Element<P>* ifc_object = new Element<P>(element_settings, id, parent_id, product_name, instance_type, product_guid, trsf);
|
||||
|
||||
returned_elements.push_back(ifc_object);
|
||||
return ifc_object;
|
||||
}
|
||||
|
||||
@@ -622,15 +417,14 @@ namespace IfcGeom {
|
||||
// TODO: Correctly implement destructor for IfcFile
|
||||
delete ifc_file;
|
||||
|
||||
typename std::vector<Element<P>*>::const_iterator it;
|
||||
for (it = returned_elements.begin(); it != returned_elements.end(); ++ it ) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
returned_elements.clear();
|
||||
delete current_triangulation;
|
||||
current_triangulation = 0;
|
||||
delete current_serialization;
|
||||
current_serialization = 0;
|
||||
delete current_shape_model;
|
||||
current_shape_model = 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
#include "../ifcgeom/IfcGeomRenderStyles.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
|
||||
@@ -30,21 +30,21 @@ bool process_colour(IfcSchema::IfcColourRgb* colour, std::tr1::array<double, 3>&
|
||||
return colour != 0;
|
||||
}
|
||||
|
||||
bool process_colour(IfcUtil::IfcArgumentSelect* factor, std::tr1::array<double, 3>& rgb) {
|
||||
bool process_colour(IfcSchema::IfcNormalisedRatioMeasure* factor, std::tr1::array<double, 3>& rgb) {
|
||||
if (factor != 0) {
|
||||
const double f = *factor->wrappedValue();
|
||||
const double f = *factor;
|
||||
rgb[0] = rgb[1] = rgb[2] = f;
|
||||
}
|
||||
return factor != 0;
|
||||
}
|
||||
|
||||
bool process_colour(IfcSchema::IfcColourOrFactor colour_or_factor, std::tr1::array<double, 3>& rgb) {
|
||||
bool process_colour(IfcSchema::IfcColourOrFactor* colour_or_factor, std::tr1::array<double, 3>& rgb) {
|
||||
if (colour_or_factor == 0) {
|
||||
return false;
|
||||
} else if (colour_or_factor->is(IfcSchema::Type::IfcColourRgb)) {
|
||||
return process_colour(static_cast<IfcSchema::IfcColourRgb*>(colour_or_factor), rgb);
|
||||
} else if (colour_or_factor->is(IfcSchema::Type::IfcNormalisedRatioMeasure)) {
|
||||
return process_colour(static_cast<IfcUtil::IfcArgumentSelect*>(colour_or_factor), rgb);
|
||||
return process_colour(static_cast<IfcSchema::IfcNormalisedRatioMeasure*>(colour_or_factor), rgb);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -86,14 +86,14 @@ const IfcGeom::SurfaceStyle* IfcGeom::Kernel::get_style(const IfcSchema::IfcRepr
|
||||
surface_style.Specular().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
|
||||
}
|
||||
if (rendering_style->hasSpecularHighlight()) {
|
||||
IfcUtil::IfcArgumentSelect* highlight = static_cast<IfcUtil::IfcArgumentSelect*>(rendering_style->SpecularHighlight());
|
||||
IfcSchema::IfcSpecularHighlightSelect* highlight = rendering_style->SpecularHighlight();
|
||||
if (highlight->is(IfcSchema::Type::IfcSpecularRoughness)) {
|
||||
double roughness = *highlight->wrappedValue();
|
||||
double roughness = *((IfcSchema::IfcSpecularRoughness*)highlight);
|
||||
if (roughness >= 1e-9) {
|
||||
surface_style.Specularity().reset(1.0 / roughness);
|
||||
}
|
||||
} else if (highlight->is(IfcSchema::Type::IfcSpecularRoughness)) {
|
||||
surface_style.Specularity().reset(*highlight->wrappedValue());
|
||||
} else if (highlight->is(IfcSchema::Type::IfcSpecularExponent)) {
|
||||
surface_style.Specularity().reset(*((IfcSchema::IfcSpecularExponent*)highlight));
|
||||
}
|
||||
}
|
||||
if (rendering_style->hasTransmissionColour()) {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
@@ -40,8 +41,11 @@ namespace IfcGeom {
|
||||
protected:
|
||||
const ElementSettings _settings;
|
||||
public:
|
||||
explicit Representation(const ElementSettings& settings) : _settings(settings) {}
|
||||
explicit Representation(const ElementSettings& settings)
|
||||
: _settings(settings)
|
||||
{}
|
||||
const ElementSettings& settings() const { return _settings; }
|
||||
virtual ~Representation() {}
|
||||
};
|
||||
|
||||
class BRep : public Representation {
|
||||
|
||||
@@ -253,9 +253,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace* l,
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
|
||||
IfcUtil::IfcAbstractSelect::list::ptr shells = l->SbsmBoundary();
|
||||
IfcEntityList::ptr shells = l->SbsmBoundary();
|
||||
const SurfaceStyle* collective_style = get_style(l);
|
||||
for( IfcUtil::IfcAbstractSelect::list::it it = shells->begin(); it != shells->end(); ++ it ) {
|
||||
for( IfcEntityList::it it = shells->begin(); it != shells->end(); ++ it ) {
|
||||
TopoDS_Shape s;
|
||||
const SurfaceStyle* shell_style = 0;
|
||||
if ((*it)->is(IfcSchema::Type::IfcRepresentationItem)) {
|
||||
@@ -272,8 +272,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
|
||||
TopoDS_Shape s1, s2;
|
||||
IfcRepresentationShapeItems items1, items2;
|
||||
TopoDS_Wire boundary_wire;
|
||||
IfcSchema::IfcBooleanOperand operand1 = l->FirstOperand();
|
||||
IfcSchema::IfcBooleanOperand operand2 = l->SecondOperand();
|
||||
IfcSchema::IfcBooleanOperand* operand1 = l->FirstOperand();
|
||||
IfcSchema::IfcBooleanOperand* operand2 = l->SecondOperand();
|
||||
bool is_halfspace = operand2->is(IfcSchema::Type::IfcHalfSpaceSolid);
|
||||
|
||||
if ( is_shape_collection(operand1) ) {
|
||||
@@ -467,7 +467,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentati
|
||||
gtrsf = (gp_Trsf) trsf_2d;
|
||||
}
|
||||
IfcSchema::IfcRepresentationMap* map = l->MappingSource();
|
||||
IfcSchema::IfcAxis2Placement placement = map->MappingOrigin();
|
||||
IfcSchema::IfcAxis2Placement* placement = map->MappingOrigin();
|
||||
gp_Trsf trsf;
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
@@ -506,12 +506,12 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcShapeRepresentation* l, IfcRep
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresentationShapeItems& shapes) {
|
||||
IfcUtil::IfcAbstractSelect::list::ptr elements = l->Elements();
|
||||
IfcEntityList::ptr elements = l->Elements();
|
||||
if ( !elements->Size() ) return false;
|
||||
bool part_succes = false;
|
||||
const IfcGeom::SurfaceStyle* parent_style = get_style(l);
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = elements->begin(); it != elements->end(); ++ it ) {
|
||||
IfcSchema::IfcGeometricSetSelect element = *it;
|
||||
for ( IfcEntityList::it it = elements->begin(); it != elements->end(); ++ it ) {
|
||||
IfcSchema::IfcGeometricSetSelect* element = *it;
|
||||
if (element->is(IfcSchema::Type::IfcSurface)) {
|
||||
IfcSchema::IfcSurface* surface = (IfcSchema::IfcSurface*) element;
|
||||
TopoDS_Shape s;
|
||||
|
||||
@@ -180,8 +180,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
|
||||
Handle(Geom_Curve) curve;
|
||||
if ( !convert_curve(basis_curve,curve) ) return false;
|
||||
bool trim_cartesian = l->MasterRepresentation() == IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN;
|
||||
IfcUtil::IfcAbstractSelect::list::ptr trims1 = l->Trim1();
|
||||
IfcUtil::IfcAbstractSelect::list::ptr trims2 = l->Trim2();
|
||||
IfcEntityList::ptr trims1 = l->Trim1();
|
||||
IfcEntityList::ptr trims2 = l->Trim2();
|
||||
bool trimmed1 = false;
|
||||
bool trimmed2 = false;
|
||||
unsigned sense_agreement = l->SenseAgreement() ? 0 : 1;
|
||||
@@ -190,24 +190,24 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
|
||||
bool has_flts[2] = {false,false};
|
||||
bool has_pnts[2] = {false,false};
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = trims1->begin(); it != trims1->end(); it ++ ) {
|
||||
IfcUtil::IfcAbstractSelect* i = *it;
|
||||
for ( IfcEntityList::it it = trims1->begin(); it != trims1->end(); it ++ ) {
|
||||
IfcUtil::IfcBaseClass* i = *it;
|
||||
if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[sense_agreement] );
|
||||
has_pnts[sense_agreement] = true;
|
||||
} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
|
||||
const double value = *((IfcUtil::IfcArgumentSelect*)i)->wrappedValue();
|
||||
const double value = *((IfcSchema::IfcParameterValue*)i);
|
||||
flts[sense_agreement] = value * parameterFactor;
|
||||
has_flts[sense_agreement] = true;
|
||||
}
|
||||
}
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = trims2->begin(); it != trims2->end(); it ++ ) {
|
||||
IfcUtil::IfcAbstractSelect* i = *it;
|
||||
for ( IfcEntityList::it it = trims2->begin(); it != trims2->end(); it ++ ) {
|
||||
IfcUtil::IfcBaseClass* i = *it;
|
||||
if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[1-sense_agreement] );
|
||||
has_pnts[1-sense_agreement] = true;
|
||||
} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
|
||||
const double value = *((IfcUtil::IfcArgumentSelect*)i)->wrappedValue();
|
||||
const double value = *((IfcSchema::IfcParameterValue*)i);
|
||||
flts[1-sense_agreement] = value * parameterFactor;
|
||||
has_flts[1-sense_agreement] = true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# 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/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import os
|
||||
import functools
|
||||
|
||||
from . import guid
|
||||
from . import ifcopenshell_wrapper
|
||||
|
||||
if hasattr(functools, 'reduce'): reduce = functools.reduce
|
||||
|
||||
class entity_instance(object):
|
||||
def __init__(self, e):
|
||||
super(entity_instance, self).__setattr__('wrapped_data', e)
|
||||
def __getattr__(self, name):
|
||||
try: return entity_instance.wrap_value(self.wrapped_data.get_argument(self.wrapped_data.get_argument_index(name)))
|
||||
except:
|
||||
try: return entity_instance.wrap_value(self.wrapped_data.get_inverse(name))
|
||||
except: raise AttributeError("entity instance of type '%s' has no attribute '%s'"%(self.wrapped_data.is_a(), name))
|
||||
@staticmethod
|
||||
def map_value(v):
|
||||
if isinstance(v, entity_instance): return v.wrapped_data
|
||||
elif isinstance(v, (tuple, list)) and len(v):
|
||||
classes = list(map(type, v))
|
||||
if float in classes: return ifcopenshell_wrapper.double_vector(v)
|
||||
elif int in classes: return ifcopenshell_wrapper.int_vector(v)
|
||||
elif str in classes: return ifcopenshell_wrapper.string_vector(v)
|
||||
elif entity_instance in classes: return list(map(lambda e: e.wrapped_data, v))
|
||||
return v
|
||||
@staticmethod
|
||||
def wrap_value(v):
|
||||
wrap = lambda e: entity_instance(e)
|
||||
if isinstance(v, ifcopenshell_wrapper.entity_instance): return wrap(v)
|
||||
elif isinstance(v, (tuple, list)) and len(v):
|
||||
classes = list(map(type, v))
|
||||
if ifcopenshell_wrapper.entity_instance in classes: return list(map(wrap, v))
|
||||
return v
|
||||
def attribute_type(self, attr):
|
||||
attr_idx = attr if isinstance(attr, int) else self.wrapped_data.get_argument_index(attr)
|
||||
return self.wrapped_data.get_argument_type(attr_idx)
|
||||
def attribute_name(self, attr_idx):
|
||||
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):
|
||||
return entity_instance.wrap_value(self.wrapped_data.get_argument(key))
|
||||
def __setitem__(self, idx, value):
|
||||
self.wrapped_data.set_argument(idx, entity_instance.map_value(value))
|
||||
def __len__(self): return len(self.wrapped_data)
|
||||
def __repr__(self): return repr(self.wrapped_data)
|
||||
def is_a(self, *args): return self.wrapped_data.is_a(*args)
|
||||
def id(self): return self.wrapped_data.id()
|
||||
|
||||
|
||||
class file(object):
|
||||
instances = []
|
||||
def __init__(self, f=None):
|
||||
self.wrapped_data = f or ifcopenshell_wrapper.file(True)
|
||||
def create_entity(self,type,*args,**kwargs):
|
||||
e = entity_instance(ifcopenshell_wrapper.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
|
||||
self.wrapped_data.add(e.wrapped_data)
|
||||
self.instances.append(e)
|
||||
return e
|
||||
def __getattr__(self,attr):
|
||||
if attr[0:6] == 'create': return functools.partial(self.create_entity,attr[6:])
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, int):
|
||||
return entity_instance(self.wrapped_data.by_id(key))
|
||||
elif isinstance(key, str):
|
||||
return entity_instance(self.wrapped_data.by_guid(key))
|
||||
def by_type(self, type):
|
||||
return [entity_instance(e) for e in self.wrapped_data.by_type(type)]
|
||||
def write(self, fn):
|
||||
self.wrapped_data.write(fn)
|
||||
def __iter__(self):
|
||||
return iter(self[id] for id in self.wrapped_data.entity_names())
|
||||
|
||||
|
||||
def open(fn=None):
|
||||
return file(ifcopenshell_wrapper.open(os.path.abspath(fn))) if fn else file()
|
||||
|
||||
|
||||
def create_entity(type,*args,**kwargs):
|
||||
e = entity_instance(ifcopenshell_wrapper.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
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# 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/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from .. import ifcopenshell_wrapper
|
||||
|
||||
settings = ifcopenshell_wrapper.settings
|
||||
|
||||
# Hide templating precision to the user by choosing based on Python's
|
||||
# internal float type. This is probably always going to be a double.
|
||||
for ty in (ifcopenshell_wrapper.iterator_single_precision, ifcopenshell_wrapper.iterator_double_precision):
|
||||
if ty.mantissa_size() == sys.float_info.mant_dig:
|
||||
_iterator = ty
|
||||
|
||||
|
||||
# Make sure people are able to use python's platform agnostic paths
|
||||
class iterator(_iterator):
|
||||
def __init__(self, settings, filename):
|
||||
_iterator.__init__(self, settings, os.path.abspath(filename))
|
||||
|
||||
|
||||
def create_shape(settings, inst):
|
||||
return ifcopenshell_wrapper.create_shape(settings, inst.wrapped_data)
|
||||
|
||||
|
||||
def iterate(settings, filename):
|
||||
it = iterator(settings, filename)
|
||||
if not it.findContext(): return None
|
||||
while True:
|
||||
yield it.get()
|
||||
if not it.next(): break
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# 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/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import string
|
||||
|
||||
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:])
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC2X3_TC1.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFC2X3RT_H
|
||||
#define IFC2X3RT_H
|
||||
|
||||
#define IfcSchema Ifc2x3
|
||||
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcEntityDescriptor.h"
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
|
||||
namespace Ifc2x3 {
|
||||
namespace Type {
|
||||
int GetAttributeCount(Enum t);
|
||||
int GetAttributeIndex(Enum t, const std::string& a);
|
||||
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
|
||||
const std::string& GetAttributeName(Enum t, unsigned char a);
|
||||
bool GetAttributeOptional(Enum t, unsigned char a);
|
||||
bool GetAttributeDerived(Enum t, unsigned char a);
|
||||
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
|
||||
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
|
||||
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
|
||||
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
|
||||
}}
|
||||
|
||||
#endif
|
||||
+3666
-2262
File diff suppressed because one or more lines are too long
+4235
-3065
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 it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file has been generated from IFC4.exp. Do not make modifications *
|
||||
* but instead modify the python script that has been used to generate this. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFC4RT_H
|
||||
#define IFC4RT_H
|
||||
|
||||
#define IfcSchema Ifc4
|
||||
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcEntityDescriptor.h"
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
|
||||
namespace Ifc4 {
|
||||
namespace Type {
|
||||
int GetAttributeCount(Enum t);
|
||||
int GetAttributeIndex(Enum t, const std::string& a);
|
||||
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
|
||||
const std::string& GetAttributeName(Enum t, unsigned char a);
|
||||
bool GetAttributeOptional(Enum t, unsigned char a);
|
||||
bool GetAttributeDerived(Enum t, unsigned char a);
|
||||
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
|
||||
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
|
||||
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
|
||||
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
|
||||
}}
|
||||
|
||||
#endif
|
||||
+5389
-3842
File diff suppressed because one or more lines are too long
+4573
-3313
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "../ifcparse/IfcCharacterDecoder.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcSpfStream.h"
|
||||
|
||||
#define FIRST_SOLIDUS (1 << 1)
|
||||
#define PAGE (1 << 2)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
typedef unsigned int UChar32;
|
||||
#endif
|
||||
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcSpfStream.h"
|
||||
|
||||
namespace IfcParse {
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCENTITYDESCRIPTOR_H
|
||||
#define IFCENTITYDESCRIPTOR_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../ifcparse/SharedPointer.h"
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
|
||||
#ifdef USE_IFC4
|
||||
#include "../ifcparse/Ifc4enum.h"
|
||||
#else
|
||||
#include "../ifcparse/Ifc2x3enum.h"
|
||||
#endif
|
||||
|
||||
namespace IfcUtil {
|
||||
|
||||
class IfcEnumerationDescriptor {
|
||||
private:
|
||||
IfcSchema::Type::Enum type;
|
||||
std::vector<std::string> values;
|
||||
public:
|
||||
IfcEnumerationDescriptor(IfcSchema::Type::Enum type, const std::vector<std::string>& values)
|
||||
: type(type), values(values) {}
|
||||
std::pair<const char*, int> getIndex(const std::string& value) const {
|
||||
std::vector<std::string>::const_iterator it = std::find(values.begin(), values.end(), value);
|
||||
if (it != values.end()) {
|
||||
return std::make_pair(it->c_str(), std::distance(it, values.begin()));
|
||||
} else {
|
||||
throw IfcParse::IfcException("Invalid enumeration value");
|
||||
}
|
||||
}
|
||||
const std::vector<std::string>& getValues() {
|
||||
return values;
|
||||
}
|
||||
IfcSchema::Type::Enum getType() {
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
class IfcEntityDescriptor {
|
||||
public:
|
||||
class IfcArgumentDescriptor
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
bool optional;
|
||||
ArgumentType argument_type;
|
||||
IfcSchema::Type::Enum data_type;
|
||||
IfcArgumentDescriptor(const std::string& name, bool optional, ArgumentType argument_type, IfcSchema::Type::Enum data_type)
|
||||
: name(name), optional(optional), argument_type(argument_type), data_type(data_type) {}
|
||||
};
|
||||
private:
|
||||
IfcSchema::Type::Enum type;
|
||||
IfcEntityDescriptor* parent;
|
||||
std::vector<IfcArgumentDescriptor> arguments;
|
||||
unsigned argument_start() const {
|
||||
return parent ? parent->getArgumentCount() : 0;
|
||||
}
|
||||
const IfcArgumentDescriptor& get_argument(unsigned i) const {
|
||||
if (i < arguments.size()) return arguments[i];
|
||||
else throw IfcParse::IfcException("Argument out of range");
|
||||
}
|
||||
public:
|
||||
IfcEntityDescriptor(IfcSchema::Type::Enum type, IfcEntityDescriptor* parent)
|
||||
: type(type), parent(parent) {}
|
||||
void add(const std::string& name, bool optional, ArgumentType argument_type, IfcSchema::Type::Enum data_type = IfcSchema::Type::ALL) {
|
||||
arguments.push_back(IfcArgumentDescriptor(name, optional, argument_type, data_type));
|
||||
}
|
||||
unsigned getArgumentCount() const {
|
||||
return (parent ? parent->getArgumentCount() : 0) + arguments.size();
|
||||
}
|
||||
const std::string& getArgumentName(unsigned i) const {
|
||||
const unsigned a = argument_start();
|
||||
return i < a
|
||||
? parent->getArgumentName(i)
|
||||
: get_argument(i-a).name;
|
||||
}
|
||||
ArgumentType getArgumentType(unsigned i) const {
|
||||
const unsigned a = argument_start();
|
||||
return i < a
|
||||
? parent->getArgumentType(i)
|
||||
: get_argument(i-a).argument_type;
|
||||
}
|
||||
bool getArgumentOptional(unsigned i) const {
|
||||
const unsigned a = argument_start();
|
||||
return i < a
|
||||
? parent->getArgumentOptional(i)
|
||||
: get_argument(i-a).optional;
|
||||
}
|
||||
IfcSchema::Type::Enum getArgumentEnumerationClass(unsigned i) const {
|
||||
const unsigned a = argument_start();
|
||||
return i < a
|
||||
? parent->getArgumentEnumerationClass(i)
|
||||
: get_argument(i-a).data_type;
|
||||
}
|
||||
unsigned getArgumentIndex(const std::string& s) const {
|
||||
unsigned a = argument_start();
|
||||
for(std::vector<IfcArgumentDescriptor>::const_iterator i = arguments.begin(); i != arguments.end(); ++i) {
|
||||
if (i->name == s) return a;
|
||||
a++;
|
||||
}
|
||||
if (parent) return parent->getArgumentIndex(s);
|
||||
throw IfcParse::IfcException(std::string("Argument ") + s + " not found on " + IfcSchema::Type::ToString(type));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+99
-56
@@ -1,4 +1,4 @@
|
||||
/********************************************************************************
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
@@ -16,66 +16,109 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* Reads a file in chunks of BUF_SIZE and provides functions to access its *
|
||||
* contents randomly and character by character *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
#ifndef IFCFILE_H
|
||||
#define IFCFILE_H
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
// As of IfcOpenShell version 0.3.0 the paging functionality, which
|
||||
// loads a file on disk into multiple chunks, has been disabled.
|
||||
// It proved to be an inefficient way of working with large files,
|
||||
// as often these did not facilitate to be parsed in a sequential
|
||||
// manner efficiently. To enable the paging functionality uncomment
|
||||
// the following statement.
|
||||
// #define BUF_SIZE (8 * 1024 * 1024)
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
|
||||
namespace IfcParse {
|
||||
/// The IfcSpfStream class represents a ISO 10303-21 IFC-SPF file in memory.
|
||||
/// The file is interpreted as a sequence of tokens which are lazily
|
||||
/// interpreted only when requested. If the size of the file is
|
||||
/// larger than BUF_SIZE, the file is split into seperate pages, of
|
||||
/// which only one is simultaneously kept in memory, for files
|
||||
/// that define their entities not in a sequential nature, this is
|
||||
/// detrimental for the performance of the parser.
|
||||
class IfcSpfStream {
|
||||
private:
|
||||
FILE* stream;
|
||||
char* buffer;
|
||||
unsigned int ptr;
|
||||
unsigned int len;
|
||||
void ReadBuffer(bool inc=true);
|
||||
#ifdef BUF_SIZE
|
||||
unsigned int offset;
|
||||
bool paging;
|
||||
#endif
|
||||
public:
|
||||
bool valid;
|
||||
bool eof;
|
||||
unsigned int size;
|
||||
IfcSpfStream(const std::string& fn);
|
||||
IfcSpfStream(std::istream& f, int len);
|
||||
IfcSpfStream(void* data, int len);
|
||||
/// Returns the character at the cursor
|
||||
char Peek();
|
||||
/// Returns the character at specified offset
|
||||
char Read(unsigned int offset);
|
||||
/// Increment the file cursor and reads new page if necessary
|
||||
void Inc();
|
||||
void Close();
|
||||
/// Moves the file cursor to an arbitrary offset in the file
|
||||
void Seek(unsigned int offset);
|
||||
/// Returns the cursor position
|
||||
unsigned int Tell();
|
||||
};
|
||||
|
||||
/// This class provides several static convenience functions and variables
|
||||
/// and provide access to the entities in an IFC file
|
||||
class IfcFile {
|
||||
public:
|
||||
typedef std::map<IfcSchema::Type::Enum, IfcEntityList::ptr> entities_by_type_t;
|
||||
typedef std::map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
|
||||
typedef std::map<std::string, IfcSchema::IfcRoot*> entity_by_guid_t;
|
||||
typedef std::map<unsigned int, IfcEntityList::ptr> entities_by_ref_t;
|
||||
typedef std::map<unsigned int, unsigned int> offset_by_id_t;
|
||||
typedef entity_by_id_t::const_iterator const_iterator;
|
||||
private:
|
||||
bool _create_latebound_entities;
|
||||
|
||||
entity_by_id_t byid;
|
||||
entities_by_type_t bytype;
|
||||
entities_by_ref_t byref;
|
||||
entity_by_guid_t byguid;
|
||||
offset_by_id_t offsets;
|
||||
|
||||
unsigned int lastId;
|
||||
unsigned int MaxId;
|
||||
|
||||
std::string _filename;
|
||||
std::string _timestamp;
|
||||
std::string _author;
|
||||
std::string _author_email;
|
||||
std::string _author_organisation;
|
||||
|
||||
void initTimestamp();
|
||||
public:
|
||||
IfcParse::Tokens* tokens;
|
||||
IfcParse::IfcSpfStream* stream;
|
||||
|
||||
IfcFile(bool create_latebound_entities = false);
|
||||
~IfcFile();
|
||||
|
||||
/// Returns the first entity in the file, this probably is the entity with the lowest id (EXPRESS ENTITY_INSTANCE_NAME)
|
||||
const_iterator begin() const;
|
||||
/// Returns the last entity in the file, this probably is the entity with the highes id (EXPRESS ENTITY_INSTANCE_NAME)
|
||||
const_iterator end() const;
|
||||
|
||||
/// Returns all entities in the file that match the template argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
/// IfcWall will also return IfcWallStandardCase entities
|
||||
template <class T>
|
||||
typename T::list::ptr EntitiesByType() {
|
||||
IfcEntityList::ptr e = EntitiesByType(T::Class());
|
||||
typename T::list::ptr l(new typename T::list);
|
||||
if (e && e->Size()) {
|
||||
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) {
|
||||
l->push((T*)*it);
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/// Returns all entities in the file that match the positional argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
/// IfcWall will also return IfcWallStandardCase entities
|
||||
IfcEntityList::ptr EntitiesByType(IfcSchema::Type::Enum t);
|
||||
/// Returns all entities in the file that match the positional argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
/// IfcWall will also return IfcWallStandardCase entities
|
||||
IfcEntityList::ptr EntitiesByType(const std::string& t);
|
||||
/// Returns all entities in the file that reference the id
|
||||
IfcEntityList::ptr EntitiesByReference(int id);
|
||||
/// Returns the entity with the specified id
|
||||
IfcUtil::IfcBaseClass* EntityById(int id);
|
||||
/// Returns the entity with the specified GlobalId
|
||||
IfcSchema::IfcRoot* EntityByGuid(const std::string& guid);
|
||||
|
||||
bool Init(const std::string& fn);
|
||||
bool Init(std::istream& fn, int len);
|
||||
bool Init(void* data, int len);
|
||||
bool Init(IfcParse::IfcSpfStream* f);
|
||||
|
||||
unsigned int FreshId() { MaxId ++; return MaxId; }
|
||||
|
||||
void AddEntity(IfcUtil::IfcBaseClass* entity);
|
||||
void AddEntities(IfcEntityList::ptr es);
|
||||
|
||||
void filename(const std::string& s);
|
||||
std::string filename() const;
|
||||
void timestamp(const std::string& s);
|
||||
std::string timestamp() const;
|
||||
void author(const std::string& name, const std::string& email, const std::string& organisation);
|
||||
std::string authorName() const;
|
||||
std::string authorEmail() const;
|
||||
std::string authorOrganisation() const;
|
||||
|
||||
bool create_latebound_entities() const { return _create_latebound_entities; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -397,10 +397,10 @@ void IfcHierarchyHelper::clipRepresentation(IfcSchema::IfcRepresentation* rep,
|
||||
IfcSchema::IfcPresentationStyleAssignment* IfcHierarchyHelper::addStyleAssignment(double r, double g, double b, double a) {
|
||||
IfcSchema::IfcColourRgb* colour = new IfcSchema::IfcColourRgb(boost::none, r, g, b);
|
||||
IfcSchema::IfcSurfaceStyleRendering* rendering = a == 1.0
|
||||
? new IfcSchema::IfcSurfaceStyleRendering(colour, boost::none, boost::none, boost::none, boost::none, boost::none,
|
||||
boost::none, boost::none, IfcSchema::IfcReflectanceMethodEnum::IfcReflectanceMethod_FLAT)
|
||||
: new IfcSchema::IfcSurfaceStyleRendering(colour, 1.0-a, boost::none, boost::none, boost::none, boost::none,
|
||||
boost::none, boost::none, IfcSchema::IfcReflectanceMethodEnum::IfcReflectanceMethod_FLAT);
|
||||
? new IfcSchema::IfcSurfaceStyleRendering(colour, boost::none, 0, 0, 0, 0,
|
||||
0, 0, IfcSchema::IfcReflectanceMethodEnum::IfcReflectanceMethod_FLAT)
|
||||
: new IfcSchema::IfcSurfaceStyleRendering(colour, 1.0-a, 0, 0, 0, 0,
|
||||
0, 0, IfcSchema::IfcReflectanceMethodEnum::IfcReflectanceMethod_FLAT);
|
||||
|
||||
IfcEntityList::ptr styles(new IfcEntityList());
|
||||
styles->push(rendering);
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcWrite.h"
|
||||
|
||||
#ifdef USE_IFC4
|
||||
#include "../ifcparse/Ifc4-latebound.h"
|
||||
#else
|
||||
#include "../ifcparse/Ifc2x3-latebound.h"
|
||||
#endif
|
||||
|
||||
#include "IfcLateBoundEntity.h"
|
||||
|
||||
using namespace IfcUtil;
|
||||
|
||||
IfcWrite::IfcWritableEntity* IfcParse::IfcLateBoundEntity::writable_entity() {
|
||||
IfcWrite::IfcWritableEntity* e;
|
||||
if (entity->isWritable()) {
|
||||
e = (IfcWrite::IfcWritableEntity*) entity;
|
||||
} else {
|
||||
entity = e = new IfcWrite::IfcWritableEntity(entity);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
IfcParse::IfcLateBoundEntity::IfcLateBoundEntity(const std::string& s) {
|
||||
std::string S = s;
|
||||
for (std::string::iterator i = S.begin(); i != S.end(); ++i ) *i = toupper(*i);
|
||||
_type = IfcSchema::Type::FromString(S);
|
||||
entity = new IfcWrite::IfcWritableEntity(_type);
|
||||
IfcSchema::Type::PopulateDerivedFields(writable_entity());
|
||||
}
|
||||
IfcParse::IfcLateBoundEntity::IfcLateBoundEntity(IfcAbstractEntity* e) {
|
||||
entity = e;
|
||||
_type = e->type();
|
||||
}
|
||||
unsigned int IfcParse::IfcLateBoundEntity::id() const {
|
||||
if (entity->file) {
|
||||
return static_cast<unsigned int>(entity->id());
|
||||
} else {
|
||||
throw IfcException("Entity not bound to a file");
|
||||
}
|
||||
}
|
||||
bool IfcParse::IfcLateBoundEntity::is(IfcSchema::Type::Enum v) const {
|
||||
IfcSchema::Type::Enum _ty = _type;
|
||||
if (v == _ty) return true;
|
||||
while (_ty != -1) {
|
||||
_ty = IfcSchema::Type::Parent(_ty);
|
||||
if (v == _ty) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
std::string IfcParse::IfcLateBoundEntity::is_a() const {
|
||||
return IfcSchema::Type::ToString(_type);
|
||||
}
|
||||
bool IfcParse::IfcLateBoundEntity::is_a(const std::string& s) const {
|
||||
std::string S = s;
|
||||
for (std::string::iterator i = S.begin(); i != S.end(); ++i ) *i = toupper(*i);
|
||||
return is(IfcSchema::Type::FromString(S));
|
||||
}
|
||||
IfcSchema::Type::Enum IfcParse::IfcLateBoundEntity::type() const {
|
||||
return _type;
|
||||
}
|
||||
unsigned int IfcParse::IfcLateBoundEntity::getArgumentCount() const {
|
||||
return IfcSchema::Type::GetAttributeCount(_type);
|
||||
}
|
||||
IfcUtil::ArgumentType IfcParse::IfcLateBoundEntity::getArgumentType(unsigned int i) const {
|
||||
return IfcSchema::Type::GetAttributeDerived(_type, i)
|
||||
? IfcUtil::Argument_DERIVED
|
||||
: IfcSchema::Type::GetAttributeType(_type,i);
|
||||
}
|
||||
Argument* IfcParse::IfcLateBoundEntity::getArgument(unsigned int i) const {
|
||||
return entity->getArgument(i);
|
||||
}
|
||||
const char* IfcParse::IfcLateBoundEntity::getArgumentName(unsigned int i) const {
|
||||
return IfcSchema::Type::GetAttributeName(_type,i).c_str();
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::invalid_argument(unsigned int i, const std::string& t) {
|
||||
const std::string arg_name = IfcSchema::Type::GetAttributeName(_type,i);
|
||||
throw IfcException(t + " is not a valid type for '" + arg_name + "'");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i) {
|
||||
bool is_optional = IfcSchema::Type::GetAttributeOptional(_type, i);
|
||||
if (is_optional) {
|
||||
writable_entity()->setArgument(i);
|
||||
} else invalid_argument(i,"NULL");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, int v) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_INT) {
|
||||
writable_entity()->setArgument(i,v);
|
||||
} else if ( (arg_type == Argument_BOOL) && ( (v == 0) || (v == 1) ) ) {
|
||||
writable_entity()->setArgument(i, v == 1);
|
||||
} else invalid_argument(i,"INT");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, bool v) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_BOOL) {
|
||||
writable_entity()->setArgument(i,v);
|
||||
} else invalid_argument(i,"BOOL");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, double v) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_DOUBLE) {
|
||||
writable_entity()->setArgument(i,v);
|
||||
} else invalid_argument(i,"DOUBLE");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, const std::string& a) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_STRING) {
|
||||
writable_entity()->setArgument(i,a);
|
||||
} else if (arg_type == Argument_ENUMERATION) {
|
||||
std::pair<const char*, int> enum_data = IfcSchema::Type::GetEnumerationIndex(IfcSchema::Type::GetAttributeEnumerationClass(_type, i), a);
|
||||
writable_entity()->setArgument(i, enum_data.second, enum_data.first);
|
||||
} else invalid_argument(i,"STRING");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, const std::vector<int>& v) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_VECTOR_INT) {
|
||||
writable_entity()->setArgument(i,v);
|
||||
} else invalid_argument(i,"LIST of INT");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, const std::vector<double>& v) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_VECTOR_DOUBLE) {
|
||||
writable_entity()->setArgument(i,v);
|
||||
} else invalid_argument(i,"LIST of DOUBLE");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, const std::vector<std::string>& v) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_VECTOR_STRING) {
|
||||
writable_entity()->setArgument(i,v);
|
||||
} else invalid_argument(i,"LIST of STRING");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, IfcParse::IfcLateBoundEntity* v) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_ENTITY) {
|
||||
writable_entity()->setArgument(i,v);
|
||||
} else invalid_argument(i,"ENTITY");
|
||||
}
|
||||
void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, IfcEntityList::ptr v) {
|
||||
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
|
||||
if (arg_type == Argument_ENTITY_LIST) {
|
||||
writable_entity()->setArgument(i,v);
|
||||
} else invalid_argument(i,"LIST of ENTITY");
|
||||
}
|
||||
std::pair<IfcUtil::ArgumentType,Argument*> IfcParse::IfcLateBoundEntity::get_argument(unsigned i) {
|
||||
return std::pair<IfcUtil::ArgumentType,Argument*>(getArgumentType(i),getArgument(i));
|
||||
}
|
||||
std::pair<IfcUtil::ArgumentType,Argument*> IfcParse::IfcLateBoundEntity::get_argument(const std::string& a) {
|
||||
return get_argument(IfcSchema::Type::GetAttributeIndex(_type,a));
|
||||
}
|
||||
unsigned IfcParse::IfcLateBoundEntity::getArgumentIndex(const std::string& a) const {
|
||||
return IfcSchema::Type::GetAttributeIndex(_type,a);
|
||||
}
|
||||
std::string IfcParse::IfcLateBoundEntity::toString() {
|
||||
return entity->toString(false);
|
||||
}
|
||||
IfcEntityList::ptr IfcParse::IfcLateBoundEntity::get_inverse(const std::string& a) {
|
||||
std::pair<IfcSchema::Type::Enum, unsigned> inv = IfcSchema::Type::GetInverseAttribute(_type, a);
|
||||
IfcEntityList::ptr invs = entity->getInverse(inv.first);
|
||||
IfcEntityList::ptr filtered(new IfcEntityList());
|
||||
for (IfcEntityList::it it = invs->begin(); it != invs->end(); ++it) {
|
||||
try {
|
||||
const int id = *(*it)->entity->getArgument(inv.second);
|
||||
if (id == this->entity->id()) { filtered->push(*it); }
|
||||
} catch (...) {}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
bool IfcParse::IfcLateBoundEntity::is_valid() {
|
||||
const unsigned arg_count = getArgumentCount();
|
||||
bool valid = true;
|
||||
std::ostringstream oss;
|
||||
oss << "Argument ";
|
||||
for (unsigned i = 0; i < arg_count; ++i) {
|
||||
bool is_null = true;
|
||||
try {
|
||||
const Argument& arg = *getArgument(i);
|
||||
is_null = arg.isNull();
|
||||
} catch(IfcException) {}
|
||||
if (!IfcSchema::Type::GetAttributeOptional(_type,i) && is_null) {
|
||||
if (!valid) {
|
||||
oss << ", ";
|
||||
}
|
||||
oss << "\"" << getArgumentName(i) << "\"";
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
oss << " not optional";
|
||||
if (!valid) {
|
||||
throw IfcException(oss.str());
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCLATEBOUNDENTITY_H
|
||||
#define IFCLATEBOUNDENTITY_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcWrite.h"
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
|
||||
namespace IfcParse {
|
||||
|
||||
// TODO: Somehow these methods should become part of IfcBaseEntity directly so
|
||||
// that in the IfcFile class the distinction what entity type to be created is
|
||||
// no longer necessary and weird diagonal casts when creating geometry from
|
||||
// IfcLateBoundEntities are eliminated.
|
||||
class IfcLateBoundEntity : public IfcUtil::IfcBaseEntity {
|
||||
private:
|
||||
IfcSchema::Type::Enum _type;
|
||||
IfcWrite::IfcWritableEntity* writable_entity();
|
||||
void invalid_argument(unsigned int i, const std::string& t);
|
||||
public:
|
||||
IfcLateBoundEntity(const std::string& s);
|
||||
IfcLateBoundEntity(IfcAbstractEntity* e);
|
||||
|
||||
bool is(IfcSchema::Type::Enum v) const;
|
||||
IfcSchema::Type::Enum type() const;
|
||||
bool is_a(const std::string& s) const;
|
||||
std::string is_a() const;
|
||||
|
||||
unsigned int id() const;
|
||||
unsigned int getArgumentCount() const;
|
||||
IfcUtil::ArgumentType getArgumentType(unsigned int i) const;
|
||||
Argument* getArgument(unsigned int i) const;
|
||||
const char* getArgumentName(unsigned int i) const;
|
||||
unsigned getArgumentIndex(const std::string& a) const;
|
||||
|
||||
IfcEntityList::ptr get_inverse(const std::string& a);
|
||||
|
||||
void setArgument(unsigned int i);
|
||||
void setArgument(unsigned int i, int v);
|
||||
void setArgument(unsigned int i, bool v);
|
||||
void setArgument(unsigned int i, double v);
|
||||
void setArgument(unsigned int i, const std::string& v);
|
||||
void setArgument(unsigned int i, const std::vector<int>& v);
|
||||
void setArgument(unsigned int i, const std::vector<double>& v);
|
||||
void setArgument(unsigned int i, const std::vector<std::string>& v);
|
||||
void setArgument(unsigned int i, IfcLateBoundEntity* v);
|
||||
void setArgument(unsigned int i, IfcEntityList::ptr v);
|
||||
|
||||
std::string toString();
|
||||
|
||||
// TODO: Write as SWIG extension methods?
|
||||
std::pair<IfcUtil::ArgumentType,Argument*> get_argument(unsigned i);
|
||||
std::pair<IfcUtil::ArgumentType,Argument*> get_argument(const std::string& a);
|
||||
|
||||
bool is_valid();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+39
-40
@@ -31,8 +31,10 @@
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcSpfStream.h"
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
#include "../ifcparse/IfcLateBoundEntity.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
using namespace IfcParse;
|
||||
|
||||
@@ -404,8 +406,13 @@ TokenArgument::TokenArgument(const Token& t) {
|
||||
token = t;
|
||||
}
|
||||
|
||||
EntityArgument::EntityArgument(IfcSchema::Type::Enum ty, const Token& t) {
|
||||
entity = new IfcUtil::IfcArgumentSelect(ty,new TokenArgument(t));
|
||||
EntityArgument::EntityArgument(const Token& t) {
|
||||
IfcParse::IfcFile* file = t.first->file;
|
||||
if (file->create_latebound_entities()) {
|
||||
entity = new IfcLateBoundEntity(new Entity(0, file, t.second));
|
||||
} else {
|
||||
entity = IfcSchema::SchemaEntity(new Entity(0, file, t.second));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -413,6 +420,8 @@ EntityArgument::EntityArgument(IfcSchema::Type::Enum ty, const Token& t) {
|
||||
// Aditionally, stores the ids (i.e. #[\d]+) in a vector
|
||||
//
|
||||
ArgumentList::ArgumentList(Tokens* t, std::vector<unsigned int>& ids) {
|
||||
IfcParse::IfcFile* file = t->file;
|
||||
|
||||
Token next = t->Next();
|
||||
while( next.second || next.first ) {
|
||||
if ( TokenFunc::isOperator(next,',') ) {}
|
||||
@@ -423,11 +432,10 @@ ArgumentList::ArgumentList(Tokens* t, std::vector<unsigned int>& ids) {
|
||||
if ( TokenFunc::isDatatype(next) ) {
|
||||
t->Next();
|
||||
try {
|
||||
Push ( new EntityArgument(IfcSchema::Type::FromString(TokenFunc::asString(next)),t->Next()) );
|
||||
Push ( new EntityArgument(next) );
|
||||
} catch ( IfcException& e ) {
|
||||
Logger::Message(Logger::LOG_ERROR,e.what());
|
||||
}
|
||||
t->Next();
|
||||
} else {
|
||||
Push ( new TokenArgument(next) );
|
||||
}
|
||||
@@ -592,29 +600,14 @@ EntityArgument::operator std::string() const { throw IfcException("Argument is n
|
||||
EntityArgument::operator std::vector<double>() const { throw IfcException("Argument is not a list of floats"); }
|
||||
EntityArgument::operator std::vector<int>() const { throw IfcException("Argument is not a list of ints"); }
|
||||
EntityArgument::operator std::vector<std::string>() const { throw IfcException("Argument is not a list of strings"); }
|
||||
EntityArgument::operator IfcUtil::IfcBaseClass*() const { return entity; }
|
||||
EntityArgument::operator IfcUtil::IfcBaseClass*() const { return entity; }
|
||||
//EntityArgument::operator IfcUtil::IfcAbstractSelect::ptr() const { return entity; }
|
||||
EntityArgument::operator IfcEntityList::ptr() const { throw IfcException("Argument is not a list of entities"); }
|
||||
EntityArgument::operator IfcEntityListList::ptr() const { throw IfcException("Argument is not a list of entity lists"); }
|
||||
unsigned int EntityArgument::Size() const { return 1; }
|
||||
Argument* EntityArgument::operator [] (unsigned int i) const { throw IfcException("Argument is not a list of arguments"); }
|
||||
std::string EntityArgument::toString(bool upper) const {
|
||||
Argument* arg = entity->wrappedValue();
|
||||
IfcParse::TokenArgument* token_arg = dynamic_cast<IfcParse::TokenArgument*>(arg);
|
||||
const bool is_string = TokenFunc::isString(token_arg->token);
|
||||
std::string token_string = token_arg ? (is_string
|
||||
? TokenFunc::asString(token_arg->token)
|
||||
: TokenFunc::toString(token_arg->token))
|
||||
: std::string();
|
||||
std::string dt = IfcSchema::Type::ToString(entity->type());
|
||||
if ( upper ) {
|
||||
for (std::string::iterator p = dt.begin(); p != dt.end(); ++p ) *p = toupper(*p);
|
||||
if (is_string) token_string = IfcWrite::IfcCharacterEncoder(token_string);
|
||||
} else {
|
||||
token_string.insert(token_string.begin(),'\'');
|
||||
token_string.push_back('\'');
|
||||
}
|
||||
return dt + "(" + token_string + ")";
|
||||
return entity->entity->toString(upper);
|
||||
}
|
||||
//return entity->entity->toString(); }
|
||||
bool EntityArgument::isNull() const { return false; }
|
||||
@@ -736,15 +729,17 @@ IfcEntityList::ptr Entity::getInverse(IfcSchema::Type::Enum c, int i, const std:
|
||||
}
|
||||
return l;
|
||||
}
|
||||
bool Entity::is(IfcSchema::Type::Enum v) const { return _type == v; }
|
||||
bool Entity::is(IfcSchema::Type::Enum v) const { return _type == v; }
|
||||
unsigned int Entity::id() { return _id; }
|
||||
|
||||
IfcWrite::IfcWritableEntity* Entity::isWritable() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
IfcFile::IfcFile() {
|
||||
file = 0;
|
||||
IfcFile::IfcFile(bool create_latebound_entities)
|
||||
: _create_latebound_entities(create_latebound_entities)
|
||||
{
|
||||
stream = 0;
|
||||
lastId = 0;
|
||||
tokens = 0;
|
||||
MaxId = 0;
|
||||
@@ -767,9 +762,9 @@ bool IfcFile::Init(void* data, int len) {
|
||||
}
|
||||
bool IfcFile::Init(IfcParse::IfcSpfStream* f) {
|
||||
IfcSchema::InitStringMap();
|
||||
file = f;
|
||||
if ( ! file->valid ) return false;
|
||||
tokens = new Tokens (file,this);
|
||||
stream = f;
|
||||
if ( ! stream->valid ) return false;
|
||||
tokens = new Tokens (stream,this);
|
||||
Token token = TokenPtr();
|
||||
Token previous = TokenPtr();
|
||||
unsigned int currentId = 0;
|
||||
@@ -778,11 +773,15 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* f) {
|
||||
Entity* e;
|
||||
IfcUtil::IfcBaseClass* entity = 0;
|
||||
Logger::Status("Scanning file...");
|
||||
while ( ! file->eof ) {
|
||||
while ( ! stream->eof ) {
|
||||
if ( currentId ) {
|
||||
try {
|
||||
e = new Entity(currentId,this);
|
||||
entity = IfcSchema::SchemaEntity(e);
|
||||
if (this->create_latebound_entities()) {
|
||||
entity = new IfcLateBoundEntity(e);
|
||||
} else {
|
||||
entity = IfcSchema::SchemaEntity(e);
|
||||
}
|
||||
} catch (IfcException ex) {
|
||||
currentId = 0;
|
||||
Logger::Message(Logger::LOG_ERROR,ex.what());
|
||||
@@ -947,7 +946,7 @@ void IfcFile::AddEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
}
|
||||
}
|
||||
IfcEntityList::ptr IfcFile::EntitiesByType(IfcSchema::Type::Enum t) {
|
||||
MapEntitiesByType::const_iterator it = bytype.find(t);
|
||||
entities_by_type_t::const_iterator it = bytype.find(t);
|
||||
return (it == bytype.end()) ? IfcEntityList::ptr() : it->second;
|
||||
}
|
||||
IfcEntityList::ptr IfcFile::EntitiesByType(const std::string& t) {
|
||||
@@ -956,13 +955,13 @@ IfcEntityList::ptr IfcFile::EntitiesByType(const std::string& t) {
|
||||
return EntitiesByType(IfcSchema::Type::FromString(ty));
|
||||
}
|
||||
IfcEntityList::ptr IfcFile::EntitiesByReference(int t) {
|
||||
MapEntitiesByRef::const_iterator it = byref.find(t);
|
||||
entities_by_ref_t::const_iterator it = byref.find(t);
|
||||
return (it == byref.end()) ? IfcEntityList::ptr() : it->second;
|
||||
}
|
||||
IfcUtil::IfcBaseClass* IfcFile::EntityById(int id) {
|
||||
MapEntityById::const_iterator it = byid.find(id);
|
||||
entity_by_id_t::const_iterator it = byid.find(id);
|
||||
if ( it == byid.end() ) {
|
||||
MapOffsetById::const_iterator it2 = offsets.find(id);
|
||||
offset_by_id_t::const_iterator it2 = offsets.find(id);
|
||||
if ( it2 == offsets.end() ) throw IfcException("Entity not found");
|
||||
const unsigned int offset = (*it2).second;
|
||||
Entity* e = new Entity(id,this,offset);
|
||||
@@ -973,7 +972,7 @@ IfcUtil::IfcBaseClass* IfcFile::EntityById(int id) {
|
||||
return it->second;
|
||||
}
|
||||
IfcSchema::IfcRoot* IfcFile::EntityByGuid(const std::string& guid) {
|
||||
MapEntityByGuid::const_iterator it = byguid.find(guid);
|
||||
entity_by_guid_t::const_iterator it = byguid.find(guid);
|
||||
if ( it == byguid.end() ) {
|
||||
throw IfcException("Entity not found");
|
||||
} else {
|
||||
@@ -987,18 +986,18 @@ const char* IfcException::what() const throw() { return error.c_str(); }
|
||||
|
||||
// FIXME: Test destructor to delete entity and arg allocations
|
||||
IfcFile::~IfcFile() {
|
||||
for( MapEntityById::const_iterator it = byid.begin(); it != byid.end(); ++ it ) {
|
||||
for( entity_by_id_t::const_iterator it = byid.begin(); it != byid.end(); ++ it ) {
|
||||
delete it->second->entity;
|
||||
delete it->second;
|
||||
}
|
||||
delete file;
|
||||
delete stream;
|
||||
delete tokens;
|
||||
}
|
||||
|
||||
MapEntityById::const_iterator IfcFile::begin() const {
|
||||
IfcFile::entity_by_id_t::const_iterator IfcFile::begin() const {
|
||||
return byid.begin();
|
||||
}
|
||||
MapEntityById::const_iterator IfcFile::end() const {
|
||||
IfcFile::entity_by_id_t::const_iterator IfcFile::end() const {
|
||||
return byid.end();
|
||||
}
|
||||
|
||||
@@ -1023,7 +1022,7 @@ std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f) {
|
||||
os << "ENDSEC;" << std::endl;
|
||||
os << "DATA;" << std::endl;
|
||||
|
||||
for ( MapEntityById::const_iterator it = f.begin(); it != f.end(); ++ it ) {
|
||||
for ( IfcFile::entity_by_id_t::const_iterator it = f.begin(); it != f.end(); ++ it ) {
|
||||
const IfcUtil::IfcBaseClass* e = it->second;
|
||||
os << e->entity->toString(true) << ";" << std::endl;
|
||||
}
|
||||
|
||||
+3
-82
@@ -47,7 +47,7 @@
|
||||
#include "../ifcparse/Ifc2x3.h"
|
||||
#endif
|
||||
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcSpfStream.h"
|
||||
|
||||
namespace IfcParse {
|
||||
|
||||
@@ -178,9 +178,9 @@ namespace IfcParse {
|
||||
/// ===================== =====================
|
||||
class EntityArgument : public Argument {
|
||||
private:
|
||||
IfcUtil::IfcArgumentSelect* entity;
|
||||
IfcUtil::IfcBaseClass* entity;
|
||||
public:
|
||||
EntityArgument(IfcSchema::Type::Enum ty, const Token& t);
|
||||
EntityArgument(const Token& t);
|
||||
~EntityArgument();
|
||||
|
||||
IfcUtil::ArgumentType type() const;
|
||||
@@ -229,85 +229,6 @@ namespace IfcParse {
|
||||
IfcWrite::IfcWritableEntity* isWritable();
|
||||
};
|
||||
|
||||
typedef std::map<IfcSchema::Type::Enum, IfcEntityList::ptr> MapEntitiesByType;
|
||||
typedef std::map<unsigned int, IfcUtil::IfcBaseClass*> MapEntityById;
|
||||
typedef std::map<std::string, IfcSchema::IfcRoot*> MapEntityByGuid;
|
||||
typedef std::map<unsigned int, IfcEntityList::ptr> MapEntitiesByRef;
|
||||
typedef std::map<unsigned int, unsigned int> MapOffsetById;
|
||||
|
||||
/// This class provides several static convenience functions and variables
|
||||
/// and provide access to the entities in an IFC file
|
||||
class IfcFile {
|
||||
private:
|
||||
MapEntityById byid;
|
||||
MapEntitiesByType bytype;
|
||||
MapEntitiesByRef byref;
|
||||
MapEntityByGuid byguid;
|
||||
MapOffsetById offsets;
|
||||
unsigned int lastId;
|
||||
unsigned int MaxId;
|
||||
std::string _filename;
|
||||
std::string _timestamp;
|
||||
std::string _author;
|
||||
std::string _author_email;
|
||||
std::string _author_organisation;
|
||||
void initTimestamp();
|
||||
public:
|
||||
typedef MapEntityById::const_iterator const_iterator;
|
||||
IfcFile();
|
||||
~IfcFile();
|
||||
/// Returns the first entity in the file, this probably is the entity with the lowest id (EXPRESS ENTITY_INSTANCE_NAME)
|
||||
const_iterator begin() const;
|
||||
/// Returns the last entity in the file, this probably is the entity with the highes id (EXPRESS ENTITY_INSTANCE_NAME)
|
||||
const_iterator end() const;
|
||||
IfcParse::IfcSpfStream* file;
|
||||
IfcParse::Tokens* tokens;
|
||||
/// Returns all entities in the file that match the template argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
/// IfcWall will also return IfcWallStandardCase entities
|
||||
template <class T>
|
||||
typename T::list::ptr EntitiesByType() {
|
||||
IfcEntityList::ptr e = EntitiesByType(T::Class());
|
||||
typename T::list::ptr l(new typename T::list);
|
||||
if (e && e->Size()) {
|
||||
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) {
|
||||
l->push((T*)*it);
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
/// Returns all entities in the file that match the positional argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
/// IfcWall will also return IfcWallStandardCase entities
|
||||
IfcEntityList::ptr EntitiesByType(IfcSchema::Type::Enum t);
|
||||
/// Returns all entities in the file that match the positional argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
/// IfcWall will also return IfcWallStandardCase entities
|
||||
IfcEntityList::ptr EntitiesByType(const std::string& t);
|
||||
/// Returns all entities in the file that reference the id
|
||||
IfcEntityList::ptr EntitiesByReference(int id);
|
||||
/// Returns the entity with the specified id
|
||||
IfcUtil::IfcBaseClass* EntityById(int id);
|
||||
/// Returns the entity with the specified GlobalId
|
||||
IfcSchema::IfcRoot* EntityByGuid(const std::string& guid);
|
||||
bool Init(const std::string& fn);
|
||||
bool Init(std::istream& fn, int len);
|
||||
bool Init(void* data, int len);
|
||||
bool Init(IfcParse::IfcSpfStream* f);
|
||||
unsigned int FreshId() { MaxId ++; return MaxId; }
|
||||
void AddEntity(IfcUtil::IfcBaseClass* entity);
|
||||
void AddEntities(IfcEntityList::ptr es);
|
||||
|
||||
void filename(const std::string& s);
|
||||
std::string filename() const;
|
||||
void timestamp(const std::string& s);
|
||||
std::string timestamp() const;
|
||||
void author(const std::string& name, const std::string& email, const std::string& organisation);
|
||||
std::string authorName() const;
|
||||
std::string authorEmail() const;
|
||||
std::string authorOrganisation() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f);
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/*********************************************************************************
|
||||
* *
|
||||
* Reads a file in chunks of BUF_SIZE and provides functions to access its *
|
||||
* contents randomly and character by character *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCSPFSTREAM_H
|
||||
#define IFCSPFSTREAM_H
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
// As of IfcOpenShell version 0.3.0 the paging functionality, which
|
||||
// loads a file on disk into multiple chunks, has been disabled.
|
||||
// It proved to be an inefficient way of working with large files,
|
||||
// as often these did not facilitate to be parsed in a sequential
|
||||
// manner efficiently. To enable the paging functionality uncomment
|
||||
// the following statement.
|
||||
// #define BUF_SIZE (8 * 1024 * 1024)
|
||||
|
||||
namespace IfcParse {
|
||||
/// The IfcSpfStream class represents a ISO 10303-21 IFC-SPF file in memory.
|
||||
/// The file is interpreted as a sequence of tokens which are lazily
|
||||
/// interpreted only when requested. If the size of the file is
|
||||
/// larger than BUF_SIZE, the file is split into seperate pages, of
|
||||
/// which only one is simultaneously kept in memory, for files
|
||||
/// that define their entities not in a sequential nature, this is
|
||||
/// detrimental for the performance of the parser.
|
||||
class IfcSpfStream {
|
||||
private:
|
||||
FILE* stream;
|
||||
char* buffer;
|
||||
unsigned int ptr;
|
||||
unsigned int len;
|
||||
void ReadBuffer(bool inc=true);
|
||||
#ifdef BUF_SIZE
|
||||
unsigned int offset;
|
||||
bool paging;
|
||||
#endif
|
||||
public:
|
||||
bool valid;
|
||||
bool eof;
|
||||
unsigned int size;
|
||||
IfcSpfStream(const std::string& fn);
|
||||
IfcSpfStream(std::istream& f, int len);
|
||||
IfcSpfStream(void* data, int len);
|
||||
/// Returns the character at the cursor
|
||||
char Peek();
|
||||
/// Returns the character at specified offset
|
||||
char Read(unsigned int offset);
|
||||
/// Increment the file cursor and reads new page if necessary
|
||||
void Inc();
|
||||
void Close();
|
||||
/// Moves the file cursor to an arbitrary offset in the file
|
||||
void Seek(unsigned int offset);
|
||||
/// Returns the cursor position
|
||||
unsigned int Tell();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+29
-14
@@ -17,9 +17,12 @@
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "IfcUtil.h"
|
||||
#include <iostream>
|
||||
|
||||
#include "../ifcparse/IfcException.h"
|
||||
|
||||
#include "IfcUtil.h"
|
||||
|
||||
void IfcEntityList::push(IfcUtil::IfcBaseClass* l) {
|
||||
if ( l ) ls.push_back(l);
|
||||
}
|
||||
@@ -49,19 +52,10 @@ IfcEntityList::ptr IfcEntityList::getInverse(IfcSchema::Type::Enum c, int ar, co
|
||||
return l;
|
||||
}
|
||||
|
||||
bool IfcUtil::IfcEntitySelect::is(IfcSchema::Type::Enum v) const { return entity->is(v); }
|
||||
IfcSchema::Type::Enum IfcUtil::IfcEntitySelect::type() const { return entity->type(); }
|
||||
IfcUtil::IfcEntitySelect::IfcEntitySelect(IfcBaseClass* b) { entity = b->entity; }
|
||||
IfcUtil::IfcEntitySelect::IfcEntitySelect(IfcAbstractEntity* e) { entity = e; }
|
||||
bool IfcUtil::IfcEntitySelect::isSimpleType() { return false; }
|
||||
IfcUtil::IfcEntitySelect::~IfcEntitySelect() { delete entity; }
|
||||
|
||||
bool IfcUtil::IfcArgumentSelect::is(IfcSchema::Type::Enum v) const { return _type == v; }
|
||||
IfcSchema::Type::Enum IfcUtil::IfcArgumentSelect::type() const { return _type; }
|
||||
IfcUtil::IfcArgumentSelect::IfcArgumentSelect(IfcSchema::Type::Enum t, Argument* a) { _type = t; arg = a; }
|
||||
Argument* IfcUtil::IfcArgumentSelect::wrappedValue() { return arg; }
|
||||
bool IfcUtil::IfcArgumentSelect::isSimpleType() { return true; }
|
||||
IfcUtil::IfcArgumentSelect::~IfcArgumentSelect() { delete arg; }
|
||||
unsigned int IfcUtil::IfcBaseType::getArgumentCount() const { return 1; }
|
||||
Argument* IfcUtil::IfcBaseType::getArgument(unsigned int i) const { return entity->getArgument(i); }
|
||||
const char* IfcUtil::IfcBaseType::getArgumentName(unsigned int i) const { if (i == 0) { return "wrappedValue"; } else { throw IfcParse::IfcException("argument out of range"); } }
|
||||
|
||||
void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
|
||||
log1 = l1;
|
||||
@@ -98,4 +92,25 @@ std::ostream* Logger::log1 = 0;
|
||||
std::ostream* Logger::log2 = 0;
|
||||
std::stringstream Logger::log_stream;
|
||||
Logger::Severity Logger::verbosity = Logger::LOG_NOTICE;
|
||||
const char* Logger::severity_strings[] = { "Notice","Warning","Error" };
|
||||
const char* Logger::severity_strings[] = { "Notice","Warning","Error" };
|
||||
|
||||
static const char* const argument_type_string[] = {
|
||||
"NULL",
|
||||
"DERIVED",
|
||||
"INT",
|
||||
"BOOL",
|
||||
"DOUBLE",
|
||||
"STRING",
|
||||
"VECTOR_INT",
|
||||
"VECTOR_DOUBLE",
|
||||
"VECTOR_STRING",
|
||||
"ENUMERATION",
|
||||
"ENTITY",
|
||||
"ENTITY_LIST",
|
||||
"ENTITY_LIST_LIST",
|
||||
"UNKNOWN"
|
||||
};
|
||||
|
||||
const char* IfcUtil::ArgumentTypeToString(ArgumentType argument_type) {
|
||||
return argument_type_string[static_cast<int>(argument_type)];
|
||||
}
|
||||
|
||||
+13
-32
@@ -42,7 +42,9 @@ namespace IfcWrite {
|
||||
|
||||
namespace IfcUtil {
|
||||
enum ArgumentType {
|
||||
Argument_INT,
|
||||
Argument_NULL,
|
||||
Argument_DERIVED,
|
||||
Argument_INT,
|
||||
Argument_BOOL,
|
||||
Argument_DOUBLE,
|
||||
Argument_STRING,
|
||||
@@ -56,6 +58,8 @@ namespace IfcUtil {
|
||||
Argument_UNKNOWN
|
||||
};
|
||||
|
||||
const char* ArgumentTypeToString(ArgumentType argument_type);
|
||||
|
||||
class IfcBaseClass {
|
||||
public:
|
||||
IfcAbstractEntity* entity;
|
||||
@@ -70,6 +74,14 @@ namespace IfcUtil {
|
||||
virtual Argument* getArgument(unsigned int i) const = 0;
|
||||
virtual const char* getArgumentName(unsigned int i) const = 0;
|
||||
};
|
||||
|
||||
// TODO: Investigate whether these should be template classes instead
|
||||
class IfcBaseType : public IfcBaseEntity {
|
||||
public:
|
||||
virtual unsigned int getArgumentCount() const;
|
||||
virtual Argument* getArgument(unsigned int i) const;
|
||||
virtual const char* getArgumentName(unsigned int i) const;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -185,37 +197,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
namespace IfcUtil {
|
||||
class IfcAbstractSelect : public IfcBaseClass {
|
||||
public:
|
||||
typedef IfcTemplatedEntityList<IfcAbstractSelect> list;
|
||||
virtual bool isSimpleType() = 0;
|
||||
static IfcSchema::Type::Enum Class() { return IfcSchema::Type::ALL; }
|
||||
};
|
||||
class IfcEntitySelect : public IfcAbstractSelect {
|
||||
public:
|
||||
typedef IfcEntitySelect* ptr;
|
||||
IfcEntitySelect(IfcBaseClass* b);
|
||||
IfcEntitySelect(IfcAbstractEntity* e);
|
||||
~IfcEntitySelect();
|
||||
bool is(IfcSchema::Type::Enum v) const;
|
||||
IfcSchema::Type::Enum type() const;
|
||||
bool isSimpleType();
|
||||
};
|
||||
class IfcArgumentSelect : public IfcAbstractSelect {
|
||||
IfcSchema::Type::Enum _type;
|
||||
Argument* arg;
|
||||
public:
|
||||
typedef IfcArgumentSelect* ptr;
|
||||
IfcArgumentSelect(IfcSchema::Type::Enum t, Argument* a);
|
||||
~IfcArgumentSelect();
|
||||
Argument* wrappedValue();
|
||||
bool is(IfcSchema::Type::Enum v) const;
|
||||
IfcSchema::Type::Enum type() const;
|
||||
bool isSimpleType();
|
||||
};
|
||||
}
|
||||
|
||||
namespace IfcParse {
|
||||
class IfcFile;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "../ifcparse/IfcWrite.h"
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
#include "../ifcparse/IfcCharacterDecoder.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
using namespace IfcWrite;
|
||||
|
||||
@@ -301,7 +302,7 @@ IfcWriteArgument::operator std::vector<std::string>() const { return as<std::vec
|
||||
IfcWriteArgument::operator IfcUtil::IfcBaseClass*() const { return as<IfcUtil::IfcBaseClass*>(); }
|
||||
IfcWriteArgument::operator IfcEntityList::ptr() const { return as<IfcEntityList::ptr>(); }
|
||||
IfcWriteArgument::operator IfcEntityListList::ptr() const { throw; }
|
||||
bool IfcWriteArgument::isNull() const { return argumentType() == argument_type_null; }
|
||||
bool IfcWriteArgument::isNull() const { return type() == IfcUtil::Argument_NULL; }
|
||||
Argument* IfcWriteArgument::operator [] (unsigned int i) const { throw IfcParse::IfcException("Invalid cast"); }
|
||||
std::string IfcWriteArgument::toString(bool upper) const {
|
||||
std::ostringstream str;
|
||||
@@ -318,18 +319,9 @@ unsigned int IfcWriteArgument::Size() const {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
IfcWriteArgument::argument_type IfcWriteArgument::argumentType() const {
|
||||
return static_cast<argument_type>(container.which());
|
||||
}
|
||||
|
||||
IfcUtil::ArgumentType IfcWriteArgument::type() const {
|
||||
// TODO: Make these the same enumeration
|
||||
int ty = static_cast<int>(container.which()) - 2;
|
||||
if (ty < 0) {
|
||||
return IfcUtil::Argument_UNKNOWN;
|
||||
} else {
|
||||
return static_cast<IfcUtil::ArgumentType>(ty);
|
||||
}
|
||||
return static_cast<IfcUtil::ArgumentType>(container.which());
|
||||
}
|
||||
|
||||
IfcEntityList::ptr IfcSelectHelperEntity::getInverse(IfcSchema::Type::Enum,int,const std::string &) {throw IfcParse::IfcException("Invalid cast");}
|
||||
|
||||
@@ -91,21 +91,6 @@ namespace IfcWrite {
|
||||
IfcEntityListList::ptr
|
||||
> container;
|
||||
public:
|
||||
enum argument_type {
|
||||
argument_type_null,
|
||||
argument_type_derived,
|
||||
argument_type_int,
|
||||
argument_type_bool,
|
||||
argument_type_double,
|
||||
argument_type_string,
|
||||
argument_type_vector_int,
|
||||
argument_type_vector_double,
|
||||
argument_type_vector_string,
|
||||
argument_type_enumeration,
|
||||
argument_type_entity,
|
||||
argument_type_entity_list,
|
||||
argument_type_entity_list_list
|
||||
};
|
||||
IfcWriteArgument(IfcAbstractEntity* e) : entity(e) {}
|
||||
template <typename T> const T& as() const {
|
||||
if (const T* val = boost::get<T>(&container)) {
|
||||
@@ -131,7 +116,6 @@ namespace IfcWrite {
|
||||
Argument* operator [] (unsigned int i) const;
|
||||
std::string toString(bool upper=false) const;
|
||||
unsigned int Size() const;
|
||||
argument_type argumentType() const;
|
||||
IfcUtil::ArgumentType type() const;
|
||||
};
|
||||
|
||||
|
||||
+12
-11
@@ -15,21 +15,22 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
SET(CMAKE_SWIG_FLAGS "")
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(IfcPython.i PROPERTIES CPLUSPLUS ON)
|
||||
SWIG_ADD_MODULE(IfcImport python IfcPython.i)
|
||||
SWIG_LINK_LIBRARIES(IfcImport ${PYTHON_LIBRARIES} IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKOffset)
|
||||
SWIG_ADD_MODULE(ifcopenshell_wrapper python IfcPython.i)
|
||||
SWIG_LINK_LIBRARIES(ifcopenshell_wrapper ${PYTHON_LIBRARIES} IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKOffset)
|
||||
|
||||
# To install IfcPython let's get the site-packackes dir from python
|
||||
EXECUTE_PROCESS(COMMAND python -c "from distutils.sysconfig import get_python_lib as x; print (x())"
|
||||
# To install IfcPython let's get the site-packages dir from python
|
||||
EXECUTE_PROCESS(COMMAND python -c "import sys; from distutils.sysconfig import get_python_lib; sys.stdout.write(get_python_lib())"
|
||||
OUTPUT_VARIABLE python_package_dir)
|
||||
|
||||
# Strip trailing whitespace from python print
|
||||
STRING(REPLACE "\r" "" python_package_dir "${python_package_dir}")
|
||||
STRING(REPLACE "\n" "" python_package_dir "${python_package_dir}")
|
||||
|
||||
INSTALL(FILES
|
||||
"${CMAKE_BINARY_DIR}/ifcwrap/IfcImport.py"
|
||||
DESTINATION "${python_package_dir}")
|
||||
INSTALL(TARGETS _IfcImport DESTINATION "${python_package_dir}")
|
||||
"${CMAKE_BINARY_DIR}/ifcwrap/ifcopenshell_wrapper.py"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/__init__.py"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/guid.py"
|
||||
DESTINATION "${python_package_dir}/ifcopenshell")
|
||||
INSTALL(FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/geom/__init__.py"
|
||||
DESTINATION "${python_package_dir}/ifcopenshell/geom")
|
||||
INSTALL(TARGETS _ifcopenshell_wrapper DESTINATION "${python_package_dir}/ifcopenshell")
|
||||
|
||||
ENDIF(PYTHONLIBS_FOUND)
|
||||
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
%rename("settings") IteratorSettings;
|
||||
|
||||
// This is only used for RGB colours, hence the size of 3
|
||||
%typemap(out) const double* {
|
||||
$result = PyTuple_New(3);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
PyTuple_SetItem($result, i, PyFloat_FromDouble($1[i]));
|
||||
}
|
||||
}
|
||||
|
||||
%include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
%include "../ifcgeom/IfcGeomElement.h"
|
||||
%include "../ifcgeom/IfcGeomMaterial.h"
|
||||
%include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
%include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
// Using RTTI return a more specialized type of Element
|
||||
// Note that these elements are not to be owned by SWIG/Python as they will be freed automatically upon the next iteration
|
||||
// except for the IfcGeom::Element instances which are returned by Iterator::getObject() calls
|
||||
%typemap(out) IfcGeom::Element<float>* {
|
||||
IfcGeom::SerializedElement<float>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<float>*>($1);
|
||||
IfcGeom::TriangulationElement<float>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<float>*>($1);
|
||||
if (triangulation_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_float_t, 0);
|
||||
} else if (serialized_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_float_t, 0);
|
||||
} else {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr($1), SWIGTYPE_p_IfcGeom__ElementT_float_t, SWIG_POINTER_OWN);
|
||||
}
|
||||
}
|
||||
|
||||
// Using RTTI return a more specialized type of Element
|
||||
// Note that these elements are not to be owned by SWIG/Python as they will be freed automatically upon the next iteration
|
||||
// except for the IfcGeom::Element instances which are returned by Iterator::getObject() calls
|
||||
%typemap(out) IfcGeom::Element<double>* {
|
||||
IfcGeom::SerializedElement<double>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<double>*>($1);
|
||||
IfcGeom::TriangulationElement<double>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<double>*>($1);
|
||||
if (triangulation_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_double_t, 0);
|
||||
} else if (serialized_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_double_t, 0);
|
||||
} else {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr($1), SWIGTYPE_p_IfcGeom__ElementT_double_t, SWIG_POINTER_OWN);
|
||||
}
|
||||
}
|
||||
|
||||
// Note that these elements ARE to be owned by SWIG/Python
|
||||
%typemap(out) boost::variant<IfcGeom::Element<double>*, IfcGeom::Representation::Representation*> {
|
||||
// See which type is set and return appropriate
|
||||
IfcGeom::Element<double>* elem = boost::get<IfcGeom::Element<double>*>($1);
|
||||
IfcGeom::SerializedElement<double>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<double>*>(elem);
|
||||
IfcGeom::TriangulationElement<double>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<double>*>(elem);
|
||||
if (triangulation_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_double_t, SWIG_POINTER_OWN);
|
||||
} else if (serialized_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_double_t, SWIG_POINTER_OWN);
|
||||
}
|
||||
}
|
||||
|
||||
// SWIG does not support bool references in a meaningful way, so the
|
||||
// IfcGeom::IteratorSettings functions degrade to return a read only value
|
||||
%typemap(out) double& {
|
||||
$result = SWIG_From_double(*$1);
|
||||
}
|
||||
%typemap(out) bool& {
|
||||
$result = PyBool_FromLong(static_cast<long>(*$1));
|
||||
}
|
||||
|
||||
// This does not seem to work:
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, IfcParse::IfcFile*);
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, void*, int);
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, std::istream&, int);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, IfcParse::IfcFile*);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, void*, int);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, std::istream&, int);
|
||||
|
||||
%extend IfcGeom::IteratorSettings {
|
||||
%pythoncode %{
|
||||
attrs = ("convert_back_units", "deflection_tolerance", "disable_opening_subtractions", "disable_triangulation", "faster_booleans", "force_ccw_face_orientation", "sew_shells", "use_brep_data", "use_world_coords", "weld_vertices")
|
||||
def __repr__(self):
|
||||
return "%s(%s)"%(self.__class__.__name__, ",".join(tuple("%s=%r"%(a, getattr(self, a)()) for a in self.attrs)))
|
||||
%}
|
||||
}
|
||||
|
||||
%extend IfcGeom::Iterator<float> {
|
||||
static int mantissa_size() {
|
||||
return std::numeric_limits<float>::digits;
|
||||
}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Iterator<double> {
|
||||
static int mantissa_size() {
|
||||
return std::numeric_limits<double>::digits;
|
||||
}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Representation::Triangulation {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
id = property(id)
|
||||
verts = property(verts)
|
||||
faces = property(faces)
|
||||
edges = property(edges)
|
||||
normals = property(normals)
|
||||
material_ids = property(material_ids)
|
||||
materials = property(materials)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Representation::Serialization {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
id = property(id)
|
||||
brep_data = property(brep_data)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Element {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
id = property(id)
|
||||
parent_id = property(parent_id)
|
||||
name = property(name)
|
||||
type = property(type)
|
||||
guid = property(guid)
|
||||
transformation = property(transformation)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::TriangulationElement {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
geometry = property(geometry)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::SerializedElement {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
geometry = property(geometry)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Material {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
has_diffuse = property(hasDiffuse)
|
||||
has_specular = property(hasSpecular)
|
||||
has_transparency = property(hasTransparency)
|
||||
has_specularity = property(hasSpecularity)
|
||||
diffuse = property(diffuse)
|
||||
specular = property(specular)
|
||||
transparency = property(transparency)
|
||||
specularity = property(specularity)
|
||||
name = property(name)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Transformation {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
matrix = property(matrix)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Matrix {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
data = property(data)
|
||||
%}
|
||||
};
|
||||
|
||||
%inline %{
|
||||
boost::variant<IfcGeom::Element<double>*, IfcGeom::Representation::Representation*> create_shape(IfcGeom::IteratorSettings& settings, IfcParse::IfcLateBoundEntity* instance) {
|
||||
if (instance->is(IfcSchema::Type::IfcProduct)) {
|
||||
IfcParse::IfcFile* file = instance->entity->file;
|
||||
|
||||
IfcSchema::IfcProject::list::ptr projects = file->EntitiesByType<IfcSchema::IfcProject>();
|
||||
if (projects->Size() != 1) {
|
||||
throw IfcParse::IfcException("Not a single IfcProject instance");
|
||||
}
|
||||
IfcSchema::IfcProject* project = *projects->begin();
|
||||
|
||||
IfcGeom::Kernel kernel;
|
||||
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1);
|
||||
kernel.setValue(IfcGeom::Kernel::GV_FORCE_CCW_FACE_ORIENTATION, settings.force_ccw_face_orientation() ? 1 : -1);
|
||||
|
||||
IfcSchema::IfcProduct* product = (IfcSchema::IfcProduct*) instance;
|
||||
|
||||
if (!product->hasRepresentation()) {
|
||||
throw IfcParse::IfcException("Representation is NULL");
|
||||
}
|
||||
|
||||
IfcSchema::IfcProductRepresentation* prodrep = product->Representation();
|
||||
IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations();
|
||||
IfcSchema::IfcRepresentation* representation = 0;
|
||||
for (IfcSchema::IfcRepresentation::list::it it = reps->begin(); it != reps->end(); ++it) {
|
||||
IfcSchema::IfcRepresentation* rep = *it;
|
||||
if (rep->RepresentationIdentifier() == "Body") {
|
||||
representation = rep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!representation) {
|
||||
throw IfcParse::IfcException("No IfcRepresentations with a 'Body' RepresentationIdentifier found");
|
||||
}
|
||||
|
||||
IfcSchema::IfcRepresentationContext* ctx = representation->ContextOfItems();
|
||||
if (!ctx->is(IfcSchema::Type::IfcGeometricRepresentationContext)) {
|
||||
throw IfcParse::IfcException("Context not of type IfcGeometricRepresentationContext");
|
||||
}
|
||||
IfcSchema::IfcGeometricRepresentationContext* context = (IfcSchema::IfcGeometricRepresentationContext*) ctx;
|
||||
if (context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) {
|
||||
IfcSchema::IfcGeometricRepresentationSubContext* subcontext = (IfcSchema::IfcGeometricRepresentationSubContext*) context;
|
||||
context = subcontext->ParentContext();
|
||||
}
|
||||
|
||||
double precision = 1.e-5;
|
||||
if (context->hasPrecision()) {
|
||||
precision = context->Precision();
|
||||
}
|
||||
std::pair<std::string, double> length_unit = kernel.initializeUnits(project->UnitsInContext());
|
||||
precision *= length_unit.second;
|
||||
kernel.setValue(IfcGeom::Kernel::GV_PRECISION, precision);
|
||||
|
||||
IfcGeom::BRepElement<double>* brep = kernel.create_brep_for_representation_and_product<double>(settings, representation, product);
|
||||
if (settings.use_brep_data()) {
|
||||
IfcGeom::SerializedElement<double>* serialization = new IfcGeom::SerializedElement<double>(*brep);
|
||||
delete brep;
|
||||
return serialization;
|
||||
} else if (!settings.disable_triangulation()) {
|
||||
IfcGeom::TriangulationElement<double>* triangulation = new IfcGeom::TriangulationElement<double>(*brep);
|
||||
delete brep;
|
||||
return triangulation;
|
||||
} else {
|
||||
throw IfcParse::IfcException("No element to return based on provided settings");
|
||||
}
|
||||
} else {
|
||||
throw IfcParse::IfcException("Only obtaining representations for IfcProduct instances is currently supported");
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
namespace IfcGeom {
|
||||
%template(iterator_single_precision) Iterator<float>;
|
||||
%template(iterator_double_precision) Iterator<double>;
|
||||
|
||||
%template(element_single_precision) Element<float>;
|
||||
%template(element_double_precision) Element<double>;
|
||||
|
||||
%template(triangulation_element_single_precision) TriangulationElement<float>;
|
||||
%template(triangulation_element_double_precision) TriangulationElement<double>;
|
||||
|
||||
%template(serialized_element_single_precision) SerializedElement<float>;
|
||||
%template(serialized_element_double_precision) SerializedElement<double>;
|
||||
|
||||
%template(transformation_single_precision) Transformation<float>;
|
||||
%template(transformation_double_precision) Transformation<double>;
|
||||
|
||||
%template(matrix_single_precision) Matrix<float>;
|
||||
%template(matrix_double_precision) Matrix<double>;
|
||||
|
||||
namespace Representation {
|
||||
%template(triangulation_single_precision) Triangulation<float>;
|
||||
%template(triangulation_double_precision) Triangulation<double>;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,179 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
%ignore IfcParse::IfcLateBoundEntity::is;
|
||||
%ignore IfcParse::IfcLateBoundEntity::type;
|
||||
%ignore IfcParse::IfcLateBoundEntity::getArgument;
|
||||
%ignore IfcParse::IfcLateBoundEntity::IfcLateBoundEntity(IfcAbstractEntity*);
|
||||
|
||||
%ignore IfcParse::IfcFile::Init;
|
||||
%ignore IfcParse::IfcFile::EntityById;
|
||||
%ignore IfcParse::IfcFile::EntityByGuid;
|
||||
%ignore IfcParse::IfcFile::AddEntity;
|
||||
%ignore operator<<;
|
||||
|
||||
%rename("by_type") EntitiesByType;
|
||||
%rename("__len__") getArgumentCount;
|
||||
%rename("get_argument_type") getArgumentType;
|
||||
%rename("get_argument_name") getArgumentName;
|
||||
%rename("get_argument_index") getArgumentIndex;
|
||||
%rename("_set_argument") setArgument;
|
||||
%rename("__repr__") toString;
|
||||
%rename("entity_instance") IfcLateBoundEntity;
|
||||
%rename("file") IfcFile;
|
||||
|
||||
%typemap(typecheck,precedence=SWIG_TYPECHECK_INTEGER) IfcEntityList::ptr {
|
||||
$1 = (PySequence_Check($input) && !PyUnicode_Check($input) && !PyString_Check($input)) ? 1 : 0;
|
||||
}
|
||||
|
||||
%typemap(in) IfcEntityList::ptr {
|
||||
if (PySequence_Check($input)) {
|
||||
$1 = IfcEntityList::ptr(new IfcEntityList());
|
||||
for(Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
|
||||
PyObject* obj = PySequence_GetItem($input, i);
|
||||
if (obj) {
|
||||
void *arg = 0;
|
||||
int res = SWIG_ConvertPtr(obj, &arg, SWIGTYPE_p_IfcParse__IfcLateBoundEntity, 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "Entity__set_argument" "', argument " "3"" of type '" "IfcParse::IfcLateBoundEntity *""'");
|
||||
} else {
|
||||
$1->push(reinterpret_cast<IfcParse::IfcLateBoundEntity*>(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SWIG_exception(SWIG_RuntimeError,"Unknown argument type");
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(out) IfcEntityList::ptr {
|
||||
const unsigned size = $1 ? $1->Size() : 0;
|
||||
$result = PyList_New(size);
|
||||
for (unsigned i = 0; i < size; ++i) {
|
||||
PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr((*$1)[i]), SWIGTYPE_p_IfcParse__IfcLateBoundEntity, 0);
|
||||
PyList_SetItem($result,i,o);
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(out) IfcUtil::ArgumentType {
|
||||
$result = SWIG_Python_str_FromChar(IfcUtil::ArgumentTypeToString($1));
|
||||
}
|
||||
|
||||
%typemap(out) std::pair<IfcUtil::ArgumentType, Argument*> {
|
||||
const Argument& arg = *($1.second);
|
||||
const IfcUtil::ArgumentType type = $1.first;
|
||||
if (arg.isNull() || type == IfcUtil::Argument_DERIVED) {
|
||||
Py_INCREF(Py_None);
|
||||
$result = Py_None;
|
||||
} else {
|
||||
switch(type) {
|
||||
case IfcUtil::Argument_INT:
|
||||
$result = PyInt_FromLong((int)arg);
|
||||
break;
|
||||
case IfcUtil::Argument_BOOL:
|
||||
$result = PyBool_FromLong((bool)arg);
|
||||
break;
|
||||
case IfcUtil::Argument_DOUBLE:
|
||||
$result = PyFloat_FromDouble(arg);
|
||||
break;
|
||||
case IfcUtil::Argument_ENUMERATION:
|
||||
case IfcUtil::Argument_STRING: {
|
||||
const std::string s = arg;
|
||||
$result = PyString_FromString(s.c_str());
|
||||
break; }
|
||||
case IfcUtil::Argument_VECTOR_INT: {
|
||||
const std::vector<int> v = arg;
|
||||
const unsigned size = v.size();
|
||||
$result = PyList_New(size);
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
PyList_SetItem($result,i,PyInt_FromLong(v[i]));
|
||||
}
|
||||
break; }
|
||||
case IfcUtil::Argument_VECTOR_DOUBLE: {
|
||||
const std::vector<double> v = arg;
|
||||
const unsigned size = v.size();
|
||||
$result = PyList_New(size);
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
PyList_SetItem($result,i,PyFloat_FromDouble(v[i]));
|
||||
}
|
||||
break; }
|
||||
case IfcUtil::Argument_VECTOR_STRING: {
|
||||
const std::vector<std::string> v = arg;
|
||||
const unsigned size = v.size();
|
||||
$result = PyList_New(size);
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
PyList_SetItem($result,i,PyString_FromString(v[i].c_str()));
|
||||
}
|
||||
break; }
|
||||
case IfcUtil::Argument_ENTITY: {
|
||||
IfcUtil::IfcBaseClass* e = arg;
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(e), SWIGTYPE_p_IfcParse__IfcLateBoundEntity, 0);
|
||||
break; }
|
||||
case IfcUtil::Argument_ENTITY_LIST: {
|
||||
IfcEntityList::ptr es = arg;
|
||||
const unsigned size = es->Size();
|
||||
$result = PyList_New(size);
|
||||
for (unsigned i = 0; i < size; ++i) {
|
||||
PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr((*es)[i]), SWIGTYPE_p_IfcParse__IfcLateBoundEntity, 0);
|
||||
PyList_SetItem($result,i,o);
|
||||
}
|
||||
break; }
|
||||
case IfcUtil::Argument_UNKNOWN:
|
||||
default:
|
||||
SWIG_exception(SWIG_RuntimeError,"Unknown argument type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%extend IfcParse::IfcFile {
|
||||
IfcParse::IfcLateBoundEntity* by_id(unsigned id) {
|
||||
return (IfcParse::IfcLateBoundEntity*) $self->EntityById(id);
|
||||
}
|
||||
IfcParse::IfcLateBoundEntity* by_guid(const std::string& guid) {
|
||||
return (IfcParse::IfcLateBoundEntity*) $self->EntityByGuid(guid);
|
||||
}
|
||||
void add(IfcParse::IfcLateBoundEntity* e) {
|
||||
$self->AddEntity(e);
|
||||
}
|
||||
void write(const std::string& fn) {
|
||||
std::ofstream f(fn.c_str());
|
||||
f << (*$self);
|
||||
}
|
||||
}
|
||||
|
||||
%extend IfcParse::IfcLateBoundEntity {
|
||||
%pythoncode %{
|
||||
set_argument = lambda self,x,y: self._set_argument(x) if y is None else self._set_argument(x,y)
|
||||
%}
|
||||
}
|
||||
|
||||
%include "../ifcparse/IfcFile.h"
|
||||
%include "../ifcparse/IfcLateBoundEntity.h"
|
||||
|
||||
// The IfcFile* returned by open() is to be freed by SWIG/Python
|
||||
%newobject open;
|
||||
|
||||
%inline %{
|
||||
IfcParse::IfcFile* open(const std::string& s) {
|
||||
IfcParse::IfcFile* f = new IfcParse::IfcFile(true);
|
||||
f->Init(s);
|
||||
return f;
|
||||
}
|
||||
%}
|
||||
+13
-199
@@ -21,48 +21,11 @@
|
||||
%include "std_string.i"
|
||||
%include "exception.i"
|
||||
|
||||
// This is only used for RGB colours, hence the size of 3
|
||||
%typemap(out) const double* {
|
||||
$result = PyTuple_New(3);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
PyTuple_SetItem($result, i, PyFloat_FromDouble($1[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Using RTTI return a more specialized type of Element
|
||||
%typemap(out) IfcGeom::Element<float>* {
|
||||
IfcGeom::SerializedElement<float>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<float>*>($1);
|
||||
IfcGeom::TriangulationElement<float>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<float>*>($1);
|
||||
if (triangulation_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_float_t, 0);
|
||||
} else if (serialized_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_float_t, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Using RTTI return a more specialized type of Element
|
||||
%typemap(out) IfcGeom::Element<double>* {
|
||||
IfcGeom::SerializedElement<double>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<double>*>($1);
|
||||
IfcGeom::TriangulationElement<double>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<double>*>($1);
|
||||
if (triangulation_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_double_t, 0);
|
||||
} else if (serialized_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_double_t, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// SWIG does not support bool references in a meaningful way, so the
|
||||
// IfcGeom::IteratorSettings functions degrade to return a read only value
|
||||
%typemap(out) double& {
|
||||
$result = SWIG_From_double(*$1);
|
||||
}
|
||||
%typemap(out) bool& {
|
||||
$result = PyBool_FromLong(static_cast<long>(*$1));
|
||||
}
|
||||
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
} catch(IfcParse::IfcException& e) {
|
||||
SWIG_exception(SWIG_RuntimeError, e.what());
|
||||
} catch(std::runtime_error& e) {
|
||||
SWIG_exception(SWIG_RuntimeError, e.what());
|
||||
} catch(...) {
|
||||
@@ -70,170 +33,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
%include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
%include "../ifcgeom/IfcGeomMaterial.h"
|
||||
%include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
%include "../ifcgeom/IfcGeomElement.h"
|
||||
%include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
// This does not seem to work:
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, IfcParse::IfcFile*);
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, void*, int);
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, std::istream&, int);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, IfcParse::IfcFile*);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, void*, int);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, std::istream&, int);
|
||||
|
||||
%extend IfcGeom::IteratorSettings {
|
||||
%pythoncode %{
|
||||
attrs = ("convert_back_units", "deflection_tolerance", "disable_opening_subtractions", "disable_triangulation", "faster_booleans", "force_ccw_face_orientation", "sew_shells", "use_brep_data", "use_world_coords", "weld_vertices")
|
||||
def __repr__(self):
|
||||
return "IteratorSettings(%s)"%(",".join(tuple("%s=%r"%(a, getattr(self, a)()) for a in self.attrs)))
|
||||
%}
|
||||
}
|
||||
|
||||
%module ifcopenshell %{
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
%module ifcopenshell_wrapper %{
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
using namespace IfcGeom;
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcLateBoundEntity.h"
|
||||
%}
|
||||
|
||||
%extend IfcGeom::Iterator<float> {
|
||||
static int mantissa_size() {
|
||||
return std::numeric_limits<float>::digits;
|
||||
}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Iterator<double> {
|
||||
static int mantissa_size() {
|
||||
return std::numeric_limits<double>::digits;
|
||||
}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Representation::Triangulation {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
id = property(id)
|
||||
verts = property(verts)
|
||||
faces = property(faces)
|
||||
edges = property(edges)
|
||||
normals = property(normals)
|
||||
material_ids = property(material_ids)
|
||||
materials = property(materials)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Representation::Serialization {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
id = property(id)
|
||||
brep_data = property(brep_data)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Element {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
id = property(id)
|
||||
parent_id = property(parent_id)
|
||||
name = property(name)
|
||||
type = property(type)
|
||||
guid = property(guid)
|
||||
transformation = property(transformation)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::TriangulationElement {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
geometry = property(geometry)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::SerializedElement {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
geometry = property(geometry)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Material {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
has_diffuse = property(hasDiffuse)
|
||||
has_specular = property(hasSpecular)
|
||||
has_transparency = property(hasTransparency)
|
||||
has_specularity = property(hasSpecularity)
|
||||
diffuse = property(diffuse)
|
||||
specular = property(specular)
|
||||
transparency = property(transparency)
|
||||
specularity = property(specularity)
|
||||
name = property(name)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Transformation {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
matrix = property(matrix)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Matrix {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
data = property(data)
|
||||
%}
|
||||
};
|
||||
|
||||
namespace std {
|
||||
%template(IntVector) vector<int>;
|
||||
%template(FloatVector) vector<float>;
|
||||
%template(DoubleVector) vector<double>;
|
||||
%template(MaterialVector) vector<IfcGeom::Material>;
|
||||
%template(int_vector) vector<int>;
|
||||
%template(float_vector) vector<float>;
|
||||
%template(double_vector) vector<double>;
|
||||
%template(string_vector) vector<std::string>;
|
||||
%template(material_vector) vector<IfcGeom::Material>;
|
||||
};
|
||||
|
||||
namespace IfcGeom {
|
||||
%template(IteratorSinglePrecision) Iterator<float>;
|
||||
%template(IteratorDoublePrecision) Iterator<double>;
|
||||
|
||||
%template(ElementSinglePrecision) Element<float>;
|
||||
%template(ElementDoublePrecision) Element<double>;
|
||||
|
||||
%template(TriangulationElementSinglePrecision) TriangulationElement<float>;
|
||||
%template(TriangulationElementDoublePrecision) TriangulationElement<double>;
|
||||
|
||||
%template(SerializedElementSinglePrecision) SerializedElement<float>;
|
||||
%template(SerializedElementDoublePrecision) SerializedElement<double>;
|
||||
|
||||
%template(TransformationSinglePrecision) Transformation<float>;
|
||||
%template(TransformationDoublePrecision) Transformation<double>;
|
||||
|
||||
%template(MatrixSinglePrecision) Matrix<float>;
|
||||
%template(MatrixDoublePrecision) Matrix<double>;
|
||||
|
||||
namespace Representation {
|
||||
%template(TriangulationSinglePrecision) Triangulation<float>;
|
||||
%template(TriangulationDoublePrecision) Triangulation<double>;
|
||||
};
|
||||
};
|
||||
|
||||
// Hide templating precision to the user by choosing based on Python's
|
||||
// internal float type. This is probably always going to be a double.
|
||||
%pythoncode %{
|
||||
import sys
|
||||
for ty in (IteratorSinglePrecision, IteratorDoublePrecision):
|
||||
if ty.mantissa_size() == sys.float_info.mant_dig: Iterator = ty
|
||||
%}
|
||||
%include "IfcGeomWrapper.i"
|
||||
%include "IfcParseWrapper.i"
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
namespace IfcGeomObjects {
|
||||
|
||||
const int WELD_VERTICES = 1;
|
||||
const int USE_WORLD_COORDS = 2;
|
||||
const int CONVERT_BACK_UNITS = 3;
|
||||
const int USE_BREP_DATA = 4;
|
||||
const int SEW_SHELLS = 5;
|
||||
const int FASTER_BOOLEANS = 6;
|
||||
const int FORCE_CCW_FACE_ORIENTATION = 7;
|
||||
const int DISABLE_OPENING_SUBTRACTIONS = 8;
|
||||
const int DISABLE_TRIANGULATION = 9;
|
||||
|
||||
class Material {
|
||||
private:
|
||||
void* style;
|
||||
public:
|
||||
bool hasDiffuse() const;
|
||||
bool hasSpecular() const;
|
||||
bool hasTransparency() const;
|
||||
bool hasSpecularity() const;
|
||||
const double* diffuse() const;
|
||||
const double* specular() const;
|
||||
double transparency() const;
|
||||
double specularity() const;
|
||||
const std::string name() const;
|
||||
};
|
||||
|
||||
class IfcRepresentationTriangulation {
|
||||
private:
|
||||
int _id;
|
||||
std::vector<float> _verts;
|
||||
std::vector<int> _faces;
|
||||
std::vector<int> _edges;
|
||||
std::vector<float> _normals;
|
||||
std::vector<int> _material_ids;
|
||||
std::vector<Material> _materials;
|
||||
|
||||
IfcRepresentationTriangulation();
|
||||
IfcRepresentationTriangulation(const IfcRepresentationTriangulation&);
|
||||
IfcRepresentationTriangulation& operator=(const IfcRepresentationTriangulation&);
|
||||
virtual ~IfcRepresentationTriangulation();
|
||||
public:
|
||||
int id() const;
|
||||
const std::vector<float>& verts() const;
|
||||
const std::vector<int>& faces() const;
|
||||
const std::vector<int>& edges() const;
|
||||
const std::vector<float>& normals() const;
|
||||
const std::vector<int>& material_ids() const;
|
||||
const std::vector<Material>& materials() const;
|
||||
};
|
||||
|
||||
class IfcRepresentationBrepData {
|
||||
private:
|
||||
int _id;
|
||||
std::string _brep_data;
|
||||
|
||||
IfcRepresentationBrepData();
|
||||
IfcRepresentationBrepData(const IfcRepresentationBrepData&);
|
||||
IfcRepresentationBrepData& operator=(const IfcRepresentationBrepData&);
|
||||
virtual ~IfcRepresentationBrepData();
|
||||
public:
|
||||
int id() const;
|
||||
const std::string& brep_data() const;
|
||||
};
|
||||
|
||||
class IfcObject {
|
||||
private:
|
||||
int _id;
|
||||
int _parent_id;
|
||||
std::string _name;
|
||||
std::string _type;
|
||||
std::string _guid;
|
||||
std::vector<float> _matrix;
|
||||
|
||||
IfcObject();
|
||||
IfcObject(const IfcObject& other);
|
||||
IfcObject& operator=(const IfcObject& other);
|
||||
virtual ~IfcObject() {}
|
||||
public:
|
||||
int id() const;
|
||||
int parent_id() const;
|
||||
const std::string& name() const;
|
||||
const std::string& type() const;
|
||||
const std::string& guid() const;
|
||||
const std::vector<float>& matrix() const;
|
||||
};
|
||||
|
||||
class IfcGeomObject : public IfcObject {
|
||||
private:
|
||||
IfcRepresentationTriangulation* _mesh;
|
||||
|
||||
IfcGeomObject();
|
||||
IfcGeomObject(const IfcGeomObject& other);
|
||||
IfcGeomObject& operator=(const IfcGeomObject& other);
|
||||
virtual ~IfcGeomObject();
|
||||
public:
|
||||
const IfcRepresentationTriangulation& mesh() const;
|
||||
};
|
||||
|
||||
class IfcGeomBrepDataObject : public IfcObject {
|
||||
private:
|
||||
IfcRepresentationBrepData* _mesh;
|
||||
|
||||
IfcGeomBrepDataObject();
|
||||
IfcGeomBrepDataObject(const IfcGeomBrepDataObject& other);
|
||||
IfcGeomBrepDataObject& operator=(const IfcGeomBrepDataObject& other);
|
||||
virtual ~IfcGeomBrepDataObject();
|
||||
public:
|
||||
const IfcRepresentationBrepData& mesh() const;
|
||||
};
|
||||
|
||||
void Settings(int setting, bool value);
|
||||
|
||||
bool Init(const std::string fn);
|
||||
|
||||
const IfcGeomObject* Get();
|
||||
const IfcGeomBrepDataObject* GetBrepData();
|
||||
|
||||
const IfcObject* GetObject(int id);
|
||||
|
||||
bool Next();
|
||||
|
||||
int Progress();
|
||||
|
||||
const std::string GetLog();
|
||||
bool CleanUp();
|
||||
};
|
||||
Reference in New Issue
Block a user