mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 21:42:19 +00:00
Calculate and store min. and max. placements IfcGeom::Iterator. Implement --center-model for OBJ.
This commit is contained in:
@@ -47,10 +47,6 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define INF std::numeric_limits<real_t>::infinity()
|
|
||||||
real_t bounds_min[3] = { INF, INF, INF };
|
|
||||||
real_t bounds_max[3] = { -INF, -INF, -INF };
|
|
||||||
|
|
||||||
#if USE_VLD
|
#if USE_VLD
|
||||||
#include <vld.h>
|
#include <vld.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -198,8 +194,8 @@ int main(int argc, char** argv) {
|
|||||||
"Use material names instead of unique IDs for naming materials upon serialization. "
|
"Use material names instead of unique IDs for naming materials upon serialization. "
|
||||||
"Applicable for OBJ and DAE output.")
|
"Applicable for OBJ and DAE output.")
|
||||||
("center-model",
|
("center-model",
|
||||||
"Centers the models upon serialization by applying the center point of "
|
"Centers the elements upon serialization by applying the center point of "
|
||||||
"the scene bounds as an offset. Applicable only for DAE output currently.");
|
"all placements as an offset. Applicable for OBJ and DAE output.");
|
||||||
|
|
||||||
boost::program_options::options_description cmdline_options;
|
boost::program_options::options_description cmdline_options;
|
||||||
cmdline_options.add(generic_options).add(fileio_options).add(geom_options).add(serializer_options);
|
cmdline_options.add(generic_options).add(fileio_options).add(geom_options).add(serializer_options);
|
||||||
@@ -375,21 +371,18 @@ int main(int argc, char** argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_extension != ".dae") {
|
const bool is_tesselated = serializer->isTesselated(); // isTesselated() doesn't change at run-time
|
||||||
if (center_model) {
|
if (!is_tesselated) {
|
||||||
Logger::Message(Logger::LOG_NOTICE, "--center-model setting ignored for non-DAE output");
|
|
||||||
settings.set(IfcGeom::IteratorSettings::CENTER_MODEL, false);
|
|
||||||
center_model = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!serializer->isTesselated()) {
|
|
||||||
if (weld_vertices) {
|
if (weld_vertices) {
|
||||||
Logger::Message(Logger::LOG_NOTICE, "Weld vertices setting ignored when writing non-tesselated output");
|
Logger::Message(Logger::LOG_NOTICE, "Weld vertices setting ignored when writing non-tesselated output");
|
||||||
}
|
}
|
||||||
if (generate_uvs) {
|
if (generate_uvs) {
|
||||||
Logger::Message(Logger::LOG_NOTICE, "Generate UVs setting ignored when writing non-tesselated output");
|
Logger::Message(Logger::LOG_NOTICE, "Generate UVs setting ignored when writing non-tesselated output");
|
||||||
}
|
}
|
||||||
|
if (center_model) {
|
||||||
|
Logger::Message(Logger::LOG_NOTICE, "Center model setting ignored when writing non-tesselated output");
|
||||||
|
}
|
||||||
|
|
||||||
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
|
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,42 +446,31 @@ int main(int argc, char** argv) {
|
|||||||
const int progress = context_iterator.progress() / 2;
|
const int progress = context_iterator.progress() / 2;
|
||||||
if (old_progress != progress) Logger::ProgressBar(progress);
|
if (old_progress != progress) Logger::ProgressBar(progress);
|
||||||
old_progress = progress;
|
old_progress = progress;
|
||||||
|
|
||||||
if (center_model) {
|
|
||||||
const std::vector<real_t>& pos = geom_object->transformation().matrix().data();
|
|
||||||
bounds_min[0] = std::min(bounds_min[0], pos[9]);
|
|
||||||
bounds_min[1] = std::min(bounds_min[1], pos[10]);
|
|
||||||
bounds_min[2] = std::min(bounds_min[2], pos[11]);
|
|
||||||
bounds_max[0] = std::max(bounds_max[0], pos[9]);
|
|
||||||
bounds_max[1] = std::max(bounds_max[1], pos[10]);
|
|
||||||
bounds_max[2] = std::max(bounds_max[2], pos[11]);
|
|
||||||
}
|
|
||||||
} while (context_iterator.next());
|
} while (context_iterator.next());
|
||||||
|
|
||||||
Logger::Status("\rDone creating geometry (" + boost::lexical_cast<std::string>(geometries.size()) +
|
Logger::Status("\rDone creating geometry (" + boost::lexical_cast<std::string>(geometries.size()) +
|
||||||
" objects) ");
|
" objects) ");
|
||||||
|
|
||||||
if (center_model) {
|
if (center_model) {
|
||||||
settings.offset[0] = -(bounds_min[0] + bounds_max[0]) * real_t(0.5);
|
double* offset = serializer->settings().offset;
|
||||||
settings.offset[1] = -(bounds_min[1] + bounds_max[1]) * real_t(0.5);
|
gp_XYZ center = (context_iterator.bounds_min() + context_iterator.bounds_max()) * 0.5;
|
||||||
settings.offset[2] = -(bounds_min[2] + bounds_max[2]) * real_t(0.5);
|
offset[0] = -center.X();
|
||||||
//printf("Bounds min. (%g, %g, %g)\n", bounds_min[0], bounds_min[1], bounds_min[2]);
|
offset[1] = -center.Y();
|
||||||
//printf("Bounds max. (%g, %g, %g)\n", bounds_max[0], bounds_max[1], bounds_max[2]);
|
offset[2] = -center.Z();
|
||||||
printf("Using model offset (%g, %g, %g)\n", settings.offset[0], settings.offset[1], settings.offset[2]); //TODO Logger::Message(Logger::LOG_NOTICE, ...);
|
//printf("Bounds min. (%g, %g, %g)\n", context_iterator.bounds_min().X(), context_iterator.bounds_min().Y(), context_iterator.bounds_min().Z());
|
||||||
|
//printf("Bounds max. (%g, %g, %g)\n", context_iterator.bounds_min().X(), context_iterator.bounds_min().X(), context_iterator.bounds_min().Z());
|
||||||
|
printf("Using model offset (%g, %g, %g)\n", offset[0], offset[1], offset[2]); //TODO Logger::Message(Logger::LOG_NOTICE, ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Status("Serializing geometry...");
|
Logger::Status("Serializing geometry...");
|
||||||
|
|
||||||
if (serializer->isTesselated()) { // isTesselated() doesn't change at run-time
|
foreach(const IfcGeom::Element<real_t>* geom, geometries) {
|
||||||
foreach(const IfcGeom::Element<real_t>* geom, geometries) {
|
if (is_tesselated) {
|
||||||
serializer->write(static_cast<const IfcGeom::TriangulationElement<real_t>*>(geom));
|
serializer->write(static_cast<const IfcGeom::TriangulationElement<real_t>*>(geom));
|
||||||
delete geom;
|
} else {
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach(const IfcGeom::Element<real_t>* geom, geometries) {
|
|
||||||
serializer->write(static_cast<const IfcGeom::BRepElement<real_t>*>(geom));
|
serializer->write(static_cast<const IfcGeom::BRepElement<real_t>*>(geom));
|
||||||
delete geom;
|
|
||||||
}
|
}
|
||||||
|
delete geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
serializer->finalize();
|
serializer->finalize();
|
||||||
|
|||||||
@@ -84,9 +84,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++);
|
const real_t x = *(it++) + (real_t)settings().offset[0];
|
||||||
const real_t y = *(it++);
|
const real_t y = *(it++) + (real_t)settings().offset[1];
|
||||||
const real_t z = *(it++);
|
const real_t z = *(it++) + (real_t)settings().offset[2];
|
||||||
obj_stream << "v " << x << " " << y << " " << z << "\n";
|
obj_stream << "v " << x << " " << y << " " << z << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "../ifcconvert/GeometrySerializer.h"
|
#include "../ifcconvert/GeometrySerializer.h"
|
||||||
|
|
||||||
|
// http://people.sc.fsu.edu/~jburkardt/txt/obj_format.txt
|
||||||
class WaveFrontOBJSerializer : public GeometrySerializer {
|
class WaveFrontOBJSerializer : public GeometrySerializer {
|
||||||
private:
|
private:
|
||||||
const std::string mtl_filename;
|
const std::string mtl_filename;
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ namespace IfcGeom {
|
|||||||
std::string unit_name;
|
std::string unit_name;
|
||||||
// double?
|
// double?
|
||||||
P unit_magnitude;
|
P unit_magnitude;
|
||||||
|
gp_XYZ bounds_min_;
|
||||||
|
gp_XYZ bounds_max_;
|
||||||
|
|
||||||
void initUnits() {
|
void initUnits() {
|
||||||
IfcSchema::IfcProject::list::ptr projects = ifc_file->entitiesByType<IfcSchema::IfcProject>();
|
IfcSchema::IfcProject::list::ptr projects = ifc_file->entitiesByType<IfcSchema::IfcProject>();
|
||||||
@@ -251,6 +253,28 @@ namespace IfcGeom {
|
|||||||
done = 0;
|
done = 0;
|
||||||
total = representations->size();
|
total = representations->size();
|
||||||
|
|
||||||
|
for (int i = 1; i < 4; ++i) {
|
||||||
|
bounds_min_.SetCoord(i, std::numeric_limits<double>::infinity());
|
||||||
|
bounds_max_.SetCoord(i, -std::numeric_limits<double>::infinity());
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcSchema::IfcProduct::list::ptr products = ifc_file->entitiesByType<IfcSchema::IfcProduct>();
|
||||||
|
for (IfcSchema::IfcProduct::list::it iter = products->begin(); iter != products->end(); ++iter) {
|
||||||
|
IfcSchema::IfcProduct* product = *iter;
|
||||||
|
if (product->hasObjectPlacement()) {
|
||||||
|
gp_Trsf trsf; // Use a fresh trsf every time in order to prevent the result to be concatenated
|
||||||
|
if (kernel.convert(product->ObjectPlacement(), trsf)) {
|
||||||
|
const gp_XYZ& pos = trsf.TranslationPart();
|
||||||
|
bounds_min_.SetX(std::min(bounds_min_.X(), pos.X()));
|
||||||
|
bounds_min_.SetY(std::min(bounds_min_.Y(), pos.Y()));
|
||||||
|
bounds_min_.SetZ(std::min(bounds_min_.Z(), pos.Z()));
|
||||||
|
bounds_max_.SetX(std::max(bounds_max_.X(), pos.X()));
|
||||||
|
bounds_max_.SetY(std::max(bounds_max_.Y(), pos.Y()));
|
||||||
|
bounds_max_.SetZ(std::max(bounds_max_.Z(), pos.Z()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,6 +318,9 @@ namespace IfcGeom {
|
|||||||
include_entities_in_processing = false;
|
include_entities_in_processing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const gp_XYZ& bounds_min() const { return bounds_min_; }
|
||||||
|
const gp_XYZ& bounds_max() const { return bounds_max_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Move to the next IfcRepresentation
|
// Move to the next IfcRepresentation
|
||||||
void _nextShape() {
|
void _nextShape() {
|
||||||
@@ -484,7 +511,8 @@ namespace IfcGeom {
|
|||||||
unit_magnitude = 1.f;
|
unit_magnitude = 1.f;
|
||||||
|
|
||||||
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1);
|
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1);
|
||||||
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES) ? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.));
|
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES)
|
||||||
|
? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool owns_ifc_file;
|
bool owns_ifc_file;
|
||||||
|
|||||||
Reference in New Issue
Block a user