public static Tree CreateTreeFromSceneGraph(SceneGraph graph) { Tree t; Stack <_node> work_items; _node n; int i; _node child; SceneGraphNode childsgn; TNode childtn; SceneGraphNode rootsgn; TNode roottn; _node root; int numNodes; t = new Tree(); rootsgn = graph.GetRoot(); roottn = new TNode(); roottn.Data = rootsgn; root = new _node(roottn, rootsgn); work_items = new Stack <_node>(); work_items.Push(root); numNodes = 0; while (work_items.Count > 0) { n = work_items.Pop(); n.tnode.Level = n.sgn.Depth; numNodes++; for (i = 0; i < n.sgn.Children.Count; i++) { childsgn = n.sgn.Children[i]; childtn = new TNode() { Data = childsgn }; childtn.Parent = n.tnode; childtn.Level = n.sgn.Depth; child = new _node(childtn, childsgn); n.tnode.Children.Add(childtn); work_items.Push(child); } } t.Root = root.tnode; t.Count = numNodes; return(t); }
set => SetProperty(ref _node, value);
/// <summary> /// Serializes an X3D Scene from model back to XML. /// </summary> /// <returns> /// Returns an XML document in a string. /// </returns> public string Serialize() { string xml, chXml; XmlDocument document; _node item, ch, ro; XmlDocument childDoc; SceneGraphNode node; XmlNode parent, p; Stack <_node> work_items = new Stack <_node>(); dynamic instanceOfDerived; XmlTextWriter writer; StreamReader reader; MemoryStream ms; int depth; int maxDepth = 0; XmlNode curr; XmlDocument @new; XmlElement elemp; XmlElement elem; XmlNode n; instanceOfDerived = Activator.CreateInstance(root.GetType()); instanceOfDerived = Clone(instanceOfDerived, root); xml = Serialize(instanceOfDerived); xml = removeXmlTypeDefinition(xml); document = new XmlDocument(); document.LoadXml(xml); ro = new _node() { data = root, dom = document, outerXml = xml, parent = null }; work_items.Push(ro); // X3D SERIALIZE // have to do in 2 passes to join the XmlDocuments since each child is a separate XmlDocument int id = 0; while (work_items.Count > 0) { item = work_items.Pop(); node = item.data; parent = item.dom.FirstChild; elem = (XmlElement)item.dom.FirstChild; elem.SetAttribute(ID_PROPERTY, id.ToString()); // add temporary id to make merging XmlDocuments easier. id++; foreach (dynamic child in node.Children) { childDoc = new XmlDocument(); chXml = removeXmlTypeDefinition(Serialize(child)); childDoc.LoadXml(chXml); p = parent; depth = 0; while (p != null) { depth++; p = p.ParentNode; } if (depth > maxDepth) { maxDepth = depth; } ch = new _node() { data = child, dom = childDoc, outerXml = parent.OuterXml, depth = depth, parent = item }; item.children.Add(ch); work_items.Push(ch); } } // find the deapest node to get all the outer xml work_items.Push(ro); curr = null; @new = new XmlDocument(); @new.AppendChild(@new.CreateNode(XmlNodeType.Element, "X3D", "")); curr = null; // root while (work_items.Count > 0) { item = work_items.Pop(); n = @new.ImportNode(item.dom.FirstChild, true); elem = (XmlElement)n; elemp = item.parent == null ? null : (XmlElement)item.parent.dom.FirstChild; if (curr == null) { curr = @new.FirstChild; } else { string _id = elemp.GetAttribute(ID_PROPERTY); curr = findNodeDfs(_id, @new); elem.RemoveAttribute(ID_PROPERTY); curr.AppendChild(n); } foreach (_node child in item.children) { work_items.Push(child); } } document = @new; // Indent the XML ms = new MemoryStream(); writer = new XmlTextWriter(ms, encoding); writer.Formatting = Formatting.Indented; document.WriteContentTo(writer); writer.Flush(); ms.Flush(); ms.Position = 0; reader = new StreamReader(ms); xml = reader.ReadToEnd(); return(xml); }