public override void SetOutputDescription(CompleteOutputDescription coDesc)
        {
            //MetaBlobsSchemeSettings settings = (MetaBlobsSchemeSettings)coDesc.SchemeSettings;

            atomsBufferCreators = new AtomGeometryCreator[] { new AtomBlobBufferCreator() };
            atomsBufferCreators[0].SetupForCreation(null);

            this.coDesc = coDesc;
        }
        public override void SetOutputDescription(CompleteOutputDescription coDesc)
        {
            //MetaBlobsSchemeSettings settings = (MetaBlobsSchemeSettings)coDesc.SchemeSettings;

            atomsBufferCreators = new AtomGeometryCreator[] { new AtomBlobBufferCreator() };
            atomsBufferCreators[0].SetupForCreation(null);

            this.coDesc = coDesc;
        }
示例#3
0
 public void ApplySettings(CompleteOutputDescription outputDesc)
 {
     this.outputDesc = outputDesc;
     this.outputDesc.AtomShadingDesc.MoleculeMaterials = modules[0];
     this.outputDesc.BondShadingDesc.MoleculeMaterials = modules[0];
     if (renderContext != null)
     {
         renderContext.ApplyOutputDescription(outputDesc);
         renderContext.OnResize(Width, Height);
     }
 }
        public void ApplyOutputDescription(CompleteOutputDescription desc)
        {
            desc.CompareAgainst(desc, true);
            outputDescription = desc;

            /*if (desc.GeneralShadingDesc.AntiAliasing > 0)
             *  presentParams.MultiSample = MultiSampleType.FourSamples;
             * else
             *  presentParams.MultiSample = MultiSampleType.None;*/

            try
            {
                device.Reset(presentParams);
            }
            catch (Exception e)
            {
                log.AddItem(new LogItem(string.Format("Device failed to reset with pParams={0},{1},{2},{3},{4},{5},{6}: Exception is - {7}",
                                                      presentParams.AutoDepthStencilFormat,
                                                      presentParams.BackBufferFormat,
                                                      presentParams.BackBufferHeight,
                                                      presentParams.BackBufferWidth,
                                                      presentParams.EnableAutoDepthStencil,
                                                      presentParams.MultiSample,
                                                      presentParams.SwapEffect,
                                                      e.Message),
                                        LogItem.ItemLevel.Error));
                throw;
            }

            sceneManager.SetScheme(desc.SchemeSettings.GetScheme(device));
            sceneManager.SetOutputDesc(desc);

            if (desc.GeneralShadingDesc.Wireframe)
            {
                device.RenderState.FillMode = FillMode.WireFrame;
            }
            else
            {
                device.RenderState.FillMode = FillMode.Solid;
            }

            switch (desc.GeneralShadingDesc.ShadingMode)
            {
            case NuGenSVisualLib.Rendering.Shading.GeneralShadingDesc.ShadingModes.Smooth:
                device.RenderState.ShadeMode = ShadeMode.Phong;
                break;

            case NuGenSVisualLib.Rendering.Shading.GeneralShadingDesc.ShadingModes.Flat:
                device.RenderState.ShadeMode = ShadeMode.Flat;
                break;
            }

            RefreshDescription();
        }
        public override void SetOutputDescription(CompleteOutputDescription coDesc)
        {
            //SpriteSchemeSettings settings = (SpriteSchemeSettings)coDesc.SchemeSettings;

            atomsBufferCreators = new AtomGeometryCreator[] { new AtomSpriteBufferCreator() };
            atomsBufferCreators[0].SetupForCreation(null);

            lightBonds = false;
            lightAtoms = true;

            this.coDesc = coDesc;
        }
示例#6
0
        public override void SetOutputDescription(CompleteOutputDescription coDesc)
        {
            //SpriteSchemeSettings settings = (SpriteSchemeSettings)coDesc.SchemeSettings;

            atomsBufferCreators = new AtomGeometryCreator[] { new AtomSpriteBufferCreator() };
            atomsBufferCreators[0].SetupForCreation(null);

            lightBonds = false;
            lightAtoms = true;

            this.coDesc = coDesc;
        }
示例#7
0
        public override void SetOutputDescription(CompleteOutputDescription coDesc)
        {
            //SpaceFillSchemeSettings settings = (SpaceFillSchemeSettings)coDesc.SchemeSettings;

            atomsBufferCreators = new AtomGeometryCreator[] { new AtomSphereBufferCreator(0.5f, 16, 12) };
            atomsBufferCreators[0].SetupForCreation(null);

            bondsBufferCreators = null;

            lightAtoms = true;

            this.coDesc = coDesc;
        }
        public override void SetOutputDescription(CompleteOutputDescription coDesc)
        {
            //SpaceFillSchemeSettings settings = (SpaceFillSchemeSettings)coDesc.SchemeSettings;

            atomsBufferCreators = new AtomGeometryCreator[] { new AtomSphereBufferCreator(0.5f, 16, 12) };
            atomsBufferCreators[0].SetupForCreation(null);

            bondsBufferCreators = null;

            lightAtoms = true;

            this.coDesc = coDesc;
        }
示例#9
0
        public void SetScheme(MoleculeRenderingScheme scheme, CompleteOutputDescription coDesc)
        {
            latestCoDesc = new CompleteOutputDescription(coDesc);
            sceneManger.SetScheme(scheme);
            sceneManger.SetOutputDesc(coDesc);

            scheme.device = device;
            // build preview via thread
            if (generatorThread.ThreadState == ThreadState.Running)
            {
                // abort thread
                generatorThread.Abort();
                generatorThread.Join();
            }
            generatorThread = new Thread(GeneratePreviewProcess);
            generatorThread.Start();

            wantPreview = true;
        }
示例#10
0
        public void UpdateBonds(CompleteOutputDescription latestCoDesc, IBond[] bonds)
        {
            if (scheme.HandlesBonds)
            {
                scheme.SetOutputDescription(coDesc);

                DataFields[][]         allStreams = new DataFields[1][];
                IGeometryCreator[]     schStreams = scheme.GetBondStreams();
                GeomDataBufferStream[] geomStream = new GeomDataBufferStream[schStreams.Length];

                for (int i = 0; i < geomStream.Length; i++)
                {
                    allStreams[0] = schStreams[i].Fields;
                    GeomDataTransformer.CreateBufferStream(allStreams, out geomStream[i]);
                }
                // fill buffer stream
                scheme.SetBondData(bonds, geomStream);
            }
        }
示例#11
0
        public MoleculeSchemeDlg(HashTableSettings settings, OutputCaps outCaps, Device device, CompleteOutputDescription coDesc)
        {
            InitializeComponent();

            currentEffects = new List <Effect>();

            this.settings = settings;

            LoadLocalResources();

            this.refDevice = device;
            this.outCaps   = outCaps;
            this.refcoDesc = coDesc;
            this.coDesc    = new CompleteOutputDescription(coDesc);

            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.LightingPresets.config"))
            {
                LoadLightingPresets(stream);
            }

            SetupLightingPreview();
            SetupEffectPreview();

            schemePreviewControl.OnNewPreview += new EventHandler(schemePreviewControl_OnNewPreview);
            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.MoleculeSchemes.config"))
            {
                if (stream != null)
                {
                    XmlDocument xml = new XmlDocument();
                    xml.Load(stream);

                    LoadSchemes(xml);
                    LoadEffects(xml);
                    LoadMaterials(xml);
                }
            }

            previewReady = true;

            updateThread = new Thread(this.UpdatePreviewsProcess);
            updateThread.Start();
        }
示例#12
0
        public void UpdateAtoms(CompleteOutputDescription coDesc, IAtom[] atoms)
        {
            if (scheme.HandlesAtoms)
            {
                scheme.SetOutputDescription(coDesc);

                // pass throught scheme & effects
                IGeometryCreator[] schStreams = scheme.GetAtomStreams();
                DataFields[][]     allStreams = new DataFields[1][];

                GeomDataBufferStream[] geomStream = new GeomDataBufferStream[schStreams.Length];
                for (int i = 0; i < geomStream.Length; i++)
                {
                    allStreams[0] = schStreams[i].Fields;
                    GeomDataTransformer.CreateBufferStream(allStreams, out geomStream[i]);
                }
                // fill buffer stream
                scheme.SetAtomData(atoms, geomStream);
            }
        }
示例#13
0
        private void CreatePreviewData()
        {
            atoms = new IAtom[] { new Atom("O", new Point3d(0, 0, 0)) };

            ElementPTFactory elements = ElementPTFactory.Instance;

            foreach (IAtom atom in atoms)
            {
                PeriodicTableElement pe = elements.getElement(atom.Symbol);
                if (pe != null)
                {
                    atom.AtomicNumber = pe.AtomicNumber;
                    atom.Properties["PeriodicTableElement"] = pe;
                    atom.Properties["Period"] = int.Parse(pe.Period);
                }
            }

            projMat = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, Width / Height, 0.1f, 20);
            viewMat = Matrix.LookAtLH(new Vector3(2, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 1, 0));

            latestCoDesc = CompleteOutputDescription.New();
            latestCoDesc.SchemeSettings         = new BallAndStickSchemeSettings();
            latestCoDesc.SchemeSettings.AtomLOD = 3;
        }
示例#14
0
        public void Init(HashTableSettings settings, ICommonDeviceInterface cdi)
        {
            this.settings = settings;
            settings["Molecule.Shading.Material.Type"] = "BySerie";

            // load settings
            BackColor = (Color)settings["View3D.BgClr"];

            // load local modules
            foreach (ISettingsModule module in modules)
            {
                module.LoadModuleSettings(settings);
            }

            renderContext           = new ChemRenderingContext3DDX9(settings, this, (CommonDeviceInterface)cdi);
            renderContext.BackColor = BackColor;

            // load default output settings
            CompleteOutputDescription desc = CompleteOutputDescription.LoadDescription(Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.defaultOutput.xml"));

            desc.SchemeSettings         = new BallAndStickSchemeSettings();
            desc.SchemeSettings.AtomLOD = 2;
            ApplySettings(desc);
        }
示例#15
0
 private void LoadOutputSettings()
 {
     outputDesc = CompleteOutputDescription.LoadDescription(outputSettingsXmlFile);
     outputDesc.SchemeSettings = new BallAndStickSchemeSettings();
     ApplySettings(outputDesc);
 }
示例#16
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
        }
示例#17
0
        public override void SetOutputDescription(CompleteOutputDescription coDesc)
        {
            bool updateAtomLOD = true;
            bool updateBondLOD = true;
            bool updateSymbols = true;
            bool updateGlow    = true;

            bool updateBondSize = true;

            bool updateBonds  = true;
            bool updateAtoms  = true;
            bool updateScheme = true;

            if (this.coDesc != null)
            {
                this.coDesc = coDesc;
                updateAtoms = coDesc.CheckChange("AtomShadingDesc.");
                if (updateAtoms)
                {
                    updateSymbols = coDesc.CheckChange("AtomShadingDesc.", "SymbolText");
                    updateGlow    = coDesc.CheckChange("SchemeSettings.", "Glow");
                }
                updateBonds = coDesc.CheckChange("BondShadingDesc.");

                updateScheme = coDesc.CheckChange("SchemeSettings.");
                if (updateScheme)
                {
                    updateAtomLOD = coDesc.CheckChange("SchemeSettings.", "AtomLOD");
                    updateBondLOD = coDesc.CheckChange("SchemeSettings.", "BondLOD");

                    updateBondSize = coDesc.CheckChange("SchemeSettings.", "StickThickness");
                }
            }
            else
            {
                this.coDesc = coDesc;
            }
            BallAndStickSchemeSettings settings = (BallAndStickSchemeSettings)coDesc.SchemeSettings;

            int atomDetail1 = 4;
            int atomDetail2 = 1;

            if (updateAtoms || updateScheme)
            {
                /*if (updateAtomLOD)
                 * {*/
                switch (settings.AtomLOD)
                {
                case 0:
                    atomDetail1 = 4;
                    atomDetail2 = 1;
                    break;

                case 1:
                    atomDetail1 = 8;
                    atomDetail2 = 6;
                    break;

                case 2:
                    atomDetail1 = 12;
                    atomDetail2 = 9;
                    break;

                case 3:
                    atomDetail1 = 16;
                    atomDetail2 = 12;
                    break;

                case 4:
                    atomDetail1 = 24;
                    atomDetail2 = 18;
                    break;

                case 5:
                    atomDetail1 = 32;
                    atomDetail2 = 26;
                    break;
                }
                //}
                int bufCount = 1;
                if (settings.ElectronChargeCloud)
                {
                    bufCount++;
                }
                if (settings.Glow > 0)
                {
                    bufCount++;
                }
                if (coDesc.AtomShadingDesc.SymbolText)
                {
                    bufCount++;
                }

                // TODO: Reconfigure previous creators
                atomsBufferCreators    = new AtomGeometryCreator[bufCount];
                atomsBufferCreators[0] = new AtomSphereBufferCreator(0.2f, atomDetail1, atomDetail2);
                bufCount = 1;
                if (settings.Glow > 0)
                {
                    atomsBufferCreators[bufCount++] = new AtomSpriteBufferCreator();
                }
                if (settings.ElectronChargeCloud)
                {
                    atomsBufferCreators[bufCount++] = new AtomMetaballsBufferCreator(true);
                }
                if (coDesc.AtomShadingDesc.SymbolText)
                {
                    atomsBufferCreators[bufCount++] = new AtomSymbolSpriteBufferCreator();
                }

                foreach (AtomGeometryCreator creator in atomsBufferCreators)
                {
                    creator.SetupForCreation(null);
                }
            }

            if (updateBonds || updateScheme)
            {
                if (updateBondSize)
                {
                    if (settings.StickThickness == 0 && (bondsBufferCreators == null || !(bondsBufferCreators[0] is BondLinesBufferCreator)))
                    {
                        bondsBufferCreators = new BondGeometryCreator[] { new BondLinesBufferCreator() }
                    }
                    ;
                    else if (settings.StickThickness > 0 && (bondsBufferCreators == null || !(bondsBufferCreators[0] is BondThickLinesBufferCreator)))
                    {
                        bondsBufferCreators = new BondGeometryCreator[] { new BondThickLinesBufferCreator(5) }
                    }
                    ;
                    bondsBufferCreators[0].SetupForCreation(null);
                }
            }

            lightBonds = false;
            lightAtoms = true;

            this.coDesc = coDesc;
        }
    }
        public override void SetOutputDescription(CompleteOutputDescription coDesc)
        {
            bool updateAtomLOD = true;
            bool updateBondLOD = true;
            bool updateSymbols = true;
            bool updateGlow = true;

            bool updateBondSize = true;

            bool updateBonds = true;
            bool updateAtoms = true;
            bool updateScheme = true;

            if (this.coDesc != null)
            {
                this.coDesc = coDesc;
                updateAtoms = coDesc.CheckChange("AtomShadingDesc.");
                if (updateAtoms)
                {
                    updateSymbols = coDesc.CheckChange("AtomShadingDesc.", "SymbolText");
                    updateGlow = coDesc.CheckChange("SchemeSettings.", "Glow");
                }
                updateBonds = coDesc.CheckChange("BondShadingDesc.");

                updateScheme = coDesc.CheckChange("SchemeSettings.");
                if (updateScheme)
                {
                    updateAtomLOD = coDesc.CheckChange("SchemeSettings.", "AtomLOD");
                    updateBondLOD = coDesc.CheckChange("SchemeSettings.", "BondLOD");
                    
                    updateBondSize = coDesc.CheckChange("SchemeSettings.", "StickThickness");
                }
            }
            else
                this.coDesc = coDesc;
            BallAndStickSchemeSettings settings = (BallAndStickSchemeSettings)coDesc.SchemeSettings;

            int atomDetail1 = 4;
            int atomDetail2 = 1;
            if (updateAtoms || updateScheme)
            {
                /*if (updateAtomLOD)
                {*/
                    switch (settings.AtomLOD)
                    {
                        case 0:
                            atomDetail1 = 4;
                            atomDetail2 = 1;
                            break;
                        case 1:
                            atomDetail1 = 8;
                            atomDetail2 = 6;
                            break;
                        case 2:
                            atomDetail1 = 12;
                            atomDetail2 = 9;
                            break;
                        case 3:
                            atomDetail1 = 16;
                            atomDetail2 = 12;
                            break;
                        case 4:
                            atomDetail1 = 24;
                            atomDetail2 = 18;
                            break;
                        case 5:
                            atomDetail1 = 32;
                            atomDetail2 = 26;
                            break;
                    }
                //}
                int bufCount = 1;
                if (settings.ElectronChargeCloud)
                    bufCount++;
                if (settings.Glow > 0)
                    bufCount++;
                if (coDesc.AtomShadingDesc.SymbolText)
                    bufCount++;

                // TODO: Reconfigure previous creators
                atomsBufferCreators = new AtomGeometryCreator[bufCount];
                atomsBufferCreators[0] = new AtomSphereBufferCreator(0.2f, atomDetail1, atomDetail2);
                bufCount = 1;
                if (settings.Glow > 0)
                    atomsBufferCreators[bufCount++] = new AtomSpriteBufferCreator();
                if (settings.ElectronChargeCloud)
                    atomsBufferCreators[bufCount++] = new AtomMetaballsBufferCreator(true);
                if (coDesc.AtomShadingDesc.SymbolText)
                    atomsBufferCreators[bufCount++] = new AtomSymbolSpriteBufferCreator();

                foreach (AtomGeometryCreator creator in atomsBufferCreators)
                {
                    creator.SetupForCreation(null);
                }
            }

            if (updateBonds || updateScheme)
            {
                if (updateBondSize)
                {
                    if (settings.StickThickness == 0 && (bondsBufferCreators == null || !(bondsBufferCreators[0] is BondLinesBufferCreator)))
                        bondsBufferCreators = new BondGeometryCreator[] { new BondLinesBufferCreator() };
                    else if (settings.StickThickness > 0 && (bondsBufferCreators == null || !(bondsBufferCreators[0] is BondThickLinesBufferCreator)))
                        bondsBufferCreators = new BondGeometryCreator[] { new BondThickLinesBufferCreator(5) };
                    bondsBufferCreators[0].SetupForCreation(null);
                }
            }

            lightBonds = false;
            lightAtoms = true;

            this.coDesc = coDesc;
        }
        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 override void CreateGeometryForObjects(Device device, ICollection<IBond> 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;
                    }
                }
            }

            // count bond orders via preview data
            int numActualBonds = 0;
            foreach (IBond bond in objs)
            {
                numActualBonds += (int)bond.Order;
            }

            int numVerts = 0;
            if (coDesc.BondShadingDesc.BlendEndClrs)
                numVerts = numActualBonds * 2;
            else
                numVerts = numActualBonds * 4;

            // create buffers
            buffer = new BufferedGeometryData(device, objs.Count);
            buffer.vBuffers = new BufferedGeometryData.VertexData[1];
            buffer.vBuffers[0] = new BufferedGeometryData.VertexData();
            buffer.vBuffers[0].Stride = geomStream.Stride;
            buffer.vBuffers[0].NumElements = 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 = numVerts / 2;
            buffer.iBuffers[0].PrimType = PrimitiveType.LineList;

            buffer.vBuffers[0].NumElements = numVerts;
            buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * numVerts,
                                                         Usage.WriteOnly, geomStream.Format, Pool.Managed);

            // write bonds to buffer
            Vector3 direction, directionUV;
            IAtom[] atoms;
            Vector3[] atomsPos;
            IMoleculeMaterial materialA, materialB;
            Vector3[] bondInstances = null;
            float midPos;
            BondShadingDesc bShading = coDesc.BondShadingDesc;

            // lock stream
            GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None);

            long pos = 0;
            foreach (IBond bond in objs)
            {
                GenericBondSetup(bond, false, bShading, out direction, out directionUV,
                                 out atoms, out atomsPos, out materialA, out materialB);

                // calc bond positioning / instances
                GenericBondCalcPositions(bond, bShading, direction, directionUV,
                                         atoms, atomsPos, 0.1f, out bondInstances,
                                         out midPos, true);

                // draw bond instances
                for (int bInst = 0; bInst < bondInstances.Length; bInst += 2)
                {
                    if (bShading.BlendEndClrs)
                    {
                        GenericDrawBondSolidBlended(bondInstances[bInst], bondInstances[bInst + 1],
                                                    materialA, materialB, data, ref pos, geomStream.Stride, positionPos, diffusePos);
                        //GenericDrawBondDashedBlended(bondInstances[bInst], bondInstances[bInst + 1],
                        //                            materialA, materialB);
                    }
                    else
                    {
                        Vector3 sectA = directionUV * midPos;

                        // convert into points (2 lines)
                        if (positionPos != -1)
                        {
                            data.Seek(pos + positionPos, SeekOrigin.Begin);
                            data.Write(bondInstances[bInst].X);
                            data.Write(bondInstances[bInst].Y);
                            data.Write(bondInstances[bInst].Z);

                            data.Seek(pos + geomStream.Stride + positionPos, SeekOrigin.Begin);
                            Vector3 p = bondInstances[bInst] + sectA;
                            data.Write(p.X);
                            data.Write(p.Y);
                            data.Write(p.Z);

                            data.Seek(pos + geomStream.Stride + geomStream.Stride + positionPos, SeekOrigin.Begin);
                            data.Write(p.X);
                            data.Write(p.Y);
                            data.Write(p.Z);

                            data.Seek(pos + geomStream.Stride + geomStream.Stride + geomStream.Stride + positionPos, SeekOrigin.Begin);
                            data.Write(bondInstances[bInst + 1].X);
                            data.Write(bondInstances[bInst + 1].Y);
                            data.Write(bondInstances[bInst + 1].Z);
                        }
                        if (diffusePos != -1)
                        {
                            data.Seek(pos + diffusePos, SeekOrigin.Begin);
                            int clr = materialA.BaseColor.ToArgb();
                            data.Write(clr);

                            data.Seek(pos + geomStream.Stride + diffusePos, SeekOrigin.Begin);
                            data.Write(clr);

                            clr = materialB.BaseColor.ToArgb();
                            data.Seek(pos + geomStream.Stride + geomStream.Stride + diffusePos, SeekOrigin.Begin);
                            data.Write(clr);

                            data.Seek(pos + geomStream.Stride + geomStream.Stride + geomStream.Stride + diffusePos, SeekOrigin.Begin);
                            data.Write(clr);
                        }

                        pos += geomStream.Stride * 4;
                    }
                }
            }

            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 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 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 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();
        }
示例#24
0
        public override void CreateGeometryForObjects(Device device, ICollection <IBond> 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;
                    }
                }
            }

            // count bond orders via preview data
            int numActualBonds = 0;

            foreach (IBond bond in objs)
            {
                numActualBonds += (int)bond.Order;
            }

            if (!coDesc.BondShadingDesc.BlendEndClrs)
            {
                numActualBonds *= 2;
            }

            int numTriangles = objs.Count * (numSides * 2);

            SphereMathHelper.EndType endType = SphereMathHelper.EndType.Open;
            float offset = 0.0f;

            switch (coDesc.BondShadingDesc.EndType)
            {
            case BondShadingDesc.BondEndTypes.Open:
                break;

            case BondShadingDesc.BondEndTypes.Closed:
                numTriangles += numActualBonds * (numSides * 2);
                endType       = SphereMathHelper.EndType.Flat;
                break;

            case BondShadingDesc.BondEndTypes.Point:
                offset        = 0.05f;
                numTriangles += numActualBonds * (numSides * 2);
                endType       = SphereMathHelper.EndType.Flat;
                break;

            case BondShadingDesc.BondEndTypes.Rounded:
                offset        = 0.075f;
                numTriangles += numActualBonds * (numSides * 6);
                endType       = SphereMathHelper.EndType.Rounded;
                break;
            }

            // build template bond
            Vector3[] tCylinderPoints, tCylinderEndPoints1, tCylinderEndPoints2;
            Vector3[] tCylinderNormals, tCylinderEndNormals1, tCylinderEndNormals2;
            int[]     tCylinderTris, tCylinderEndTris1, tCylinderEndTris2;

            SphereMathHelper.CalcCylinderTriangles(numSides, 1, 1.0f, new Vector3(0, 0, 0), new Vector3(0, 0, 1),
                                                   true, endType, offset, out tCylinderPoints,
                                                   out tCylinderNormals, out tCylinderTris, out tCylinderEndPoints1,
                                                   out tCylinderEndNormals1, out tCylinderEndTris1,
                                                   out tCylinderEndPoints2, out tCylinderEndNormals2,
                                                   out tCylinderEndTris2);
            int numActualVerts = tCylinderPoints.Length + tCylinderEndPoints1.Length + tCylinderEndPoints2.Length;
            int numActualTris  = tCylinderTris.Length + tCylinderEndTris1.Length + tCylinderEndTris2.Length;

            // create buffers
            buffer                         = new BufferedGeometryData(device, objs.Count);
            buffer.vBuffers                = new BufferedGeometryData.VertexData[1];
            buffer.vBuffers[0]             = new BufferedGeometryData.VertexData();
            buffer.vBuffers[0].Stride      = geomStream.Stride;
            buffer.vBuffers[0].NumElements = numActualVerts;
            buffer.vBuffers[0].Format      = geomStream.Format;

            buffer.vBuffers[0].NumElements = numActualVerts * numActualBonds;
            buffer.vBuffers[0].Buffer      = new VertexBuffer(device, geomStream.Stride * numActualTris * numActualBonds * 3,
                                                              Usage.WriteOnly, geomStream.Format, Pool.Managed);

            buffer.iBuffers                  = new BufferedGeometryData.IndexData[1];
            buffer.iBuffers[0]               = new BufferedGeometryData.IndexData();
            buffer.iBuffers[0].Desc          = BufferedGeometryData.IndexData.Description.Geometry;
            buffer.iBuffers[0].NumPrimitives = numActualTris;
            buffer.iBuffers[0].PrimType      = PrimitiveType.TriangleList;

            buffer.iBuffers[0].NumPrimitives = (numActualTris * numActualBonds) / 3;

            /*buffer.iBuffers[0].Buffer = new IndexBuffer(typeof(int), numActualTris * numActualBonds, device,
             *                                          Usage.WriteOnly, Pool.Managed);*/

            // lock stream
            GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None);

            // write bonds to buffer
            Vector3 direction, directionUV;

            IAtom[]           atoms;
            Vector3[]         atomsPos;
            IMoleculeMaterial matA, matB;

            foreach (IBond bond in objs)
            {
                BondLinesBufferCreator.GenericBondSetup(bond, true, coDesc.BondShadingDesc, out direction,
                                                        out directionUV, out atoms, out atomsPos, out matA,
                                                        out matB);

                // calc bond positioning / instances
                Vector3[] bondInstances = null;
                float     midPos;
                BondLinesBufferCreator.GenericBondCalcPositions(bond, coDesc.BondShadingDesc, direction,
                                                                directionUV, atoms, atomsPos, 0.15f,
                                                                out bondInstances, out midPos, false);

                long pos = 0;
                for (int bInst = 0; bInst < bondInstances.Length; bInst += 2)
                {
                    // translation
                    Matrix translate = Matrix.Translation(bondInstances[bInst]);

                    // rotation
                    double x = direction.X;
                    double y = direction.Y;
                    double z = direction.Z;

                    double alpha = (z == 0) ? Math.PI / 2 : Math.Atan(x / z);
                    double r     = (alpha == 0) ? z : x / Math.Sin(alpha);
                    float  sign  = 1f;
                    if (z != 0)
                    {
                        sign *= Math.Sign(z);
                    }
                    else if (x != 0)
                    {
                        sign *= Math.Sign(x);
                    }
                    if (y != 0)
                    {
                        sign *= Math.Sign(y);
                    }
                    double theta = -sign *Math.Abs((r == 0)?Math.PI / 2 : Math.Atan(y / r));

                    Matrix rotation = Matrix.RotationX((float)theta) * Matrix.RotationY((float)alpha);

                    // scaling
                    float zScale;
                    if (coDesc.BondShadingDesc.BlendEndClrs)
                    {
                        zScale = (bondInstances[1] - bondInstances[0]).Length();//(atomsPos[1] - atomsPos[0]).Length();//direction.Length();
                    }
                    else
                    {
                        zScale = midPos;
                    }
                    float  xyScale = 0.05f; // thickness
                    Matrix scale   = Matrix.Scaling(xyScale, xyScale, zScale);

                    // rotate & translate ends
                    if (tCylinderEndPoints1 != null)
                    {
                        Matrix    endFinal       = Matrix.Scaling(xyScale, xyScale, 1f) * rotation * translate;
                        Vector4[] tfEndTriangles = Vector3.Transform(tCylinderEndPoints1, endFinal);
                        // first end
                        for (int point = 0; point < tCylinderEndTris1.Length; point++)
                        {
                            int pointIdx = tCylinderEndTris1[point];
                            if (positionPos != -1)
                            {
                                data.Seek(pos + positionPos, SeekOrigin.Begin);
                                data.Write(tfEndTriangles[pointIdx].X);
                                data.Write(tfEndTriangles[pointIdx].Y);
                                data.Write(tfEndTriangles[pointIdx].Z);
                            }
                            if (normalPos != -1)
                            {
                                data.Seek(pos + normalPos, SeekOrigin.Begin);
                                data.Write(tCylinderEndNormals1[pointIdx].X);
                                data.Write(tCylinderEndNormals1[pointIdx].Y);
                                data.Write(tCylinderEndNormals1[pointIdx].Z);
                            }
                            if (diffusePos != -1)
                            {
                                data.Seek(pos + diffusePos, SeekOrigin.Begin);
                                data.Write(matA.BaseColor.ToArgb());
                            }
                            pos += geomStream.Stride;
                        }
                        // second end
                        endFinal = Matrix.Scaling(xyScale, xyScale, 1f) * rotation *
                                   Matrix.Translation(bondInstances[bInst + 1]);
                        tfEndTriangles = Vector3.Transform(tCylinderEndPoints2, endFinal);
                        // first end
                        for (int point = 0; point < tCylinderEndTris2.Length; point++)
                        {
                            int pointIdx = tCylinderEndTris2[point];
                            if (positionPos != -1)
                            {
                                data.Seek(pos + positionPos, SeekOrigin.Begin);
                                data.Write(tfEndTriangles[pointIdx].X);
                                data.Write(tfEndTriangles[pointIdx].Y);
                                data.Write(tfEndTriangles[pointIdx].Z);
                            }
                            if (normalPos != -1)
                            {
                                data.Seek(pos + normalPos, SeekOrigin.Begin);
                                data.Write(tCylinderEndNormals2[pointIdx].X);
                                data.Write(tCylinderEndNormals2[pointIdx].Y);
                                data.Write(tCylinderEndNormals2[pointIdx].Z);
                            }
                            if (diffusePos != -1)
                            {
                                data.Seek(pos + diffusePos, SeekOrigin.Begin);
                                data.Write(matB.BaseColor.ToArgb());
                            }
                            pos += geomStream.Stride;
                        }
                    }

                    Matrix final = scale * rotation * translate;

                    if (coDesc.BondShadingDesc.BlendEndClrs)
                    {
                        DrawSolidBondBlended(tCylinderPoints, tCylinderNormals, tCylinderTris,
                                             matA, matB, final, data, positionPos, normalPos,
                                             diffusePos, ref pos, geomStream.Stride, rotation);
                    }
                    else
                    {
                        float bLen2 = (bondInstances[bInst + 1] - (bondInstances[bInst] + (directionUV * midPos))).Length();

                        DrawSolidBondDistinct(tCylinderPoints, tCylinderNormals, tCylinderTris,
                                              matA, matB, final, data, xyScale, bLen2, rotation,
                                              bondInstances[bInst], directionUV, midPos, positionPos,
                                              normalPos, diffusePos, ref pos, geomStream.Stride);
                    }
                }
            }
        }
        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;

            // 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 == "POINTSIZE")
                        {
                            sizePos = geomStream.FieldPositions[gf];
                        }
                        break;
                    }
                }
            }

            // pre-scan for index groups
            Dictionary <string, List <int> > groups = new Dictionary <string, List <int> >();
            int aIdx = 0;

            foreach (IAtom atom in objs)
            {
                if (!groups.ContainsKey(atom.Symbol))
                {
                    groups[atom.Symbol] = new List <int>();
                }
                groups[atom.Symbol].Add(aIdx++);
            }

            // 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);
            buffer.vBuffers[0].Stride      = geomStream.Stride;
            buffer.vBuffers[0].NumElements = objs.Count;
            buffer.vBuffers[0].Format      = geomStream.Format;

            buffer.DataValidity = BufferedGeometryData.DataValidityType.View;

            ChemSymbolTextures cTex = ChemSymbolTextures.Instance;

            buffer.iBuffers = new BufferedGeometryData.IndexData[groups.Count];

            int gIdx = 0;

            foreach (KeyValuePair <string, List <int> > group in groups)
            {
                buffer.iBuffers[gIdx]               = new BufferedGeometryData.IndexData();
                buffer.iBuffers[gIdx].Desc          = BufferedGeometryData.IndexData.Description.Sprites;
                buffer.iBuffers[gIdx].NumPrimitives = group.Value.Count;
                buffer.iBuffers[gIdx].PrimType      = PrimitiveType.PointList;
                buffer.iBuffers[gIdx].Textures      = new Texture[] { cTex[group.Key] };

                buffer.iBuffers[gIdx].Buffer = new IndexBuffer(typeof(int), group.Value.Count, device,
                                                               Usage.WriteOnly, Pool.Managed);
                int[] indices = (int[])buffer.iBuffers[gIdx].Buffer.Lock(0, LockFlags.None);
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] = group.Value[i];
                }
                buffer.iBuffers[gIdx].Buffer.Unlock();

                gIdx++;
            }

            // 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.2f);
                }
                pos += geomStream.Stride;
            }
            buffer.vBuffers[0].Buffer.Unlock();
        }
示例#26
0
 public void SetOutputDesc(CompleteOutputDescription desc)
 {
     this.coDesc = new CompleteOutputDescription(desc);
     scheme.SetOutputDescription(desc);
 }
示例#27
0
 public abstract void SetOutputDescription(CompleteOutputDescription coDesc);
示例#28
0
 private void LoadOutputSettings()
 {
     outputDesc = CompleteOutputDescription.LoadDescription(outputSettingsXmlFile);
     outputDesc.SchemeSettings = new BallAndStickSchemeSettings();
     ApplySettings(outputDesc);
 }
示例#29
0
 public void ApplySettings(CompleteOutputDescription outputDesc)
 {
     this.outputDesc = outputDesc;
     this.outputDesc.AtomShadingDesc.MoleculeMaterials = modules[0];
     this.outputDesc.BondShadingDesc.MoleculeMaterials = modules[0];
     if (renderContext != null)
     {
         renderContext.ApplyOutputDescription(outputDesc);
         renderContext.OnResize(Width, Height);
     }
 }
        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 <IBond> 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;
                    }
                }
            }

            // count bond orders via preview data
            int numActualBonds = 0;

            foreach (IBond bond in objs)
            {
                numActualBonds += (int)bond.Order;
            }

            int numVerts = 0;

            if (coDesc.BondShadingDesc.BlendEndClrs)
            {
                numVerts = numActualBonds * 2;
            }
            else
            {
                numVerts = numActualBonds * 4;
            }

            // create buffers
            buffer                         = new BufferedGeometryData(device, objs.Count);
            buffer.vBuffers                = new BufferedGeometryData.VertexData[1];
            buffer.vBuffers[0]             = new BufferedGeometryData.VertexData();
            buffer.vBuffers[0].Stride      = geomStream.Stride;
            buffer.vBuffers[0].NumElements = 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 = numVerts / 2;
            buffer.iBuffers[0].PrimType      = PrimitiveType.LineList;

            buffer.vBuffers[0].NumElements = numVerts;
            buffer.vBuffers[0].Buffer      = new VertexBuffer(device, geomStream.Stride * numVerts,
                                                              Usage.WriteOnly, geomStream.Format, Pool.Managed);

            // write bonds to buffer
            Vector3 direction, directionUV;

            IAtom[]           atoms;
            Vector3[]         atomsPos;
            IMoleculeMaterial materialA, materialB;

            Vector3[]       bondInstances = null;
            float           midPos;
            BondShadingDesc bShading = coDesc.BondShadingDesc;

            // lock stream
            GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None);

            long pos = 0;

            foreach (IBond bond in objs)
            {
                GenericBondSetup(bond, false, bShading, out direction, out directionUV,
                                 out atoms, out atomsPos, out materialA, out materialB);

                // calc bond positioning / instances
                GenericBondCalcPositions(bond, bShading, direction, directionUV,
                                         atoms, atomsPos, 0.1f, out bondInstances,
                                         out midPos, true);

                // draw bond instances
                for (int bInst = 0; bInst < bondInstances.Length; bInst += 2)
                {
                    if (bShading.BlendEndClrs)
                    {
                        GenericDrawBondSolidBlended(bondInstances[bInst], bondInstances[bInst + 1],
                                                    materialA, materialB, data, ref pos, geomStream.Stride, positionPos, diffusePos);
                        //GenericDrawBondDashedBlended(bondInstances[bInst], bondInstances[bInst + 1],
                        //                            materialA, materialB);
                    }
                    else
                    {
                        Vector3 sectA = directionUV * midPos;

                        // convert into points (2 lines)
                        if (positionPos != -1)
                        {
                            data.Seek(pos + positionPos, SeekOrigin.Begin);
                            data.Write(bondInstances[bInst].X);
                            data.Write(bondInstances[bInst].Y);
                            data.Write(bondInstances[bInst].Z);

                            data.Seek(pos + geomStream.Stride + positionPos, SeekOrigin.Begin);
                            Vector3 p = bondInstances[bInst] + sectA;
                            data.Write(p.X);
                            data.Write(p.Y);
                            data.Write(p.Z);

                            data.Seek(pos + geomStream.Stride + geomStream.Stride + positionPos, SeekOrigin.Begin);
                            data.Write(p.X);
                            data.Write(p.Y);
                            data.Write(p.Z);

                            data.Seek(pos + geomStream.Stride + geomStream.Stride + geomStream.Stride + positionPos, SeekOrigin.Begin);
                            data.Write(bondInstances[bInst + 1].X);
                            data.Write(bondInstances[bInst + 1].Y);
                            data.Write(bondInstances[bInst + 1].Z);
                        }
                        if (diffusePos != -1)
                        {
                            data.Seek(pos + diffusePos, SeekOrigin.Begin);
                            int clr = materialA.BaseColor.ToArgb();
                            data.Write(clr);

                            data.Seek(pos + geomStream.Stride + diffusePos, SeekOrigin.Begin);
                            data.Write(clr);

                            clr = materialB.BaseColor.ToArgb();
                            data.Seek(pos + geomStream.Stride + geomStream.Stride + diffusePos, SeekOrigin.Begin);
                            data.Write(clr);

                            data.Seek(pos + geomStream.Stride + geomStream.Stride + geomStream.Stride + diffusePos, SeekOrigin.Begin);
                            data.Write(clr);
                        }

                        pos += geomStream.Stride * 4;
                    }
                }
            }

            buffer.vBuffers[0].Buffer.Unlock();
        }
示例#32
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
        }
示例#33
0
 public abstract void SetOutputDescription(CompleteOutputDescription coDesc);
        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();
        }
示例#35
0
 public override abstract void CreateGeometryForObjects(Device device, ICollection <IBond> objs,
                                                        GeomDataBufferStream geomStream, int stream,
                                                        ref BufferedGeometryData buffer,
                                                        CompleteOutputDescription coDesc);
        public override void CreateGeometryForObjects(Device device, ICollection<IBond> 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;
                    }
                }
            }

            // count bond orders via preview data
            int numActualBonds = 0;
            foreach (IBond bond in objs)
            {
                numActualBonds += (int)bond.Order;
            }

            if (!coDesc.BondShadingDesc.BlendEndClrs)
                numActualBonds *= 2;

            int numTriangles = objs.Count * (numSides * 2);

            SphereMathHelper.EndType endType = SphereMathHelper.EndType.Open;
            float offset = 0.0f;
            switch (coDesc.BondShadingDesc.EndType)
            {
                case BondShadingDesc.BondEndTypes.Open:
                    break;
                case BondShadingDesc.BondEndTypes.Closed:
                    numTriangles += numActualBonds * (numSides * 2);
                    endType = SphereMathHelper.EndType.Flat;
                    break;
                case BondShadingDesc.BondEndTypes.Point:
                    offset = 0.05f;
                    numTriangles += numActualBonds * (numSides * 2);
                    endType = SphereMathHelper.EndType.Flat;
                    break;
                case BondShadingDesc.BondEndTypes.Rounded:
                    offset = 0.075f;
                    numTriangles += numActualBonds * (numSides * 6);
                    endType = SphereMathHelper.EndType.Rounded;
                    break;
            }

            // build template bond
            Vector3[] tCylinderPoints, tCylinderEndPoints1, tCylinderEndPoints2;
            Vector3[] tCylinderNormals, tCylinderEndNormals1, tCylinderEndNormals2;
            int[] tCylinderTris, tCylinderEndTris1, tCylinderEndTris2;

            SphereMathHelper.CalcCylinderTriangles(numSides, 1, 1.0f, new Vector3(0, 0, 0), new Vector3(0, 0, 1),
                                                   true, endType, offset, out tCylinderPoints,
                                                   out tCylinderNormals, out tCylinderTris, out tCylinderEndPoints1,
                                                   out tCylinderEndNormals1, out tCylinderEndTris1,
                                                   out tCylinderEndPoints2, out tCylinderEndNormals2,
                                                   out tCylinderEndTris2);
            int numActualVerts = tCylinderPoints.Length + tCylinderEndPoints1.Length + tCylinderEndPoints2.Length;
            int numActualTris = tCylinderTris.Length + tCylinderEndTris1.Length + tCylinderEndTris2.Length;

            // create buffers
            buffer = new BufferedGeometryData(device, objs.Count);
            buffer.vBuffers = new BufferedGeometryData.VertexData[1];
            buffer.vBuffers[0] = new BufferedGeometryData.VertexData();
            buffer.vBuffers[0].Stride = geomStream.Stride;
            buffer.vBuffers[0].NumElements = numActualVerts;
            buffer.vBuffers[0].Format = geomStream.Format;

            buffer.vBuffers[0].NumElements = numActualVerts * numActualBonds;
            buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * numActualTris * numActualBonds * 3,
                                                         Usage.WriteOnly, geomStream.Format, Pool.Managed);

            buffer.iBuffers = new BufferedGeometryData.IndexData[1];
            buffer.iBuffers[0] = new BufferedGeometryData.IndexData();
            buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry;
            buffer.iBuffers[0].NumPrimitives = numActualTris;
            buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList;

            buffer.iBuffers[0].NumPrimitives = (numActualTris * numActualBonds) / 3;
            /*buffer.iBuffers[0].Buffer = new IndexBuffer(typeof(int), numActualTris * numActualBonds, device,
                                                        Usage.WriteOnly, Pool.Managed);*/

            // lock stream
            GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None);

            // write bonds to buffer
            Vector3 direction, directionUV;
            IAtom[] atoms;
            Vector3[] atomsPos;
            IMoleculeMaterial matA, matB;

            foreach (IBond bond in objs)
            {
                BondLinesBufferCreator.GenericBondSetup(bond, true, coDesc.BondShadingDesc, out direction,
                                                        out directionUV, out atoms, out atomsPos, out matA,
                                                        out matB);

                // calc bond positioning / instances
                Vector3[] bondInstances = null;
                float midPos;
                BondLinesBufferCreator.GenericBondCalcPositions(bond, coDesc.BondShadingDesc, direction,
                                                                directionUV, atoms, atomsPos, 0.15f,
                                                                out bondInstances, out midPos, false);

                long pos = 0;
                for (int bInst = 0; bInst < bondInstances.Length; bInst += 2)
                {
                    // translation
                    Matrix translate = Matrix.Translation(bondInstances[bInst]);

                    // rotation
                    double x = direction.X;
                    double y = direction.Y;
                    double z = direction.Z;

                    double alpha = (z == 0) ? Math.PI / 2 : Math.Atan(x / z);
                    double r = (alpha == 0) ? z : x / Math.Sin(alpha);
                    float sign = 1f;
                    if (z != 0)
                        sign *= Math.Sign(z);
                    else if (x != 0)
                        sign *= Math.Sign(x);
                    if (y != 0)
                        sign *= Math.Sign(y);
                    double theta = -sign * Math.Abs((r == 0) ? Math.PI / 2 : Math.Atan(y / r));

                    Matrix rotation = Matrix.RotationX((float)theta) * Matrix.RotationY((float)alpha);

                    // scaling
                    float zScale;
                    if (coDesc.BondShadingDesc.BlendEndClrs)
                        zScale = (bondInstances[1] - bondInstances[0]).Length();//(atomsPos[1] - atomsPos[0]).Length();//direction.Length();
                    else
                        zScale = midPos;
                    float xyScale = 0.05f; // thickness
                    Matrix scale = Matrix.Scaling(xyScale, xyScale, zScale);

                    // rotate & translate ends
                    if (tCylinderEndPoints1 != null)
                    {
                        Matrix endFinal = Matrix.Scaling(xyScale, xyScale, 1f) * rotation * translate;
                        Vector4[] tfEndTriangles = Vector3.Transform(tCylinderEndPoints1, endFinal);
                        // first end
                        for (int point = 0; point < tCylinderEndTris1.Length; point++)
                        {
                            int pointIdx = tCylinderEndTris1[point];
                            if (positionPos != -1)
                            {
                                data.Seek(pos + positionPos, SeekOrigin.Begin);
                                data.Write(tfEndTriangles[pointIdx].X);
                                data.Write(tfEndTriangles[pointIdx].Y);
                                data.Write(tfEndTriangles[pointIdx].Z);
                            }
                            if (normalPos != -1)
                            {
                                data.Seek(pos + normalPos, SeekOrigin.Begin);
                                data.Write(tCylinderEndNormals1[pointIdx].X);
                                data.Write(tCylinderEndNormals1[pointIdx].Y);
                                data.Write(tCylinderEndNormals1[pointIdx].Z);
                            }
                            if (diffusePos != -1)
                            {
                                data.Seek(pos + diffusePos, SeekOrigin.Begin);
                                data.Write(matA.BaseColor.ToArgb());
                            }
                            pos += geomStream.Stride;
                        }
                        // second end
                        endFinal = Matrix.Scaling(xyScale, xyScale, 1f) * rotation *
                                   Matrix.Translation(bondInstances[bInst + 1]);
                        tfEndTriangles = Vector3.Transform(tCylinderEndPoints2, endFinal);
                        // first end
                        for (int point = 0; point < tCylinderEndTris2.Length; point++)
                        {
                            int pointIdx = tCylinderEndTris2[point];
                            if (positionPos != -1)
                            {
                                data.Seek(pos + positionPos, SeekOrigin.Begin);
                                data.Write(tfEndTriangles[pointIdx].X);
                                data.Write(tfEndTriangles[pointIdx].Y);
                                data.Write(tfEndTriangles[pointIdx].Z);
                            }
                            if (normalPos != -1)
                            {
                                data.Seek(pos + normalPos, SeekOrigin.Begin);
                                data.Write(tCylinderEndNormals2[pointIdx].X);
                                data.Write(tCylinderEndNormals2[pointIdx].Y);
                                data.Write(tCylinderEndNormals2[pointIdx].Z);
                            }
                            if (diffusePos != -1)
                            {
                                data.Seek(pos + diffusePos, SeekOrigin.Begin);
                                data.Write(matB.BaseColor.ToArgb());
                            }
                            pos += geomStream.Stride;
                        }
                    }

                    Matrix final = scale * rotation * translate;

                    if (coDesc.BondShadingDesc.BlendEndClrs)
                    {
                        DrawSolidBondBlended(tCylinderPoints, tCylinderNormals, tCylinderTris,
                                             matA, matB, final, data, positionPos, normalPos,
                                             diffusePos, ref pos, geomStream.Stride, rotation);
                    }
                    else
                    {
                        float bLen2 = (bondInstances[bInst + 1] - (bondInstances[bInst] + (directionUV * midPos))).Length();

                        DrawSolidBondDistinct(tCylinderPoints, tCylinderNormals, tCylinderTris,
                                              matA, matB, final, data, xyScale, bLen2, rotation,
                                              bondInstances[bInst], directionUV, midPos, positionPos,
                                              normalPos, diffusePos, ref pos, geomStream.Stride);
                    }
                }
            }
        }