mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
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:
@@ -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
|
|
||||||
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]] \
|
if wrong_unicode:
|
||||||
for i in range(0, len(v), 3)]
|
ob_type = ''.join([chr(c) for c in ob.type_as_intvector()])
|
||||||
faces = [[f[i], f[i + 1], f[i + 2]] \
|
ob_name = ''.join([chr(c) for c in ob.name_as_intvector()])
|
||||||
for i in range(0, len(f), 3)]
|
ob_guid = ''.join([chr(c) for c in ob.guid_as_intvector()])
|
||||||
|
else:
|
||||||
|
ob_type, ob_name, ob_guid = ob.name, ob.type, ob.guid
|
||||||
|
|
||||||
me = bpy.data.meshes.new('mesh%d' % ob.mesh.id)
|
f = ob.mesh.faces
|
||||||
me.from_pydata(verts, [], faces)
|
v = ob.mesh.verts
|
||||||
if t in bpy.data.materials:
|
m = ob.matrix
|
||||||
mat = bpy.data.materials[t]
|
t = ob_type[0:21]
|
||||||
mat.use_fake_user = True
|
nm = ob_name if len(ob_name) and use_names else ob_guid
|
||||||
else:
|
|
||||||
mat = bpy.data.materials.new(t)
|
|
||||||
me.materials.append(mat)
|
|
||||||
|
|
||||||
bob = bpy.data.objects.new(nm, me)
|
verts = [[v[i], v[i + 1], v[i + 2]] \
|
||||||
mat = mathutils.Matrix(([m[0], m[1], m[2], 0],
|
for i in range(0, len(v), 3)]
|
||||||
[m[3], m[4], m[5], 0],
|
faces = [[f[i], f[i + 1], f[i + 2]] \
|
||||||
[m[6], m[7], m[8], 0],
|
for i in range(0, len(f), 3)]
|
||||||
[m[9], m[10], m[11], 1]))
|
|
||||||
if process_relations:
|
|
||||||
id_to_matrix[ob.id] = mat
|
|
||||||
else:
|
|
||||||
bob.matrix_world = mat
|
|
||||||
bpy.context.scene.objects.link(bob)
|
|
||||||
|
|
||||||
bpy.ops.object.select_all(action='DESELECT')
|
me = bpy.data.meshes.new('mesh%d' % ob.mesh.id)
|
||||||
bpy.ops.object.select_name(name=bob.name)
|
me.from_pydata(verts, [], faces)
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
if t in bpy.data.materials:
|
||||||
bpy.ops.mesh.normals_make_consistent()
|
mat = bpy.data.materials[t]
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
mat.use_fake_user = True
|
||||||
|
else:
|
||||||
|
mat = bpy.data.materials.new(t)
|
||||||
|
me.materials.append(mat)
|
||||||
|
|
||||||
bob.ifc_id, bob.ifc_guid, bob.ifc_name, bob.ifc_type = \
|
bob = bpy.data.objects.new(nm, me)
|
||||||
ob.id, ob.guid, ob.name, ob.type
|
mat = mathutils.Matrix(([m[0], m[1], m[2], 0],
|
||||||
|
[m[3], m[4], m[5], 0],
|
||||||
|
[m[6], m[7], m[8], 0],
|
||||||
|
[m[9], m[10], m[11], 1]))
|
||||||
|
if process_relations:
|
||||||
|
id_to_matrix[ob.id] = mat
|
||||||
|
else:
|
||||||
|
bob.matrix_world = mat
|
||||||
|
bpy.context.scene.objects.link(bob)
|
||||||
|
|
||||||
bob.hide = ob.type == 'IfcSpace'
|
bpy.ops.object.select_all(action='DESELECT')
|
||||||
id_to_object[ob.id] = bob
|
bpy.ops.object.select_name(name=bob.name)
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
bpy.ops.mesh.normals_make_consistent()
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
bob.ifc_id, bob.ifc_guid, bob.ifc_name, bob.ifc_type = \
|
||||||
|
ob.id, ob_guid, ob_name, ob_type
|
||||||
|
|
||||||
|
bob.hide = ob_type == 'IfcSpace' or ob_type == 'IfcOpeningElement'
|
||||||
|
id_to_object[ob.id] = bob
|
||||||
|
|
||||||
|
if ob.parent_id > 0:
|
||||||
|
id_to_parent[ob.id] = ob.parent_id
|
||||||
|
|
||||||
if ob.parent_id > 0:
|
|
||||||
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
|
||||||
@@ -184,8 +207,9 @@ 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'
|
||||||
|
|||||||
@@ -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>();
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user