private Part GetPartAtVoxelPos(int i, int j, int k, ref VoxelChunk section)
 {
     return section.GetVoxelPartGlobalIndex(i + j * 8 + k * 64);
 }
        //Use when guaranteed that you will not attempt to write to the same section simultaneously
        private void SetVoxelPointNoLock(int i, int j, int k, Part part)
        {
            int iSec, jSec, kSec;
            //Find the voxel section that this point points to

            iSec = i >> 3;
            jSec = j >> 3;
            kSec = k >> 3;

            VoxelChunk section;

            section = voxelChunks[iSec, jSec, kSec];
            if (section == null)
            {
                lock(clearedChunks)
                {
                    if(clearedChunks.Count > 0)
                    {
                        section = clearedChunks.Pop();
                    }
                }
                if (section == null)
                    section = new VoxelChunk(elementSize, lowerRightCorner + new Vector3d(iSec, jSec, kSec) * elementSize * 8, iSec * 8, jSec * 8, kSec * 8, overridingParts);
                else
                    section.SetChunk(elementSize, lowerRightCorner + new Vector3d(iSec, jSec, kSec) * elementSize * 8, iSec * 8, jSec * 8, kSec * 8, overridingParts);

                voxelChunks[iSec, jSec, kSec] = section;
            }

            //Debug.Log(i.ToString() + ", " + j.ToString() + ", " + k.ToString() + ", " + part.partInfo.title);

            section.SetVoxelPointGlobalIndexNoLock(i + j * 8 + k * 64, part);
        }
        private void DetermineIfPartGetsForcesAndAreas(Dictionary<Part, VoxelCrossSection.SideAreaValues> partSideAreas, VoxelChunk.PartSizePair voxel, int i, int j, int k)
        {
            VoxelCrossSection.SideAreaValues areas;
            VoxelOrientationPlane filledPlanes = VoxelOrientationPlane.NONE;
            bool partGetsForces = true;

            Part p = voxel.part;

            if (!partSideAreas.TryGetValue(p, out areas))
            {
                areas = new VoxelCrossSection.SideAreaValues();
                partGetsForces = false;
            }
            if (i + 1 >= xCellLength || (object)GetPartAtVoxelPos(i + 1, j, k) == null)
            {
                areas.iP += elementSize * elementSize;
                areas.exposedAreaCount++;
                partGetsForces = true;
            }
            else
                filledPlanes |= VoxelOrientationPlane.X_UP;

            if (i - 1 < 0 || (object)GetPartAtVoxelPos(i - 1, j, k) == null)
            {
                areas.iN += elementSize * elementSize;
                areas.exposedAreaCount++;
                partGetsForces = true;
            }
            else
                filledPlanes |= VoxelOrientationPlane.X_DOWN;

            if (j + 1 >= yCellLength || (object)GetPartAtVoxelPos(i, j + 1, k) == null)
            {
                areas.jP += elementSize * elementSize;
                areas.exposedAreaCount++;
                partGetsForces = true;
            }
            else
                filledPlanes |= VoxelOrientationPlane.Y_UP;

            if (j - 1 < 0 || (object)GetPartAtVoxelPos(i, j - 1, k) == null)
            {
                areas.jN += elementSize * elementSize;
                areas.exposedAreaCount++;
                partGetsForces = true;
            }
            else
                filledPlanes |= VoxelOrientationPlane.Y_DOWN;

            if (k + 1 >= zCellLength || (object)GetPartAtVoxelPos(i, j, k + 1) == null)
            {
                areas.kP += elementSize * elementSize;
                areas.exposedAreaCount++;
                partGetsForces = true;
            }
            else
                filledPlanes |= VoxelOrientationPlane.Z_UP;

            if (k - 1 < 0 || (object)GetPartAtVoxelPos(i, j, k - 1) == null)
            {
                areas.kN += elementSize * elementSize;
                areas.exposedAreaCount++;
                partGetsForces = true;
            }
            else
                filledPlanes |= VoxelOrientationPlane.Z_DOWN;

            if (partGetsForces)
            {
                areas.crossSectionalAreaCount++;
                partSideAreas[p] = areas;
            }

            voxel.SetFilledSides(filledPlanes);
        }