예제 #1
0
Mesh Mesh::createBox(const Box3f &box) {
    Vector3f center = box.center();
    Vector3f extents = box.extents() * 0.5;
    Mesh mesh;
    int i = 0;
    for (int f = 0; f < 3; ++f) {
        for (int s = -1; s <= 1; s += 2) {
            Vector3f p(center), n(0.f), u(0.f), v(0.f);
            p[f] += extents[f] * s;
            n[f] = s;
            u[(f + 1) % 3] = extents[(f + 1) % 3];
            v[(f + 2) % 3] = extents[(f + 2) % 3];
            mesh.addVertex(p - u - v, n, Vector2f(0.f, 0.f));
            mesh.addVertex(p + u - v, n, Vector2f(1.f, 0.f));
            mesh.addVertex(p - u + v, n, Vector2f(0.f, 1.f));
            mesh.addVertex(p + u + v, n, Vector2f(1.f, 1.f));
            mesh.addTriangle(i, i + 1, i + 2);
            mesh.addTriangle(i + 1, i + 2, i + 3);
            i += 4;
        }
    }
    return mesh;
}
예제 #2
0
void Renderer::renderSLG() {

    FileUtils::createDir("slg");
    std::string currentDir = FileUtils::getCurrentDir();
    FileUtils::changeCurrentDir("slg");

    std::string imageFilename = tfm::format("../%s-images/frame-%04d.png", _animationName, _frameIndex);

    int width = 1280;
    int height = 720;
    int spp = 64;

    {
        std::ofstream os("render.cfg");
        os << "opencl.platform.index = -1" << std::endl;
        os << "opencl.cpu.use = 0" << std::endl;
        os << "opencl.gpu.use = 1" << std::endl;
        os << "opencl.gpu.workgroup.size = 64" << std::endl;
        os << "scene.epsilon.min = 9.99999971718068536574719e-10" << std::endl;
        os << "scene.epsilon.max = 0.100000001490116119384766" << std::endl;
        os << "renderengine.type = PATHOCL" << std::endl;
        os << "accelerator.instances.enable = 0" << std::endl;
        os << "path.maxdepth = 12" << std::endl;
        os << tfm::format("film.width = %d", width) << std::endl;
        os << tfm::format("film.height = %d", height) << std::endl;
        os << tfm::format("image.filename = %s", imageFilename) << std::endl;
        os << "sampler.type = RANDOM" << std::endl;
        os << "film.filter.type = GAUSSIAN" << std::endl;
        os << "film.filter.xwidth = 1" << std::endl;
        os << "film.filter.ywidth = 1" << std::endl;
        os << "scene.file = scene.scn" << std::endl;
        os << "film.imagepipeline.0.type = TONEMAP_LINEAR" << std::endl;
        os << "film.imagepipeline.1.type = GAMMA_CORRECTION" << std::endl;
        os << "film.imagepipeline.1.value = 2.2" << std::endl;
        os << tfm::format("batch.haltspp = %d", spp) << std::endl;
    }

    {
        std::ofstream os("scene.scn");

        Vector3f origin = _engine.camera().position();
        Vector3f target = _engine.camera().target();
        Vector3f up = _engine.camera().up();
        float fov = _engine.camera().fov() * 1.6f;

        os << tfm::format("scene.camera.lookat.orig = %f %f %f", origin.x(), origin.y(), origin.z()) << std::endl;
        os << tfm::format("scene.camera.lookat.target = %f %f %f", target.x(), target.y(), target.z()) << std::endl;
        os << tfm::format("scene.camera.up = %f %f %f", up.x(), up.y(), up.z()) << std::endl;
        os << tfm::format("scene.camera.fieldofview = %f", fov) << std::endl;

#if 0
#scene.camera.screenwindow = -1 1 -1 1
scene.camera.cliphither = 0.0010000000474974513053894
scene.camera.clipyon = 1.00000001504746621987669e+30
scene.camera.lensradius = 0.00218750000931322574615479
scene.camera.focaldistance = 0.28457677364349365234375
scene.camera.horizontalstereo.enable = 0
scene.camera.horizontalstereo.oculusrift.barrelpostpro.enable = 0
scene.camera.autofocus.enable = 1
#endif

        Vector3f dir = Vector3f(1.f).normalized();
#if 0
        os << tfm::format("scene.sunlight.dir = %f %f %f", dir.x(), dir.y(), dir.z()) << std::endl;
        os << "scene.sunlight.turbidity = 2.2" << std::endl;
        os << "scene.sunlight.relsize = 1" << std::endl;
        os << "scene.sunlight.gain = 0.0001 0.0001 0.0001" << std::endl;
#endif
        os << tfm::format("scene.skylight.dir = %f %f %f", dir.x(), dir.y(), dir.z()) << std::endl;
        os << "scene.skylight.turbidity = 2.2" << std::endl;
        os << "scene.skylight.gain = 0.00007 0.00007 0.00007" << std::endl;

        os << "scene.materials.fluid.type = matte" << std::endl;
        os << "scene.materials.fluid.kd = 0.3 0.3 1.0" << std::endl;
        os << "scene.materials.boundary.type = matte" << std::endl;
        os << "scene.materials.boundary.kd = 0.5 0.5 0.5" << std::endl;
        os << "scene.materials.floor.type = matte" << std::endl;
        os << "scene.materials.floor.kd = 0.2 0.2 0.2" << std::endl;

        // export fluid
        PlyWriter::save(_engine.fluidMesh(), "fluid.ply");
        os << "scene.objects.fluid.material = fluid" << std::endl;
        os << "scene.objects.fluid.ply = fluid.ply" << std::endl;

        // export boundaries
        const auto &boundaryMeshes = _engine.sph().boundaryMeshes();
        for (size_t i = 0; i < boundaryMeshes.size(); ++i) {
            std::string name = tfm::format("boundary-%03d", i);
            std::string filename = name + ".ply";
            PlyWriter::save(boundaryMeshes[i], filename);
            os << tfm::format("scene.objects.%s.material = boundary", name) << std::endl;
            os << tfm::format("scene.objects.%s.ply = %s", name, filename) << std::endl;
        }

        // export floor
        Box3f box = _engine.scene().world.bounds;
        box.max.y() = box.min.y();
        box.min.y() -= 0.01f * box.extents().norm();
        Mesh floorMesh = Mesh::createBox(box);
        PlyWriter::save(floorMesh, "floor.ply");
        os << "scene.objects.floor.material = floor" << std::endl;
        os << "scene.objects.floor.ply = floor.ply" << std::endl;
    }


    std::cout << std::endl;
    std::cout << tfm::format("Rendering frame %d with SLG4 ...", _frameIndex) << std::endl;

    try {
        std::string slg = "/home/freak/luxmark-v3.1/slg4";
        std::string arguments = "-o render.cfg";
        exec_stream_t es;
        // Set 1 minutes timeout
        es.set_wait_timeout(exec_stream_t::s_out | exec_stream_t::s_err | exec_stream_t::s_child, 60*1000);
        es.start(slg, arguments);

        std::string s;
        while (std::getline(es.err(), s).good()) {
            std::cout << s << std::endl;
            if (StringUtils::endsWith(StringUtils::trim(s), "Done.")) {
                DBG("detected finish");
                break;
            }
        }

        DBG("closing slg");
        if (!es.close()) {
            std::cerr << "SLG4 timeout!" << std::endl;
        }
        DBG("closed");
    } catch (const std::exception &e) {
        std::cerr << "exec-stream error: " << e.what() << "\n";
    }

    FileUtils::changeCurrentDir(currentDir);
}
예제 #3
0
void run(const std::string &filename, const Settings &settings) {
    DBG("Loading scene from '%s' ...", filename);
    Scene scene = Scene::load(filename);
    DBG("%s", scene.toString());
    SPH sph(scene);
    std::string cachePath = FileUtils::splitExtension(filename).first + ".cache";
    Cache cache(cachePath);

    if (settings.task == "mesh") {
        if (!cache.valid()) {
            throw Exception("Cache is invalid!");
        }

        Timer timer;

        int startFrame = std::max(settings.startFrame, 0);
        int endFrame = std::min(settings.endFrame + 1, cache.frameCount());

        for (int frame = startFrame; frame < endFrame; ++frame) {
            DBG("processing frame %d ...", frame);

            cache.setFrame(frame);

            std::vector<Vector3f> particles;
            cache.readParticles(particles);

            ParticleMesher::Parameters params;
            params.particleRadius = sph.parameters().particleRadius;
            params.particleDiameter = sph.parameters().particleDiameter;
            params.kernelRadius = sph.parameters().kernelRadius;
            params.kernelSupportParticles = sph.parameters().kernelSupportParticles;
            params.particleMass = sph.parameters().particleMass;
            params.restDensity = sph.parameters().restDensity;

            MatrixXf positions = toMatrix(particles);
            Box3f bounds = sph.bounds().expanded(sph.bounds().extents() * 0.05f); // expand bounds by 5% of diagonal
            Vector3f extents = bounds.extents();

            Vector3i cells(
                int(std::ceil(extents.x() / params.particleRadius)),
                int(std::ceil(extents.y() / params.particleRadius)),
                int(std::ceil(extents.z() / params.particleRadius))
            );

            bool anisotropic = false;
            params.isoLevel = anisotropic ? 0.2f : 0.75f;
            Mesh mesh = anisotropic ? ParticleMesher::createMeshAnisotropic(positions, bounds, cells, params)
                                    : ParticleMesher::createMeshIsotropic(positions, bounds, cells, params);
            cache.writeMesh(mesh);

            // Show time estimate
            float elapsed = timer.elapsed();
            float progress = float(frame - startFrame + 1) / (endFrame - startFrame);
            float eta = progress != 0.f ? elapsed / progress - elapsed : 0.f;
            DBG("Progress %.1f%% (Elapsed: %s ETA: %s)", progress * 100.f, timeString(elapsed), timeString(eta));

        }
        cache.commit();

    } else {
        throw Exception("Unknown task '%s'", settings.task);
    }
}