Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorremi durand <remi-j.durand@thalesgroup.com>2022-01-12 10:49:19 +0300
committerremi durand <remi-j.durand@thalesgroup.com>2022-01-12 10:49:19 +0300
commit6e0017ff8fc82ce66e65bcddd2285d48c1b6fb1c (patch)
tree07fa4bca6aa5dfb8fb3dcdeb8c5d691e443247dc /sandboxes/its_neighbor_index/main.cpp
parent42db5ca0d12e9a54b8c378dbf8ec12671566a9ec (diff)
parent215e845c31889f92f78e8be1d9ee52f6209a8082 (diff)
Merge remote-tracking branch 'remotes/prusa/master' 2.4 into dev 2.3.58
still need much tests (& bugfixes) and finish some merging things.
Diffstat (limited to 'sandboxes/its_neighbor_index/main.cpp')
-rw-r--r--sandboxes/its_neighbor_index/main.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/sandboxes/its_neighbor_index/main.cpp b/sandboxes/its_neighbor_index/main.cpp
new file mode 100644
index 000000000..2c89da3ac
--- /dev/null
+++ b/sandboxes/its_neighbor_index/main.cpp
@@ -0,0 +1,273 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <tuple>
+#include <random>
+
+#include "ItsNeighborIndex.hpp"
+
+#include "libnest2d/tools/benchmark.h"
+#include "libnest2d/utils/metaloop.hpp"
+
+namespace Slic3r {
+
+enum { IndexCreation, Split };
+struct MeasureResult
+{
+ static constexpr const char * Names[] = {
+ "Index creation [s]",
+ "Split [s]"
+ };
+
+ double measurements[std::size(Names)] = {0.};
+};
+
+template<class IndexCreatorFn>
+static MeasureResult measure_index(const indexed_triangle_set &its, IndexCreatorFn fn)
+{
+ Benchmark b;
+
+ MeasureResult r;
+ for (int i = 0; i < 10; ++i) {
+ b.start();
+ ItsNeighborsWrapper itsn{its, fn(its)};
+ b.stop();
+
+ r.measurements[IndexCreation] += b.getElapsedSec();
+
+ b.start();
+ auto res = its_split(itsn);
+ b.stop();
+
+// if (res.size() != 2 || res[0].indices.size() != res[1].indices.size() )
+// std::cerr << "Something is wrong, split result invalid" << std::endl;
+
+ r.measurements[Split] += b.getElapsedSec();
+ }
+
+ r.measurements[IndexCreation] /= 10;
+ r.measurements[Split] /= 10;
+
+ return r;
+}
+
+const auto Seed = 0;// std::random_device{}();
+
+static indexed_triangle_set make_sphere_rnd(double radius, double detail)
+{
+ using namespace Slic3r;
+
+ auto sphere = its_make_sphere(radius, detail);
+
+ auto vfidx = create_vertex_faces_index(sphere);
+
+ const size_t vertexnum = sphere.vertices.size();
+ const size_t facenum = sphere.indices.size();
+
+ std::mt19937 rng{Seed};
+ std::uniform_int_distribution<size_t> distv(sphere.vertices.size() / 2, sphere.vertices.size() - 1);
+ std::uniform_int_distribution<size_t> distf(sphere.indices.size() / 2, sphere.indices.size() - 1) ;
+
+ std::vector<bool> was(vertexnum / 2, false);
+
+ for (size_t i = 0; i < vertexnum / 2; ++i) {
+ size_t image = distv(rng);
+ if (was[image - vertexnum / 2]) continue;
+ was[image - vertexnum / 2] = true;
+
+ std::swap(sphere.vertices[i], sphere.vertices[image]);
+ for (size_t face_id : vfidx[i]) {
+ for (int &vi : sphere.indices[face_id])
+ if (vi == int(i)) vi = image;
+ }
+
+ for (size_t face_id : vfidx[image]) {
+ for (int &vi : sphere.indices[face_id])
+ if (vi == int(image)) vi = i;
+ }
+
+ std::swap(vfidx[i], vfidx[image]);
+ }
+
+ for (size_t i = 0; i < facenum / 2; ++i) {
+ size_t image = distf(rng);
+ std::swap(sphere.indices[i], sphere.indices[image]);
+ }
+
+ return sphere;
+}
+
+static indexed_triangle_set two_spheres(double detail)
+{
+ auto sphere1 = make_sphere_rnd(10., 2 * PI / detail), sphere2 = sphere1;
+
+ its_transform(sphere1, identity3f().translate(Vec3f{-5.f, 0.f, 0.f}));
+ its_transform(sphere2, identity3f().translate(Vec3f{5.f, 0.f, 0.f}));
+
+ its_merge(sphere1, sphere2);
+
+ return sphere1;
+}
+
+static indexed_triangle_set make_spheres(unsigned N, double detail)
+{
+ indexed_triangle_set ret, sphere = make_sphere_rnd(10., 2. * PI / detail);
+
+ for (unsigned i = 0u ; i < N; ++i)
+ its_merge(ret, sphere);
+
+ return ret;
+}
+
+constexpr double sq2 = std::sqrt(2.);
+
+static const std::pair<const std::string, indexed_triangle_set> ToMeasure[] = {
+// {"two_spheres_1x", two_spheres(60.)},
+// {"two_spheres_2x", two_spheres(120.)},
+// {"two_spheres_4x", two_spheres(240.)},
+// {"two_spheres_8x", two_spheres(480.)},
+// {"two_spheres_16x", two_spheres(2 * 480.)},
+// {"two_spheres_32x", two_spheres(2 * 2 * 480.)},
+
+ {"two_spheres_1x", two_spheres(60.)},
+ {"two_spheres_2x", two_spheres(sq2 * 60.)},
+ {"two_spheres_4x", two_spheres(2 * 60.)},
+ {"two_spheres_8x", two_spheres(sq2 * 2. * 60.)},
+ {"two_spheres_16x", two_spheres(4. * 60.)},
+ {"two_spheres_32x", two_spheres(sq2 * 4. * 60.)},
+ {"two_spheres_64x", two_spheres(8. * 60.)},
+ {"two_spheres_128x", two_spheres(sq2 * 8. * 60.)},
+ {"two_spheres_256x", two_spheres(16. * 60.)},
+ {"two_spheres_512x", two_spheres(sq2 * 16. * 60.)},
+
+ {"2_spheres", make_spheres(2, 60.)},
+ {"4_spheres", make_spheres(4, 60.)},
+ {"8_spheres", make_spheres(8, 60.)},
+ {"16_spheres", make_spheres(16, 60.)},
+ {"32_spheres", make_spheres(32, 60.)},
+ {"64_spheres", make_spheres(64, 60.)},
+ {"128_spheres", make_spheres(128, 60.)},
+ {"256_spheres", make_spheres(256, 60.)},
+ {"512_spheres", make_spheres(512, 60.)},
+ {"1024_spheres", make_spheres(1024, 60.)}
+};
+
+static const auto IndexFunctions = std::make_tuple(
+ std::make_pair("tamas's unordered_map based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_1); }),
+ std::make_pair("vojta std::sort based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_2); }),
+ std::make_pair("vojta tbb::parallel_sort based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_3); }),
+ std::make_pair("filip's vertex->face based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_5); }),
+ std::make_pair("vojta's vertex->face", [](const auto &its) { return measure_index(its, its_create_neighbors_index_9); }),
+ std::make_pair("vojta's vertex->face parallel", [](const auto &its) { return measure_index(its, its_create_neighbors_index_10); }),
+ std::make_pair("tamas's std::sort based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_6); }),
+ std::make_pair("tamas's tbb::parallel_sort based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_7); }),
+ std::make_pair("tamas's map based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_8); }),
+ std::make_pair("TriangleMesh split", [](const auto &its) {
+
+ MeasureResult r;
+ for (int i = 0; i < 10; ++i) {
+ TriangleMesh m{its};
+ Benchmark b;
+
+ b.start();
+ m.repair(); // FIXME: this does more than just create neighborhood map
+ b.stop();
+ r.measurements[IndexCreation] += b.getElapsedSec();
+
+ b.start();
+ auto res = m.split();
+ b.stop();
+ r.measurements[Split] += b.getElapsedSec();
+
+// if (res.size() != 2 || res[0]->size() != res[1]->size())
+// std::cerr << "Something is wrong, split result invalid" << std::endl;
+ }
+ r.measurements[IndexCreation] /= 10;
+ r.measurements[Split] /= 10;
+
+ return r;
+ })
+
+// std::make_pair("Vojta's vertex->face index", [](const auto &its){
+// Benchmark b;
+// b.start();
+// auto index = create_vertex_faces_index(its);
+// b.stop();
+
+// if (index.size() != its.vertices.size())
+// std::cerr << "Something went wrong!";
+
+// return MeasureResult{b.getElapsedSec(), 0., 0.};
+// }),
+// std::make_pair("Tamas's vertex->face index", [](const auto &its){
+// Benchmark b;
+// b.start();
+// VertexFaceIndex index{its};
+// b.stop();
+
+// if (index.size() < its.vertices.size())
+// std::cerr << "Something went wrong!";
+
+// return MeasureResult{b.getElapsedSec(), 0., 0.};
+// })
+);
+
+static constexpr size_t IndexFuncNum = std::tuple_size_v<decltype (IndexFunctions)>;
+
+} // namespace Slic3r
+
+int main(const int argc, const char * argv[])
+{
+ using namespace Slic3r;
+
+ std::array<MeasureResult, IndexFuncNum> results[std::size(ToMeasure)];
+ std::array<std::string, IndexFuncNum> funcnames;
+
+ for (size_t i = 0; i < std::size(ToMeasure); ++i) {
+ auto &m = ToMeasure[i];
+ auto &name = m.first;
+ auto &mesh = m.second;
+
+// its_write_obj(mesh, (std::string(name) + ".obj").c_str());
+
+ std::cout << "Mesh " << name << " has " << mesh.indices.size() << " faces and " << mesh.vertices.size() << " vertices." << std::endl;
+ libnest2d::opt::metaloop::apply([&mesh, i, &results, &funcnames](int N, auto &e) {
+ MeasureResult r = e.second(mesh);
+ funcnames[N] = e.first;
+ results[i][N] = r;
+ }, IndexFunctions);
+ }
+
+ std::string outfilename = "out.csv";
+ std::fstream outfile;
+ if (argc > 1) {
+ outfilename = argv[1];
+ outfile.open(outfilename, std::fstream::out);
+ std::cout << outfilename << " will be used" << std::endl;
+ }
+
+ std::ostream &out = outfile.is_open() ? outfile : std::cout;
+
+ for (size_t m = 0; m < std::size(MeasureResult::Names); ++m) {
+ out << MeasureResult::Names[m] << "\n";
+ out << std::endl;
+ out << "model;" ;
+ for (const std::string &funcname : funcnames) {
+ out << funcname << ";";
+ }
+
+ out << std::endl;
+
+ for (size_t i = 0; i < std::size(ToMeasure); ++i) {
+ const auto &result_row = results[i];
+ const std::string &name = ToMeasure[i].first;
+ out << name << ";";
+ for (auto &r : result_row)
+ out << r.measurements[m] << ";";
+
+ out << std::endl;
+ }
+ }
+
+ return 0;
+}