Replies: 12 comments 3 replies
-
|
I found!! There are two steps:
Then it's easy to finish: for each face of |
Beta Was this translation helpful? Give feedback.
-
|
After doing |
Beta Was this translation helpful? Give feedback.
-
|
This is much more complicated when typedef std::map<face_descriptor, face_descriptor> MapBetweenFaces;
struct ClipVisitor :
public PMP::Corefinement::Default_visitor<EMesh3>
{
void before_subface_creations(face_descriptor fsplit, const EMesh3 & tm) {
*ofaceindex = fsplit;
if(*is_tm) {
size_t nf = tm.number_of_faces();
if((*nfaces).size() >= 1 && nf < (*nfaces).back()) {
*is_tm = false;
} else {
(*nfaces).push_back(nf);
}
}
}
void after_subface_created(face_descriptor fnew, const EMesh3 & tm) {
if(*is_tm) {
(*fmap_tm).insert(std::make_pair(fnew, *ofaceindex));
} else {
(*fmap_clipper).insert(std::make_pair(fnew, *ofaceindex));
}
}
void after_face_copy(
face_descriptor fsrc, const EMesh3 & tmsrc,
face_descriptor ftgt, const EMesh3 & tmtgt
) {
(*ftargets).insert(std::make_pair(ftgt, fsrc));
}
ClipVisitor()
: fmap_tm(new MapBetweenFaces()),
fmap_clipper(new MapBetweenFaces()),
ofaceindex(new face_descriptor()),
nfaces(new std::vector<size_t>()),
ftargets(new MapBetweenFaces()),
is_tm(new bool(true))
{}
std::shared_ptr<MapBetweenFaces> fmap_tm;
std::shared_ptr<MapBetweenFaces> fmap_clipper;
std::shared_ptr<MapBetweenFaces> ftargets;
std::shared_ptr<face_descriptor> ofaceindex;
std::shared_ptr<std::vector<size_t>> nfaces;
std::shared_ptr<bool> is_tm;
};
ClipVisitor vis;
std::size_t undetermined = 9999999;
Face_index_map fimap =
tm.add_property_map<face_descriptor, std::size_t>("f:i", undetermined).first;
std::size_t nfaces = tm.number_of_faces();
const bool clipping = PMP::clip(
tm, clipper,
PMP::parameters::clip_volume(true).visitor(vis).face_index_map(fimap),
PMP::parameters::clip_volume(true).do_not_modify(false)
);
tm.collect_garbage();
MapBetweenFaces fmap_tm = *(vis.fmap_tm);
MapBetweenFaces fmap_clipper = *(vis.fmap_clipper);
MapBetweenFaces ftargets = *(vis.ftargets);
MapBetweenFaces zeros;
{
int fdi = 0;
for(auto it = ftargets.rbegin(); it != ftargets.rend(); ++it) {
while(fimap[CGAL::SM_Face_index(fdi)] != undetermined) {
fdi++;
}
zeros[CGAL::SM_Face_index(fdi++)] = it->first;
}
}
std::map<face_descriptor, int> originalMesh;
MapBetweenFaces originalFace;
for(EMesh3::Face_index fi : tm.faces()) {
std::size_t ifi = fimap[fi];
face_descriptor fd = CGAL::SM_Face_index(ifi);
if(fi != fd && ifi != undetermined) {
originalMesh[fi] = 1;
originalFace[fi] = fmap_tm[fd];
} else if(ifi != undetermined) {
originalMesh[fi] = 1;
originalFace[fi] = ifi < nfaces ? fd : fmap_tm[fd];
} else if(ifi == undetermined) {
originalMesh[fi] = 2;
originalFace[fi] = zeros[fi];
}
} |
Beta Was this translation helpful? Give feedback.
-
|
And here is an application: the intersection of three cylinders with different colors. |
Beta Was this translation helpful? Give feedback.
-
|
I unmark the answer I accepted because it is wrong. I partially fixed it: I'm able to retrieve the original face of any face of the corefined clipped mesh, but I'm unable to retrieve the original face of a face of the corefined clipping mesh. |
Beta Was this translation helpful? Give feedback.
-
|
I guess it has to do with the |
Beta Was this translation helpful? Give feedback.
-
|
Here is my new visitor. To identify the mesh with struct ClipVisitor :
public PMP::Corefinement::Default_visitor<EMesh3>
{
void before_subface_creations(face_descriptor fsplit, const EMesh3 & tm) {
*ofaceindex = fsplit;
}
void after_subface_created(face_descriptor fnew, const EMesh3 & tm) {
if(*is_tm) {
if(tm.property_map<face_descriptor, std::size_t>("f:i").second) {
(*fmap_tm).insert(std::make_pair(fnew, *ofaceindex));
} else {
*is_tm = false;
(*fmap_clipper).insert(std::make_pair(fnew, *ofaceindex));
}
} else {
(*fmap_clipper).insert(std::make_pair(fnew, *ofaceindex));
}
}
void after_face_copy(
face_descriptor fsrc, const EMesh3 & tmsrc,
face_descriptor ftgt, const EMesh3 & tmtgt
) {
(*ftargets).insert(std::make_pair(ftgt, fsrc));
}
ClipVisitor()
: ofaceindex(new face_descriptor()),
fmap_tm(new MapBetweenFaces()),
fmap_clipper(new MapBetweenFaces()),
ftargets(new MapBetweenFaces()),
is_tm(new bool(true))
{}
std::shared_ptr<face_descriptor> ofaceindex;
std::shared_ptr<MapBetweenFaces> fmap_tm;
std::shared_ptr<MapBetweenFaces> fmap_clipper;
std::shared_ptr<MapBetweenFaces> ftargets;
std::shared_ptr<bool> is_tm;
}; |
Beta Was this translation helpful? Give feedback.
-
|
Then I do: ClipVisitor vis;
std::size_t undetermined = 9999999;
Face_index_map fimap =
tm.add_property_map<face_descriptor, std::size_t>("f:i", undetermined).first;
std::size_t nfaces = tm.number_of_faces();
const bool clipping = PMP::clip(
tm, clipper,
PMP::parameters::clip_volume(true).visitor(vis).face_index_map(fimap),
PMP::parameters::clip_volume(true).do_not_modify(false)
);
tm.collect_garbage();Then in I tried to put another |
Beta Was this translation helpful? Give feedback.
-
|
I don't understand your code. Did you have a look at this example: https://github.com/CGAL/cgal/blob/master/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_mesh_union_with_attributes.cpp ? As far as I understand it should work also for what you want to achieve. |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for looking into this. I will more carefully look at this example. My visitor creates three maps between face descriptors:
Then I do (I don't put all the code, not sure this is more understandable :-/): MaybeFcolorMap fcolorMap_ =
copy_prop<face_descriptor, std::string>(mesh, "f:color");
MaybeFcolorMap fcolorMap2_ =
copy_prop<face_descriptor, std::string>(clipper, "f:color");
std::size_t nfaces = mesh.number_of_faces();
std::size_t nfaces_clipper = clipper.number_of_faces();
std::size_t undetermined = 9999999;
ClipVisitor vis;
Face_index_map fimap =
mesh.add_property_map<face_descriptor, std::size_t>(
"f:i", undetermined
).first;
const bool doNotModify = !clipVolume;
const bool clipping = PMP::clip(
mesh, clipper,
PMP::parameters::clip_volume(clipVolume)
.visitor(vis).face_index_map(fimap),
PMP::parameters::clip_volume(clipVolume).do_not_modify(doNotModify)
);
if(!clipping) {
Rcpp::stop("Clipping has failed.");
}
mesh.collect_garbage();
MapBetweenFaces fmap_tm = *(vis.fmap_tm);
MapBetweenFaces fmap_clipper = *(vis.fmap_clipper);
MapBetweenFaces ftargets = *(vis.ftargets);
MapBetweenFaces zeros;
std::map<face_descriptor, std::string> fcolorMap;
std::map<face_descriptor, std::string> fcolorMap2;
std::map<face_descriptor, std::string> fcolorMap_clipper;
fcolorMap = fcolorMap_.first;
fcolorMap2 = fcolorMap2_.first;
{
int fdi = 0;
for(auto it = ftargets.begin(); it != ftargets.end(); ++it) {
face_descriptor fd = it->second;
if(std::size_t(fd) >= nfaces_clipper) {
fd = fmap_clipper[fd];
}
fcolorMap_clipper[it->first] = fcolorMap2[fd];
while(fimap[CGAL::SM_Face_index(fdi)] != undetermined) {
fdi++;
}
zeros[CGAL::SM_Face_index(fdi++)] = it->first;
}
}
Face_index_map whichPart =
mesh.add_property_map<face_descriptor, std::size_t>("f:which").first;
Fcolors_map newfcolor;
newfcolor = mesh.add_property_map<face_descriptor, std::string>(
"f:color", ""
).first;
for(EMesh3::Face_index fi : mesh.faces()) {
std::size_t ifi = fimap[fi];
face_descriptor fd = CGAL::SM_Face_index(ifi);
if(ifi != undetermined) {
whichPart[fi] = 0;
newfcolor[fi] = ifi < nfaces ? fcolorMap[fd] : fcolorMap[fmap_tm[fd]];
} else {
whichPart[fi] = 1;
newfcolor[fi] = fcolorMap_clipper[zeros[fi]];
}
}
mesh.remove_property_map(fimap);
EMesh3 tmesh;
{
Filtered_graph ffg(mesh, 0, whichPart);
MapBetweenFaceDescriptors f2fmap_;
boost::associative_property_map<MapBetweenFaceDescriptors> f2fmap(f2fmap_);
CGAL::copy_face_graph(
ffg, tmesh, CGAL::parameters::face_to_face_map(f2fmap)
);
copy_property<ffg_face_descriptor, face_descriptor, std::string>(
mesh, tmesh, f2fmap_, "f:color"
);
}
EMesh3 tmesh2;
{
Filtered_graph ffg(mesh, 1, whichPart);
MapBetweenFaceDescriptors f2fmap_;
boost::associative_property_map<MapBetweenFaceDescriptors> f2fmap(f2fmap_);
CGAL::copy_face_graph(
ffg, tmesh2, CGAL::parameters::face_to_face_map(f2fmap)
);
copy_property<ffg_face_descriptor, face_descriptor, std::string>(
mesh, tmesh2, f2fmap_, "f:color"
);
}With this code, I obtain the mesh |
Beta Was this translation helpful? Give feedback.
-
|
Well, I try to adapt the example. Now I do: struct ClipVisitor :
public PMP::Corefinement::Default_visitor<EMesh3>
{
void before_subface_creations(face_descriptor fsplit, EMesh3 & tm) {
*color = properties[&tm][fsplit];
}
void after_subface_created(face_descriptor fnew, EMesh3 & tm) {
properties[&tm][fnew] = *color;
(*(fmap_mesh))[fnew] = *color;
}
void after_face_copy(
face_descriptor fsrc, EMesh3 & tmsrc,
face_descriptor ftgt, EMesh3 & tmtgt
) {
(*(fmap_mesh))[ftgt] = properties[&tmsrc][fsrc];
}
ClipVisitor()
: color(new std::string("black")),
fmap_mesh(new std::map<face_descriptor, std::string>())
{
properties.reserve(2);
}
boost::container::flat_map<const EMesh3*, std::map<face_descriptor, std::string>> properties;
std::shared_ptr<std::string> color;
std::shared_ptr<std::map<face_descriptor, std::string>> fmap_mesh;
}; std::map<face_descriptor, std::string> fcolorMap = fcolorMap_.first; // mesh color map
std::map<face_descriptor, std::string> fcolorMap2 = fcolorMap2_.first; // clipper color map
ClipVisitor vis;
vis.properties[&mesh] = fcolorMap;
vis.properties[&clipper] = fcolorMap2;
size_t undetermined = 9999999;
Face_index_map fimap =
mesh.add_property_map<face_descriptor, std::size_t>(
"f:i", undetermined
).first;
const bool clipping = PMP::clip(
mesh, clipper,
PMP::parameters::clip_volume(true).visitor(vis).face_index_map(fimap),
PMP::parameters::clip_volume(true).do_not_modify(false)
);
if(!clipping) {
Rcpp::stop("Clipping has failed.");
}
mesh.collect_garbage();
Fcolors_map newfcolor = mesh.add_property_map<face_descriptor, std::string>(
"f:color", ""
).first;
for(EMesh3::Face_index fi : mesh.faces()) {
std::string col = (*(vis.fmap_mesh))[fi];
if(col == "") {
std::size_t ifi = fimap[fi];
if(ifi == undetermined) {
col = fcolorMap2[fi];
} else {
col = fcolorMap[fi];
}
}
newfcolor[fi] = col;
}Then, when I clip two unicolor meshes, I get a perfect bicolor mesh. But when I clip two meshes with multiple colors, the colors are completely messy. |
Beta Was this translation helpful? Give feedback.
-
|
Well, still spent two days on this problem and I now believe it's impossible. The |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
Hello,
I have a mesh
meshthat I clip to a meshclipper. Let's callcmeshthe clipped mesh. Mymeshhas a colour associated to each of its faces, and I want to retrieve these colors incmesh. If I correctly understand the splitting, each face ofcmeshis either an unchanged face ofmeshor a subface of a face ofmesh, so what I want to do make sense.Actually I managed to do it using an inefficient solution: for each face of
cmesh, I take its centroid and I iterate over the faces ofmeshto see in which original face this face belongs.But then I discovered the corefinement visitors and this looks promising. For example, I tried to use these two visitor functions:
With these two visitor functions, I create a map from the splitted face descriptors to the new face descriptors. This didn't help me to solve my problem. The splitted face descriptors obtained in this way belong to
mesh, so ok I have their color. In view of the large values of the new face descriptors, I guess that these are some face descriptors of the corefined mesh. That doesn't help.The goal is to obtain what I was able to obtain with my inefficient method: for each face of
cmesh, I want to know its original face inmesh. Is it possible with the refinement visitors?Beta Was this translation helpful? Give feedback.
All reactions