コード例 #1
0
ファイル: SurfacePoint.cs プロジェクト: dtegunov/membranorama
 public SurfacePoint(Vector3 position, Triangle face, Vector3 barycentricCoords, float surfaceOffset, Matrix3 orientationMatrix)
 {
     Position = position;
     Face = face;
     BarycentricCoords = barycentricCoords;
     SurfaceOffset = surfaceOffset;
     Psi = 0;
     OriginalMatrix = orientationMatrix;
 }
コード例 #2
0
ファイル: SurfacePoint.cs プロジェクト: dtegunov/membranorama
 public SurfacePoint(Vector3 position, Triangle face, Vector3 barycentricCoords, float surfaceOffset, float psi)
 {
     Position = position;
     Face = face;
     BarycentricCoords = barycentricCoords;
     SurfaceOffset = surfaceOffset;
     Psi = psi;
     OriginalMatrix = face.GetPlaneMatrix3();
 }
コード例 #3
0
ファイル: SurfacePatch.cs プロジェクト: dtegunov/membranorama
        public SurfacePatch(Membrane membrane, string name, Color color, IEnumerable<Triangle> triangles)
        {
            Membrane = membrane;
            Name = name;
            Color = color;

            Dictionary<Vertex, Vertex> VertexToTransformed = new Dictionary<Vertex, Vertex>();
            List<Triangle> NewTriangles = new List<Triangle>(triangles.Count());

            foreach (var t in triangles)
            {
                foreach (var v in t.Vertices)
                    if (!VertexToTransformed.ContainsKey(v))
                        VertexToTransformed.Add(v, new Vertex(v.VolumePosition, v.VolumeNormal));

                Triangle NewTriangle = new Triangle(t.ID, VertexToTransformed[t.V0], VertexToTransformed[t.V1], VertexToTransformed[t.V2]);
                NewTriangles.Add(NewTriangle);
                OriginalToTransformed.Add(t, NewTriangle);
                TransformedToOriginal.Add(NewTriangle, t);
            }

            SurfaceMesh = new Mesh();
            SurfaceMesh.Vertices.AddRange(VertexToTransformed.Values);
            SurfaceMesh.Triangles.AddRange(OriginalToTransformed.Values);

            SurfaceMesh.UpdateGraph();
            SurfaceMesh.UpdateVertexIDs();

            TurnUpsideUp();
            // Don't update buffers because there is no OpenGL context yet.

            UpdateStats();
            UpdatePlanarizationStats();

            Membrane.DisplayedPatches.CollectionChanged += MembraneDisplayedPatches_CollectionChanged;
            Membrane.PointGroups.CollectionChanged += MembranePointGroups_CollectionChanged;
            MembranePointGroups_CollectionChanged(null, null);
        }
コード例 #4
0
ファイル: Mesh.cs プロジェクト: dtegunov/membranorama
        private static Triangle[] Polygonize(Vector3[] p, float[] val, float threshold)
        {
            // Determine the index into the edge table which
            // tells us which vertices are inside of the surface
            uint cubeindex = 0;
            if (val[0] < threshold) cubeindex |= 1;
            if (val[1] < threshold) cubeindex |= 2;
            if (val[2] < threshold) cubeindex |= 4;
            if (val[3] < threshold) cubeindex |= 8;
            if (val[4] < threshold) cubeindex |= 16;
            if (val[5] < threshold) cubeindex |= 32;
            if (val[6] < threshold) cubeindex |= 64;
            if (val[7] < threshold) cubeindex |= 128;

            // Cube is entirely in/out of the surface
            if (EdgeTable[cubeindex] == 0)
                return null;

            Vector3[] VertList = new Vector3[12];

            // Find the vertices where the surface intersects the cube
            if ((EdgeTable[cubeindex] & 1) > 0)
                VertList[0] =
                   VertexInterp(threshold, p[0], p[1], val[0], val[1]);
            if ((EdgeTable[cubeindex] & 2) > 0)
                VertList[1] =
                   VertexInterp(threshold, p[1], p[2], val[1], val[2]);
            if ((EdgeTable[cubeindex] & 4) > 0)
                VertList[2] =
                   VertexInterp(threshold, p[2], p[3], val[2], val[3]);
            if ((EdgeTable[cubeindex] & 8) > 0)
                VertList[3] =
                   VertexInterp(threshold, p[3], p[0], val[3], val[0]);
            if ((EdgeTable[cubeindex] & 16) > 0)
                VertList[4] =
                   VertexInterp(threshold, p[4], p[5], val[4], val[5]);
            if ((EdgeTable[cubeindex] & 32) > 0)
                VertList[5] =
                   VertexInterp(threshold, p[5], p[6], val[5], val[6]);
            if ((EdgeTable[cubeindex] & 64) > 0)
                VertList[6] =
                   VertexInterp(threshold, p[6], p[7], val[6], val[7]);
            if ((EdgeTable[cubeindex] & 128) > 0)
                VertList[7] =
                   VertexInterp(threshold, p[7], p[4], val[7], val[4]);
            if ((EdgeTable[cubeindex] & 256) > 0)
                VertList[8] =
                   VertexInterp(threshold, p[0], p[4], val[0], val[4]);
            if ((EdgeTable[cubeindex] & 512) > 0)
                VertList[9] =
                   VertexInterp(threshold, p[1], p[5], val[1], val[5]);
            if ((EdgeTable[cubeindex] & 1024) > 0)
                VertList[10] =
                   VertexInterp(threshold, p[2], p[6], val[2], val[6]);
            if ((EdgeTable[cubeindex] & 2048) > 0)
                VertList[11] =
                   VertexInterp(threshold, p[3], p[7], val[3], val[7]);

            /* Create the triangle */
            uint ntriang = 0;
            for (uint i = 0; TriTable[cubeindex, i] != -1; i += 3)
                ntriang++;

            Triangle[] Triangles = new Triangle[ntriang];
            ntriang = 0;

            for (uint i = 0; TriTable[cubeindex, i] != -1; i += 3)
            {
                Triangles[ntriang] = new Triangle(0,
                                                  new Vertex(VertList[TriTable[cubeindex, i]], Vector3.UnitX),
                                                  new Vertex(VertList[TriTable[cubeindex, i + 1]], Vector3.UnitX),
                                                  new Vertex(VertList[TriTable[cubeindex, i + 2]], Vector3.UnitX));
                ntriang++;
            }

            return Triangles;
        }
コード例 #5
0
ファイル: Mesh.cs プロジェクト: dtegunov/membranorama
        public void UpdateProcessedGeometry(float offset)
        {
            ProcessedTriangles = new List<Triangle>(Triangles.Count);
            ProcessedTriangleMapping.Clear();

            foreach (Triangle t in Triangles)
            {
                Vertex IV0 = new Vertex(t.Vertices[0].Position + t.Vertices[0].SmoothNormal * offset, new Vector3());
                Vertex IV1 = new Vertex(t.Vertices[1].Position + t.Vertices[1].SmoothNormal * offset, new Vector3());
                Vertex IV2 = new Vertex(t.Vertices[2].Position + t.Vertices[2].SmoothNormal * offset, new Vector3());

                Triangle IT = new Triangle(t.ID, IV0, IV1, IV2)
                {
                    IsVisible = t.IsVisible,
                    Patch = t.Patch
                };

                ProcessedTriangles.Add(IT);

                ProcessedTriangleMapping.Add(IT, t);
            }
        }
コード例 #6
0
ファイル: Mesh.cs プロジェクト: dtegunov/membranorama
        /// <summary>
        /// Implementation of Marching Cubes based on http://paulbourke.net/geometry/polygonise/
        /// </summary>
        /// <param name="volume">Volume intensity values</param>
        /// <param name="dims">Volume dimensions</param>
        /// <param name="angpix">Angstrom per pixel</param>
        /// <param name="threshold">Isosurface threshold</param>
        /// <returns></returns>
        public static Mesh FromVolume(float[] volume, int3 dims, float angpix, float threshold)
        {
            Triangle[][] CellTriangles = new Triangle[volume.Length][];

            unsafe
            {
                fixed (float* volumePtr = volume)
                    for (int z = 0; z < dims.Z - 1; z++)
                    {
                        float zz = (z - dims.Z / 2) * angpix;
                        for (int y = 0; y < dims.Y - 1; y++)
                        {
                            float yy = (y - dims.Y / 2) * angpix;
                            for (int x = 0; x < dims.X - 1; x++)
                            {
                                float xx = (x - dims.X / 2) * angpix;

                                Vector3[] p = new Vector3[8];
                                float[] val = new float[8];

                                p[0] = new Vector3(xx, yy, zz);
                                p[1] = new Vector3(xx + angpix, yy, zz);
                                p[2] = new Vector3(xx + angpix, yy + angpix, zz);
                                p[3] = new Vector3(xx, yy + angpix, zz);
                                p[4] = new Vector3(xx, yy, zz + angpix);
                                p[5] = new Vector3(xx + angpix, yy, zz + angpix);
                                p[6] = new Vector3(xx + angpix, yy + angpix, zz + angpix);
                                p[7] = new Vector3(xx, yy + angpix, zz + angpix);

                                val[0] = volumePtr[((z + 0) * dims.Y + (y + 0)) * dims.X + (x + 0)];
                                val[1] = volumePtr[((z + 0) * dims.Y + (y + 0)) * dims.X + (x + 1)];
                                val[2] = volumePtr[((z + 0) * dims.Y + (y + 1)) * dims.X + (x + 1)];
                                val[3] = volumePtr[((z + 0) * dims.Y + (y + 1)) * dims.X + (x + 0)];
                                val[4] = volumePtr[((z + 1) * dims.Y + (y + 0)) * dims.X + (x + 0)];
                                val[5] = volumePtr[((z + 1) * dims.Y + (y + 0)) * dims.X + (x + 1)];
                                val[6] = volumePtr[((z + 1) * dims.Y + (y + 1)) * dims.X + (x + 1)];
                                val[7] = volumePtr[((z + 1) * dims.Y + (y + 1)) * dims.X + (x + 0)];

                                CellTriangles[(z * dims.Y + y) * dims.X + x] = Polygonize(p, val, threshold);
                            }
                        }
                    }
            }

            Mesh NewMesh = new Mesh();

            for (int i = 0; i < CellTriangles.Length; i++)
            {
                if (CellTriangles[i] == null)
                    continue;

                foreach (var tri in CellTriangles[i])
                {
                    NewMesh.Vertices.Add(tri.V0);
                    NewMesh.Vertices.Add(tri.V1);
                    NewMesh.Vertices.Add(tri.V2);

                    tri.ID = NewMesh.Triangles.Count;
                    NewMesh.Triangles.Add(tri);
                }
            }

            NewMesh.UpdateGraph();
            NewMesh.UpdateVertexIDs();

            return NewMesh;
        }