Пример #1
0
    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);
        }
    }
Пример #2
0
    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;
            }
        }
    }
Пример #3
0
    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);
            }
        }
    }
Пример #4
0
    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;
    }
Пример #5
0
 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;
     }
 }
Пример #6
0
    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);
            }
        }
    }
Пример #7
0
    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();
            }
        }
    }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
            }
        }