private void RemoveUnderPlane() { if (numPicks == 0) { voxelPlane = voxelizer.GetAllVoxelOnPlane(pickedVoxel[0], pickedVoxel[1], pickedVoxel[2], true); startPlane = voxelPlane; voxelizer.RemoveVoxelPlane(ref voxelPlane, pickedVoxel[0], pickedVoxel[1], pickedVoxel[2]); List <STLLoader.Vec3> localCorners = voxelizer.CalculateLocalCorners(); voxelizer.CalculateCenterOfMass(); Transform[] ts = gameObject.GetComponentsInChildren <Transform>(); for (int i = 1; i < ts.Length; ++i) { Destroy(ts[i].gameObject); } STLLoader.Quickhull quickhull = new STLLoader.Quickhull(); List <int> convexFaces = new List <int>(); quickhull.CalculateQuickhull(localCorners, ref convexFaces); convexHullOutline.Clear(); quickhull.CalculatePolygonEdges(ref convexHullOutline); voxelMesh = new STLLoader.Mesh[1]; voxelMesh[0] = voxelizer.GenerateMesh(0, resolution); float voxelSize = voxelizer.GetVoxelSize(); STLLoader.Vec3 offset = voxelizer.GetMinOffset(); convexHull.ConfigureConvexHull(ref localCorners, ref convexFaces, voxelSize, new Vector3(offset.x, offset.y, offset.z), ref convexHullOutline); CreateIndexedMesh(ref voxelMesh, (int)resolution); } }
public void PickVoxel() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); STLLoader.Vec3 res = voxelizer.PickVoxel(new STLLoader.Vec3(ray.origin.x, ray.origin.y, ray.origin.z), new STLLoader.Vec3(ray.direction.x, ray.direction.y, ray.direction.z)); if (res.x < 0) { return; } numPicks = (numPicks + 1) % 3; pickedVoxel[numPicks] = res + new STLLoader.Vec3(0.5f, 0.5f, 0.5f); SetPickedVoxel((res + new STLLoader.Vec3(0.5f, 0.5f, 0.5f))); if (numPicks == 0) { voxelPlane = voxelizer.GetAllVoxelOnPlane(pickedVoxel[0], pickedVoxel[1], pickedVoxel[2], false); for (int i = 0; i < voxelPlane.Count; ++i) { GameObject ins1 = Instantiate <GameObject>(testCube); STLLoader.Vec3 minOffset1 = voxelizer.GetMinOffset(); float sizeVoxel1 = voxelizer.GetSizeVoxel(); ins1.transform.position = new Vector3((voxelPlane[i].x + 0.5f) * sizeVoxel1 + minOffset1.x, (voxelPlane[i].y + 0.5f) * sizeVoxel1 + minOffset1.y, (voxelPlane[i].z + 0.5f) * sizeVoxel1 + minOffset1.z); ins1.transform.localScale = new Vector3(sizeVoxel1 + 0.2f * sizeVoxel1, sizeVoxel1 + 0.1f * sizeVoxel1, sizeVoxel1 + 0.1f * sizeVoxel1); ins1.transform.parent = transform; } } }
public void ShowNewPlane(Vector3 normal, Vector3 p1, Vector3 p2, Vector3 p3) { planeController.gameObject.SetActive(false); showPlane = false; choosePlane = false; if (voxelizer != null) { planeController.gameObject.SetActive(false); showPlane = false; float voxelScale = voxelizer.GetSizeVoxel(); STLLoader.Vec3 offset = voxelizer.GetMinOffset(); STLLoader.Vec3 newP1 = new STLLoader.Vec3(p1.x, p1.y, p1.z); STLLoader.Vec3 newP2 = new STLLoader.Vec3(p2.x, p2.y, p2.z); STLLoader.Vec3 newP3 = new STLLoader.Vec3(p3.x, p3.y, p3.z); newP1 = (newP1 - offset) / voxelScale; newP2 = (newP2 - offset) / voxelScale; newP3 = (newP3 - offset) / voxelScale; List <STLLoader.Vec3> voxelPlane = voxelizer.GetAllVoxelOnPlane(newP1, newP2, newP3, true); if (voxelPlane.Count != 0) { Transform[] ts = gameObject.GetComponentsInChildren <Transform>(); for (int i = 1; i < ts.Length; ++i) { Destroy(ts[i].gameObject); } voxelizer.GenerateMeshPlane(ref voxelPlane, new STLLoader.Vec3(normal.x, normal.y, normal.z), newP1, false); STLLoader.Mesh[] mesh; if (layersSet) { mesh = voxelizer.GenerateMeshLayerWiseVisible(0, (int)resolution); CreateIndexedMesh(ref mesh, 0); MeshPrefab[] prefab = gameObject.GetComponentsInChildren <MeshPrefab>(); int layer; for (int i = 0; i < prefab.Length; ++i) { layer = prefab[i].layer; if (layer < resolution) { prefab[i].renderer.material = materials[layer % periode]; } } } else { mesh = new STLLoader.Mesh[1]; mesh[0] = voxelizer.GenerateMeshVisible(); CreateIndexedMesh(ref mesh, (int)resolution); } voxelizer.GenerateMeshPlane(ref voxelPlane, new STLLoader.Vec3(normal.x, normal.y, normal.z), newP1, true); } } }
public void VoxelizeMesh() { if (mesh[0] == null) { return; } if (!objectHasChanged) { return; } Transform[] ts = gameObject.GetComponentsInChildren <Transform>(); for (int i = 1; i < ts.Length; ++i) { Destroy(ts[i].gameObject); } STLLoader.Vec3[] direction = new STLLoader.Vec3[3]; direction[0] = new STLLoader.Vec3(1, 0, 0); direction[1] = new STLLoader.Vec3(0, 1, 0); direction[2] = new STLLoader.Vec3(0, 0, 1); voxelizer = new STLLoader.Voxelizer(xResolution, yResolution, zResolution); voxelizer.MultiyDirectionsVoxelize(mesh[0], direction); List <STLLoader.Vec3> localCorners = voxelizer.CalculateLocalCorners(); STLLoader.Quickhull quickhull = new STLLoader.Quickhull(); List <int> convexFaces = new List <int>(); quickhull.CalculateQuickhull(localCorners, ref convexFaces); convexHullOutline.Clear(); quickhull.CalculatePolygonEdges(ref convexHullOutline); STLLoader.Vec3 centerOfMass = voxelizer.GetCenterOfMass(); //voxelizer.SafeLayer(fileName, 0); voxelMesh = new STLLoader.Mesh[1]; voxelMesh[0] = voxelizer.GenerateMesh(0, resolution); float voxelSize = voxelizer.GetVoxelSize(); STLLoader.Vec3 offset = voxelizer.GetMinOffset(); convexHull.ConfigureConvexHull(ref localCorners, ref convexFaces, voxelSize, new Vector3(offset.x, offset.y, offset.z), ref convexHullOutline); CreateIndexedMesh(ref voxelMesh, (int)resolution); transform.localScale = new Vector3(voxelSize, voxelSize, voxelSize); transform.position = new Vector3(offset.x, offset.y, offset.z); objectHasChanged = false; voxelMeshHasChanged = false; }
public void ChoosePlane() { if (showPlane == false && !choosePlane) { planeController.gameObject.SetActive(true); showPlane = true; choosePlane = true; STLLoader.Vec3 offset = voxelizer.GetCenterOfMass() * voxelizer.GetSizeVoxel() + voxelizer.GetMinOffset(); float voxelScale = voxelizer.GetSizeVoxel() * 2f * resolution; planeController.transform.position = new Vector3(offset.x, offset.y, offset.z); planeController.transform.localScale = new Vector3(voxelScale, voxelScale / 2f / (int)resolution, voxelScale); } else { planeController.gameObject.SetActive(false); showPlane = false; choosePlane = false; } }
public void SetPickedVoxel(STLLoader.Vec3 point) { float scale = voxelizer.GetSizeVoxel(); STLLoader.Vec3 offset = voxelizer.GetMinOffset(); float distance = 3f / 4f; STLLoader.Vec3 voxel; STLLoader.Vec3 tmpVec; Transform[] ts = gameObject.GetComponentsInChildren <Transform>(); for (int i = 0; i < indexedVoxelMesh[resolution].Count; ++i) { for (int j = 0; j < indexedVoxelMesh[resolution][i].indices.Count; j += 3) { voxel = indexedVoxelMesh[resolution][i].vertices[indexedVoxelMesh[resolution][i].indices[j]]; tmpVec = voxel - point; if (tmpVec.x * tmpVec.x + tmpVec.y * tmpVec.y + tmpVec.z * tmpVec.z > distance) { continue; } voxel = indexedVoxelMesh[resolution][i].vertices[indexedVoxelMesh[resolution][i].indices[j + 1]]; tmpVec = voxel - point; if (tmpVec.x * tmpVec.x + tmpVec.y * tmpVec.y + tmpVec.z * tmpVec.z > distance) { continue; } voxel = indexedVoxelMesh[resolution][i].vertices[indexedVoxelMesh[resolution][i].indices[j + 2]]; tmpVec = voxel - point; if (tmpVec.x * tmpVec.x + tmpVec.y * tmpVec.y + tmpVec.z * tmpVec.z > distance) { continue; } (ts[i + 1].GetComponent <MeshPrefab>()).SetPickedVoxel(pickedMaterial, j, 1); } } }
void Update() { if (!showPlane) { changeUpLayer = 0; changeDownLayer = 0; if (Input.GetKeyDown("w")) { changeUpLayer = maxLayer <= resolution ? ++changeUpLayer : changeUpLayer; voxelMeshHasChanged = true; } if (Input.GetKeyDown("escape")) { Application.Quit(); } if (Input.GetKeyDown("e")) { changeDownLayer = minLayer < maxLayer ? ++changeDownLayer : changeDownLayer; voxelMeshHasChanged = true; } if (Input.GetKeyDown("s")) { changeUpLayer = maxLayer > minLayer ? --changeUpLayer : changeUpLayer; voxelMeshHasChanged = true; } if (Input.GetKeyDown("d")) { changeDownLayer = minLayer > 0 ? --changeDownLayer : changeDownLayer; voxelMeshHasChanged = true; } if (voxelMeshHasChanged) { RecreateMesh(); voxelMeshHasChanged = false; } if (Input.GetKeyDown(KeyCode.LeftControl)) { chooseConvexHullObject = true; convexHull.gameObject.SetActive(true); convexHullEdges.isActive = true; } if (Input.GetKeyUp(KeyCode.LeftControl)) { chooseConvexHullObject = false; convexHull.gameObject.SetActive(false); convexHullEdges.isActive = false; } if (Input.GetMouseButtonDown(0)) { if (chooseConvexHullObject) { Vector3 p1 = new Vector3(); Vector3 p2 = new Vector3(); Vector3 p3 = new Vector3(); if (convexHull.FindFaceOnConvexHull(ref p1, ref p2, ref p3)) { float scale = voxelizer.GetSizeVoxel(); STLLoader.Vec3 offset = voxelizer.GetMinOffset(); STLLoader.Vec3 voxelP1 = new STLLoader.Vec3(p1.x, p1.y, p1.z); STLLoader.Vec3 voxelP2 = new STLLoader.Vec3(p2.x, p2.y, p2.z); STLLoader.Vec3 voxelP3 = new STLLoader.Vec3(p3.x, p3.y, p3.z); List <STLLoader.Vec3> voxelPlane = voxelizer.GetAllVoxelOnPlane(voxelP1, voxelP2, voxelP3, false); for (int i = 0; i < voxelPlane.Count; ++i) { GameObject ins1 = Instantiate <GameObject>(testCube); STLLoader.Vec3 minOffset1 = voxelizer.GetMinOffset(); float sizeVoxel1 = voxelizer.GetSizeVoxel(); ins1.transform.position = new Vector3((voxelPlane[i].x + 0.5f) * sizeVoxel1 + minOffset1.x, (voxelPlane[i].y + 0.5f) * sizeVoxel1 + minOffset1.y, (voxelPlane[i].z + 0.5f) * sizeVoxel1 + minOffset1.z); ins1.transform.localScale = new Vector3(sizeVoxel1 + 0.2f * sizeVoxel1, sizeVoxel1 + 0.1f * sizeVoxel1, sizeVoxel1 + 0.1f * sizeVoxel1); ins1.transform.parent = transform; } startPlane = voxelPlane; } } else if (Input.GetKey(KeyCode.LeftAlt)) { PickVoxel(); } } if (Input.GetKey(KeyCode.LeftAlt) && Input.GetMouseButtonDown(1)) { RemoveUnderPlane(); } } }
private bool FindHorizonParallel(ref List <int> foundFaces, ref List <int> horizonEdges, int currentFace, int currentHalfEdge, Vec3 normal) { Face current = faces[currentFace]; int halfEdge = current.halfEdge; Vec3 normalOnFace = current.normal; if (normalOnFace.dot(normal) >= 1f - epsilon2) { foundFaces.Add(currentFace); for (int i = 1; i <= 3; ++i) { currentFace = edges[edges[currentHalfEdge].opposite].face; if (!foundFaces.Contains(currentFace)) { if (!FindHorizonParallel(ref foundFaces, ref horizonEdges, currentFace, edges[currentHalfEdge].opposite, normalOnFace)) { horizonEdges.Add(currentHalfEdge); } } currentHalfEdge = halfEdge + ((currentHalfEdge + 1) % 3); } return(true); } return(false); }
private bool FindHorizon(ref List <int> foundFaces, ref List <int> horizonEdges, int currentFace, int currentHalfEdge, ref Vec3 vertex) { Face current = faces[currentFace]; int halfEdge = current.halfEdge; Vec3 vertexOnFace = points[edges[halfEdge].vertex]; if (current.normal.dot(vertex - vertexOnFace) >= 0 - epsilon) { foundFaces.Add(currentFace); for (int i = 1; i <= 3; ++i) { currentFace = edges[edges[currentHalfEdge].opposite].face; if (!foundFaces.Contains(currentFace)) { if (!FindHorizon(ref foundFaces, ref horizonEdges, currentFace, edges[currentHalfEdge].opposite, ref vertex)) { horizonEdges.Add(currentHalfEdge); } } currentHalfEdge = halfEdge + ((currentHalfEdge + 1) % 3); } return(true); } return(false); }
private void CreateStart() { float lowestX = points[0].x, highestX = points[0].x; float lowestY = points[0].y, highestY = points[0].y; float lowestZ = points[0].z, highestZ = points[0].z; int[] lowest = new int[3]; int[] highest = new int[3]; int listSize = points.Count; Vec3 point; for (int i = 0; i < listSize; ++i) { point = points[i]; if (point.x < lowestX) { lowestX = point.x; lowest[0] = i; } if (point.x > highestX) { highestX = point.x; highest[0] = i; } if (point.y < lowestY) { lowestY = point.y; lowest[1] = i; } if (point.y > highestY) { highestY = point.y; highest[1] = i; } if (point.z < lowestZ) { lowestZ = point.z; lowest[2] = i; } if (point.z > highestZ) { highestZ = point.z; highest[2] = i; } } int greatestDistanceUp = lowest[0]; int greatestDistanceDown = highest[0]; Vec3 distanceVec = points[greatestDistanceDown] - points[greatestDistanceUp]; float maxDistance = distanceVec.dot(distanceVec); float tmpDistance = 0; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { distanceVec = points[lowest[i]] - points[highest[j]]; tmpDistance = distanceVec.dot(distanceVec); if (tmpDistance > maxDistance) { greatestDistanceUp = lowest[i]; greatestDistanceDown = highest[j]; maxDistance = tmpDistance; } } } distanceVec = points[greatestDistanceDown] - points[greatestDistanceUp]; int distanceIdx = 0; Vec3 tmpVec; float newMaxDistance = 0; for (int i = 0; i < 3; ++i) { tmpVec = distanceVec.Cross(points[greatestDistanceUp] - points[lowest[i]]); tmpDistance = (tmpVec).dot(tmpVec) / maxDistance; if (tmpDistance > newMaxDistance) { distanceIdx = lowest[i]; newMaxDistance = tmpDistance; } } for (int i = 0; i < 3; ++i) { tmpVec = distanceVec.Cross(points[greatestDistanceUp] - points[highest[i]]); tmpDistance = (tmpVec).dot(tmpVec) / maxDistance; if (tmpDistance > newMaxDistance) { distanceIdx = highest[i]; newMaxDistance = tmpDistance; } } Vec3 normal = (distanceVec.Cross(points[greatestDistanceDown] - points[distanceIdx])); normal.Normalize(); newMaxDistance = 0; int distanceIdx2 = 0; for (int i = 0; i < 3; ++i) { tmpDistance = Math.Abs(normal.dot(points[distanceIdx] - points[lowest[i]])); if (tmpDistance > newMaxDistance) { distanceIdx2 = lowest[i]; newMaxDistance = tmpDistance; } } for (int i = 0; i < 3; ++i) { tmpDistance = Math.Abs(normal.dot(points[distanceIdx] - points[highest[i]])); if (tmpDistance > newMaxDistance) { distanceIdx2 = highest[i]; newMaxDistance = tmpDistance; } } if (normal.dot(points[distanceIdx2] - points[distanceIdx]) > 0) { //Face 0 HalfEdge newHalfEdge = new HalfEdge(); newHalfEdge.vertex = greatestDistanceUp; newHalfEdge.face = 0; newHalfEdge.opposite = 3; edges.Add(newHalfEdge); newHalfEdge.vertex = distanceIdx; newHalfEdge.face = 0; newHalfEdge.opposite = 6; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceDown; newHalfEdge.face = 0; newHalfEdge.opposite = 9; edges.Add(newHalfEdge); //Face 1 newHalfEdge.vertex = greatestDistanceDown; newHalfEdge.face = 1; newHalfEdge.opposite = 0; edges.Add(newHalfEdge); newHalfEdge.vertex = distanceIdx2; newHalfEdge.face = 1; newHalfEdge.opposite = 11; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceUp; newHalfEdge.face = 1; newHalfEdge.opposite = 7; edges.Add(newHalfEdge); //Face2 newHalfEdge.vertex = greatestDistanceUp; newHalfEdge.face = 2; newHalfEdge.opposite = 1; edges.Add(newHalfEdge); newHalfEdge.vertex = distanceIdx2; newHalfEdge.face = 2; newHalfEdge.opposite = 5; edges.Add(newHalfEdge); newHalfEdge.vertex = distanceIdx; newHalfEdge.face = 2; newHalfEdge.opposite = 10; edges.Add(newHalfEdge); //Face3 newHalfEdge.vertex = distanceIdx; newHalfEdge.face = 3; newHalfEdge.opposite = 2; edges.Add(newHalfEdge); newHalfEdge.vertex = distanceIdx2; newHalfEdge.face = 3; newHalfEdge.opposite = 8; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceDown; newHalfEdge.face = 3; newHalfEdge.opposite = 4; edges.Add(newHalfEdge); } else { //Face 0 HalfEdge newHalfEdge = new HalfEdge(); newHalfEdge.vertex = distanceIdx; newHalfEdge.face = 0; newHalfEdge.opposite = 11; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceUp; newHalfEdge.face = 0; newHalfEdge.opposite = 8; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceDown; newHalfEdge.face = 0; newHalfEdge.opposite = 5; edges.Add(newHalfEdge); //Face 1 newHalfEdge.vertex = distanceIdx2; newHalfEdge.face = 1; newHalfEdge.opposite = 7; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceDown; newHalfEdge.face = 1; newHalfEdge.opposite = 9; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceUp; newHalfEdge.face = 1; newHalfEdge.opposite = 2; edges.Add(newHalfEdge); //Face2 newHalfEdge.vertex = distanceIdx2; newHalfEdge.face = 2; newHalfEdge.opposite = 10; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceUp; newHalfEdge.face = 2; newHalfEdge.opposite = 3; edges.Add(newHalfEdge); newHalfEdge.vertex = distanceIdx; newHalfEdge.face = 2; newHalfEdge.opposite = 1; edges.Add(newHalfEdge); //Face3 newHalfEdge.vertex = distanceIdx2; newHalfEdge.face = 3; newHalfEdge.opposite = 4; edges.Add(newHalfEdge); newHalfEdge.vertex = distanceIdx; newHalfEdge.face = 3; newHalfEdge.opposite = 6; edges.Add(newHalfEdge); newHalfEdge.vertex = greatestDistanceDown; newHalfEdge.face = 3; newHalfEdge.opposite = 0; edges.Add(newHalfEdge); } Face newFace = new Face(); for (int i = 0; i < 4; ++i) { newFace.halfEdge = i * 3; newFace.normal = ((points[edges[i * 3 + 2].vertex] - points[edges[i * 3].vertex]).Cross(points[edges[i * 3 + 1].vertex] - points[edges[i * 3].vertex])); newFace.normal.Normalize(); newFace.pointList = -1; faces.Add(newFace); } }