Beispiel #1
0
 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);
            }
        }
Beispiel #4
0
        public static IEnumerable <IOctreeNode> Flatten(this IOctreeNode node)
        {
            yield return(node);

            foreach (var c in node.Children.SelectMany(child => child.Flatten()))
            {
                yield return(c);
            }
        }
Beispiel #5
0
 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());
         }
     }
 }
Beispiel #6
0
        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);
        }
Beispiel #7
0
 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;
         }
     }
 }
Beispiel #8
0
 public OctreeModel(IOctreeNode root)
 {
     Root = root;
 }
Beispiel #9
0
 public Octree()
 {
     root        = new OctreeNode(0);
     ColorsCount = 0;
 }
Beispiel #10
0
 public void ReduceColorsCount(IOctreeNode nodeToReduce, Color avgFamilyColor)
 {
 }
Beispiel #11
0
        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.");
        }