mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-28 19:27:10 +00:00
Matrix multiplication in OCC rather than boost::ublas (re #211)
This commit is contained in:
@@ -32,14 +32,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <cmath>
|
#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 IfcSchema;
|
||||||
using namespace boost::numeric::ublas;
|
using namespace boost::numeric::ublas;
|
||||||
|
|
||||||
@@ -69,7 +61,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(
|
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<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<int> material_ids, const std::vector<IfcGeom::Material>& materials,
|
||||||
const std::vector<real_t>& uvs)
|
const std::vector<real_t>& uvs)
|
||||||
@@ -188,7 +180,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::close() {
|
|||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
||||||
const std::string& node_id, const std::string& node_name, const std::string& geom_name,
|
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) {
|
if (!scene_opened) {
|
||||||
openVisualScene(scene_id);
|
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.
|
// 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.
|
// Note that this placement is absolute, ie it is multiplied with all parent placements.
|
||||||
|
|
||||||
double matrix_array[4][4] = {
|
IfcGeom::Transformation<real_t>* relative_trsf = 0;
|
||||||
{ (double)posmatrix[0], (double)posmatrix[3], (double)posmatrix[6], (double)posmatrix[ 9] },
|
const IfcGeom::Transformation<real_t>* transformation_towrite = &transformation;
|
||||||
{ (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 }
|
|
||||||
};
|
|
||||||
|
|
||||||
// If this is not the first parent, get the relative placement
|
// If this is not the first parent, get the relative placement
|
||||||
if (parentNodes.size() > 0)
|
if (parentNodes.size() > 0)
|
||||||
{
|
{
|
||||||
double relative[4][4] = {
|
relative_trsf = new IfcGeom::Transformation<real_t>(matrixStack.top().multiplied(transformation));
|
||||||
{ 0, 0, 0, 0 },
|
transformation_towrite = relative_trsf;
|
||||||
{ 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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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[0][3] += serializer->settings().offset[0];
|
||||||
matrix_array[1][3] += serializer->settings().offset[1];
|
matrix_array[1][3] += serializer->settings().offset[1];
|
||||||
matrix_array[2][3] += serializer->settings().offset[2];
|
matrix_array[2][3] += serializer->settings().offset[2];
|
||||||
|
|
||||||
|
delete relative_trsf;
|
||||||
|
|
||||||
node.start();
|
node.start();
|
||||||
node.addMatrix(matrix_array);
|
node.addMatrix(matrix_array);
|
||||||
COLLADASW::InstanceGeometry instanceGeometry(mSW);
|
COLLADASW::InstanceGeometry instanceGeometry(mSW);
|
||||||
@@ -263,63 +242,36 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::
|
|||||||
scene_opened = true;
|
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 matrix_array[4][4] = {
|
||||||
{ (double)parentMatrix[0], (double)parentMatrix[3], (double)parentMatrix[6], (double)parentMatrix[9] },
|
{ (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[1], (double)parentMatrix[4], (double)parentMatrix[7], (double)parentMatrix[10] },
|
||||||
{ (double)parentMatrix[2], (double)parentMatrix[5], (double)parentMatrix[8], (double)parentMatrix[11] },
|
{ (double)parentMatrix[2], (double)parentMatrix[5], (double)parentMatrix[8], (double)parentMatrix[11] },
|
||||||
{ 0, 0, 0, 1 }
|
{ 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
|
// Chose a name of the parent object
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
if (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES)) { name = parent.type() + " " + parent.name(); }
|
if (serializer->settings().get(SerializerSettings::USE_ELEMENT_TYPES)) {
|
||||||
else
|
name = parent.type() + " " + parent.name();
|
||||||
{
|
} else {
|
||||||
if (parent.name() == "") { name = "unnamed"; }
|
name = parent.unique_id();
|
||||||
else { name = parent.name(); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& id = name;
|
||||||
|
|
||||||
COLLADASW::Node *current_node;
|
COLLADASW::Node *current_node;
|
||||||
current_node = new COLLADASW::Node(mSW);
|
current_node = new COLLADASW::Node(mSW);
|
||||||
@@ -329,83 +281,10 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::
|
|||||||
current_node->start();
|
current_node->start();
|
||||||
current_node->addMatrix(matrix_array);
|
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
|
// Add the node to the parent stack
|
||||||
|
matrixStack.push(parent_trsf.inverted());
|
||||||
parentNodes.push(current_node);
|
parentNodes.push(current_node);
|
||||||
serializer->parentStackId.push(parent.id());
|
serializer->parentStackId.push(parent.id());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaScene::closeParent()
|
void ColladaSerializer::ColladaExporter::ColladaScene::closeParent()
|
||||||
@@ -532,12 +411,14 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
|
|||||||
material_references.push_back(material_name);
|
material_references.push_back(material_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeferredObject defered = (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY) ?
|
DeferredObject deferred(name, representation_id, o->type(), o->transformation(), mesh.verts(), mesh.normals(),
|
||||||
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());
|
||||||
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(),
|
if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY)) {
|
||||||
mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs()));
|
deferred.parents() = o->parents();
|
||||||
deferreds.push_back(defered);
|
}
|
||||||
|
|
||||||
|
deferreds.push_back(deferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement<real_t>* o) {
|
std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement<real_t>* o) {
|
||||||
@@ -589,14 +470,12 @@ void ColladaSerializer::ColladaExporter::endDocument() {
|
|||||||
}
|
}
|
||||||
geometries.close();
|
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){
|
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){
|
||||||
const std::string object_name = it->unique_id;
|
const std::string object_name = it->unique_id;
|
||||||
|
|
||||||
if (use_hierarchy)
|
if (use_hierarchy)
|
||||||
{
|
{
|
||||||
unsigned parentsNumber = it->parents.size();
|
unsigned parentsNumber = it->parents_.size();
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
|
|
||||||
// If we have no parent in the stack and the object has no parent, nothing to do : skip the loop
|
// 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 we need to add a parent
|
||||||
if (serializer->parentStackId.size() <= parentsNumber)
|
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
|
else
|
||||||
{
|
{
|
||||||
unsigned diff = parentsNumber - serializer->parentStackId.size();
|
unsigned diff = parentsNumber - serializer->parentStackId.size();
|
||||||
|
|
||||||
// If we have the wrong parent in the list
|
// 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();
|
scene.closeParent();
|
||||||
}
|
} else {
|
||||||
// So far we have the right parents, we just need to add the missing ones
|
// 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))); }
|
||||||
{
|
|
||||||
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, 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 (diff == 0) { finished = true; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
// IF serializer->parentStackId.size() > parentsNumber
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Close the finished nodes. After this we get the first case (serializer->parentStackId.size() <= parentsNumber)
|
// Close the finished nodes. After this we get the first case (serializer->parentStackId.size() <= parentsNumber)
|
||||||
while (serializer->parentStackId.size() > parentsNumber) { scene.closeParent(); }
|
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
|
/// @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.
|
//close the remaining parent tags.
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ private:
|
|||||||
const std::string scene_id;
|
const std::string scene_id;
|
||||||
bool scene_opened;
|
bool scene_opened;
|
||||||
std::stack<COLLADASW::Node*> parentNodes;
|
std::stack<COLLADASW::Node*> parentNodes;
|
||||||
std::stack<boost::numeric::ublas::matrix<double> > matrixStack;
|
std::stack<IfcGeom::Transformation<double> > matrixStack;
|
||||||
public:
|
public:
|
||||||
ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
|
ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
|
||||||
: COLLADASW::LibraryVisualScenes(&stream)
|
: COLLADASW::LibraryVisualScenes(&stream)
|
||||||
@@ -95,7 +95,7 @@ private:
|
|||||||
, serializer(_serializer)
|
, serializer(_serializer)
|
||||||
{}
|
{}
|
||||||
void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name,
|
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 addParent(const IfcGeom::Element<real_t>& parent);
|
||||||
void closeParent();
|
void closeParent();
|
||||||
COLLADASW::Node* GetDirectParent();
|
COLLADASW::Node* GetDirectParent();
|
||||||
@@ -132,28 +132,29 @@ private:
|
|||||||
ColladaSerializer *serializer;
|
ColladaSerializer *serializer;
|
||||||
ColladaEffects effects;
|
ColladaEffects effects;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeferredObject {
|
class DeferredObject {
|
||||||
|
|
||||||
friend bool operator < (const DeferredObject & def_obj1, const DeferredObject & def_obj2)
|
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());
|
||||||
unsigned size = (def_obj1.parents.size() < def_obj2.parents.size() ? def_obj1.parents.size() : def_obj2.parents.size());
|
size_t cpt = 0;
|
||||||
int cpt = 0;
|
|
||||||
|
|
||||||
// Skip the shared parents
|
// Skip the shared parents
|
||||||
while (cpt < size && *(def_obj1.parents.at(cpt)) == *(def_obj2.parents.at(cpt))) { cpt++; }
|
while (cpt < size && *(def_obj1.parents_.at(cpt)) == *(def_obj2.parents_.at(cpt))) {
|
||||||
|
cpt++;
|
||||||
|
}
|
||||||
|
|
||||||
// If a parent list container the other one
|
// If a parent list container the other one
|
||||||
if (cpt >= size) { return (def_obj1.parents.size() < def_obj2.parents.size() ? true : false); }
|
if (cpt >= size) {
|
||||||
else
|
return def_obj1.parents_.size() < def_obj2.parents_.size();
|
||||||
{
|
} else {
|
||||||
return *(def_obj1.parents.at(cpt)) < *(def_obj2.parents.at(cpt));
|
return *(def_obj1.parents_.at(cpt)) < *(def_obj2.parents_.at(cpt));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string unique_id, representation_id, type;
|
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> vertices;
|
||||||
std::vector<real_t> normals;
|
std::vector<real_t> normals;
|
||||||
std::vector<int> faces;
|
std::vector<int> faces;
|
||||||
@@ -162,36 +163,16 @@ private:
|
|||||||
std::vector<IfcGeom::Material> materials;
|
std::vector<IfcGeom::Material> materials;
|
||||||
std::vector<std::string> material_references;
|
std::vector<std::string> material_references;
|
||||||
std::vector<real_t> uvs;
|
std::vector<real_t> uvs;
|
||||||
std::vector<const IfcGeom::Element<real_t>*> parents;
|
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)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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<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<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<std::string>& material_references, const std::vector<real_t>& uvs)
|
||||||
: unique_id(unique_id)
|
: unique_id(unique_id)
|
||||||
, representation_id(representation_id)
|
, representation_id(representation_id)
|
||||||
, type(type)
|
, type(type)
|
||||||
, matrix(matrix)
|
, transformation(transformation)
|
||||||
, vertices(vertices)
|
, vertices(vertices)
|
||||||
, normals(normals)
|
, normals(normals)
|
||||||
, faces(faces)
|
, faces(faces)
|
||||||
@@ -200,9 +181,10 @@ private:
|
|||||||
, materials(materials)
|
, materials(materials)
|
||||||
, material_references(material_references)
|
, material_references(material_references)
|
||||||
, uvs(uvs)
|
, 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;
|
COLLADABU::NativeString filename;
|
||||||
COLLADASW::StreamWriter stream;
|
COLLADASW::StreamWriter stream;
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ public:
|
|||||||
void writeHeader();
|
void writeHeader();
|
||||||
void writeMaterial(const IfcGeom::Material& style);
|
void writeMaterial(const IfcGeom::Material& style);
|
||||||
void write(const IfcGeom::TriangulationElement<real_t>* o);
|
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 write(const IfcGeom::BRepElement<real_t>* /*o*/) {}
|
||||||
void finalize() {}
|
void finalize() {}
|
||||||
bool isTesselated() const { return true; }
|
bool isTesselated() const { return true; }
|
||||||
|
|||||||
@@ -58,15 +58,25 @@ namespace IfcGeom {
|
|||||||
template <typename P>
|
template <typename P>
|
||||||
class Transformation {
|
class Transformation {
|
||||||
private:
|
private:
|
||||||
gp_Trsf trsf;
|
ElementSettings settings_;
|
||||||
Matrix<P> _matrix;
|
gp_Trsf trsf_;
|
||||||
|
Matrix<P> matrix_;
|
||||||
public:
|
public:
|
||||||
Transformation(const ElementSettings& settings, const gp_Trsf& trsf)
|
Transformation(const ElementSettings& settings, const gp_Trsf& trsf)
|
||||||
: trsf(trsf)
|
: settings_(settings)
|
||||||
, _matrix(settings, trsf)
|
, trsf_(trsf)
|
||||||
|
, matrix_(settings, trsf)
|
||||||
{}
|
{}
|
||||||
const gp_Trsf& data() const { return trsf; }
|
const gp_Trsf& data() const { return trsf_; }
|
||||||
const Matrix<P>& matrix() const { return _matrix; }
|
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>
|
template <typename P>
|
||||||
@@ -126,10 +136,15 @@ namespace IfcGeom {
|
|||||||
, product_(product)
|
, product_(product)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
try { oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); }
|
|
||||||
catch (std::exception e)
|
if (type == "IfcProject") {
|
||||||
{
|
oss << "project";
|
||||||
oss << "product-cannotfindId";
|
} else {
|
||||||
|
try {
|
||||||
|
oss << "product-" << IfcParse::IfcGlobalId(guid).formatted();
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
oss << "product";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_context.empty()) {
|
if (!_context.empty()) {
|
||||||
@@ -138,6 +153,7 @@ namespace IfcGeom {
|
|||||||
boost::replace_all(ctx, " ", "-");
|
boost::replace_all(ctx, " ", "-");
|
||||||
oss << "-" << ctx;
|
oss << "-" << ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
_unique_id = oss.str();
|
_unique_id = oss.str();
|
||||||
}
|
}
|
||||||
virtual ~Element() {}
|
virtual ~Element() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user