27 using namespace CVLib;
29 static int gcd(
int num1,
int num2) {
30 int remainder = (num2 % num1);
32 return (remainder != 0 ?
gcd(remainder, num1) : num1);
47 static bool SampleSphere(
unsigned N, std::vector<CCVector3>& dirs) {
48 static const double c_eps = 2.2204e-16;
49 static const double c_twist = 4.0;
58 }
catch (
const std::bad_alloc&) {
68 double area = (4 *
M_PI) / N;
69 double beta = acos(1.0 - 2.0 / N);
71 double gamma =
M_PI - 2 * beta;
72 double fuzz = c_eps * 2 * N;
74 int Ltemp =
static_cast<int>(
ceil(gamma / sqrt(area) - fuzz));
78 std::vector<double> mbar;
83 double theta = gamma / (L - 2);
84 for (
int i = 1; i < L - 1; ++i) {
87 (cos(theta * (i - 1) + beta) - cos(theta * i + beta)) /
100 for (
int i = 1; i < L; ++i) {
101 double f =
floor(mbar[i] + alpha + fuzz);
102 if ((mbar[i] - f) >= 0.5) f =
ceil(mbar[i] + alpha - fuzz);
103 m[i] =
static_cast<int>(f);
105 alpha += mbar[i] - m[i];
111 std::vector<double>
offset;
114 double z = 1.0 -
static_cast<double>(2 + m[1]) / N;
116 unsigned int rayIndex = 1;
117 for (
int i = 1; i < L - 1; ++i) {
118 if (m[i - 1] != 0 && m[i] != 0) {
120 static_cast<double>(
gcd(m[i], m[i - 1])) /
121 (2 * m[i] * m[i - 1]) +
122 std::min<double>(c_twist,
123 floor(m[i - 1] / c_twist)) /
129 double temp =
static_cast<double>(m[i]) / N;
131 double h = cos((acos(z + temp) + acos(z - temp)) / 2);
132 double r = sqrt(1.0 - h * h);
134 for (
int j = 0; j < m[i]; ++j) {
135 double theta = 2.0 *
M_PI *
136 (
offset[i] +
static_cast<double>(j) / m[i]);
144 z -=
static_cast<double>(m[i] + m[i + 1]) / N;
147 assert(rayIndex + 1 == N);
149 }
catch (
const std::bad_alloc&) {
160 std::vector<CCVector3>& rays,
163 unsigned rayCount = numberOfRays * (mode360 ? 1 : 2);
171 unsigned lastIndex = 0;
172 for (
size_t i = 0; i < rays.size(); ++i) {
174 if (lastIndex != i) {
175 rays[lastIndex] = rays[i];
180 rayCount = lastIndex;
181 rays.resize(rayCount);
188 GenericCloud* vertices,
194 CVLib::GenericProgressCallback* progressCb ,
195 QString entityName ) {
197 std::vector<CCVector3> rays;
198 if (!GenerateRays(numberOfRays, rays, mode360)) {
202 if (!Launch(rays, vertices, mesh, meshIsClosed,
width,
height, progressCb,
207 return static_cast<int>(rays.size());
211 CVLib::GenericCloud* vertices,
212 CVLib::GenericMesh* mesh ,
216 CVLib::GenericProgressCallback* progressCb ,
217 QString entityName ) {
218 if (rays.empty())
return false;
220 if (!vertices || !vertices->enableScalarField())
return false;
223 unsigned numberOfPoints = vertices->size();
225 unsigned numberOfRays =
static_cast<unsigned>(rays.size());
229 std::vector<int> visibilityCount;
231 visibilityCount.resize(numberOfPoints, 0);
232 }
catch (
const std::bad_alloc&) {
239 CVLib::NormalizedProgress
nProgress(progressCb, numberOfRays);
241 if (progressCb->textCanBeEdited()) {
242 progressCb->setMethodTitle(
"ShadeVis");
244 if (!entityName.isEmpty()) infoStr = entityName +
"\n";
245 infoStr.append(QString(
"Rays: %1").arg(numberOfRays));
247 infoStr.append(QString(
"\nFaces: %1").arg(mesh->size()));
249 infoStr.append(QString(
"\nVertices: %1").arg(numberOfPoints));
250 progressCb->setInfo(qPrintable(infoStr));
252 progressCb->update(0);
261 for (
unsigned i = 0; i < numberOfRays; ++i) {
276 for (
unsigned j = 0; j < numberOfPoints; ++j) {
277 ScalarType visValue =
278 static_cast<ScalarType
>(visibilityCount[j]) /
280 vertices->setPointScalarValue(j, visValue);
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
static int gcd(int num1, int num2)
static bool SampleSphere(unsigned N, std::vector< CCVector3 > &dirs)
Sample points on the unit sphere.
PCV (Portion de Ciel Visible / Ambiant Illumination) OpenGL context.
bool init(unsigned W, unsigned H, cloudViewer::GenericCloud *cloud, cloudViewer::GenericMesh *mesh=0, bool closedMesh=true)
Initialization.
void setViewDirection(const CCVector3 &V)
Set the viewing directions.
int GLAccumPixel(std::vector< int > &visibilityCount)
static bool GenerateRays(unsigned numberOfRays, std::vector< CCVector3 > &rays, bool mode360=true)
Generates a given number of rays.
static int Launch(unsigned numberOfRays, cloudViewer::GenericCloud *vertices, cloudViewer::GenericMesh *mesh=nullptr, bool meshIsClosed=false, bool mode360=true, unsigned width=1024, unsigned height=1024, cloudViewer::GenericProgressCallback *progressCb=nullptr, QString entityName=QString())
bool oneStep()
Increments total progress value of a single unit.
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)