mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 02:47:48 +00:00
Matrix multiplication in OCC rather than boost::ublas (re #211)
This commit is contained in:
@@ -32,14 +32,6 @@
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/numeric/ublas/vector.hpp>
|
||||
#include <boost/numeric/ublas/vector_proxy.hpp>
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
#include <boost/numeric/ublas/triangular.hpp>
|
||||
#include <boost/numeric/ublas/lu.hpp>
|
||||
#include <boost/numeric/ublas/io.hpp>
|
||||
|
||||
using namespace IfcSchema;
|
||||
using namespace boost::numeric::ublas;
|
||||
|
||||
@@ -69,7 +61,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(
|
||||
const std::string &mesh_id, const std::string& default_material_name, const std::vector<real_t>& positions,
|
||||
const std::string &mesh_id, const std::string& /*default_material_name*/, const std::vector<real_t>& positions,
|
||||
const std::vector<real_t>& 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<real_t>& uvs)
|
||||
@@ -188,7 +180,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::close() {
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
||||
const std::string& node_id, const std::string& node_name, const std::string& geom_name,
|
||||
const std::vector<std::string>& material_ids, const std::vector<real_t>& posmatrix)
|
||||
const std::vector<std::string>& material_ids, const IfcGeom::Transformation<real_t>& transformation)
|
||||
{
|
||||
if (!scene_opened) {
|
||||
openVisualScene(scene_id);
|
||||
@@ -202,46 +194,33 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
||||
|
||||
// The matrix attribute of an entity is basically a 4x3 representation of its ObjectPlacement.
|
||||
// Note that this placement is absolute, ie it is multiplied with all parent placements.
|
||||
|
||||
double matrix_array[4][4] = {
|
||||
{ (double)posmatrix[0], (double)posmatrix[3], (double)posmatrix[6], (double)posmatrix[ 9] },
|
||||
{ (double)posmatrix[1], (double)posmatrix[4], (double)posmatrix[7], (double)posmatrix[10] },
|
||||
{ (double)posmatrix[2], (double)posmatrix[5], (double)posmatrix[8], (double)posmatrix[11] },
|
||||
{ 0, 0, 0, 1 }
|
||||
};
|
||||
|
||||
IfcGeom::Transformation<real_t>* relative_trsf = 0;
|
||||
const IfcGeom::Transformation<real_t>* transformation_towrite = &transformation;
|
||||
|
||||
// If this is not the first parent, get the relative placement
|
||||
if (parentNodes.size() > 0)
|
||||
{
|
||||
double relative[4][4] = {
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
// Multiplication
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
relative[i][j] += matrixStack.top()(i, k) * matrix_array[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy from relative to matrix_array
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
matrix_array[i][j] = relative[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
relative_trsf = new IfcGeom::Transformation<real_t>(matrixStack.top().multiplied(transformation));
|
||||
transformation_towrite = relative_trsf;
|
||||
}
|
||||
|
||||
const std::vector<real_t>& posmatrix = transformation_towrite->matrix().data();
|
||||
|
||||
double matrix_array[4][4] = {
|
||||
{ (double)posmatrix[0], (double)posmatrix[3], (double)posmatrix[6], (double)posmatrix[9] },
|
||||
{ (double)posmatrix[1], (double)posmatrix[4], (double)posmatrix[7], (double)posmatrix[10] },
|
||||
{ (double)posmatrix[2], (double)posmatrix[5], (double)posmatrix[8], (double)posmatrix[11] },
|
||||
{ 0, 0, 0, 1 }
|
||||
};
|
||||
|
||||
/// @todo: TFK: Rather than applying this offset to all leafs (which might be undesirable) should this offset be applied to a node higher up in the hierarchy?
|
||||
matrix_array[0][3] += serializer->settings().offset[0];
|
||||
matrix_array[1][3] += serializer->settings().offset[1];
|
||||
matrix_array[2][3] += serializer->settings().offset[2];
|
||||
|
||||
delete relative_trsf;
|
||||
|
||||
node.start();
|
||||
node.addMatrix(matrix_array);
|
||||
COLLADASW::InstanceGeometry instanceGeometry(mSW);
|
||||
@@ -263,63 +242,36 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::
|
||||
scene_opened = true;
|
||||
}
|
||||
|
||||
const IfcGeom::Transformation<real_t>& parent_trsf = parent.transformation();
|
||||
|
||||
IfcGeom::Transformation<real_t>* relative_trsf = 0;
|
||||
const IfcGeom::Transformation<real_t>* transformation_towrite = &parent_trsf;
|
||||
|
||||
// If this is not the first parent, get the relative placement
|
||||
if (parentNodes.size() > 0)
|
||||
{
|
||||
relative_trsf = new IfcGeom::Transformation<real_t>(matrixStack.top().multiplied(parent_trsf));
|
||||
transformation_towrite = relative_trsf;
|
||||
}
|
||||
|
||||
const std::vector<real_t>& parentMatrix = transformation_towrite->matrix().data();
|
||||
|
||||
const std::vector<real_t> parentMatrix = parent.transformation().matrix().data();
|
||||
|
||||
double matrix_array[4][4] = {
|
||||
{ (double)parentMatrix[0], (double)parentMatrix[3], (double)parentMatrix[6], (double)parentMatrix[9] },
|
||||
{ (double)parentMatrix[1], (double)parentMatrix[4], (double)parentMatrix[7], (double)parentMatrix[10] },
|
||||
{ (double)parentMatrix[2], (double)parentMatrix[5], (double)parentMatrix[8], (double)parentMatrix[11] },
|
||||
{ 0, 0, 0, 1 }
|
||||
};
|
||||
|
||||
// =========
|
||||
|
||||
// If this is not the first parent, get the relative placement
|
||||
if (parentNodes.size() > 0)
|
||||
{
|
||||
double relative[4][4] = {
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
// Multiplication
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
relative[i][j] += matrixStack.top()(i, k) * matrix_array[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : Handle the case where there was no inverse
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
matrix_array[i][j] = relative[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//adding the offset to the matrix
|
||||
//matrix_array[0][3] += serializer->settings().offset[0];
|
||||
//matrix_array[1][3] += serializer->settings().offset[1];
|
||||
//matrix_array[2][3] += serializer->settings().offset[2];
|
||||
|
||||
|
||||
const std::string id = "representation-" + boost::lexical_cast<std::string>(parent.id());
|
||||
|
||||
// Chose a name of the parent object
|
||||
std::string name = "";
|
||||
if (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES)) { name = parent.type() + " " + parent.name(); }
|
||||
else
|
||||
{
|
||||
if (parent.name() == "") { name = "unnamed"; }
|
||||
else { name = parent.name(); }
|
||||
if (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES)) {
|
||||
name = parent.type() + " " + parent.name();
|
||||
} else {
|
||||
name = parent.unique_id();
|
||||
}
|
||||
|
||||
|
||||
const std::string& id = name;
|
||||
|
||||
COLLADASW::Node *current_node;
|
||||
current_node = new COLLADASW::Node(mSW);
|
||||
@@ -329,83 +281,10 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::
|
||||
current_node->start();
|
||||
current_node->addMatrix(matrix_array);
|
||||
|
||||
// ==== Inverse the matrix and save it ====
|
||||
|
||||
double m[4][4] = {
|
||||
{ (double)parentMatrix[0], (double)parentMatrix[3], (double)parentMatrix[6], (double)parentMatrix[9] },
|
||||
{ (double)parentMatrix[1], (double)parentMatrix[4], (double)parentMatrix[7], (double)parentMatrix[10] },
|
||||
{ (double)parentMatrix[2], (double)parentMatrix[5], (double)parentMatrix[8], (double)parentMatrix[11] },
|
||||
{ 0, 0, 0, 1 }
|
||||
};
|
||||
|
||||
double det =
|
||||
m[0][3] * m[1][2] * m[2][1] * m[3][0] - m[0][2] * m[1][3] * m[2][1] * m[3][0] - m[0][3] * m[1][1] * m[2][2] * m[3][0] + m[0][1] * m[1][3] * m[2][2] * m[3][0] +
|
||||
m[0][2] * m[1][1] * m[2][3] * m[3][0] - m[0][1] * m[1][2] * m[2][3] * m[3][0] - m[0][3] * m[1][2] * m[2][0] * m[3][1] + m[0][2] * m[1][3] * m[2][0] * m[3][1] +
|
||||
m[0][3] * m[1][0] * m[2][2] * m[3][1] - m[0][0] * m[1][3] * m[2][2] * m[3][1] - m[0][2] * m[1][0] * m[2][3] * m[3][1] + m[0][0] * m[1][2] * m[2][3] * m[3][1] +
|
||||
m[0][3] * m[1][1] * m[2][0] * m[3][2] - m[0][1] * m[1][3] * m[2][0] * m[3][2] - m[0][3] * m[1][0] * m[2][1] * m[3][2] + m[0][0] * m[1][3] * m[2][1] * m[3][2] +
|
||||
m[0][1] * m[1][0] * m[2][3] * m[3][2] - m[0][0] * m[1][1] * m[2][3] * m[3][2] - m[0][2] * m[1][1] * m[2][0] * m[3][3] + m[0][1] * m[1][2] * m[2][0] * m[3][3] +
|
||||
m[0][2] * m[1][0] * m[2][1] * m[3][3] - m[0][0] * m[1][2] * m[2][1] * m[3][3] - m[0][1] * m[1][0] * m[2][2] * m[3][3] + m[0][0] * m[1][1] * m[2][2] * m[3][3];
|
||||
|
||||
|
||||
if (det != 0)
|
||||
{
|
||||
double inverse[4][4];
|
||||
inverse[0][0] = m[1][2] * m[2][3] * m[3][1] - m[1][3] * m[2][2] * m[3][1] + m[1][3] * m[2][1] * m[3][2] - m[1][1] * m[2][3] * m[3][2] - m[1][2] * m[2][1] * m[3][3] + m[1][1] * m[2][2] * m[3][3];
|
||||
inverse[0][1] = m[0][3] * m[2][2] * m[3][1] - m[0][2] * m[2][3] * m[3][1] - m[0][3] * m[2][1] * m[3][2] + m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] - m[0][1] * m[2][2] * m[3][3];
|
||||
inverse[0][2] = m[0][2] * m[1][3] * m[3][1] - m[0][3] * m[1][2] * m[3][1] + m[0][3] * m[1][1] * m[3][2] - m[0][1] * m[1][3] * m[3][2] - m[0][2] * m[1][1] * m[3][3] + m[0][1] * m[1][2] * m[3][3];
|
||||
inverse[0][3] = m[0][3] * m[1][2] * m[2][1] - m[0][2] * m[1][3] * m[2][1] - m[0][3] * m[1][1] * m[2][2] + m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] - m[0][1] * m[1][2] * m[2][3];
|
||||
|
||||
inverse[1][0] = m[1][3] * m[2][2] * m[3][0] - m[1][2] * m[2][3] * m[3][0] - m[1][3] * m[2][0] * m[3][2] + m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] - m[1][0] * m[2][2] * m[3][3];
|
||||
inverse[1][1] = m[0][2] * m[2][3] * m[3][0] - m[0][3] * m[2][2] * m[3][0] + m[0][3] * m[2][0] * m[3][2] - m[0][0] * m[2][3] * m[3][2] - m[0][2] * m[2][0] * m[3][3] + m[0][0] * m[2][2] * m[3][3];
|
||||
inverse[1][2] = m[0][3] * m[1][2] * m[3][0] - m[0][2] * m[1][3] * m[3][0] - m[0][3] * m[1][0] * m[3][2] + m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] - m[0][0] * m[1][2] * m[3][3];
|
||||
inverse[1][3] = m[0][2] * m[1][3] * m[2][0] - m[0][3] * m[1][2] * m[2][0] + m[0][3] * m[1][0] * m[2][2] - m[0][0] * m[1][3] * m[2][2] - m[0][2] * m[1][0] * m[2][3] + m[0][0] * m[1][2] * m[2][3];
|
||||
|
||||
inverse[2][0] = m[1][1] * m[2][3] * m[3][0] - m[1][3] * m[2][1] * m[3][0] + m[1][3] * m[2][0] * m[3][1] - m[1][0] * m[2][3] * m[3][1] - m[1][1] * m[2][0] * m[3][3] + m[1][0] * m[2][1] * m[3][3];
|
||||
inverse[2][1] = m[0][3] * m[2][1] * m[3][0] - m[0][1] * m[2][3] * m[3][0] - m[0][3] * m[2][0] * m[3][1] + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] - m[0][0] * m[2][1] * m[3][3];
|
||||
inverse[2][2] = m[0][1] * m[1][3] * m[3][0] - m[0][3] * m[1][1] * m[3][0] + m[0][3] * m[1][0] * m[3][1] - m[0][0] * m[1][3] * m[3][1] - m[0][1] * m[1][0] * m[3][3] + m[0][0] * m[1][1] * m[3][3];
|
||||
inverse[2][3] = m[0][3] * m[1][1] * m[2][0] - m[0][1] * m[1][3] * m[2][0] - m[0][3] * m[1][0] * m[2][1] + m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] - m[0][0] * m[1][1] * m[2][3];
|
||||
|
||||
inverse[3][0] = m[1][2] * m[2][1] * m[3][0] - m[1][1] * m[2][2] * m[3][0] - m[1][2] * m[2][0] * m[3][1] + m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - m[1][0] * m[2][1] * m[3][2];
|
||||
inverse[3][1] = m[0][1] * m[2][2] * m[3][0] - m[0][2] * m[2][1] * m[3][0] + m[0][2] * m[2][0] * m[3][1] - m[0][0] * m[2][2] * m[3][1] - m[0][1] * m[2][0] * m[3][2] + m[0][0] * m[2][1] * m[3][2];
|
||||
inverse[3][2] = m[0][2] * m[1][1] * m[3][0] - m[0][1] * m[1][2] * m[3][0] - m[0][2] * m[1][0] * m[3][1] + m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - m[0][0] * m[1][1] * m[3][2];
|
||||
inverse[3][3] = m[0][1] * m[1][2] * m[2][0] - m[0][2] * m[1][1] * m[2][0] + m[0][2] * m[1][0] * m[2][1] - m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2] + m[0][0] * m[1][1] * m[2][2];
|
||||
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
inverse[i][j] /= det;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a save matrix to push to the stack
|
||||
matrix<double> toSave(4, 4);
|
||||
|
||||
// Initialization
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
toSave(i, j) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the inverse matrix
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
toSave(i, j) = inverse[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// Save the matrix
|
||||
matrixStack.push(toSave);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "couldn't inverse the position matrix \n";
|
||||
}
|
||||
|
||||
// Add the node to the parent stack
|
||||
matrixStack.push(parent_trsf.inverted());
|
||||
parentNodes.push(current_node);
|
||||
serializer->parentStackId.push(parent.id());
|
||||
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaScene::closeParent()
|
||||
@@ -532,12 +411,14 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
|
||||
material_references.push_back(material_name);
|
||||
}
|
||||
|
||||
DeferredObject defered = (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) ?
|
||||
DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(),
|
||||
mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs(), o->parents()) :
|
||||
DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(),
|
||||
mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs()));
|
||||
deferreds.push_back(defered);
|
||||
DeferredObject deferred(name, representation_id, o->type(), o->transformation(), mesh.verts(), mesh.normals(),
|
||||
mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs());
|
||||
|
||||
if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY)) {
|
||||
deferred.parents() = o->parents();
|
||||
}
|
||||
|
||||
deferreds.push_back(deferred);
|
||||
}
|
||||
|
||||
std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement<real_t>* o) {
|
||||
@@ -589,14 +470,12 @@ void ColladaSerializer::ColladaExporter::endDocument() {
|
||||
}
|
||||
geometries.close();
|
||||
|
||||
int parent_id = -1;
|
||||
bool is_parent_tag_opened = false;
|
||||
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){
|
||||
const std::string object_name = it->unique_id;
|
||||
|
||||
if (use_hierarchy)
|
||||
{
|
||||
unsigned parentsNumber = it->parents.size();
|
||||
unsigned parentsNumber = it->parents_.size();
|
||||
bool finished = false;
|
||||
|
||||
// If we have no parent in the stack and the object has no parent, nothing to do : skip the loop
|
||||
@@ -607,29 +486,23 @@ void ColladaSerializer::ColladaExporter::endDocument() {
|
||||
// If we need to add a parent
|
||||
if (serializer->parentStackId.size() <= parentsNumber)
|
||||
{
|
||||
if (serializer->parentStackId.empty()) { scene.addParent(*(it->parents.at(0))); }
|
||||
if (serializer->parentStackId.empty()) { scene.addParent(*(it->parents_.at(0))); }
|
||||
else
|
||||
{
|
||||
unsigned diff = parentsNumber - serializer->parentStackId.size();
|
||||
|
||||
// If we have the wrong parent in the list
|
||||
if (serializer->parentStackId.top() != it->parents.at(parentsNumber - diff - 1)->id())
|
||||
{
|
||||
if (serializer->parentStackId.top() != it->parents_.at(parentsNumber - diff - 1)->id()) {
|
||||
scene.closeParent();
|
||||
}
|
||||
// So far we have the right parents, we just need to add the missing ones
|
||||
else
|
||||
{
|
||||
for (unsigned i = parentsNumber - diff; i < parentsNumber; i++) { scene.addParent(*(it->parents.at(i))); }
|
||||
} else {
|
||||
// So far we have the right parents, we just need to add the missing ones
|
||||
for (unsigned i = parentsNumber - diff; i < parentsNumber; i++) { scene.addParent(*(it->parents_.at(i))); }
|
||||
|
||||
// if diff == 0, we can leave the loop. In fact we have the right number of parents, and the last one is ok
|
||||
if (diff == 0) { finished = true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
// IF serializer->parentStackId.size() > parentsNumber
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Close the finished nodes. After this we get the first case (serializer->parentStackId.size() <= parentsNumber)
|
||||
while (serializer->parentStackId.size() > parentsNumber) { scene.closeParent(); }
|
||||
}
|
||||
@@ -637,7 +510,7 @@ void ColladaSerializer::ColladaExporter::endDocument() {
|
||||
}
|
||||
|
||||
/// @todo redundant information using ID as both ID and Name, maybe omit Name or allow specifying what would be used as the name
|
||||
scene.add(object_name, object_name, it->representation_id, it->material_references, it->matrix);
|
||||
scene.add(object_name, object_name, it->representation_id, it->material_references, it->transformation);
|
||||
}
|
||||
|
||||
//close the remaining parent tags.
|
||||
|
||||
@@ -86,7 +86,7 @@ private:
|
||||
const std::string scene_id;
|
||||
bool scene_opened;
|
||||
std::stack<COLLADASW::Node*> parentNodes;
|
||||
std::stack<boost::numeric::ublas::matrix<double> > matrixStack;
|
||||
std::stack<IfcGeom::Transformation<double> > matrixStack;
|
||||
public:
|
||||
ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
|
||||
: COLLADASW::LibraryVisualScenes(&stream)
|
||||
@@ -95,7 +95,7 @@ private:
|
||||
, serializer(_serializer)
|
||||
{}
|
||||
void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name,
|
||||
const std::vector<std::string>& material_ids, const std::vector<real_t>& matrix);
|
||||
const std::vector<std::string>& material_ids, const IfcGeom::Transformation<real_t>& matrix);
|
||||
void addParent(const IfcGeom::Element<real_t>& parent);
|
||||
void closeParent();
|
||||
COLLADASW::Node* GetDirectParent();
|
||||
@@ -132,28 +132,29 @@ private:
|
||||
ColladaSerializer *serializer;
|
||||
ColladaEffects effects;
|
||||
};
|
||||
|
||||
class DeferredObject {
|
||||
|
||||
friend bool operator < (const DeferredObject & def_obj1, const DeferredObject & def_obj2)
|
||||
{
|
||||
unsigned size = (def_obj1.parents.size() < def_obj2.parents.size() ? def_obj1.parents.size() : def_obj2.parents.size());
|
||||
int cpt = 0;
|
||||
friend bool operator < (const DeferredObject& def_obj1, const DeferredObject& def_obj2) {
|
||||
size_t size = (def_obj1.parents_.size() < def_obj2.parents_.size() ? def_obj1.parents_.size() : def_obj2.parents_.size());
|
||||
size_t cpt = 0;
|
||||
|
||||
// Skip the shared parents
|
||||
while (cpt < size && *(def_obj1.parents.at(cpt)) == *(def_obj2.parents.at(cpt))) { cpt++; }
|
||||
// Skip the shared parents
|
||||
while (cpt < size && *(def_obj1.parents_.at(cpt)) == *(def_obj2.parents_.at(cpt))) {
|
||||
cpt++;
|
||||
}
|
||||
|
||||
// If a parent list container the other one
|
||||
if (cpt >= size) { return (def_obj1.parents.size() < def_obj2.parents.size() ? true : false); }
|
||||
else
|
||||
{
|
||||
return *(def_obj1.parents.at(cpt)) < *(def_obj2.parents.at(cpt));
|
||||
// If a parent list container the other one
|
||||
if (cpt >= size) {
|
||||
return def_obj1.parents_.size() < def_obj2.parents_.size();
|
||||
} else {
|
||||
return *(def_obj1.parents_.at(cpt)) < *(def_obj2.parents_.at(cpt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
std::string unique_id, representation_id, type;
|
||||
std::vector<real_t> matrix;
|
||||
IfcGeom::Transformation<real_t> transformation;
|
||||
std::vector<real_t> vertices;
|
||||
std::vector<real_t> normals;
|
||||
std::vector<int> faces;
|
||||
@@ -162,36 +163,16 @@ private:
|
||||
std::vector<IfcGeom::Material> materials;
|
||||
std::vector<std::string> material_references;
|
||||
std::vector<real_t> uvs;
|
||||
std::vector<const IfcGeom::Element<real_t>*> parents;
|
||||
DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector<real_t>& matrix,
|
||||
const std::vector<real_t>& vertices, const std::vector<real_t>& 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<real_t>& uvs, const std::vector<const IfcGeom::Element<real_t>*>& parent)
|
||||
: unique_id(unique_id)
|
||||
, representation_id(representation_id)
|
||||
, type(type)
|
||||
, matrix(matrix)
|
||||
, vertices(vertices)
|
||||
, normals(normals)
|
||||
, faces(faces)
|
||||
, edges(edges)
|
||||
, material_ids(material_ids)
|
||||
, materials(materials)
|
||||
, material_references(material_references)
|
||||
, uvs(uvs)
|
||||
, parents(parent)
|
||||
{
|
||||
|
||||
}
|
||||
std::vector<const IfcGeom::Element<real_t>*> parents_;
|
||||
|
||||
DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector<real_t>& matrix,
|
||||
DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const IfcGeom::Transformation<real_t>& transformation,
|
||||
const std::vector<real_t>& vertices, const std::vector<real_t>& 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<real_t>& uvs)
|
||||
: unique_id(unique_id)
|
||||
, representation_id(representation_id)
|
||||
, type(type)
|
||||
, matrix(matrix)
|
||||
, transformation(transformation)
|
||||
, vertices(vertices)
|
||||
, normals(normals)
|
||||
, faces(faces)
|
||||
@@ -200,9 +181,10 @@ private:
|
||||
, materials(materials)
|
||||
, material_references(material_references)
|
||||
, uvs(uvs)
|
||||
{
|
||||
parents.clear();
|
||||
}
|
||||
{}
|
||||
|
||||
std::vector<const IfcGeom::Element<real_t>*>& parents() { return parents_; }
|
||||
const std::vector<const IfcGeom::Element<real_t>*>& parents() const { return parents_; }
|
||||
};
|
||||
COLLADABU::NativeString filename;
|
||||
COLLADASW::StreamWriter stream;
|
||||
|
||||
@@ -51,7 +51,6 @@ public:
|
||||
void writeHeader();
|
||||
void writeMaterial(const IfcGeom::Material& style);
|
||||
void write(const IfcGeom::TriangulationElement<real_t>* o);
|
||||
void write(const IfcGeom::TriangulationElement<real_t>* o, const IfcGeom::Element<real_t>* parent) {}
|
||||
void write(const IfcGeom::BRepElement<real_t>* /*o*/) {}
|
||||
void finalize() {}
|
||||
bool isTesselated() const { return true; }
|
||||
|
||||
@@ -58,15 +58,25 @@ namespace IfcGeom {
|
||||
template <typename P>
|
||||
class Transformation {
|
||||
private:
|
||||
gp_Trsf trsf;
|
||||
Matrix<P> _matrix;
|
||||
ElementSettings settings_;
|
||||
gp_Trsf trsf_;
|
||||
Matrix<P> matrix_;
|
||||
public:
|
||||
Transformation(const ElementSettings& settings, const gp_Trsf& trsf)
|
||||
: trsf(trsf)
|
||||
, _matrix(settings, trsf)
|
||||
: settings_(settings)
|
||||
, trsf_(trsf)
|
||||
, matrix_(settings, trsf)
|
||||
{}
|
||||
const gp_Trsf& data() const { return trsf; }
|
||||
const Matrix<P>& matrix() const { return _matrix; }
|
||||
const gp_Trsf& data() const { return trsf_; }
|
||||
const Matrix<P>& matrix() const { return matrix_; }
|
||||
|
||||
Transformation inverted() const {
|
||||
return Transformation(settings_, trsf_.Inverted());
|
||||
}
|
||||
|
||||
Transformation multiplied(const Transformation& other) const {
|
||||
return Transformation(settings_, trsf_.Multiplied(other.data()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
@@ -126,10 +136,15 @@ namespace IfcGeom {
|
||||
, product_(product)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
try { oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); }
|
||||
catch (std::exception e)
|
||||
{
|
||||
oss << "product-cannotfindId";
|
||||
|
||||
if (type == "IfcProject") {
|
||||
oss << "project";
|
||||
} else {
|
||||
try {
|
||||
oss << "product-" << IfcParse::IfcGlobalId(guid).formatted();
|
||||
} catch (const std::exception&) {
|
||||
oss << "product";
|
||||
}
|
||||
}
|
||||
|
||||
if (!_context.empty()) {
|
||||
@@ -138,6 +153,7 @@ namespace IfcGeom {
|
||||
boost::replace_all(ctx, " ", "-");
|
||||
oss << "-" << ctx;
|
||||
}
|
||||
|
||||
_unique_id = oss.str();
|
||||
}
|
||||
virtual ~Element() {}
|
||||
|
||||
Reference in New Issue
Block a user