Browse Source

fixed all bugs within underlyng modules;

stored formatted implicit arrangements data, and it is tested to be read correctly.
pull/1/head
ZCWang 8 months ago
parent
commit
3e279b63f8
  1. 7
      3rdparty/xmake.lua
  2. 6
      application/main.cpp
  3. 6
      application/xmake.lua
  4. 187910
      data/ia_data.dat
  5. 258
      data/ia_indices.dat
  6. 1
      implicit_arrangements/interface/implicit_arrangement.h
  7. 280
      implicit_arrangements/src/lut.cpp
  8. 9
      implicit_arrangements/test_lut/main.cpp
  9. 1
      implicit_arrangements/xmake.lua
  10. 16
      implicit_functions/include/implicit_function.hpp
  11. 14
      implicit_functions/include/load_functions.hpp
  12. 215
      implicit_functions/include/primitive_functions.hpp
  13. 27
      implicit_functions/include/utils/eigen_alias.hpp
  14. 4
      implicit_functions/interface/implicit_functions.hpp
  15. 82
      implicit_functions/src/main.cpp
  16. 3
      implicit_functions/xmake.lua
  17. 3
      network_process/include/implicit_surface_network_processor.hpp
  18. 2
      xmake.lua

7
3rdparty/xmake.lua

@ -15,14 +15,13 @@ target_end()
rule("config.indirect_predicates.flags")
on_config(function (target)
target:set("fpmodels", "strict")
if (target:has_tool("cxx", "cl", "clang_cl")) then
target:add("cxflags", "/fp:strict")
target:add("cxflags", "/Oi")
target:add("defines", "_CRT_SECURE_NO_WARNINGS")
target:add("cxflags", "/link /STACK:8421376")
-- target:add("cxflags", "/link /STACK:8421376")
else
target:add("cxflags", "-Wl,-z,stacksize=8421376")
target:add("cxflags", "-frounding-math")
-- target:add("cxflags", "-Wl,-z,stacksize=8421376")
end
target:add("vectorexts", "fma")
target:add("vectorexts", "neon")

6
application/main.cpp

@ -0,0 +1,6 @@
#include <implicit_functions.hpp>
#include <implicit_surface_network_processor.hpp>
int main(){
return 0;
}

6
application/xmake.lua

@ -0,0 +1,6 @@
target("implicit_surface_integrator")
set_kind("binary")
add_rules("config.indirect_predicates.flags")
add_deps("implicit_surface_network_process", "implicit_functions", "shared_module")
add_files("main.cpp")
target_end()

187910
data/ia_data.dat

File diff suppressed because it is too large

258
data/ia_indices.dat

@ -0,0 +1,258 @@
257
0
1
2
3
11
12
13
15
19
20
22
23
27
35
39
43
57
58
59
61
65
66
67
71
73
75
79
83
87
91
93
97
101
102
104
105
109
111
115
119
123
124
128
129
131
135
139
141
145
153
157
161
175
179
181
185
189
193
197
199
203
217
221
225
233
234
235
237
241
242
243
247
249
251
255
259
263
267
269
273
277
278
279
283
285
286
287
295
296
300
308
322
326
328
329
333
334
336
340
344
348
352
360
374
378
382
396
404
408
412
416
420
422
426
428
432
436
438
439
443
444
448
452
456
458
462
463
465
466
467
469
470
474
476
480
484
488
489
493
494
496
500
504
506
510
512
516
520
524
528
536
550
554
558
572
580
584
588
592
596
598
599
603
604
606
610
624
632
636
637
645
646
647
649
653
654
655
659
663
665
669
673
677
681
683
685
689
690
691
695
697
698
699
707
711
715
729
733
735
739
743
747
751
753
757
771
775
779
787
791
793
797
801
803
804
808
809
813
817
821
823
827
828
830
831
835
839
841
845
849
853
857
859
861
865
866
867
871
873
874
875
889
893
897
905
909
910
912
913
917
919
920
921
929
930
931
932

1
implicit_arrangements/interface/implicit_arrangement.h

@ -98,6 +98,7 @@ struct Arrangement3DResult {
};
EXTERN_C API bool load_lut();
EXTERN_C API void lut_print_test();
EXTERN_C API Arrangement2DResult compute_arrangement_2d(const Plane2D* planes, const uint32_t num_planes);
EXTERN_C API Arrangement3DResult compute_arrangement_3d(const Plane3D* planes, const uint32_t num_planes);
EXTERN_C API void free_arrangement_2d(Arrangement2D* arr);

280
implicit_arrangements/src/lut.cpp

@ -28,97 +28,189 @@ std::vector<uint32_t> ia_num_cells{};
std::vector<Arrangement3D> ia_data{};
std::vector<uint32_t> ia_indices{};
inline void from_json(const nlohmann::json& j, Point3D& p)
{
p.i0 = j[0].get<uint32_t>();
p.i1 = j[1].get<uint32_t>();
p.i2 = j[2].get<uint32_t>();
}
inline void parse_ia_into_pods(const nlohmann::json& j)
{
const auto& vertices = j[0].get<std::vector<Point3D>>();
ia_num_vertices.emplace_back(vertices.size());
ia_vertices.insert(ia_vertices.end(), vertices.begin(), vertices.end());
assert(ia_num_vertices.back() > 0);
ia_num_faces.emplace_back(j[1].size());
for (const auto& face_entry : j[1]) {
ia_face_vertices_count.emplace_back(face_entry[0].size());
ia_face_vertices.emplace_back(face_entry[0].get<std::vector<uint32_t>>());
ia_faces_ptr.emplace_back(ia_face_vertices.back().data());
ia_supporting_planes.emplace_back(face_entry[1].get<uint32_t>());
ia_positive_cells.emplace_back(face_entry[2].get<uint32_t>());
ia_negative_cells.emplace_back(face_entry[3].get<uint32_t>());
}
assert(ia_num_faces.back() > 0);
ia_num_cells.emplace_back(j[2].size());
for (const auto& cell_entry : j[2]) {
ia_cell_faces_count.emplace_back(cell_entry.size());
ia_cell_faces.emplace_back(cell_entry.get<std::vector<uint32_t>>());
ia_cells_ptr.emplace_back(ia_cell_faces.back().data());
}
assert(ia_num_cells.back() > 0);
}
// inline void from_json(const nlohmann::json& j, Point3D& p)
// {
// p.i0 = j[0].get<uint32_t>();
// p.i1 = j[1].get<uint32_t>();
// p.i2 = j[2].get<uint32_t>();
// }
// inline void parse_ia_into_pods(const nlohmann::json& j)
// {
// const auto& vertices = j[0].get<std::vector<Point3D>>();
// ia_num_vertices.emplace_back(vertices.size());
// ia_vertices.insert(ia_vertices.end(), vertices.begin(), vertices.end());
// assert(ia_num_vertices.back() > 0);
// ia_num_faces.emplace_back(j[1].size());
// for (const auto& face_entry : j[1]) {
// ia_face_vertices_count.emplace_back(face_entry[0].size());
// ia_face_vertices.emplace_back(face_entry[0].get<std::vector<uint32_t>>());
// ia_faces_ptr.emplace_back(ia_face_vertices.back().data());
// ia_supporting_planes.emplace_back(face_entry[1].get<uint32_t>());
// ia_positive_cells.emplace_back(face_entry[2].get<uint32_t>());
// ia_negative_cells.emplace_back(face_entry[3].get<uint32_t>());
// }
// assert(ia_num_faces.back() > 0);
// ia_num_cells.emplace_back(j[2].size());
// for (const auto& cell_entry : j[2]) {
// ia_cell_faces_count.emplace_back(cell_entry.size());
// ia_cell_faces.emplace_back(cell_entry.get<std::vector<uint32_t>>());
// ia_cells_ptr.emplace_back(ia_cell_faces.back().data());
// }
// assert(ia_num_cells.back() > 0);
// }
// EXTERN_C API bool load_lut()
// {
// if (!ia_data.empty() && !ia_indices.empty()) return true;
// auto t0 = tbb::tick_count::now();
// std::ifstream file("ia_lut.msgpack", std::ios::in | std::ios::binary);
// if (!file.is_open()) {
// std::cerr << "Error: IA LUT file does not exist!" << std::endl;
// return false;
// }
// std::vector<char> msgpack(std::istreambuf_iterator<char>(file), {});
// nlohmann::json json = nlohmann::json::from_msgpack(msgpack);
// file.close();
// ia_indices = json["start_index"].get<std::vector<uint32_t>>();
// /* a tet has at least 4 vertices and 4 faces, and we'll use this assumption to reverse space for POD data */
// ia_vertices.reserve(json["data"].size() * 4);
// ia_face_vertices.reserve(json["data"].size() * 4 * 3); // 3 vertices per triangle face
// ia_faces_ptr.reserve(json["data"].size() * 4);
// ia_face_vertices_count.reserve(json["data"].size() * 4);
// ia_supporting_planes.reserve(json["data"].size() * 4);
// ia_positive_cells.reserve(json["data"].size() * 4);
// ia_negative_cells.reserve(json["data"].size() * 4);
// ia_cell_faces.reserve(json["data"].size() * 4);
// ia_cells_ptr.reserve(json["data"].size());
// ia_cell_faces_count.reserve(json["data"].size());
// ia_num_vertices.reserve(json["data"].size());
// ia_num_faces.reserve(json["data"].size());
// ia_num_cells.reserve(json["data"].size());
// // HINT: change of capcity may happen here.
// uint32_t i = 0;
// for (const auto& entry : json["data"]) {
// parse_ia_into_pods(entry);
// std::cout << "Parsed IA: " << i << std::endl;
// i++;
// }
// ia_data.resize(json["data"].size());
// uint32_t vertices_offset{}, faces_offset{}, cells_offset{};
// for (size_t i = 0; i < json["data"].size(); i++) {
// auto& ia = ia_data[i];
// ia.num_vertices = ia_num_vertices[i];
// ia.points = ia_vertices.data() + vertices_offset;
// ia.num_faces = ia_num_faces[i];
// ia.vertices = ia_faces_ptr.data() + faces_offset;
// ia.face_vertices_count = ia_face_vertices_count.data() + faces_offset;
// ia.supporting_planes = ia_supporting_planes.data() + faces_offset;
// ia.positive_cells = ia_positive_cells.data() + faces_offset;
// ia.negative_cells = ia_negative_cells.data() + faces_offset;
// ia.num_cells = ia_num_cells[i];
// ia.faces = ia_cells_ptr.data() + cells_offset;
// ia.cell_faces_count = ia_cell_faces_count.data() + cells_offset;
// ia.num_unique_planes = 0;
// }
// auto t1 = tbb::tick_count::now();
// std::cout << "Loading LUT took " << std::fixed << std::setprecision(10) << (t1 - t0).seconds() << " seconds." <<
// std::endl; return true;
// }
EXTERN_C API bool load_lut()
{
if (!ia_data.empty() && !ia_indices.empty()) return true;
auto deserialize_ia = [](const nlohmann::json& json) {
auto& ia = ia_data.emplace_back(Arrangement3D{});
const auto& vertices = json[0].get<std::vector<Point3D>>();
};
auto t0 = tbb::tick_count::now();
std::ifstream file("ia_lut.msgpack", std::ios::in | std::ios::binary);
if (!file.is_open()) {
std::ifstream ia_data_file("ia_data.dat", std::ios::in | std::ios::binary);
std::ifstream ia_indices_file("ia_indices.dat", std::ios::in | std::ios::binary);
if (!ia_data_file.is_open() || !ia_indices_file.is_open()) {
std::cerr << "Error: IA LUT file does not exist!" << std::endl;
return false;
}
std::vector<char> msgpack(std::istreambuf_iterator<char>(file), {});
nlohmann::json json = nlohmann::json::from_msgpack(msgpack);
file.close();
ia_indices = json["start_index"].get<std::vector<uint32_t>>();
/* a tet has at least 4 vertices and 4 faces, and we'll use this assumption to reverse space for POD data */
ia_vertices.reserve(json["data"].size() * 4);
ia_face_vertices.reserve(json["data"].size() * 4 * 3); // 3 vertices per triangle face
ia_faces_ptr.reserve(json["data"].size() * 4);
ia_face_vertices_count.reserve(json["data"].size() * 4);
ia_supporting_planes.reserve(json["data"].size() * 4);
ia_positive_cells.reserve(json["data"].size() * 4);
ia_negative_cells.reserve(json["data"].size() * 4);
ia_cell_faces.reserve(json["data"].size() * 4);
ia_cells_ptr.reserve(json["data"].size());
ia_cell_faces_count.reserve(json["data"].size());
ia_num_vertices.reserve(json["data"].size());
ia_num_faces.reserve(json["data"].size());
ia_num_cells.reserve(json["data"].size());
// HINT: change of capcity may happen here.
for (const auto& entry : json["data"]) parse_ia_into_pods(entry);
ia_data.resize(json["data"].size());
size_t curr_blob_size{};
ia_data_file >> curr_blob_size;
ia_num_vertices.resize(curr_blob_size);
ia_num_faces.resize(curr_blob_size);
ia_num_cells.resize(curr_blob_size);
ia_data.resize(curr_blob_size);
ia_data_file >> curr_blob_size;
ia_vertices.resize(curr_blob_size);
for (size_t i = 0; i < curr_blob_size; ++i) ia_data_file >> ia_vertices[i].i0 >> ia_vertices[i].i1 >> ia_vertices[i].i2;
ia_data_file >> curr_blob_size;
ia_face_vertices.resize(curr_blob_size);
ia_faces_ptr.resize(curr_blob_size);
ia_face_vertices_count.resize(curr_blob_size);
ia_supporting_planes.resize(curr_blob_size);
ia_positive_cells.resize(curr_blob_size);
ia_negative_cells.resize(curr_blob_size);
for (size_t i = 0; i < curr_blob_size; i++) {
ia_data_file >> ia_face_vertices_count[i];
ia_face_vertices[i].resize(ia_face_vertices_count[i]);
for (size_t j = 0; j < ia_face_vertices_count[i]; j++) ia_data_file >> ia_face_vertices[i][j];
ia_faces_ptr[i] = ia_face_vertices[i].data();
}
for (size_t i = 0; i < curr_blob_size; i++) ia_data_file >> ia_supporting_planes[i];
for (size_t i = 0; i < curr_blob_size; i++) ia_data_file >> ia_positive_cells[i];
for (size_t i = 0; i < curr_blob_size; i++) ia_data_file >> ia_negative_cells[i];
ia_data_file >> curr_blob_size;
ia_cell_faces.resize(curr_blob_size);
ia_cells_ptr.resize(curr_blob_size);
ia_cell_faces_count.resize(curr_blob_size);
for (size_t i = 0; i < curr_blob_size; i++) {
ia_data_file >> ia_cell_faces_count[i];
ia_cell_faces[i].resize(ia_cell_faces_count[i]);
for (size_t j = 0; j < ia_cell_faces_count[i]; j++) ia_data_file >> ia_cell_faces[i][j];
ia_cells_ptr[i] = ia_cell_faces[i].data();
}
for (size_t i = 0; i < ia_data.size(); i++) ia_data_file >> ia_num_vertices[i];
for (size_t i = 0; i < ia_data.size(); i++) ia_data_file >> ia_num_faces[i];
for (size_t i = 0; i < ia_data.size(); i++) ia_data_file >> ia_num_cells[i];
ia_indices_file >> curr_blob_size;
ia_indices.resize(curr_blob_size);
for (size_t i = 0; i < curr_blob_size; i++) ia_indices_file >> ia_indices[i];
ia_data_file.close();
ia_indices_file.close();
uint32_t vertices_offset{}, faces_offset{}, cells_offset{};
for (size_t i = 0; i < json["data"].size(); i++) {
for (size_t i = 0; i < ia_data.size(); i++) {
auto& ia = ia_data[i];
ia.num_vertices = ia_num_vertices[i];
ia.points = ia_vertices.data() + vertices_offset;
ia.num_vertices = ia_num_vertices[i];
ia.points = ia_vertices.data() + vertices_offset;
vertices_offset += ia.num_vertices;
ia.num_faces = ia_num_faces[i];
ia.vertices = ia_faces_ptr.data() + faces_offset;
ia.face_vertices_count = ia_face_vertices_count.data() + faces_offset;
ia.supporting_planes = ia_supporting_planes.data() + faces_offset;
ia.positive_cells = ia_positive_cells.data() + faces_offset;
ia.negative_cells = ia_negative_cells.data() + faces_offset;
ia.num_faces = ia_num_faces[i];
ia.vertices = ia_faces_ptr.data() + faces_offset;
ia.face_vertices_count = ia_face_vertices_count.data() + faces_offset;
ia.supporting_planes = ia_supporting_planes.data() + faces_offset;
ia.positive_cells = ia_positive_cells.data() + faces_offset;
ia.negative_cells = ia_negative_cells.data() + faces_offset;
faces_offset += ia.num_faces;
ia.num_cells = ia_num_cells[i];
ia.faces = ia_cells_ptr.data() + cells_offset;
ia.cell_faces_count = ia_cell_faces_count.data() + cells_offset;
ia.num_cells = ia_num_cells[i];
ia.faces = ia_cells_ptr.data() + cells_offset;
ia.cell_faces_count = ia_cell_faces_count.data() + cells_offset;
cells_offset += ia.num_cells;
ia.num_unique_planes = 0;
}
@ -128,6 +220,42 @@ EXTERN_C API bool load_lut()
return true;
}
EXTERN_C API void lut_print_test()
{
const auto& ia = ia_data[0];
std::cout << "num_vertices: " << ia.num_vertices << std::endl;
std::cout << "num_faces: " << ia.num_faces << std::endl;
std::cout << "num_cells: " << ia.num_cells << std::endl;
std::cout << "points: " << std::endl;
for (size_t i = 0; i < ia.num_vertices; i++) {
std::cout << ia.points[i].i0 << " " << ia.points[i].i1 << " " << ia.points[i].i2 << std::endl;
}
std::cout << "faces: " << std::endl;
for (size_t i = 0; i < ia.num_faces; i++) {
std::cout << "face " << i << std::endl;
for (size_t j = 0; j < ia.face_vertices_count[i]; j++) { std::cout << ia.vertices[i][j] << " "; }
std::cout << std::endl;
}
std::cout << "supporting_planes: " << std::endl;
for (size_t i = 0; i < ia.num_faces; i++) {
std::cout << ia.supporting_planes[i] << std::endl;
}
std::cout << "positive_cells: " << std::endl;
for (size_t i = 0; i < ia.num_faces; i++) {
std::cout << ia.positive_cells[i] << std::endl;
}
std::cout << "negative_cells: " << std::endl;
for (size_t i = 0; i < ia.num_faces; i++) {
std::cout << ia.negative_cells[i] << std::endl;
}
std::cout << "cells: " << std::endl;
for (size_t i = 0; i < ia.num_cells; i++) {
std::cout << "cell " << i << std::endl;
for (size_t j = 0; j < ia.cell_faces_count[i]; j++) { std::cout << ia.faces[i][j] << " "; }
std::cout << std::endl;
}
}
uint32_t ia_compute_outer_index(const Plane3D& p0)
{
// Plane must not intersect tet at vertices.

9
implicit_arrangements/test_lut/main.cpp

@ -0,0 +1,9 @@
#include <implicit_arrangement.h>
int main()
{
load_lut();
lut_print_test();
return 0;
}

1
implicit_arrangements/xmake.lua

@ -24,6 +24,7 @@ target_end()
target("implicit_arrangements.LUT.load_test")
set_kind("binary")
add_rules("config.indirect_predicates.flags")
add_defines("SHARED_MODULE=0")
add_deps("implicit_arrangements")
add_files("./test_lut/main.cpp")
target_end()

16
implicit_functions/include/implicit_function.hpp

@ -0,0 +1,16 @@
#pragma once
#include "utils/eigen_alias.hpp"
class ImplicitFunction
{
public:
template <size_t Dim>
double evaluate_scalar(const Eigen::Ref<const Eigen::Vector<double, Dim>>& pos) const;
template <size_t Dim>
Eigen::Vector<double, Dim> evaluate_gradient(const Eigen::Ref<const Eigen::Vector<double, Dim>>& pos) const;
template <size_t Dim>
Eigen::Vector<double, Dim + 1> evaluate_scalar_gradient(const Eigen::Ref<const Eigen::Vector<double, Dim>>& pos) const;
};

14
implicit_functions/include/load_functions.hpp

@ -0,0 +1,14 @@
#pragma once
#include <string_view>
#include <container/small_vector.hpp>
#include "implicit_function.hpp"
struct load_functions_result_t {
small_vector_mp<std::unique_ptr<ImplicitFunction>> functions{};
bool success{};
};
load_functions_result_t load_functions(const std::string_view& filename);

215
implicit_functions/include/primitive_functions.hpp

@ -0,0 +1,215 @@
#pragma once
#include "implicit_function.hpp"
static constexpr double kEpsilon = 1e-6;
class ConstantFunction : public ImplicitFunction
{
public:
explicit ConstantFunction(double value) : value_(value) {}
template <size_t Dim>
double evaluate_scalar(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const
{
return value_;
}
template <size_t Dim>
Eigen::Vector<double, Dim> evaluate_gradient(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const
{
return Eigen::Vector<double, Dim>::Zero();
}
template <size_t Dim>
Eigen::Vector<double, Dim + 1> evaluate_scalar_gradient(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const
{
auto res = Eigen::Vector<double, Dim + 1>::Zero();
res[0] = value_;
return res;
}
private:
double value_{};
};
template <size_t Dim>
class PlaneDistanceFunction : public ImplicitFunction
{
public:
PlaneDistanceFunction(const Eigen::Ref<const Eigen::Vector<double, Dim>> &point,
const Eigen::Ref<const Eigen::Vector<double, Dim>> &normal)
: point_(point), normal_(normal)
{
normal_.normalize();
}
double evaluate_scalar(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const { return normal_.dot(pos - point_); }
Eigen::Vector<double, Dim> evaluate_gradient(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const
{
return normal_;
}
Eigen::Vector<double, Dim + 1> evaluate_scalar_gradient(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const
{
Eigen::Vector<double, Dim + 1> res{};
res.template head<Dim>().array() = normal_.array();
res[Dim] = evaluate_scalar(pos);
return res;
}
private:
Eigen::Vector<double, Dim> point_{};
Eigen::Vector<double, Dim> normal_{};
};
template <size_t Dim>
class SphereDistanceFunction : public ImplicitFunction
{
public:
SphereDistanceFunction(const Eigen::Ref<const Eigen::Vector<double, Dim>> &center, double radius)
: center_(center), radius_(radius)
{
}
double evaluate_scalar(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const
{
return (pos - center_).norm() - radius_;
}
Eigen::Vector<double, Dim> evaluate_gradient(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const
{
auto vec = pos - center_;
double norm = vec.norm();
if (norm <= kEpsilon) return Eigen::Vector<double, Dim>::Zero();
return vec / norm;
}
Eigen::Vector<double, Dim + 1> evaluate_scalar_gradient(const Eigen::Ref<const Eigen::Vector<double, Dim>> &pos) const
{
Eigen::Vector<double, Dim + 1> res{};
auto vec = pos - center_;
double norm = vec.norm();
if (norm <= kEpsilon) {
res[Dim] = -radius_;
return res;
}
res.template head<Dim>().array() = vec.array() / norm;
res[Dim] = norm - radius_;
return res;
}
private:
Eigen::Vector<double, Dim> center_{};
double radius_{};
};
template <size_t Dim>
class CylinderDistanceFunction;
template <>
class CylinderDistanceFunction<3> : public ImplicitFunction
{
public:
CylinderDistanceFunction(const Eigen::Ref<const Eigen::Vector3d> &axis_point,
const Eigen::Ref<const Eigen::Vector3d> &axis_dir,
double radius)
: axis_point_(axis_point), axis_dir_(axis_dir), radius_(radius)
{
axis_dir_.normalize();
}
double evaluate_scalar(const Eigen::Ref<const Eigen::Vector3d> &pos) const
{
auto vec = pos - axis_point_;
auto dist = vec.dot(axis_dir_);
return (vec - dist * axis_dir_).norm() - radius_;
}
Eigen::Vector3d evaluate_gradient(const Eigen::Ref<const Eigen::Vector3d> &pos) const
{
auto vec = pos - axis_point_;
auto dist = vec.dot(axis_dir_);
auto vec_para = dist * axis_dir_;
Eigen::Vector3d vec_perp = vec - vec_para;
double norm = vec_perp.norm();
if (norm <= kEpsilon) return Eigen::Vector3d::Zero();
return vec_perp / norm;
}
Eigen::Vector4d evaluate_scalar_gradient(const Eigen::Ref<const Eigen::Vector3d> &pos) const
{
Eigen::Vector4d res{};
auto vec = pos - axis_point_;
auto dist = vec.dot(axis_dir_);
auto vec_para = dist * axis_dir_;
Eigen::Vector3d vec_perp = vec - vec_para;
double norm = vec_perp.norm();
if (norm <= kEpsilon) {
res[3] = -radius_;
return res;
}
res.template head<3>().array() = vec_perp.array() / norm;
res[3] = norm - radius_;
return res;
}
private:
Eigen::Vector3d axis_point_{};
Eigen::Vector3d axis_dir_{};
double radius_{};
};
template <size_t Dim>
class ConeDistanceFunction;
template <>
class ConeDistanceFunction<3> : public ImplicitFunction
{
public:
ConeDistanceFunction(const Eigen::Ref<const Eigen::Vector3d> &apex_point,
const Eigen::Ref<const Eigen::Vector3d> &axis_dir,
double apex_angle)
: apex_point_(apex_point), axis_dir_(axis_dir), apex_angle_cosine_(std::cos(apex_angle))
{
axis_dir_.normalize();
}
double evaluate_scalar(const Eigen::Ref<const Eigen::Vector3d> &pos) const
{
return apex_angle_cosine_ * (pos - apex_point_).norm() - (pos - apex_point_).dot(axis_dir_);
}
Eigen::Vector3d evaluate_gradient(const Eigen::Ref<const Eigen::Vector3d> &pos) const
{
auto vec_apex = pos - apex_point_;
auto vec_norm = vec_apex.norm();
if (vec_norm <= kEpsilon) return Eigen::Vector3d::Zero();
return vec_apex * apex_angle_cosine_ / vec_norm - axis_dir_;
}
Eigen::Vector4d evaluate_scalar_gradient(const Eigen::Ref<const Eigen::Vector3d> &pos) const
{
auto vec_apex = pos - apex_point_;
auto vec_norm = vec_apex.norm();
if (vec_norm <= kEpsilon) return Eigen::Vector4d::Zero();
Eigen::Vector4d res{};
res.template head<3>().array() = vec_apex.array() * apex_angle_cosine_ / vec_norm - axis_dir_.array();
res[3] = apex_angle_cosine_ * vec_norm - vec_apex.dot(axis_dir_);
return res;
}
private:
Eigen::Vector3d apex_point_{};
Eigen::Vector3d axis_dir_{};
double apex_angle_cosine_{};
};
template <size_t Dim>
class TorusDistanceFunction;

27
implicit_functions/include/utils/eigen_alias.hpp

@ -0,0 +1,27 @@
#pragma once
#include <tbb/tbbmalloc_proxy.h>
#define EIGEN_NO_CUDA 1
#define EIGEN_USE_MKL 1
#define EIGEN_USE_MKL_ALL 1
#define EIGEN_USE_THREADS 1
// just an experiment, since it seems OKay to mix oneTBB and OpenMP, see
// https://oneapi-src.github.io/oneTBB/main/tbb_userguide/appendix_B.html
// #define EIGEN_DONT_PARALLELIZE \
// 1 // use this macro to disable multi-threading in Eigen, since Eigen's multi-threading is
// // restricted to use OpenMP
#define EIGEN_INITIALIZE_MATRICES_BY_ZERO 1
#define EIGEN_NO_AUTOMATIC_RESIZING 1
// #define EIGEN_MAX_CPP_VER 17
#include <Eigen/Dense>
// namespace BlobtreeIntegral::IMath
// {
// using namespace Eigen;
// static aligned_allocator<double> g_aligned_allocator{};
// static ThreadPool g_thread_pool(nbThreads());
// static ThreadPoolDevice g_tensor_thread_pool_handle(&g_thread_pool, nbThreads());
// } // namespace BlobtreeIntegral::IMath

4
implicit_functions/interface/implicit_functions.hpp

@ -0,0 +1,4 @@
#pragma once
#include <primitive_functions.hpp>
#include <load_functions.hpp>

82
implicit_functions/src/main.cpp

@ -0,0 +1,82 @@
#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
#include <implicit_functions.hpp>
#include "primitive_functions.hpp"
load_functions_result_t load_functions(const std::string_view& filename)
{
using json = nlohmann::json;
std::ifstream file(filename.data());
if (!file) {
std::cout << "Failed to open function file: " << filename << std::endl;
return {};
}
json data;
file >> data;
file.close();
load_functions_result_t result{};
const auto num_functions = data.size();
result.functions.reserve(num_functions);
for (size_t j = 0; j < num_functions; ++j) {
const auto type = data[j]["type"].get<std::string>();
if (type == "plane") {
Eigen::Vector3d point, normal;
for (auto i = 0; i < 3; ++i) {
point[i] = data[j]["point"][i].get<double>();
normal[i] = data[j]["normal"][i].get<double>();
}
result.functions.emplace_back(std::make_unique<PlaneDistanceFunction<3>>(point, normal));
} else if (type == "line") {
Eigen::Vector3d point, direction;
for (auto i = 0; i < 3; ++i) {
point[i] = data[j]["point"][i].get<double>();
direction[i] = data[j]["direction"][i].get<double>();
}
result.functions.emplace_back(std::make_unique<CylinderDistanceFunction<3>>(point, direction, 0));
} else if (type == "cylinder") {
Eigen::Vector3d axis_point, axis_direction;
if (data[j].contains("axis_point1") && data[j].contains("axis_point2")) {
Eigen::Vector3d axis_point_;
for (auto i = 0; i < 3; ++i) {
axis_point[i] = data[j]["axis_point1"][i].get<double>();
axis_point_[i] = data[j]["axis_point2"][i].get<double>();
}
axis_direction = axis_point_ - axis_point;
} else {
for (auto i = 0; i < 3; ++i) {
axis_point[i] = data[j]["axis_point"][i].get<double>();
axis_direction[i] = data[j]["axis_direction"][i].get<double>();
}
}
double radius = data[j]["radius"].get<double>();
result.functions.emplace_back(std::make_unique<CylinderDistanceFunction<3>>(axis_point, axis_direction, radius));
} else if (type == "sphere") {
Eigen::Vector3d center;
for (auto i = 0; i < 3; ++i) { center[i] = data[j]["center"][i].get<double>(); }
double radius = data[j]["radius"].get<double>();
result.functions.emplace_back(std::make_unique<SphereDistanceFunction<3>>(center, radius));
} else if (type == "cone") {
Eigen::Vector3d apex_point, axis_direction;
for (auto i = 0; i < 3; ++i) {
apex_point[i] = data[j]["apex_point"][i].get<double>();
axis_direction[i] = data[j]["axis_direction"][i].get<double>();
}
double apex_angle = data[j]["apex_angle"].get<double>();
result.functions.emplace_back(std::make_unique<ConeDistanceFunction<3>>(apex_point, axis_direction, apex_angle));
} else if (type == "constant") {
double value = data[j]["value"].get<double>();
result.functions.emplace_back(std::make_unique<ConstantFunction>(value));
} else {
std::cout << "Unsupported function type: " << type << std::endl;
return {};
}
}
return result;
}

3
implicit_functions/xmake.lua

@ -14,7 +14,8 @@ target("implicit_functions")
add_vectorexts("ssse3")
add_vectorexts("sse4.2")
add_defines("SHARED_MODULE=0")
add_includedirs("include", {public = true})
add_includedirs("include")
add_includedirs("interface", {public = true})
add_files("src/*.cpp")
add_packages("eigen-latest", {public = true})
add_packages("nlohmann_json")

3
network_process/include/implicit_surface_network_processor.hpp

@ -11,7 +11,8 @@
struct ImplicitSurfaceNetworkProcessor {
ImplicitSurfaceNetworkProcessor() = default;
ImplicitSurfaceNetworkProcessor(const tetrahedron_mesh_t& background_mesh, const Eigen::MatrixXd& sdf_scalar_field)
ImplicitSurfaceNetworkProcessor(const tetrahedron_mesh_t& background_mesh,
const Eigen::Ref<const Eigen::MatrixXd>& sdf_scalar_field)
: background_mesh(background_mesh), sdf_scalar_field(sdf_scalar_field)
{
}

2
xmake.lua

@ -14,4 +14,4 @@ includes("./shared_module/xmake.lua")
includes("./implicit_**/xmake.lua")
includes("./network_process/xmake.lua")
includes("./application/**/xmake.lua")
includes("./application/xmake.lua")
Loading…
Cancel
Save