Beispiel #1
0
        public void InstantiateLatches(Manifold manifold, FaceHandleController handleController)
        {
            var neighbourFaces = manifold.GetAdjacentFaceIdsAndEdgeCenters(handleController.AssociatedFaceID);
            var edgeCenters    = neighbourFaces.edgeCenter;

            for (int j = 0; j < neighbourFaces.edgeId.Length; j++)
            {
                var adjacentFace = neighbourFaces.faceId[j];

                int uniqueHalfedgeId = Mathf.Max(manifold.GetOppHalfEdge(neighbourFaces.edgeId[j]), neighbourFaces.edgeId[j]);

                EdgeHandleController existingEdgeHandle = null;
                var latchExists = _edgeHandles.TryGetValue(uniqueHalfedgeId, out existingEdgeHandle);

                if (latchExists)
                {
                    handleController.AttachLatch(existingEdgeHandle);
                }
                else
                {
                    var newLatch = Instantiate(LatchPrefab, transform, false);
                    //newLatch.transform.localScale = Vector3.Scale(transform.lossyScale, newLatch.transform.localScale);
                    newLatch.transform.SetParent(transform);

                    var edgeCenter = edgeCenters[j];

                    var edgeHandleController = newLatch.GetComponent <EdgeHandleController>();

                    var adjacentFaceNormal = manifold.GetFaceNormal(adjacentFace);
                    var normal             = manifold.GetFaceNormal(handleController.AssociatedFaceID);

                    edgeHandleController.UpdatePositionAndRotation(edgeCenter, neighbourFaces.edgeNormals[j],
                                                                   adjacentFaceNormal + normal);

                    edgeHandleController.FirstFace  = handleController.AssociatedFaceID;
                    edgeHandleController.SecondFace = adjacentFace;
                    // always use max halfedge id - to uniquely identify halfedge
                    edgeHandleController.AssociatedEdgeID = uniqueHalfedgeId;

                    KeyValuePair <int, int> pairToRemove = new KeyValuePair <int, int>();
                    foreach (var pair in _closedEdgeBackup)
                    {
                        if (edgeHandleController.IsAdjacent(pair.Key, pair.Value))
                        {
                            pairToRemove = pair;
                            edgeHandleController.Locked = true;
                            break;
                        }
                    }

                    _closedEdgeBackup.Remove(pairToRemove);

                    handleController.AttachLatch(edgeHandleController);
                    _edgeHandles.Add(edgeHandleController.AssociatedEdgeID, edgeHandleController);
                }
            }
        }
Beispiel #2
0
    public bool ValidateFaceLoop(int halfedgeId1, int halfedgeId2)
    {
        Manifold manifold = _extrudableMesh._manifold;

        //if (manifold.GetIncidentFace(halfedgeId1) == manifold.GetIncidentFace(halfedgeId2))
        //{
        //    return false;
        //}

        if (!manifold.IsHalfedgeInUse(halfedgeId1) || !manifold.IsHalfedgeInUse(halfedgeId2))
        {
            return(false);
        }

        int f = manifold.GetIncidentFace(halfedgeId1);
        int h = halfedgeId1;

        while (true)
        {
            int h2 = manifold.GetNextHalfEdge(h);
            h2 = manifold.GetNextHalfEdge(h2);
            int h3 = manifold.GetOppHalfEdge(h2);


            if (h2 == halfedgeId2 || h3 == halfedgeId2)
            {
                return(true);
            }

            else if (manifold.GetIncidentFace(h3) == f)
            {
                return(false);
            }
            h = h3;
        }
    }
Beispiel #3
0
        public void DestroyInvalidObjects()
        {
            Manifold manifold  = Extrudable._manifold;
            var      toDeleteV = new List <int>(_vertexHandles.Keys).FindAll(key => !manifold.IsVertexInUse(key));

            foreach (var v in toDeleteV)
            {
                var obj = _vertexHandles[v];
                _vertexHandles.Remove(v);
                Destroy(obj.gameObject);
            }
            var toDeleteF = new List <int>(_faceHandles.Keys).FindAll(key => !manifold.IsFaceInUse(key));

            foreach (var f in toDeleteF)
            {
                var obj = _faceHandles[f];
                _faceHandles.Remove(f);
                Destroy(obj.gameObject);
            }
            var toDeleteE = new List <int>(_edgeHandles.Keys).FindAll(key => !manifold.IsHalfedgeInUse(key) || key < manifold.GetOppHalfEdge(key));

            foreach (var e in toDeleteE)
            {
                var obj   = _edgeHandles[e];
                var faces = new[] { obj.FirstFace, obj.SecondFace };
                foreach (var face in faces)
                {
                    FaceHandleController fhc;
                    if (_faceHandles.TryGetValue(face, out fhc))
                    {
                        fhc.ConnectedLatches.Remove(obj);
                    }
                }
                _edgeHandles.Remove(e);
                Destroy(obj.gameObject);
            }

            // Brute force delete all edge controllers every cleanup, might not be effecient but circumvents bug that doesn't remove all invalid edgecontrollers.
            int[] ekeys = _edgeHandles.Keys.ToArray();
            foreach (int key in ekeys)
            {
                var obj = _edgeHandles[key];
                if (!obj.Locked)
                {
                }
                _edgeHandles.Remove(key);
                Destroy(obj.gameObject);
            }

            int[] fkeys = _faceHandles.Keys.ToArray();
            foreach (int key in fkeys)
            {
                var obj = _faceHandles[key];
                _faceHandles.Remove(key);
                Destroy(obj.gameObject);
            }

            int[] vkeys = _vertexHandles.Keys.ToArray();
            foreach (int key in vkeys)
            {
                var obj = _vertexHandles[key];
                _vertexHandles.Remove(key);
                Destroy(obj.gameObject);
            }
        }
Beispiel #4
0
    public bool RefinementTestLoop(int halfedge1, int halfedge2)
    {
        if (!ValidateFaceLoop(halfedge1, halfedge2))
        {
            return(false);
        }
        ExtrudableMesh _extrudableMesh = modellingObject.GetComponentInChildren <ExtrudableMesh>();
        Manifold       manifold        = _extrudableMesh._manifold;

        int h          = halfedge1;
        int initital_f = manifold.GetIncidentFace(halfedge1);
        int f          = initital_f;

        List <int> faceloop = new List <int>();
        List <int> edgeloop = new List <int>();

        while (true)
        {
            if (manifold.IsFaceInUse(f))
            {
                if (manifold.IsHalfedgeInUse(h))
                {
                    int h2 = manifold.GetNextHalfEdge(h);
                    h2 = manifold.GetNextHalfEdge(h2);
                    if (manifold.IsHalfedgeInUse(h2))
                    {
                        int w = manifold.SplitEdge(h);
                        edgeloop.Add(w);
                        faceloop.Add(f);

                        h = manifold.GetOppHalfEdge(h2);
                        f = manifold.GetIncidentFace(h);
                        if (f == initital_f)
                        {
                            int[] farray = faceloop.ToArray();
                            int[] earray = edgeloop.ToArray();
                            for (int i = 0; i < farray.Length; i++)
                            {
                                if (i == farray.Length - 1)
                                {
                                    int output = manifold.SplitFaceByEdges(farray[i], earray[i], earray[0]); // earray[1]);
                                }
                                else
                                {
                                    int output = manifold.SplitFaceByEdges(farray[i], earray[i], earray[i + 1]);
                                }
                            }
                            _extrudableMesh.UpdateMesh();
                            return(true);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
    }