Skip to content

Commit

Permalink
Merge pull request #27 from gcherchi/new-release
Browse files Browse the repository at this point in the history
New release with bugfix
  • Loading branch information
gcherchi authored Nov 27, 2023
2 parents 72339fd + b53b69f commit 9b38a49
Show file tree
Hide file tree
Showing 4 changed files with 4,747 additions and 85 deletions.
2 changes: 2 additions & 0 deletions arrangements/code/processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ inline double computeMultiplier(const std::vector<double> &coords)
int e = static_cast<int>(std::round(std::log2(div)));
double multiplier = (e >= 0) ? static_cast<double>(1 << e) : (1.0 / (1 << (-1 * e)));

if(multiplier < 0) multiplier = 1; // temporary fix

return multiplier;
}

Expand Down
105 changes: 27 additions & 78 deletions code/booleans.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
inline void customBooleanPipeline(std::vector<genericPoint*>& arr_verts, std::vector<uint>& arr_in_tris,
std::vector<uint>& arr_out_tris, std::vector<std::bitset<NBIT>>& arr_in_labels,
std::vector<DuplTriInfo>& dupl_triangles, Labels& labels,
std::vector<phmap::flat_hash_set<uint>>& patches, cinolib::FOctree& octree,
std::vector<phmap::flat_hash_set<uint>>& patches, cinolib::Octree& octree,
const BoolOp &op, std::vector<double> &bool_coords, std::vector<uint> &bool_tris,
std::vector< std::bitset<NBIT>> &bool_labels)
{
Expand All @@ -54,7 +54,7 @@ inline void customBooleanPipeline(std::vector<genericPoint*>& arr_verts, std::ve
addDuplicateTrisInfoInStructures(dupl_triangles, arr_in_tris, arr_in_labels, octree);

// parse patches with octree and rays
cinolib::vec3d max_coords(octree.nodes[0].bbox.max.x() +0.5, octree.nodes[0].bbox.max.y() +0.5, octree.nodes[0].bbox.max.z() +0.5);
cinolib::vec3d max_coords(octree.root->bbox.max.x() +0.5, octree.root->bbox.max.y() +0.5, octree.root->bbox.max.z() +0.5);
computeInsideOut(tm, patches, octree, arr_verts, arr_in_tris, arr_in_labels, max_coords, labels);

// booleand operations
Expand All @@ -76,6 +76,10 @@ inline void customBooleanPipeline(std::vector<genericPoint*>& arr_verts, std::ve
computeFinalExplicitResult(tm, labels, num_tris_in_final_solution, bool_coords, bool_tris, bool_labels, true);
}

extern int arr_time;
extern int bool_time;
extern std::vector<std::string> files;

inline void booleanPipeline(const std::vector<double> &in_coords, const std::vector<uint> &in_tris,
const std::vector<uint> &in_labels, const BoolOp &op, std::vector<double> &bool_coords,
std::vector<uint> &bool_tris, std::vector< std::bitset<NBIT> > &bool_labels)
Expand All @@ -89,7 +93,7 @@ inline void booleanPipeline(const std::vector<double> &in_coords, const std::vec
std::vector<DuplTriInfo> dupl_triangles;
Labels labels;
std::vector<phmap::flat_hash_set<uint>> patches;
cinolib::FOctree octree; // built with arr_in_tris and arr_in_labels
cinolib::Octree octree; // built with arr_in_tris and arr_in_labels

customArrangementPipeline(in_coords, in_tris, in_labels, arr_in_tris, arr_in_labels, arena, arr_verts,
arr_out_tris, labels, octree, dupl_triangles);
Expand All @@ -98,13 +102,15 @@ inline void booleanPipeline(const std::vector<double> &in_coords, const std::vec
patches, octree, op, bool_coords, bool_tris, bool_labels);
}



//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

/* a custom arrangement pipeline in witch we can expose the octree used to find the starting intersection list */
inline void customArrangementPipeline(const std::vector<double> &in_coords, const std::vector<uint> &in_tris, const std::vector<uint> &in_labels,
std::vector<uint> &arr_in_tris, std::vector< std::bitset<NBIT>> &arr_in_labels,
point_arena& arena, std::vector<genericPoint *> &vertices, std::vector<uint> &arr_out_tris, Labels &labels,
cinolib::FOctree &octree, std::vector<DuplTriInfo> &dupl_triangles)
cinolib::Octree &octree, std::vector<DuplTriInfo> &dupl_triangles)
{
arr_in_labels.resize(in_labels.size());
std::bitset<NBIT> mask;
Expand Down Expand Up @@ -317,69 +323,11 @@ inline void customDetectIntersections(const TriangleSoup &ts, std::vector<std::p
remove_duplicates(intersection_list);
}

inline void customDetectIntersections(const TriangleSoup &ts, std::vector<std::pair<uint, uint> > &intersection_list, cinolib::FOctree &o)
{
std::vector<cinolib::vec3d> verts(ts.numVerts());

for(uint v_id = 0; v_id < ts.numVerts(); v_id++)
verts[v_id] = cinolib::vec3d(ts.vertX(v_id), ts.vertY(v_id), ts.vertZ(v_id));

o.build_from_vectors(verts, ts.trisVector(), 100, 100, true);

struct ShewchukCache
{
double minor[3];
double perm[3];
};
std::vector<ShewchukCache> cache(o.items.size());
std::vector<bool> cached(o.items.size(),false);

intersection_list.reserve(ts.numTris());

auto leaves = o.get_leaves();

tbb::spin_mutex mutex;
tbb::parallel_for((uint)0, (uint)leaves.size(), [&](uint i)
{
auto leaf = &o.nodes[leaves[i]];
if(leaf->item_indices.empty()) return;
for(uint j=0; j<leaf->item_indices.size()-1; ++j)
for(uint k=j+1; k<leaf->item_indices.size(); ++k)
{
uint tid0 = leaf->item_indices[j];
uint tid1 = leaf->item_indices[k];
auto& T0 = o.items[tid0];
auto& T1 = o.items[tid1];
if(T0.aabb.intersects_box(T1.aabb)) // early reject based on AABB intersection
{
// update cache, if needed
if(!cached[tid0])
{
cinolib::orient3d_get_minors(T0.v[0].ptr(), T0.v[1].ptr(), T0.v[2].ptr(), cache[tid0].minor, cache[tid0].perm);
cached[tid0] = true;
}
if(!cached[tid1])
{
cinolib::orient3d_get_minors(T1.v[0].ptr(), T1.v[1].ptr(), T1.v[2].ptr(), cache[tid1].minor, cache[tid1].perm);
cached[tid1] = true;
}
if(o.intersects_triangle(T0.v,T1.v,true,
cache[tid0].minor, cache[tid0].perm,
cache[tid1].minor, cache[tid1].perm)) // precise check (exact if CINOLIB_USES_EXACT_PREDICATES is defined)
{
std::lock_guard<tbb::spin_mutex> guard(mutex);
intersection_list.push_back(cinolib::unique_pair(tid0,tid1));
}
}
}
});
remove_duplicates(intersection_list);
}

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

inline void addDuplicateTrisInfoInStructures(const std::vector<DuplTriInfo> &dupl_tris, std::vector<uint> &in_tris,
std::vector<std::bitset<NBIT>> &in_labels, cinolib::FOctree &octree)
std::vector<std::bitset<NBIT>> &in_labels, cinolib::Octree &octree)
{
for(auto &item : dupl_tris)
{
Expand All @@ -390,7 +338,7 @@ inline void addDuplicateTrisInfoInStructures(const std::vector<DuplTriInfo> &dup
std::bitset<NBIT> new_label;
new_label[item.l_id] = true;

const cinolib::Triangle &orig_tri = octree.items.at(item.t_id);
const cinolib::Triangle *orig_tri = dynamic_cast<const cinolib::Triangle*>(octree.items.at(item.t_id));

uint new_t_id = in_tris.size() / 3;

Expand All @@ -399,14 +347,14 @@ inline void addDuplicateTrisInfoInStructures(const std::vector<DuplTriInfo> &dup
in_tris.push_back(v0_id);
in_tris.push_back(v1_id);
in_tris.push_back(v2_id);
octree.items.emplace_back(new_t_id, orig_tri.v[0], orig_tri.v[1], orig_tri.v[2]);
octree.items.push_back(new cinolib::Triangle(new_t_id, orig_tri->v[0], orig_tri->v[1], orig_tri->v[2]));
}
else
{
in_tris.push_back(v0_id);
in_tris.push_back(v2_id);
in_tris.push_back(v1_id);
octree.items.emplace_back(new_t_id, orig_tri.v[0], orig_tri.v[2], orig_tri.v[1]);
octree.items.push_back(new cinolib::Triangle(new_t_id, orig_tri->v[0], orig_tri->v[1], orig_tri->v[2]));
}

in_labels.push_back(new_label); // we add the new_label to the new_triangle
Expand Down Expand Up @@ -593,45 +541,46 @@ inline void findRayEndpoints(const FastTrimesh &tm, const phmap::flat_hash_set<u
}

std::cout << "WARNING: the arrangement contains a fully implicit patch that requires exact rationals for evaluation. This version of the code does not support rationals, therefore the output result may contain open boundaries." << std::endl;

std::exit(EXIT_FAILURE);
}

//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

inline bool intersects_box(const cinolib::FOctree& tree, const cinolib::AABB & b, phmap::flat_hash_set<uint> & ids)
inline bool intersects_box(const cinolib::Octree& tree, const cinolib::AABB & b, phmap::flat_hash_set<uint> & ids)
{
auto root = &tree.nodes[0];
auto root = tree.root;
auto& items = tree.items;

std::stack<const cinolib::FOctreeNode*> lifo;
std::stack<cinolib::OctreeNode*> lifo;
if(root && root->bbox.intersects_box(b))
{
lifo.push(root);
}

while(!lifo.empty())
{
const cinolib::FOctreeNode *node = lifo.top();
{
cinolib::OctreeNode *node = lifo.top();
lifo.pop();
assert(node->bbox.intersects_box(b));

if(node->is_inner)
{
for(int i=0; i<8; ++i)
for(int i = 0; i < 8; ++i)
{
auto child = &tree.nodes[node->start + i];
if(child->bbox.intersects_box(b))
if(node->children[i]->bbox.intersects_box(b))
{
lifo.push(child);
lifo.push(node->children[i]);
}
}
}
else
{
for(uint i : node->item_indices)
{
if(items[i].aabb.intersects_box(b))
if(items.at(i)->aabb.intersects_box(b))
{
ids.insert(items[i].id);
ids.insert(items.at(i)->id);
}
}
}
Expand All @@ -640,7 +589,7 @@ inline bool intersects_box(const cinolib::FOctree& tree, const cinolib::AABB & b
return !ids.empty();
}

inline void computeInsideOut(const FastTrimesh &tm, const std::vector<phmap::flat_hash_set<uint>> &patches, const cinolib::FOctree &octree,
inline void computeInsideOut(const FastTrimesh &tm, const std::vector<phmap::flat_hash_set<uint>> &patches, const cinolib::Octree &octree,
const std::vector<genericPoint *> &in_verts, const std::vector<uint> &in_tris,
const std::vector<std::bitset<NBIT>> &in_labels, const cinolib::vec3d &max_coords, Labels &labels)
{
Expand Down
13 changes: 6 additions & 7 deletions code/booleans.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#include "triangle_soup.h"
#include "intersection_classification.h"
#include "triangulation.h"
#include "foctree.h"
#include <cinolib/octree.h>

#include <bitset>

Expand Down Expand Up @@ -100,7 +100,7 @@ struct less_than_GP_on_Z // lessThan GenericPoint along Z
inline void customBooleanPipeline(std::vector<genericPoint*>& arr_verts, std::vector<uint>& arr_in_tris,
std::vector<uint>& arr_out_tris, std::vector<std::bitset<NBIT>>& arr_in_labels,
std::vector<DuplTriInfo>& dupl_triangles, Labels& labels,
std::vector<phmap::flat_hash_set<uint>>& patches, cinolib::FOctree& octree,
std::vector<phmap::flat_hash_set<uint>>& patches, cinolib::Octree& octree,
const BoolOp &op, std::vector<double> &bool_coords, std::vector<uint> &bool_tris,
std::vector< std::bitset<NBIT>> &bool_labels);

Expand All @@ -112,17 +112,16 @@ inline void booleanPipeline(const std::vector<double> &in_coords, const std::vec
inline void customArrangementPipeline(const std::vector<double> &in_coords, const std::vector<uint> &in_tris, const std::vector<uint> &in_labels,
std::vector<uint> &arr_in_tris, std::vector< std::bitset<NBIT>> &arr_in_labels,
point_arena& arena, std::vector<genericPoint *> &vertices, std::vector<uint> &arr_out_tris, Labels &labels,
cinolib::FOctree &octree, std::vector<DuplTriInfo> &dupl_triangles);
cinolib::Octree &octree, std::vector<DuplTriInfo> &dupl_triangles);

inline void customRemoveDegenerateAndDuplicatedTriangles(const std::vector<genericPoint*> &verts, std::vector<uint> &tris,
std::vector< std::bitset<NBIT> > &labels, std::vector<DuplTriInfo> &dupl_triangles,
bool parallel);

inline void customDetectIntersections(const TriangleSoup &ts, std::vector<std::pair<uint, uint> > &intersection_list, cinolib::Octree &o);
inline void customDetectIntersections(const TriangleSoup &ts, std::vector<std::pair<uint, uint> > &intersection_list, cinolib::FOctree &o);

inline void addDuplicateTrisInfoInStructures(const std::vector<DuplTriInfo> &dupl_tris, std::vector<uint> &in_tris,
std::vector<std::bitset<NBIT>> &in_labels, cinolib::FOctree &octree);
std::vector<std::bitset<NBIT>> &in_labels, cinolib::Octree &octree);

inline void computeAllPatches(FastTrimesh &tm, const Labels &labels, std::vector<phmap::flat_hash_set<uint>> &patches, bool parallel);

Expand All @@ -131,9 +130,9 @@ inline void computeSinglePatch(FastTrimesh &tm, uint seed_t, const Labels &label

inline void findRayEndpoints(const FastTrimesh &tm, const phmap::flat_hash_set<uint> &patch, const cinolib::vec3d &max_coords, Ray &ray);

inline bool intersects_box(const cinolib::FOctree& tree, const cinolib::AABB & b, phmap::flat_hash_set<uint> & ids);
inline bool intersects_box(const cinolib::Octree& tree, const cinolib::AABB & b, phmap::flat_hash_set<uint> & ids);

inline void computeInsideOut(const FastTrimesh &tm, const std::vector<phmap::flat_hash_set<uint>> &patches, const cinolib::FOctree &octree,
inline void computeInsideOut(const FastTrimesh &tm, const std::vector<phmap::flat_hash_set<uint>> &patches, const cinolib::Octree &octree,
const std::vector<genericPoint *> &in_verts, const std::vector<uint> &in_tris,
const std::vector<std::bitset<NBIT>> &in_labels, const cinolib::vec3d &max_coords, Labels &labels);

Expand Down
Loading

0 comments on commit 9b38a49

Please sign in to comment.