Esempio n. 1
0
        /// <summary>Creates a new isosurface calculator. You may pass variables created from a OpenGL context to the CL variables if you are using interop or NULL
        /// if not using OpenCL/GL interop.</summary>
        /// <param name="FuncValues">Values of the evaluated 3D function f(x,y,z). FuncValues=float[maxX,maxY,maxZ]</param>
        /// <param name="CLEdgeCoords">OpenCL variable (float) to hold edge coordinates. Dimension has to be 9 * maxX * maxY * maxZ</param>
        /// <param name="CLEdgeNormals">OpenCL variable (float) to hold edge normals. Dimension has to be 9 * maxX * maxY * maxZ</param>
        /// <param name="CLElementArrayIndex">OpenCL variable (int) to hold element array index. Dimension has to be 5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)</param>
        private void InitMarchingCubes(float[, ,] FuncValues, CLCalc.Program.Variable CLEdgeCoords, CLCalc.Program.Variable CLEdgeNormals, CLCalc.Program.Variable CLElementArrayIndex)
        {
            if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) CLCalc.InitCL();

            if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL)
            {
                //Reads maximum lengths
                int maxX = FuncValues.GetLength(0);
                int maxY = FuncValues.GetLength(1);
                int maxZ = FuncValues.GetLength(2);
                max = new int[] { maxX, maxY, maxZ };

                #region Creating variables

                //Isolevel
                isoLevel = new float[1] { 1.32746E-5f };
                varIsoLevel = new CLCalc.Program.Variable(isoLevel);

                //Step size and x0,y0,z0
                varStep = new CLCalc.Program.Variable(step);
                varInitVals = new CLCalc.Program.Variable(initVals);

                //Create and copy function values
                funcVals = new float[maxX * maxY * maxZ];
                CLFuncVals = new CLCalc.Program.Variable(funcVals);
                SetFuncVals(FuncValues);

                //Edge coordinates - 3 coords * 3 possible directions * number of points
                edgeCoords = new float[9 * maxX * maxY * maxZ];
                if (CLEdgeCoords != null)
                {
                    varEdgeCoords = CLEdgeCoords;
                    varEdgeCoords.WriteToDevice(edgeCoords);
                }
                else varEdgeCoords = new CLCalc.Program.Variable(edgeCoords);

                //4 preliminary normals per edge - has to be averaged afterwards
                edgePrelimNormals = new float[36 * maxX * maxY * maxZ];
                varEdgePrelimNormals = new CLCalc.Program.Variable(edgePrelimNormals);

                //Edge normals
                edgeNormals = new float[9 * maxX * maxY * maxZ];
                if (CLEdgeNormals != null)
                {
                    varEdgeNormals = CLEdgeNormals;
                    varEdgeNormals.WriteToDevice(edgeNormals);
                }
                else varEdgeNormals = new CLCalc.Program.Variable(edgeNormals);

                //Number of cubes: (maxX-1)*(maxY-1)*(maxZ-1)
                //Marching cube algorithm: each cube can have 5 triangles drawn, 3 vertexes per triangle
                //q-th vertex of p-th triangle of the ijk-th cube: [(5*(i+(maxX-1)*j+k*(maxX-1)*(maxY-1))+p)*3+q]
                elementIndex = new int[5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)];
                if (CLElementArrayIndex != null)
                {
                    varElemIndex = CLElementArrayIndex;
                    varElemIndex.WriteToDevice(elementIndex);
                }
                else varElemIndex = new CLCalc.Program.Variable(elementIndex);

                //Edge remapping to build output
                edges = new int[edgeCoords.Length / 3];
                for (int i = 0; i < edges.Length; i++) edges[i] = -1;

                #endregion

                #region Compile code and create kernels

                CLMarchingCubesSrc cmsrc = new CLMarchingCubesSrc();

                CLCalc.Program.Compile(new string[] { cmsrc.definitions, cmsrc.src });
                kernelInterpPts = new CLCalc.Program.Kernel("interpPts");
                kernelPolygonize = new CLCalc.Program.Kernel("Polygonize");
                kernelSmoothNormals = new CLCalc.Program.Kernel("SmoothNormals");
                kernelPolygonizeNoNormals = new CLCalc.Program.Kernel("PolygonizeNoNormals");
                #endregion
            }
            else throw new Exception("OpenCL not available");
        }
Esempio n. 2
0
        /// <summary>Creates a new isosurface calculator. You may pass variables created from a OpenGL context to the CL variables if you are using interop or NULL
        /// if not using OpenCL/GL interop.</summary>
        /// <param name="FuncValues">Values of the evaluated 3D function f(x,y,z). FuncValues=float[maxX,maxY,maxZ]</param>
        /// <param name="CLEdgeCoords">OpenCL variable (float) to hold edge coordinates. Dimension has to be 9 * maxX * maxY * maxZ</param>
        /// <param name="CLEdgeNormals">OpenCL variable (float) to hold edge normals. Dimension has to be 9 * maxX * maxY * maxZ</param>
        /// <param name="CLElementArrayIndex">OpenCL variable (int) to hold element array index. Dimension has to be 5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)</param>
        private void InitMarchingCubes(float[, ,] FuncValues, CLCalc.Program.Variable CLEdgeCoords, CLCalc.Program.Variable CLEdgeNormals, CLCalc.Program.Variable CLElementArrayIndex)
        {
            if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown)
            {
                CLCalc.InitCL();
            }

            if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL)
            {
                //Reads maximum lengths
                int maxX = FuncValues.GetLength(0);
                int maxY = FuncValues.GetLength(1);
                int maxZ = FuncValues.GetLength(2);
                max = new int[] { maxX, maxY, maxZ };

                #region Creating variables

                //Isolevel
                isoLevel = new float[1] {
                    1.32746E-5f
                };
                varIsoLevel = new CLCalc.Program.Variable(isoLevel);

                //Step size and x0,y0,z0
                varStep     = new CLCalc.Program.Variable(step);
                varInitVals = new CLCalc.Program.Variable(initVals);

                //Create and copy function values
                funcVals   = new float[maxX * maxY * maxZ];
                CLFuncVals = new CLCalc.Program.Variable(funcVals);
                SetFuncVals(FuncValues);

                //Edge coordinates - 3 coords * 3 possible directions * number of points
                edgeCoords = new float[9 * maxX * maxY * maxZ];
                if (CLEdgeCoords != null)
                {
                    varEdgeCoords = CLEdgeCoords;
                    varEdgeCoords.WriteToDevice(edgeCoords);
                }
                else
                {
                    varEdgeCoords = new CLCalc.Program.Variable(edgeCoords);
                }

                //4 preliminary normals per edge - has to be averaged afterwards
                edgePrelimNormals    = new float[36 * maxX * maxY * maxZ];
                varEdgePrelimNormals = new CLCalc.Program.Variable(edgePrelimNormals);

                //Edge normals
                edgeNormals = new float[9 * maxX * maxY * maxZ];
                if (CLEdgeNormals != null)
                {
                    varEdgeNormals = CLEdgeNormals;
                    varEdgeNormals.WriteToDevice(edgeNormals);
                }
                else
                {
                    varEdgeNormals = new CLCalc.Program.Variable(edgeNormals);
                }

                //Number of cubes: (maxX-1)*(maxY-1)*(maxZ-1)
                //Marching cube algorithm: each cube can have 5 triangles drawn, 3 vertexes per triangle
                //q-th vertex of p-th triangle of the ijk-th cube: [(5*(i+(maxX-1)*j+k*(maxX-1)*(maxY-1))+p)*3+q]
                elementIndex = new int[5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)];
                if (CLElementArrayIndex != null)
                {
                    varElemIndex = CLElementArrayIndex;
                    varElemIndex.WriteToDevice(elementIndex);
                }
                else
                {
                    varElemIndex = new CLCalc.Program.Variable(elementIndex);
                }

                //Edge remapping to build output
                edges = new int[edgeCoords.Length / 3];
                for (int i = 0; i < edges.Length; i++)
                {
                    edges[i] = -1;
                }

                #endregion

                #region Compile code and create kernels

                CLMarchingCubesSrc cmsrc = new CLMarchingCubesSrc();

                CLCalc.Program.Compile(new string[] { cmsrc.definitions, cmsrc.src });
                kernelInterpPts           = new CLCalc.Program.Kernel("interpPts");
                kernelPolygonize          = new CLCalc.Program.Kernel("Polygonize");
                kernelSmoothNormals       = new CLCalc.Program.Kernel("SmoothNormals");
                kernelPolygonizeNoNormals = new CLCalc.Program.Kernel("PolygonizeNoNormals");
                #endregion
            }
            else
            {
                throw new Exception("OpenCL not available");
            }
        }