public override void LoadModuleSettings(HashTableSettings settings) { // Load random template Random ran = new Random(); // series foreach (string serie in serieNames) { int r = (int)(ran.NextDouble() * 255f); int g = (int)(ran.NextDouble() * 255f); int b = (int)(ran.NextDouble() * 255f); Color baseColor = Color.FromArgb(r, g, b); series[serie] = new AtomMaterial(baseColor); } // elements ElementPTFactory ptElements = ElementPTFactory.Instance; foreach (PeriodicTableElement element in ptElements) { int r = (int)(ran.NextDouble() * 255f); int g = (int)(ran.NextDouble() * 255f); int b = (int)(ran.NextDouble() * 255f); Color baseColor = Color.FromArgb(r, g, b); IMoleculeMaterial serieMat = null; series.TryGetValue(element.ChemicalSerie, out serieMat); elements[element.Symbol] = new MoleculeMaterialTemplate(new AtomMaterial(baseColor), serieMat); } }
public IMoleculeMaterial GetBySeries(string serie) { IMoleculeMaterial mat = null; series.TryGetValue(serie, out mat); return(mat); }
private void GenericDrawBondSolidBlended(Vector3 start, Vector3 end, IMoleculeMaterial matA, IMoleculeMaterial matB, GraphicsStream data, ref long pos, int stride, int positionPos, int diffusePos) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(start.X); data.Write(start.Y); data.Write(start.Z); data.Seek(pos + stride + positionPos, SeekOrigin.Begin); data.Write(end.X); data.Write(end.Y); data.Write(end.Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matA.BaseColor.ToArgb()); data.Seek(pos + stride + diffusePos, SeekOrigin.Begin); data.Write(matB.BaseColor.ToArgb()); } pos += stride * 2; }
private void GenericDrawBondDashedBlended(Vector3 start, Vector3 end, IMoleculeMaterial matA, IMoleculeMaterial matB, ref int vertsIdx, CustomVertex.PositionColored[] bondsVerts) { float dashFreq = 0.1f; // generate lnear dashed 3d line Vector3[] dashes; LineHelperMath.CalcDashedLineLinear(start, end, dashFreq, out dashes); // NOTE: Batch sampling or something? to improve speed ColourHelperMath.ColourGradient gradient; ColourHelperMath.GenerateLinearGradient(matA.BaseColor, matB.BaseColor, out gradient); // copy to buffer int numDashes = dashes.Length / 2; float lineLen = (end - start).Length(); float dashScale = 1f / (lineLen / (dashFreq * 2f)); float startScale = 0f; float endScale = dashScale; for (int dash = 0; dash < numDashes; dash += 2) { bondsVerts[vertsIdx].Position = dashes[dash]; bondsVerts[vertsIdx].Color = gradient.Sample(startScale); vertsIdx++; bondsVerts[vertsIdx].Position = dashes[dash + 1]; bondsVerts[vertsIdx].Color = gradient.Sample(endScale); vertsIdx++; startScale += dashScale; endScale += dashScale; } }
private void DrawSolidBondBlended(Vector3[] tCylinderPoints, Vector3[] tCylinderNormals, int[] tCylinderTris, IMoleculeMaterial matA, IMoleculeMaterial matB, Matrix final, GraphicsStream data, int positionPos, int normalPos, int diffusePos, ref long pos, int stride, Matrix rotation) { // write transformed template to buffer Vector4[] tfTriangles = Vector3.Transform(tCylinderPoints, final); //Vector4[] rtNormals = Vector3.Transform(tCylinderNormals, rotation); int halfWay = tfTriangles.Length / 2; for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); if (pointIdx < halfWay) { data.Write(matA.BaseColor.ToArgb()); } else { data.Write(matB.BaseColor.ToArgb()); } } pos += stride; } }
public override void LoadModuleSettings(HashTableSettings settings) { //settings["Materials.Molecules.IMoleculeMaterialLookup"] = this; // load molecule settings from xml resource ColorConverter cc = new ColorConverter(); Stream str = Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.Molecule.config"); XmlDocument doc = new XmlDocument(); doc.Load(str); // load series settings XmlNodeList series = doc.SelectNodes("configuration/chemicalSeries/chemicalSerie"); foreach (XmlNode serie in series) { string id = serie.Attributes["id"].InnerText; Color baseColor = (Color)cc.ConvertFromString(serie.SelectSingleNode("color").Attributes["desc"].InnerText); this.series[id] = new AtomMaterial(baseColor); } // load symbols XmlNodeList symbols = doc.SelectNodes("configuration/chemicalSymbols/symbol"); ElementPTFactory ptElements = ElementPTFactory.Instance; foreach (XmlNode symbol in symbols) { string id = symbol.Attributes["id"].InnerText; Color baseColor = (Color)cc.ConvertFromString(symbol.SelectSingleNode("color").Attributes["desc"].InnerText); PeriodicTableElement element = ptElements.getElement(id); IMoleculeMaterial serie = null; this.series.TryGetValue(element.ChemicalSerie, out serie); elements[id] = new MoleculeMaterialTemplate(new AtomMaterial(baseColor), serie); } }
public MoleculeMaterialTemplate(IMoleculeMaterial symbolMat, IMoleculeMaterial serieMat) { this.symbolMat = symbolMat; this.serieMat = serieMat; }
public void DrawPT(Bitmap bitmap, int cellWidth, int cellHeight, bool showStates, bool showNaturalOccurance, bool showSeries, bool showRowColumnHeadings) { Graphics g = Graphics.FromImage(bitmap); g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; Pen solidCellBorder = new Pen(Color.Black, 1f); Pen dashedCellBorder = new Pen(Color.Black, 1f); dashedCellBorder.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; Pen dottedCellBorder = new Pen(Color.Black, 1f); dottedCellBorder.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; Font symbolFont = new Font("Tohoma", 7); SolidBrush symbolBrush = new SolidBrush(Color.White); SolidBrush symbolBrush2 = new SolidBrush(Color.Black); int xOffset = 0, yOffset = 0; if (showRowColumnHeadings) { // draw row / column headers xOffset = cellWidth; yOffset = cellHeight; for (int i = 1; i <= 18; i++) { int x = i * cellWidth; int y = 3; SizeF sz = g.MeasureString(i.ToString(), symbolFont); g.DrawString(i.ToString(), symbolFont, symbolBrush2, (float)x + ((float)cellWidth / 2) - (sz.Width / 2), y); } for (int i = 1; i <= 7; i++) { int x = 3; int y = i * cellHeight; SizeF sz = g.MeasureString(i.ToString(), symbolFont); g.DrawString(i.ToString(), symbolFont, symbolBrush2, x, (float)y + ((float)cellHeight / 2) - (sz.Height / 2)); } } foreach (PeriodicTableElement element in ElementPTFactory.Instance) { if (element.Group.Length > 0) { int group = int.Parse(element.Group); int period = int.Parse(element.Period); int x = xOffset + (group - 1) * cellWidth; int y = yOffset + (period - 1) * cellHeight; // fill IMoleculeMaterial elMat = null, seriesMat = null; if (elements.ContainsKey(element.Symbol)) { elMat = elements[element.Symbol].BySymbol; seriesMat = elements[element.Symbol].BySerie; } if (series.ContainsKey(element.ChemicalSerie)) { seriesMat = series[element.ChemicalSerie]; } using (LinearGradientBrush brush = new LinearGradientBrush(new Point(0, 0), new Point(0, cellHeight / 2), seriesMat.BaseColor, Color.White)) { g.FillRectangle(brush, x, y + (cellHeight / 2), cellWidth - 1, (cellHeight / 2) - 1); } using (SolidBrush brush = new SolidBrush(seriesMat.BaseColor)) { g.FillRectangle(brush, x, y, cellWidth - 1, (cellHeight / 2) + 1); } if (elMat != null) { using (SolidBrush brush = new SolidBrush(elMat.BaseColor)) { g.FillRectangle(brush, x + 4, y + 4, cellWidth - 9, cellHeight - 9); } } // border if (element.Phase == "Gas") { g.DrawRectangle(dottedCellBorder, x, y, cellWidth - 2, cellHeight - 2); } else if (element.Phase == "Liquid") { g.DrawRectangle(dashedCellBorder, x, y, cellWidth - 2, cellHeight - 2); } else { g.DrawRectangle(solidCellBorder, x, y, cellWidth - 2, cellHeight - 2); } // symbol SizeF symbolSz = g.MeasureString(element.Symbol, symbolFont); g.DrawString(element.Symbol, symbolFont, symbolBrush2, x + ((float)cellWidth / 2) - (symbolSz.Width / 2) + 1, y + ((float)cellHeight / 2) - (symbolSz.Height / 2) + 1); g.DrawString(element.Symbol, symbolFont, symbolBrush, x + ((float)cellWidth / 2) - (symbolSz.Width / 2), y + ((float)cellHeight / 2) - (symbolSz.Height / 2)); } } g.Flush(); g.Dispose(); }
private void DrawSolidBondDistinct(Vector3[] tCylinderPoints, Vector3[] tCylinderNormals, int[] tCylinderTris, IMoleculeMaterial matA, IMoleculeMaterial matB, Matrix final, GraphicsStream data, float xyScale, float bLen2, Matrix rotation, Vector3 bondInstance1, Vector3 directionUV, float midPos, int positionPos, int normalPos, int diffusePos, ref long pos, int stride) { // side 1 Vector4[] tfTriangles = Vector3.Transform(tCylinderPoints, final); //Vector4[] rtNormals = Vector3.Transform(tCylinderNormals, rotation); for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal.Normalize(); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matA.BaseColor.ToArgb()); } pos += stride; } // side 2 final = Matrix.Scaling(xyScale, xyScale, bLen2) * rotation * Matrix.Translation(bondInstance1 + (directionUV * midPos)); tfTriangles = Vector3.Transform(tCylinderPoints, final); for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal.Normalize(); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matB.BaseColor.ToArgb()); } pos += stride; } }
private void DrawSolidBondBlended(Vector3[] tCylinderPoints, Vector3[] tCylinderNormals, int[] tCylinderTris, IMoleculeMaterial matA, IMoleculeMaterial matB, Matrix final, GraphicsStream data, int positionPos, int normalPos, int diffusePos, ref long pos, int stride, Matrix rotation) { // write transformed template to buffer Vector4[] tfTriangles = Vector3.Transform(tCylinderPoints, final); //Vector4[] rtNormals = Vector3.Transform(tCylinderNormals, rotation); int halfWay = tfTriangles.Length / 2; for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); if (pointIdx < halfWay) data.Write(matA.BaseColor.ToArgb()); else data.Write(matB.BaseColor.ToArgb()); } pos += stride; } }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { if (spriteTexture == null) { Stream texstm = Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.Resources.Atom.PNG"); spriteTexture = TextureLoader.FromStream(device, texstm); } // fillable fields int positionPos = -1; int sizePos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "POINTSIZE") { sizePos = geomStream.FieldPositions[gf]; } break; } } } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(typeof(PointSprite), objs.Count, device, Usage.WriteOnly, geomStream.Format, Pool.Managed); /*new VertexBuffer(device, geomStream.Stride * objs.Count, * Usage.None, geomStream.Format, Pool.Managed);*/ buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Sprites; buffer.iBuffers[0].NumPrimitives = objs.Count; buffer.iBuffers[0].PrimType = PrimitiveType.PointList; buffer.iBuffers[0].Textures = new Texture[] { spriteTexture }; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); AtomShadingDesc aShading = coDesc.AtomShadingDesc; long pos = 0; foreach (IAtom atom in objs) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write((float)atom.X3d); data.Write((float)atom.Y3d); data.Write((float)atom.Z3d); } if (sizePos != -1) { data.Seek(pos + sizePos, SeekOrigin.Begin); int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } data.Write((float)period * 0.4f); } if (diffusePos != -1) { IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(material.BaseColor.ToArgb()); } pos += geomStream.Stride; } /*Dictionary<int, List<int>> atomSizeGroups = new Dictionary<int, List<int>>(); * // first split into group counts * int aIdx = 0; * foreach (IAtom[] atoms in atomSets) * { * foreach (IAtom atom in atoms) * { * int period = 1; * if (atom.Properties.ContainsKey("Period")) * period = (int)atom.Properties["Period"]; * * List<int> groupAtoms = null; * if (!atomSizeGroups.TryGetValue(period, out groupAtoms)) * atomSizeGroups.Add(period, groupAtoms = new List<int>()); * * groupAtoms.Add(aIdx++); * } * } * * int vertsIdx = 0; * Dictionary<int, List<int>>.Enumerator group = atomSizeGroups.GetEnumerator(); * sBuffer.groupLengths = new int[atomSizeGroups.Count]; * sBuffer.groupSizes = new int[atomSizeGroups.Count]; * sBuffer.groupStarts = new int[atomSizeGroups.Count]; * int bIdx = 0; * while (group.MoveNext()) * { * int groupPeriod = group.Current.Key; * List<int> groupMembers = group.Current.Value; * aIdx = 0; * int gIdx = 0; * sBuffer.groupSizes[bIdx] = groupPeriod; * sBuffer.groupStarts[bIdx] = vertsIdx; * sBuffer.groupLengths[bIdx] = groupMembers.Count; * foreach (IAtom[] atoms in atomSets) * { * foreach (IAtom atom in atoms) * { * if (aIdx == groupMembers[gIdx]) * { * IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; * IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); * IMoleculeMaterial material = null; * if (matTemp != null) * material = matTemp.BySymbol; * else * { * PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; * if (pe != null) * material = lookup.GetBySeries(pe.ChemicalSerie); * } * * atomVerts[vertsIdx].Position = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); * atomVerts[vertsIdx].Color = material.BaseColor.ToArgb(); * vertsIdx++; * gIdx++; * } * if (gIdx == groupMembers.Count) * break; * aIdx++; * } * if (gIdx == groupMembers.Count) * break; * } * bIdx++; * }*/ buffer.vBuffers[0].Buffer.Unlock(); }
public static void GenericBondSetup(IBond bond, bool sort, BondShadingDesc bShading, out Vector3 direction, out Vector3 directionUV, out IAtom[] atoms, out Vector3[] atomsPos, out IMoleculeMaterial matA, out IMoleculeMaterial matB) { atoms = bond.getAtoms(); Vector3 v1 = new Vector3((float)atoms[0].X3d, (float)atoms[0].Y3d, (float)atoms[0].Z3d); Vector3 v2 = new Vector3((float)atoms[1].X3d, (float)atoms[1].Y3d, (float)atoms[1].Z3d); direction = v2 - v1; atomsPos = new Vector3[2]; if (sort) { if (direction.Z < (v1 - v2).Z) { IAtom temp = atoms[0]; atoms[0] = atoms[1]; atoms[1] = temp; atomsPos[0] = v2; atomsPos[1] = v1; } else { atomsPos[0] = v1; atomsPos[1] = v2; } direction = Vector3.Normalize(atomsPos[1] - atomsPos[0]); } else { atomsPos[0] = v1; atomsPos[1] = v2; } directionUV = Vector3.Normalize(direction); IMoleculeMaterialLookup lookup = bShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atoms[0].Symbol); if (matTemp != null) { matA = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atoms[0].Properties["PeriodicTableElement"]; matA = lookup.GetBySeries(pe.ChemicalSerie); } matTemp = lookup.ResolveBySymbol(atoms[1].Symbol); if (matTemp != null) { matB = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atoms[1].Properties["PeriodicTableElement"]; matB = lookup.GetBySeries(pe.ChemicalSerie); } }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; int texPos = -1; // match field locations //int[] fieldsPos = new int[fields.Length]; for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "TEXTURE0") { texPos = geomStream.FieldPositions[gf]; } //fieldsPos[i] = geomStream.FieldPositions[gf]; break; } } } int numVerts = sphereDetail1 * sphereDetail2 * 6; int numTris = sphereDetail1 * sphereDetail2 * 2; // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * numVerts * objs.Count, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count * numVerts; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; buffer.iBuffers[0].NumPrimitives = objs.Count * numTris; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields bool newWay = true; if (!newWay) { // create template sphere SphereMathHelper.SphereN sphere = SphereMathHelper.CalcSphereWNormals(sphereDetail1, sphereDetail2, 1.0f, new Vector3(), true); // clone and scale template for each size required Vector3 center = new Vector3(); Dictionary <int, Vector3[]> spheres = new Dictionary <int, Vector3[]>(); AtomShadingDesc aShading = coDesc.AtomShadingDesc; //int vertsIdx = 0; long pos = 0; foreach (IAtom atom in objs) { int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } // check for existing if (!spheres.ContainsKey(period)) { // scale template float size = period * _Scaling; Vector4[] vertices = Vector3.Transform(sphere.Positions, Matrix.Scaling(size, size, size)); Vector3[] vertices3 = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { vertices3[i] = new Vector3(vertices[i].X, vertices[i].Y, vertices[i].Z); } spheres.Add(period, vertices3); } Vector3[] sphereData = spheres[period]; // write to buffer IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } // copy sphere Vector3 atomSpace = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); /*Vector4 clr = new Vector4((float)material.BaseColor.R / 255f, (float)material.BaseColor.G / 255f, * (float)material.BaseColor.B / 255f, (float)material.BaseColor.A / 255f);*/ int clr = material.BaseColor.ToArgb(); for (int v = 0; v < sphereData.Length; v++) { if (positionPos != -1) { Vector3 position = sphereData[v] + atomSpace; data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(position.X); data.Write(position.Y); data.Write(position.Z); } if (texPos != -1) { data.Seek(pos + texPos, SeekOrigin.Begin); data.Write(0f); //sphere.TexCoords[v].X); data.Write(0f); //sphere.TexCoords[v].Y); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(sphere.Normals[v].X); data.Write(sphere.Normals[v].Y); data.Write(sphere.Normals[v].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); /*data.Write(clr.X); * data.Write(clr.Y); * data.Write(clr.Z); * data.Write(clr.W);*/ data.Write((Int32)clr); } pos += geomStream.Stride; } } } else { Vector3[] Positions, normals; Vector2[] texCoords; SphereMathHelper.CreateSphereTriangles(new Vector3(), 1, sphereDetail1, out Positions, out normals, out texCoords); // clone and scale template for each size required Vector3 center = new Vector3(); Dictionary <int, Vector3[]> spheres = new Dictionary <int, Vector3[]>(); AtomShadingDesc aShading = coDesc.AtomShadingDesc; int vertsIdx = 0; long pos = 0; foreach (IAtom atom in objs) { int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } // check for existing if (!spheres.ContainsKey(period)) { // scale template float size = period * _Scaling; Vector4[] vertices = Vector3.Transform(Positions, Matrix.Scaling(size, size, size)); Vector3[] vertices3 = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { vertices3[i] = new Vector3(vertices[i].X, vertices[i].Y, vertices[i].Z); } spheres.Add(period, vertices3); } Vector3[] sphereData = spheres[period]; // write to buffer IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } // copy sphere Vector3 atomSpace = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); int clr = material.BaseColor.ToArgb(); for (int v = 0; v < sphereData.Length; v++) { if (positionPos != -1) { Vector3 position = sphereData[v] + atomSpace; data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(position.X); data.Write(position.Y); data.Write(position.Z); } if (texPos != -1) { data.Seek(pos + texPos, SeekOrigin.Begin); data.Write(texCoords[v].X); data.Write(texCoords[v].Y); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(normals[v].X); data.Write(normals[v].Y); data.Write(normals[v].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); /*data.Write(clr.X); * data.Write(clr.Y); * data.Write(clr.Z); * data.Write(clr.W);*/ data.Write((Int32)clr); } pos += geomStream.Stride; } } } buffer.vBuffers[0].Buffer.Unlock(); }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } break; } } } // actually create the metaball triangles or points IVolume[] volumes = new IVolume[objs.Count]; int sIdx = 0; AtomShadingDesc aShading = coDesc.AtomShadingDesc; IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; foreach (IAtom atom in objs) { IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } volumes[sIdx++] = new Metaball(new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d), 0.17f, material.BaseColor); } // process volume into triangles GenericVolumeScene scene = new GenericVolumeScene(volumes); int[] triangles = null; Vector3[] vertices; Color[] colours; Vector3[] normals = null; if (!pointsOnly) { IsosurfaceGenerator3D.GenerateSimpleMesh(scene, new Vector3(), scene.EstimateVolumeMaxSize(), 40, false, out triangles, out vertices, out colours); MeshOptimzer.GenerateTriPointNormals(triangles, vertices, out normals); } else { IsosurfaceGenerator3D.GenerateSimplePointOutline(scene, new Vector3(), scene.EstimateVolumeMaxSize(), 40, out vertices, out colours); } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * vertices.Length, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = vertices.Length; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; if (pointsOnly) { buffer.iBuffers[0].NumPrimitives = vertices.Length; buffer.iBuffers[0].PrimType = PrimitiveType.PointList; buffer.Light = false; } else { buffer.iBuffers[0].NumPrimitives = triangles.Length / 3; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; buffer.iBuffers[0].Buffer = new IndexBuffer(typeof(int), triangles.Length, device, Usage.WriteOnly, Pool.Managed); } // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields int clr = Color.FromArgb(255, 255, 255).ToArgb(); long pos = 0; for (int i = 0; i < vertices.Length; i++) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(vertices[i].X); data.Write(vertices[i].Y); data.Write(vertices[i].Z); } if (normalPos != -1 && !pointsOnly) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(normals[i].X); data.Write(normals[i].Y); data.Write(normals[i].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(colours[i].ToArgb()); } //verts[i].Color = colours[i].ToArgb(); pos += geomStream.Stride; } buffer.vBuffers[0].Buffer.Unlock(); if (!pointsOnly) { buffer.iBuffers[0].Buffer.SetData(triangles, 0, LockFlags.None); } // dispose of temp data }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int sizePos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "SIZEFLOAT") { sizePos = geomStream.FieldPositions[gf]; } break; } } } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(typeof(MetaBlobsEffect.PointVertex), objs.Count, device, Usage.None, VertexFormats.Position | VertexFormats.PointSize | VertexFormats.Diffuse, Pool.SystemMemory); /*new VertexBuffer(device, geomStream.Stride * objs.Count, * Usage.WriteOnly, geomStream.Format, Pool.SystemMemory);*/ buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count; buffer.vBuffers[0].Format = geomStream.Format; buffer.DataValidity = BufferedGeometryData.DataValidityType.Source; buffer.Target = BufferedGeometryData.DataTarget.Geometry; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields // create points AtomShadingDesc aShading = coDesc.AtomShadingDesc; long pos = 0; foreach (IAtom atom in objs) { int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write((float)atom.X3d); data.Write((float)atom.Y3d); data.Write((float)atom.Z3d); } if (sizePos != -1) { data.Seek(pos + sizePos, SeekOrigin.Begin); data.Write((float)period); } if (diffusePos != -1) { IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } if (material != null) { data.Seek(pos + diffusePos, SeekOrigin.Begin); //data.Write((float)material.BaseColor.ToArgb()); if (material.BaseColor.R > 0) { data.Write(255f / material.BaseColor.R); } else { data.Write((float)0); } if (material.BaseColor.G > 0) { data.Write(255f / material.BaseColor.G); } else { data.Write((float)0); } if (material.BaseColor.B > 0) { data.Write(255f / material.BaseColor.B); } else { data.Write((float)0); } } } pos += geomStream.Stride; } buffer.vBuffers[0].Buffer.Unlock(); }
public static void GenericBondSetup(IBond bond, bool sort, BondShadingDesc bShading, out Vector3 direction, out Vector3 directionUV, out IAtom[] atoms, out Vector3[] atomsPos, out IMoleculeMaterial matA, out IMoleculeMaterial matB) { atoms = bond.getAtoms(); Vector3 v1 = new Vector3((float)atoms[0].X3d, (float)atoms[0].Y3d, (float)atoms[0].Z3d); Vector3 v2 = new Vector3((float)atoms[1].X3d, (float)atoms[1].Y3d, (float)atoms[1].Z3d); direction = v2 - v1; atomsPos = new Vector3[2]; if (sort) { if (direction.Z < (v1 - v2).Z) { IAtom temp = atoms[0]; atoms[0] = atoms[1]; atoms[1] = temp; atomsPos[0] = v2; atomsPos[1] = v1; } else { atomsPos[0] = v1; atomsPos[1] = v2; } direction = Vector3.Normalize(atomsPos[1] - atomsPos[0]); } else { atomsPos[0] = v1; atomsPos[1] = v2; } directionUV = Vector3.Normalize(direction); IMoleculeMaterialLookup lookup = bShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atoms[0].Symbol); if (matTemp != null) matA = matTemp.BySymbol; else { PeriodicTableElement pe = (PeriodicTableElement)atoms[0].Properties["PeriodicTableElement"]; matA = lookup.GetBySeries(pe.ChemicalSerie); } matTemp = lookup.ResolveBySymbol(atoms[1].Symbol); if (matTemp != null) matB = matTemp.BySymbol; else { PeriodicTableElement pe = (PeriodicTableElement)atoms[1].Properties["PeriodicTableElement"]; matB = lookup.GetBySeries(pe.ChemicalSerie); } }