diff --git a/source/frontend.cpp b/source/frontend.cpp index 774b521..afbb7f6 100644 --- a/source/frontend.cpp +++ b/source/frontend.cpp @@ -2860,13 +2860,12 @@ void get_connected_component_data_impl_detail( std::stack> disjoint_seq_stack; // stores the next vertices on the left and right side of seed vertex // find any seam vertex that is not traversed, use that as a starting point -> the "seed" - std::unordered_map::iterator seed_fiter = std::find_if( // O(n) + auto seed_fiter = std::find_if( // O(n) traversed_seam_vertices.begin(), traversed_seam_vertices.end(), [](const std::pair& elem) { return elem.second == false; }); - seed_fiter->second = true; // marked the seed as traversed const McSize cur_seq_size_value_idx = seam_vertex_sequence_array.size(); @@ -2889,6 +2888,8 @@ void get_connected_component_data_impl_detail( // are stored in "disjoint_vertex_sequences_of_same_seam". const McUint32 seed_vertex_descr = (McUint32)seed_fiter->first; + // print coordinates of seed vertex + std::cout << "seed vertex: " << cc->vertex(seed_fiter->first) << std::endl; seam_vertex_sequence_array.push_back(seed_vertex_descr); // @@ -2900,26 +2901,33 @@ void get_connected_component_data_impl_detail( const std::vector& halfedges_around_seed_vertex = cc->get_halfedges_around_vertex(vd_t(seed_vertex_descr)); // for each halfedge whose target is the seed - for (std::vector::const_iterator it = halfedges_around_seed_vertex.cbegin(); it != halfedges_around_seed_vertex.cend(); ++it) { - const hd_t h = *it; + for (const auto& h : halfedges_around_seed_vertex) { const vd_t src = cc->source(h); // get the halfedge's source + std::cout << "halfedge's source " << cc->vertex(src) << std::endl; // is it even a seam vertex first of all? - std::unordered_map::iterator fiter = traversed_seam_vertices.find(src); + auto fiter = traversed_seam_vertices.find(src); const bool is_seam_vertex = fiter != traversed_seam_vertices.cend(); if (is_seam_vertex) { bool& is_traversed = fiter->second; + std::cout << "halfedge's source is a seam vertex, traversed? " << is_traversed << std::endl; if (!is_traversed) { // push since this neighbour is a seam vertex that has not been traversed - disjoint_seq_stack.push(std::make_pair(src, h)); + disjoint_seq_stack.emplace(src, h); is_traversed = true; // mark the neighbour as traversed (because we immediately traverse it next) } } } + std::cout << "disjoint_seq_stack.size() = " << disjoint_seq_stack.size() << std::endl; + // if (!(disjoint_seq_stack.size() == 1 || disjoint_seq_stack.size() == 2)) + // { + // // print debug information + // std::cout << cc->vertex(disjoint_seq_stack.top().first) << std::endl; + // } MCUT_ASSERT(disjoint_seq_stack.size() == 1 || disjoint_seq_stack.size() == 2); // this means will we are guarranteed to find just one sequence i.e. the draft disjoint sequence @@ -2930,10 +2938,13 @@ void get_connected_component_data_impl_detail( // An iteration will find a single sequence (which may be a loop, or a an open sequence that does not form a loop, do { - + // take the next neighbour from the stack to process and extend the sequence std::pair cur_vh_pair = disjoint_seq_stack.top(); disjoint_seq_stack.pop(); + // show which vertex we are currently processing + std::cout << "process rn: " << cc->vertex(cur_vh_pair.first) << std::endl; + const vd_t v = cur_vh_pair.first; // vertex, one of whose halfedges (along the seam) is h const hd_t h = cur_vh_pair.second; // halfedge whose source is v @@ -2944,17 +2955,13 @@ void get_connected_component_data_impl_detail( // similar logic as above to find the neighours of the seed, which polulate the stack "disjoint_seq_stack" const std::vector& halfedges_around_vertex = cc->get_halfedges_around_vertex(v); - for (std::vector::const_iterator it = halfedges_around_vertex.cbegin(); - it != halfedges_around_vertex.cend(); - ++it) { - const hd_t incident_h = *it; - + for (const auto& incident_h : halfedges_around_vertex) { if (cc->edge(incident_h) == cc->edge(h)) { continue; // skip! dont want to go backwards now... } const vd_t src = cc->source(incident_h); - std::unordered_map::iterator fiter = traversed_seam_vertices.find(src); + auto fiter = traversed_seam_vertices.find(src); const bool is_seam_vertex = fiter != traversed_seam_vertices.cend(); if (is_seam_vertex) { @@ -2962,14 +2969,17 @@ void get_connected_component_data_impl_detail( if (!is_traversed) { untraversed_adj_seam_vertex_count++; - disjoint_seq_stack.push(std::make_pair(src, incident_h)); + std::cout << "stack populated with: " << cc->vertex(src) << std::endl; + disjoint_seq_stack.emplace(src, incident_h); is_traversed = true; } } } + // we fail here right now MCUT_ASSERT(untraversed_adj_seam_vertex_count <= 1); + // if (untraversed_adj_seam_vertex_count > 1) continue; // no further neighbours to walk/traverse but the stack still has seam vertices to be walked. // This implies we have an open loop, and that we have finished finding the first disjoint part @@ -3022,6 +3032,7 @@ void get_connected_component_data_impl_detail( seam_vertex_sequence_array.cend()); MCUT_ASSERT(cur_seq_size_value_idx == seam_vertex_sequence_array_start_offset); + // if (cur_seq_size_value_idx != seam_vertex_sequence_array_start_offset) continue; total_seq_count += 1; // increment number of sequences found @@ -3262,7 +3273,7 @@ void get_connected_component_data_impl_detail( for (std::vector::const_iterator f_iter = block_start_; f_iter != block_end_; ++f_iter) { - if ((elem_offset + 1) >= elems_to_copy) { + if ((elem_offset + 1) > elems_to_copy) { break; } diff --git a/tutorials/QuerySeamVerticesSorted/QuerySeamVerticesSorted.cpp b/tutorials/QuerySeamVerticesSorted/QuerySeamVerticesSorted.cpp index 1bba653..5be3f8d 100644 --- a/tutorials/QuerySeamVerticesSorted/QuerySeamVerticesSorted.cpp +++ b/tutorials/QuerySeamVerticesSorted/QuerySeamVerticesSorted.cpp @@ -28,6 +28,7 @@ #include #include +#include #define my_assert(cond) \ if (!(cond)) { \ @@ -240,6 +241,123 @@ int main() // ... and so on, until last sequence // ] + // // check that connected component has correct source mesh + // api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_ORIGIN, 0, NULL, &numBytes); + // if (api_err != MC_NO_ERROR) { + // fprintf(stderr, "1:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_ORIGIN) failed (api_err=%d)\n", (int)api_err); + // exit(1); + // } + // McSeamOrigin origin; + // api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_ORIGIN, numBytes, &origin, NULL); + // if (api_err != MC_NO_ERROR) { + // fprintf(stderr, "2:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_ORIGIN) failed (api_err=%d)\n", (int)api_err); + // exit(1); + // } + + // if (origin != MC_SEAM_ORIGIN_SRCMESH) { + // fprintf(stderr, "connected component %d does not have source mesh as origin\n", i); + // continue; + // } + + // query the seam vertices (indices) + // --------------------------------- + + + api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_SEAM_VERTEX, 0, NULL, &numBytes); + + if (api_err != MC_NO_ERROR) { + fprintf(stderr, "1:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_SEAM_VERTEX) failed (api_err=%d)\n", (int)api_err); + exit(1); + } + + std::vector seamVertexIndices; + seamVertexIndices.resize(numBytes / sizeof(uint32_t)); + + api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_SEAM_VERTEX, numBytes, seamVertexIndices.data(), NULL); + + if (api_err != MC_NO_ERROR) { + fprintf(stderr, "2:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_SEAM_VERTEX) failed (api_err=%d)\n", (int)api_err); + exit(1); + } + + uint32_t faceSizesStub = seamVertexIndices.size(); + + char seamFnameBuf[40]; + sprintf(seamFnameBuf, "frag-%d-seam-vertices.txt", i); + + // save seam vertices to file (.txt) + // ------------------------ + writeOFF(seamFnameBuf, + NULL, + // We pretend that the list of seam vertices is a face, when in actual + // fact we are simply using the output file as storage for later inspection + seamVertexIndices.data(), + &faceSizesStub, + NULL, + 0, + 1, // one face + 0); + + + // query the vertices (coordinates) + // -------------------------------- + numBytes = 0; + api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_VERTEX_DOUBLE, 0, NULL, &numBytes); + + if (api_err != MC_NO_ERROR) { + fprintf(stderr, "1:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_VERTEX_DOUBLE) failed (api_err=%d)\n", (int)api_err); + exit(1); + } + + uint32_t numberOfVertices = (uint32_t)(numBytes / (sizeof(double) * 3)); + + std::vector vertices(numberOfVertices * 3u); + + api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_VERTEX_DOUBLE, numBytes, (void*)vertices.data(), NULL); + + if (api_err != MC_NO_ERROR) { + fprintf(stderr, "2:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_VERTEX_DOUBLE) failed (api_err=%d)\n", (int)api_err); + exit(1); + } + + // query (triangulated) faces + // ----------------------------- + numBytes = 0; + api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_FACE_TRIANGULATION, 0, NULL, &numBytes); + + if (api_err != MC_NO_ERROR) { + fprintf(stderr, "1:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_FACE_TRIANGULATION) failed (api_err=%d)\n", (int)api_err); + exit(1); + } + + uint32_t numberOfTriangles = (uint32_t)(numBytes / (sizeof(McIndex) * 3)); + + std::vector triangleIndices(numberOfTriangles * 3u); + + api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_FACE_TRIANGULATION, numBytes, (void*)triangleIndices.data(), NULL); + + if (api_err != MC_NO_ERROR) { + fprintf(stderr, "2:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_FACE_TRIANGULATION) failed (api_err=%d)\n", (int)api_err); + exit(1); + } + + // save mesh to file (.off) + // ------------------------ + char fnameBuf[32]; + sprintf(fnameBuf, "frag-%d.off", i); + + writeOFF(fnameBuf, + vertices.data(), + triangleIndices.data(), + NULL, // if null then function treat faceIndices array as made up of triangles + NULL, // we don't care about writing edges + numberOfVertices, + numberOfTriangles, + 0 // zero edges since we don't care about writing edges + ); + + std::cout << "working component" << i << std::endl; + api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_SEAM_VERTEX_SEQUENCE, 0, NULL, &numBytes); if (api_err != MC_NO_ERROR) { @@ -274,14 +392,14 @@ int main() // create entry to store own array and flag seamVertexSequences.push_back(std::pair, McBool>()); std::pair, McBool>& currentSeamVertexSequenceData = seamVertexSequences.back(); - - std::vector& currentSeamVertexSequenceIndices = currentSeamVertexSequenceData.first; // Ordered list of vertex indices in CC defining the seam sequence + + std::vector& currentSeamVertexSequenceIndices = currentSeamVertexSequenceData.first; // Ordered list of vertex indices in CC defining the seam sequence McBool &isLoop = currentSeamVertexSequenceData.second; // does it form a loop? (auxilliary piece of info that might be useful to users) - + // NOTE: order in which we do things here matter because of how we rely on "runningOffset++" // So here, for each sequence we have 1) the number of vertex indices in that sequence 2) - // a flag telling us whether the sequence is a loop, and 3) the actually consecutive list of - // sorted vertex indices that for the sequence + // a flag telling us whether the sequence is a loop, and 3) the actually consecutive list of + // sorted vertex indices that for the sequence const uint32_t currentSeamVertexSequenceIndicesArraySize = seamVertexSequenceArrayFromMCUT[runningOffset++]; currentSeamVertexSequenceIndices.resize(currentSeamVertexSequenceIndicesArraySize); @@ -289,8 +407,8 @@ int main() // copy seam vertex indices of current sequence into local array memcpy( - currentSeamVertexSequenceIndices.data(), - seamVertexSequenceArrayFromMCUT.data() + runningOffset, + currentSeamVertexSequenceIndices.data(), + seamVertexSequenceArrayFromMCUT.data() + runningOffset, sizeof(McUint32) * currentSeamVertexSequenceIndicesArraySize); runningOffset += currentSeamVertexSequenceIndicesArraySize; @@ -298,7 +416,7 @@ int main() // // We are now going to save the sequences to file. To do so, we piggyback - // on the "writeOFF" function and pretend that we are writing a mesh where + // on the "writeOFF" function and pretend that we are writing a mesh where // each sequence is a face. // @@ -306,7 +424,7 @@ int main() uint32_t numFacesStub = seamVertexSequences.size(); std::vector faceSizesArrayStub(numFacesStub); std::vector faceIndicesArrayStub; - + std::string flags_str; // for each sequence @@ -314,14 +432,14 @@ int main() { faceSizesArrayStub[j] = seamVertexSequences[j].first.size(); faceIndicesArrayStub.insert( - faceIndicesArrayStub.cend(), - seamVertexSequences[j].first.cbegin(), + faceIndicesArrayStub.cend(), + seamVertexSequences[j].first.cbegin(), seamVertexSequences[j].first.cend()); flags_str.append("-id" +std::to_string(j) + ((seamVertexSequences[j].second == MC_TRUE) ? "_isLOOP" : "_isOPEN")); } - char seamFnameBuf[1024]; + // char seamFnameBuf[1024]; sprintf(seamFnameBuf, "frag-%d-seam-vertices%s.txt", i, flags_str.c_str()); // save seam vertices to file (.txt) @@ -334,66 +452,8 @@ int main() faceSizesArrayStub.data(), NULL, 0, - (uint32_t)faceSizesArrayStub.size(), + (uint32_t)faceSizesArrayStub.size(), 0); - - - // query the vertices (coordinates) - // -------------------------------- - numBytes = 0; - api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_VERTEX_DOUBLE, 0, NULL, &numBytes); - - if (api_err != MC_NO_ERROR) { - fprintf(stderr, "1:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_VERTEX_DOUBLE) failed (api_err=%d)\n", (int)api_err); - exit(1); - } - - uint32_t numberOfVertices = (uint32_t)(numBytes / (sizeof(double) * 3)); - - std::vector vertices(numberOfVertices * 3u); - - api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_VERTEX_DOUBLE, numBytes, (void*)vertices.data(), NULL); - - if (api_err != MC_NO_ERROR) { - fprintf(stderr, "2:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_VERTEX_DOUBLE) failed (api_err=%d)\n", (int)api_err); - exit(1); - } - - // query (triangulated) faces - // ----------------------------- - numBytes = 0; - api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_FACE_TRIANGULATION, 0, NULL, &numBytes); - - if (api_err != MC_NO_ERROR) { - fprintf(stderr, "1:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_FACE_TRIANGULATION) failed (api_err=%d)\n", (int)api_err); - exit(1); - } - - uint32_t numberOfTriangles = (uint32_t)(numBytes / (sizeof(McIndex) * 3)); - - std::vector triangleIndices(numberOfTriangles * 3u); - - api_err = mcGetConnectedComponentData(context, connComp, MC_CONNECTED_COMPONENT_DATA_FACE_TRIANGULATION, numBytes, (void*)triangleIndices.data(), NULL); - - if (api_err != MC_NO_ERROR) { - fprintf(stderr, "2:mcGetConnectedComponentData(MC_CONNECTED_COMPONENT_DATA_FACE_TRIANGULATION) failed (api_err=%d)\n", (int)api_err); - exit(1); - } - - // save mesh to file (.off) - // ------------------------ - char fnameBuf[32]; - sprintf(fnameBuf, "frag-%d.off", i); - - writeOFF(fnameBuf, - vertices.data(), - triangleIndices.data(), - NULL, // if null then function treat faceIndices array as made up of triangles - NULL, // we don't care about writing edges - numberOfVertices, - numberOfTriangles, - 0 // zero edges since we don't care about writing edges - ); } // 6. free connected component data diff --git a/tutorials/QuerySeamVerticesSorted/data/cut-mesh.off b/tutorials/QuerySeamVerticesSorted/data/cut-mesh.off index f75aa26..2e849c6 100644 --- a/tutorials/QuerySeamVerticesSorted/data/cut-mesh.off +++ b/tutorials/QuerySeamVerticesSorted/data/cut-mesh.off @@ -1,7 +1,26 @@ OFF -4 1 0 --1.0829577445983887 -0.4735214114189148 -2.0000000000000000 -2.9170422554016113 -0.4735214114189148 -2.0000000000000000 --1.0829577445983887 -0.4735215902328491 2.0000000000000000 -2.9170422554016113 -0.4735215902328491 2.0000000000000000 -4 0 1 3 2 +12 12 0 +4.000000 0.000000 30.000000 +2.161209 3.365884 30.000000 +-1.664587 3.637190 30.000000 +-3.959970 0.564480 30.000000 +-2.614574 -3.027210 30.000000 +1.134649 -3.835697 30.000000 +4.000000 0.000000 -1.000000 +2.161209 3.365884 -1.000000 +-1.664587 3.637190 -1.000000 +-3.959970 0.564480 -1.000000 +-2.614574 -3.027210 -1.000000 +1.134649 -3.835697 -1.000000 +3 6 0 1 +3 6 1 7 +3 7 1 2 +3 7 2 8 +3 8 2 3 +3 8 3 9 +3 9 3 4 +3 9 4 10 +3 10 4 5 +3 10 5 11 +3 11 5 0 +3 11 0 6 diff --git a/tutorials/QuerySeamVerticesSorted/data/source-mesh.off b/tutorials/QuerySeamVerticesSorted/data/source-mesh.off index c815df8..7947273 100644 --- a/tutorials/QuerySeamVerticesSorted/data/source-mesh.off +++ b/tutorials/QuerySeamVerticesSorted/data/source-mesh.off @@ -1,28 +1,46 @@ OFF -16 10 0 --1.5000000000000000 0.8999999761581421 0.5000001192092896 -1.5000000000000000 0.8999999761581421 0.5000001192092896 -1.5000000000000000 0.8999999761581421 -0.4999998509883881 --1.5000000000000000 0.8999999761581421 -0.4999998509883881 -1.5000000000000000 -1.1000001430511475 0.4999998211860657 -1.5000000000000000 -1.0999999046325684 -0.5000001788139343 -0.5000000000000000 -1.1000001430511475 0.4999998211860657 -0.5000000000000000 -1.0999999046325684 -0.5000001788139343 -0.5000000000000000 -0.1000000834465027 0.4999999701976776 -0.5000000000000000 -0.0999999642372131 -0.4999999701976776 --0.5000000000000000 -0.1000000834465027 0.4999999701976776 --0.5000000000000000 -0.0999999642372131 -0.4999999701976776 --0.5000000000000000 -1.1000001430511475 0.4999998211860657 --0.5000000000000000 -1.0999999046325684 -0.5000001788139343 --1.5000000000000000 -1.1000001430511475 0.4999998211860657 --1.5000000000000000 -1.0999999046325684 -0.5000001788139343 -4 5 2 1 4 -4 11 9 8 10 -4 9 7 6 8 -8 2 5 7 9 11 13 15 3 -4 3 15 14 0 -4 13 11 10 12 -4 7 5 4 6 -8 1 0 14 12 10 8 6 4 -4 2 3 0 1 -4 15 13 12 14 +16 28 0 +-5 5 10 +-5 5 0 +-5 -5 0 +-5 -5 10 +-5 -15 10 +-5 -15 20 +-5 15 20 +-5 15 10 +5 -5 10 +5 -5 0 +5 5 0 +5 5 10 +5 15 10 +5 15 20 +5 -15 20 +5 -15 10 +3 0 1 2 200 200 200 +3 3 4 5 200 200 200 +3 6 7 0 200 200 200 +3 3 5 0 200 200 200 +3 3 0 2 200 200 200 +3 5 6 0 200 200 200 +3 8 9 10 200 200 200 +3 11 12 13 200 200 200 +3 14 15 8 200 200 200 +3 11 13 8 200 200 200 +3 11 8 10 200 200 200 +3 13 14 8 200 200 200 +3 5 14 13 200 200 200 +3 6 5 13 200 200 200 +3 9 8 3 200 200 200 +3 2 9 3 200 200 200 +3 4 3 15 200 200 200 +3 8 15 3 200 200 200 +3 9 2 1 200 200 200 +3 9 1 10 200 200 200 +3 15 14 5 200 200 200 +3 4 15 5 200 200 200 +3 7 6 13 200 200 200 +3 12 7 13 200 200 200 +3 12 11 7 200 200 200 +3 0 7 11 200 200 200 +3 1 0 11 200 200 200 +3 10 1 11 200 200 200 \ No newline at end of file