mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 23:36:20 +00:00
Format obj and dae output predictably based on rfc notation of GlobalId. As discussed in https://sourceforge.net/p/ifcopenshell/discussion/1782717/thread/cbb0c8ca/
This commit is contained in:
@@ -129,7 +129,7 @@ ADD_LIBRARY(IfcParse STATIC
|
|||||||
../src/ifcparse/Ifc4-latebound.cpp
|
../src/ifcparse/Ifc4-latebound.cpp
|
||||||
../src/ifcparse/Ifc4.cpp
|
../src/ifcparse/Ifc4.cpp
|
||||||
../src/ifcparse/IfcCharacterDecoder.cpp
|
../src/ifcparse/IfcCharacterDecoder.cpp
|
||||||
../src/ifcparse/IfcGuidHelper.cpp
|
../src/ifcparse/IfcGlobalId.cpp
|
||||||
../src/ifcparse/IfcHierarchyHelper.cpp
|
../src/ifcparse/IfcHierarchyHelper.cpp
|
||||||
../src/ifcparse/IfcLateBoundEntity.cpp
|
../src/ifcparse/IfcLateBoundEntity.cpp
|
||||||
../src/ifcparse/IfcParse.cpp
|
../src/ifcparse/IfcParse.cpp
|
||||||
@@ -220,6 +220,7 @@ SET(include_files_parse
|
|||||||
../src/ifcparse/IfcEntityDescriptor.h
|
../src/ifcparse/IfcEntityDescriptor.h
|
||||||
../src/ifcparse/IfcException.h
|
../src/ifcparse/IfcException.h
|
||||||
../src/ifcparse/IfcFile.h
|
../src/ifcparse/IfcFile.h
|
||||||
|
../src/ifcparse/IfcGlobalId.h
|
||||||
../src/ifcparse/IfcHierarchyHelper.h
|
../src/ifcparse/IfcHierarchyHelper.h
|
||||||
../src/ifcparse/IfcLateBoundEntity.h
|
../src/ifcparse/IfcLateBoundEntity.h
|
||||||
../src/ifcparse/IfcParse.h
|
../src/ifcparse/IfcParse.h
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
// Some convenience typedefs and definitions.
|
// Some convenience typedefs and definitions.
|
||||||
typedef std::string S;
|
typedef std::string S;
|
||||||
typedef IfcWrite::IfcGuidHelper guid;
|
typedef IfcParse::IfcGlobalId guid;
|
||||||
typedef std::pair<double, double> XY;
|
typedef std::pair<double, double> XY;
|
||||||
boost::none_t const null = (static_cast<boost::none_t>(0));
|
boost::none_t const null = (static_cast<boost::none_t>(0));
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ std::string collada_id(const std::string& s) {
|
|||||||
id.reserve(s.size());
|
id.reserve(s.size());
|
||||||
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
||||||
const std::string::value_type c = *it;
|
const std::string::value_type c = *it;
|
||||||
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_')) {
|
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || ( c == '-')) {
|
||||||
id.push_back(c);
|
id.push_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n
|
|||||||
asset.add();
|
asset.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::write(const std::string& guid, const std::string& name, const std::string& type, const std::string& context, int obj_id, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& _materials) {
|
void ColladaSerializer::ColladaExporter::write(const std::string& unique_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& _materials) {
|
||||||
std::vector<std::string> material_references;
|
std::vector<std::string> material_references;
|
||||||
for (std::vector<IfcGeom::Material>::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
|
for (std::vector<IfcGeom::Material>::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
|
||||||
const IfcGeom::Material& material = *it;
|
const IfcGeom::Material& material = *it;
|
||||||
@@ -256,18 +256,7 @@ void ColladaSerializer::ColladaExporter::write(const std::string& guid, const st
|
|||||||
}
|
}
|
||||||
material_references.push_back(collada_id(material.name()));
|
material_references.push_back(collada_id(material.name()));
|
||||||
}
|
}
|
||||||
deferreds.push_back(DeferredObject(guid, name, type, context, obj_id, matrix, vertices, normals, faces, edges, material_ids, _materials, material_references));
|
deferreds.push_back(DeferredObject(unique_id, type, matrix, vertices, normals, faces, edges, material_ids, _materials, material_references));
|
||||||
}
|
|
||||||
|
|
||||||
const std::string ColladaSerializer::ColladaExporter::DeferredObject::Name() const {
|
|
||||||
std::stringstream ss;
|
|
||||||
if (!this->name.empty()) {
|
|
||||||
ss << this->obj_id << "_" << this->name;
|
|
||||||
} else {
|
|
||||||
ss << this->guid;
|
|
||||||
}
|
|
||||||
ss << "_" << this->context;
|
|
||||||
return collada_id(ss.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::endDocument() {
|
void ColladaSerializer::ColladaExporter::endDocument() {
|
||||||
@@ -275,13 +264,13 @@ void ColladaSerializer::ColladaExporter::endDocument() {
|
|||||||
// only at this point all objects are written to the stream.
|
// only at this point all objects are written to the stream.
|
||||||
materials.write();
|
materials.write();
|
||||||
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
|
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
|
||||||
const std::string object_name = it->Name();
|
const std::string object_name = it->unique_id + "-representation";
|
||||||
geometries.write(object_name, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials);
|
geometries.write(object_name, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials);
|
||||||
}
|
}
|
||||||
geometries.close();
|
geometries.close();
|
||||||
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
|
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
|
||||||
const std::string object_name = it->Name();
|
const std::string object_name = it->unique_id;
|
||||||
scene.add(object_name + "-instance", object_name, object_name, it->material_references, it->matrix);
|
scene.add(object_name, object_name, object_name + "-representation", it->material_references, it->matrix);
|
||||||
}
|
}
|
||||||
scene.write();
|
scene.write();
|
||||||
stream.endDocument();
|
stream.endDocument();
|
||||||
@@ -297,7 +286,7 @@ void ColladaSerializer::writeHeader() {
|
|||||||
|
|
||||||
void ColladaSerializer::write(const IfcGeom::TriangulationElement<double>* o) {
|
void ColladaSerializer::write(const IfcGeom::TriangulationElement<double>* o) {
|
||||||
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
||||||
exporter.write(o->guid(), o->name(), o->type(), o->context(), o->id(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials());
|
exporter.write(o->unique_id(), o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::finalize() {
|
void ColladaSerializer::finalize() {
|
||||||
|
|||||||
@@ -94,8 +94,7 @@ private:
|
|||||||
};
|
};
|
||||||
class DeferredObject {
|
class DeferredObject {
|
||||||
public:
|
public:
|
||||||
std::string guid, name, type, context;
|
std::string unique_id, type;
|
||||||
int obj_id;
|
|
||||||
std::vector<double> matrix;
|
std::vector<double> matrix;
|
||||||
std::vector<double> vertices;
|
std::vector<double> vertices;
|
||||||
std::vector<double> normals;
|
std::vector<double> normals;
|
||||||
@@ -104,14 +103,11 @@ private:
|
|||||||
std::vector<int> material_ids;
|
std::vector<int> material_ids;
|
||||||
std::vector<IfcGeom::Material> materials;
|
std::vector<IfcGeom::Material> materials;
|
||||||
std::vector<std::string> material_references;
|
std::vector<std::string> material_references;
|
||||||
DeferredObject(const std::string& guid, const std::string& name, const std::string& type, const std::string& context, int obj_id, const std::vector<double>& matrix, const std::vector<double>& vertices,
|
DeferredObject(const std::string& unique_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices,
|
||||||
const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids,
|
const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids,
|
||||||
const std::vector<IfcGeom::Material>& materials, const std::vector<std::string>& material_references)
|
const std::vector<IfcGeom::Material>& materials, const std::vector<std::string>& material_references)
|
||||||
: guid(guid)
|
: unique_id(unique_id)
|
||||||
, name(name)
|
|
||||||
, type(type)
|
, type(type)
|
||||||
, context(context)
|
|
||||||
, obj_id(obj_id)
|
|
||||||
, matrix(matrix)
|
, matrix(matrix)
|
||||||
, vertices(vertices)
|
, vertices(vertices)
|
||||||
, normals(normals)
|
, normals(normals)
|
||||||
@@ -121,7 +117,6 @@ private:
|
|||||||
, materials(materials)
|
, materials(materials)
|
||||||
, material_references(material_references)
|
, material_references(material_references)
|
||||||
{}
|
{}
|
||||||
const std::string Name() const;
|
|
||||||
};
|
};
|
||||||
COLLADABU::NativeString filename;
|
COLLADABU::NativeString filename;
|
||||||
COLLADASW::StreamWriter stream;
|
COLLADASW::StreamWriter stream;
|
||||||
@@ -139,7 +134,7 @@ private:
|
|||||||
std::vector<DeferredObject> deferreds;
|
std::vector<DeferredObject> deferreds;
|
||||||
virtual ~ColladaExporter() {}
|
virtual ~ColladaExporter() {}
|
||||||
void startDocument(const std::string& unit_name, float unit_magnitude);
|
void startDocument(const std::string& unit_name, float unit_magnitude);
|
||||||
void write(const std::string& guid, const std::string& name, const std::string& type, const std::string& context, int obj_id, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& materials);
|
void write(const std::string& unique_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& materials);
|
||||||
void endDocument();
|
void endDocument();
|
||||||
};
|
};
|
||||||
ColladaExporter exporter;
|
ColladaExporter exporter;
|
||||||
|
|||||||
@@ -67,13 +67,7 @@ void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style) {
|
|||||||
}
|
}
|
||||||
void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement<double>* o) {
|
void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement<double>* o) {
|
||||||
|
|
||||||
std::string tmp = o->name().empty() ? o->guid() : o->name();
|
obj_stream << "g " << o->unique_id() << "\n";
|
||||||
|
|
||||||
std::replace( tmp.begin(), tmp.end(), ' ', '_');
|
|
||||||
std::string name = tmp;
|
|
||||||
name += std::string("_") + o->context();
|
|
||||||
|
|
||||||
obj_stream << "g " << name << "\n";
|
|
||||||
obj_stream << "s 1" << "\n";
|
obj_stream << "s 1" << "\n";
|
||||||
|
|
||||||
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
||||||
|
|||||||
@@ -20,10 +20,14 @@
|
|||||||
#ifndef IFCGEOMELEMENT_H
|
#ifndef IFCGEOMELEMENT_H
|
||||||
#define IFCGEOMELEMENT_H
|
#define IFCGEOMELEMENT_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "../ifcparse/IfcGlobalId.h"
|
||||||
|
|
||||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||||
|
|
||||||
|
|
||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
|
|
||||||
template <typename P>
|
template <typename P>
|
||||||
@@ -73,6 +77,7 @@ namespace IfcGeom {
|
|||||||
std::string _type;
|
std::string _type;
|
||||||
std::string _guid;
|
std::string _guid;
|
||||||
std::string _context;
|
std::string _context;
|
||||||
|
std::string _unique_id;
|
||||||
Transformation<P> _transformation;
|
Transformation<P> _transformation;
|
||||||
public:
|
public:
|
||||||
int id() const { return _id; }
|
int id() const { return _id; }
|
||||||
@@ -81,10 +86,21 @@ namespace IfcGeom {
|
|||||||
const std::string& type() const { return _type; }
|
const std::string& type() const { return _type; }
|
||||||
const std::string& guid() const { return _guid; }
|
const std::string& guid() const { return _guid; }
|
||||||
const std::string& context() const { return _context; }
|
const std::string& context() const { return _context; }
|
||||||
|
const std::string& unique_id() const { return _unique_id; }
|
||||||
const Transformation<P>& transformation() const { return _transformation; }
|
const Transformation<P>& transformation() const { return _transformation; }
|
||||||
Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const std::string& context, const gp_Trsf& trsf)
|
Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const std::string& context, const gp_Trsf& trsf)
|
||||||
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
|
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
|
||||||
{}
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "product-" << IfcParse::IfcGlobalId(guid).formatted();
|
||||||
|
if (!_context.empty()) {
|
||||||
|
std::string ctx = _context;
|
||||||
|
std::transform(ctx.begin(), ctx.end(), ctx.begin(), ::tolower);
|
||||||
|
std::replace(ctx.begin(), ctx.end(), ' ', '-');
|
||||||
|
oss << "-" << ctx;
|
||||||
|
}
|
||||||
|
_unique_id = oss.str();
|
||||||
|
}
|
||||||
virtual ~Element() {}
|
virtual ~Element() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -57,17 +57,20 @@ namespace IfcGeom {
|
|||||||
boost::optional<double> specularity;
|
boost::optional<double> specularity;
|
||||||
public:
|
public:
|
||||||
SurfaceStyle() {
|
SurfaceStyle() {
|
||||||
this->name = "IfcSurfaceStyleShading";
|
this->name = "surface-style";
|
||||||
}
|
}
|
||||||
SurfaceStyle(int id) : id(id) {
|
SurfaceStyle(int id) : id(id) {
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr << "IfcSurfaceStyleShading_" << id;
|
sstr << "surface-style-" << id;
|
||||||
this->name = sstr.str();
|
this->name = sstr.str();
|
||||||
}
|
}
|
||||||
SurfaceStyle(const std::string& name) : name(name) {}
|
SurfaceStyle(const std::string& name) : name(name) {}
|
||||||
SurfaceStyle(int id, const std::string& name) : id(id) {
|
SurfaceStyle(int id, const std::string& name) : id(id) {
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr << id << "_" << name;
|
std::string sanitized = name;
|
||||||
|
std::transform(sanitized.begin(), sanitized.end(), sanitized.begin(), ::tolower);
|
||||||
|
std::replace(sanitized.begin(), sanitized.end(), ' ', '-');
|
||||||
|
sstr << "surface-style-" << id << "-" << sanitized;
|
||||||
this->name = sstr.str();
|
this->name = sstr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ class file(object):
|
|||||||
return entity_instance(self.wrapped_data.by_id(key))
|
return entity_instance(self.wrapped_data.by_id(key))
|
||||||
elif isinstance(key, str):
|
elif isinstance(key, str):
|
||||||
return entity_instance(self.wrapped_data.by_guid(key))
|
return entity_instance(self.wrapped_data.by_guid(key))
|
||||||
|
def by_id(self, id): return self[id]
|
||||||
|
def by_guid(self, guid): return self[guid]
|
||||||
def add(self, inst):
|
def add(self, inst):
|
||||||
inst.wrapped_data.this.disown()
|
inst.wrapped_data.this.disown()
|
||||||
return entity_instance(self.wrapped_data.add(inst.wrapped_data))
|
return entity_instance(self.wrapped_data.add(inst.wrapped_data))
|
||||||
|
|||||||
@@ -17,91 +17,112 @@
|
|||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
/********************************************************************************
|
#include <vector>
|
||||||
* *
|
|
||||||
* Please consider this a placeholder for an actual GlobalId generation *
|
|
||||||
* algorithm. A real implementation could for example be based on Boost::uuid *
|
|
||||||
* *
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <boost/uuid/uuid.hpp>
|
#include <boost/uuid/uuid.hpp>
|
||||||
#include <boost/uuid/uuid_generators.hpp>
|
#include <boost/uuid/uuid_generators.hpp>
|
||||||
#include <boost/uuid/uuid_io.hpp>
|
#include <boost/uuid/uuid_io.hpp>
|
||||||
|
|
||||||
#include "../ifcparse/IfcWrite.h"
|
#include "../ifcparse/IfcGlobalId.h"
|
||||||
#include "../ifcparse/IfcException.h"
|
#include "../ifcparse/IfcException.h"
|
||||||
|
|
||||||
static const char* chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$";
|
static const char* chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$";
|
||||||
|
|
||||||
// Converts an unsigned integer into a base64 string of length l
|
// Converts an unsigned integer into a base64 string of length l
|
||||||
std::string base64(unsigned v, int l) {
|
std::string base64(unsigned v, int l) {
|
||||||
std::string r;
|
std::string r;
|
||||||
r.reserve(l);
|
r.reserve(l);
|
||||||
while ( v ) {
|
while ( v ) {
|
||||||
r.push_back(chars[v%64]);
|
r.push_back(chars[v%64]);
|
||||||
v /= 64;
|
v /= 64;
|
||||||
}
|
}
|
||||||
while ( r.size() != l ) r.push_back('0');
|
while ( r.size() != l ) r.push_back('0');
|
||||||
std::reverse(r.begin(),r.end());
|
std::reverse(r.begin(),r.end());
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a base64 string into an unsigned integer
|
// Converts a base64 string into an unsigned integer
|
||||||
unsigned from_base64(const std::string& s) {
|
unsigned from_base64(const std::string& s) {
|
||||||
std::string::size_type zeros = s.find_first_not_of('0');
|
std::string::size_type zeros = s.find_first_not_of('0');
|
||||||
unsigned r = 0;
|
unsigned r = 0;
|
||||||
if ( zeros != std::string::npos )
|
if ( zeros != std::string::npos )
|
||||||
for ( std::string::const_iterator i = s.begin()+zeros; i != s.end(); ++ i ) {
|
for ( std::string::const_iterator i = s.begin()+zeros; i != s.end(); ++ i ) {
|
||||||
r *= 64;
|
r *= 64;
|
||||||
const char* c = strchr(chars,*i);
|
const char* c = strchr(chars,*i);
|
||||||
if ( !c ) throw IfcParse::IfcException("Failed to decode GlobalId");
|
if ( !c ) throw IfcParse::IfcException("Failed to decode GlobalId");
|
||||||
r += (c-chars);
|
r += (c-chars);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compresses the UUID byte array into a base64 representation
|
// Compresses the UUID byte array into a base64 representation
|
||||||
std::string compress(unsigned char* v) {
|
std::string compress(unsigned char* v) {
|
||||||
std::string r;
|
std::string r;
|
||||||
r.reserve(22);
|
r.reserve(22);
|
||||||
r += base64(v[0],2);
|
r += base64(v[0],2);
|
||||||
for ( unsigned i = 1; i < 16; i += 3 ) {
|
for ( unsigned i = 1; i < 16; i += 3 ) {
|
||||||
r += base64((v[i]<<16) + (v[i+1]<<8) + v[i+2],4);
|
r += base64((v[i]<<16) + (v[i+1]<<8) + v[i+2],4);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expands the base64 representation into a UUID byte array
|
// Expands the base64 representation into a UUID byte array
|
||||||
void expand(const std::string& s, std::vector<unsigned char>& v) {
|
void expand(const std::string& s, std::vector<unsigned char>& v) {
|
||||||
v.push_back(from_base64(s.substr(0,2)));
|
v.push_back(from_base64(s.substr(0,2)));
|
||||||
for( unsigned i = 0; i < 5; ++i ) {
|
for( unsigned i = 0; i < 5; ++i ) {
|
||||||
unsigned d = from_base64(s.substr(2+4*i,4));
|
unsigned d = from_base64(s.substr(2+4*i,4));
|
||||||
for ( unsigned j = 0; j < 3; ++ j ) {
|
for ( unsigned j = 0; j < 3; ++ j ) {
|
||||||
v.push_back((d>>(8*(2-j))) % 256);
|
v.push_back((d>>(8*(2-j))) % 256);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A random number generator for the UUID
|
// A random number generator for the UUID
|
||||||
static boost::uuids::basic_random_generator<boost::mt19937> gen;
|
static boost::uuids::basic_random_generator<boost::mt19937> gen;
|
||||||
|
|
||||||
IfcWrite::IfcGuidHelper::IfcGuidHelper() {
|
IfcParse::IfcGlobalId::IfcGlobalId() {
|
||||||
boost::uuids::uuid u = gen();
|
uuid_data = gen();
|
||||||
std::vector<unsigned char> v(u.size());
|
std::vector<unsigned char> v(uuid_data.size());
|
||||||
std::copy(u.begin(), u.end(), v.begin());
|
std::copy(uuid_data.begin(), uuid_data.end(), v.begin());
|
||||||
data = compress(&v[0]);
|
string_data = compress(&v[0]);
|
||||||
|
formatted_string = boost::uuids::to_string(uuid_data);
|
||||||
|
|
||||||
std::vector<unsigned char> v2;
|
#ifndef NDEBUG
|
||||||
expand(data,v2);
|
std::vector<unsigned char> test_vector;
|
||||||
boost::uuids::uuid u2;
|
expand(string_data, test_vector);
|
||||||
std::copy(v2.begin(), v2.end(), u2.begin());
|
boost::uuids::uuid test_uuid;
|
||||||
}
|
std::copy(test_vector.begin(), test_vector.end(), test_uuid.begin());
|
||||||
IfcWrite::IfcGuidHelper::operator std::string() const {
|
if (uuid_data != test_uuid) {
|
||||||
return data;
|
throw IfcParse::IfcException("Internal error generating GlobalId");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IfcWrite::IfcGuidHelper::seeded = false;
|
IfcParse::IfcGlobalId::IfcGlobalId(const std::string& s)
|
||||||
|
: string_data(s)
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> v;
|
||||||
|
expand(string_data, v);
|
||||||
|
std::copy(v.begin(), v.end(), uuid_data.begin());
|
||||||
|
formatted_string = boost::uuids::to_string(uuid_data);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
const std::string test_string = compress(&uuid_data.data[0]);
|
||||||
|
if (string_data != test_string) {
|
||||||
|
throw IfcParse::IfcException("Internal error generating GlobalId");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcParse::IfcGlobalId::operator const std::string&() const {
|
||||||
|
return string_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcParse::IfcGlobalId::operator const boost::uuids::uuid&() const {
|
||||||
|
return uuid_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& IfcParse::IfcGlobalId::formatted() const {
|
||||||
|
return formatted_string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/********************************************************************************
|
||||||
|
* *
|
||||||
|
* 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 IFCGLOBALID_H
|
||||||
|
#define IFCGLOBALID_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/uuid/uuid.hpp>
|
||||||
|
|
||||||
|
namespace IfcParse {
|
||||||
|
|
||||||
|
/// A helper class for the creation of IFC GlobalIds.
|
||||||
|
class IfcGlobalId {
|
||||||
|
private:
|
||||||
|
std::string string_data, formatted_string;
|
||||||
|
boost::uuids::uuid uuid_data;
|
||||||
|
public:
|
||||||
|
static const unsigned int length = 22;
|
||||||
|
IfcGlobalId();
|
||||||
|
IfcGlobalId(const std::string&);
|
||||||
|
operator const std::string&() const;
|
||||||
|
operator const boost::uuids::uuid&() const;
|
||||||
|
const std::string& formatted() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -108,7 +108,7 @@ IfcSchema::IfcProject* IfcHierarchyHelper::addProject(IfcSchema::IfcOwnerHistory
|
|||||||
|
|
||||||
IfcSchema::IfcUnitAssignment* unit_assignment = new IfcSchema::IfcUnitAssignment(units);
|
IfcSchema::IfcUnitAssignment* unit_assignment = new IfcSchema::IfcUnitAssignment(units);
|
||||||
|
|
||||||
IfcSchema::IfcProject* project = new IfcSchema::IfcProject(IfcWrite::IfcGuidHelper(), owner_hist, boost::none, boost::none,
|
IfcSchema::IfcProject* project = new IfcSchema::IfcProject(IfcParse::IfcGlobalId(), owner_hist, boost::none, boost::none,
|
||||||
boost::none, boost::none, boost::none, rep_contexts, unit_assignment);
|
boost::none, boost::none, boost::none, rep_contexts, unit_assignment);
|
||||||
|
|
||||||
addEntity(dimexp);
|
addEntity(dimexp);
|
||||||
@@ -146,7 +146,7 @@ IfcSchema::IfcSite* IfcHierarchyHelper::addSite(IfcSchema::IfcProject* proj, Ifc
|
|||||||
proj = addProject(owner_hist);
|
proj = addProject(owner_hist);
|
||||||
}
|
}
|
||||||
|
|
||||||
IfcSchema::IfcSite* site = new IfcSchema::IfcSite(IfcWrite::IfcGuidHelper(), owner_hist, boost::none,
|
IfcSchema::IfcSite* site = new IfcSchema::IfcSite(IfcParse::IfcGlobalId(), owner_hist, boost::none,
|
||||||
boost::none, boost::none, addLocalPlacement(), 0, boost::none,
|
boost::none, boost::none, addLocalPlacement(), 0, boost::none,
|
||||||
IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT,
|
IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT,
|
||||||
boost::none, boost::none, boost::none, boost::none, 0);
|
boost::none, boost::none, boost::none, boost::none, 0);
|
||||||
@@ -169,7 +169,7 @@ IfcSchema::IfcBuilding* IfcHierarchyHelper::addBuilding(IfcSchema::IfcSite* site
|
|||||||
if (! site) {
|
if (! site) {
|
||||||
site = addSite(0, owner_hist);
|
site = addSite(0, owner_hist);
|
||||||
}
|
}
|
||||||
IfcSchema::IfcBuilding* building = new IfcSchema::IfcBuilding(IfcWrite::IfcGuidHelper(), owner_hist, boost::none, boost::none, boost::none,
|
IfcSchema::IfcBuilding* building = new IfcSchema::IfcBuilding(IfcParse::IfcGlobalId(), owner_hist, boost::none, boost::none, boost::none,
|
||||||
addLocalPlacement(), 0, boost::none, IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT,
|
addLocalPlacement(), 0, boost::none, IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT,
|
||||||
boost::none, boost::none, 0);
|
boost::none, boost::none, 0);
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ IfcSchema::IfcBuildingStorey* IfcHierarchyHelper::addBuildingStorey(IfcSchema::I
|
|||||||
if (! building) {
|
if (! building) {
|
||||||
building = addBuilding(0, owner_hist);
|
building = addBuilding(0, owner_hist);
|
||||||
}
|
}
|
||||||
IfcSchema::IfcBuildingStorey* storey = new IfcSchema::IfcBuildingStorey(IfcWrite::IfcGuidHelper(),
|
IfcSchema::IfcBuildingStorey* storey = new IfcSchema::IfcBuildingStorey(IfcParse::IfcGlobalId(),
|
||||||
owner_hist, boost::none, boost::none, boost::none, addLocalPlacement(), 0, boost::none,
|
owner_hist, boost::none, boost::none, boost::none, addLocalPlacement(), 0, boost::none,
|
||||||
IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT, boost::none);
|
IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT, boost::none);
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,10 @@
|
|||||||
#else
|
#else
|
||||||
#include "../ifcparse/Ifc2x3.h"
|
#include "../ifcparse/Ifc2x3.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../ifcparse/IfcFile.h"
|
#include "../ifcparse/IfcFile.h"
|
||||||
#include "../ifcparse/IfcWrite.h"
|
#include "../ifcparse/IfcWrite.h"
|
||||||
|
#include "../ifcparse/IfcGlobalId.h"
|
||||||
|
|
||||||
class IfcHierarchyHelper : public IfcParse::IfcFile {
|
class IfcHierarchyHelper : public IfcParse::IfcFile {
|
||||||
public:
|
public:
|
||||||
@@ -100,7 +102,7 @@ public:
|
|||||||
}
|
}
|
||||||
IfcSchema::IfcObjectDefinition::list::ptr relating_objects (new IfcTemplatedEntityList<IfcSchema::IfcObjectDefinition>());
|
IfcSchema::IfcObjectDefinition::list::ptr relating_objects (new IfcTemplatedEntityList<IfcSchema::IfcObjectDefinition>());
|
||||||
relating_objects->push(relating_object);
|
relating_objects->push(relating_object);
|
||||||
T* t = new T(IfcWrite::IfcGuidHelper(), owner_hist, boost::none, boost::none, related_object, relating_objects);
|
T* t = new T(IfcParse::IfcGlobalId(), owner_hist, boost::none, boost::none, related_object, relating_objects);
|
||||||
addEntity(t);
|
addEntity(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +198,7 @@ inline void IfcHierarchyHelper::addRelatedObject <IfcSchema::IfcRelContainedInSp
|
|||||||
}
|
}
|
||||||
IfcSchema::IfcProduct::list::ptr relating_objects (new IfcTemplatedEntityList<IfcSchema::IfcProduct>());
|
IfcSchema::IfcProduct::list::ptr relating_objects (new IfcTemplatedEntityList<IfcSchema::IfcProduct>());
|
||||||
relating_objects->push((IfcSchema::IfcProduct*)relating_object);
|
relating_objects->push((IfcSchema::IfcProduct*)relating_object);
|
||||||
IfcSchema::IfcRelContainedInSpatialStructure* t = new IfcSchema::IfcRelContainedInSpatialStructure(IfcWrite::IfcGuidHelper(), owner_hist,
|
IfcSchema::IfcRelContainedInSpatialStructure* t = new IfcSchema::IfcRelContainedInSpatialStructure(IfcParse::IfcGlobalId(), owner_hist,
|
||||||
boost::none, boost::none, relating_objects, (IfcSchema::IfcSpatialStructureElement*)related_object);
|
boost::none, boost::none, relating_objects, (IfcSchema::IfcSpatialStructureElement*)related_object);
|
||||||
|
|
||||||
addEntity(t);
|
addEntity(t);
|
||||||
|
|||||||
@@ -136,17 +136,6 @@ namespace IfcWrite {
|
|||||||
IfcUtil::ArgumentType type() const;
|
IfcUtil::ArgumentType type() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A helper class for the creation of IFC GlobalIds.
|
|
||||||
class IfcGuidHelper {
|
|
||||||
private:
|
|
||||||
std::string data;
|
|
||||||
static bool seeded;
|
|
||||||
public:
|
|
||||||
static const unsigned int length = 22;
|
|
||||||
IfcGuidHelper();
|
|
||||||
operator std::string() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Accumulates all schema instances created from constructors
|
// Accumulates all schema instances created from constructors
|
||||||
// This way they can be added in a single batch to the IfcFile
|
// This way they can be added in a single batch to the IfcFile
|
||||||
class EntityBuffer {
|
class EntityBuffer {
|
||||||
|
|||||||
@@ -146,6 +146,7 @@
|
|||||||
type = property(type)
|
type = property(type)
|
||||||
guid = property(guid)
|
guid = property(guid)
|
||||||
context = property(context)
|
context = property(context)
|
||||||
|
unique_id = property(unique_id)
|
||||||
transformation = property(transformation)
|
transformation = property(transformation)
|
||||||
%}
|
%}
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-1
@@ -222,7 +222,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\ifcparse\IfcGuidHelper.cpp"
|
RelativePath="..\src\ifcparse\IfcGlobalId.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -279,6 +279,10 @@
|
|||||||
RelativePath="..\src\ifcparse\IfcFile.h"
|
RelativePath="..\src\ifcparse\IfcFile.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ifcparse\IfcGlobalId.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\ifcparse\IfcHierarchyHelper.h"
|
RelativePath="..\src\ifcparse\IfcHierarchyHelper.h"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user