Пример #1
0
 public Primitive(Primitive _p)
 {
     id = Guid.NewGuid().ToString();
     type = _p.type;
     edges = _p.edges;
     nodes = _p.nodes;
     CopyNodesAndEdges();
 }
Пример #2
0
        // Algorithms from http://www.geometrictools.com/Documentation/MinimalCycleBasis.pdf
        // The Minimal Cycle Basis for a Planar Graph by David Eberly

        /// <summary>
        /// Attempts to find minimal cycles
        /// </summary>
        public static void ExtractPrimitive(Node _n0, ref List<Node> _nodes, ref List<Edge> _edges, ref List<Primitive> _primitives)
        {
            List<Node> visited = new List<Node>();
            List<Node> sequence = new List<Node>();

            EdgeGraphUtility.CheckAdjacentNodes(ref _nodes, ref _edges);

            if (_n0.adjacents.Count == 0)
            {
                EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                return;
            }

            sequence.Add(_n0);
            Node _n1 = GetClockwiseMostAdjacent(null, _n0, ref _nodes);
            Node prev = _n0;
            Node curr = _n1;

            while (curr != null && curr != _n0 && !visited.Contains(curr))
            {
                sequence.Add(curr);
                visited.Add(curr);
                Node next = GetCounterClockwiseMostAdjacent(prev, curr, ref _nodes);
                prev = curr;
                curr = next;
            }

            if (curr == null)
            {
                // Filament found, not necessarily rooted at prev
                ExtractFilament(prev, EdgeGraphUtility.GetNode(prev.adjacents[0], ref _nodes), ref _nodes, ref _edges, ref _primitives);
            }
            else if (curr == _n0)
            {
                // Minimal cycle found
                Primitive primitive = new Primitive(Primitive.PrimitiveType.MinimalCycle);
                primitive.nodes.AddRange(sequence);

                for (int i = 0; i < sequence.Count; i++)
                {
                    Node n1;
                    Node n2;
                    if (i == sequence.Count - 1)
                    {
                        n1 = sequence[i];
                        n2 = sequence[0];
                    }
                    else
                    {
                        n1 = sequence[i];
                        n2 = sequence[i + 1];
                    }
                    Edge e = EdgeGraphUtility.FindEdgeByNodes(n1, n2, _edges);
                    if (e != null)
                    {
                        primitive.edges.Add(e);
                        e.isPartOfCycle = true;
                    }
                }

                EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);

                if (_n0.adjacents.Count == 1)
                {
                    // Remove the filament rooted at v0
                    ExtractFilament(_n0, EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes), ref _nodes, ref _edges, ref _primitives);
                }

                if (_n1.adjacents.Count == 1)
                {
                    // Remove the filament rooted at v1
                    ExtractFilament(_n1, EdgeGraphUtility.GetNode(_n1.adjacents[0], ref _nodes), ref _nodes, ref _edges, ref _primitives);
                }

                _primitives.Add(primitive);
            }
            else   // curr was visited earlier
            {
                // A cycle has been found, but is not guaranteed to be a minimal cycle.
                // This implies v0 is part of a filament
                // Locate the starting point for the filament by traversing from v0 away from the initial v1

                while (_n0.adjacents.Count == 2)
                {
                    if (_n0.adjacents[0] != _n1.ID)
                    {
                        _n1 = _n0;
                        _n0 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                    }
                    else
                    {
                        _n1 = _n0;
                        _n0 = EdgeGraphUtility.GetNode(_n0.adjacents[1], ref _nodes);
                    }
                }

                ExtractFilament(_n0, _n1, ref _nodes, ref _edges, ref _primitives);
            }
        }
Пример #3
0
        /// <summary>
        /// Extracts filament consisting of nodes and edges
        /// </summary>
        public static void ExtractFilament(Node _n0, Node _n1, ref List<Node> _nodes, ref List<Edge> _edges, ref List<Primitive> _primitives)
        {
            Edge e = EdgeGraphUtility.FindEdgeByNodes(_n0, _n1, _edges);
            if (e != null && e.isPartOfCycle)
            {
                if (_n0.adjacents.Count >= 3)
                {
                    EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);
                    _n0 = _n1;
                    if (_n0.adjacents.Count == 1) _n1 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                }

                while (_n0.adjacents.Count == 1)
                {
                    _n1 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                    Edge ee = EdgeGraphUtility.FindEdgeByNodes(_n0, _n1, _edges);
                    if (ee != null && e.isPartOfCycle)
                    {
                        EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                        EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);
                    }
                    else
                        break;
                }

                if (_n0.adjacents.Count == 0)
                {
                    EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                }
            }
            else
            {
                Primitive primitive = new Primitive(Primitive.PrimitiveType.Filament);

                if (_n0.adjacents.Count >= 3)
                {
                    primitive.nodes.Add(_n0);
                    primitive.edges.Add(e);
                    EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);
                    _n0 = _n1;
                    if (_n0.adjacents.Count == 1) _n1 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                }

                while (_n0.adjacents.Count == 1)
                {
                    primitive.nodes.Add(_n0);
                    _n1 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                    EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                    Edge _e = EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);
                    if (_e != null) primitive.edges.Add(_e);
                    _n0 = _n1;
                }

                primitive.nodes.Add(_n0);
                if (_n0.adjacents.Count == 0)
                {
                    EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                }

                _primitives.Add(primitive);
            }
        }
Пример #4
0
        void ProcessSubPrimitives(Primitive p)
        {
            if (p.subEdges == null || p.subEdges.Count <= 0) return;

            // Copy local lists from primitive's sub nodes and edges
            List<Node> _nodes = new List<Node>();
            List<Edge> _edges = new List<Edge>();

            EdgeGraphUtility.CopyNodesAndEdges(p.subNodes, p.subEdges, out _nodes, out _edges);

            EdgeGraphUtility.CheckAdjacentNodes(ref _nodes, ref _edges);

            //subPrimitives = new List<Primitive>();
            List<Primitive> _subPrimitives = new List<Primitive>();

            // Extract primitives inside main primitives
            try
            {
                MinimalCycle.Extract(ref _nodes, ref _edges, ref _subPrimitives);
            }
            catch (Exception e)
            {
                Debug.LogWarning("Graph::GeneratePrimitiveSubPrimitives() - Error while extracting primitives: " + e.Message);
                return;
            }

            _subPrimitives.ForEach((sp) =>
            {
                sp.Process();
            });

            for (int i = _subPrimitives.Count - 1; i >= 0; i--)
            {
                if (!_subPrimitives[i].EvaluationResult)
                    _subPrimitives.RemoveAt(i);
            }

            _subPrimitives.ForEach((sp) =>
            {
                sp.parent = p.ID;

                GameObject subGraphObj = new GameObject("SubGraph");
                subGraphObj.transform.SetParent(transform);
                subGraphObj.transform.localPosition = Vector3.zero;
                subGraphObj.transform.localScale = Vector3.one;

                Graph subGraph = subGraphObj.AddComponent<Graph>();
                subGraph.GraphID = Guid.NewGuid().GetHashCode();
                subGraphObj.name += subGraph.GraphID;

                subGraph.nodes = new List<Node>();
                foreach (var node in sp.nodes)
                {
                    subGraph.nodes.Add(node);
                }
                subGraph.edges = new List<Edge>();
                foreach (var edge in sp.edges)
                {
                    edge.Width = 0f;
                    subGraph.edges.Add(edge);
                }

                subGraph.ProcessMinimalCycles();

                subGraph.mainPrimitives[0].parent = p.ID;

                subGraphs.Add(subGraph);

                //subPrimitives.Add(subGraph.mainPrimitives[0]);

                FacadeBuilder builder = GetComponent<FacadeBuilder>();
                if (builder != null)
                {
                    FacadeBuilder subBuilder = subGraph.gameObject.AddComponent<FacadeBuilder>();
                    subBuilder.inSet = builder.inSet;
                    subBuilder.facadeStretchPrefab = builder.facadeStretchPrefab;
                    subBuilder.facadePrefabs = builder.facadePrefabs;
                    subBuilder.roofMiddleMaterial = builder.roofMiddleMaterial;
                    subBuilder.roofSideMaterial = builder.roofSideMaterial;
                    subBuilder.roofHeight = builder.roofHeight;
                    subBuilder.roofMiddleAddHeight = builder.roofMiddleAddHeight;
                    subBuilder.roofAccentWidth = builder.roofAccentWidth;
                }

                FootprintPlacer placer = GetComponent<FootprintPlacer>();
                if (placer != null)
                {
                    FootprintPlacer _placer = subGraph.gameObject.AddComponent<FootprintPlacer>();
                    _placer.footprintPrefabsOnEdge = placer.footprintPrefabsOnEdge;
                    _placer.footprintPrefabsInside = placer.footprintPrefabsInside;
                    _placer.UpdateData();
                }
            });
        }
Пример #5
0
 void GenerateSubEdges(int seed, Primitive p)
 {
     p.Generate(seed);
 }
Пример #6
0
        void ClearSubPrimitives(Primitive p)
        {
            //for (int i = 0; i < subPrimitives.Count; i++)
            //{
            //    if (subPrimitives[i].parent == p.ID)
            //    {
            //        subPrimitives[i].subNodes = new List<Node>();
            //        subPrimitives[i].subEdges = new List<Edge>();
            //        subPrimitives.RemoveAt(i);
            //        i--;
            //    }
            //}

            for (int i = 0; i < subGraphs.Count; i++)
            {
                if (subGraphs[i] == null)
                {
                    subGraphs.RemoveAt(i);
                    i--;
                    continue;
                }

                if (subGraphs[i].mainPrimitives[0].parent == p.ID)
                {
                    DestroyImmediate(subGraphs[i].gameObject);
                    subGraphs.RemoveAt(i);
                    i--;
                }
            }
        }
Пример #7
0
        // Algorithms from http://www.geometrictools.com/Documentation/MinimalCycleBasis.pdf
        // The Minimal Cycle Basis for a Planar Graph by David Eberly

        /// <summary>
        /// Attempts to find minimal cycles
        /// </summary>
        public static void ExtractPrimitive(Node _n0, ref List <Node> _nodes, ref List <Edge> _edges, ref List <Primitive> _primitives)
        {
            List <Node> visited  = new List <Node>();
            List <Node> sequence = new List <Node>();

            EdgeGraphUtility.CheckAdjacentNodes(ref _nodes, ref _edges);

            if (_n0.adjacents.Count == 0)
            {
                EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                return;
            }

            sequence.Add(_n0);
            Node _n1  = GetClockwiseMostAdjacent(null, _n0, ref _nodes);
            Node prev = _n0;
            Node curr = _n1;

            while (curr != null && curr != _n0 && !visited.Contains(curr))
            {
                sequence.Add(curr);
                visited.Add(curr);
                Node next = GetCounterClockwiseMostAdjacent(prev, curr, ref _nodes);
                prev = curr;
                curr = next;
            }

            if (curr == null)
            {
                // Filament found, not necessarily rooted at prev
                ExtractFilament(prev, EdgeGraphUtility.GetNode(prev.adjacents[0], ref _nodes), ref _nodes, ref _edges, ref _primitives);
            }
            else if (curr == _n0)
            {
                // Minimal cycle found
                Primitive primitive = new Primitive(Primitive.PrimitiveType.MinimalCycle);
                primitive.nodes.AddRange(sequence);

                for (int i = 0; i < sequence.Count; i++)
                {
                    Node n1;
                    Node n2;
                    if (i == sequence.Count - 1)
                    {
                        n1 = sequence[i];
                        n2 = sequence[0];
                    }
                    else
                    {
                        n1 = sequence[i];
                        n2 = sequence[i + 1];
                    }
                    Edge e = EdgeGraphUtility.FindEdgeByNodes(n1, n2, _edges);
                    if (e != null)
                    {
                        primitive.edges.Add(e);
                        e.isPartOfCycle = true;
                    }
                }

                EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);

                if (_n0.adjacents.Count == 1)
                {
                    // Remove the filament rooted at v0
                    ExtractFilament(_n0, EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes), ref _nodes, ref _edges, ref _primitives);
                }

                if (_n1.adjacents.Count == 1)
                {
                    // Remove the filament rooted at v1
                    ExtractFilament(_n1, EdgeGraphUtility.GetNode(_n1.adjacents[0], ref _nodes), ref _nodes, ref _edges, ref _primitives);
                }

                _primitives.Add(primitive);
            }
            else   // curr was visited earlier
            {
                // A cycle has been found, but is not guaranteed to be a minimal cycle.
                // This implies v0 is part of a filament
                // Locate the starting point for the filament by traversing from v0 away from the initial v1

                while (_n0.adjacents.Count == 2)
                {
                    if (_n0.adjacents[0] != _n1.ID)
                    {
                        _n1 = _n0;
                        _n0 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                    }
                    else
                    {
                        _n1 = _n0;
                        _n0 = EdgeGraphUtility.GetNode(_n0.adjacents[1], ref _nodes);
                    }
                }

                ExtractFilament(_n0, _n1, ref _nodes, ref _edges, ref _primitives);
            }
        }
Пример #8
0
        /// <summary>
        /// Extracts filament consisting of nodes and edges
        /// </summary>
        public static void ExtractFilament(Node _n0, Node _n1, ref List <Node> _nodes, ref List <Edge> _edges, ref List <Primitive> _primitives)
        {
            Edge e = EdgeGraphUtility.FindEdgeByNodes(_n0, _n1, _edges);

            if (e != null && e.isPartOfCycle)
            {
                if (_n0.adjacents.Count >= 3)
                {
                    EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);
                    _n0 = _n1;
                    if (_n0.adjacents.Count == 1)
                    {
                        _n1 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                    }
                }

                while (_n0.adjacents.Count == 1)
                {
                    _n1 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                    Edge ee = EdgeGraphUtility.FindEdgeByNodes(_n0, _n1, _edges);
                    if (ee != null && e.isPartOfCycle)
                    {
                        EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                        EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);
                    }
                    else
                    {
                        break;
                    }
                }

                if (_n0.adjacents.Count == 0)
                {
                    EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                }
            }
            else
            {
                Primitive primitive = new Primitive(Primitive.PrimitiveType.Filament);

                if (_n0.adjacents.Count >= 3)
                {
                    primitive.nodes.Add(_n0);
                    primitive.edges.Add(e);
                    EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);
                    _n0 = _n1;
                    if (_n0.adjacents.Count == 1)
                    {
                        _n1 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                    }
                }

                while (_n0.adjacents.Count == 1)
                {
                    primitive.nodes.Add(_n0);
                    _n1 = EdgeGraphUtility.GetNode(_n0.adjacents[0], ref _nodes);
                    EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                    Edge _e = EdgeGraphUtility.RemoveEdgeAndCleanAdjacents(_n0, _n1, ref _nodes, ref _edges);
                    if (_e != null)
                    {
                        primitive.edges.Add(_e);
                    }
                    _n0 = _n1;
                }

                primitive.nodes.Add(_n0);
                if (_n0.adjacents.Count == 0)
                {
                    EdgeGraphUtility.RemoveNodeAndCleanAdjacents(_n0, ref _nodes, ref _edges);
                }

                _primitives.Add(primitive);
            }
        }