public void TestUnorderedPairGetters() { IPair a = new UnorderedPair(1, 2); Assert.IsTrue(a.First.Equals(1)); Assert.IsTrue(a.Second.Equals(2)); }
private void DeleteEdge(UnorderedPair <ISceneNode> key) { var gizmo = edgeGizmos[key]; edgeGizmos.Remove(key); Node.ChildNodes.Remove(gizmo); }
public void TestInterPairEquals() { IPair a = new OrderedPair(1, 2); IPair b = new UnorderedPair(1, 2); Assert.IsTrue(!a.Equals(b)); Assert.IsTrue(!b.Equals(a)); }
private void AddNewEdge(UnorderedPair <ISceneNode> key, IStandardMaterial material, IStandardRenderState renderState) { var gizmo = AmFactory.Factory.CreateWorldNodeWithComponent <StoryFlowchartEdgeGizmoComponent>(out var component); gizmo.Name = $"EdgeGizmo({key.First}->{key.Second})"; component.Material = material; component.RenderState = renderState; edgeGizmos.Add(key, gizmo); Node.ChildNodes.Add(gizmo); }
public override bool Equals(object obj) { if (obj is UnorderedPair <FirstType, SecondType> ) { UnorderedPair <FirstType, SecondType> pair = (UnorderedPair <FirstType, SecondType>)obj; return(base.Equals(pair) || (EqualsFirstSecond(pair) && EqualsSecondFirst(pair))); } return(false); }
public void SelectEdgeLoop(ICollection <UnorderedPair <int> > edges, UnorderedPair <int> start, bool recurses = true) { UpdateGraph(); edges.Add(start); int prev = start.Item1; int cur = start.Item2; while (true) { UnorderedPair <int> curEdge = new UnorderedPair <int>(prev, cur); if (vertexNeighbors[cur].Count != 4) { break; } bool found = false; foreach (var v in vertexNeighbors[cur]) { var e = new UnorderedPair <int>(cur, v); bool ok = true; foreach (int f in edgeFaces[e]) { if (edgeFaces[curEdge].Contains(f)) { ok = false; break; } } if (ok) { found = true; edges.Add(e); prev = cur; cur = e.Not(cur); break; } } if (!found || cur == start.Item1) { break; } } if (recurses && cur != start.Item1) { SelectEdgeLoop(edges, new UnorderedPair <int>(start.Item2, start.Item1), false); } }
private bool IsNotInnerEdge(UnorderedPair <int> edge, ICollection <int> faceIndices) { foreach (var neighbor in edgeFaces[edge]) { if (!faceIndices.Contains(neighbor)) { return(true); } } return(false); }
public void TestUnorderedPairEquals() { IPair a = new UnorderedPair(1, 2); Assert.IsTrue(a.Equals(a)); Assert.IsTrue(!a.Equals(null)); IPair b = new UnorderedPair(1, 2); Assert.IsTrue(a.Equals(b)); Assert.IsTrue(b.Equals(a)); Assert.IsTrue(a.GetHashCode() == b.GetHashCode()); IPair c = new UnorderedPair(2, 1); Assert.IsTrue(a.Equals(c)); Assert.IsTrue(c.Equals(a)); Assert.IsTrue(a.GetHashCode() == c.GetHashCode()); }
public void unordered_pair_pinning_test() { var pair1 = new UnorderedPair <Point>(new Point(0, 1), new Point(5, 5)); var sameAsPair1 = new UnorderedPair <Point>(new Point(0, 1), new Point(5, 5)); var p1 = new Point(5, 5); var p2 = new Point(0, 1); var pair1Flipped = new UnorderedPair <Point>(p1, p2); var pair2 = new UnorderedPair <Point>(new Point(0, -5), new Point(5, 5)); Assert.True(pair1.Equals(pair1), "UnorderedPair.Equals works on self"); Assert.True(pair1.Equals(sameAsPair1), "UnorderedPair.Equals works on identical set"); Assert.True(pair1.Equals(pair1Flipped), "UnorderedPair.Equals works on flipped set"); Assert.False(pair1.Equals(pair2), "UnorderedPair.Equals should be false for 2 different pairs"); Assert.True(pair1 == sameAsPair1, "UnorderedPair == works on identical set"); Assert.True(pair1 == pair1Flipped, "UnorderedPair == works on flipped set"); Assert.False(pair1 == pair2, "UnorderedPair == should be false for 2 different pairs"); }
private void InsertVertex(Face face, UnorderedPair <int> edge, int vertex) { int i1 = face.vertices.IndexOf(edge.Item1); int i2 = face.vertices.IndexOf(edge.Item2); if (i2 == (i1 + 1) % face.vertices.Count) { face.vertices.Insert(i1 + 1, vertex); graphDirty = true; } else if (i1 == (i2 + 1) % face.vertices.Count) { face.vertices.Insert(i2 + 1, vertex); graphDirty = true; } else { Debug.Log("Vertex not inserted!"); } }
public List <UnorderedPair <int> > GetEdges() { List <UnorderedPair <int> > edges = new List <UnorderedPair <int> >(); foreach (var f in faces) { for (int i = 0; i < f.vertices.Count; i++) { int j = (i + 1) % f.vertices.Count; UnorderedPair <int> edge = new UnorderedPair <int>(f.vertices[i], f.vertices[j]); if (!edges.Contains(edge)) { edges.Add(edge); } } } return(edges); }
private bool IsOuterEdge(UnorderedPair <int> edge, ICollection <int> faceIndices) { bool outer = false, inner = false; foreach (var neighbor in edgeFaces[edge]) { if (!faceIndices.Contains(neighbor)) { outer = true; } else { inner = true; } if (outer && inner) { return(true); } } return(false); }
private bool GetEdgeOrder(UnorderedPair <int> edge, out int t1, out int t2) { UpdateGraph(); var n = edgeFaces[edge]; if (n.Count != 1) { t1 = -1; t2 = -1; return(false); } Face f = faces[n[0]]; int ind1 = f.vertices.IndexOf(edge.Item1); int ind2 = f.vertices.IndexOf(edge.Item2); if (ind2 == (ind1 + 1) % f.vertices.Count) { t1 = edge.Item2; t2 = edge.Item1; return(true); } else if (ind1 == (ind2 + 1) % f.vertices.Count) { t1 = edge.Item1; t2 = edge.Item2; return(true); } else { t1 = -1; t2 = -1; return(false); } }
public bool InsertLoop(ICollection <UnorderedPair <int> > edges) { if (edges.Count != 1) { return(false); } UpdateGraph(); var iter = edges.GetEnumerator(); iter.MoveNext(); var edge = iter.Current; iter.Dispose(); List <UnorderedPair <int> > edgeLoop = new List <UnorderedPair <int> > { edge }; List <int> faceLoop = new List <int> { edgeFaces[edge][0] }; bool oneSide = false; while (true) { int cnt = faceLoop.Count; int cur = faceLoop[cnt - 1]; foreach (var e in faceEdges[cur]) { if (!e.Adjacent(edgeLoop[edgeLoop.Count - 1])) { edgeLoop.Add(e); if (e == edgeLoop[0]) { break; } var ef = edgeFaces[e]; foreach (int f in ef) { if (f != cur && faceEdges[f].Count == 4 && f != faceLoop[0]) { faceLoop.Add(f); break; } } break; } } if (faceLoop.Count == cnt || edgeLoop[edgeLoop.Count - 1] == edgeLoop[0]) { oneSide = edgeLoop[edgeLoop.Count - 1] != edgeLoop[0]; break; } } if (oneSide) { while (true) { int cnt = faceLoop.Count; var cur = edgeLoop[0]; foreach (int f in edgeFaces[cur]) { if (f != faceLoop[0] && faceEdges[f].Count == 4) { faceLoop.Insert(0, f); foreach (var e in faceEdges[f]) { if (!e.Adjacent(cur)) { edgeLoop.Insert(0, e); break; } } break; } } if (faceLoop.Count == cnt) { break; } } } List <int> addedVerts = new List <int>(); for (int i = 0; i < faceLoop.Count; i++) { Face face = faces[faceLoop[i]]; UnorderedPair <int> edge1 = edgeLoop[i]; UnorderedPair <int> edge2 = edgeLoop[i + 1]; int v1, v2; if (i == 0) { v1 = AddVertex(GetEdgeCenter(edge1)); addedVerts.Add(v1); } else { v1 = addedVerts[addedVerts.Count - 1]; } if (i == faceLoop.Count - 1 && edge2 == edgeLoop[0]) { v2 = addedVerts[0]; } else { v2 = AddVertex(GetEdgeCenter(edge2)); addedVerts.Add(v2); } Face newFace = new Face(); newFace.vertices = new List <int>(); InsertVertex(face, edge1, v1); InsertVertex(face, edge2, v2); int ind1 = face.vertices.IndexOf(v1); int ind2 = face.vertices.IndexOf(v2); if (ind1 == -1 || ind2 == -1) { Debug.LogError("Could not insert vertex"); continue; } for (int j = ind1; j != (ind2 + 1) % face.vertices.Count; j = (j + 1) % face.vertices.Count) { newFace.vertices.Add(face.vertices[j]); if (j != ind1 && j != ind2) { face.vertices[j] = -1; } } face.vertices.RemoveAll(v => v < 0); faces.Add(newFace); } graphDirty = true; return(true); }
public Vector3 GetEdgeCenter(UnorderedPair <int> edge) { return((vertices[edge.Item1].position + vertices[edge.Item2].position) / 2.0f); }
private bool EdgesAreContiguous(ICollection <UnorderedPair <int> > edges, out List <int> vertices) { UpdateGraph(); var iter = edges.GetEnumerator(); iter.MoveNext(); var edge = iter.Current; iter.Dispose(); int t1, t2; if (!GetEdgeOrder(edge, out t1, out t2)) { vertices = null; return(false); } vertices = new List <int> { t1, t2 }; for (int i = 1; i < edges.Count; i++) { int prev = vertices[vertices.Count - 2]; int cur = vertices[vertices.Count - 1]; var curEdge = new UnorderedPair <int>(prev, cur); if (edgeFaces[curEdge].Count > 1) { vertices = null; return(false); } bool found = false; foreach (var e in edges) { if (e == curEdge || (e.Item1 != cur && e.Item2 != cur)) { continue; } int next = e.Not(cur); if (next == vertices[0]) { if (i == edges.Count - 1) { return(true); } else { vertices = null; return(false); } } vertices.Add(next); found = true; break; } if (found) { continue; } vertices = null; return(false); } vertices = null; return(false); }
private void UpdateGraph() { if (!graphDirty) { return; } edgeFaces = new Dictionary <UnorderedPair <int>, List <int> >(); vertexNeighbors = new Dictionary <int, HashSet <int> >(); vertexFaces = new Dictionary <int, HashSet <int> >(); faceEdges = new Dictionary <int, HashSet <UnorderedPair <int> > >(); for (int i = 0; i < faces.Count; i++) { Face face = faces[i]; for (int j = 0; j < face.vertices.Count; j++) { int next = face.vertices[(j + 1) % face.vertices.Count]; int prev = face.vertices[((j - 1) + face.vertices.Count) % face.vertices.Count]; int vert = face.vertices[j]; if (!vertexFaces.ContainsKey(vert)) { vertexFaces[vert] = new HashSet <int>(); } vertexFaces[vert].Add(i); if (!vertexNeighbors.ContainsKey(vert)) { vertexNeighbors[vert] = new HashSet <int>(); } vertexNeighbors[vert].Add(prev); vertexNeighbors[vert].Add(next); UnorderedPair <int> edge1 = new UnorderedPair <int>(prev, vert); if (!edgeFaces.ContainsKey(edge1)) { edgeFaces[edge1] = new List <int>(); } edgeFaces[edge1].Add(i); } } foreach (var pair in edgeFaces) { foreach (var face in pair.Value) { if (!faceEdges.ContainsKey(face)) { faceEdges[face] = new HashSet <UnorderedPair <int> >(); } faceEdges[face].Add(pair.Key); } } graphDirty = false; }
private bool EqualsSecondFirst(UnorderedPair <FirstType, SecondType> pair) { return(((m_second == null) && (pair.m_first == null)) || ((m_second != null) && (pair.m_first != null) && m_second.Equals(pair.m_first))); }
public bool Adjacent(UnorderedPair <T> other) { return(Contains(other.t1) || Contains(other.t2)); }
// done! internal static void UnweightedMinimizeOld <T, S>(DFSA <T, S> dfsa) { ICollection <DFSAState <T, S> > states = dfsa.States(); IDictionary <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> >, IList <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > > stateUPairToDependentUPairList = Generics.NewHashMap(states.Count * states.Count / 2 + 1); IDictionary <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> >, bool> stateUPairToDistinguished = Generics.NewHashMap(states.Count * states.Count / 2 + 1); int[] c = new int[states.Count * states.Count / 2 + 1]; int streak = 0; int collisions = 0; int entries = 0; long time = Runtime.CurrentTimeMillis(); if (debug) { time = Runtime.CurrentTimeMillis(); log.Info("Starting on " + dfsa.dfsaID); log.Info(" -- " + states.Count + " states."); } // initialize grid int numDone = 0; foreach (DFSAState <T, S> state1 in states) { foreach (DFSAState <T, S> state2 in states) { UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > up = new UnorderedPair <DFSAState <T, S>, DFSAState <T, S> >(state1, state2); if (state1.Equals(state2)) { continue; } if (stateUPairToDistinguished.Contains(up)) { continue; } int bucket = (up.GetHashCode() & unchecked ((int)(0x7FFFFFFF))) % (states.Count * states.Count / 2 + 1); c[bucket]++; entries++; if (c[bucket] > 1) { collisions++; streak = 0; } else { streak++; } if (state1.IsAccepting() != state2.IsAccepting()) { //log.info(Utils.pad((String)state1.stateID, 20)+" "+state2.stateID); stateUPairToDistinguished[up] = true; } else { stateUPairToDistinguished[up] = false; } } //stateUPairToDependentUPairList.put(up, new ArrayList()); numDone++; if (numDone % 20 == 0) { log.Info("\r" + numDone + " " + ((double)collisions / (double)entries)); } } if (debug) { log.Info("\nInitialized: " + (Runtime.CurrentTimeMillis() - time)); time = Runtime.CurrentTimeMillis(); } // visit each undistinguished pair foreach (UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > up_1 in stateUPairToDistinguished.Keys) { DFSAState <T, S> state1_1 = up_1.first; DFSAState <T, S> state2 = up_1.second; if (stateUPairToDistinguished[up_1].Equals(true)) { continue; } // check if some input distinguishes this pair ICollection <T> inputs = Generics.NewHashSet(state1_1.ContinuingInputs()); Sharpen.Collections.AddAll(inputs, state2.ContinuingInputs()); bool distinguishable = false; ICollection <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > pendingUPairs = Generics.NewHashSet(); IEnumerator <T> inputI = inputs.GetEnumerator(); while (inputI.MoveNext() && !distinguishable) { T input = inputI.Current; DFSATransition <T, S> transition1 = state1_1.Transition(input); DFSATransition <T, S> transition2 = state2.Transition(input); if ((transition1 == null) != (transition2 == null)) { distinguishable = true; } if (transition1 != null && transition2 != null) { DFSAState <T, S> target1 = transition1.GetTarget(); DFSAState <T, S> target2 = transition2.GetTarget(); UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > targetUPair = new UnorderedPair <DFSAState <T, S>, DFSAState <T, S> >(target1, target2); if (!target1.Equals(target2)) { if (stateUPairToDistinguished[targetUPair].Equals(true)) { distinguishable = true; } else { pendingUPairs.Add(targetUPair); } } } } // if the pair is distinguishable, record that if (distinguishable) { IList <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > markStack = new List <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > >(); markStack.Add(up_1); while (!markStack.IsEmpty()) { UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > upToMark = markStack[markStack.Count - 1]; markStack.Remove(markStack.Count - 1); stateUPairToDistinguished[upToMark] = true; IList <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > addList = stateUPairToDependentUPairList[upToMark]; if (addList != null) { Sharpen.Collections.AddAll(markStack, addList); stateUPairToDependentUPairList[upToMark].Clear(); } } } else { // otherwise add it to any pending pairs foreach (UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > pendingUPair in pendingUPairs) { IList <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > dependentList = stateUPairToDependentUPairList[pendingUPair]; if (dependentList == null) { dependentList = new List <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > >(); stateUPairToDependentUPairList[pendingUPair] = dependentList; } dependentList.Add(up_1); } } } if (debug) { log.Info("All pairs marked: " + (Runtime.CurrentTimeMillis() - time)); time = Runtime.CurrentTimeMillis(); } // decide what canonical state each state will map to... IDisjointSet <DFSAState <T, S> > stateClasses = new FastDisjointSet <DFSAState <T, S> >(states); foreach (UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > up_2 in stateUPairToDistinguished.Keys) { if (stateUPairToDistinguished[up_2].Equals(false)) { DFSAState <T, S> state1_1 = up_2.first; DFSAState <T, S> state2 = up_2.second; stateClasses.Union(state1_1, state2); } } IDictionary <DFSAState <T, S>, DFSAState <T, S> > stateToRep = Generics.NewHashMap(); foreach (DFSAState <T, S> state in states) { DFSAState <T, S> rep = stateClasses.Find(state); stateToRep[state] = rep; } if (debug) { log.Info("Canonical states chosen: " + (Runtime.CurrentTimeMillis() - time)); time = Runtime.CurrentTimeMillis(); } // reduce the DFSA by replacing transition targets with their reps foreach (DFSAState <T, S> state_1 in states) { if (!state_1.Equals(stateToRep[state_1])) { continue; } foreach (DFSATransition <T, S> transition in state_1.Transitions()) { transition.target = stateClasses.Find(transition.target); } } dfsa.initialState = stateClasses.Find(dfsa.initialState); if (debug) { log.Info("Done: " + (Runtime.CurrentTimeMillis() - time)); } }
public bool ExtrudeFaces(HashSet <int> selected) { if (!FacesAreConnected(selected)) { Debug.LogError("Cannot Extrude Disconnected Faces"); return(false); } var startEdge = FindOuterEdge(selected); if (startEdge.Item1 == -1) { Debug.LogError("Cannot Find Outer Edge"); return(false); } // Make sure the first two vertices are in the right order by comparing with a selected face foreach (var f in edgeFaces[startEdge]) { if (!selected.Contains(f)) { continue; } int t1index = faces[f].vertices.IndexOf(startEdge.Item1); int t2index = faces[f].vertices.IndexOf(startEdge.Item2); if (t1index == (t2index + 1) % faces[f].vertices.Count) { // Edge is in the wrong order. Fix it (this doesn't modify the orignal edge). int temp = startEdge.Item2; startEdge = new UnorderedPair <int>(temp, startEdge.Item1); } break; } Vector3 normal = GetFacesNormal(selected); List <int> edgeLoop = new List <int> { startEdge.Item1, startEdge.Item2 }; while (true) { int cur = edgeLoop[edgeLoop.Count - 1]; int prev = edgeLoop[edgeLoop.Count - 2]; int next = -1; foreach (int cand in vertexNeighbors[cur]) { var edge = new UnorderedPair <int>(cur, cand); if (cand == prev || !IsOuterEdge(edge, selected)) { continue; } next = cand; break; } if (next != -1) { if (next == edgeLoop[0]) { break; } edgeLoop.Add(next); } else { Debug.LogError("Edge Loop Not Found"); return(false); } } Face lastCreatedFace = null; int v1 = -1, v2 = -1; foreach (var v in edgeLoop) { int newVert = AddVertex(vertices[v].position); if (lastCreatedFace != null) { lastCreatedFace.vertices.Add(v); lastCreatedFace.vertices.Add(newVert); } else { v1 = v; v2 = newVert; } lastCreatedFace = new Face(newVert, v); faces.Add(lastCreatedFace); foreach (int face in selected) { for (int k = 0; k < faces[face].vertices.Count; k++) { if (faces[face].vertices[k] == v) { faces[face].vertices[k] = newVert; } } } } lastCreatedFace.vertices.Add(v1); lastCreatedFace.vertices.Add(v2); foreach (int v in GetUniqueVertexList(selected)) { vertices[v].position += normal; } graphDirty = true; return(true); }
public void Select(Transform transform, Vector2 mousePos, Camera camera, out int selVertex, out int selFace, out UnorderedPair <int> selEdge, float radius = 10, float bump = 0.2f) { selVertex = -1; selFace = -1; selEdge = new UnorderedPair <int>(-1, -1); float minDist = Mathf.Infinity; Ray ray = camera.ScreenPointToRay(mousePos); ray.origin = transform.InverseTransformPoint(ray.origin); ray.direction = transform.InverseTransformDirection(ray.direction); for (int v = 0; v < vertices.Count; v++) { Vertex vert = vertices[v]; Vector3 world = transform.TransformPoint(vert.position); Vector3 screen = camera.WorldToScreenPoint(world); if (screen.z > 0) { screen.z = 0; float mouseDist2 = Vector2.SqrMagnitude((Vector2)screen - mousePos); float camDist = Vector3.Distance(camera.transform.position, world) - bump * 3; if (mouseDist2 < radius * radius && camDist < minDist) { selVertex = v; minDist = camDist; } } } foreach (var e in GetEdges()) { Vertex vert1 = vertices[e.Item1]; Vertex vert2 = vertices[e.Item2]; Vector3 v1 = vert1.position; Vector3 v2 = vert2.position; Vector3 segment = v2 - v1; Vector3 c = Vector3.Cross(camera.transform.forward, segment); Vector3 n = Vector3.Cross(c, segment); Plane plane = new Plane(n, v1); float camDist; if (plane.Raycast(ray, out camDist) && camDist - bump < minDist) { Vector3 hitPos = ray.GetPoint(camDist); Vector3 hitProj = MathUtil.ProjectPointOnLineSegment(v1, v2, hitPos); Vector3 projScreen = camera.WorldToScreenPoint(transform.TransformPoint(hitProj)); if (projScreen.z > 0 && Vector2.Distance(projScreen, mousePos) < radius * 0.6f) { selEdge = e; selVertex = -1; minDist = camDist - bump; } } } for (int f = 0; f < faces.Count; f++) { Face face = faces[f]; Vector3 normal = face.GetNormal(this); Plane plane = new Plane(normal, vertices[face.vertices[0]].position); float dist; if (plane.Raycast(ray, out dist) && dist < minDist) { Vector3 hitPos = ray.GetPoint(dist); bool inside = true; for (int i = 0; i < face.vertices.Count; i++) { int j = (i + 1) % face.vertices.Count; Vector3 v1 = vertices[face.vertices[i]].position; Vector3 v2 = vertices[face.vertices[j]].position; Vector3 edge = v2 - v1; Vector3 toHit = hitPos - v1; Vector3 cross = Vector3.Cross(edge, toHit); if (Vector3.Dot(cross, normal) < 0) { inside = false; break; } } if (inside) { selVertex = -1; selEdge = new UnorderedPair <int>(-1, -1); selFace = f; minDist = dist; } } } }