/**
 * - If the xml-file with camera intrinsics, extrinsics and distortion is missing,
 *   create it from the checkerboard video and the measured camera intrinsics
 * - After that initialize the scene rendering classes
 * - Run it!
 */
void VoxelReconstruction::run(int argc, char** argv)
{
	for (int v = 0; v < _cam_views_amount; ++v)
	{
		bool has_cam = Camera::detExtrinsics(_cam_views[v]->getDataPath(), General::CheckerboadVideo,
				General::IntrinsicsFile, _cam_views[v]->getCamPropertiesFile());
		if (has_cam) has_cam = _cam_views[v]->initialize();
		assert(has_cam);
	}

	destroyAllWindows();
	namedWindow(VIDEO_WINDOW, CV_WINDOW_KEEPRATIO);

	Reconstructor reconstructor(_cam_views);
	VoxelTracker voxeltracker(reconstructor, _cam_views, 4); //JV
	Scene3DRenderer scene3d(reconstructor, voxeltracker, _cam_views);
	Glut glut(scene3d);

#ifdef __linux__
	glut.initializeLinux(SCENE_WINDOW.c_str(), argc, argv);
#elif defined _WIN32
	glut.initializeWindows(SCENE_WINDOW.c_str());
	glut.mainLoopWindows();
#endif
}
bool Foam::fileOperations::autoParallelFileOperation::writeObject
(
    const regIOobject& io,
    IOstream::streamFormat fmt,
    IOstream::versionNumber ver,
    IOstream::compressionType cmp,
    const bool valid
) const
{
    bool ok = true;

    if (Pstream::parRun())
    {
        if (debug)
        {
            Pout<< indent
                << "autoParallelFileOperation::writeObject :"
                << " Searching for handler for type:" << io.type()
                << " of object: " << io.objectPath() << endl;
        }

        autoPtr<streamReconstructor> typeReconstructor
        (
            streamReconstructor::New(io.type())
        );

        if (typeReconstructor.valid())
        {
            const Time& runTime = io.time();

            Pout<< incrIndent;

            // Install basic file handler
            storeFileHandler defaultOp(basicFileHandler_);

            // Mapping engine from mesh to baseMesh (demand loads various)
            const parUnallocatedFvFieldReconstructor& mapper
                 = reconstructor(runTime);

            if (debug)
            {
                Pout<< indent
                    << "autoParallelFileOperation::writeObject :"
                    << " reconstructing and writing:" << io.name()
                    << " with handler for type:" << io.type()
                    << endl;
            }

            Pout<< decrIndent;

            typeReconstructor().reconstruct
            (
                mapper,
                io,
                false,          // no face flips. Tbd.
                fmt,
                ver,
                cmp
            );
        }
        else if
        (
            io.instance() == io.time().timeName()
         && io.local() == "uniform"
        )
        {
            if (valid)
            {
                // Copy of fileOperation::writeObject but with parent path

                fileName pathName
                (
                    io.rootPath()
                   /io.time().globalCaseName()
                   /io.instance()
                   /io.db().dbDir()
                   /io.local()
                   /io.name()
                );

                mkDir(pathName.path());

                autoPtr<Ostream> osPtr
                (
                    NewOFstream
                    (
                        pathName,
                        fmt,
                        ver,
                        cmp
                    )
                );

                if (!osPtr.valid())
                {
                    return false;
                }

                Ostream& os = osPtr();

                // If any of these fail, return (leave error handling to
                // Ostream class)
                if (!os.good())
                {
                    return false;
                }

                if (!io.writeHeader(os))
                {
                    return false;
                }

                // Write the data to the Ostream
                if (!io.writeData(os))
                {
                    return false;
                }

                IOobject::writeEndDivider(os);
            }
            return true;
        }
        else
        {
            ok = uncollatedFileOperation::writeObject
            (
                io,
                fmt,
                ver,
                cmp,
                valid
            );
        }
    }
    else
    {
        ok = uncollatedFileOperation::writeObject
        (
            io,
            fmt,
            ver,
            cmp,
            valid
        );
    }
    return ok;
}
bool Foam::fileOperations::autoParallelFileOperation::read
(
    regIOobject& io,
    const bool masterOnly,
    const IOstream::streamFormat format,
    const word& type
) const
{
    bool ok = true;

    if (Pstream::parRun())
    {
        if (debug)
        {
            Pout<< indent
                << "autoParallelFileOperation::read :"
                << " Searching for handler for type:" << type
                << " global:" << io.globalObject()
                << " masterOnly:" << masterOnly
                << " of object: " << io.objectPath() << endl;
        }
        autoPtr<streamReconstructor> typeReconstructor
        (
            streamReconstructor::New(type)
        );

        if (typeReconstructor.valid())
        {
            // Set flag for e.g. codeStream
            const bool oldGlobal = io.globalObject();
            io.globalObject() = masterOnly;
            // If codeStream originates from dictionary which is
            // not IOdictionary we have a problem so use global
            //const bool oldFlag = regIOobject::masterOnlyReading;
            //regIOobject::masterOnlyReading = masterOnly;


            // Find file, check in parent directory
            fileName objPath = filePath(oldGlobal, io, type);

            // Check if the file comes from the parent path
            fileName parentObjectPath =
                io.rootPath()/io.time().globalCaseName()
               /io.instance()/io.db().dbDir()/io.local()/io.name();

            if (debug)
            {
                Pout<< indent
                    << "io.objectPath   :" << io.objectPath() << nl
                    << indent
                    << "filePath        :" << objPath << nl
                    << indent
                    << "parentObjectPath:" << parentObjectPath << endl;
            }

            if (io.objectPath() != objPath && objPath == parentObjectPath)
            {
                const Time& runTime = io.time();

                // Install basic file handler
                storeFileHandler defaultOp(basicFileHandler_);

                Pout<< incrIndent;

                // Read local mesh
                const unallocatedFvMesh& procMesh = mesh(runTime);
                // Read undecomposed mesh. Read procAddressing files
                // (from runTime).
                const unallocatedFvMesh& baseUMesh = baseMesh(runTime);
                // Mapping engine from mesh to baseMesh
                const parUnallocatedFvFieldReconstructor& mapper
                     = reconstructor(runTime);

                IOobject baseIO
                (
                    io.name(),
                    io.instance(),
                    io.local(),
                    baseUMesh.thisDb(),
                    IOobject::MUST_READ,
                    IOobject::NO_WRITE,
                    false
                );

                OStringStream os(IOstream::BINARY);

                if (debug)
                {
                    Pout<< "autoParallelFileOperation::read :"
                        << " decompose and writing:" << baseIO.objectPath()
                        << endl;
                }
                bool ok = typeReconstructor().decompose
                (
                    mapper,
                    baseUMesh,
                    baseIO,
                    procMesh,
                    io,
                    false,              // no face flips. Tbd.
                    os
                );

                Pout<< decrIndent;

                if (ok)
                {
                    IStringStream is(os.str(), IOstream::BINARY);

                    // Read field from stream
                    ok = io.readData(is);
                    io.close();

                    if (debug)
                    {
                        const word oldName(io.name());
                        io.rename(oldName + '_' + typeName_());
                        io.write();
                        Pout<< indent
                            << "autoParallelFileOperation::read :"
                            << " sucessfully decomposed " << io.objectPath()
                            << " into " << io.objectPath()
                            << endl;
                        io.rename(oldName);
                    }
                }
                else
                {
                    if (debug)
                    {
                        Pout<< indent
                            << "autoParallelFileOperation::read :"
                            << " ** failed decomposing " << io.objectPath()
                            << endl;
                    }
                    return false;
                }
            }
            else
            {
                ok = io.readData(io.readStream(type));
                io.close();
            }

            // Restore flags
            io.globalObject() = oldGlobal;
            //regIOobject::masterOnlyReading = oldFlag;
        }
        else
        {
            ok = io.readData(io.readStream(type));
            io.close();
        }
    }
    else
    {
        ok = uncollatedFileOperation::read
        (
            io,
            masterOnly,
            format,
            type
        );
    }

    return ok;
}