ENH: Change MCUT version to 1.2.0

https://github.com/cutdigital/mcut/releases/tag/v1.2.0

Change-Id: I6eb053986c6155333bf399b4cfd8c634e6fafefa
(cherry picked from commit 110a088a5da0b9f4409e56fe3e1c2d8516691856)
This commit is contained in:
jianjia.ma
2023-06-20 11:36:40 +08:00
committed by Lane.Wei
parent db44de9dbe
commit de29527d5b
9 changed files with 1208 additions and 372 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -33,8 +33,8 @@
#include "mcut/internal/hmesh.h"
#include "mcut/internal/kernel.h"
#include "mcut/internal/math.h"
#include "mcut/internal/utils.h"
#include "mcut/internal/timer.h"
#include "mcut/internal/utils.h"
#ifndef LICENSE_PURCHASED
#define lmsg() printf("NOTE: MCUT is copyrighted and may not be sold or included in commercial products without a license.\n")
@@ -656,8 +656,15 @@ hmesh_t extract_connected_components(
// structure "mesh" to the (local) connected-component
//
//#define EXTRACT_SEAM_HALFEDGES
#ifdef EXTRACT_SEAM_HALFEDGES
std::vector<halfedge_descriptor_t> cc_seam_halfedges;
const std::vector<halfedge_descriptor_t>& halfedges_on_face = mesh.get_halfedges_around_face(fd);
bool prev_vertex_belonged_to_seam = false; // previous in face
#endif
// for each vertex around the current face
const std::vector<vertex_descriptor_t> vertices_around_face = mesh.get_vertices_around_face(fd);
const std::vector<vertex_descriptor_t> vertices_around_face = mesh.get_vertices_around_face(fd); // order according to "halfedges_on_face" (targets)
for (std::vector<vertex_descriptor_t>::const_iterator face_vertex_iter = vertices_around_face.cbegin();
face_vertex_iter != vertices_around_face.cend();
@@ -683,9 +690,31 @@ hmesh_t extract_connected_components(
// check if we need to save vertex as being a seam vertex
// std::vector<bool>::const_iterator fiter = mesh_vertex_to_seam_flag.find(*face_vertex_iter);
bool is_seam_vertex = (size_t)(*face_vertex_iter) < mesh_vertex_to_seam_flag.size() && SAFE_ACCESS(mesh_vertex_to_seam_flag, *face_vertex_iter); //(size_t)(*face_vertex_iter) < mesh_vertex_to_seam_flag.size(); //fiter != mesh_vertex_to_seam_flag.cend() && fiter->second == true;
if (is_seam_vertex) {
cc_seam_vertices.push_back(cc_descriptor);
#ifdef EXTRACT_SEAM_HALFEDGES
const uint32_t face_vertex_idx = std::distance(vertices_around_face.cbegin(), face_vertex_iter);
const bool is_first_face_vertex = (face_vertex_idx == 0);
bool have_seam_halfedge = prev_vertex_belonged_to_seam;
if (is_first_face_vertex) {
vd_t last_vtx_descr = (*(vertices_around_face.end() - 1));
bool last_vertex_is_seam_vertex = (size_t)(last_vtx_descr) < mesh_vertex_to_seam_flag.size() && SAFE_ACCESS(mesh_vertex_to_seam_flag, last_vtx_descr); //(size_t)(*face_vertex_iter) < mesh_vertex_to_seam_flag.size(); //fiter != mesh_vertex_to_seam_flag.cend() && fiter->second == true;
have_seam_halfedge = (last_vertex_is_seam_vertex);
}
if (have_seam_halfedge) {
const halfedge_descriptor_t seam_he = SAFE_ACCESS(halfedges_on_face, face_vertex_idx); // number of halfedge == number of vertices in face
cc_seam_halfedges.push_back(seam_he);
}
#endif
}
#ifdef EXTRACT_SEAM_HALFEDGES
prev_vertex_belonged_to_seam = is_seam_vertex;
#endif
}
}
} // for (face_array_iterator_t face_iter = mesh.faces_begin(); face_iter != mesh.faces_end(); ++face_iter)
@@ -1453,13 +1482,13 @@ void update_neighouring_ps_iface_m0_edge_list(
typedef std::vector<hd_t> traced_polygon_t;
bool mesh_is_closed(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
#if 0 //defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
thread_pool& scheduler,
#endif
const hmesh_t& mesh)
{
bool all_halfedges_incident_to_face = true;
#if 0 //defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
#if 0 // defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
{
printf("mesh=%d\n", (int)mesh.number_of_halfedges());
all_halfedges_incident_to_face = parallel_find_if(
@@ -1556,7 +1585,7 @@ void dispatch(output_t& output, const input_t& input)
TIMESTACK_PUSH("Check source mesh is closed");
const bool sm_is_watertight = mesh_is_closed(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
#if 0 //defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
*input.scheduler,
#endif
sm);
@@ -1565,7 +1594,7 @@ void dispatch(output_t& output, const input_t& input)
TIMESTACK_PUSH("Check cut mesh is closed");
const bool cm_is_watertight = mesh_is_closed(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
#if 0// defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
*input.scheduler,
#endif
cs);
@@ -1763,7 +1792,7 @@ void dispatch(output_t& output, const input_t& input)
///////////////////////////////////////////////////////////////////////////
std::unordered_map<ed_t, std::vector<fd_t>> ps_edge_face_intersection_pairs;
TIMESTACK_PUSH("Prepare edge-to-face pairs");
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
@@ -1971,7 +2000,7 @@ void dispatch(output_t& output, const input_t& input)
//
// build bounding boxes for each intersecting edge
//
#if 1
TIMESTACK_PUSH("Build edge bounding boxes");
// http://gamma.cs.unc.edu/RTRI/i3d08_RTRI.pdf
@@ -2146,7 +2175,7 @@ void dispatch(output_t& output, const input_t& input)
// assuming each edge will produce a new vertex
m0.reserve_for_additional_elements((std::uint32_t)ps_edge_face_intersection_pairs.size());
#endif
TIMESTACK_PUSH("Compute intersecting face properties");
// compute/extract geometry properties of each tested face
//--------------------------------------------------------
@@ -2167,6 +2196,8 @@ void dispatch(output_t& output, const input_t& input)
OutputStorageTypesTuple;
typedef std::map<fd_t, std::vector<fd_t>>::const_iterator InputStorageIteratorType;
std::atomic<int> potentially_intersecting_face_with_zero_area(-1); // did any errors occur (e.g. found a face with zero area)
auto fn_compute_intersecting_face_properties = [&](InputStorageIteratorType block_start_, InputStorageIteratorType block_end_) -> OutputStorageTypesTuple {
OutputStorageTypesTuple output_res;
std::unordered_map<fd_t, vec3>& ps_tested_face_to_plane_normal_LOCAL = std::get<0>(output_res);
@@ -2196,6 +2227,10 @@ void dispatch(output_t& output, const input_t& input)
tested_face_plane_param_d,
tested_face_vertices.data(),
(int)tested_face_vertices.size());
if (squared_length(tested_face_plane_normal) == 0) {
potentially_intersecting_face_with_zero_area.store((int)tested_faces_iter->first, std::memory_order_release);
}
}
return output_res;
};
@@ -2226,6 +2261,10 @@ void dispatch(output_t& output, const input_t& input)
OutputStorageTypesTuple future_res = f.get();
if (potentially_intersecting_face_with_zero_area.load(std::memory_order_acquire) >= 0) {
break; // stop there was a runtime error
}
std::unordered_map<fd_t, vec3>& ps_tested_face_to_plane_normal_FUTURE = std::get<0>(future_res);
std::unordered_map<fd_t, double>& ps_tested_face_to_plane_normal_d_param_FUTURE = std::get<1>(future_res);
std::unordered_map<fd_t, int>& ps_tested_face_to_plane_normal_max_comp_FUTURE = std::get<2>(future_res);
@@ -2248,6 +2287,19 @@ void dispatch(output_t& output, const input_t& input)
ps_tested_face_to_vertices_FUTURE.cend());
}
const int tmp_local = potentially_intersecting_face_with_zero_area.load(std::memory_order_acquire);
if (tmp_local >= 0) {
const bool is_cutmesh_face = (tmp_local > sm_face_count);
// if "tmp_local" > srcMeshFaceCount then "tmp_local" is a cut-mesh face with id="tmp_local-srcMeshFaceCount"
const std::string msh_name = is_cutmesh_face ? "cut-mesh" : "source-mesh";
// index/descriptor in the _kernel_ input mesh (note the stress on kernel since frontend might modify user-provided mesh)
const fd_t bad_face_desr = fd_t(is_cutmesh_face ? (tmp_local - sm_face_count) : tmp_local);
lg.set_reason_for_failure("face f" + std::to_string(bad_face_desr) + " of " + msh_name + " is degenerate (has zero area)");
output.status.store(is_cutmesh_face ? status_t::INVALID_CUT_MESH : status_t::INVALID_SRC_MESH, std::memory_order_release);
return; // stop there was a runtime error
}
} // end of parallel scope
#else
// for each face that is to be tested for intersection
@@ -2277,6 +2329,16 @@ void dispatch(output_t& output, const input_t& input)
tested_face_plane_param_d,
tested_face_vertices.data(),
(int)tested_face_vertices.size());
if (squared_length(tested_face_plane_normal) == 0) {
const int tmp_local = (int)tested_faces_iter->first;
const bool is_cutmesh_face = (tmp_local > sm_face_count);
const std::string msh_name = is_cutmesh_face ? "cut-mesh" : "source-mesh";
const fd_t bad_face_desr = fd_t(is_cutmesh_face ? (tmp_local - sm_face_count) : tmp_local);
lg.set_reason_for_failure("face f" + std::to_string(bad_face_desr) + " of " + msh_name + " is degenerate (has zero area)");
output.status = (is_cutmesh_face ? status_t::INVALID_CUT_MESH : status_t::INVALID_SRC_MESH);
return;
}
}
}
#endif
@@ -3258,7 +3320,7 @@ void dispatch(output_t& output, const input_t& input)
std::vector<hd_t> // list of halfedges whose target is the intersection point
>
ivtx_to_incoming_hlist;
#if 1 // used for debugging colinearity bug, which occur when we have poly with eg. > 3
#if 0 // used for debugging colinearity bug, which occur when we have poly with eg. > 3
// vertices where at least 3 more-or-less are colinear but exact predicate says no.
for (std::map<pair<fd_t>, std::vector<vd_t>>::const_iterator cutpath_edge_creation_info_iter = cutpath_edge_creation_info.cbegin();
cutpath_edge_creation_info_iter != cutpath_edge_creation_info.cend();
@@ -7704,8 +7766,8 @@ void dispatch(output_t& output, const input_t& input)
//
if (proceed_to_fill_holes == false) {
return; // exit
printf("[mcut-kernel]: detected a configuration that does not permit filling holes. input-mesh verification advised.\n");
return; // done
}
if (false == (input.keep_fragments_below_cutmesh || //

View File

@@ -589,9 +589,9 @@
return x;
}();
matrix_t<double> I(3, 3); // 3x3 identity
matrix_t<double> I(3, 3); // 3x3 identity with reflection
I(0, 0) = 1.0;
I(1, 1) = 1.0;
I(1, 1) = -1.0;
I(2, 2) = 1.0;
matrix_t<double> R = I;

View File

@@ -123,7 +123,7 @@ MCAPI_ATTR McResult MCAPI_CALL mcGetDebugMessageLog(
per_thread_api_log_str = "count must be > 0";
} else if (bufSize == 0) {
per_thread_api_log_str = "bufSize must be > 0";
} else if (numFetched == nullptr) {
} else if (numFetched == nullptr) {
per_thread_api_log_str = "numFetched undef (NULL)";
} else {
try {
@@ -198,7 +198,11 @@ MCAPI_ATTR McResult MCAPI_CALL mcGetInfo(const McContext context, McFlags info,
per_thread_api_log_str = "context ptr (param0) undef (NULL)";
} else if (bytes != 0 && pMem == nullptr) {
per_thread_api_log_str = "invalid specification (param2 & param3)";
} else if (false == (info == MC_CONTEXT_FLAGS || info == MC_MAX_DEBUG_MESSAGE_LENGTH)) // check all possible values
} else if (false == //
(info == MC_CONTEXT_FLAGS || //
info == MC_CONTEXT_MAX_DEBUG_MESSAGE_LENGTH || //
info == MC_CONTEXT_GENERAL_POSITION_ENFORCEMENT_CONSTANT || //
info == MC_CONTEXT_GENERAL_POSITION_ENFORCEMENT_ATTEMPTS)) // check all possible values
{
per_thread_api_log_str = "invalid info flag val (param1)";
} else if ((info == MC_CONTEXT_FLAGS) && (pMem != nullptr && bytes != sizeof(McFlags))) {
@@ -221,6 +225,50 @@ MCAPI_ATTR McResult MCAPI_CALL mcGetInfo(const McContext context, McFlags info,
return return_value;
}
MCAPI_ATTR McResult MCAPI_CALL mcBindState(
const McContext context,
McFlags stateInfo,
McSize bytes,
const McVoid* pMem)
{
McResult return_value = McResult::MC_NO_ERROR;
per_thread_api_log_str.clear();
if (context == nullptr) {
per_thread_api_log_str = "context ptr (param0) undef (NULL)";
} else if (bytes == 0) {
per_thread_api_log_str = "invalid bytes ";
} else if (pMem == nullptr) {
per_thread_api_log_str = "invalid ptr (pMem)";
} else if (false == //
(stateInfo == MC_CONTEXT_GENERAL_POSITION_ENFORCEMENT_CONSTANT || //
stateInfo == MC_CONTEXT_GENERAL_POSITION_ENFORCEMENT_ATTEMPTS ||//
stateInfo == MC_CONTEXT_CONNECTED_COMPONENT_FACE_WINDING_ORDER)) // check all possible values
{
per_thread_api_log_str = "invalid stateInfo ";
} else if (
((stateInfo == MC_CONTEXT_GENERAL_POSITION_ENFORCEMENT_CONSTANT) && bytes != sizeof(McDouble)) || //
((stateInfo == MC_CONTEXT_GENERAL_POSITION_ENFORCEMENT_ATTEMPTS) && bytes != sizeof(McUint32))|| //
((stateInfo == MC_CONTEXT_CONNECTED_COMPONENT_FACE_WINDING_ORDER) && bytes != sizeof(McConnectedComponentFaceWindingOrder))) {
per_thread_api_log_str = "invalid num bytes"; // leads to e.g. "out of bounds" memory access during memcpy
} else {
try {
bind_state_impl(context, stateInfo, bytes, pMem);
}
CATCH_POSSIBLE_EXCEPTIONS(per_thread_api_log_str);
}
if (!per_thread_api_log_str.empty()) {
std::fprintf(stderr, "%s(...) -> %s\n", __FUNCTION__, per_thread_api_log_str.c_str());
if (return_value == McResult::MC_NO_ERROR) // i.e. problem with basic local parameter checks
{
return_value = McResult::MC_INVALID_VALUE;
}
}
return return_value;
}
MCAPI_ATTR McResult MCAPI_CALL mcCreateUserEvent(
McEvent* event,
McContext context)
@@ -396,10 +444,7 @@ MCAPI_ATTR McResult MCAPI_CALL mcEnqueueDispatch(
const McEvent* pEventWaitList,
McEvent* pEvent)
{
TIMESTACK_RESET(); // reset tracking vars
SCOPED_TIMER(__FUNCTION__);
McResult return_value = McResult::MC_NO_ERROR;
per_thread_api_log_str.clear();
@@ -528,6 +573,89 @@ MCAPI_ATTR McResult MCAPI_CALL mcDispatch(
return return_value;
}
MCAPI_ATTR McResult MCAPI_CALL mcEnqueueDispatchPlanarSection(
const McContext context,
McFlags dispatchFlags,
const McVoid* pSrcMeshVertices,
const uint32_t* pSrcMeshFaceIndices,
const uint32_t* pSrcMeshFaceSizes,
uint32_t numSrcMeshVertices,
uint32_t numSrcMeshFaces,
const McDouble* pNormalVector,
const McDouble sectionOffset,
uint32_t numEventsInWaitlist,
const McEvent* pEventWaitList,
McEvent* pEvent)
{
McResult return_value = McResult::MC_NO_ERROR;
per_thread_api_log_str.clear();
if (context == nullptr) {
per_thread_api_log_str = "context ptr (param0) undef (NULL)";
} else if (dispatchFlags == 0) {
per_thread_api_log_str = "dispatch flags unspecified";
} else if ((dispatchFlags & MC_DISPATCH_REQUIRE_THROUGH_CUTS) && //
(dispatchFlags & MC_DISPATCH_FILTER_FRAGMENT_LOCATION_UNDEFINED)) {
// The user states that she does not want a partial cut but yet also states that she
// wants to keep fragments with partial cuts. These two options are mutually exclusive!
per_thread_api_log_str = "use of mutually-exclusive flags: MC_DISPATCH_REQUIRE_THROUGH_CUTS & MC_DISPATCH_FILTER_FRAGMENT_LOCATION_UNDEFINED";
} else if ((dispatchFlags & MC_DISPATCH_VERTEX_ARRAY_FLOAT) == 0 && (dispatchFlags & MC_DISPATCH_VERTEX_ARRAY_DOUBLE) == 0) {
per_thread_api_log_str = "dispatch vertex aray type unspecified";
} else if (pSrcMeshVertices == nullptr) {
per_thread_api_log_str = "source-mesh vertex-position array ptr undef (NULL)";
} else if (numSrcMeshVertices < 3) {
per_thread_api_log_str = "invalid source-mesh vertex count";
} else if (pSrcMeshFaceIndices == nullptr) {
per_thread_api_log_str = "source-mesh face-index array ptr undef (NULL)";
} /*else if (pSrcMeshFaceSizes == nullptr) {
per_thread_api_log_str = "source-mesh face-size array ptr undef (NULL)";
}*/
else if (numSrcMeshFaces < 1) {
per_thread_api_log_str = "invalid source-mesh vertex count";
} else if (pNormalVector == nullptr) {
per_thread_api_log_str = "normal vector ptr undef (NULL)";
} else if (pNormalVector[0] == 0.0 && pNormalVector[1] == 0.0 && pNormalVector[2] == 0.0) {
per_thread_api_log_str = "invalid normal vector (zero vector)";
}else if (sectionOffset <= 0 && sectionOffset >= 1.0) {
per_thread_api_log_str = "invalid section offset parameter";
} else if (pEventWaitList == nullptr && numEventsInWaitlist > 0) {
per_thread_api_log_str = "invalid event waitlist ptr (NULL)";
} else if (pEventWaitList != nullptr && numEventsInWaitlist == 0) {
per_thread_api_log_str = "invalid event waitlist size (zero)";
} else if (pEventWaitList == nullptr && numEventsInWaitlist == 0 && pEvent == nullptr) {
per_thread_api_log_str = "invalid event ptr (zero)";
} else {
try {
dispatch_planar_section_impl(
context,
dispatchFlags,
pSrcMeshVertices,
pSrcMeshFaceIndices,
pSrcMeshFaceSizes,
numSrcMeshVertices,
numSrcMeshFaces,
pNormalVector,
sectionOffset,
numEventsInWaitlist,
pEventWaitList,
pEvent);
}
CATCH_POSSIBLE_EXCEPTIONS(per_thread_api_log_str);
}
if (!per_thread_api_log_str.empty()) {
std::fprintf(stderr, "%s(...) -> %s\n", __FUNCTION__, per_thread_api_log_str.c_str());
if (return_value == McResult::MC_NO_ERROR) // i.e. problem with basic local parameter checks
{
return_value = McResult::MC_INVALID_VALUE;
}
}
return return_value;
}
MCAPI_ATTR McResult MCAPI_CALL mcEnqueueGetConnectedComponents(
const McContext context,
const McConnectedComponentType connectedComponentType,

View File

@@ -4,8 +4,8 @@
#include "mcut/internal/hmesh.h"
#include "mcut/internal/kernel.h"
#include "mcut/internal/math.h"
#include "mcut/internal/utils.h"
#include "mcut/internal/timer.h"
#include "mcut/internal/utils.h"
#include <numeric> // std::partial_sum
#include <queue>
@@ -13,8 +13,8 @@
// If the inputs are found to not be in general position, then we perturb the
// cut-mesh by this constant (scaled by bbox diag times a random variable [0.1-1.0]).
const double GENERAL_POSITION_ENFORCMENT_CONSTANT = 1e-4;
const int MAX_PERTUBATION_ATTEMPTS = 1 << 3;
// const double GENERAL_POSITION_ENFORCMENT_CONSTANT = 1e-4;
// const int MAX_PERTUBATION_ATTEMPTS = 1 << 3;
// this function converts an index array mesh (e.g. as recieved by the dispatch
// function) into a halfedge mesh representation for the kernel backend.
@@ -111,7 +111,7 @@ bool client_input_arrays_to_hmesh(
#if 0
std::partial_sum(partial_sums.begin(), partial_sums.end(), partial_sums.data());
#else
parallel_partial_sum(context_ptr->get_shared_compute_threadpool() , partial_sums.begin(), partial_sums.end());
parallel_partial_sum(context_ptr->get_shared_compute_threadpool(), partial_sums.begin(), partial_sums.end());
#endif
{
typedef std::vector<uint32_t>::const_iterator InputStorageIteratorType;
@@ -131,7 +131,7 @@ bool client_input_arrays_to_hmesh(
if (face_vertex_count < 3) {
int zero = (int)McResult::MC_NO_ERROR;
bool exchanged = atm_result.compare_exchange_strong(zero, 1);
bool exchanged = atm_result.compare_exchange_strong(zero, 1, std::memory_order_acq_rel);
if (exchanged) // first thread to detect error
{
context_ptr->dbg_cb( //
@@ -150,14 +150,9 @@ bool client_input_arrays_to_hmesh(
for (int j = 0; j < face_vertex_count; ++j) {
uint32_t idx = ((uint32_t*)pFaceIndices)[faceBaseOffset + j];
MCUT_ASSERT(idx < numVertices);
const vertex_descriptor_t descr(idx);
const bool isDuplicate = std::find(faceVertices.cbegin(), faceVertices.cend(), descr) != faceVertices.cend();
if (isDuplicate) {
if (idx >= numVertices) {
int zero = (int)McResult::MC_NO_ERROR;
bool exchanged = atm_result.compare_exchange_strong(zero, 2);
bool exchanged = atm_result.compare_exchange_strong(zero, 2, std::memory_order_acq_rel);
if (exchanged) // first thread to detect error
{
@@ -166,7 +161,26 @@ bool client_input_arrays_to_hmesh(
MC_DEBUG_TYPE_ERROR,
0,
MC_DEBUG_SEVERITY_HIGH,
"found duplicate vertex in face - " + std::to_string(faceID));
"vertex index out of range in face - " + std::to_string(faceID));
}
break;
}
const vertex_descriptor_t descr(idx);
const bool isDuplicate = std::find(faceVertices.cbegin(), faceVertices.cend(), descr) != faceVertices.cend();
if (isDuplicate) {
int zero = (int)McResult::MC_NO_ERROR;
bool exchanged = atm_result.compare_exchange_strong(zero, 2, std::memory_order_acq_rel);
if (exchanged) // first thread to detect error
{
context_ptr->dbg_cb(
MC_DEBUG_SOURCE_API,
MC_DEBUG_TYPE_ERROR,
0,
MC_DEBUG_SEVERITY_HIGH,
"duplicate vertex index in face f" + std::to_string(faceID));
}
break;
}
@@ -181,7 +195,7 @@ bool client_input_arrays_to_hmesh(
OutputStorageType partial_res;
parallel_for(
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
partial_sums.cbegin(),
partial_sums.cend(),
fn_create_faces,
@@ -203,7 +217,7 @@ bool client_input_arrays_to_hmesh(
MC_DEBUG_TYPE_ERROR, //
0, //
MC_DEBUG_SEVERITY_HIGH, //
"invalid vertices on face - " + std::to_string(faceID));
"invalid face f" + std::to_string(faceID) + " (potentially contains non-manifold edge)");
return false;
}
}
@@ -216,7 +230,7 @@ bool client_input_arrays_to_hmesh(
MCUT_ASSERT(f.valid()); // The behavior is undefined if valid()== false before the call to wait_for
OutputStorageType future_res = f.get();
const int val = atm_result.load();
const int val = atm_result.load(std::memory_order_acquire);
okay = okay && val == 0;
if (!okay) {
continue; // just go on (to next iteration) in order to at-least wait for all tasks to finish before we return to user
@@ -226,10 +240,16 @@ bool client_input_arrays_to_hmesh(
okay = okay && result == true;
}
if (!okay) {
if (!okay || atm_result.load(std::memory_order_acquire) != 0) { // check if worker threads (or master thread) encountered an error
return false;
}
// const int val = atm_result.load(); // check if master thread encountered an error
// okay = (val == 0);
// if (!okay) {
// return false;
//}
// add lastly in order to maintain order
bool result = add_faces(partial_res.first, partial_res.second);
if (!result) {
@@ -254,6 +274,18 @@ bool client_input_arrays_to_hmesh(
for (int j = 0; j < face_vertex_count; ++j) {
uint32_t idx = ((uint32_t*)pFaceIndices)[faceSizeOffset + j];
if (idx >= numVertices) {
context_ptr->dbg_cb(
MC_DEBUG_SOURCE_API,
MC_DEBUG_TYPE_ERROR,
0,
MC_DEBUG_SEVERITY_HIGH,
"vertex index out of range in face - f" + std::to_string(i));
return false;
}
const vertex_descriptor_t descr(idx); // = fIter->second; //vmap[*fIter.first];
const bool isDuplicate = std::find(faceVertices.cbegin(), faceVertices.cend(), descr) != faceVertices.cend();
@@ -345,7 +377,7 @@ bool check_input_mesh(std::shared_ptr<context_t>& context_ptr, const hmesh_t& m)
std::vector<int> cc_to_face_count;
int n = find_connected_components(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
#endif
fccmap, m, cc_to_vertex_count, cc_to_face_count);
@@ -369,7 +401,7 @@ bool check_input_mesh(std::shared_ptr<context_t>& context_ptr, const hmesh_t& m)
MC_DEBUG_TYPE_OTHER,
0,
MC_DEBUG_SEVERITY_NOTIFICATION,
"Vertices (" + std::to_string(fv_count) + ") on face " + std::to_string(*f) + " not coplanar");
"Vertices (" + std::to_string(fv_count) + ") on face f" + std::to_string(*f) + " are not coplanar");
// No need to return false, simply warn. It is difficult to
// know whether the non-coplanarity is severe enough to cause
// confusion when computing intersection points between two
@@ -397,8 +429,11 @@ McResult convert(const status_t& v)
case status_t::INVALID_MESH_INTERSECTION:
result = McResult::MC_INVALID_OPERATION;
break;
case status_t::INVALID_CUT_MESH: case status_t::INVALID_SRC_MESH:
result = McResult::MC_INVALID_VALUE;
break;
default:
std::fprintf(stderr, "[MCUT]: warning - conversion error (McResult=%d)\n", (int)v);
std::fprintf(stderr, "[MCUT]: warning - unknown conversion (McResult=%d)\n", (int)v);
}
return result;
}
@@ -1266,7 +1301,7 @@ extern "C" void preproc(
input_t kernel_input; // kernel/backend inpout
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
kernel_input.scheduler = &context_ptr->get_shared_compute_threadpool() ;
kernel_input.scheduler = &context_ptr->get_shared_compute_threadpool();
#endif
kernel_input.src_mesh = source_hmesh;
@@ -1319,7 +1354,7 @@ extern "C" void preproc(
kernel_input.keep_cutmesh_seam = true;
}
kernel_input.enforce_general_position = (0 != (dispatchFlags & MC_DISPATCH_ENFORCE_GENERAL_POSITION));
kernel_input.enforce_general_position = (0 != (dispatchFlags & MC_DISPATCH_ENFORCE_GENERAL_POSITION)) || (0 != (dispatchFlags & MC_DISPATCH_ENFORCE_GENERAL_POSITION_ABSOLUTE));
// Construct BVHs
// ::::::::::::::
@@ -1332,7 +1367,7 @@ extern "C" void preproc(
std::vector<bounding_box_t<vec3>> source_hmesh_face_aabb_array;
build_oibvh(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
#endif
*source_hmesh.get(), source_hmesh_BVH_aabb_array, source_hmesh_BVH_leafdata_array, source_hmesh_face_aabb_array);
#else
@@ -1404,7 +1439,10 @@ extern "C" void preproc(
int cut_mesh_perturbation_count = 0; // number of times we have perturbed the cut mesh
int kernel_invocation_counter = -1; // number of times we have called the internal dispatch/intersect function
double numerical_perturbation_constant = 0.0; // = cut_hmesh_aabb_diag * GENERAL_POSITION_ENFORCMENT_CONSTANT;
double relative_perturbation_constant = 0.0; // i.e. relative to the bbox diagonal length
// the (translation) vector to hold the values with which we will
// carry out numerical perturbation of the cutting surface
vec3 perturbation(0.0, 0.0, 0.0);
// RESOLVE mesh intersections
// ::::::::::::::::::::::::::
@@ -1420,6 +1458,8 @@ extern "C" void preproc(
// And if floating polygons arise, then we partition the suspected face into two new faces with an edge that is guaranteed to be
// severed during the cut.
do {
TIMESTACK_RESET();
kernel_invocation_counter++;
// here we check the reason (if any) for entering the loop body.
@@ -1440,17 +1480,15 @@ extern "C" void preproc(
kernel_output.status = status_t::SUCCESS;
#endif
// the (translation) vector to hold the values with which we will
// carry out numerical perturbation of the cutting surface
vec3 perturbation(0.0, 0.0, 0.0);
if (general_position_assumption_was_violated) { // i.e. do we need to perturb the cut-mesh?
MCUT_ASSERT(floating_polygon_was_detected == false); // cannot occur at same time! (see kernel)
if (cut_mesh_perturbation_count == MAX_PERTUBATION_ATTEMPTS) {
context_ptr->dbg_cb(MC_DEBUG_SOURCE_KERNEL, MC_DEBUG_TYPE_OTHER, 0, MC_DEBUG_SEVERITY_HIGH, "general position assumption violated!");
context_ptr->dbg_cb(MC_DEBUG_SOURCE_KERNEL, MC_DEBUG_TYPE_OTHER, 0, MC_DEBUG_SEVERITY_MEDIUM, kernel_output.logger.get_reason_for_failure());
if (cut_mesh_perturbation_count == context_ptr->get_general_position_enforcement_constant()) {
context_ptr->dbg_cb(MC_DEBUG_SOURCE_KERNEL, MC_DEBUG_TYPE_OTHER, 0, MC_DEBUG_SEVERITY_HIGH, kernel_output.logger.get_reason_for_failure());
throw std::runtime_error("max perturbation iteratons reached");
}
@@ -1459,14 +1497,14 @@ extern "C" void preproc(
// not intersect at all, which means we need to perturb again.
kernel_input.general_position_enforcement_count = cut_mesh_perturbation_count;
MCUT_ASSERT(numerical_perturbation_constant != double(0.0));
MCUT_ASSERT(relative_perturbation_constant != double(0.0));
static thread_local std::default_random_engine random_engine(1);
static thread_local std::mt19937 mersenne_twister_generator(random_engine());
static thread_local std::uniform_real_distribution<double> uniform_distribution(-1.0, 1.0);
for (int i = 0; i < 3; ++i) {
perturbation[i] = uniform_distribution(mersenne_twister_generator) * numerical_perturbation_constant;
perturbation[i] = uniform_distribution(mersenne_twister_generator) * relative_perturbation_constant;
}
cut_mesh_perturbation_count++;
@@ -1488,7 +1526,12 @@ extern "C" void preproc(
throw std::invalid_argument("invalid cut-mesh arrays");
}
numerical_perturbation_constant = cut_hmesh_aabb_diag * GENERAL_POSITION_ENFORCMENT_CONSTANT;
/*const*/ double perturbation_scalar = cut_hmesh_aabb_diag;
if (dispatchFlags & MC_DISPATCH_ENFORCE_GENERAL_POSITION_ABSOLUTE) {
perturbation_scalar = 1.0;
}
relative_perturbation_constant = perturbation_scalar * context_ptr->get_general_position_enforcement_constant();
kernel_input.cut_mesh = cut_hmesh;
@@ -1498,11 +1541,11 @@ extern "C" void preproc(
cut_hmesh_BVH_leafdata_array.clear();
build_oibvh(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
#endif
*cut_hmesh.get(), cut_hmesh_BVH_aabb_array, cut_hmesh_BVH_leafdata_array, cut_hmesh_face_face_aabb_array, numerical_perturbation_constant);
*cut_hmesh.get(), cut_hmesh_BVH_aabb_array, cut_hmesh_BVH_leafdata_array, cut_hmesh_face_face_aabb_array, relative_perturbation_constant);
#else
cut_hmesh_BVH.buildTree(cut_hmesh, numerical_perturbation_constant);
cut_hmesh_BVH.buildTree(cut_hmesh, relative_perturbation_constant);
#endif
source_or_cut_hmesh_BVH_rebuilt = true;
}
@@ -1539,7 +1582,7 @@ extern "C" void preproc(
source_hmesh_BVH_leafdata_array.clear();
build_oibvh(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
#endif
*source_hmesh.get(),
source_hmesh_BVH_aabb_array,
@@ -1556,15 +1599,15 @@ extern "C" void preproc(
cut_hmesh_BVH_leafdata_array.clear();
build_oibvh(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
#endif
*cut_hmesh.get(),
cut_hmesh_BVH_aabb_array,
cut_hmesh_BVH_leafdata_array,
cut_hmesh_face_face_aabb_array,
numerical_perturbation_constant);
relative_perturbation_constant);
#else
cut_hmesh_BVH.buildTree(cut_hmesh, numerical_perturbation_constant);
cut_hmesh_BVH.buildTree(cut_hmesh, relative_perturbation_constant);
#endif
}
@@ -1605,7 +1648,7 @@ extern "C" void preproc(
#else
BoundingVolumeHierarchy::intersectBVHTrees(
#if defined(MCUT_WITH_COMPUTE_HELPER_THREADPOOL)
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
#endif
ps_face_to_potentially_intersecting_others,
source_hmesh_BVH,
@@ -1727,16 +1770,16 @@ extern "C" void preproc(
// const std::string cs_patch_loc_str = to_string(j->first);
for (std::vector<std::shared_ptr<output_mesh_info_t>>::const_iterator k = j->second.cbegin(); k != j->second.cend(); ++k) {
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new fragment_cc_t, fn_delete_cc<fragment_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<fragment_cc_t> asFragPtr = std::dynamic_pointer_cast<fragment_cc_t>(cc_ptr);
MCUT_ASSERT(asFragPtr != nullptr);
asFragPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
asFragPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
asFragPtr->type = MC_CONNECTED_COMPONENT_TYPE_FRAGMENT;
asFragPtr->fragmentLocation = convert(i->first);
asFragPtr->patchLocation = convert(j->first);
@@ -1757,6 +1800,8 @@ extern "C" void preproc(
asFragPtr->internal_sourcemesh_face_count = source_hmesh->number_of_faces();
asFragPtr->client_sourcemesh_face_count = numSrcMeshFaces; // or source_hmesh_face_count
asFragPtr->perturbation_vector = perturbation;
context_ptr->connected_components.push_front(cc_ptr); // copy the connected component ptr into the context object
}
}
@@ -1774,15 +1819,15 @@ extern "C" void preproc(
for (std::vector<std::shared_ptr<output_mesh_info_t>>::const_iterator j = i->second.cbegin(); j != i->second.cend(); ++j) { // for each mesh
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new fragment_cc_t, fn_delete_cc<fragment_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<fragment_cc_t> asFragPtr = std::dynamic_pointer_cast<fragment_cc_t>(cc_ptr);
MCUT_ASSERT(asFragPtr != nullptr);
asFragPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
asFragPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
asFragPtr->type = MC_CONNECTED_COMPONENT_TYPE_FRAGMENT;
asFragPtr->fragmentLocation = convert(i->first);
asFragPtr->patchLocation = McPatchLocation::MC_PATCH_LOCATION_UNDEFINED;
@@ -1800,6 +1845,8 @@ extern "C" void preproc(
asFragPtr->internal_sourcemesh_face_count = source_hmesh->number_of_faces();
asFragPtr->client_sourcemesh_face_count = numSrcMeshFaces; // or source_hmesh_face_count
asFragPtr->perturbation_vector = perturbation;
context_ptr->connected_components.push_front(cc_ptr); // copy the connected component ptr into the context object
}
}
@@ -1813,20 +1860,20 @@ extern "C" void preproc(
it != insidePatches.cend();
++it) {
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new patch_cc_t, fn_delete_cc<patch_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<patch_cc_t> asPatchPtr = std::dynamic_pointer_cast<patch_cc_t>(cc_ptr);
MCUT_ASSERT(asPatchPtr != nullptr);
asPatchPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new patch_cc_t, fn_delete_cc<patch_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<patch_cc_t> asPatchPtr = std::dynamic_pointer_cast<patch_cc_t>(cc_ptr);
MCUT_ASSERT(asPatchPtr != nullptr);
asPatchPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
#if 0
// std::shared_ptr<connected_component_t> patchConnComp = std::unique_ptr<patch_cc_t, void (*)(connected_component_t*)>(new patch_cc_t, fn_delete_cc<patch_cc_t>);
// McConnectedComponent clientHandle = reinterpret_cast<McConnectedComponent>(patchConnComp.get());
// context_ptr->connected_components.emplace(clientHandle, std::move(patchConnComp));
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
// allocate internal context object (including associated threadpool etc.)
context_ptr->connected_components.add_or_update_mapping(handle, std::shared_ptr<connected_component_t>(new patch_cc_t, fn_delete_cc<patch_cc_t>));
@@ -1851,6 +1898,8 @@ extern "C" void preproc(
asPatchPtr->internal_sourcemesh_face_count = source_hmesh->number_of_faces();
asPatchPtr->client_sourcemesh_face_count = numSrcMeshFaces; // or source_hmesh_face_count
asPatchPtr->perturbation_vector = perturbation;
context_ptr->connected_components.push_front(cc_ptr); // copy the connected component ptr into the context object
}
TIMESTACK_POP();
@@ -1860,20 +1909,20 @@ extern "C" void preproc(
const std::vector<std::shared_ptr<output_mesh_info_t>>& outsidePatches = kernel_output.outside_patches[cm_patch_winding_order_t::DEFAULT];
for (std::vector<std::shared_ptr<output_mesh_info_t>>::const_iterator it = outsidePatches.cbegin(); it != outsidePatches.cend(); ++it) {
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new patch_cc_t, fn_delete_cc<patch_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<patch_cc_t> asPatchPtr = std::dynamic_pointer_cast<patch_cc_t>(cc_ptr);
MCUT_ASSERT(asPatchPtr != nullptr);
asPatchPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new patch_cc_t, fn_delete_cc<patch_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<patch_cc_t> asPatchPtr = std::dynamic_pointer_cast<patch_cc_t>(cc_ptr);
MCUT_ASSERT(asPatchPtr != nullptr);
asPatchPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
#if 0
/// std::shared_ptr<connected_component_t> patchConnComp = std::unique_ptr<patch_cc_t, void (*)(connected_component_t*)>(new patch_cc_t, fn_delete_cc<patch_cc_t>);
// McConnectedComponent clientHandle = reinterpret_cast<McConnectedComponent>(patchConnComp.get());
// context_ptr->connected_components.emplace(clientHandle, std::move(patchConnComp));
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
// allocate internal context object (including associated threadpool etc.)
context_ptr->connected_components.add_or_update_mapping(handle, std::shared_ptr<connected_component_t>(new patch_cc_t, fn_delete_cc<patch_cc_t>));
@@ -1897,6 +1946,8 @@ extern "C" void preproc(
asPatchPtr->internal_sourcemesh_face_count = source_hmesh->number_of_faces();
asPatchPtr->client_sourcemesh_face_count = numSrcMeshFaces; // or source_hmesh_face_count
asPatchPtr->perturbation_vector = perturbation;
context_ptr->connected_components.push_front(cc_ptr); // copy the connected component ptr into the context object
}
TIMESTACK_POP();
@@ -1910,22 +1961,22 @@ extern "C" void preproc(
if (kernel_output.seamed_src_mesh != nullptr && kernel_output.seamed_src_mesh->mesh->number_of_faces() > 0) {
TIMESTACK_PUSH("store source-mesh seam");
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new seam_cc_t, fn_delete_cc<seam_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<seam_cc_t> asSrcMeshSeamPtr = std::dynamic_pointer_cast<seam_cc_t>(cc_ptr);
MCUT_ASSERT(asSrcMeshSeamPtr != nullptr);
asSrcMeshSeamPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
asSrcMeshSeamPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
#if 0
// std::shared_ptr<connected_component_t> srcMeshSeam = std::unique_ptr<seam_cc_t, void (*)(connected_component_t*)>(new seam_cc_t, fn_delete_cc<seam_cc_t>);
// McConnectedComponent clientHandle = reinterpret_cast<McConnectedComponent>(srcMeshSeam.get());
// context_ptr->connected_components.emplace(clientHandle, std::move(srcMeshSeam));
// allocate internal context object (including associated threadpool etc.)
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
context_ptr->connected_components.add_or_update_mapping(handle, std::shared_ptr<connected_component_t>(new seam_cc_t, fn_delete_cc<seam_cc_t>));
@@ -1950,6 +2001,8 @@ extern "C" void preproc(
asSrcMeshSeamPtr->internal_sourcemesh_face_count = source_hmesh->number_of_faces();
asSrcMeshSeamPtr->client_sourcemesh_face_count = numSrcMeshFaces; // or source_hmesh_face_count
asSrcMeshSeamPtr->perturbation_vector = perturbation;
context_ptr->connected_components.push_front(cc_ptr); // copy the connected component ptr into the context object
TIMESTACK_POP();
@@ -1959,21 +2012,21 @@ extern "C" void preproc(
if (kernel_output.seamed_cut_mesh != nullptr && kernel_output.seamed_cut_mesh->mesh->number_of_faces() > 0) {
TIMESTACK_PUSH("store cut-mesh seam");
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new seam_cc_t, fn_delete_cc<seam_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<seam_cc_t> asCutMeshSeamPtr = std::dynamic_pointer_cast<seam_cc_t>(cc_ptr);
MCUT_ASSERT(asCutMeshSeamPtr != nullptr);
asCutMeshSeamPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
asCutMeshSeamPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
#if 0
// std::shared_ptr<connected_component_t> cutMeshSeam = std::unique_ptr<seam_cc_t, void (*)(connected_component_t*)>(new seam_cc_t, fn_delete_cc<seam_cc_t>);
// McConnectedComponent clientHandle = reinterpret_cast<McConnectedComponent>(cutMeshSeam.get());
// context_ptr->connected_components.emplace(clientHandle, std::move(cutMeshSeam));
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
context_ptr->connected_components.add_or_update_mapping(handle, std::shared_ptr<connected_component_t>(new seam_cc_t, fn_delete_cc<seam_cc_t>));
@@ -1997,6 +2050,8 @@ extern "C" void preproc(
asCutMeshSeamPtr->internal_sourcemesh_face_count = source_hmesh->number_of_faces();
asCutMeshSeamPtr->client_sourcemesh_face_count = numSrcMeshFaces; // or source_hmesh_face_count
asCutMeshSeamPtr->perturbation_vector = perturbation;
context_ptr->connected_components.push_front(cc_ptr); // copy the connected component ptr into the context object
TIMESTACK_POP();
@@ -2010,19 +2065,19 @@ extern "C" void preproc(
TIMESTACK_PUSH("store original cut-mesh");
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new input_cc_t, fn_delete_cc<input_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<input_cc_t> asCutMeshInputPtr = std::dynamic_pointer_cast<input_cc_t>(cc_ptr);
MCUT_ASSERT(asCutMeshInputPtr != nullptr);
asCutMeshInputPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
asCutMeshInputPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
#if 0
// std::shared_ptr<connected_component_t> internalCutMesh = std::unique_ptr<input_cc_t, void (*)(connected_component_t*)>(new input_cc_t, fn_delete_cc<input_cc_t>);
// McConnectedComponent clientHandle = reinterpret_cast<McConnectedComponent>(internalCutMesh.get());
// context_ptr->connected_components.emplace(clientHandle, std::move(internalCutMesh));
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
context_ptr->connected_components.add_or_update_mapping(handle, std::shared_ptr<connected_component_t>(new input_cc_t, fn_delete_cc<input_cc_t>));
@@ -2051,7 +2106,7 @@ extern "C" void preproc(
};
parallel_for(
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
cut_hmesh->vertices_begin(),
cut_hmesh->vertices_end(),
fn_fill_vertex_map);
@@ -2060,7 +2115,6 @@ extern "C" void preproc(
omi->data_maps.vertex_map[*i] = vd_t((*i) + source_hmesh->number_of_vertices()); // apply offset like kernel does
}
#endif
}
if (kernel_input.populate_face_maps) {
@@ -2073,7 +2127,7 @@ extern "C" void preproc(
};
parallel_for(
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
cut_hmesh->faces_begin(),
cut_hmesh->faces_end(),
fn_fill_face_map);
@@ -2098,6 +2152,8 @@ extern "C" void preproc(
asCutMeshInputPtr->internal_sourcemesh_face_count = source_hmesh->number_of_faces();
asCutMeshInputPtr->client_sourcemesh_face_count = numSrcMeshFaces; // or source_hmesh_face_count
asCutMeshInputPtr->perturbation_vector = perturbation;
context_ptr->connected_components.push_front(cc_ptr); // copy the connected component ptr into the context object
TIMESTACK_POP();
@@ -2108,19 +2164,19 @@ extern "C" void preproc(
TIMESTACK_PUSH("store original src-mesh");
std::shared_ptr<connected_component_t> cc_ptr = std::shared_ptr<connected_component_t>(new input_cc_t, fn_delete_cc<input_cc_t>);
MCUT_ASSERT(cc_ptr != nullptr);
std::shared_ptr<input_cc_t> asSrcMeshInputPtr = std::dynamic_pointer_cast<input_cc_t>(cc_ptr);
MCUT_ASSERT(asSrcMeshInputPtr != nullptr);
asSrcMeshInputPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
asSrcMeshInputPtr->m_user_handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
#if 0
// std::shared_ptr<connected_component_t> internalSrcMesh = std::unique_ptr<input_cc_t, void (*)(connected_component_t*)>(new input_cc_t, fn_delete_cc<input_cc_t>);
// McConnectedComponent clientHandle = reinterpret_cast<McConnectedComponent>(internalSrcMesh.get());
// context_ptr->connected_components.emplace(clientHandle, std::move(internalSrcMesh));
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter++);
const McConnectedComponent handle = reinterpret_cast<McConnectedComponent>(g_objects_counter.fetch_add(1, std::memory_order_relaxed));
context_ptr->connected_components.add_or_update_mapping(handle, std::shared_ptr<connected_component_t>(new input_cc_t, fn_delete_cc<input_cc_t>));
@@ -2145,7 +2201,7 @@ extern "C" void preproc(
};
parallel_for(
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
source_hmesh->vertices_begin(),
source_hmesh->vertices_end(),
fn_fill_vertex_map);
@@ -2166,7 +2222,7 @@ extern "C" void preproc(
};
parallel_for(
context_ptr->get_shared_compute_threadpool() ,
context_ptr->get_shared_compute_threadpool(),
source_hmesh->faces_begin(),
source_hmesh->faces_end(),
fn_fill_face_map);
@@ -2191,6 +2247,8 @@ extern "C" void preproc(
asSrcMeshInputPtr->internal_sourcemesh_face_count = source_hmesh->number_of_faces();
asSrcMeshInputPtr->client_sourcemesh_face_count = numSrcMeshFaces; // or source_hmesh_face_count
asSrcMeshInputPtr->perturbation_vector = perturbation;
context_ptr->connected_components.push_front(cc_ptr); // copy the connected component ptr into the context object
TIMESTACK_POP();