/** * Compute the diffusely reemited light data and place the result into reemited. * localBasis : the object localBasis at the computation point. * surfaceCoordinate : the surface coordinate (texture coordinate) of the computation * point on the object. * incident : the incident ray (light ray) * view : the view ray (from the camera or bounced) * incidentLight : the incident light comming from the incident ray. * reemitedLight : the light reemited into the view direction (result will be placed * here). */ void RoughLambertianBRDF::getDiffuseReemited(const Basis& localBasis, const Point2D& surfaceCoordinate, const LightVector& incidentLight, LightVector& reemitedLight) { Vector view = reemitedLight.getRay().v; Vector incident = incidentLight.getRay().v; Real cosOi = -incident.dot(localBasis.k); Real cosOv = -view.dot(localBasis.k); if(cosOi <= 0) { reemitedLight.clear(); return; } if(cosOi>=1.0) cosOi=1.0; if(cosOv>=1.0) cosOv=1.0; Real Oi = std::acos(cosOi); Real Ov = std::acos(cosOv); Real Pi = std::atan2(incident.dot(localBasis.j), incident.dot(localBasis.i)); Real Pv = std::atan2(view.dot(localBasis.j), view.dot(localBasis.i)); Real factor = OrenNayarFormula::orenNayarReflectance(Oi, Pi, Ov, Pv, _roughness); for(unsigned int i=0; i<reemitedLight.size(); i++) reemitedLight[i].setRadiance(incidentLight[i].getRadiance()*_spectrum[incidentLight[i].getIndex()]*factor); reemitedLight.changeReemitedPolarisationFramework(localBasis.k); }
/** * Compute the estimated reflected radiance. * @param localBasis : the local basis at the computation point. * @param surfaceCoordinate : the local surface coordinate at the computation point. * @param object : the surface that reflect the light. * @param radius : the initial radius search for the nearest photon photon search pass. * @param nb_poton : the number of nearest pĥoton to take count in the computation. * @param lightdata : the reflected light data to compute. */ inline void MultispectralPhotonMap::getEstimation(const Basis& localBasis, const Point2D& surfaceCoordinate, Object& object, Real radius, int nb_photon, LightVector& lightdata) { lightdata.clear(); //Get the nearest photons std::vector<MultispectralPhoton*> photons; Real r2 = _tree.getNearestNeighbor(localBasis.o, nb_photon, radius, localBasis.k, photons); if(r2==0.0) return; Real invarea = 1.0/(M_PI*r2); Real photonPower = _photonPower*invarea; LightVector incident; LightVector reemited; reemited.initGeometricalData(lightdata); for(unsigned int i=0; i<photons.size(); i++) { Real weight = photonPower/std::abs(photons[i]->direction.dot(localBasis.k)); reemited.initSpectralData(lightdata); incident.initSpectralData(lightdata); incident.changeReemitedPolarisationFramework(localBasis.k); for(unsigned int k=0; k<lightdata.size(); k++) incident[k].setRadiance(weight*photons[i]->radiance[lightdata[k].getIndex()]); incident.setRay(photons[i]->position, photons[i]->direction); object.getDiffuseReemited(localBasis, surfaceCoordinate, incident, reemited); lightdata.add(reemited); } lightdata.changeReemitedPolarisationFramework(localBasis.k); }
void outputGNUPlot(LightVector<XY>& points, char* filename) { ofstream of; of.open(filename); unsigned int n = points.size(); for (unsigned int i = 0; i<n; ++i) { of<<points[i].x()<<" "<<points[i].y()<<" "<<points[(i+1)%n].x()<<" "<<points[(i+1)%n].y()<<endl; } of.close(); }
/** * Compute the absorption of a light ray through the medium. */ inline void Medium::transportLight(LightVector& light) const { if(isOpaque) { light.clear(); return; } if(useLambertianModel) { for(unsigned int i=0; i<light.size(); i++) light[i].mul(t[light[i].getIndex()]); } if(useFresnelModel) { for(unsigned int i=0; i<light.size(); i++) { Real a = DielectricFormula::dielectricAbsorption(light.getDistance(), GlobalSpectrum::getWaveLength(light[i].getIndex())*1E-9, k[light[i].getIndex()]); light[i].mul(a); } } }
LightVector<TriMesh::VertexHandle> ring::getRing(TriMesh::VertexHandle _vh, int k) // returns all vertices that are within the k-ring of the vertex vh { if (!initialised) init(); int aux; int epoch_base = epoch; epoch++; //std::list<TriMesh::VertexHandle> lik; TriMesh::VertexHandle vh; TriMesh::VertexVertexIter vvi, vvstart; mesh.property(epochs, _vh) = epoch+1; LightVector<TriMesh::VertexHandle> vect; vect.push_back(_vh); unsigned int i = 0; while (i < vect.size()) { vh = vect[i]; aux = mesh.property(epochs, vh); if (aux > epoch_base + k+1) break; // we have finished exploring all the vertices from the k-1 ring. if (aux == epoch + 1) ++epoch; // finished all vertices in the current epoch, go to next ring vvstart = vvi = mesh.vv_iter(vh); do { vh = vvi.handle(); aux = mesh.property(epochs, vh); if (aux <= epoch_base) // node has not been visited yet { mesh.property(epochs, vh) = epoch+1; vect.push_back(vh); } else { // the node has been visted already and has been added to vect, continue } ++vvi; } while (vvi); ++i; // move to next vertex } // i < vect.size() return vect; } // void getRing(TriMesh mesh, TriMesh::VertexHandle _vh, int k)
void BeckmannBRDF::getDiffuseReemitedFromAmbiant(const Basis& localBasis, const Point2D& surfaceCoordinate, LightVector& reemitedLight, const Spectrum& incident) { const Vector& light = localBasis.k; const Vector& view = reemitedLight.getRay().v; //Computing the micro normal Vector microNormal; microNormal.setsum(light, view); microNormal.mul(-1.0); microNormal.normalize(); //Computing some cosinuses and sinuses Real cosLN = -localBasis.k.dot(light); // light and normal Real cosVN = -localBasis.k.dot(view); // view and normal Real cosHN = localBasis.k.dot(microNormal); // micro normal and normal Real cosLH = -microNormal.dot(light); // light and micro normal Real cosVH = -microNormal.dot(view); // view and micro normal //Compute Beckmann and Shadowing&masking coeficients Real beckmann = BeckmannRoughnessFormula::BeckmannDistribution(cosHN, _roughness); Real shadmask = BeckmannRoughnessFormula::BeckmannShadowMasking(cosLN, cosVN, cosVH, cosHN); if(cosVN <=0.001 ) { reemitedLight.clear(); return; } for(unsigned int wl=0; wl < reemitedLight.size(); wl++) { Real ROrth, RPara; getReflectance(cosLH, wl, ROrth, RPara); ROrth *= beckmann * shadmask; RPara *= beckmann * shadmask; reemitedLight[wl].setRadiance(incident[wl] /** cosVN*/ * 0.5 * (ROrth + RPara)); } reemitedLight.changeReemitedPolarisationFramework(microNormal); }
// https://msdn.microsoft.com/en-us/library/ms182372.aspx -< Profiler int main(int argc, char **argv) { //ann_test(); glutInit(&argc, argv); ValenceViewer window("Wireframe", 512, 512); // window.open_mesh("bunny.off"); window.open_mesh("torus(10,3,50).off"); glutMainLoop(); /* cgal<myPoint> cg; pointSet<myPoint> ps("pentagram.pts"); cg = ps; cg.polyStats(); cout<<cg.inside(Point(15,0))<<endl; // yes cout<<cg.inside(Point(15,0.5))<<endl; // yes cout<<cg.inside(Point(1,1))<<endl; // yes cout<<cg.inside(Point(100,100))<<endl; // no return; */ // testMyPolyTriangulation(); /* LightVector<double> angles(7); angles.fill(0); // double lens[7] = {3, 6, 8, 10, 4, 9, 2}; double lens[7] = {10, 3, 8, 10, 4, 9, 7}; LightVector<double> edgeLengths(7, lens); mp.init(angles, edgeLengths); mp.list(); mp.breakDown(1.618, true); // use the golden ratio, go clockwise mp.list(); mp.breakDown(1.618, false); // use the golden ratio, go counter-clockwise mp.list(); mp.head->clear(); mp.head = NULL; return; */ //tutorial1(); //tutorial2("tetrahedron.off", "tetrahedron2.off",5); //tutorial1Hu(); // Mat3 m(1,2,3,4,4,6,7,8,9); // Mat3 m2 = m.inverse(); // cout<<m.determinant()<<endl; // cout<<m2; TriMesh mesh2 = createTorus(10, 3, 50); ring ri(mesh2); LightVector<TriMesh::VertexHandle> vhv = ri.getRing(TriMesh::VertexHandle(0), 2); for (unsigned int i= 0; i<vhv.size(); ++i) { cout<< vhv[i]<<" "; } OpenMesh::IO::write_mesh(mesh2, "torus.off"); mesh2.request_face_normals(); mesh2.request_vertex_normals(); mesh2.update_normals(); TriMesh::VertexHandle vh = TriMesh::VertexHandle(5); TriMesh::VertexFaceIter vfi = mesh2.vf_iter(vh); int cc=0; OpenMesh::Vec3f norm (0, 0, 0), normv; while (vfi) { cout<<"+"<<vfi.handle()<<endl; norm += mesh2.normal(*vfi); ++cc; ++vfi; } double len = norm.length(); if (len != 0) { norm *= 1/len; } normv = mesh2.normal(vh); meshVolume(mesh2); return 0; TriMesh mesh; //mesh = createSphere(2.0f,4); OpenMesh::IO::write_mesh(mesh, "tetraSphere.off"); //mesh = createTetra(2); OpenMesh::IO::write_mesh(mesh, "tetra.off"); readmesh(mesh, "tetra.off"); // readmesh(mesh, "sphereholes.off"); readmesh(mesh, "lyukas.off"); // suboptimal, add normals to all faces while we need it only for the 1-ring around the hole if ( ! mesh.has_face_normals()) mesh.request_face_normals(); // mesh.update_normals(); holeFiller hf(mesh); hf.findHoles(); hf.displayHoles(); // hf.fill(0); // Az emberkeben, i.e. readmesh(mesh, "lyukas.off"); // hf.fill(0); // hat // hf.fill(1); // has hf.fill(2); // fej // printOff(mesh, holes[2]); mesh.release_face_normals(); // always release after request // closeHole(mesh, holes[1]); // closeHole(mesh, holes[0]); // closeHole(mesh, holes[2]); /* mesh.request_face_normals(); if (mesh.has_vertex_normals() ) mesh.update_vertex_normals(); for (; v_it!=v_end; ++v_it) this->set_normal(v_it.handle(), calc_vertex_normal(v_it.handle())); */ /* readmesh(mesh, "icosahedron.off"); OpenMesh::Vec3f P(-2,0.2,2); OpenMesh::FaceHandle fh = faceClosestToPoint(mesh,P); cout<<fh.idx(); extendMesh(mesh, fh, P, true); OpenMesh::IO::write_mesh(mesh, "ico--.off"); */ //cout<<"Volume = "<<meshVolume(mesh)<<endl; // OpenMesh::IO::write_mesh(mesh, "spherevolt.off"); OpenMesh::IO::write_mesh(mesh, "lyukasvolt.off"); } // void main()