// returns true on success internal static bool RemoveNode(HierarchyItem node, ParentNodeData top) { if (node.Parent == null) { //Debug.Log("parent == null"); return(false); } // on each level remove self from parent. // if it doesn't have any childNodes left, remove itself from it's parent var iterator = node; do { var parent = iterator.Parent; if (parent == null) { break; } parent.RemoveChildItem(iterator); iterator = parent; } while (iterator.ChildNodes.Length == 0); node.Parent = null; top.ChildrenModified = true; return(true); }
internal bool AddChildItem(HierarchyItem item) { int index; if (FindSiblingIndex(item, out index)) { // The transform is already in the array? return(false); } var currentLoopCount = CurrentLoopCount; if (item.LastLoopCount != currentLoopCount) { item.CachedTransformSiblingIndex = item.Transform.GetSiblingIndex(); item.LastLoopCount = currentLoopCount; } if (FindSiblingIndex(item.Transform, item.CachedTransformSiblingIndex, item.TransformID, out index)) { //Debug.Log("found transform, but should be impossible"); return(false); } // make sure item is added in the correct position within the array UnityEditor.ArrayUtility.Insert(ref ChildNodes, index, item); item.SiblingIndex = index; bool childrenModified = false; for (int i = index + 1; i < ChildNodes.Length; i++) { if (ChildNodes[i].SiblingIndex != i) { ChildNodes[i].SiblingIndex = i; childrenModified = true; } } if (childrenModified) { var parentData = this as ParentNodeData; if (parentData != null) { parentData.ChildrenModified = true; } } //var builder = new System.Text.StringBuilder(); //for (int i = 0; i < childNodes.Length; i++) //{ // if (builder.Length != 0) // builder.Append(", "); // builder.Append(childNodes[i].nodeIndex); //} //Debug.Log("adding " + item.transform.name +"(" + item.nodeIndex + ") at " + index + " of " + this.transform.name + " now " + builder.ToString()); Debug.Assert(ChildNodes[index] == item); return(true); }
static Int32[] UpdateChildList(HierarchyItem top) { var ids = new List <int>(); { var parents = new List <TreePosition> { new TreePosition(top) }; while (parents.Count > 0) { var parent = parents[parents.Count - 1]; parents.RemoveAt(parents.Count - 1); var children = parent.item.ChildNodes; for (var i = parent.index; i < children.Length; i++) { var node = children[i]; var nodeID = node.NodeID; if (nodeID == CSGNode.InvalidNodeID) { var operation = node.Transform ? node.Transform.GetComponent <CSGOperation>() : null; if (operation) { if (operation.operationNodeID != CSGNode.InvalidNodeID) { nodeID = node.NodeID = operation.operationNodeID; } } if (nodeID == CSGNode.InvalidNodeID) { if (node.ChildNodes.Length > 0) { var next_index = i + 1; if (next_index < children.Length) { parent.index = next_index; parents.Add(parent); } parents.Add(new TreePosition(node)); break; } continue; } } ids.Add(nodeID); if (node.PrevSiblingIndex != node.SiblingIndex) { External.SetDirty(nodeID); node.PrevSiblingIndex = node.SiblingIndex; } } } } return(ids.ToArray()); }
public virtual void Reset() { Transform = null; TransformID = 0; Parent = null; PrevSiblingIndex = -1; SiblingIndex = -1; NodeID = -1; ChildNodes = new HierarchyItem[0]; LastLoopCount = -1; CachedTransformSiblingIndex = 0; }
internal static bool AddChildItem(this HierarchyItem self, HierarchyItem item) { int index; if (self.FindSiblingIndex(item, out index)) { // The transform is already in the array? return(false); } var currentLoopCount = HierarchyItem.CurrentLoopCount; if (item.LastLoopCount != currentLoopCount) { item.CachedTransformSiblingIndex = item.Transform.GetSiblingIndex(); item.LastLoopCount = currentLoopCount; } if (self.FindSiblingIndex(item.Transform, item.CachedTransformSiblingIndex, item.TransformID, out index)) { return(false); } // make sure item is added in the correct position within the array UnityEditor.ArrayUtility.Insert(ref self.ChildNodes, index, item); item.SiblingIndex = index; /* * bool childrenModified = false; * for (int i = index + 1; i < ChildNodes.Length; i++) * { * if (ChildNodes[i].SiblingIndex != i) * { * ChildNodes[i].SiblingIndex = i; * childrenModified = true; * } * } * if (childrenModified)*/ { var parentData = self as ParentNodeData; if (parentData != null) { parentData.ChildrenModified = true; } } Debug.Assert(self.ChildNodes[index] == item); return(true); }
internal bool RemoveChildItem(HierarchyItem item) { int index; if (!FindSiblingIndex(item, out index)) { // The transform is not in the array? return(false); } // make sure item is removed from the array UnityEditor.ArrayUtility.RemoveAt(ref ChildNodes, index); //item.siblingIndex = -1; return(true); }
public static IEnumerable <HierarchyItem> IterateChildrenDeep(this HierarchyItem self) { for (var i = 0; i < self.ChildNodes.Length; i++) { var childNode = self.ChildNodes[i]; yield return(childNode); if (childNode.ChildNodes.Length == 0) { continue; } foreach (var item in childNode.IterateChildrenDeep()) { yield return(item); } } }
static void SetNodeParent(ChildNodeData childData, HierarchyItem hierarchyItem, CSGOperation parentOp, CSGModel parentModel) { var oldParentData = childData.OwnerParentData; childData.Parent = parentOp; childData.Model = parentModel; var newParentData = GetParentData(childData); if (oldParentData != newParentData) { if (oldParentData != null) { oldParentData.RemoveNode(hierarchyItem); } if (newParentData != null) { newParentData.AddNode(hierarchyItem); } childData.OwnerParentData = newParentData; childData.ModelTransform = (!childData.Model) ? null : childData.Model.transform; } }
internal static bool FindSiblingIndex(this HierarchyItem self, HierarchyItem item, out int index) { if (self.ChildNodes == null || self.ChildNodes.Length == 0) { index = 0; return(false); } for (var i = 0; i < self.ChildNodes.Length; i++) { if (item != self.ChildNodes[i]) { continue; } index = i; return(true); } index = 0; return(false); }
internal bool FindSiblingIndex(HierarchyItem item, out int index) { if (ChildNodes == null || ChildNodes.Length == 0) { //Debug.Log("childNodes == null || childNodes.Length == 0", Transform); index = 0; return(false); } for (var i = 0; i < ChildNodes.Length; i++) { if (item != ChildNodes[i]) { continue; } index = i; return(true); } index = 0; return(false); }
// returns true when modified internal static bool UpdateNodePosition(HierarchyItem node, ParentNodeData top) { // on each level, compare sibling position to nodes before and after it. // if it's different, remove self and find new position in array. // continue to next parent. var iteratorParent = node.Parent; if (iteratorParent == null) { AddNode(node, top); top.ChildrenModified = true; return(true); } var currentLoopCount = CurrentLoopCount; var iterator = node; while (iteratorParent != null) { var iteratorTransformID = iterator.TransformID; if (iteratorTransformID == 0) { Debug.Log("iterator_transform == null"); } else if (iterator.LastLoopCount != currentLoopCount) { var iteratorTransform = iterator.Transform; var iteratorParentTransformID = iteratorTransform.parent == null ? 0 : iteratorTransform.parent.GetInstanceID(); // Compare the unity parent transform to the stored parent transform if (iteratorParent.TransformID != iteratorParentTransformID) { var defaultCSGInstanceID = 0; var defaultCSGModel = InternalCSGModelManager.GetDefaultCSGModelForObject(iteratorTransform); if (defaultCSGModel != null && defaultCSGModel.transform != null) { defaultCSGInstanceID = defaultCSGModel.transform.GetInstanceID(); } if (defaultCSGInstanceID == 0 || defaultCSGInstanceID != iteratorParent.TransformID) { RemoveNode(node, top); AddNode(node, top); top.ChildrenModified = true; return(true); } } if (iterator.LastLoopCount != currentLoopCount) { iterator.CachedTransformSiblingIndex = iteratorTransform.GetSiblingIndex(); iterator.LastLoopCount = currentLoopCount; } // Does the child even exist in the parent transform? int iteratorChildIndex; if (!iteratorParent.FindSiblingIndex(iteratorTransform, iterator.CachedTransformSiblingIndex, iteratorTransformID, out iteratorChildIndex)) { RemoveNode(node, top); AddNode(node, top); top.ChildrenModified = true; return(true); } // See if the position of the child has changed .. if (iteratorChildIndex != iterator.SiblingIndex) { iterator.SiblingIndex = iteratorChildIndex; RemoveNode(node, top); AddNode(node, top); top.ChildrenModified = true; return(true); } // Compare the child index to the one before and after it .. var iteratorParentChildNodes = iteratorParent.ChildNodes; var iteratorSiblingIndex = iteratorTransform.GetSiblingIndex(); if (iteratorChildIndex > 0) { var prevTransform = iteratorParentChildNodes[iteratorChildIndex - 1].Transform; if (!prevTransform) { return(false); } var iteratorPrevSiblingIndex = prevTransform.GetSiblingIndex(); if (iteratorPrevSiblingIndex >= iteratorSiblingIndex) { RemoveNode(node, top); AddNode(node, top); top.ChildrenModified = true; return(true); } } else if (iteratorChildIndex < iteratorParentChildNodes.Length - 1) { var nextTransform = iteratorParentChildNodes[iteratorChildIndex + 1].Transform; if (!nextTransform) { return(false); } var iteratorNextSiblingIndex = nextTransform.GetSiblingIndex(); if (iteratorNextSiblingIndex <= iteratorSiblingIndex) { RemoveNode(node, top); AddNode(node, top); top.ChildrenModified = true; return(true); } } } iterator = iteratorParent; iteratorParent = iterator.Parent; } return(false); }
public bool RemoveNode(HierarchyItem hierarchyItem) { return(RemoveNode(hierarchyItem, this)); }
public bool AddNode(HierarchyItem hierarchyItem) { return(AddNode(hierarchyItem, this)); }
// returns true on success internal static bool AddNode(HierarchyItem node, ParentNodeData top) { if (node.Parent != null) { //Debug.Log("node.parent != null"); return(false); } if (!top.Transform) { // var top_transform_name = (top.transform == null) ? "null" : top.transform.name; // var node_transform_name = (node.transform == null) ? "null" : node.transform.name; // Debug.Log("!top.transform (top.transform=" + top_transform_name + ", node.transform = " + node_transform_name + ")", node.transform); return(false); } var ancestors = new List <Transform>(); var leafTransform = node.Transform; if (leafTransform == null) { //Debug.Log("node.transform == null"); return(false); } var iterator = leafTransform.parent; while (iterator != null && iterator != top.Transform) { ancestors.Add(iterator); iterator = iterator.parent; } var defaultModel = InternalCSGModelManager.GetDefaultCSGModelForObject(iterator); if (!defaultModel) { return(false); } var defaultModelTransform = defaultModel.transform; if (iterator == null || top.Transform == null || top.Transform == defaultModelTransform) { iterator = defaultModelTransform; } if (iterator == null) { node.Reset(); top.Reset(); //Debug.Log("iterator == null"); return(false); } if (iterator != top.Transform) { //Debug.Log("iterator != top.transform"); return(false); } // var currentLoopCount = CurrentLoopCount; HierarchyItem lastParent = top; var ancestorDepth = ancestors.Count - 1; while (ancestorDepth >= 0) { var ancestor = ancestors[ancestorDepth]; int childIndex; if (!lastParent.FindSiblingIndex(ancestor, ancestor.GetSiblingIndex(), ancestor.GetInstanceID(), out childIndex)) { break; } lastParent = lastParent.ChildNodes[childIndex]; ancestorDepth--; } while (ancestorDepth >= 0) { var newAncestor = new HierarchyItem(); newAncestor.Transform = ancestors[ancestorDepth]; newAncestor.TransformID = newAncestor.Transform.GetInstanceID(); newAncestor.Parent = lastParent; if (!lastParent.AddChildItem(newAncestor)) { return(false); } lastParent = newAncestor; ancestorDepth--; } node.Parent = lastParent; top.ChildrenModified = true; return(lastParent.AddChildItem(node)); }
public static void Init(this HierarchyItem self, CSGNode node, Int32 nodeID) { self.Transform = node.transform; self.TransformID = node.transform.GetInstanceID(); self.NodeID = nodeID; }
public TreePosition(HierarchyItem _item) { item = _item; index = 0; }
internal static bool FindSiblingIndex(this HierarchyItem self, Transform searchTransform, int siblingIndex, int searchTransformID, out int index) { if (self.ChildNodes == null || self.ChildNodes.Length == 0) { index = 0; return(false); } var checkIndex = siblingIndex; var last = self.ChildNodes.Length - 1; var currentLoopCount = HierarchyItem.CurrentLoopCount; if (self.ChildNodes[last].LastLoopCount != currentLoopCount) { if (self.ChildNodes[last].Transform != null && self.ChildNodes[last].Transform) { self.ChildNodes[last].CachedTransformSiblingIndex = self.ChildNodes[last].Transform.GetSiblingIndex(); } else { self.ChildNodes[last].CachedTransformSiblingIndex = -1; } self.ChildNodes[last].LastLoopCount = currentLoopCount; } if (self.ChildNodes[last].CachedTransformSiblingIndex < checkIndex) { index = self.ChildNodes.Length; return(false); } // continue searching while [imin,imax] is not empty var imin = 0; var imax = last; while (imin <= imax) { // calculate the midpoint for roughly equal partition var imid = (imin + imax) / 2; if (self.ChildNodes[imid].LastLoopCount != currentLoopCount) { if (self.ChildNodes[imid].Transform != null && self.ChildNodes[imid].Transform) { self.ChildNodes[imid].CachedTransformSiblingIndex = self.ChildNodes[imid].Transform.GetSiblingIndex(); } else { self.ChildNodes[imid].CachedTransformSiblingIndex = -1; } self.ChildNodes[imid].LastLoopCount = currentLoopCount; } var midKey2 = self.ChildNodes[imid].CachedTransformSiblingIndex; // determine which subarray to search if (midKey2 < checkIndex) { // change min index to search upper subarray imin = imid + 1; } else { if (midKey2 == checkIndex) { // key found at index imid index = imid; return(searchTransformID == self.ChildNodes[imid].TransformID); } if (imid > 0) { if (self.ChildNodes[imid - 1].LastLoopCount != currentLoopCount) { if (self.ChildNodes[imid - 1].Transform != null && self.ChildNodes[imid - 1].Transform) { self.ChildNodes[imid - 1].CachedTransformSiblingIndex = self.ChildNodes[imid - 1].Transform.GetSiblingIndex(); } else { self.ChildNodes[imid - 1].CachedTransformSiblingIndex = -1; } self.ChildNodes[imid - 1].LastLoopCount = currentLoopCount; } var midKey1 = self.ChildNodes[imid - 1].CachedTransformSiblingIndex; if (midKey1 < checkIndex) { // key found at index imid index = imid; return(searchTransformID == self.ChildNodes[imid].TransformID); } } // change max index to search lower subarray imax = imid - 1; } } index = 0; return(false); }
public static bool RemoveNode(this ParentNodeData parentNodeData, HierarchyItem hierarchyItem) { return(RemoveNode(hierarchyItem, parentNodeData)); }
// returns true on success internal static bool AddNode(HierarchyItem node, ParentNodeData top) { if (node.Parent != null) { return(false); } if (!top.Transform) { return(false); } var ancestors = new List <Transform>(); var leafTransform = node.Transform; if (leafTransform == null) { return(false); } var iterator = leafTransform.parent; while (iterator != null && iterator != top.Transform) { ancestors.Add(iterator); iterator = iterator.parent; } var defaultModel = InternalCSGModelManager.GetDefaultCSGModelForObject(iterator); if (!defaultModel) { return(false); } var defaultModelTransform = defaultModel.transform; if (iterator == null || top.Transform == null || top.Transform == defaultModelTransform) { iterator = defaultModelTransform; } if (iterator == null) { node.Reset(); top.Reset(); return(false); } #if !UNITY_2018_3_OR_NEWER // TODO: figure out how to check this, yet still support prefab isolation mode if (iterator != top.Transform) { return(false); } #endif //var currentLoopCount = CurrentLoopCount; HierarchyItem lastParent = top; var ancestorDepth = ancestors.Count - 1; while (ancestorDepth >= 0) { var ancestor = ancestors[ancestorDepth]; int childIndex; if (!lastParent.FindSiblingIndex(ancestor, ancestor.GetSiblingIndex(), ancestor.GetInstanceID(), out childIndex)) { break; } lastParent = lastParent.ChildNodes[childIndex]; ancestorDepth--; } while (ancestorDepth >= 0) { var newAncestor = new HierarchyItem(); newAncestor.Transform = ancestors[ancestorDepth]; newAncestor.TransformID = newAncestor.Transform.GetInstanceID(); newAncestor.Parent = lastParent; if (!lastParent.AddChildItem(newAncestor)) { return(false); } lastParent = newAncestor; ancestorDepth--; } node.Parent = lastParent; top.ChildrenModified = true; return(lastParent.AddChildItem(node)); }