public Network(Mesh m, bool Branching = false) : this() { for (int i = 0; i < m.TopologyVertices.Count; ++i) { Node n; if (Branching && m.TopologyVertices.ConnectedTopologyVertices(i).Length == 3) { n = new BranchingNode(); } else if (m.TopologyVertices.ConnectedTopologyVertices(i).Length == 1) { n = new FootNode(); } else { n = new Node(); } MeshPoint mp = m.ClosestMeshPoint(m.TopologyVertices[i], MeshMaxDistance); n.Frame = new Plane(mp.Point, m.NormalAt(mp)); Nodes.Add(n); } for (int i = 0; i < m.TopologyEdges.Count; ++i) { Edge e = new Edge(); e.Ends = m.TopologyEdges.GetTopologyVertices(i); Edges.Add(e); } Edges = new HashSet <Edge>(Edges).ToList(); BuildNodeData(false, false); BuildBranchingData(); }
public void BuildBranchingData() { for (int i = 0; i < Nodes.Count; ++i) { if (Nodes[i] is BranchingNode) { BranchingNode bn = Nodes[i] as BranchingNode; double[] DistValues = new double[bn.Edges.Count]; for (int j = 0; j < bn.Edges.Count; ++j) { for (int k = 0; k < bn.Edges.Count; ++k) { if (j == k) { continue; } double dot = bn.Edges[j].Vector * bn.Edges[k].Vector; DistValues[j] += -dot; } } int index = Array.IndexOf(DistValues, DistValues.Max()); bn.TrunkIndex = index; bn.SortEdgesLR(bn.Frame.ZAxis); Vector3d TrunkProj = bn.Trunk().Vector.ProjectToPlane(bn.Frame); double angle = Vector3d.VectorAngle(bn.Frame.YAxis, TrunkProj); double xangle = bn.Frame.XAxis * TrunkProj; if (xangle < 0) { bn.Frame.Transform(Transform.Rotation(angle, bn.Frame.ZAxis, bn.Frame.Origin)); } else { bn.Frame.Transform(Transform.Rotation(-angle, bn.Frame.ZAxis, bn.Frame.Origin)); } } } }
public Network(List <Line> NetworkLines, Mesh M = null, bool Branching = false) : this() { // Init variables Point3d[] RawPoints = new Point3d[NetworkLines.Count * 2]; int[] RawPointRemapping = new int[NetworkLines.Count * 2]; bool[] RemappingFlags = new bool[NetworkLines.Count * 2]; Tuple <int, int>[] RawEdges = new Tuple <int, int> [NetworkLines.Count]; // Fill raw data lists int ii; for (int i = 0; i < NetworkLines.Count; ++i) { ii = i * 2; RawPoints[ii] = NetworkLines[i].From; RawPoints[ii + 1] = NetworkLines[i].To; RawEdges[i] = new Tuple <int, int>(ii, ii + 1); } // TODO: speed up dupli matching w/ RTree //RTree tree = new RTree(); // Remap vertices to get rid of duplicates List <Point3d> Points = new List <Point3d>(); int Index = 0; for (int i = 0; i < RawPoints.Length; ++i) { if (RemappingFlags[i]) { RemappingFlags[i] = true; continue; } else { RawPointRemapping[i] = Index; Point3d p = RawPoints[i]; Points.Add(p); //MeshPoint mp = M.ClosestMeshPoint(p, 500.0); // Construct node for each point, using Mesh for // node frame construction Node n = new Node(); //n.Frame = new Plane(p, M.NormalAt(mp)); n.Frame = new Plane(p, Vector3d.ZAxis); Nodes.Add(n); } for (int j = i; j < RawPoints.Length; ++j) { if (RemappingFlags[j]) { continue; } if (RawPoints[j].DistanceTo(RawPoints[i]) < NodeMergeDistance) { RawPointRemapping[j] = Index; RemappingFlags[j] = true; } } ++Index; } // Remap edge indices for (int i = 0; i < RawEdges.Length; ++i) { RawEdges[i] = new Tuple <int, int>( RawPointRemapping[RawEdges[i].Item1], RawPointRemapping[RawEdges[i].Item2] ); } // Construct network edges List <Line> NewLines = new List <Line>(); //RawEdges = RawEdges.Distinct(new RawEdgeComparer()).ToArray(); for (int i = 0; i < RawEdges.Length; ++i) { int a = RawEdges[i].Item1; int b = RawEdges[i].Item2; Line l = new Line(Points[a], Points[b]); NewLines.Add(l); Edge e = new Edge(); e.Ends = new IndexPair(a, b); e.Curve = l.ToNurbsCurve(); Edges.Add(e); } if (M != null) { try { if (M.FaceNormals == null || M.FaceNormals.Count < 1) { M.FaceNormals.ComputeFaceNormals(); } if (M.Normals == null || M.Normals.Count < 1) { M.Normals.ComputeNormals(); } foreach (Node n in Nodes) { MeshPoint mp = M.ClosestMeshPoint(n.Frame.Origin, MeshMaxDistance); if (mp == null) { continue; } n.Frame = new Plane(n.Frame.Origin, M.NormalAt(mp)); } } catch { Debug.WriteLine("Something wrong with the mesh..."); } } BuildNodeData(false, true); if (Branching) { for (int i = 0; i < Nodes.Count; ++i) { if (Nodes[i].Edges.Count == 3) { BranchingNode bn = new BranchingNode(); bn.Edges = Nodes[i].Edges; bn.Frame = Nodes[i].Frame; bn.Chains = Nodes[i].Chains; //bn.SortEdgesLR(Nodes[i].Frame.ZAxis); Nodes[i] = bn; } } BuildBranchingData(); } }
public static Network Load(string Path) { if (!System.IO.File.Exists(Path)) { throw new Exception("Network::Load: File does not exist!"); } XDocument doc = XDocument.Load(Path); if (doc == null) { throw new Exception("Network::Load: Failed to load file."); } XElement root = doc.Root; if (root.Name != "network") { throw new Exception("Network::Load: Not a valid Network file."); } Network net = new Network(); XElement nodes = root.Element("nodes"); if (nodes != null) { var node_list = nodes.Elements(); foreach (XElement node in node_list) { if (node.Name != "node") { continue; } Node n; string type = node.Attribute("type").Value; if (type == "FootNode") { n = new FootNode(); } else if (type == "BranchingNode") { n = new BranchingNode(); BranchingNode bn = n as BranchingNode; if (bn == null) { continue; } XElement branch_weights = node.Element("branch_weights"); if (branch_weights != null) { var branch_weight_list = branch_weights.Elements(); foreach (XElement bw in branch_weight_list) { if (bw.Name == "branch_weight") { bn.BranchWeights.Add(Convert.ToInt32(bw.Value)); } } } } else { n = new Node(); } XElement node_edges = node.Element("node_edges"); var edge_list = node_edges.Elements("node_edge"); foreach (XElement ne in edge_list) { double x = Convert.ToDouble(ne.Attribute("vX").Value); double y = Convert.ToDouble(ne.Attribute("vY").Value); double z = Convert.ToDouble(ne.Attribute("vZ").Value); n.Edges.Add(new NodeInterface(new Vector3d(x, y, z), Convert.ToInt32(ne.Attribute("index").Value))); } XElement frame = node.Element("frame"); double fx = Convert.ToDouble(frame.Attribute("PosX").Value); double fy = Convert.ToDouble(frame.Attribute("PosY").Value); double fz = Convert.ToDouble(frame.Attribute("PosZ").Value); double fxx = Convert.ToDouble(frame.Attribute("XX").Value); double fxy = Convert.ToDouble(frame.Attribute("XY").Value); double fxz = Convert.ToDouble(frame.Attribute("XZ").Value); double fyx = Convert.ToDouble(frame.Attribute("YX").Value); double fyy = Convert.ToDouble(frame.Attribute("YY").Value); double fyz = Convert.ToDouble(frame.Attribute("YZ").Value); n.Frame = new Plane(new Point3d(fx, fy, fz), new Vector3d(fxx, fxy, fxz), new Vector3d(fyx, fyy, fyz)); net.Nodes.Add(n); } } XElement edges = root.Element("edges"); if (edges != null) { var edge_list = edges.Elements("edge"); foreach (XElement edge in edge_list) { int i = Convert.ToInt32(edge.Attribute("end1").Value); int j = Convert.ToInt32(edge.Attribute("end2").Value); Edge e = new Edge(); e.Ends = new IndexPair(i, j); net.Edges.Add(e); } } return(net); }
public bool Save(string Path) { XDocument doc = new XDocument(); XElement root = new XElement("network"); XElement edges = new XElement("edges"); for (int i = 0; i < Edges.Count; ++i) { XElement edge = new XElement("edge"); edge.SetAttributeValue("index", i); edge.SetAttributeValue("end1", Edges[i].Ends.I); edge.SetAttributeValue("end2", Edges[i].Ends.J); edges.Add(edge); } XElement nodes = new XElement("nodes"); for (int i = 0; i < Nodes.Count; ++i) { XElement node = new XElement("node"); node.SetAttributeValue("index", i); node.SetAttributeValue("type", Nodes[i].ToString()); XElement node_edges = new XElement("node_edges"); for (int j = 0; j < Nodes[i].Edges.Count; ++j) { XElement node_edge = new XElement("node_edge"); node_edge.SetAttributeValue("index", Nodes[i].Edges[j].Index); node_edge.SetAttributeValue("vX", Nodes[i].Edges[j].Vector.X); node_edge.SetAttributeValue("vY", Nodes[i].Edges[j].Vector.Y); node_edge.SetAttributeValue("vZ", Nodes[i].Edges[j].Vector.Z); node_edge.SetAttributeValue("weight", Nodes[i].Edges[j].Weight); node_edge.SetAttributeValue("user_data", Nodes[i].Edges[j].UserData); node_edges.Add(node_edge); } node.Add(node_edges); XElement frame = new XElement("frame"); frame.SetAttributeValue("PosX", Nodes[i].Frame.OriginX); frame.SetAttributeValue("PosY", Nodes[i].Frame.OriginY); frame.SetAttributeValue("PosZ", Nodes[i].Frame.OriginZ); frame.SetAttributeValue("XX", Nodes[i].Frame.XAxis.X); frame.SetAttributeValue("XY", Nodes[i].Frame.XAxis.Y); frame.SetAttributeValue("XZ", Nodes[i].Frame.XAxis.Z); frame.SetAttributeValue("YX", Nodes[i].Frame.YAxis.X); frame.SetAttributeValue("YY", Nodes[i].Frame.YAxis.Y); frame.SetAttributeValue("YZ", Nodes[i].Frame.YAxis.Z); if (Nodes[i] is BranchingNode) { BranchingNode bn = Nodes[i] as BranchingNode; XElement branch_weights = new XElement("branch_weights"); for (int j = 0; j < bn.BranchWeights.Count; ++j) { XElement branch_weight = new XElement("branch_weight"); branch_weight.SetAttributeValue("index", j); branch_weight.Value = bn.BranchWeights[j].ToString(); branch_weights.Add(branch_weight); } node.Add(branch_weights); } node.Add(frame); nodes.Add(node); } root.Add(edges); root.Add(nodes); doc.Add(root); doc.Save(Path); return(true); }
public static Node Read(XElement elem) { Node n; if (elem.Name != "node") { throw new Exception("XElement is not a valid Node!"); } XAttribute attr; Guid id; attr = elem.Attribute("id"); if (attr != null) { id = Guid.Parse(attr.Value); } attr = elem.Attribute("type"); if (attr == null) { throw new Exception("XElement does not contain a node type!"); } string type = attr.Value; if (type == "FootNode") { n = new FootNode(); } else if (type == "BranchingNode") { n = new BranchingNode(); } else { n = new Node(); } XElement nedges = elem.Element("node_edges"); XElement[] edges = nedges.Elements("node_edge").ToArray(); for (int i = 0; i < edges.Length; ++i) { attr = edges[i].Attribute("index"); if (attr == null) { throw new Exception("NodeInterface needs an index!"); } int index = Convert.ToInt32(attr.Value); double vx, vy, vz; attr = edges[i].Attribute("vX"); if (attr == null) { throw new Exception("NodeInterface is missing part of its vector!"); } vx = Convert.ToDouble(attr.Value); attr = edges[i].Attribute("vY"); if (attr == null) { throw new Exception("NodeInterface is missing part of its vector!"); } vy = Convert.ToDouble(attr.Value); attr = edges[i].Attribute("vZ"); if (attr == null) { throw new Exception("NodeInterface is missing part of its vector!"); } vz = Convert.ToDouble(attr.Value); int w; attr = edges[i].Attribute("weight"); if (attr == null) { throw new Exception("NodeInterface is missing part of its vector!"); } w = Convert.ToInt32(attr.Value); int ud = 0; attr = edges[i].Attribute("user_data"); if (attr != null) { ud = Convert.ToInt32(attr.Value); } NodeInterface ni = new NodeInterface(new Vector3d(vx, vy, vz), index); ni.Weight = w; ni.UserData = ud; n.Edges.Add(ni); } if (n is BranchingNode) { BranchingNode bn = n as BranchingNode; XElement bweights = elem.Element("branch_weights"); if (bweights != null) { XElement[] bw_list = bweights.Elements("branch_weight").ToArray(); for (int i = 0; i < bw_list.Length; ++i) { bn.BranchWeights.Add(Convert.ToInt32(bw_list[i].Value)); } } n = bn; } return(n); }