void MakeGrid() { var bounds = _voids .GetComponentsInChildren <MeshCollider>() .Select(c => c.bounds) .ToArray(); var voxelSize = float.Parse(_voxelSize); _grid = Grid3d.MakeGridWithBounds(bounds, voxelSize); // shortest path to test if connectivity is working var faces = _grid.GetFaces().Where(f => f.IsActive).ToList(); var graphEdges = faces.Select(f => new TaggedEdge <Voxel, Face>(f.Voxels[0], f.Voxels[1], f)); var graph = graphEdges.ToUndirectedGraph <Voxel, TaggedEdge <Voxel, Face> >(); var start = _grid.GetVoxels().ElementAt(2); var end = _grid.GetVoxels().ElementAt(250); var shortest = graph.ShortestPathsDijkstra(_ => 1, start); shortest(end, out var path); var current = start; _flowPath = new List <Voxel>(); _flowPath.Add(current); foreach (var face in path) { current = face.GetOtherVertex(current); _flowPath.Add(current); } }
IEnumerator GrowGrid() { int count = 100000; int lastFitness = 0; while (count-- > 0) { var skinVoxels = _grid.GetVoxels().Where(v => v.IsSkin).ToList(); if (skinVoxels.Count == 0) { break; } var index = Random.Range(0, skinVoxels.Count); var candidate = skinVoxels[index]; candidate.IsActive = false; int componentCount = _grid.GetConnectedComponents(); if (componentCount != 1) { Debug.Log("Tried to remove a voxel that disconnected the structure."); candidate.IsActive = true; yield return(null); } int fitness = 0; foreach (var voxel in _grid.GetVoxels()) { if (!voxel.IsActive) { continue; } int neighbourCount = voxel.GetFaceNeighbours().Count(n => n.IsActive); if (neighbourCount == 2) { fitness += 1; } } if (fitness < lastFitness) { Debug.Log("Fitness decreased."); candidate.IsActive = true; continue; } lastFitness = fitness; UpdateCenters(); yield return(new WaitForSeconds(0.001f)); } }
void UpdateActiveVoxels() { _centers.Clear(); foreach (var voxel in _grid.GetVoxels()) { if (voxel.IsActive) { _centers.Add(voxel.Center); } } }
void Analysis() { // analysis model var model = new Model(); var corners = _grid.GetCorners() .Where(c => c.GetConnectedVoxels().Any(v => v.IsActive)) .Select(c => new FeaCorner(c)) .ToList(); var nodes = corners.Select(c => c.Node).ToArray(); var elements = _grid.GetVoxels() .Where(b => b.IsActive) .SelectMany(v => MakeTetrahedra(v)) .ToArray(); model.Nodes.Add(nodes); model.Elements.Add(elements); model.Solve(); // analysis results foreach (var corner in corners) { var d = corner.Node .GetNodalDisplacement(LoadCase.DefaultLoadCase) .Displacements; corner.Displacement = new Vector3((float)d.X, (float)d.Z, (float)d.Y); var length = corner.Displacement.magnitude; foreach (var voxel in corner.GetConnectedVoxels()) { voxel.Value += length; } } var activeVoxels = _grid.GetVoxels().Where(v => v.IsActive); foreach (var voxel in activeVoxels) { voxel.Value /= voxel.GetCorners().Count(); } var min = activeVoxels.Min(v => v.Value); var max = activeVoxels.Max(v => v.Value); foreach (var voxel in activeVoxels) { voxel.Value = Mathf.InverseLerp(min, max, voxel.Value); } }
void MakeGrid() { var colliders = _voids .GetComponentsInChildren <MeshCollider>() .ToArray(); var voxelSize = float.Parse(_voxelSize); _grid = Grid3d.MakeGridWithVoids(colliders, voxelSize, true); var faces = _grid.GetFaces().Where(f => f.IsActive); var graphEdges = faces.Select(f => new TaggedEdge <Voxel, Face>(f.Voxels[0], f.Voxels[1], f)); var graph = graphEdges.ToAdjacencyGraph <Voxel, TaggedEdge <Voxel, Face> >(); var voxels = _grid.GetVoxels().Where(v => v.IsActive); var start = voxels.First(); var end = voxels.ElementAt(100); var flow = graph.MaximumFlowEdmondsKarp(_ => 1, start, end, out var predecessors, (s, e) => new TaggedEdge <Voxel, Face>(s, e, null)); var current = end; _flowPath = new List <Voxel>(); _flowPath.Add(current); while (predecessors(current, out var next)) { current = next.GetOtherVertex(current); _flowPath.Add(current); } print(flow); }
void MakeGrid() { // create grid with voids var colliders = _voids .GetComponentsInChildren <MeshCollider>() .ToArray(); _grid = new Grid3d(colliders, voxelSize); //sorting the Voxel var faces = _grid.GetFaces().Where(f => f.IsActive); var graphFaces = faces.Select(e => new TaggedEdge <Voxel, Face>(e.Voxels[0], e.Voxels[1], e)); var graphVoxel = graphFaces.ToUndirectedGraph <Voxel, TaggedEdge <Voxel, Face> >(); var startVoxel = _grid.GetVoxels().Where(v => Vector3.Distance(v.Center, Vector3.zero) < 1.5f).First(); var shortestGrow = QuickGraph.Algorithms.AlgorithmExtensions.ShortestPathsDijkstra(graphVoxel, e => 1.0, startVoxel); linkFaces = faces.ToList(); //foreach (var botomFaces in _grid.GetFaces().Where(f => f.Index.y == 0 && f.Direction == Axis.Y)) linkFaces.Add(botomFaces); foreach (var voxel in _grid.GetVoxels().Where(v => v.IsActive)) { IEnumerable <TaggedEdge <Voxel, Face> > path; if (shortestGrow(voxel, out path)) { voxel.Order = path.Count() + UnityEngine.Random.value * 0.9f; } activeVoxels.Add(voxel); voxel.IsActive = false; } activeVoxels = activeVoxels.OrderBy(v => v.Order).ToList(); for (int i = 0; i < _grid.GetFaces().Max(f => f.Index.z) / 2; i++) { startFaces.Add(_grid.GetFaces().Where(f => f.Index.y == 0 && f.Index.x == 0 && f.Index.z == i * 2 && f.Direction == Axis.Y).First()); startFaces.Add(_grid.GetFaces().Where(f => f.Index.y == 0 && f.Index.x == 15 && f.Index.z == i * 2 && f.Direction == Axis.Y).First()); } foreach (var sf in startFaces) { var stack = Instantiate(stackPrefab, sf.Center, Quaternion.identity); _stackList.Add(stack); } }
void Update() { if (_grid == null) { return; } foreach (var voxel in _grid.GetVoxels()) { Drawing.DrawCube(voxel.Center, _grid.VoxelSize, voxel.Tile); } }
void Start() { var bounds = new Bounds(new Vector3(0, 5, 0), new Vector3(15, 9, 9)); _grid = new Grid3d(bounds, 0.8f); foreach (var voxel in _grid.GetVoxels()) { voxel.IsActive = true; } StartCoroutine(GrowGrid()); }
void Update() { if (_grid == null) { return; } foreach (var voxel in _grid.GetVoxels().Where(v => v.IsActive)) { Drawing.DrawCube(voxel.Center, _grid.VoxelSize * 0.9f, 0.8f); } foreach (var voxel in _flowPath) { Drawing.DrawCube(voxel.Center, _grid.VoxelSize, 0); } }