mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-05 20:06:25 +00:00
Write voxelization logic in geom server
This commit is contained in:
@@ -165,7 +165,7 @@ ELSE()
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
set(BOOST_COMPONENTS system program_options regex thread date_time)
|
set(BOOST_COMPONENTS system program_options regex thread date_time)
|
||||||
if(USE_MMAP)
|
if(USE_MMAP OR USE_VOXELS)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# filesystem is necessary for the utf-16 wpath
|
# filesystem is necessary for the utf-16 wpath
|
||||||
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} iostreams filesystem)
|
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} iostreams filesystem)
|
||||||
@@ -183,6 +183,7 @@ if (USE_VOXELS)
|
|||||||
FIND_LIBRARY(libvoxel NAMES voxel libvoxel PATHS ${VOXEL_LIBRARY_DIR} NO_DEFAULT_PATH)
|
FIND_LIBRARY(libvoxel NAMES voxel libvoxel PATHS ${VOXEL_LIBRARY_DIR} NO_DEFAULT_PATH)
|
||||||
FIND_LIBRARY(libvoxec NAMES voxec libvoxec PATHS ${VOXEL_LIBRARY_DIR} NO_DEFAULT_PATH)
|
FIND_LIBRARY(libvoxec NAMES voxec libvoxec PATHS ${VOXEL_LIBRARY_DIR} NO_DEFAULT_PATH)
|
||||||
set(VOXEL_LIBRARIES ${libvoxel} ${libvoxec})
|
set(VOXEL_LIBRARIES ${libvoxel} ${libvoxec})
|
||||||
|
ADD_DEFINITIONS("-DUSE_VOXELS")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
FIND_PACKAGE(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
FIND_PACKAGE(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||||
|
|||||||
@@ -59,6 +59,12 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#ifdef USE_VOXELS
|
||||||
|
#include <voxel/storage.h>
|
||||||
|
#include <voxel/traversal.h>
|
||||||
|
#include <voxel/processor.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
union data_field {
|
union data_field {
|
||||||
char buffer[sizeof(T)];
|
char buffer[sizeof(T)];
|
||||||
@@ -470,9 +476,9 @@ public:
|
|||||||
put_json(TOTAL_SURFACE_AREA, a);
|
put_json(TOTAL_SURFACE_AREA, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elem_->geometry().calculate_volume(a)) {
|
TopoDS_Compound compound = TopoDS::Compound(((IfcGeom::OpenCascadeShape*) elem_->geometry().as_compound(true))->shape());
|
||||||
put_json(TOTAL_SHAPE_VOLUME, a);
|
double bbox_xyz[6];
|
||||||
}
|
bool has_boundingbox = false;
|
||||||
|
|
||||||
if (elem_->calculate_projected_surface_area(a, b, c)) {
|
if (elem_->calculate_projected_surface_area(a, b, c)) {
|
||||||
put_json(SURFACE_AREA_ALONG_X, a);
|
put_json(SURFACE_AREA_ALONG_X, a);
|
||||||
@@ -483,7 +489,6 @@ public:
|
|||||||
boost::optional<gp_Dir> largest_face_dir;
|
boost::optional<gp_Dir> largest_face_dir;
|
||||||
|
|
||||||
{
|
{
|
||||||
TopoDS_Compound compound = TopoDS::Compound(((IfcGeom::OpenCascadeShape*) elem_->geometry().as_compound(true))->shape());
|
|
||||||
TopExp_Explorer exp(compound, TopAbs_FACE);
|
TopExp_Explorer exp(compound, TopAbs_FACE);
|
||||||
for (; exp.More(); exp.Next()) {
|
for (; exp.More(); exp.Next()) {
|
||||||
GProp_GProps prop;
|
GProp_GProps prop;
|
||||||
@@ -503,19 +508,48 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bnd_Box box;
|
Bnd_Box box;
|
||||||
double xyz[6];
|
|
||||||
|
|
||||||
BRepBndLib::AddClose(compound, box);
|
BRepBndLib::AddClose(compound, box);
|
||||||
|
|
||||||
if (!box.IsVoid()) {
|
if (!box.IsVoid()) {
|
||||||
box.Get(xyz[0], xyz[1], xyz[2], xyz[3], xyz[4], xyz[5]);
|
has_boundingbox = true;
|
||||||
|
box.Get(bbox_xyz[0], bbox_xyz[1], bbox_xyz[2], bbox_xyz[3], bbox_xyz[4], bbox_xyz[5]);
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
const double bsz = xyz[i + 3] - xyz[i];
|
const double bsz = bbox_xyz[i + 3] - bbox_xyz[i];
|
||||||
put_json(BOUNDING_BOX_SIZE_ALONG_ + XYZ[i], bsz);
|
put_json(BOUNDING_BOX_SIZE_ALONG_ + XYZ[i], bsz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (elem_->geometry().calculate_volume(a)) {
|
||||||
|
put_json(TOTAL_SHAPE_VOLUME, a);
|
||||||
|
}
|
||||||
|
#ifdef USE_VOXELS
|
||||||
|
// Sometimes geometries are not a topologically valid manifold,
|
||||||
|
// but still (approximately) enclose a volume. In this case
|
||||||
|
// we can voxlize the geometry and fill the interior solid volume.
|
||||||
|
else if (has_boundingbox) {
|
||||||
|
std::array< vec_n<3, double>, 2 > bounds;
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
bounds[0].get(i) = bbox_xyz[i + 0];
|
||||||
|
bounds[1].get(i) = bbox_xyz[i + 3];
|
||||||
|
}
|
||||||
|
progress_writer silent;
|
||||||
|
auto surface = storage_for(bounds);
|
||||||
|
threaded_processor proc(surface, silent);
|
||||||
|
surface = (regular_voxel_storage*) proc.voxels();
|
||||||
|
double vsize = surface->voxel_size();
|
||||||
|
delete surface;
|
||||||
|
auto surface_count = surface->count();
|
||||||
|
traversal_voxel_filler_inverse filler;
|
||||||
|
auto volume = filler(surface);
|
||||||
|
auto volume_count = volume->count();
|
||||||
|
delete volume;
|
||||||
|
double total_volume = (volume_count + surface_count / 2) * (vsize * vsize * vsize);
|
||||||
|
put_json(TOTAL_SHAPE_VOLUME, total_volume);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (largest_face_dir) {
|
if (largest_face_dir) {
|
||||||
put_json(LARGEST_FACE_DIRECTION, *largest_face_dir);
|
put_json(LARGEST_FACE_DIRECTION, *largest_face_dir);
|
||||||
put_json(LARGEST_FACE_AREA, largest_face_area);
|
put_json(LARGEST_FACE_AREA, largest_face_area);
|
||||||
|
|||||||
Reference in New Issue
Block a user