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;
            }
        }
Example #5
0
        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 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;
            }
        }
Example #10
0
        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;
            }
        }
 public MoleculeMaterialTemplate(IMoleculeMaterial symbolMat, IMoleculeMaterial serieMat)
 {
     this.symbolMat = symbolMat;
     this.serieMat = serieMat;
 }
 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;
     }
 }
        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;
            }
        }
        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();
        }
        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;
        }
        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();
        }
Example #18
0
        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);
            }
        }