Пример #1
0
int calc_vertex_normal(struct stl_reader *r, int fi, int vi, float normal[3])
{
	int i, ref = 0;
	float n[3];
	assert(fi>-1);
	assert(vi>-1);
	assert(fi<r->nf);
	assert(vi<r->nv);
	n[0] = r->f[fi].normal[0];
	n[1] = r->f[fi].normal[1];
	n[2] = r->f[fi].normal[2];
	for (i=0; i<r->nf && ref<r->v[vi].refcnt; i++) {
		if (i!=fi && (r->f[i].vertex[0]==vi
		    ||r->f[i].vertex[1]==vi
		    ||r->f[i].vertex[2]==vi)) {
			ref++;
			if (cosphi(r->f[i].normal,r->f[fi].normal)>cflimit 
			    && maxdim(r, i)/maxdim(r, fi)>dimlimit) {
				n[0] += r->f[i].normal[0];
				n[1] += r->f[i].normal[1];
				n[2] += r->f[i].normal[2];
			}
		}
	}
	normalize(n);
	memcpy(normal, n, sizeof(float[3]));
	if (fabsf(n[0]-r->f[fi].normal[0])>eps 
	    || fabsf(n[1]-r->f[fi].normal[1])>eps 
	    || fabsf(n[2]-r->f[fi].normal[2])>eps)
		return 1; /* vertex normal _not_ equal to facet normal */
	return 0; /* vertex normal equal to facet normal */
}
Пример #2
0
///< The function projects latitude-longitude environment map to SH basis up to lmax band
void ShProjectEnvironmentMap(float3 const* envmap, int width, int height, int lmax, float3* coeffs)
{
    // Resulting coefficients for RGB
    // std::vector<float3> coeffs(NumShTerms(lmax));
    // Temporary coefficients storage
    std::vector<float>  ylm(NumShTerms(lmax));

    // Precompute sin and cos for the sphere
    std::vector<float> sintheta(height);
    std::vector<float> costheta(height);
    std::vector<float> sinphi(width);
    std::vector<float> cosphi(width);

    float thetastep = PI / height;
    float phistep = 2.f * PI / width;
    float theta0 = PI / height / 2;
    float phi0 = 2.f * PI / width / 2;

    for (int i = 0; i < width; ++i)
    {
        sinphi[i] = std::sin(phi0 + i * phistep);
        cosphi[i] = std::cos(phi0 + i * phistep);
    }

    for (int i = 0; i < height; ++i)
    {
        sintheta[i] = std::sin(theta0 + i * thetastep);
        costheta[i] = std::cos(theta0 + i * thetastep);
    }

    // Iterate over the pixels calculating Riemann sum
    for (int phi = 0; phi < width; ++phi)
    {
        for (int theta = 0; theta < height; ++theta)
        {
            // Construct direction vector
            float3 w = normalize(float3(sintheta[theta] * cosphi[phi], costheta[theta], sintheta[theta] * sinphi[phi]));

            // Construct uv sample coordinates
            float2 uv = float2((float)phi / width, (float)theta / height);

            // Sample environment map
            int iu = (int)floor(uv.x * width);
            int iv = (int)floor(uv.y * height);

            float3 le = envmap[width * iv + iu];

            // Evaluate SH functions at w up to lmax band
            ShEvaluate(w, lmax, &ylm[0]);

            // Evaluate Riemann sum accouting for solid angle conversion (sin term)
            for (int i = 0; i < NumShTerms(lmax); ++i)
            {
                coeffs[i] += le * ylm[i] * sintheta[theta] * (PI / height) * (2.f * PI / width);
            }
        }
    }
}
Пример #3
0
///< The function evaluates SH functions and dumps values to latitude-longitude map
void ShEvaluateAndDump(ImageIo& io, std::string const& filename,  int width, int height, int lmax, float3 const* coeffs)
{
    // Prepare image memory
    std::vector<float> imagedata(width * height * 3);

    // Allocate space for SH functions
    std::vector<float> ylm(NumShTerms(lmax));

    // Precalculate sin and cos terms 
    std::vector<float> sintheta(height);
    std::vector<float> costheta(height);
    std::vector<float> sinphi(width);
    std::vector<float> cosphi(width);

    float thetastep = PI / height;
    float phistep = 2.f*PI / width;
    float theta0 = PI / height / 2;
    float phi0= 2.f*PI / width / 2;

    for (int i = 0; i < width; ++i)
    {
        sinphi[i] = std::sin(phi0 + i * phistep);
        cosphi[i] = std::cos(phi0 + i * phistep);
    }

    for (int i = 0; i < height; ++i)
    {
        sintheta[i] = std::sin(theta0 + i * thetastep);
        costheta[i] = std::cos(theta0 + i * thetastep);
    }

    // Iterate thru image pixels
    for (int phi = 0; phi < width; ++phi)
    {
        for (int theta = 0; theta < height; ++theta)
        {
            // Calculate direction
            float3 w = normalize(float3(sintheta[theta] * cosphi[phi], costheta[theta], sintheta[theta] * sinphi[phi]));

            // Evaluate SH functions at w up to lmax band
            ShEvaluate(w, lmax, &ylm[0]);

            // Evaluate function injecting SH coeffs
            for (int i = 0; i < NumShTerms(lmax); ++i)
            {
                imagedata[theta * width * 3 + phi * 3] += ylm[i] * coeffs[i].x;
                imagedata[theta * width * 3 + phi * 3 + 1] += ylm[i] * coeffs[i].y;
                imagedata[theta * width * 3 + phi * 3 + 2] += ylm[i] * coeffs[i].z;
            }
        }
    }

    // Write image to file
    ImageIo::ImageDesc imgdesc(width, height, 3);
    io.Write(filename, imagedata, imgdesc);
}
Пример #4
0
///< The function projects latitude-longitude environment map to SH basis up to lmax band
void ShProjectEnvironmentMap(TextureSystem const& texsys, std::string const& texture, int lmax, float3* coeffs)
{
    // Resulting coefficients for RGB
    // std::vector<float3> coeffs(NumShTerms(lmax));
    // Temporary coefficients storage
    std::vector<float>  ylm(NumShTerms(lmax));

    // Get texture width and height
    TextureSystem::TextureDesc texdesc;
    texsys.GetTextureInfo(texture, texdesc);

    // Precompute sin and cos for the sphere
    std::vector<float> sintheta(texdesc.height);
    std::vector<float> costheta(texdesc.height);
    std::vector<float> sinphi(texdesc.width);
    std::vector<float> cosphi(texdesc.width);

    float thetastep = PI / texdesc.height;
    float phistep = 2.f*PI / texdesc.width;
    float theta0 = PI / texdesc.height / 2;
    float phi0 = 2.f*PI / texdesc.width / 2;

    for (int i = 0; i < texdesc.width; ++i)
    {
        sinphi[i] = std::sin(phi0 + i * phistep);
        cosphi[i] = std::cos(phi0 + i * phistep);
    }

    for (int i = 0; i < texdesc.height; ++i)
    {
        sintheta[i] = std::sin(theta0 + i * thetastep);
        costheta[i] = std::cos(theta0 + i * thetastep);
    }

    // Iterate over the pixels calculating Riemann sum
    for (int phi = 0; phi < texdesc.width; ++phi)
    {
        for (int theta = 0; theta < texdesc.height; ++theta)
        {
            // Construct direction vector
            float3 w = normalize(float3(sintheta[theta] * cosphi[phi], costheta[theta], sintheta[theta] * sinphi[phi]));

            // Construct uv sample coordinates
            float2 uv = float2((float)phi / texdesc.width, (float)theta / texdesc.height);

            // Sample environment map
            TextureSystem::Options opts;
            opts.wrapmode = TextureSystem::Options::kRepeat;
            opts.filter= TextureSystem::Options::kPoint;
            float3 le = texsys.Sample(texture, uv, float2());

            // Evaluate SH functions at w up to lmax band
            ShEvaluate(w, lmax, &ylm[0]);

            // Evaluate Riemann sum accouting for solid angle conversion (sin term)
            for (int i = 0; i < NumShTerms(lmax); ++i)
            {
                coeffs[i] += le * ylm[i] * sintheta[theta] * (PI / texdesc.height) * (2.f * PI / texdesc.width);
            }
        }
    }
}