51 #define OPENMESH_MULTIPLE_CHOICE_DECIMATER_DECIMATERT_CC 58 #if defined(OM_CC_MIPS) 65 # include <OpenMesh/Core/Utils/RandomNumberGenerator.hh> 78 mesh_(_mesh), randomSamples_(10) {
81 mesh_.request_vertex_status();
82 mesh_.request_halfedge_status();
83 mesh_.request_edge_status();
84 mesh_.request_face_status();
93 mesh_.release_vertex_status();
94 mesh_.release_edge_status();
95 mesh_.release_halfedge_status();
96 mesh_.release_face_status();
107 unsigned int n_collapses(0);
109 bool collapsesUnchanged =
false;
111 unsigned int oldCollapses = 0;
114 unsigned int noCollapses = 0;
120 const bool update_normals = mesh_.has_face_normals();
122 while ( n_collapses < _n_collapses) {
124 if (noCollapses > 20) {
125 omlog() <<
"[McDecimater] : no collapses performed in over 20 iterations in a row\n";
130 typename Mesh::HalfedgeHandle bestHandle(-1);
131 typename Mesh::HalfedgeHandle tmpHandle(-1);
132 double bestEnergy = FLT_MAX;
133 double energy = FLT_MAX;
136 for (
int i = 0; i < (int)randomSamples_; ++i) {
140 tmpHandle =
typename Mesh::HalfedgeHandle(
int(randGen.getRand() * double(mesh_.n_halfedges() - 1.0)) );
142 tmpHandle =
typename Mesh::HalfedgeHandle( (
double(rand()) /
double(RAND_MAX) ) *
double(mesh_.n_halfedges()-1) );
146 if ( ! mesh_.status(tmpHandle).deleted() ) {
156 if ( energy < bestEnergy ) {
158 bestHandle = tmpHandle;
169 if ( bestEnergy != FLT_MAX ) {
182 mesh_.collapse(bestHandle);
186 oldCollapses = n_collapses;
188 collapsesUnchanged =
false;
194 for (; vf_it.is_valid(); ++vf_it)
195 if (!mesh_.status(*vf_it).deleted())
196 mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it));
207 if (oldCollapses == n_collapses) {
208 if (collapsesUnchanged ==
false) {
210 collapsesUnchanged =
true;
232 if ( (_nv == 0) && (_nf == 1) )
235 size_t nv = mesh_.n_vertices();
236 size_t nf = mesh_.n_faces();
237 unsigned int n_collapses(0);
240 bool collapsesUnchanged =
false;
242 unsigned int oldCollapses = 0;
245 unsigned int noCollapses = 0;
251 const bool update_normals = mesh_.has_face_normals();
253 while ((_nv < nv) && (_nf < nf)) {
255 if (noCollapses > 20) {
256 omlog() <<
"[McDecimater] : no collapses performed in over 20 iterations in a row\n";
261 typename Mesh::HalfedgeHandle bestHandle(-1);
262 typename Mesh::HalfedgeHandle tmpHandle(-1);
263 double bestEnergy = FLT_MAX;
264 double energy = FLT_MAX;
267 for (
int i = 0; i < (int) randomSamples_; ++i) {
271 tmpHandle =
typename Mesh::HalfedgeHandle(
int(randGen.getRand() * double(mesh_.n_halfedges() - 1.0)) );
273 tmpHandle =
typename Mesh::HalfedgeHandle( (
double(rand()) /
double(RAND_MAX) ) *
double(mesh_.n_halfedges() - 1));
277 if (!mesh_.status(tmpHandle).deleted()) {
287 if (energy < bestEnergy) {
289 bestHandle = tmpHandle;
300 if ( bestEnergy != FLT_MAX ) {
316 if (mesh_.is_boundary(ci.
v0v1) || mesh_.is_boundary(ci.
v1v0))
325 mesh_.collapse(bestHandle);
329 oldCollapses = n_collapses;
331 collapsesUnchanged =
false;
337 for (; vf_it.is_valid(); ++vf_it)
338 if (!mesh_.status(*vf_it).deleted())
339 mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it));
350 if (oldCollapses == n_collapses) {
351 if (collapsesUnchanged ==
false) {
353 collapsesUnchanged =
true;
377 unsigned int n_collapses(0);
378 size_t nv = mesh_.n_vertices();
379 size_t nf = mesh_.n_faces();
381 bool lastCollapseIllegal =
false;
383 unsigned int illegalCollapses = 0;
385 bool collapsesUnchanged =
false;
387 unsigned int oldCollapses = 0;
390 unsigned int noCollapses = 0;
392 double energy = FLT_MAX;
393 double bestEnergy = FLT_MAX;
399 while ((noCollapses <= 50) && (illegalCollapses <= 50) && (nv > 0) && (nf > 1)) {
402 typename Mesh::HalfedgeHandle bestHandle(-1);
403 typename Mesh::HalfedgeHandle tmpHandle(-1);
404 bestEnergy = FLT_MAX;
408 const double randomNormalizer = (1.0 / RAND_MAX) * (mesh_.n_halfedges() - 1);
412 for (
int i = 0; i < (int) randomSamples_; ++i) {
416 tmpHandle =
typename Mesh::HalfedgeHandle(
int(randGen.getRand() * double(mesh_.n_halfedges() - 1.0)) );
418 tmpHandle =
typename Mesh::HalfedgeHandle(
int(rand() * randomNormalizer ) );
422 if (!mesh_.status(mesh_.edge_handle(tmpHandle)).deleted()) {
432 if (lastCollapseIllegal) {
435 illegalCollapses = 1;
436 lastCollapseIllegal =
true;
440 illegalCollapses = 0;
441 lastCollapseIllegal =
false;
444 if (energy < bestEnergy) {
446 bestHandle = tmpHandle;
460 if ( bestEnergy != FLT_MAX ) {
476 if (mesh_.is_boundary(ci.
v0v1) || mesh_.is_boundary(ci.
v1v0))
485 mesh_.collapse(bestHandle);
489 oldCollapses = n_collapses;
491 collapsesUnchanged =
false;
496 for (; vf_it.is_valid(); ++vf_it)
497 if (!mesh_.status(*vf_it).deleted())
498 mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it));
508 if (oldCollapses == n_collapses) {
509 if (collapsesUnchanged ==
false) {
511 collapsesUnchanged =
true;
Base class for all decimation modules.
Definition: ModBaseT.hh:192
Mesh::HalfedgeHandle v0v1
Halfedge to be collapsed.
Definition: CollapseInfoT.hh:89
Kernel::VertexFaceIter VertexFaceIter
Circulator.
Definition: PolyMeshT.hh:166
~McDecimaterT()
Destructor.
Definition: McDecimaterT_impl.hh:91
size_t decimate(size_t _n_collapses)
Decimate (perform _n_collapses collapses).
Definition: McDecimaterT_impl.hh:102
Definition: BaseDecimaterT.hh:85
Mesh::HalfedgeHandle v1v0
Reverse halfedge.
Definition: CollapseInfoT.hh:90
void set_error_tolerance_factor(double _factor)
This provides a function that allows the setting of a percentage of the original constraint of the mo...
Definition: BaseDecimaterT_impl.hh:191
float collapse_priority(const CollapseInfo &_ci)
Calculate priority of an halfedge collapse (using the modules)
Definition: BaseDecimaterT_impl.hh:154
McDecimaterT(Mesh &_mesh)
Constructor.
Definition: McDecimaterT_impl.hh:76
size_t decimate_to_faces(size_t _n_vertices=0, size_t _n_faces=0)
Decimate to target complexity (vertices and faces).
Definition: McDecimaterT_impl.hh:226
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
Generate a random number between 0.0 and 1.0 with a guaranteed resolution ( Number of possible values...
Definition: RandomNumberGenerator.hh:77
Mesh::VertexHandle v1
Remaining vertex.
Definition: CollapseInfoT.hh:92
bool is_collapse_legal(const CollapseInfo &_ci)
Is an edge collapse legal? Performs topological test only.
Definition: BaseDecimaterT_impl.hh:100
void preprocess_collapse(CollapseInfo &_ci)
Pre-process a collapse.
Definition: BaseDecimaterT_impl.hh:179
size_t decimate_constraints_only(float _factor)
Decimate only with constraints, while _factor gives the percentage of the constraints that should be ...
Definition: McDecimaterT_impl.hh:369
Stores information about a halfedge collapse.
Definition: CollapseInfoT.hh:74
bool notify_observer(size_t _n_collapses)
returns false, if abort requested by observer
Definition: BaseDecimaterT.hh:191
void postprocess_collapse(CollapseInfo &_ci)
Post-process a collapse.
Definition: BaseDecimaterT_impl.hh:167
bool is_initialized() const
Returns whether decimater has been successfully initialized.
Definition: BaseDecimaterT.hh:111