diff --git a/src/OpenMesh/Core/Utils/RandomNumberGenerator.cc b/src/OpenMesh/Core/Utils/RandomNumberGenerator.cc new file mode 100644 index 00000000..836f3758 --- /dev/null +++ b/src/OpenMesh/Core/Utils/RandomNumberGenerator.cc @@ -0,0 +1,95 @@ +/*===========================================================================*\ + * * + * OpenMesh * + * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + * * + * OpenMesh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of * + * the License, or (at your option) any later version with the * + * following exceptions: * + * * + * If other files instantiate templates or use macros * + * or inline functions from this file, or you compile this file and * + * link it with other files to produce an executable, this file does * + * not by itself cause the resulting executable to be covered by the * + * GNU Lesser General Public License. This exception does not however * + * invalidate any other reasons why the executable file might be * + * covered by the GNU Lesser General Public License. * + * * + * OpenMesh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU LesserGeneral Public * + * License along with OpenMesh. If not, * + * see . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $Revision: 362 $ * + * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for generating a random number between 0.0 and 1.0 with +// a garantueed resolution +// +//============================================================================= + + +//== INCLUDES ================================================================= + + +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//== IMPLEMENTATION =========================================================== + +RandomNumberGenerator::RandomNumberGenerator(const double _resolution) : + resolution_(_resolution), + iterations_(1), + maxNum_(RAND_MAX) +{ + double tmp = resolution_; + while (tmp > (double(RAND_MAX) + 1) ) { + iterations_++; + tmp /= (double(RAND_MAX) + 1); + } + + for ( unsigned int i = 0 ; i < iterations_ - 1; ++i ) { + maxNum_ *= (RAND_MAX + 1); + } +} + +//----------------------------------------------------------------------------- + +double RandomNumberGenerator::getRand() const { + double randNum = 0.0; + for ( unsigned int i = 0 ; i < iterations_; ++i ) { + randNum *= (RAND_MAX + 1); + randNum += rand(); + } + + return randNum / maxNum_; +} + +//============================================================================= +} // namespace OpenMesh +//============================================================================= diff --git a/src/OpenMesh/Core/Utils/RandomNumberGenerator.hh b/src/OpenMesh/Core/Utils/RandomNumberGenerator.hh new file mode 100644 index 00000000..842f1e8c --- /dev/null +++ b/src/OpenMesh/Core/Utils/RandomNumberGenerator.hh @@ -0,0 +1,103 @@ +/*===========================================================================*\ + * * + * OpenMesh * + * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + * * + * OpenMesh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of * + * the License, or (at your option) any later version with the * + * following exceptions: * + * * + * If other files instantiate templates or use macros * + * or inline functions from this file, or you compile this file and * + * link it with other files to produce an executable, this file does * + * not by itself cause the resulting executable to be covered by the * + * GNU Lesser General Public License. This exception does not however * + * invalidate any other reasons why the executable file might be * + * covered by the GNU Lesser General Public License. * + * * + * OpenMesh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU LesserGeneral Public * + * License along with OpenMesh. If not, * + * see . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $Revision: 693 $ * + * $Date: 2012-09-23 16:25:16 +0200 (So, 23 Sep 2012) $ * + * * +\*===========================================================================*/ + + +//============================================================================= +// +// Helper Functions for generating a random number between 0.0 and 1.0 with +// a garantueed resolution +// +//============================================================================= + + +#ifndef OPENMESH_UTILS_RANDOMNUMBERGENERATOR_HH +#define OPENMESH_UTILS_RANDOMNUMBERGENERATOR_HH + + +//== INCLUDES ================================================================= + + +#include +#include + + +//== NAMESPACES =============================================================== + + +namespace OpenMesh { + + +//============================================================================= + + +/** Generate a random number between 0.0 and 1.0 with a garantueed resolution + */ +class OPENMESHDLLEXPORT RandomNumberGenerator +{ +public: + + /** \brief Constructor + * + * @param _resolution specifies the desired resolution for the random number generated + */ + RandomNumberGenerator(const double _resolution); + + /// returns a random double between 0.0 and 1.0 with a garantueed resolution + double getRand() const; + +private: + + /// desired resolution + const double resolution_; + + /// number of "blocks" of RAND_MAX that make up the desired _resolution + unsigned int iterations_; + + /// maximum random number generated, which is used for normalization + double maxNum_; +}; + +//============================================================================= +} // namespace OpenMesh +//============================================================================= +#endif // OPENMESH_UTILS_RANDOMNUMBERGENERATOR_HH defined +//============================================================================= + diff --git a/src/OpenMesh/Tools/Decimater/McDecimaterT.cc b/src/OpenMesh/Tools/Decimater/McDecimaterT.cc index adf82c58..fed92a47 100644 --- a/src/OpenMesh/Tools/Decimater/McDecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/McDecimaterT.cc @@ -60,6 +60,9 @@ # include #endif +#ifdef WIN32 +# include +#endif //== NAMESPACE =============================================================== @@ -111,6 +114,10 @@ size_t McDecimaterT::decimate(size_t _n_collapses) { // performed in a row unsigned int noCollapses = 0; +#ifdef WIN32 + RandomNumberGenerator randGen(mesh_.n_halfedges()); +#endif + while ( n_collapses < _n_collapses) { if (noCollapses > 20) { @@ -128,7 +135,11 @@ size_t McDecimaterT::decimate(size_t _n_collapses) { for ( int i = 0; i < (int)randomSamples_; ++i) { // Random halfedge handle +#ifdef WIN32 + tmpHandle = typename Mesh::HalfedgeHandle(int(randGen.getRand() * (mesh_.n_halfedges() - 1)) ); +#else tmpHandle = typename Mesh::HalfedgeHandle((static_cast(rand()) / RAND_MAX) * (mesh_.n_halfedges()-1) ); +#endif // if it is not deleted, we analyse it if ( ! mesh_.status(tmpHandle).deleted() ) { @@ -225,6 +236,10 @@ size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { // performed in a row unsigned int noCollapses = 0; +#ifdef WIN32 + RandomNumberGenerator randGen(mesh_.n_halfedges()); +#endif + while ((_nv < nv) && (_nf < nf)) { if (noCollapses > 20) { @@ -242,7 +257,11 @@ size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { for (int i = 0; i < (int) randomSamples_; ++i) { // Random halfedge handle +#ifdef WIN32 + tmpHandle = typename Mesh::HalfedgeHandle(int(randGen.getRand() * (mesh_.n_halfedges() - 1)) ); +#else tmpHandle = typename Mesh::HalfedgeHandle((static_cast(rand()) / RAND_MAX) * (mesh_.n_halfedges() - 1)); +#endif // if it is not deleted, we analyse it if (!mesh_.status(tmpHandle).deleted()) { @@ -356,6 +375,10 @@ size_t McDecimaterT::decimate_constraints_only(float _factor) { double energy = FLT_MAX; double bestEnergy = FLT_MAX; +#ifdef WIN32 + RandomNumberGenerator randGen(mesh_.n_halfedges()); +#endif + while ((noCollapses <= 50) && (illegalCollapses <= 50) && (nv > 0) && (nf > 1)) { // Optimal id and value will be collected during the random sampling @@ -363,13 +386,20 @@ size_t McDecimaterT::decimate_constraints_only(float _factor) { typename Mesh::HalfedgeHandle tmpHandle(-1); bestEnergy = FLT_MAX; + +#ifndef WIN32 const double randomNormalizer = (1.0 / RAND_MAX) * (mesh_.n_halfedges() - 1); +#endif // Generate random samples for collapses for (int i = 0; i < (int) randomSamples_; ++i) { // Random halfedge handle +#ifdef WIN32 + tmpHandle = typename Mesh::HalfedgeHandle(int(randGen.getRand() * (mesh_.n_halfedges() - 1)) ); +#else tmpHandle = typename Mesh::HalfedgeHandle(int(rand() * randomNormalizer ) ); +#endif // if it is not deleted, we analyze it if (!mesh_.status(mesh_.edge_handle(tmpHandle)).deleted()) {