public void Init(MeshManager manager, Data data, MeshPatternDelta delta)
    {
        m_data    = data;
        m_delta   = delta;
        m_manager = manager;

        CalcBounds();
    }
    public IEnumerator Convert()
    {
        // check if this is totally out of bounds
        if (m_voxelStart.x >= m_manager.m_blob.width || m_voxelStart.y >= m_manager.m_blob.height ||
            m_voxelStart.z >= m_manager.m_blob.depth || m_voxelEnd.x < 0 || m_voxelEnd.y < 0 ||
            m_voxelEnd.z < 0)
        {
            if (m_delta != null)
            {
                m_delta.MarkConversionDone();
            }
            gameObject.SetActive(false);
            Destroy(gameObject);
            yield break;
        }

        /// Create an Octree for the altered faces
        m_meshOctree = new Octree(0, m_data.faces, m_lowerBound, m_upperBound);

        if (m_delta == null)
        {
            m_delta = new MeshPatternDelta(this, m_data, m_manager.chunkSize);
            m_manager.PushNewDelta(m_delta);
        }

        if (Scheduler.ShouldYield())
        {
            yield return(null);
        }
        if (shouldAbort)
        {
            yield break;
        }

        IWaitCondition[] waitConds = new IWaitCondition[3];
        for (int dir = 0; dir < 3; ++dir)
        {
            waitConds[dir] = new WaitCoroutine(Scheduler.StartCoroutine(CreateVoxelsFromDirection(dir)));
        }

        yield return(new WaitAll(waitConds));

        if (!shouldAbort)
        {
            m_delta.MarkConversionDone();
        }

        gameObject.SetActive(false);
        Destroy(gameObject);
        Dispatcher.RemoveListener(MenuController.kEventNewBlob, CancelConversion);
    }