// AreaLight Method Definitions AreaLight::AreaLight(const Transform &light2world, const Spectrum &le, int ns, const Reference<Shape> &s) : Light(light2world, ns) { Lemit = le; if (s->CanIntersect()) shape = s; else { // Create _ShapeSet_ for _Shape_ Reference<Shape> shapeSet = s; vector<Reference<Shape> > todo, done; todo.push_back(shapeSet); while (todo.size()) { Reference<Shape> sh = todo.back(); todo.pop_back(); if (sh->CanIntersect()) done.push_back(sh); else sh->Refine(todo); } if (done.size() == 1) shape = done[0]; else { if (done.size() > 16) Warning("Area light geometry turned into %d shapes; " "may be very inefficient.", (int)done.size()); shape = new ShapeSet(done, s->ObjectToWorld, s->reverseOrientation); } } area = shape->Area(); }
void Primitive::FullyRefine(std::vector<Reference<Primitive> > &refined) const { std::vector<Reference<Primitive> > todo; todo.push_back(const_cast<Primitive *>(this)); while (todo.size()) { // Refine last primitive in todo list Reference<Primitive> prim = todo.back(); todo.pop_back(); if (prim->CanIntersect()) refined.push_back(prim); else prim->Refine(todo); } };
// ShapeSet Method Definitions ShapeSet::ShapeSet(const Reference<Shape> &s) { vector<Reference<Shape> > todo; todo.push_back(s); while (todo.size()) { Reference<Shape> sh = todo.back(); todo.pop_back(); if (sh->CanIntersect()) shapes.push_back(sh); else sh->Refine(todo); } if (shapes.size() > 64) Warning("Area light geometry turned into %d shapes; " "may be very inefficient.", (int)shapes.size()); // Compute total area of shapes in _ShapeSet_ and area CDF sumArea = 0.f; for (uint32_t i = 0; i < shapes.size(); ++i) { float a = shapes[i]->Area(); areas.push_back(a); sumArea += a; } areaDistribution = new Distribution1D(&areas[0], areas.size()); }