public static CleanUpEdges ( List |
||
nodes | List |
|
edges | List |
|
return | void |
/// <summary> /// Combines two nodes into one /// </summary> /// <param name="node1">First node, this node is transformed into the combined node</param> /// <param name="node2">Second node</param> /// <param name="edges">List of edges in which the IDs are fixed</param> /// <returns>Combined node</returns> public static Node CombineNodes(Node node1, Node node2, List <Edge> edges, List <Node> nodes) { //Combine node positions node1.position = (node1.position + node2.position) / 2f; //Fix edges for (int i = 0; i < edges.Count; i++) { //Remove edges that end in the node2, which will be removed if (node2.adjacents.Count == 1 && (edges[i].Node1 == node2.ID || edges[i].Node2 == node2.ID)) { edges.RemoveAt(i); i--; continue; } if (edges[i].Node1 == node2.ID) { edges[i].Node1 = node1.ID; } if (edges[i].Node2 == node2.ID) { edges[i].Node2 = node1.ID; } } EdgeGraphUtility.CleanUpEdges(ref nodes, ref edges); //Fix node adjacents EdgeGraphUtility.CheckAdjacentNodes(ref nodes, ref edges); return(node1); }
void GenerateSubEdges() { // Save hard copies of this primitive's original nodes and edges List <Node> nodeCopies = new List <Node>(); List <Edge> edgeCopies = new List <Edge>(); EdgeGraphUtility.CopyNodesAndEdges(nodes, edges, out nodeCopies, out edgeCopies, false, false); if (subEdgeSegmentLength <= 0f || subEdgeTargets == null || subEdgeTargets.Count <= 0) { return; } if (subEdgeRootIndex >= nodeCopies.Count) { subEdgeRootIndex = nodeCopies.Count - 1; } Node rootNode = nodeCopies[subEdgeRootIndex]; //EdgeBuilder builder = null; if (subEdgeSegmentLength == 0f) { subEdgeSegmentLength = .5f; } List <Node> _builtSubNodes = new List <Node>(); List <Edge> _builtSubEdges = new List <Edge>(); new EdgeBuilder(rootNode, subEdgeTargets, subEdgeWidth, subEdgeSegmentLength, subEdgeMinAngle, subEdgeMinDistance, subEdgeMaxDistance, (_nodes, _edges) => { if (_nodes == null || _nodes.Count <= 0) { Debug.Log("Primitive::GenerateSubEdges() - Builder nodes null / empty."); return; } _builtSubNodes = _nodes; if (_edges == null || _edges.Count <= 0) { Debug.Log("Primitive::GenerateSubEdges() - Builder edges null / empty."); return; } _builtSubEdges = _edges; CombineSubNodes(rootNode, _builtSubNodes, _builtSubEdges, subEdgeNodeCombineRange); }); nodeCopies.AddRange(_builtSubNodes); edgeCopies.AddRange(_builtSubEdges); ConnectEndPoints(nodeCopies, edgeCopies); CombineSubNodes(rootNode, nodeCopies, edgeCopies, subEdgeNodeCombineRange, false); List <Node> _copiedSubNodes = new List <Node>(); List <Edge> _copiedSubEdges = new List <Edge>(); EdgeGraphUtility.CopyNodesAndEdges(nodeCopies, edgeCopies, out _copiedSubNodes, out _copiedSubEdges); EdgeGraphUtility.CheckAdjacentNodes(ref nodeCopies, ref edgeCopies); EdgeGraphUtility.CleanUpEdges(ref nodeCopies, ref edgeCopies); subNodes = nodeCopies; subEdges = edgeCopies; }
public void CutAcuteAngles() { if (type != PrimitiveType.MinimalCycle) { return; } List <Node> _nodesToRemove = new List <Node>(); List <Node> _newNodes = new List <Node>(); List <Edge> _newEdges = new List <Edge>(); // Old edges are kept in the edges list, but node changes are saved here and refreshed to the edges once all angles are checked Dictionary <string, List <NodePair> > nodesToSwitchInEdges = new Dictionary <string, List <NodePair> >(); for (int i = 0; i < nodes.Count; i++) { Node prevNode = EdgeGraphUtility.GetNode(nodes[i].adjacents[0], ref nodes); Node nextNode = EdgeGraphUtility.GetNode(nodes[i].adjacents[1], ref nodes); Vector3 dirToPrev = (prevNode.Position - nodes[i].Position).normalized; Vector3 dirToNext = (nextNode.Position - nodes[i].Position).normalized; Edge prevEdge = EdgeGraphUtility.FindEdgeByNodes(nodes[i], prevNode, edges); Edge nextEdge = EdgeGraphUtility.FindEdgeByNodes(nodes[i], nextNode, edges); float angle = Vector3.Angle(dirToPrev, dirToNext); if (angle < 45f) { // Move nodes so that the cut side is 1f wide float distanceToMove = .55f / Mathf.Sin(Mathf.Deg2Rad * angle / 2f); float distToPrev = Vector3.Distance(prevNode.Position, nodes[i].Position); float distToNext = Vector3.Distance(nextNode.Position, nodes[i].Position); if (distanceToMove > distToPrev) { distanceToMove = distToPrev * .8f; } if (distanceToMove > distToNext) { distanceToMove = distToNext * .8f; } Vector3 newNodePrevPos = (nodes[i].Position + dirToPrev * distanceToMove); Vector3 newNodeNextPos = (nodes[i].Position + dirToNext * distanceToMove); string oldNodeID = nodes[i].ID; // Remove old node _nodesToRemove.Add(nodes[i]); // Make new nodes Node newNodeToPrev = new Node(newNodePrevPos); Node newNodeToNext = new Node(newNodeNextPos); if (!nodesToSwitchInEdges.ContainsKey(prevEdge.ID)) { nodesToSwitchInEdges.Add(prevEdge.ID, new List <NodePair>()); } nodesToSwitchInEdges[prevEdge.ID].Add(new NodePair(oldNodeID, newNodeToPrev.ID)); if (!nodesToSwitchInEdges.ContainsKey(nextEdge.ID)) { nodesToSwitchInEdges.Add(nextEdge.ID, new List <NodePair>()); } nodesToSwitchInEdges[nextEdge.ID].Add(new NodePair(oldNodeID, newNodeToNext.ID)); // Add the new edge Edge newEdge = new Edge(newNodeToNext.ID, newNodeToPrev.ID); _newEdges.Add(newEdge); // Add new nodes to the dict _newNodes.Add(newNodeToPrev); _newNodes.Add(newNodeToNext); } } foreach (var n in _nodesToRemove) { for (int i = 0; i < nodes.Count; i++) { if (nodes[i].ID == n.ID) { nodes.RemoveAt(i); i--; } } } foreach (var kvp in nodesToSwitchInEdges) { for (int i = 0; i < edges.Count; i++) { if (edges[i].ID == kvp.Key) { Edge e = edges[i]; for (int j = 0; j < kvp.Value.Count; j++) { NodePair pair = kvp.Value[j]; if (e.Node1 == pair.oldNode) { e.Node1 = pair.newNode; } if (e.Node2 == pair.oldNode) { e.Node2 = pair.newNode; } } } } } _newEdges.ForEach((e) => edges.Add(e)); _newNodes.ForEach((n) => nodes.Add(n)); EdgeGraphUtility.CleanUpEdges(ref nodes, ref edges); EdgeGraphUtility.CheckAdjacentNodes(ref nodes, ref edges); }