public void ReloadFromData(SplineCanvasData data) { // Clear everything Reset(); bulbs.Clear(); foreach (BulbData bData in data.bulbs) { // Make bulbs at all the saved positions with the saved radii DraggablePoint pt = AddBulb(bData.position.GetVector()); pt.SetSize(bData.radius); pt.containingCanvas = this; if (bData.type == PointType.Spline) { pt.SwitchBulbType(PointType.Bulb); } else { pt.SwitchBulbType(bData.type); } } foreach (SplineData sData in data.splines) { // Convert the serialized vectors to Unity vectors List <Vector3> posList = new List <Vector3>(); foreach (V3Serialize v3s in sData.points) { posList.Add(v3s.GetVector()); } // Make a spline with the same control points CatmullRomSpline spline = CatmullRomSpline.SplineOfPoints(posList); AddExistingSpline(spline); // Set the begin/end bulbs if (sData.startBulb >= 0) { spline.StartBulb = bulbs[sData.startBulb]; } if (sData.endBulb >= 0) { spline.EndBulb = bulbs[sData.endBulb]; } } }
public void ReplaceWithBulb(int index) { // Do nothing if this is an endpoint -- we can only insert // a bulb at an interior point. if (index <= 1) { return; } if (index >= points.Count - 2) { return; } List <Vector3> beforePoints = new List <Vector3>(); List <Vector3> afterPoints = new List <Vector3>(); // We want to copy all of the points up to the split position, // and make a new spline out of that. for (int i = 0; i < index; i++) { beforePoints.Add(points[i]); } // Add the split position as the last point beforePoints.Add(points[index]); // Add the last tangent handle as a point farther down the spline Vector3 middleBefore = sample(index + 0.5f); beforePoints.Add(middleBefore); // We also want to make a new spline of all the points // starting after the split position. // Add first tangent handle as coming before the split Vector3 middleAfter = sample(index - 0.5f); afterPoints.Add(middleAfter); // Add the split position as the first point afterPoints.Add(points[index]); for (int i = index + 1; i < points.Count; i++) { afterPoints.Add(points[i]); } // Make the splines CatmullRomSpline before = SplineOfPoints(beforePoints); containingCanvas.AddExistingSpline(before); CatmullRomSpline after = SplineOfPoints(afterPoints); containingCanvas.AddExistingSpline(after); // Connect splines to the bulb we just added DraggablePoint bulb = containingCanvas.AddBulb(points[index]); before.StartBulb = StartBulb; before.EndBulb = bulb; after.StartBulb = bulb; after.EndBulb = EndBulb; bulb.SetSize(0.1f); // Delete the current spline that was split containingCanvas.DeleteSpline(this); Destroy(gameObject); }
void DepthFirstSearch(int initial) { GetCanvas(); bool[] visited = new bool[heMesh.Vertices.Length]; int numVisited = 0; foreach (bool b in visited) { if (b) { numVisited++; } } Debug.Log("Initial " + numVisited + " / " + visited.Length); Stack <IntPair> dfsStack = new Stack <IntPair>(); dfsStack.Push(new IntPair(initial, initial)); // Keep track of the current chain of points List <int> currentPoints = null; Dictionary <int, DraggablePoint> bulbDict = new Dictionary <int, DraggablePoint>(); DraggablePoint bulbAtStart = null; while (dfsStack.Count > 0) { IntPair nextPair = dfsStack.Pop(); int next = nextPair.num; if (visited[next]) { continue; } HashSet <int> equivClass = uf.Find(next).MergedPoints; // Mark this point and all points merged with it as visited foreach (int p in equivClass) { visited[p] = true; } // Add all neighbors of this point to the list // if they haven't been visited already HashSet <int> neighbors = adjacency[next]; foreach (int neighbor in neighbors) { if (!visited[neighbor]) { dfsStack.Push(new IntPair(neighbor, next)); } } // If this is the first point, start a new line segment. if (currentPoints == null) { Vector3 pos = transform.rotation * mesh.vertices[next] + transform.position; bulbAtStart = outputCanvas.AddBulb(pos); //bulbAtStart.SetSize(FitSphere(mesh.vertices[next])); bulbAtStart.SetSize(0.1f); bulbDict.Add(next, bulbAtStart); currentPoints = new List <int>(); currentPoints.Add(next); } // If this point has degree 2 (i.e. is a part of a straight line segment) // then just continue the current segment. else if (neighbors.Count == 2) { currentPoints.Add(next); } // If this point has degree 1, then we just end the current segment. else if (neighbors.Count == 1) { currentPoints.Add(next); // Can filter out single dead-ends to try to remove noise //if (currentPoints.Count > 2) CatmullRomSpline spline = AddLine(currentPoints); spline.StartBulb = bulbAtStart; // Start a new segment at the predecessor of the most recent branch point. currentPoints = new List <int>(); if (dfsStack.Count > 0) { currentPoints.Add(dfsStack.Peek().predecessor); DraggablePoint bulb; if (bulbDict.TryGetValue(dfsStack.Peek().predecessor, out bulb)) { bulbAtStart = bulb; } else { bulbAtStart = null; } } } // If the point has degree greater than 2, then it is a branch, and we // start a new segment at the current point. else { Vector3 pos = transform.rotation * mesh.vertices[next] + transform.position; DraggablePoint bulb = outputCanvas.AddBulb(pos); //bulb.SetSize(FitSphere(mesh.vertices[next])); bulb.SetSize(0.1f); bulbDict.Add(next, bulb); currentPoints.Add(next); CatmullRomSpline spline = AddLine(currentPoints); spline.EndBulb = bulb; spline.StartBulb = bulbAtStart; // New segments should start at the bulb we just inserted. bulbAtStart = bulb; currentPoints = new List <int>(); currentPoints.Add(next); } } numVisited = 0; foreach (bool b in visited) { if (b) { numVisited++; } } Debug.Log("Visited " + numVisited + " / " + visited.Length); }