Allow for string data to be passed as vectors of int between IfcPython and IfcGeom, to circumvent SWG trying to access UCS-2 data as UCS-4 and vice versa

This commit is contained in:
Thomas Krijnen
2011-12-05 14:23:22 +00:00
parent cab44ce754
commit 08d3eb649c
4 changed files with 98 additions and 64 deletions
+74 -60
View File
@@ -39,20 +39,23 @@ bl_info = {
"tracker_url": "http://sourceforge.net/tracker/?group_id=543113", "tracker_url": "http://sourceforge.net/tracker/?group_id=543113",
"category": "Import-Export"} "category": "Import-Export"}
import sys
max_unicode = 0x110000-1 if sys.platform[0:5] == 'linux' else 0x10000-1
wrong_unicode = max_unicode != sys.maxunicode
if wrong_unicode:
print("\nWarning: wrong unicode representation detected, switching to "\
"compatibility layer for text transferral\n")
if "bpy" in locals(): if "bpy" in locals():
import imp import imp
if "IfcImport" in locals(): if "IfcImport" in locals():
imp.reload(IfcImport) imp.reload(IfcImport)
import sys
import bpy import bpy
import mathutils import mathutils
from bpy.props import StringProperty, IntProperty, BoolProperty from bpy.props import StringProperty, IntProperty, BoolProperty
from bpy_extras.io_utils import ImportHelper from bpy_extras.io_utils import ImportHelper
wrong_unicode = sys.platform[0:5] == 'linux' and sys.maxunicode==(2**16-1)
warned_about_wrong_unicode = False
bpy.types.Object.ifc_id = IntProperty(name="IFC Entity ID", bpy.types.Object.ifc_id = IntProperty(name="IFC Entity ID",
description="The STEP entity instance name") description="The STEP entity instance name")
bpy.types.Object.ifc_guid = StringProperty(name="IFC Entity GUID", bpy.types.Object.ifc_guid = StringProperty(name="IFC Entity GUID",
@@ -64,9 +67,16 @@ bpy.types.Object.ifc_type = StringProperty(name="IFC Entity Type",
def import_ifc(filename, use_names, process_relations): def import_ifc(filename, use_names, process_relations):
global wrong_unicode
from . import IfcImport from . import IfcImport
print("Reading %s..."%bpy.path.basename(filename)) print("Reading %s..."%bpy.path.basename(filename))
if (wrong_unicode and not IfcImport.InitUCS2(''.join(['\0']+['\0%s'%s for s in filename]+['\0\0']))) or (not wrong_unicode and not IfcImport.Init(filename)): if wrong_unicode:
vec = IfcImport.IntVector(len(filename))
for i in range(len(filename)): vec[i] = ord(filename[i])
valid_file = IfcImport.Init(vec)
else:
valid_file = IfcImport.Init(filename)
if not valid_file:
return False return False
print("Done reading file") print("Done reading file")
id_to_object = {} id_to_object = {}
@@ -76,52 +86,60 @@ def import_ifc(filename, use_names, process_relations):
print("Creating geometry...") print("Creating geometry...")
while True: while True:
ob = IfcImport.Get() ob = IfcImport.Get()
if ob.type != 'IfcOpeningElement':
f = ob.mesh.faces if wrong_unicode:
v = ob.mesh.verts ob_type = ''.join([chr(c) for c in ob.type_as_intvector()])
m = ob.matrix ob_name = ''.join([chr(c) for c in ob.name_as_intvector()])
t = ob.type[0:21] ob_guid = ''.join([chr(c) for c in ob.guid_as_intvector()])
nm = ob.name if len(ob.name) and use_names else ob.guid else:
ob_type, ob_name, ob_guid = ob.name, ob.type, ob.guid
f = ob.mesh.faces
v = ob.mesh.verts
m = ob.matrix
t = ob_type[0:21]
nm = ob_name if len(ob_name) and use_names else ob_guid
verts = [[v[i], v[i + 1], v[i + 2]] \ verts = [[v[i], v[i + 1], v[i + 2]] \
for i in range(0, len(v), 3)] for i in range(0, len(v), 3)]
faces = [[f[i], f[i + 1], f[i + 2]] \ faces = [[f[i], f[i + 1], f[i + 2]] \
for i in range(0, len(f), 3)] for i in range(0, len(f), 3)]
me = bpy.data.meshes.new('mesh%d' % ob.mesh.id) me = bpy.data.meshes.new('mesh%d' % ob.mesh.id)
me.from_pydata(verts, [], faces) me.from_pydata(verts, [], faces)
if t in bpy.data.materials: if t in bpy.data.materials:
mat = bpy.data.materials[t] mat = bpy.data.materials[t]
mat.use_fake_user = True mat.use_fake_user = True
else: else:
mat = bpy.data.materials.new(t) mat = bpy.data.materials.new(t)
me.materials.append(mat) me.materials.append(mat)
bob = bpy.data.objects.new(nm, me) bob = bpy.data.objects.new(nm, me)
mat = mathutils.Matrix(([m[0], m[1], m[2], 0], mat = mathutils.Matrix(([m[0], m[1], m[2], 0],
[m[3], m[4], m[5], 0], [m[3], m[4], m[5], 0],
[m[6], m[7], m[8], 0], [m[6], m[7], m[8], 0],
[m[9], m[10], m[11], 1])) [m[9], m[10], m[11], 1]))
if process_relations: if process_relations:
id_to_matrix[ob.id] = mat id_to_matrix[ob.id] = mat
else: else:
bob.matrix_world = mat bob.matrix_world = mat
bpy.context.scene.objects.link(bob) bpy.context.scene.objects.link(bob)
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_name(name=bob.name) bpy.ops.object.select_name(name=bob.name)
bpy.ops.object.mode_set(mode='EDIT') bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.normals_make_consistent() bpy.ops.mesh.normals_make_consistent()
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
bob.ifc_id, bob.ifc_guid, bob.ifc_name, bob.ifc_type = \ bob.ifc_id, bob.ifc_guid, bob.ifc_name, bob.ifc_type = \
ob.id, ob.guid, ob.name, ob.type ob.id, ob_guid, ob_name, ob_type
bob.hide = ob.type == 'IfcSpace' bob.hide = ob_type == 'IfcSpace' or ob_type == 'IfcOpeningElement'
id_to_object[ob.id] = bob id_to_object[ob.id] = bob
if ob.parent_id > 0: if ob.parent_id > 0:
id_to_parent[ob.id] = ob.parent_id id_to_parent[ob.id] = ob.parent_id
progress = IfcImport.Progress() // 2 progress = IfcImport.Progress() // 2
if progress > old_progress: if progress > old_progress:
print("\r[" + "#" * progress + " " * (50 - progress) + "]", end="") print("\r[" + "#" * progress + " " * (50 - progress) + "]", end="")
@@ -158,9 +176,14 @@ def import_ifc(filename, use_names, process_relations):
bpy.context.scene.objects.link(bob) bpy.context.scene.objects.link(bob)
bob.ifc_id = parent_ob.id bob.ifc_id = parent_ob.id
bob.ifc_guid = parent_ob.guid if wrong_unicode:
bob.ifc_name = parent_ob.name bob.ifc_type = ''.join([chr(c) for c in parent_ob.type_as_intvector()])
bob.ifc_type = parent_ob.type bob.ifc_name = ''.join([chr(c) for c in parent_ob.name_as_intvector()])
bob.ifc_guid = ''.join([chr(c) for c in parent_ob.guid_as_intvector()])
else:
bob.ifc_guid = parent_ob.guid
bob.ifc_name = parent_ob.name
bob.ifc_type = parent_ob.type
if parent_ob.parent_id > 0: if parent_ob.parent_id > 0:
id_to_parent[parent_id] = parent_ob.parent_id id_to_parent[parent_id] = parent_ob.parent_id
@@ -183,9 +206,10 @@ def import_ifc(filename, use_names, process_relations):
if process_relations: if process_relations:
print("Done processing relations") print("Done processing relations")
txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename)) if not wrong_unicode:
txt.from_string(IfcImport.GetLog()) txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
txt.from_string(IfcImport.GetLog())
IfcImport.CleanUp() IfcImport.CleanUp()
@@ -209,16 +233,6 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
default=False) default=False)
def execute(self, context): def execute(self, context):
global wrong_unicode,warned_about_wrong_unicode
if wrong_unicode and not warned_about_wrong_unicode:
warned_about_wrong_unicode = True
self.report({'WARNING'},
"""This addon has been built with a different unicode configuration
This will result in incorrectly imported text and may result in undefined behaviour
Additionally it will result in IfcSpaces and IfcOpeningElements being visible by default
You can use the offical builds from the blender.org website instead
Sorry for the inconvenience"""
)
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.report({'ERROR'}, self.report({'ERROR'},
'Unable to parse .ifc file or no geometrical entities found' 'Unable to parse .ifc file or no geometrical entities found'
+7 -2
View File
@@ -435,8 +435,13 @@ const IfcGeomObjects::IfcGeomObject* IfcGeomObjects::Get() {
bool IfcGeomObjects::Init(const std::string fn) { bool IfcGeomObjects::Init(const std::string fn) {
return IfcGeomObjects::Init(fn, 0, 0); return IfcGeomObjects::Init(fn, 0, 0);
} }
bool IfcGeomObjects::InitUCS2(char* fn) { bool IfcGeomObjects::Init(const std::vector<int>& fn) {
return IfcGeomObjects::Init(fn+1, 0, 0); std::string f;
for ( std::vector<int>::const_iterator it = fn.begin(); it != fn.end(); ++ it ) {
const char c = (char) *it;
f.push_back(c);
}
return IfcGeomObjects::Init(f, 0, 0);
} }
bool _Init() { bool _Init() {
shapereps = Ifc::EntitiesByType<Ifc2x3::IfcShapeRepresentation>(); shapereps = Ifc::EntitiesByType<Ifc2x3::IfcShapeRepresentation>();
+1 -1
View File
@@ -116,7 +116,7 @@ namespace IfcGeomObjects {
}; };
bool Init(const std::string fn); bool Init(const std::string fn);
bool InitUCS2(char* fn); bool Init(const std::vector<int>& fn);
bool Init(void* data, int len); bool Init(void* data, int len);
bool Init(const std::string fn, std::ostream* log1= 0, std::ostream* log2= 0); bool Init(const std::string fn, std::ostream* log1= 0, std::ostream* log2= 0);
bool Init(std::istream& f, int len, std::ostream* log1= 0, std::ostream* log2= 0); bool Init(std::istream& f, int len, std::ostream* log1= 0, std::ostream* log2= 0);
+16 -1
View File
@@ -39,6 +39,21 @@ namespace IfcGeomObjects {
std::string type; std::string type;
std::string guid; std::string guid;
std::vector<float> matrix; std::vector<float> matrix;
const std::vector<int> name_as_intvector() {
std::vector<int> r;
for ( std::string::const_iterator it = name.begin(); it != name.end(); ++ it ) r.push_back(*it);
return r;
}
const std::vector<int> type_as_intvector() {
std::vector<int> r;
for ( std::string::const_iterator it = type.begin(); it != type.end(); ++ it ) r.push_back(*it);
return r;
}
const std::vector<int> guid_as_intvector() {
std::vector<int> r;
for ( std::string::const_iterator it = guid.begin(); it != guid.end(); ++ it ) r.push_back(*it);
return r;
}
}; };
class IfcGeomObject : public IfcObject { class IfcGeomObject : public IfcObject {
@@ -49,7 +64,7 @@ namespace IfcGeomObjects {
bool Next(); bool Next();
const IfcGeomObject* Get(); const IfcGeomObject* Get();
bool Init(const std::string fn); bool Init(const std::string fn);
bool InitUCS2(char* fn); bool Init(const std::vector<int>& fn);
void Settings(int setting, bool value); void Settings(int setting, bool value);
int Progress(); int Progress();
const IfcObject* GetObject(int id); const IfcObject* GetObject(int id);