public Form1() { InitializeComponent(); GenericVolumeScene volumeScene = new GenericVolumeScene(new IVolume[] { //new BoxVolume(new Vector3(), 50, 50, 50) //new BoxVolume(new Vector3(70, 0 , 0), 30, 30, 30) //new Metaball(new Vector3(0, 0, 0), 15f), //new Metaball(new Vector3(110, 0, 0), 10f), //new Metaball(new Vector3(75, 75, 0), 8f) }); //pictureBox1.Image = IsosurfaceGenerator2D.GenerateBitmapSurface(pictureBox1.Width, pictureBox1.Height, 1.0f, 1.0f, volumeScene); PresentParameters pParams = new PresentParameters(); //pParams.EnableAutoDepthStencil = true; pParams.Windowed = true; pParams.SwapEffect = SwapEffect.Discard; device = new Device(0, DeviceType.Hardware, this.pictureBox1, CreateFlags.SoftwareVertexProcessing /*.HardwareVertexProcessing*/, pParams); device.RenderState.Lighting = false; //Vector3[] points = IsosurfaceGenerator3D.GenerateSimplePointField(volumeScene, new Vector3(), 400, 20); Vector3[] points; int[] triangles; Color[] colors; IsosurfaceGenerator3D.GenerateSimpleMesh(volumeScene, new Vector3(), 400, 30, false, out triangles, out points, out colors); vBuffer = new VertexBuffer(typeof(CustomVertex.PositionOnly), triangles.Length, device, Usage.None, CustomVertex.PositionOnly.Format, Pool.Managed); CustomVertex.PositionOnly[] vertices = (CustomVertex.PositionOnly[])vBuffer.Lock(0, LockFlags.None); for (int vIdx = 0; vIdx < triangles.Length; vIdx++) { vertices[vIdx].Position = points[triangles[vIdx]]; } vBuffer.Unlock(); numPoints = triangles.Length; numTris = numPoints / 3; }
public Form1() { InitializeComponent(); GenericVolumeScene volumeScene = new GenericVolumeScene(new IVolume[] { //new BoxVolume(new Vector3(), 50, 50, 50) //new BoxVolume(new Vector3(70, 0 , 0), 30, 30, 30) //new Metaball(new Vector3(0, 0, 0), 15f), //new Metaball(new Vector3(110, 0, 0), 10f), //new Metaball(new Vector3(75, 75, 0), 8f) }); //pictureBox1.Image = IsosurfaceGenerator2D.GenerateBitmapSurface(pictureBox1.Width, pictureBox1.Height, 1.0f, 1.0f, volumeScene); PresentParameters pParams = new PresentParameters(); //pParams.EnableAutoDepthStencil = true; pParams.Windowed = true; pParams.SwapEffect = SwapEffect.Discard; device = new Device(0, DeviceType.Hardware, this.pictureBox1, CreateFlags.SoftwareVertexProcessing/*.HardwareVertexProcessing*/, pParams); device.RenderState.Lighting = false; //Vector3[] points = IsosurfaceGenerator3D.GenerateSimplePointField(volumeScene, new Vector3(), 400, 20); Vector3[] points; int[] triangles; Color[] colors; IsosurfaceGenerator3D.GenerateSimpleMesh(volumeScene, new Vector3(), 400, 30, false, out triangles, out points, out colors); vBuffer = new VertexBuffer(typeof(CustomVertex.PositionOnly), triangles.Length, device, Usage.None, CustomVertex.PositionOnly.Format, Pool.Managed); CustomVertex.PositionOnly[] vertices = (CustomVertex.PositionOnly[])vBuffer.Lock(0, LockFlags.None); for (int vIdx = 0; vIdx < triangles.Length; vIdx++) { vertices[vIdx].Position = points[triangles[vIdx]]; } vBuffer.Unlock(); numPoints = triangles.Length; numTris = numPoints / 3; }
public override void CreateGeometryForObjects(Device device, ICollection<IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") positionPos = geomStream.FieldPositions[gf]; else if (fields[i].Usage == "NORMAL") normalPos = geomStream.FieldPositions[gf]; else if (fields[i].Usage == "DIFFUSE") diffusePos = geomStream.FieldPositions[gf]; break; } } } // actually create the metaball triangles or points IVolume[] volumes = new IVolume[objs.Count]; int sIdx = 0; AtomShadingDesc aShading = coDesc.AtomShadingDesc; IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; foreach (IAtom atom in objs) { IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) material = matTemp.BySymbol; else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) material = lookup.GetBySeries(pe.ChemicalSerie); } volumes[sIdx++] = new Metaball(new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d), 0.17f, material.BaseColor); } // process volume into triangles GenericVolumeScene scene = new GenericVolumeScene(volumes); int[] triangles = null; Vector3[] vertices; Color[] colours; Vector3[] normals = null; if (!pointsOnly) { IsosurfaceGenerator3D.GenerateSimpleMesh(scene, new Vector3(), scene.EstimateVolumeMaxSize(), 40, false, out triangles, out vertices, out colours); MeshOptimzer.GenerateTriPointNormals(triangles, vertices, out normals); } else IsosurfaceGenerator3D.GenerateSimplePointOutline(scene, new Vector3(), scene.EstimateVolumeMaxSize(), 40, out vertices, out colours); // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * vertices.Length, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = vertices.Length; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; if (pointsOnly) { buffer.iBuffers[0].NumPrimitives = vertices.Length; buffer.iBuffers[0].PrimType = PrimitiveType.PointList; buffer.Light = false; } else { buffer.iBuffers[0].NumPrimitives = triangles.Length / 3; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; buffer.iBuffers[0].Buffer = new IndexBuffer(typeof(int), triangles.Length, device, Usage.WriteOnly, Pool.Managed); } // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields int clr = Color.FromArgb(255, 255, 255).ToArgb(); long pos = 0; for (int i = 0; i < vertices.Length; i++) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(vertices[i].X); data.Write(vertices[i].Y); data.Write(vertices[i].Z); } if (normalPos != -1 && !pointsOnly) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(normals[i].X); data.Write(normals[i].Y); data.Write(normals[i].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(colours[i].ToArgb()); } //verts[i].Color = colours[i].ToArgb(); pos += geomStream.Stride; } buffer.vBuffers[0].Buffer.Unlock(); if (!pointsOnly) buffer.iBuffers[0].Buffer.SetData(triangles, 0, LockFlags.None); // dispose of temp data }
public static void GenerateSimplePointOutline(GenericVolumeScene scene, Vector3 origin, float sceneCubeVolSize, int numCubes, out Vector3[] vertices, out Color[] colours) { // list all cubes / points in volume space PointBind[] points = new PointBind[numCubes * numCubes * numCubes]; float spacing = sceneCubeVolSize / (float)numCubes; // scan for points float startX = origin.X - (sceneCubeVolSize / 2f); float startY = origin.Y - (sceneCubeVolSize / 2f); float startZ = origin.Z - (sceneCubeVolSize / 2f); float x, y, z = startZ; int index = 0; for (int zPointIdx = 0; zPointIdx < numCubes; zPointIdx++) { x = startX; for (int xPointIdx = 0; xPointIdx < numCubes; xPointIdx++) { y = startY; for (int yPointIdx = 0; yPointIdx < numCubes; yPointIdx++) { Vector3 point = new Vector3(x, y, z); float potential = scene.GetPotentialAtPoint(point); //if (potential > 0.1f) points[index] = new PointBind(point, potential); y += spacing; index++; } x += spacing; } z += spacing; } // map cubes index = 0; List<Cube> cubes = new List<Cube>(); Vector3[] cPoints = new Vector3[8]; float[] cPotentials = new float[8]; int[] indices = new int[8]; int layerSz = numCubes * numCubes; for (int zPointIdx = 0; zPointIdx < numCubes - 1; zPointIdx++) { for (int xPointIdx = 0; xPointIdx < numCubes - 1; xPointIdx++) { for (int yPointIdx = 0; yPointIdx < numCubes - 1; yPointIdx++) { // create cube indices[0] = index; indices[1] = index + 1; indices[2] = index + numCubes + 1; indices[3] = index + numCubes; indices[4] = index + layerSz; indices[5] = index + layerSz + 1; indices[6] = index + layerSz + 1 + numCubes; indices[7] = index + layerSz + numCubes; int numPoints = 0; int numVPoints = 0; for (int i = 0; i < 8; i++) { PointBind value = points[indices[i]]; //if (points.TryGetValue(indices[i], out value)) //{ cPoints[i] = value.Position; cPotentials[i] = value.Potential; numPoints++; if (value.Potential >= 0.1f) numVPoints++; //} //else //{ // cPotentials[i] = float.NaN; //} } if (numPoints > 0 && numVPoints > 0) { cubes.Add(new Cube(cPoints, cPotentials, zPointIdx, xPointIdx, yPointIdx)); cPotentials = new float[8]; cPoints = new Vector3[8]; // TODO: Switch to indices // calc normals/directions they can move for each point in cube // based on side-plane matching/analysis } index++; } index++; // push on to next line } index += numCubes; } Cube[] cubeArray = cubes.ToArray(); // modify cubes for adaptive points //if (adaptive) // ApplyAdaptiveProcess(scene, cubeArray, 1, sceneCubeVolSize); // transform into triangles MarchingCubes.PointsCubes(cubeArray, 0.1f, (sceneCubeVolSize / (float)numCubes) / 2f, out vertices); // colourize all vertices colours = new Color[vertices.Length]; for (int vert = 0; vert < vertices.Length; vert++) { colours[vert] = scene.ColourizePoint(vertices[vert]); } }
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 }