Keep in mind that not every element has geometry. Some of these elements might only carry information.
Category defines the highest orgasnization level and carries a template for input and output properties of the element. The category list is built into Revit and cannot change.
Family defines the second organized level. Family is like a function f(x), that takes inputs from type and instance parameters, produces metadata, and geometry. The family logic is either built into Revit as System Families e.g. Floors, Walls, and Roofs, or can be defined using Custom Famuilies e.g. Doors and Windows.
Type defines the third organization level. Type also carries value of type parameters. These values are fed in to the Family function to generate the element and calculated type parametes.
Instance carries transform information that places the element in the 2D or 3D space. It also carries values of instance paramters. These values are fed in to the Family function to generate the element and calculated instance parameters.
So practically, we feed type and instance information into the family function, to generate the element metadata(including calculated properties) and geometry.
The generated elements are stored in a Revit Document. They are also organized by a series of Containers.
Subcategories can be think as a property of geometry. When a Family function generates geometry, it can group them into subcategories of the main category.
Elements & Instances
Elements are the basic building block in Revit data model.
Elements have Parameters that hold data associated with Element.
Bulit-in parameters
custom parameters defined by user.
An Element could
has geometry (e.g. Walls(3D), Detail Components(2D))
I set up my blog with some other bloggers’ help. So I think the first post should be the things about how to write a blog with HEXO. After walked throught the intallation parts, there’re only 4 commands I need to rememeber, which I might not.
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
Inorder Tree Traversal without recursion and without stack
Using Morris Travesal, we can traverse the tree without using stack and recursion. The idea of Morris Traversal is based on Threaded Binary Tree.
In this traveral, we first create links to Inorder successor and print the data using these links, and finally revert the changes to restore original tree.
Initalize current as root
While current is not NULL If the current does not have left child
1. Print current's data
2. Go to the right, i.e., current = current->right
Else
Find rightmost node in current left subtree `OR` node whose right child == current
*If*
we found right child == current
Go to the right, i.e. current = current->right
*Else*
1. Make current as the right child of that rightmost node we found; and
2. Go to this left child, i.e., current = current -> current->left
Although the tree is modified through the traversal, it is reverted back to its original shape after the completion. No extra space is required
if(root == NULL) return; current = root; while(current != NULL){ if(current->left == NULL){ printf("%d", current->data); current = current->right; } else{ // Find the inorder predecessor of current pre = current->left; while(pre->right != NULL && pre->right != current) pre = pre->right;
// Make current as the right child of its inorder predecessor if(pre->right == NULL){ pre->right = current; current = current->left; }
// Revert the changes made in the `if` part to restore the original tree i.e., fix the right child of predecessor else{ pre->right = NULL; printf("%d", current->data); current = current->right; } } }
Breath-first search(BFS) is an algorithm for traversing or searching tree or graph data structures. It starts ar the tree root(or some arbitrary node of a graph), and explores all of the neighbor nodes at the present depth prior to moving on to the nodes at the next depth level. -Wiki
Queue Method
Pseudocode
Input: A graph G and a starting vertex root of G Output: Goal state. THe parent links trace the shortest path back to root.
1 2 3 4 5 6 7 8 9
procedure BFS(G, root) is let Q be a queue label root as discovered Q.enqueue(root) while Q is not empty do v := Q.dequeue() if c is the goal then return v for all edges from v to w in G.
The concept can refer to this article, though it is in Japanese. BFS_queue LeetCode_BFS
Typically, we can solve a tree problem recursively using a top-down approach or using a bottom-up approach.
Top-down Solution
Top-down means that in each recursive call, we will visit the node first to come up with some values, and pass these values to its children when calling the function recursively.
So the top-down solution can be consideredd as a kind of preorder travesal. To be specific, the recursive function top-down(root, params) works like this:
return the answer if needed // answers <— left_ans, right_ans
For example - find height of a binary Tree
We know that depth of the root node is 1
For each node, if we know its depth, we will know the depth of its children.
Therefore, if we pass the depth of the node as a parameter when calling the function recursively, all the nodes will know their depth.
return if root is NULL
if root is a leaf node:
answer = max(answer, depth) // update the answer if needed
maximum_depth(root.left, depth + 1)
maximum_depth(root.right, depth+ 1)
1 2 3 4 5 6 7 8 9 10 11
int answer; // don't forget to initialize answer before call maximum_depth voidmaximum_depth(TreeNode* root, int depth){ if (!root) { return; } if (!root->left && !root->right) { answer = max(answer, depth); } maximum_depth(root->left, depth + 1); maximum_depth(root->right, depth + 1); }
Button-up Solution
Button-up is another recursive solution. In each recursive call, we will firstly call the function recursively for all the children nodes and then come up with the answer according to the returned valued and the value of the current node itself. This process can be regraded as a kind of postordered traversal. Typically, a “button-up” recursive function bottom_up(root) will be something like this:
return specific value for null node
left_ans = bottom_up(root.left) // call function recursively for left child
right_ans = bottom_up(root.right) // call function recursively for right child
If we know the maximum depth l of the subtree rooted at its left child and the maximum depth r of the subtree rooted at its right child, can we answer the previous question?
Of course yes, we can choose the maximum between them and add 1 to get the maximum depth of the subtree rooted at the current node. That is x = max(l,r) + 1
return 0 if root is null
left_depth = maximum_depth(root.left)
right_depth = maximum_depth(root.right)
return max(left_depth, right_depth) + 1
1 2 3 4 5 6 7 8
intmaximum_depth(TreeNode* root){ if (!root) { return0; // return 0 for null node } int left_depth = maximum_depth(root->left); int right_depth = maximum_depth(root->right); returnmax(left_depth, right_depth) + 1; // return depth of the subtree rooted at root }