-
Notifications
You must be signed in to change notification settings - Fork 5
Home
Welcome to the DynamoUnfold wiki!
##current branches/development##
DynamoUnfold Status
Development is currently on branch: naive unroll, this will be merged to master soon, changes include:
- fixed bug labeling scaled or translated surfaces
- introduced tab generation method
- new method for finding ruling lines of singly curved surface
- cleaned up leaky tests that crash on ASM 220/221
when this branch is merged I will produce a new package .02
####'Working' Features - Referencing Version of Library on Package Manager as of Jan 13. - 0.01
- unfold a list of planar faces
- unfold a list of planar surfaces
- generate labels on initial surfaces ( labels are simply an index number for each surface made of geometry (lines or curves))
- generate labels on unfolded surfaces
- merge multiple unfolds so that can be labeled and packed together, won't actually merge any geometry - this is useful if you produce a set of unfolds by mapping or replicating and want to pack all the resulting unfolds together with no repeating labels. (Zach's Sphere example) does not yet work with tabs
- Successfully cleans up intermediate geometry and doesn't crash on Revit 2015 ASM 220
- use ASM's tessellation to transform surface into set of triangular surfaces (trimmed surfaces)
####Existing Nodes(current nodes should be refined, some intenal should be removed) Looking for feedback on this API!!
- unfold List of Faces and Return Transforms
- unfold List of Surfaces and Return Transforms
- unfold List of Faces
- unfold List of Surfaces
- Generate Initial Labels
- Generate Unfolded Labels
- Pack Unfolded Surfaces
- Merge UnfoldObjects
Nodes that are currently exposed which are should possibly be removed
- UnfoldCurvedSurfacesByTessellation
- BFSTestTessellation
- DebugGeoFromGraph
- BFSTestNoGeometryGeneration
- TessellateSurfaces currently required
- Generate Tabs
- finding intermediate geometry that has arisen beause of work in progress
- writing tests for transformation bug and tabs
- singly curved surface (developable) unrolling and ruling line finding
###Library overview... How To Find Your Way Around! This solution is split into 3 projects:
- The unfold project (contains the actual methods that analyze,unfold,and pack the sets of surfaces)
- The unfold tests project (contains methods that use the unfolding methods without Dynamo interaction and test for correct unfold results)
- DynamoUnfold project, is a set of functions that are loaded as nodes into Dynamo, these nodes call generic functions in the unfold library with types set. This is the .dll that is imported into Dynamo to display unfold nodes.
###Unfold Project###
####Topology#### This namespace contains a set of classes and methods for building a graph that represents the topology of a set of surfaces or faces. The graph is represented by an adjacency list structure of nodes,(GraphVertex), these nodes represent some face or surface and are connected by arcs(GraphEdge), representing some shared edge between faces.
A graph is simply a list of GraphVertex, List<Graphvertex>.
Facelike and EdgeLike entities are wrappers around faces/surfaces and edges/curves. These simply point to some geometry object and also store some properties about them, like perimeter curves, or start/end points.
The ModelTopology class is the entry point for building a topology graph of some set of faces or surfaces. It walks a list of surfaces or faces, building a dictionary from each edgelike to the facelike that it belongs. We then use this dictionary to detect shared edges or to find the adjacent faces of a particular face by looking at all of its edges. Then a graph is built from the facelikes, a graphedge points from each facelike to its adjacent faces. This graph most likely has loops or cycles. Edges are equated as equal by looking at their start and end points, this is important to be aware of.
//IMAGE//
The last important algorithm in this section is an implementation of Breadth First Search that walks the topology graph and returns the search tree, this tree will not have any loops. This tree is used for the actual unfolding. Each edge in this tree is an edge we'll fold over.
There is also a tessellation class, these methods rely on Dynamo Core, they use Dynamo's visualization tessellation methods to tessellate curved surfaces into sets of triangular trimmed surfaces to be unfolded, this is very inefficient but lets a user experiment with different tessellation tolerances and lets the unfold algorithm work on curved surfaces.
####AlignPlanarFaces#### The purpose of this class is a set of methods for determining the required rotation in degrees to make one face coplanar with another for which it shares an edge. We operate on a parent face, that stays in place, a child face that will be rotated, and the shared edge between them we wish to rotate around.
/////IMAGE//////
The main method in this class is GetCoplanarRotation(). We use Atan2() of the shared edge length and the dot product of the normals of the two faces. The algorithm would be trivial except in the case that the surface normal is pointing reverse from what is expected, this would give us an incorrect rotation. To look out for this condition we use the method CheckNormalConsistency() between the parent face, and the child face.
####GraphUtilities#### misc. graph methods... This is a utilities class of methods for finding geometry edges and faces in the topology graph, cloning a graph, and there is also an implementation of Tarjan's strongly connceted component algorithm which is used for looking for cycle detection. (used for testing)
####Packing#### This class is responsible for packing the bounding boxes of facelikes (which may represent many coplanar surfaces) into an overall bounding box of a specific size. This relies on the DynamoPack library which is built on Nuclex Framework's CygonRectanglePacker.
###PlanarUnfolder!### This class is quite large! It may be split into multiple parts later. Currently this class defines the method that performs unfolding, PlanarUnfold(). This method takes a list of graph verticies, but the graph must be a tree for the unfold to work. Each edge in the tree is a shared edge that we rotate a face or list of faces around.
Unfolding algorithm pseudocode:
Once an unfolding tree is found, one can rotate the leaves of the tree to be coplanar with their parents, merging those coplanar faces together and doing this iteratively until all the faces in the tree are coplanar. The leaves of the tree are just the faces in the tree that have no children of their own. The unfolding algorithm is this simple process. The rotation is done two graph vertices at a time, and as the faces become merged together we rotate those merged faces as if they were one at all future steps in the unfold. At each step we must calculate the angle between two surfaces, the child and its parent.
Explicity the steps are:
- find a leaf in the tree – this is a face we’ll fold, that has no folds after it, call this the child
- find this face’s parent – the parent represents the face we need to make the child coplanar with.
- find the edge that points from the parent face to the child, this edge represents the edge we’ll rotate around, the fold edge or shared edge.
- rotate the child to be coplanar with the parent.
- check if this rotation caused any overlaps to occur with previously unfolded faces.
- if not, then join the parent and child surface into a polysurface and store this polysurface in the tree node that used to represent the parent face.
- remove the child node from the tree – this is a contraction of the parent and child nodes into one node.
- repeat until there is only one node left in the tree.
This process outlined above is almost the entire story. There’s a bit more that happens if there is an overlap. If an overlap occurs during the unfold we take a step back, leaving the current unfolded set of faces where they are, they are all coplanar to each other, so we break them off as a seperate chunk of the unfold, and move on to another leaf which we'll try to fold all the way up to the root of the tree.
I've also removed polysurfaces from this library in recent branches and instead just keep a list of surfaces.
#####Auxillary classes:#####
FaceTransformMap : to track the faces as they are joined together and rotated through the unfold we assign an ID to each orginal face before the unfold begins. This class keeps track of a set of IDS and what transformation was performed on that set of IDS. This might be a rotation, or a translation. This class is necessary because the Dynamo geometry library always returns a new piece of geometry when performing any transformation, as opposed to modifying a geometry object. Also, as faces become merged during the unfold, we want to keep track of which ones are grouped together.
PlanarUnfolding : this class represents a single unfolding operation. It stores the unfolded surfaces, the face transformation maps, and the original topology graph that was used for the unfold. Primarily, this class is used to keep track of everything about an unfold operation, relating the transformations that occured during the unfold, to the final surfaces, we can use this information to label the unfold, or generate tabs for the unfold. In general this can be used to put some geometry at the final location of a specific surface after it's unfolded., see the generate label and tab methods
UnfoldableFaceLabel : this class represents some facelike label, it holds an ID and generates text in the form of simple line geometry from the ID so that labels can be exported along with unfold geometry. see the generate label
###Testing### kind of painful to get setup right now, requires building Dynamo, notes in readme.md