Getting ready for Blender 2.65 and Python 3.3.0 with universal Unicode according to PEP 393

Allow opening of non-latin filenames on Windows, by using the non-standard _wfopen(), meaning that the IfcSpfStream no longer relies on a std::istream but a FILE* descriptor
This commit is contained in:
Thomas Krijnen
2012-12-31 15:13:35 +00:00
parent 91d6d9f20f
commit 0714fbdab5
6 changed files with 50 additions and 95 deletions
+14 -53
View File
@@ -30,8 +30,8 @@ bl_info = {
"description": "Import files in the "\
"Industry Foundation Classes (.ifc) file format",
"author": "Thomas Krijnen, IfcOpenShell",
"blender": (2, 5, 8),
"api": 37702,
"blender": (2, 6, 5),
"api": 52851,
"location": "File > Import",
"warning": "",
"wiki_url": "http://sourceforge.net/apps/"\
@@ -39,14 +39,6 @@ bl_info = {
"tracker_url": "http://sourceforge.net/tracker/?group_id=543113",
"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, may result in undefined "\
"behaviour, please use offical release from http://blender.org\n")
if "bpy" in locals():
import imp
if "IfcImport" in locals():
@@ -71,15 +63,9 @@ bpy.types.Object.ifc_type = StringProperty(name="IFC Entity Type",
def import_ifc(filename, use_names, process_relations):
global wrong_unicode
from . import IfcImport
print("Reading %s..."%bpy.path.basename(filename))
if wrong_unicode:
valid_file = IfcImport.InitUCS2(
''.join(['\0']+['\0%s'%s for s in filename]+['\0\0'])
)
else:
valid_file = IfcImport.Init(filename)
valid_file = IfcImport.Init(filename)
if not valid_file:
IfcImport.CleanUp()
return False
@@ -91,19 +77,12 @@ def import_ifc(filename, use_names, process_relations):
print("Creating geometry...")
while True:
ob = IfcImport.Get()
if wrong_unicode:
ob_name = ''.join([chr(c) for c in ob.name_as_intvector()])
ob_type = ''.join([chr(c) for c in ob.type_as_intvector()])
ob_guid = ''.join([chr(c) for c in ob.guid_as_intvector()])
else:
ob_name, ob_type, 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
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]] \
for i in range(0, len(v), 3)]
@@ -138,9 +117,9 @@ def import_ifc(filename, use_names, process_relations):
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
ob.id, ob.guid, ob.name, ob.type
bob.hide = ob_type == 'IfcSpace' or ob_type == 'IfcOpeningElement'
bob.hide = ob.type == 'IfcSpace' or ob.type == 'IfcOpeningElement'
bob.hide_render = bob.hide
if ob.id not in id_to_object: id_to_object[ob.id] = []
@@ -173,20 +152,9 @@ def import_ifc(filename, use_names, process_relations):
if parent_ob.id == -1:
bob = None
else:
if wrong_unicode:
parent_ob_name = ''.join(
[chr(c) for c in parent_ob.name_as_intvector()])
parent_ob_type = ''.join(
[chr(c) for c in parent_ob.type_as_intvector()])
parent_ob_guid = ''.join(
[chr(c) for c in parent_ob.guid_as_intvector()])
else:
parent_ob_name, parent_ob_type, parent_ob_guid = \
parent_ob.name, parent_ob.type, parent_ob.guid
m = parent_ob.matrix
nm = parent_ob_name if len(parent_ob_name) and use_names \
else parent_ob_guid
nm = parent_ob.name if len(parent_ob.name) and use_names \
else parent_ob.guid
bob = bpy.data.objects.new(nm, None)
mat = mathutils.Matrix((
@@ -201,7 +169,7 @@ def import_ifc(filename, use_names, process_relations):
bob.ifc_id = parent_ob.id
bob.ifc_name, bob.ifc_type, bob.ifc_guid = \
parent_ob_name, parent_ob_type, parent_ob_guid
parent_ob.name, parent_ob.type, parent_ob.guid
if parent_ob.parent_id > 0:
id_to_parent[parent_id] = parent_ob.parent_id
@@ -227,9 +195,8 @@ def import_ifc(filename, use_names, process_relations):
if process_relations:
print("Done processing relations")
if not wrong_unicode:
txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
txt.from_string(IfcImport.GetLog())
txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
txt.from_string(IfcImport.GetLog())
IfcImport.CleanUp()
@@ -253,13 +220,7 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
default=False)
def execute(self, context):
global wrong_unicode
if wrong_unicode and sys.platform[0:5] != 'linux':
self.report({'ERROR'},
'Your version of Blender is incompatible with IfcBlender\n' \
'Please use the offical release from http://blender.org instead'
)
elif 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'},
'Unable to parse .ifc file or no geometrical entities found'
)
+1 -1
View File
@@ -70,7 +70,7 @@ int main ( int argc, char** argv ) {
std::cout << "Creating geometry..." << std::endl;
// The functions IfcGeomObjects::Get() and IfcGeomObjects::Next() wrap an iterator of all geometrical entities in the Ifc file.
// IfcGeomObjects::Get() returns an IfcGeomObjects::IfcGeomObject (see IfcObjects.h for definition)
// IfcGeomObjects::Get() returns an IfcGeomObjects::IfcGeomObject (see IfcGeomObjects.h for definition)
// IfcGeomObjects::Next() is used to poll whether more geometrical entities are available
int vcount_total = 1;
do {
+3 -3
View File
@@ -34,9 +34,9 @@
// 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
// manner efficiently. To enable the paging functionality uncomment
// the following statement.
//const int BUF_SIZE = (128 * 1024 * 1024);
// #define BUF_SIZE (8 * 1024 * 1024)
namespace IfcParse {
/// The IfcSpfStream class represents a ISO 10303-21 IFC-SPF file in memory.
@@ -48,7 +48,7 @@ namespace IfcParse {
/// detrimental for the performance of the parser.
class IfcSpfStream {
private:
std::ifstream stream;
FILE* stream;
char* buffer;
unsigned int ptr;
unsigned int len;
+30 -18
View File
@@ -22,6 +22,10 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
#include <Windows.h>
#endif
#include "../ifcparse/IfcCharacterDecoder.h"
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcException.h"
@@ -35,15 +39,23 @@ using namespace IfcParse;
//
IfcSpfStream::IfcSpfStream(const std::string& fn) {
eof = false;
stream.open(fn.c_str(),std::ios_base::binary);
if ( ! stream.good() ) {
#ifdef _MSC_VER
int fn_buffer_size = MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, 0, 0);
wchar_t* fn_wide = new wchar_t[fn_buffer_size];
MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, fn_wide, fn_buffer_size);
stream = _wfopen(fn_wide, L"rb");
delete[] fn_wide;
#else
stream = fopen(fn.c_str(), "rb");
#endif
if (stream == NULL) {
valid = false;
return;
}
valid = true;
stream.seekg(0,std::ios_base::end);
size = (unsigned int) stream.tellg();
stream.seekg(0,std::ios_base::beg);
fseek(stream, 0, SEEK_END);
size = (unsigned int) ftell(stream);;
rewind(stream);
#ifdef BUF_SIZE
offset = 0;
paging = size > BUF_SIZE;
@@ -85,7 +97,7 @@ IfcSpfStream::IfcSpfStream(void* data, int l) {
void IfcSpfStream::Close() {
#ifdef BUF_SIZE
if ( paging ) stream.close();
if ( paging ) fclose(stream);
#endif
delete[] buffer;
}
@@ -94,26 +106,26 @@ void IfcSpfStream::Close() {
// Reads a chunk of BUF_SIZE in memory and increments cursor if requested
//
void IfcSpfStream::ReadBuffer(bool inc) {
std::cout << "Readbuffer" << std::endl;
#ifdef BUF_SIZE
if ( inc ) {
offset += len;
stream.seekg(offset,std::ios_base::beg);
fseek(stream, offset, SEEK_SET);
}
#endif
eof = stream.eof();
eof = feof(stream) != 0;
if ( eof ) return;
#ifdef BUF_SIZE
stream.read(buffer,size < BUF_SIZE ? size : BUF_SIZE);
len = (unsigned int) fread(buffer, 1, size < BUF_SIZE ? size : BUF_SIZE, stream);
#else
stream.read(buffer,size);
len = (unsigned int) fread(buffer, 1, size, stream);
#endif
len = (unsigned int) stream.gcount();
eof = len == 0;
ptr = 0;
#ifdef BUF_SIZE
if (!paging) stream.close();
if (!paging) fclose(stream);
#else
stream.close();
fclose(stream);
#endif
}
@@ -132,8 +144,8 @@ void IfcSpfStream::Seek(unsigned int o) {
ptr = o - offset;
} else {
offset = o;
stream.clear();
stream.seekg(o,std::ios_base::beg);
clearerr(stream);
fseek(stream, o, SEEK_SET);
ReadBuffer(false);
}
#endif
@@ -158,9 +170,9 @@ char IfcSpfStream::Read(unsigned int o) {
} else if ( o >= offset && (o < (offset+len)) ) {
return buffer[o-offset];
} else {
stream.clear();
stream.seekg(o,std::ios_base::beg);
return stream.peek();
clearerr(stream);
fseek(stream, o, SEEK_SET);
return ungetc(getc(stream), stream);
}
#endif
}
-19
View File
@@ -45,21 +45,6 @@ namespace IfcGeomObjects {
std::string type;
std::string guid;
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 {
@@ -70,13 +55,9 @@ namespace IfcGeomObjects {
bool Next();
const IfcGeomObject* Get();
bool Init(const std::string fn);
bool InitUCS2(const char* fn) {
return Init(std::string(fn+1));
}
void Settings(int setting, bool value);
int Progress();
const IfcObject* GetObject(int id);
bool CleanUp();
std::string GetLog();
};
+2 -1
View File
@@ -63,7 +63,8 @@ scn.render.resolution_x = 2048
scn.render.resolution_y = 2048
scn.world.horizon_color = (1,1,1)
scn.world.ambient_color = (0.05,0.05,0.05)
scn.render.color_mode = 'RGBA'
try: scn.render.color_mode = 'RGBA'
except: scn.render.image_settings.color_mode = 'RGBA'
for m in bpy.data.materials: m.specular_intensity = 0
def material(name,settings):