public void ReduceColorsCount(IOctreeNode nodeToReduce, Color avgFamilyColor) { if (nodes.Values.Contains(nodeToReduce)) { int key = 0; foreach (var node in nodes) { if (node.Value == nodeToReduce) { key = node.Key; break; } } nodes[key] = new OctreeLeaf(nodeToReduce.GetAvgColor(), nodeToReduce.GetColorPixelsCount(), Index + 1); BestColorFamilyToReduce = null; foreach (IOctreeNode octreeNode in nodes.Values) { SetBestColorFamilyToReduce(octreeNode.BestColorFamilyToReduce); } SetBestColorFamilyToReduce(this); } else { int nodeKey = GetNodeKeyForColor(avgFamilyColor); nodes[nodeKey].ReduceColorsCount(nodeToReduce, avgFamilyColor); BestColorFamilyToReduce = null; foreach (IOctreeNode octreeNode in nodes.Values) { SetBestColorFamilyToReduce(octreeNode.BestColorFamilyToReduce); } } }
public static IOctreeNode Intersect(this IOctreeNode node, Func <IOctreeNode, bool> testFunc, int maxLevel) { if (!testFunc(node)) { return(node); } if (node.Level == maxLevel) { return(new OctreeNode(node.Center, node.Size, node.Level, NodeType.Filled)); } switch (node.Type) { case NodeType.Interior: return(new OctreeNode(node.Center, node.Size, node.Level, NodeType.Interior, node.Children.Select(c => Intersect(c, testFunc, maxLevel)).ToArray())); case NodeType.Filled: return(node); case NodeType.Empty: return(new OctreeNode(node.Center, node.Size, node.Level, NodeType.Interior, node.CreateChildren().Select(c => c.Intersect(testFunc, maxLevel)).ToArray())); default: throw new ArgumentOutOfRangeException(); } }
private static void RecDrawOctree(Octree tree, IOctreeNode iOctreeNode, Vector3 LowerLocalCorner, int current_recursion) { if (iOctreeNode == null) { return; } double boxWidth = Math.Pow(2, -current_recursion); if (iOctreeNode is OctreeEndNode) { OctreeEndNode oen = ((OctreeEndNode)iOctreeNode); SurfaceTangentPoint stp = new SurfaceTangentPoint(); stp.SurfaceNormal = oen.SurfaceNormal; stp.Location = tree.OctreeToWorld(LowerLocalCorner); RenderPoint(stp); } if (iOctreeNode is OctreeParent) { double b = boxWidth / 2; OctreeParent parent = (OctreeParent)iOctreeNode; RecDrawOctree(tree, parent.xyz, LowerLocalCorner + new Vector3(0, 0, 0), current_recursion + 1); RecDrawOctree(tree, parent.xyZ, LowerLocalCorner + new Vector3(0, 0, b), current_recursion + 1); RecDrawOctree(tree, parent.xYz, LowerLocalCorner + new Vector3(0, b, 0), current_recursion + 1); RecDrawOctree(tree, parent.xYZ, LowerLocalCorner + new Vector3(0, b, b), current_recursion + 1); RecDrawOctree(tree, parent.Xyz, LowerLocalCorner + new Vector3(b, 0, 0), current_recursion + 1); RecDrawOctree(tree, parent.XyZ, LowerLocalCorner + new Vector3(b, 0, b), current_recursion + 1); RecDrawOctree(tree, parent.XYz, LowerLocalCorner + new Vector3(b, b, 0), current_recursion + 1); RecDrawOctree(tree, parent.XYZ, LowerLocalCorner + new Vector3(b, b, b), current_recursion + 1); } }
public static IEnumerable <IOctreeNode> Flatten(this IOctreeNode node) { yield return(node); foreach (var c in node.Children.SelectMany(child => child.Flatten())) { yield return(c); } }
public void ReduceColorsCount(int limit) { while (ColorsCount > limit) { if (root == root.BestColorFamilyToReduce) { ColorsCount = 1; root = new OctreeLeaf(root.GetAvgColor(), root.GetColorPixelsCount(), 0); return; } else { ColorsCount -= (root.BestColorFamilyToReduce.GetColorsCount() - 1); root.ReduceColorsCount(root.BestColorFamilyToReduce, root.BestColorFamilyToReduce.GetAvgColor()); } } }
int WriteToFileRec(List <byte> data, IOctreeNode self_node) { int thisNodeOffset = data.Count; if (self_node is OctreeParent) { OctreeParent op = (OctreeParent)self_node; byte[] block = new byte[8 * 4 + 1]; block[0] = ID_BRANCH; data.AddRange(block); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 0, WriteToFileRec(data, op.xyz)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 1, WriteToFileRec(data, op.xyZ)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 2, WriteToFileRec(data, op.xYz)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 3, WriteToFileRec(data, op.xYZ)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 4, WriteToFileRec(data, op.Xyz)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 5, WriteToFileRec(data, op.XyZ)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 6, WriteToFileRec(data, op.XYz)); writeIntToBytesAt(data, thisNodeOffset + 1 + 4 * 7, WriteToFileRec(data, op.XYZ)); } else if (self_node is OctreeEndNode) { OctreeEndNode oen = (OctreeEndNode)self_node; byte[] block = new byte[7]; block[0] = ID_LEAF; block[1] = 111; // red block[2] = 112; // green block[3] = 113; // blue block[4] = (byte)(oen.SurfaceNormal.X * 126 + 126); block[5] = (byte)(oen.SurfaceNormal.Y * 126 + 126); block[6] = (byte)(oen.SurfaceNormal.Z * 126 + 126); data.AddRange(block); } else if (self_node == null) { return(0); } return(thisNodeOffset); }
private void SetBestColorFamilyToReduce(IOctreeNode newFamily) { if (newFamily == null) { return; } if (BestColorFamilyToReduce == null || BestColorFamilyToReduce.Index < newFamily.Index) { BestColorFamilyToReduce = newFamily; } else if (newFamily.Index == BestColorFamilyToReduce.Index) { if (newFamily.GetColorPixelsCount() < BestColorFamilyToReduce.GetColorPixelsCount()) { BestColorFamilyToReduce = newFamily; } } }
public OctreeModel(IOctreeNode root) { Root = root; }
public Octree() { root = new OctreeNode(0); ColorsCount = 0; }
public void ReduceColorsCount(IOctreeNode nodeToReduce, Color avgFamilyColor) { }
public void TraceRay(IOctreeNode this_node, Ray ray, Vector3 LowerLocalCorner, int current_recursion) { double boxWidth = Math.Pow(2, -current_recursion); if (this_node is OctreeEndNode) { ray.Result = (OctreeEndNode)this_node; ray.CurrentParameter = 9999; return; } else if (this_node is OctreeParent) { while (PointInBox(ray.ParameterPoint(), LowerLocalCorner, boxWidth)) { // dispatch to the right child double b = boxWidth / 2; if (PointInBox(ray.ParameterPoint(), LowerLocalCorner + new Vector3(0, 0, 0), b)) { TraceRay(((OctreeParent)this_node).xyz, ray, LowerLocalCorner + new Vector3(0, 0, 0), current_recursion + 1); } else if (PointInBox(ray.ParameterPoint(), LowerLocalCorner + new Vector3(0, 0, b), b)) { TraceRay(((OctreeParent)this_node).xyZ, ray, LowerLocalCorner + new Vector3(0, 0, b), current_recursion + 1); } else if (PointInBox(ray.ParameterPoint(), LowerLocalCorner + new Vector3(0, b, 0), b)) { TraceRay(((OctreeParent)this_node).xYz, ray, LowerLocalCorner + new Vector3(0, b, 0), current_recursion + 1); } else if (PointInBox(ray.ParameterPoint(), LowerLocalCorner + new Vector3(0, b, b), b)) { TraceRay(((OctreeParent)this_node).xYZ, ray, LowerLocalCorner + new Vector3(0, b, b), current_recursion + 1); } else if (PointInBox(ray.ParameterPoint(), LowerLocalCorner + new Vector3(b, 0, 0), b)) { TraceRay(((OctreeParent)this_node).Xyz, ray, LowerLocalCorner + new Vector3(b, 0, 0), current_recursion + 1); } else if (PointInBox(ray.ParameterPoint(), LowerLocalCorner + new Vector3(b, 0, b), b)) { TraceRay(((OctreeParent)this_node).XyZ, ray, LowerLocalCorner + new Vector3(b, 0, b), current_recursion + 1); } else if (PointInBox(ray.ParameterPoint(), LowerLocalCorner + new Vector3(b, b, 0), b)) { TraceRay(((OctreeParent)this_node).XYz, ray, LowerLocalCorner + new Vector3(b, b, 0), current_recursion + 1); } else if (PointInBox(ray.ParameterPoint(), LowerLocalCorner + new Vector3(b, b, b), b)) { TraceRay(((OctreeParent)this_node).XYZ, ray, LowerLocalCorner + new Vector3(b, b, b), current_recursion + 1); } } return; } else if (this_node == null) { // if this box is empty, pass the ray through ray.CurrentParameter = epsilon + RayParameterForBoxExitPoint(ray, LowerLocalCorner, boxWidth); if (ray.CurrentParameter < 0) { throw new Exception("Oops"); } return; } throw new Exception("Oops what kind of tree is that? Ask the developer."); }