mirror of https://github.com/wpkong/Octree.git
9 changed files with 265 additions and 1 deletions
@ -0,0 +1 @@ |
|||
test-path.h |
@ -0,0 +1,6 @@ |
|||
configure_file( |
|||
"${CMAKE_CURRENT_SOURCE_DIR}/test-path.h.in" |
|||
"${CMAKE_CURRENT_SOURCE_DIR}/test-path.h" |
|||
) |
|||
add_executable(search_assign_test main.cpp search_assign.cpp search_assign.h) |
|||
target_link_libraries(search_assign_test Octree pMesh) |
@ -0,0 +1,114 @@ |
|||
/**
|
|||
* ------------------------------------ |
|||
* @author: Weipeng Kong |
|||
* @date: 2021/11/17 |
|||
* @email: yjxkwp@foxmail.com |
|||
* @site: https://donot.fit
|
|||
* @description: |
|||
* ------------------------------------ |
|||
**/ |
|||
|
|||
#include <iostream> |
|||
#include <igl/marching_cubes.h> |
|||
#include <igl/voxel_grid.h> |
|||
#include <igl/writeOBJ.h> |
|||
#include <igl/in_element.h> |
|||
#include <pMesh/mesh/TriangleMesh.h> |
|||
#include <pMesh/mesh/HexahedronMesh.h> |
|||
#include <pMesh/io/reader/OBJReader.h> |
|||
#include <pMesh/io/writer/VTKWriter.h> |
|||
#include <pMesh/io/adapter/DefaultReadAdapter.h> |
|||
#include <pMesh/io/adapter/DefaultWriteAdapter.h> |
|||
#include <boost/timer.hpp> |
|||
#include <boost/log/trivial.hpp> |
|||
#include <pMesh/io/reader/BaseReader.h> |
|||
|
|||
#include "Octree/udf/UDFOctree.h" |
|||
#include "Octree/OctreeBuilder.h" |
|||
#include "Octree/OctreeTraverser.h" |
|||
#include "Octree/udf/UDFTraversalSampler.h" |
|||
#include "test-path.h" |
|||
#include "search_assign.h" |
|||
|
|||
|
|||
int main() { |
|||
pMesh::io::fs_path data_base_path = TEST_DATA_BASE_PATH; |
|||
BOOST_LOG_TRIVIAL(debug) << "base data path is " << boost::filesystem::absolute(data_base_path); |
|||
bool use_udf = true; |
|||
auto out_mc_path = data_base_path / (use_udf? "sphere-udf-mc.obj": "sphere-sdf-mc.obj"); |
|||
|
|||
Eigen::AlignedBox<double, 3> aabb(Eigen::Vector3d(0,0,0), Eigen::Vector3d(1, 1, 1)); |
|||
|
|||
int aabb_res_x = 20; |
|||
int aabb_res_y = 20; |
|||
int aabb_res_z = 20; |
|||
int aabb_len = aabb_res_x * aabb_res_y * aabb_res_z; |
|||
|
|||
double x0 = 0; |
|||
double y0 = 0; |
|||
double z0 = 0; |
|||
double R = 1.2; |
|||
|
|||
auto sphere_shape = [=](double x, double y, double z) { |
|||
return sqrt(pow(x - x0, 2) + pow(y - y0, 2) + pow(z - z0, 2)) - R; |
|||
}; |
|||
Octree::UDFOctree octree(0, Octree::AABB(aabb.min(), aabb.max())); |
|||
octree.get_root()->udf = std::make_shared<Octree::UDFData>(std::vector<double>(aabb_len), aabb_res_x, aabb_res_y, |
|||
aabb_res_z); |
|||
auto &udf_data = *octree.get_root()->udf; |
|||
BOOST_LOG_TRIVIAL(debug) << "Calculating UDF"; |
|||
|
|||
for (int x = 0; x < aabb_res_x; ++x) { |
|||
double pos_x = ((aabb_res_x - x) * aabb.min().x() + x * aabb.max().x()) / (1.0 * aabb_res_x); |
|||
for (int y = 0; y < aabb_res_y; ++y) { |
|||
double pos_y = ((aabb_res_y - y) * aabb.min().y() + y * aabb.max().y()) / (1.0 * aabb_res_y); |
|||
for (int z = 0; z < aabb_res_z; ++z) { |
|||
double pos_z = ((aabb_res_z - z) * aabb.min().z() + z * aabb.max().z()) / (1.0 * aabb_res_z); |
|||
|
|||
int ind = udf_data.get_array_index(x, y, z); |
|||
if(use_udf) |
|||
udf_data.value[ind] = abs(sphere_shape(pos_x, pos_y, pos_z)); |
|||
else |
|||
udf_data.value[ind] = sphere_shape(pos_x, pos_y, pos_z); |
|||
} |
|||
} |
|||
} |
|||
BOOST_LOG_TRIVIAL(debug) << "End computing UDF"; |
|||
|
|||
if(use_udf) { |
|||
int start[3] = {aabb_res_x/2, aabb_res_y/2, aabb_res_z/2}; |
|||
double block_size[3]; |
|||
// TODO:
|
|||
double threshold = 0; |
|||
search_assign(udf_data, start, threshold); |
|||
} |
|||
|
|||
if (1) { |
|||
Eigen::MatrixXd GV; |
|||
Eigen::RowVector3i res; |
|||
const int s = 200; |
|||
igl::voxel_grid(aabb, s, 1, GV, res); |
|||
|
|||
// compute values
|
|||
std::cout << "Computing distances..." << std::endl; |
|||
Eigen::VectorXd S = Eigen::VectorXd(GV.rows()), B; |
|||
|
|||
{ |
|||
for (int i = 0; i < GV.rows(); ++i) { |
|||
auto node = octree.map_node(GV.row(i)); |
|||
if (node == nullptr) { |
|||
S[i] = 1000; |
|||
} else { |
|||
S[i] = node->get_udf(GV.row(i)); |
|||
} |
|||
} |
|||
} |
|||
std::cout << "Marching cubes..." << std::endl; |
|||
Eigen::MatrixXd SV, BV; |
|||
Eigen::MatrixXi SF, BF; |
|||
|
|||
igl::marching_cubes(S, GV, res(0), res(1), res(2), 0, SV, SF); |
|||
igl::writeOBJ(out_mc_path.string(), SV, SF); |
|||
} |
|||
return 0; |
|||
} |
@ -0,0 +1,79 @@ |
|||
/**
|
|||
* ------------------------------------ |
|||
* @author: Weipeng Kong |
|||
* @date: 2021/12/6 |
|||
* @email: yjxkwp@foxmail.com |
|||
* @site: https://donot.fit
|
|||
* @description: |
|||
* ------------------------------------ |
|||
**/ |
|||
|
|||
#include "search_assign.h" |
|||
#include <pMesh/mesh/TriangleMesh.h> |
|||
#include <iostream> |
|||
|
|||
bool *visited; |
|||
|
|||
void |
|||
dfs_for_assigning(Octree::UDFData &udf, int current_x, int current_y, int current_z, int ind, const double threshold, |
|||
std::function<void(const double *)> recorder) { |
|||
if (visited[ind] || ind == -1) return; |
|||
visited[ind] = true; |
|||
|
|||
if (abs(udf.value[ind]) < threshold) { |
|||
return; |
|||
// double pos[] = {current_x * 1.0, current_y * 1.0, current_z * 1.0, udf.value[ind]};
|
|||
// recorder(pos);
|
|||
} |
|||
|
|||
udf.value[ind] = -abs(udf.value[ind]); |
|||
|
|||
// sub routine
|
|||
for (int i = -1; i <= 1; ++i) { |
|||
int x = current_x + i; |
|||
if (x < 0 || x >= udf._x) continue; |
|||
|
|||
for (int j = -1; j <= 1; ++j) { |
|||
int y = current_y + j; |
|||
if (y < 0 || y >= udf._y) continue; |
|||
|
|||
for (int k = -1; k <= 1; ++k) { |
|||
int z = current_z + k; |
|||
if (z < 0 || z >= udf._z) continue; |
|||
|
|||
int next_ind = udf.get_array_index(x, y, z); |
|||
dfs_for_assigning(udf, x, y, z, next_ind, threshold, recorder); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// sub routine
|
|||
// for (auto nb: neighbors) {
|
|||
// if (nb[0] < 0 || nb[0] >= udf._x ||
|
|||
// nb[1] < 0 || nb[1] >= udf._y ||
|
|||
// nb[2] < 0 || nb[2] >= udf._z) {
|
|||
// continue;
|
|||
// } else {
|
|||
// int next_ind = udf.get_array_index(nb[0], nb[1], nb[2]);
|
|||
// dfs_for_assigning(udf, nb[0], nb[1], nb[2], next_ind, threshold, recorder);
|
|||
// }
|
|||
// }
|
|||
} |
|||
|
|||
void search_assign(Octree::UDFData &udf, int *start, double threshold) { |
|||
visited = new bool[udf._x * udf._y * udf._z]; |
|||
|
|||
pMesh::Triangle3dMesh point_cloud; |
|||
auto recoder = [&](const double *pos) { |
|||
// point_cloud.vertices.emplace_back(pMesh::Triangle3dMesh::VertexField())
|
|||
// std::cout << pos[0] << " " << pos[1] << " " << pos[2] << std::endl;
|
|||
}; |
|||
|
|||
// TODO: 选取开始点
|
|||
int next_ind = udf.get_array_index(start[0], start[1], start[2]); |
|||
dfs_for_assigning(udf, start[0], start[1], start[2], next_ind, threshold, recoder); |
|||
// TODO: 爆栈问题
|
|||
|
|||
delete visited; |
|||
visited = nullptr; |
|||
}; |
@ -0,0 +1,34 @@ |
|||
/**
|
|||
* ------------------------------------ |
|||
* @author: Weipeng Kong |
|||
* @date: 2021/12/6 |
|||
* @email: yjxkwp@foxmail.com |
|||
* @site: https://donot.fit
|
|||
* @description: 测试DFS赋值 |
|||
* ------------------------------------ |
|||
**/ |
|||
|
|||
#ifndef OCTREE_SEARCH_ASSIGN_H |
|||
#define OCTREE_SEARCH_ASSIGN_H |
|||
|
|||
#include "Octree/udf/UDFData.h" |
|||
|
|||
|
|||
/**
|
|||
* _________________________ |
|||
* | | | | |
|||
* | | | | |
|||
* |_______|_______|_______| |
|||
* | | ↑ | | |
|||
* | | ← d → | | |
|||
* |_______|___↓___|_______| |
|||
* | | | | |
|||
* | | | | |
|||
* |_______|_______|_______| |
|||
*/ |
|||
|
|||
void search_assign(Octree::UDFData &udf, int *start, double threshold); |
|||
|
|||
|
|||
|
|||
#endif //OCTREE_SEARCH_ASSIGN_H
|
@ -0,0 +1,16 @@ |
|||
/**
|
|||
* ------------------------------------ |
|||
* @author: Weipeng Kong |
|||
* @date: 2021/12/1 |
|||
* @email: yjxkwp@foxmail.com |
|||
* @site: https://donot.fit
|
|||
* @description: |
|||
* ------------------------------------ |
|||
**/ |
|||
|
|||
#ifndef OCTREE_SDF_TEST_PATH_H |
|||
#define OCTREE_SDF_TEST_PATH_H |
|||
|
|||
#define TEST_DATA_BASE_PATH "@TEST_DATA_BASE_PATH@" |
|||
|
|||
#endif //OCTREE_SDF_TEST_PATH_H
|
Loading…
Reference in new issue