mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-10-03 05:22:06 +00:00
Use model-offset in IfcGeom::Kernel and add model-rotation
This commit is contained in:
@@ -311,7 +311,7 @@ int main(int argc, char** argv) {
|
|||||||
"if an object does not have any specified material in the IFC file.")
|
"if an object does not have any specified material in the IFC file.")
|
||||||
("validate", "Checks whether geometrical output conforms to the included explicit quantities.");
|
("validate", "Checks whether geometrical output conforms to the included explicit quantities.");
|
||||||
|
|
||||||
std::string bounds, offset_str;
|
std::string bounds, offset_str, rotation_str;
|
||||||
#ifdef HAVE_ICU
|
#ifdef HAVE_ICU
|
||||||
std::string unicode_mode;
|
std::string unicode_mode;
|
||||||
#endif
|
#endif
|
||||||
@@ -348,7 +348,9 @@ int main(int argc, char** argv) {
|
|||||||
"Centers the elements upon serialization by applying the center point of "
|
"Centers the elements upon serialization by applying the center point of "
|
||||||
"all placements as an offset. Applicable for OBJ and DAE output. Can take several minutes on large models.")
|
"all placements as an offset. Applicable for OBJ and DAE output. Can take several minutes on large models.")
|
||||||
("model-offset", po::value<std::string>(&offset_str),
|
("model-offset", po::value<std::string>(&offset_str),
|
||||||
"Applies an arbitrary offset of form 'x;y;z' to all placements. Applicable for OBJ and DAE output.")
|
"Applies an arbitrary offset of form 'x;y;z' to all placements.")
|
||||||
|
("model-rotation", po::value<std::string>(&rotation_str),
|
||||||
|
"Applies an arbitrary quaternion rotation of form 'x;y;z;w' to all placements.")
|
||||||
("site-local-placement",
|
("site-local-placement",
|
||||||
"Place elements locally in the IfcSite coordinate system, instead of placing "
|
"Place elements locally in the IfcSite coordinate system, instead of placing "
|
||||||
"them in the IFC global coords. Applicable for OBJ and DAE output.")
|
"them in the IFC global coords. Applicable for OBJ and DAE output.")
|
||||||
@@ -417,6 +419,7 @@ int main(int argc, char** argv) {
|
|||||||
const bool no_normals = vmap.count("no-normals") != 0;
|
const bool no_normals = vmap.count("no-normals") != 0;
|
||||||
const bool center_model = vmap.count("center-model") != 0;
|
const bool center_model = vmap.count("center-model") != 0;
|
||||||
const bool model_offset = vmap.count("model-offset") != 0;
|
const bool model_offset = vmap.count("model-offset") != 0;
|
||||||
|
const bool model_rotation = vmap.count("model-rotation") != 0;
|
||||||
const bool site_local_placement = vmap.count("site-local-placement") != 0;
|
const bool site_local_placement = vmap.count("site-local-placement") != 0;
|
||||||
const bool building_local_placement = vmap.count("building-local-placement") != 0;
|
const bool building_local_placement = vmap.count("building-local-placement") != 0;
|
||||||
const bool generate_uvs = vmap.count("generate-uvs") != 0;
|
const bool generate_uvs = vmap.count("generate-uvs") != 0;
|
||||||
@@ -758,6 +761,52 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
Logger::SetOutput(quiet ? nullptr : &cout_, &log_stream);
|
Logger::SetOutput(quiet ? nullptr : &cout_, &log_stream);
|
||||||
|
|
||||||
|
if (model_rotation) {
|
||||||
|
std::array<double, 4> &rotation = settings.rotation;
|
||||||
|
if (sscanf(rotation_str.c_str(), "%lf;%lf;%lf;%lf", &rotation[0], &rotation[1], &rotation[2], &rotation[3]) != 4) {
|
||||||
|
cerr_ << "[Error] Invalid use of --model-rotation\n";
|
||||||
|
IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
|
||||||
|
print_options(serializer_options);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream msg;
|
||||||
|
msg << "Using model rotation (" << rotation[0] << "," << rotation[1] << "," << rotation[2] << "," << rotation[3] << ")";
|
||||||
|
Logger::Notice(msg.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_tesselated && (center_model || model_offset)) {
|
||||||
|
std::array<double, 3> &offset = settings.offset;
|
||||||
|
if (center_model) {
|
||||||
|
if (site_local_placement || building_local_placement) {
|
||||||
|
Logger::Error("Cannot use --center-model together with --{site,building}-local-placement");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcGeom::Iterator<real_t> tmp_context_iterator(settings, ifc_file, filter_funcs, num_threads);
|
||||||
|
|
||||||
|
if (!quiet) Logger::Status("Computing bounds...");
|
||||||
|
tmp_context_iterator.compute_bounds();
|
||||||
|
if (!quiet) Logger::Status("Done!");
|
||||||
|
|
||||||
|
gp_XYZ center = (tmp_context_iterator.bounds_min() + tmp_context_iterator.bounds_max()) * 0.5;
|
||||||
|
offset[0] = -center.X();
|
||||||
|
offset[1] = -center.Y();
|
||||||
|
offset[2] = -center.Z();
|
||||||
|
} else {
|
||||||
|
if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) {
|
||||||
|
cerr_ << "[Error] Invalid use of --model-offset\n";
|
||||||
|
IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
|
||||||
|
print_options(serializer_options);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream msg;
|
||||||
|
msg << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
|
||||||
|
Logger::Notice(msg.str());
|
||||||
|
}
|
||||||
|
|
||||||
IfcGeom::Iterator<real_t> context_iterator(settings, ifc_file, filter_funcs, num_threads);
|
IfcGeom::Iterator<real_t> context_iterator(settings, ifc_file, filter_funcs, num_threads);
|
||||||
if (!context_iterator.initialize()) {
|
if (!context_iterator.initialize()) {
|
||||||
/// @todo It would be nice to know and print separate error prints for a case where we found no entities
|
/// @todo It would be nice to know and print separate error prints for a case where we found no entities
|
||||||
@@ -781,36 +830,6 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
int old_progress = quiet ? 0 : -1;
|
int old_progress = quiet ? 0 : -1;
|
||||||
|
|
||||||
if (is_tesselated && (center_model || model_offset)) {
|
|
||||||
double* offset = serializer->settings().offset;
|
|
||||||
if (center_model) {
|
|
||||||
if (site_local_placement || building_local_placement) {
|
|
||||||
Logger::Error("Cannot use --center-model together with --{site,building}-local-placement");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!quiet) Logger::Status("Computing bounds...");
|
|
||||||
context_iterator.compute_bounds();
|
|
||||||
if (!quiet) Logger::Status("Done!");
|
|
||||||
|
|
||||||
gp_XYZ center = (context_iterator.bounds_min() + context_iterator.bounds_max()) * 0.5;
|
|
||||||
offset[0] = -center.X();
|
|
||||||
offset[1] = -center.Y();
|
|
||||||
offset[2] = -center.Z();
|
|
||||||
} else {
|
|
||||||
if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) {
|
|
||||||
cerr_ << "[Error] Invalid use of --model-offset\n";
|
|
||||||
IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
|
|
||||||
print_options(serializer_options);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream msg;
|
|
||||||
msg << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
|
|
||||||
Logger::Notice(msg.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
if (num_threads == 1) {
|
if (num_threads == 1) {
|
||||||
Logger::Status("Creating geometry...");
|
Logger::Status("Creating geometry...");
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define IFCGEOM_H
|
#define IFCGEOM_H
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
static const double ALMOST_ZERO = 1.e-9;
|
static const double ALMOST_ZERO = 1.e-9;
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ inline static bool ALMOST_THE_SAME(const T& a, const T& b, double tolerance=ALMO
|
|||||||
#include <gp_GTrsf2d.hxx>
|
#include <gp_GTrsf2d.hxx>
|
||||||
#include <gp_Trsf.hxx>
|
#include <gp_Trsf.hxx>
|
||||||
#include <gp_Trsf2d.hxx>
|
#include <gp_Trsf2d.hxx>
|
||||||
|
#include <gp_Quaternion.hxx>
|
||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
#include <TopoDS_Wire.hxx>
|
#include <TopoDS_Wire.hxx>
|
||||||
#include <TopoDS_Face.hxx>
|
#include <TopoDS_Face.hxx>
|
||||||
@@ -222,6 +224,9 @@ private:
|
|||||||
double modelling_precision;
|
double modelling_precision;
|
||||||
double dimensionality;
|
double dimensionality;
|
||||||
double layerset_first;
|
double layerset_first;
|
||||||
|
gp_Vec offset = gp_Vec{0.0, 0.0, 0.0};
|
||||||
|
gp_Quaternion rotation = gp_Quaternion{};
|
||||||
|
gp_Trsf offset_and_rotation = gp_Trsf();
|
||||||
|
|
||||||
#ifndef NO_CACHE
|
#ifndef NO_CACHE
|
||||||
MAKE_TYPE_NAME(Cache) cache;
|
MAKE_TYPE_NAME(Cache) cache;
|
||||||
@@ -264,6 +269,9 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_offset(const std::array<double, 3>& offset);
|
||||||
|
void set_rotation(const std::array<double, 4>& rotation);
|
||||||
|
|
||||||
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
|
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
|
||||||
bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);
|
bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);
|
||||||
bool convert_shapes(const IfcUtil::IfcBaseClass* L, IfcRepresentationShapeItems& result);
|
bool convert_shapes(const IfcUtil::IfcBaseClass* L, IfcRepresentationShapeItems& result);
|
||||||
|
|||||||
@@ -505,6 +505,28 @@ namespace {
|
|||||||
usd.Build();
|
usd.Build();
|
||||||
return usd.Shape();
|
return usd.Shape();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gp_Trsf combine_offset_and_rotation(const gp_Vec &offset, const gp_Quaternion& rotation) {
|
||||||
|
auto offset_transform = gp_Trsf{};
|
||||||
|
offset_transform.SetTranslation(offset);
|
||||||
|
|
||||||
|
auto rotation_transform = gp_Trsf{};
|
||||||
|
rotation_transform.SetRotation(rotation);
|
||||||
|
|
||||||
|
return rotation_transform * offset_transform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IfcGeom::Kernel::set_offset(const std::array<double, 3> &p_offset) {
|
||||||
|
offset = gp_Vec(p_offset[0], p_offset[1], p_offset[2]);
|
||||||
|
|
||||||
|
offset_and_rotation = combine_offset_and_rotation(offset, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IfcGeom::Kernel::set_rotation(const std::array<double, 4> &p_rotation) {
|
||||||
|
rotation = gp_Quaternion(p_rotation[0], p_rotation[1], p_rotation[2], p_rotation[3]);
|
||||||
|
|
||||||
|
offset_and_rotation = combine_offset_and_rotation(offset, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
|
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
|
||||||
|
|||||||
@@ -418,6 +418,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& t
|
|||||||
else break;
|
else break;
|
||||||
} else break;
|
} else break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trsf.PreMultiply(offset_and_rotation);
|
||||||
|
|
||||||
CACHE(IfcObjectPlacement,l,trsf)
|
CACHE(IfcObjectPlacement,l,trsf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -985,6 +985,8 @@ namespace IfcGeom {
|
|||||||
} else if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) {
|
} else if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) {
|
||||||
kernel.set_conversion_placement_rel_to(&IfcSchema::IfcSite::Class());
|
kernel.set_conversion_placement_rel_to(&IfcSchema::IfcSite::Class());
|
||||||
}
|
}
|
||||||
|
kernel.set_offset(settings.offset);
|
||||||
|
kernel.set_rotation(settings.rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#ifndef IFCGEOMITERATORSETTINGS_H
|
#ifndef IFCGEOMITERATORSETTINGS_H
|
||||||
#define IFCGEOMITERATORSETTINGS_H
|
#define IFCGEOMITERATORSETTINGS_H
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "ifc_geom_api.h"
|
#include "ifc_geom_api.h"
|
||||||
#include "../ifcparse/IfcException.h"
|
#include "../ifcparse/IfcException.h"
|
||||||
#include "../ifcparse/IfcBaseClass.h"
|
#include "../ifcparse/IfcBaseClass.h"
|
||||||
@@ -132,6 +134,11 @@ namespace IfcGeom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Optional offset that is applied to serialized objects, (0,0,0) by default.
|
||||||
|
std::array<double,3> offset = std::array<double,3>{0.0, 0.0, 0.0};
|
||||||
|
/// Optional rotation that is applied to serialized objects, (0,0,0,1) by default.
|
||||||
|
std::array<double,4> rotation = std::array<double,4>{0.0, 0.0, 0.0, 1.0};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SettingField settings_;
|
SettingField settings_;
|
||||||
double deflection_tolerance_;
|
double deflection_tolerance_;
|
||||||
|
|||||||
@@ -213,11 +213,6 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
|||||||
{ 0, 0, 0, 1 }
|
{ 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;
|
delete relative_trsf;
|
||||||
|
|
||||||
node.start();
|
node.start();
|
||||||
|
|||||||
@@ -55,13 +55,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
SerializerSettings()
|
SerializerSettings()
|
||||||
: precision(DEFAULT_PRECISION)
|
: precision(DEFAULT_PRECISION) { }
|
||||||
{
|
|
||||||
memset(offset, 0, sizeof(offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Optional offset that is applied to serialized objects, (0,0,0) by default.
|
|
||||||
double offset[3];
|
|
||||||
|
|
||||||
/// Sets the precision used to format floating-point values, 15 by default.
|
/// Sets the precision used to format floating-point values, 15 by default.
|
||||||
/// Use a negative value to use the system's default precision (should be 6 typically).
|
/// Use a negative value to use the system's default precision (should be 6 typically).
|
||||||
|
|||||||
@@ -93,9 +93,9 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement<real_t>*
|
|||||||
|
|
||||||
const int vcount = (int)mesh.verts().size() / 3;
|
const int vcount = (int)mesh.verts().size() / 3;
|
||||||
for ( std::vector<real_t>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) {
|
for ( std::vector<real_t>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) {
|
||||||
const real_t x = *(it++) + (real_t)settings().offset[0];
|
const real_t x = *(it++);
|
||||||
const real_t y = *(it++) + (real_t)settings().offset[1];
|
const real_t y = *(it++);
|
||||||
const real_t z = *(it++) + (real_t)settings().offset[2];
|
const real_t z = *(it++);
|
||||||
obj_stream << "v " << x << " " << y << " " << z << "\n";
|
obj_stream << "v " << x << " " << y << " " << z << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user