OpenMesh: Get handle to a boundary halfedge
I have a quite simple question on the C++ library OpenMesh. Surprisingly, I haven't found anywhere an answer on it.
For a given mesh I'd like to iterate along the mesh boundary. From the documentation I know:
You can iterate along boundaries by using the next_halfedge_handle(). If you are on a boundary, the next halfedge is guaranteed to be also a boundary halfedge.
So far, so clear. But how do I get an initial boundary halfedge so that I can use next_halfedge_handle()
from then on? Do I really have to iterate over all halfedges to find one being on the boundary?
Thanks a lot for your help.
c++ openmesh
add a comment |
I have a quite simple question on the C++ library OpenMesh. Surprisingly, I haven't found anywhere an answer on it.
For a given mesh I'd like to iterate along the mesh boundary. From the documentation I know:
You can iterate along boundaries by using the next_halfedge_handle(). If you are on a boundary, the next halfedge is guaranteed to be also a boundary halfedge.
So far, so clear. But how do I get an initial boundary halfedge so that I can use next_halfedge_handle()
from then on? Do I really have to iterate over all halfedges to find one being on the boundary?
Thanks a lot for your help.
c++ openmesh
add a comment |
I have a quite simple question on the C++ library OpenMesh. Surprisingly, I haven't found anywhere an answer on it.
For a given mesh I'd like to iterate along the mesh boundary. From the documentation I know:
You can iterate along boundaries by using the next_halfedge_handle(). If you are on a boundary, the next halfedge is guaranteed to be also a boundary halfedge.
So far, so clear. But how do I get an initial boundary halfedge so that I can use next_halfedge_handle()
from then on? Do I really have to iterate over all halfedges to find one being on the boundary?
Thanks a lot for your help.
c++ openmesh
I have a quite simple question on the C++ library OpenMesh. Surprisingly, I haven't found anywhere an answer on it.
For a given mesh I'd like to iterate along the mesh boundary. From the documentation I know:
You can iterate along boundaries by using the next_halfedge_handle(). If you are on a boundary, the next halfedge is guaranteed to be also a boundary halfedge.
So far, so clear. But how do I get an initial boundary halfedge so that I can use next_halfedge_handle()
from then on? Do I really have to iterate over all halfedges to find one being on the boundary?
Thanks a lot for your help.
c++ openmesh
c++ openmesh
asked Nov 22 '18 at 13:32
Chris87Chris87
33
33
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Yes.
The "Mesh" is a just a collection of polygons (most often triangles) and their local connectivity. There isn't really any way to know where the boundaries are (or even how many, or if there are any) without explicitly looking for them.
Iterating yourself is rather simple. You do however need to take into account that there are probably several boundaries (like holes). So it might be wise to identify all boundaries and then choose the one you're interested in.
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
typedef std::shared_ptr<MeshUtils::Mesh> MeshPtr;
typedef OpenMesh::HalfedgeHandle HEdgeHandle;
std::vector<HEdgeHandle> EnumerateBoundryCycles(MeshPtr mesh)
{
vector<HEdgeHandle> cycles_all;
size_t maxItr(mesh->n_halfedges());
mesh->request_halfedge_status();
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
mesh->status(he_itr).set_tagged(false);
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
{
if (mesh->status(he_itr).tagged())
continue;
mesh->status(he_itr).set_tagged(true);
if (false == mesh->is_boundary(he_itr))
continue;
// boundry found
cycles_all.push_back(*he_itr);
size_t counter = 1;
auto next_he = mesh->next_halfedge_handle(he_itr);
while ( (next_he != he_itr) && counter < maxItr)
{
assert(mesh->is_boundary(next_he));
assert(false == mesh->status(next_he).tagged());
mesh->status(next_he).set_tagged(true);
next_he = mesh->next_halfedge_handle(next_he);
counter++;
}
std::cout << "[EnumerateBoundryCycles]: Found cycle of length " << counter << std::endl;
if (counter >= maxItr)
{
std::cout << "WRN [EnumerateBoundryCycles]: Failed to close boundry loop." << std::endl;
assert(false);
}
}
mesh->release_halfedge_status();
return cycles_all;
}
1
Thanks! I thinkitr
in the condition of the while loop should becounter
.
– Chris87
Nov 26 '18 at 9:08
1
Just one additional remark: one should avoid usingstd::move
inreturn
. See [stackoverflow.com/questions/14856344/….
– Chris87
Nov 26 '18 at 9:38
Thanks! I wasn't aware of this.
– Mark Loyman
Nov 27 '18 at 11:51
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432138%2fopenmesh-get-handle-to-a-boundary-halfedge%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Yes.
The "Mesh" is a just a collection of polygons (most often triangles) and their local connectivity. There isn't really any way to know where the boundaries are (or even how many, or if there are any) without explicitly looking for them.
Iterating yourself is rather simple. You do however need to take into account that there are probably several boundaries (like holes). So it might be wise to identify all boundaries and then choose the one you're interested in.
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
typedef std::shared_ptr<MeshUtils::Mesh> MeshPtr;
typedef OpenMesh::HalfedgeHandle HEdgeHandle;
std::vector<HEdgeHandle> EnumerateBoundryCycles(MeshPtr mesh)
{
vector<HEdgeHandle> cycles_all;
size_t maxItr(mesh->n_halfedges());
mesh->request_halfedge_status();
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
mesh->status(he_itr).set_tagged(false);
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
{
if (mesh->status(he_itr).tagged())
continue;
mesh->status(he_itr).set_tagged(true);
if (false == mesh->is_boundary(he_itr))
continue;
// boundry found
cycles_all.push_back(*he_itr);
size_t counter = 1;
auto next_he = mesh->next_halfedge_handle(he_itr);
while ( (next_he != he_itr) && counter < maxItr)
{
assert(mesh->is_boundary(next_he));
assert(false == mesh->status(next_he).tagged());
mesh->status(next_he).set_tagged(true);
next_he = mesh->next_halfedge_handle(next_he);
counter++;
}
std::cout << "[EnumerateBoundryCycles]: Found cycle of length " << counter << std::endl;
if (counter >= maxItr)
{
std::cout << "WRN [EnumerateBoundryCycles]: Failed to close boundry loop." << std::endl;
assert(false);
}
}
mesh->release_halfedge_status();
return cycles_all;
}
1
Thanks! I thinkitr
in the condition of the while loop should becounter
.
– Chris87
Nov 26 '18 at 9:08
1
Just one additional remark: one should avoid usingstd::move
inreturn
. See [stackoverflow.com/questions/14856344/….
– Chris87
Nov 26 '18 at 9:38
Thanks! I wasn't aware of this.
– Mark Loyman
Nov 27 '18 at 11:51
add a comment |
Yes.
The "Mesh" is a just a collection of polygons (most often triangles) and their local connectivity. There isn't really any way to know where the boundaries are (or even how many, or if there are any) without explicitly looking for them.
Iterating yourself is rather simple. You do however need to take into account that there are probably several boundaries (like holes). So it might be wise to identify all boundaries and then choose the one you're interested in.
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
typedef std::shared_ptr<MeshUtils::Mesh> MeshPtr;
typedef OpenMesh::HalfedgeHandle HEdgeHandle;
std::vector<HEdgeHandle> EnumerateBoundryCycles(MeshPtr mesh)
{
vector<HEdgeHandle> cycles_all;
size_t maxItr(mesh->n_halfedges());
mesh->request_halfedge_status();
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
mesh->status(he_itr).set_tagged(false);
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
{
if (mesh->status(he_itr).tagged())
continue;
mesh->status(he_itr).set_tagged(true);
if (false == mesh->is_boundary(he_itr))
continue;
// boundry found
cycles_all.push_back(*he_itr);
size_t counter = 1;
auto next_he = mesh->next_halfedge_handle(he_itr);
while ( (next_he != he_itr) && counter < maxItr)
{
assert(mesh->is_boundary(next_he));
assert(false == mesh->status(next_he).tagged());
mesh->status(next_he).set_tagged(true);
next_he = mesh->next_halfedge_handle(next_he);
counter++;
}
std::cout << "[EnumerateBoundryCycles]: Found cycle of length " << counter << std::endl;
if (counter >= maxItr)
{
std::cout << "WRN [EnumerateBoundryCycles]: Failed to close boundry loop." << std::endl;
assert(false);
}
}
mesh->release_halfedge_status();
return cycles_all;
}
1
Thanks! I thinkitr
in the condition of the while loop should becounter
.
– Chris87
Nov 26 '18 at 9:08
1
Just one additional remark: one should avoid usingstd::move
inreturn
. See [stackoverflow.com/questions/14856344/….
– Chris87
Nov 26 '18 at 9:38
Thanks! I wasn't aware of this.
– Mark Loyman
Nov 27 '18 at 11:51
add a comment |
Yes.
The "Mesh" is a just a collection of polygons (most often triangles) and their local connectivity. There isn't really any way to know where the boundaries are (or even how many, or if there are any) without explicitly looking for them.
Iterating yourself is rather simple. You do however need to take into account that there are probably several boundaries (like holes). So it might be wise to identify all boundaries and then choose the one you're interested in.
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
typedef std::shared_ptr<MeshUtils::Mesh> MeshPtr;
typedef OpenMesh::HalfedgeHandle HEdgeHandle;
std::vector<HEdgeHandle> EnumerateBoundryCycles(MeshPtr mesh)
{
vector<HEdgeHandle> cycles_all;
size_t maxItr(mesh->n_halfedges());
mesh->request_halfedge_status();
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
mesh->status(he_itr).set_tagged(false);
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
{
if (mesh->status(he_itr).tagged())
continue;
mesh->status(he_itr).set_tagged(true);
if (false == mesh->is_boundary(he_itr))
continue;
// boundry found
cycles_all.push_back(*he_itr);
size_t counter = 1;
auto next_he = mesh->next_halfedge_handle(he_itr);
while ( (next_he != he_itr) && counter < maxItr)
{
assert(mesh->is_boundary(next_he));
assert(false == mesh->status(next_he).tagged());
mesh->status(next_he).set_tagged(true);
next_he = mesh->next_halfedge_handle(next_he);
counter++;
}
std::cout << "[EnumerateBoundryCycles]: Found cycle of length " << counter << std::endl;
if (counter >= maxItr)
{
std::cout << "WRN [EnumerateBoundryCycles]: Failed to close boundry loop." << std::endl;
assert(false);
}
}
mesh->release_halfedge_status();
return cycles_all;
}
Yes.
The "Mesh" is a just a collection of polygons (most often triangles) and their local connectivity. There isn't really any way to know where the boundaries are (or even how many, or if there are any) without explicitly looking for them.
Iterating yourself is rather simple. You do however need to take into account that there are probably several boundaries (like holes). So it might be wise to identify all boundaries and then choose the one you're interested in.
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
typedef std::shared_ptr<MeshUtils::Mesh> MeshPtr;
typedef OpenMesh::HalfedgeHandle HEdgeHandle;
std::vector<HEdgeHandle> EnumerateBoundryCycles(MeshPtr mesh)
{
vector<HEdgeHandle> cycles_all;
size_t maxItr(mesh->n_halfedges());
mesh->request_halfedge_status();
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
mesh->status(he_itr).set_tagged(false);
for (auto he_itr = mesh->halfedges_begin(); he_itr != mesh->halfedges_end(); ++he_itr)
{
if (mesh->status(he_itr).tagged())
continue;
mesh->status(he_itr).set_tagged(true);
if (false == mesh->is_boundary(he_itr))
continue;
// boundry found
cycles_all.push_back(*he_itr);
size_t counter = 1;
auto next_he = mesh->next_halfedge_handle(he_itr);
while ( (next_he != he_itr) && counter < maxItr)
{
assert(mesh->is_boundary(next_he));
assert(false == mesh->status(next_he).tagged());
mesh->status(next_he).set_tagged(true);
next_he = mesh->next_halfedge_handle(next_he);
counter++;
}
std::cout << "[EnumerateBoundryCycles]: Found cycle of length " << counter << std::endl;
if (counter >= maxItr)
{
std::cout << "WRN [EnumerateBoundryCycles]: Failed to close boundry loop." << std::endl;
assert(false);
}
}
mesh->release_halfedge_status();
return cycles_all;
}
edited Nov 27 '18 at 11:49
answered Nov 24 '18 at 18:39
Mark LoymanMark Loyman
46847
46847
1
Thanks! I thinkitr
in the condition of the while loop should becounter
.
– Chris87
Nov 26 '18 at 9:08
1
Just one additional remark: one should avoid usingstd::move
inreturn
. See [stackoverflow.com/questions/14856344/….
– Chris87
Nov 26 '18 at 9:38
Thanks! I wasn't aware of this.
– Mark Loyman
Nov 27 '18 at 11:51
add a comment |
1
Thanks! I thinkitr
in the condition of the while loop should becounter
.
– Chris87
Nov 26 '18 at 9:08
1
Just one additional remark: one should avoid usingstd::move
inreturn
. See [stackoverflow.com/questions/14856344/….
– Chris87
Nov 26 '18 at 9:38
Thanks! I wasn't aware of this.
– Mark Loyman
Nov 27 '18 at 11:51
1
1
Thanks! I think
itr
in the condition of the while loop should be counter
.– Chris87
Nov 26 '18 at 9:08
Thanks! I think
itr
in the condition of the while loop should be counter
.– Chris87
Nov 26 '18 at 9:08
1
1
Just one additional remark: one should avoid using
std::move
in return
. See [stackoverflow.com/questions/14856344/….– Chris87
Nov 26 '18 at 9:38
Just one additional remark: one should avoid using
std::move
in return
. See [stackoverflow.com/questions/14856344/….– Chris87
Nov 26 '18 at 9:38
Thanks! I wasn't aware of this.
– Mark Loyman
Nov 27 '18 at 11:51
Thanks! I wasn't aware of this.
– Mark Loyman
Nov 27 '18 at 11:51
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432138%2fopenmesh-get-handle-to-a-boundary-halfedge%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown