public Maybe <WorkChunk <T, TV> > GetWorkChunk <TV>(string name) { var packet = new MessagePacket { Topic = name, Type = MessageType.WorkChunkRequest }; var response = Communicator.GetResponse <TV>(packet); if (response.IsNone) { return(Maybe <WorkChunk <T, TV> > .None()); } var workChunk = new WorkChunk <T, TV> { Id = packet.Id, disterService = this, Value = response.Value, Name = name }; return(Maybe <WorkChunk <T, TV> > .Some(workChunk)); }
public void DisplayMolSurface() { float resolution_surface =0.1f/scale; //Target is the value that represents the surface of mesh //For example the perlin noise has a range of -1 to 1 so the mid point is were we want the surface to cut through //The target value does not have to be the mid point it can be any value with in the range MarchingCubes.SetTarget(resolution_surface); //Winding order of triangles use 2,1,0 or 0,1,2 //MarchingCubes.SetWindingOrder(2, 1, 0); //Set the mode used to create the mesh //Cubes is faster and creates less verts, tetrahedrons is slower and creates more verts but better represents the mesh surface //MarchingCubes.SetModeToCubes(); MarchingCubes.SetModeToCubes(); int nbatoms=0; for (int v=0; v<mol.Atoms.Count; v++) { if (mol.Atoms [v].Active) { nbatoms++; } } float resolution = CapResolution (nbatoms); //Debug.Log (frame); //The size of voxel array. Be carefull not to make it to large as a mesh in unity can only be made up of 65000 verts int X = (int)(((mol.MaxValue[frame].x - mol.MinValue[frame].x ) * resolution) + 13); int Y = (int)(((mol.MaxValue[frame].y - mol.MinValue[frame].y ) * resolution) + 13); int Z = (int)(((mol.MaxValue[frame].z - mol.MinValue[frame].z ) * resolution) + 13); //correspond to the number vertices in a cube int fudgeFactor = 8; Vector3 offset = mol.MinValue[frame] - (new Vector3 (fudgeFactor, fudgeFactor, fudgeFactor)) / resolution; //Debug.Log("Density minValue :: " + resolution); //Debug.Log("Density point X,Y,Z :: "+ X+","+Y+","+Z); //Debug.Log("Density minValue :: " + mol.MinValue[frame]); float[,,] gridS = new float[X,Y,Z]; Color[,,] VertColor = new Color[X, Y, Z]; //int[,,][] ids = new int[X,Y,Z][10]; List<Mesh> mesh = new List<Mesh>(); bones = new List<Transform> (); List<Vector3> pos_bones = new List<Vector3> (); List<Matrix4x4> bindPoses = new List<Matrix4x4> (); GameObject bones_g = new GameObject ("bones");; bones_g.transform.SetParent (this.transform, false); Vector3 delta = new Vector3 (resolution, resolution, resolution); //resolution // We need to refresh the molecule's origin when it's not // the first molecule for which we generate a surface. //Vector3 origin = mol.MinValue; Debug.Log ("Entering :: Generation of density from PDB"); //Debug.Log ("Density point X,Y,Z :: " + X + "," + Y + "," + Z); //Debug.Log ("Density minValue :: " + MinValue); //count for each atom the grid ? int i; int j; int k; float Dist; Color atomColor; float atomRadius; float density; for (int o=0; o<mol.Atoms.Count; o++) { if (mol.Atoms [o].Active) { if (Main.options.activateBones) { Transform tr = new GameObject(mol.Atoms [o].AtomName).transform; tr.parent = bones_g.transform; tr.localRotation = Quaternion.identity; tr.localPosition = mol.Atoms [o].Location[frame]; bones.Add(tr); pos_bones.Add(tr.localPosition); bindPoses.Add(tr.worldToLocalMatrix * mol.Gameobject[frame].transform.localToWorldMatrix); } i = Mathf.RoundToInt ((mol.Atoms [o].Location[frame].x - mol.MinValue[frame].x) * delta.x + fudgeFactor); j = Mathf.RoundToInt ((mol.Atoms [o].Location[frame].y - mol.MinValue[frame].y) * delta.y + fudgeFactor); k = Mathf.RoundToInt ((mol.Atoms [o].Location[frame].z - mol.MinValue[frame].z) * delta.z + fudgeFactor); Vector3 v1 = new Vector3 (i, j, k); atomRadius = mol.Atoms [o].AtomRadius; atomColor = setColorAtm (mol.Atoms [o], color); for (int l = i-(fudgeFactor/2 -1 ); l < i+(fudgeFactor/2); l++) for (int m = j-(fudgeFactor/2 -1); m < j+(fudgeFactor/2); m++) for (int n = k-(fudgeFactor/2 -1); n < k+(fudgeFactor/2); n++) { Vector3 v2 = new Vector3 (l, m, n); Dist = Vector3.Distance (v1, v2); density = (float)Math.Exp (-((Dist / atomRadius) * (Dist / atomRadius))); if (density > gridS [l, m, n]){ VertColor [l, m, n] = atomColor; } gridS [l, m, n] += density; } } } //gridS = SmoothVoxels (gridS); mesh = MarchingCubes.CreateMesh(gridS,VertColor); //Bones if (Main.options.activateBones) { for (int l=0; l<mesh.Count; l++) { Vector3[] v = mesh [l].vertices; int threshold = mesh [l].vertexCount / 16; ManualResetEvent[] doneEvents = new ManualResetEvent[16]; WorkChunk[] workChunks = new WorkChunk[16]; BoneWeight[] bonesWeight = new BoneWeight[mesh [l].vertexCount]; for (int w = 0; w < doneEvents.Length; w++) { workChunks [w] = new WorkChunk (v, bones.Count, bonesWeight, resolution, offset, pos_bones, w * threshold, (w + 1) * threshold); doneEvents [w] = workChunks [w].doneEvent; } for (int w = 0; w < doneEvents.Length; w++) { doneEvents [w].Reset (); ThreadPool.QueueUserWorkItem (workChunks [w].CalculateBones); } WaitHandle.WaitAll (doneEvents); mesh [l].boneWeights = bonesWeight; mesh [l].bindposes = bindPoses.ToArray (); } } //Normals Vector3[,,] normals_vox = CalculateNormals (gridS); for(int l=0;l<mesh.Count;l++){ int size = mesh[l].vertices.Length; Vector3[] normals = new Vector3[size]; Vector3[] verts = mesh[l].vertices; for(int m = 0; m < size; m++){ normals[m] = TriLinearInterpNormal(verts[m],normals_vox); } mesh[l].normals = normals; } //Debug.Log("Entire surface contains " + mesh.vertices.Length.ToString() + " vertices."); //The diffuse shader wants uvs so just fill with a empty array, there not actually used //mesh.uv = new Vector2[mesh.vertices.Length]; //mesh.RecalculateNormals(); //m_mesh = new GameObject("Mesh"); //m_mesh.GetComponent<MeshRenderer>().material = m_material; m_mesh = new GameObject[mesh.Count]; rend = new SkinnedMeshRenderer[mesh.Count]; bones_g.transform.localPosition = offset; bones_g.transform.localScale /= resolution; for (int s =0; s<m_mesh.Length; s++) { m_mesh[s] = new GameObject(); m_mesh[s].transform.SetParent(this.transform,false); if (!Main.options.activateBones) { m_mesh[s].transform.localPosition = offset; m_mesh[s].transform.localScale /= resolution; m_mesh[s].AddComponent<MeshFilter>(); m_mesh[s].AddComponent<MeshRenderer>(); m_mesh[s].GetComponent<MeshFilter>().mesh = mesh[s]; m_mesh[s].GetComponent<MeshRenderer>().material= Resources.Load("Materials/Surface") as Material; } else{ m_mesh[s].AddComponent<SkinnedMeshRenderer>(); rend[s] = m_mesh[s].GetComponent<SkinnedMeshRenderer>(); rend[s].bones = bones.ToArray(); rend[s].sharedMesh = mesh[s]; rend[s].material = Resources.Load("Materials/Surface") as Material; } } }