void AddAllDescendants(long startingID, int level, VoxelBinClass voxel0, int shortDimension = -1, int numShortLayers = -1) { var lowerLevelVoxels = AddAllDescendants(startingID, level, shortDimension, numShortLayers); lock (voxel0.InnerVoxels[level]) voxel0.InnerVoxels[level].AddRange(lowerLevelVoxels); }
private long ChangeEmptyVoxelToPartial(long ID, int level) { long voxel; if (level == 0) { //adding a new level-0 voxel is fairly straightforward var voxelbin = new VoxelBinClass(ID, VoxelRoleTypes.Partial, this); lock (voxelDictionaryLevel0) voxelDictionaryLevel0.AddOrReplace(voxelbin); voxelbin.ID = Constants.ClearFlagsFromID(ID) + Constants.MakeFlags(level, VoxelRoleTypes.Partial); return(voxelbin.ID); } // for the lower levels, first get or make the level-0 voxel (next7 lines) var thisIDwoFlags = Constants.ClearFlagsFromID(ID); var id0 = MakeParentVoxelID(thisIDwoFlags, 0); VoxelBinClass voxel0; lock (voxelDictionaryLevel0) { if (!voxelDictionaryLevel0.Contains(id0)) { ChangeEmptyVoxelToPartial(id0, 0); } voxel0 = voxelDictionaryLevel0.GetVoxel(id0); } // make the new Voxel, and add it to the proper hashset voxel = thisIDwoFlags + Constants.MakeFlags(level, VoxelRoleTypes.Partial); lock (voxel0.InnerVoxels[level - 1]) voxel0.InnerVoxels[level - 1].AddOrReplace(voxel); // well, we don't need to check if parent is full but we may need to create the parent if (level > 1) { // for the remaining voxellevels, we also need to check if the parent has been created var parentID = MakeParentVoxelID(voxel, level - 1); lock (voxel0.InnerVoxels[level - 2]) parentID = voxel0.InnerVoxels[level - 2].GetVoxel(parentID); if (parentID == 0) { ChangeEmptyVoxelToPartial(parentID, level - 1); } } return(voxel); }
//public void DeleteLowLevelVoxelCollection(IEnumerable<long> voxels) //{ // if (numberOfLevels == 1) //} private long ChangeEmptyVoxelToFull(long ID, int level, bool checkParentFull) { if (level == 0) { //adding a new level-0 voxel is fairly straightforward var voxelBin = new VoxelBinClass(ID, VoxelRoleTypes.Full, this); lock (voxelDictionaryLevel0) voxelDictionaryLevel0.AddOrReplace(voxelBin); voxelBin.ID = Constants.ClearFlagsFromID(ID) + Constants.MakeFlags(level, VoxelRoleTypes.Full); return(voxelBin.ID); } // for the lower levels, first get or make the level-0 voxel (next7 lines) var thisIDwoFlags = Constants.ClearFlagsFromID(ID); var id0 = MakeParentVoxelID(thisIDwoFlags, 0); VoxelBinClass voxel0; lock (voxelDictionaryLevel0) if (!voxelDictionaryLevel0.Contains(id0)) { ChangeEmptyVoxelToPartial(id0, 0); voxel0 = voxelDictionaryLevel0.GetVoxel(id0); } else { voxel0 = (VoxelBinClass)voxelDictionaryLevel0.GetVoxel(id0); } // make the new Voxel, and add it to the proper hashset var voxel = thisIDwoFlags + Constants.MakeFlags(level, VoxelRoleTypes.Full); lock (voxel0.InnerVoxels[level - 1]) voxel0.InnerVoxels[level - 1].AddOrReplace(voxel); if (level == 1 && checkParentFull) { //What if this is the last voxel to be added that makes the parent full? // This is checked differently for the level-1 than the others. The code could be // combined but it would be less efficient. var changeToFull = false; lock (voxel0.InnerVoxels[0]) changeToFull = (voxel0.InnerVoxels[0].Count == voxelsInParent[level] //the following All statement is slow. First, just // check if its worth counting to see if all are Full && voxel0.InnerVoxels[0].All(v => Constants.GetRole(v) == VoxelRoleTypes.Full)); if (changeToFull) { ChangeVoxelToFull(voxel0.ID, checkParentFull); } } else if (level > 1) { // for the remaining voxellevels, we also need to check if the parent has been created var parentID = MakeParentVoxelID(voxel, level - 1); long parentVoxel; var mightBeFull = false; lock (voxel0.InnerVoxels[level - 2]) parentVoxel = voxel0.InnerVoxels[level - 2].GetVoxel(parentID); if (parentVoxel == 0) { ChangeEmptyVoxelToPartial(parentID, level - 1); } else { mightBeFull = true; } if (checkParentFull && mightBeFull) { bool makeParentFull = false; lock (voxel0.InnerVoxels[level - 1]) { // since the hashsets are combined we need to count // what is indeed the immediate descendant of the the parent and see if they are all full makeParentFull = voxel0.InnerVoxels[level - 1].Count >= voxelsInParent[level]; if (makeParentFull) { makeParentFull = (voxel0.InnerVoxels[level - 1] .CountDescendants(parentID, level - 1, VoxelRoleTypes.Full) == voxelsInParent[level]); } } if (makeParentFull) { ChangeVoxelToFull(parentVoxel, checkParentFull); } } } return(voxel); }
private long CountVoxels(VoxelBinClass voxel0, int level, VoxelRoleTypes role) { return(voxel0.InnerVoxels[level - 1].Count(v => Constants.GetRole(v) == role)); }