std::vector<std::shared_ptr<Shape>> CreateCurveShape(const Transform *o2w, const Transform *w2o, bool reverseOrientation, const ParamSet ¶ms) { Float width = params.FindOneFloat("width", 1.f); Float width0 = params.FindOneFloat("width0", width); Float width1 = params.FindOneFloat("width1", width); int ncp; const Point3f *cp = params.FindPoint3f("P", &ncp); if (ncp != 4) { Error( "Must provide 4 control points for \"curve\" primitive. " "(Provided %d).", ncp); return std::vector<std::shared_ptr<Shape>>(); } CurveType type; std::string curveType = params.FindOneString("type", "flat"); if (curveType == "flat") type = CurveType::Flat; else if (curveType == "ribbon") type = CurveType::Ribbon; else if (curveType == "cylinder") type = CurveType::Cylinder; else { Error("Unknown curve type \"%s\". Using \"flat\".", curveType.c_str()); type = CurveType::Cylinder; } int nnorm; const Normal3f *n = params.FindNormal3f("N", &nnorm); if (n != nullptr) { if (type != CurveType::Ribbon) { Warning("Curve normals are only used with \"ribbon\" type curves."); n = nullptr; } else if (nnorm != 2) { Error( "Must provide two normals with \"N\" parameter for ribbon " "curves. " "(Provided %d).", nnorm); return std::vector<std::shared_ptr<Shape>>(); } } int sd = params.FindOneFloat("splitdepth", 2); if (type == CurveType::Ribbon && n == nullptr) { Error( "Must provide normals \"N\" at curve endpoints with ribbon " "curves."); return std::vector<std::shared_ptr<Shape>>(); } else return CreateCurve(o2w, w2o, reverseOrientation, cp, width0, width1, type, n, sd); }
std::shared_ptr<Medium> MakeMedium(const std::string &name, const ParamSet ¶mSet, const Transform &medium2world) { Float sig_a_rgb[3] = {.0011f, .0024f, .014f}, sig_s_rgb[3] = {2.55f, 3.21f, 3.77f}; Spectrum sig_a = Spectrum::FromRGB(sig_a_rgb), sig_s = Spectrum::FromRGB(sig_s_rgb); std::string preset = paramSet.FindOneString("preset", ""); bool found = GetMediumScatteringProperties(preset, &sig_a, &sig_s); if (preset != "" && !found) Warning("Material preset \"%s\" not found. Using defaults.", preset.c_str()); Float scale = paramSet.FindOneFloat("scale", 1.f); Float g = paramSet.FindOneFloat("g", 0.0f); sig_a = paramSet.FindOneSpectrum("sigma_a", sig_a) * scale; sig_s = paramSet.FindOneSpectrum("sigma_s", sig_s) * scale; Medium *m = NULL; if (name == "homogeneous") { m = new HomogeneousMedium(sig_a, sig_s, g); } else if (name == "heterogeneous") { int nitems; const Float *data = paramSet.FindFloat("density", &nitems); if (!data) { Error("No \"density\" values provided for heterogeneous medium?"); return NULL; } int nx = paramSet.FindOneInt("nx", 1); int ny = paramSet.FindOneInt("ny", 1); int nz = paramSet.FindOneInt("nz", 1); Point3f p0 = paramSet.FindOnePoint3f("p0", Point3f(0.f, 0.f, 0.f)); Point3f p1 = paramSet.FindOnePoint3f("p1", Point3f(1.f, 1.f, 1.f)); if (nitems != nx * ny * nz) { Error( "GridDensityMedium has %d density values; expected nx*ny*nz = " "%d", nitems, nx * ny * nz); return NULL; } Transform data2Medium = Translate(Vector3f(p0)) * Scale(p1.x - p0.x, p1.y - p0.y, p1.z - p0.z); m = new GridDensityMedium(sig_a, sig_s, g, nx, ny, nz, medium2world * data2Medium, data); } else Warning("Medium \"%s\" unknown.", name.c_str()); paramSet.ReportUnused(); return std::shared_ptr<Medium>(m); }
std::shared_ptr<BVHAccel> CreateBVHAccelerator( const std::vector<std::shared_ptr<Primitive>> &prims, const ParamSet &ps) { std::string splitMethodName = ps.FindOneString("splitmethod", "sah"); BVHAccel::SplitMethod splitMethod; if (splitMethodName == "sah") splitMethod = BVHAccel::SplitMethod::SAH; else if (splitMethodName == "hlbvh") splitMethod = BVHAccel::SplitMethod::HLBVH; else if (splitMethodName == "middle") splitMethod = BVHAccel::SplitMethod::Middle; else if (splitMethodName == "equal") splitMethod = BVHAccel::SplitMethod::EqualCounts; else { Warning("BVH split method \"%s\" unknown. Using \"sah\".", splitMethodName.c_str()); splitMethod = BVHAccel::SplitMethod::SAH; } int maxPrimsInNode = ps.FindOneInt("maxnodeprims", 4); return std::make_shared<BVHAccel>(prims, maxPrimsInNode, splitMethod); }
// NaiadMesh Method Definitions NaiadMesh::NaiadMesh(const Transform *o2w, const Transform *w2o, bool ro, const ParamSet ¶ms) : Shape(o2w, w2o, ro) { Nb::begin(); const char * empStr = params.FindOneString("emp","error").c_str(); const char * bodyStr = params.FindOneString("body","error").c_str(); Nb::EmpReader empReader(empStr,"*"); const Nb::Body * body = empReader.ejectBody(bodyStr); //Load shapes from Naiad body const Nb::TriangleShape& triangle = body->constTriangleShape(); const Nb::PointShape& point = body->constPointShape(); //Get buffers const Nb::Buffer3f& posBuf(point.constBuffer3f("position")); const Nb::Buffer3i& triIdxBuf(triangle.constBuffer3i("index")); ntris = triIdxBuf.size(); nverts = posBuf.size(); std::cout << "NaiadMesh:: Found " << nverts << " vertices." << std::endl; std::cout << "NaiadMesh:: Found " << ntris << " triangles." << std::endl; vertexIndex = new int[3 * ntris]; for (int i = 0; i < ntris; ++i) { vertexIndex[3*i ] = triIdxBuf[i].v[0]; vertexIndex[3*i + 1] = triIdxBuf[i].v[1]; vertexIndex[3*i + 2] = triIdxBuf[i].v[2]; } //memcpy(vertexIndex, &triIdxBuf[0], 3 * ntris * sizeof(int)); float dispSurface = params.FindOneFloat("disp_surface",0.f); p = new Point[nverts]; for (int i = 0; i < nverts; ++i) { Point P(posBuf[i].v[0], posBuf[i].v[1], posBuf[i].v[2]); if (dispSurface) { const Nb::Buffer3f& normalBuf(point.constBuffer3f("normal")); P.x += normalBuf[i].v[0] * dispSurface; P.y += normalBuf[i].v[1] * dispSurface; P.z += normalBuf[i].v[2] * dispSurface; } p[i] = (*ObjectToWorld)(P); #ifdef VDB if (ntris > 50000) { vdb_sample(0.1); vdb_color(0.5f, 0.8f, 1.0f); } else { vdb_sample(1.0); vdb_color(0.5f, 0.5f, 0.5f); } vdb_point(p[i].x,p[i].y,p[i].z); #endif } string uv_empStr = params.FindOneString("uv_emp","error"); if (uv_empStr != string("error")) { Nb::EmpReader empReaderUV(uv_empStr.c_str(),"*"); string uv_bodyStr = params.FindOneString("uv_body","error"); const Nb::Body * bodyUV = empReaderUV.ejectBody(uv_bodyStr.c_str()); const Nb::TriangleShape& tUV = bodyUV->constTriangleShape(); const Nb::Buffer3i& uvIdx(tUV.constBuffer3i("index")); const Nb::Buffer3f& bufU(tUV.constBuffer3f("u")); const Nb::Buffer3f& bufV(tUV.constBuffer3f("v")); uvs = new float[2*nverts]; for (int i = 0; i < uvIdx.size(); ++i) { int v0 = triIdxBuf[i].v[0]; int v1 = triIdxBuf[i].v[1]; int v2 = triIdxBuf[i].v[2]; uvs[2*v0] = bufU[i].v[0]; uvs[2*v0 + 1] = bufV[i].v[0]; uvs[2*v1] = bufU[i].v[1]; uvs[2*v1 + 1] = bufV[i].v[1]; uvs[2*v2] = bufU[i].v[2]; uvs[2*v2 + 1] = bufV[i].v[2]; } } else uvs = NULL; //No need for these parameters yet. //uvs = NULL; n = NULL; s = NULL; //For foam zbuffer foam_block = params.FindOneFloat("foam_block", 0.f); Nb::end(); }