Topologist extensions to Topologic¶
Extensions to topologic_core for ordinary buildings
The Topologic library and its topologic_core python interface models generic non-manifold mesh 3D geometry. This ‘topologist’ module overloads additional functionality onto the topologic_core module that is specific to ordinary buildings. In particular: horizontal and vertical faces are considered to be floors and walls; rooms are spaces with vertical walls on all sides; non-horizontal faces form roofs and/or soffits; and cells are tagged as inside ‘rooms’, voids, or outside spaces.
With this model of what-a-building-is, it is possible to decompose the Topologic CellComplex geometry into ‘traces’ and ‘hulls’ that define building components. Traces are 2D closed or open chains, differentiated by elevation, height and style properties, typically running in an anti-clockwise direction, these follow the outlines of rooms, walls, eaves, string-courses etc. Hulls are 3D open or closed shells, differentiated by style.
Traces are defined using a simple directed-graph implementation, ‘topologist.ugraph’, this only supports linear chains and doesn’t support branching. The traces contain references back to relevant Vertices, Faces and Cells in the original Topologic CellComplex.
Hulls are defined using a simple faceted surface implementation, ‘topologist.ushell’.
Topological relationships between rooms are useful for analysis of the resulting building, this module contains methods for creating Topologic Graph objects representing adjacency and circulation, along with methods for referencing these back-and-forth with the original CellComplex.
This ‘topologist’ module knows nothing about CAD, BIM or IFC, use the ‘molior’ module to convert these traces into something to visualise or solid to build.
Topology¶
Overloads domain-specific methods onto topologic_core.Topology
- topologist.topology.ApplyDictionary(self, source_faces_ptr)¶
Copy Dictionary items from a list of Faces onto this CellComplex
- topologist.topology.Cells_Cached(self, host_topology)¶
List of Cells directly attached to this Topology
- topologist.topology.DumpDictionary(self)¶
Dump string attributes as a python dictionary
- topologist.topology.Elevation(self)¶
Lowest Z-height in this Topology
- topologist.topology.FacesHorizontal(self, faces_ptr)¶
List of horizontal Faces within this Topology
- topologist.topology.FacesInclined(self, faces_ptr)¶
List of inclined Faces within this Topology
- topologist.topology.FacesVertical(self, faces_ptr)¶
List of vertical Faces within this Topology
- topologist.topology.FacesWorld(self, host_topology)¶
List of external world Faces directly attached to this Topology
- topologist.topology.Faces_Cached(self, host_topology)¶
List of Faces directly attached to this Topology
- topologist.topology.Get(self, key)¶
Simple string value dictionary access
- topologist.topology.GraphVertex(self, graph)¶
What Vertex in a given Graph corresponds with this Topology
- topologist.topology.Height(self)¶
Vertical distance between the lowest and highest points in this Topology
- topologist.topology.IndexTopology(self)¶
Index all faces starting at zero
- topologist.topology.Mesh(self)¶
Returns a list of Vertex coordinates, and a list of indexed Faces
- topologist.topology.MeshSplit(self)¶
Returns a list of Vertex coordinates, and indexed faces split by style
- topologist.topology.Set(self, key, value)¶
Simple string value dictionary access
Vertex¶
Overloads domain-specific methods onto topologic_core.Vertex
- topologist.vertex.CoorAsString(self)¶
Stringify the Coordinates of this Vertex
Edge¶
Overloads domain-specific methods onto topologic_core.Edge
- topologist.edge.CellsBelow(self, host_topology)¶
Returns a list of Cells attached below this Edge
- topologist.edge.FaceAbove(self, host_topology)¶
Is there a vertical Face attached above? Returns None or a single Face
- topologist.edge.FacesBelow(self, host_topology)¶
Returns a list of non-horizontal Faces attached below this Edge
- topologist.edge.IsHorizontal(self)¶
Is this Edge horizontal?
- topologist.edge.IsVertical(self)¶
Is this Edge vertical?
- topologist.edge.Length(self)¶
Straight-line distance between start and end Vertex
- topologist.edge.NormalisedVector(self)¶
Vector with a magnitude of 1.0 parallel to this Edge
Face¶
Overloads domain-specific methods onto topologic_core.Face
- topologist.face.AxisOuter(self)¶
2D bottom edge of a vertical Face as a pair of Vertices. Anti-clockwise for external walls
- topologist.face.AxisOuterTop(self)¶
2D top edge of a vertical Face as a pair of Vertices. Anti-clockwise for external walls
- topologist.face.BadNormal(self, cellcomplex)¶
Faces on outside of CellComplex are orientated correctly, but ‘outside’ Faces inside the CellComplex have random orientation. Tags with ‘badnormal’ if the Face doesn’t face ‘out’
- topologist.face.BottomLevelConditions(self, host_topology)¶
Assuming this is a vertical external wall, how do the bottom edges continue? Result is a list of [Edge, condition] pairs
- topologist.face.ByVertices(vertices)¶
Create a Face from an ordered set of Vertices
- topologist.face.CellAbove(self, host_topology)¶
Is this Face a floor for a Cell above? return it
- topologist.face.CellBelow(self, host_topology)¶
Is this Face a ceiling for a Cell below? return it
- topologist.face.CellsBelow(self, host_topology)¶
Returns a list of Cells attached below to a horizontal bottom Edge?
- topologist.face.CellsOrdered(self, host_topology)¶
Front Cell and back Cell, can be [None, None]
- topologist.face.EdgesBottom(self, result_edges_ptr)¶
A list of horizontal edges at the lowest level of this face
- topologist.face.EdgesCrop(self, result_edges_ptr)¶
Which edges are not vertical or top/bottom?
- topologist.face.EdgesTop(self, result_edges_ptr)¶
A list of horizontal edges at the highest level of this face
- topologist.face.FaceAbove(self, host_topology)¶
Is there a vertical Face attached above to a horizontal top Edge? Returns None or a single Face
- topologist.face.FacesBelow(self, host_topology)¶
Returns a list of Faces attached below to a horizontal bottom Edge?
- topologist.face.HorizontalFacesSideways(self, host_topology)¶
Which horizontal faces are attached to the bottom Edges of this Face?
- topologist.face.IsCoplanar(self, face, k=0.01)¶
Check if face is coplanar
- topologist.face.IsExternal(self, host_topology)¶
Is this Face between an inside Cell and outside Cell (or world)?
- topologist.face.IsHorizontal(self)¶
Is this Face horizontal?
- topologist.face.IsInternal(self, host_topology)¶
Is this Face between two inside Cells?
- topologist.face.IsOpen(self, host_topology)¶
Is this Face on the outside of the mesh and adjoining an ‘outside’ Cell?
- topologist.face.IsUpward(self)¶
Does the normal of this Face point up?
- topologist.face.IsVertical(self)¶
Is this Face vertical?
- topologist.face.IsWorld(self, host_topology)¶
Is this Face on the outside of the mesh? i.e. does it adjoin only one Cell?
- topologist.face.Normal(self)¶
A normal for this Face as a three element list, but flipped if this Face is tagged with ‘badnormal’
- topologist.face.ParallelSlice(self, inc=0.45, radians=0.0, origin=[0.0, 0.0])¶
Crop a face with parallel lines. Returns a list of cropped Faces and a list of Edges between them
- topologist.face.Plane(self)¶
Return A, B, C, D plane parameters
- topologist.face.TopLevelConditions(self, host_topology)¶
Assuming this is a vertical external wall, how do the top edges continue?
- topologist.face.VerticesPerimeter(self, vertices_ptr)¶
List of Vertices tracing the outer perimeter of this Face
Cell¶
Overloads domain-specific methods onto topologic_core.Cell
- topologist.cell.CellsAbove(self, topology, result_cells_ptr)¶
Cells (excluding self) connected to horizontal Faces at the top of this Cell
- topologist.cell.CellsBelow(self, topology, result_cells_ptr)¶
Cells (excluding self) connected to horizontal Faces at the bottom of this cell
- topologist.cell.Crinkliness(self, cellcomplex)¶
ExternalWallArea() / PlanArea()
- topologist.cell.ExternalWallArea(self, cellcomplex)¶
Surface area of external vertical Faces
- topologist.cell.FacesBottom(self, result_faces_ptr)¶
List of horizontal Faces at the lowest level of this Cell
- topologist.cell.FacesTop(self, result_faces_ptr)¶
List of horizontal Faces at the highest level of this Cell
- topologist.cell.FacesVerticalExternal(self, cellcomplex, result_faces_ptr)¶
List of vertical external Faces
- topologist.cell.IsOutside(self)¶
Is this Cell outside? i.e. usage is ‘outside’ or ‘sahn’
- topologist.cell.Perimeter(self, host_topology)¶
2D outline of Cell vertical walls, closed, anti-clockwise. Result is a ugraph graph
- topologist.cell.PlanArea(self)¶
Surface area of horizontal Faces at the bottom of this Cell
- topologist.cell.Usage(self)¶
What kind of room or space is this (Type() is taken by Topologic)
- topologist.cell.Volume(self)¶
Volume of this cell, no allowance is made for wall thickness
CellComplex¶
Overloads domain-specific methods onto topologic_core.CellComplex
- topologist.cellcomplex.Adjacency(self)¶
Returns a Topologic adjacency Graph that has nodes for Cells, and nodes for Faces that connect them
- topologist.cellcomplex.AllocateCells(self, widgets)¶
Set Cell types using a list of widgets, or default to ‘living’ (‘void’ when no Perimeter). A widget is any topology (typically a Vertex) with ‘usage’ tagged
- topologist.cellcomplex.FootPrint(self)¶
returns the outline(s) of the cellcomplex at the lowest level
- topologist.cellcomplex.GetHulls(self)¶
Returns a ‘hulls’ dictionary. Hulls are 3D ushell surfaces that define roofs, soffits etc..
- topologist.cellcomplex.GetTraces(self)¶
Returns ‘traces’, ‘normals’ and ‘elevations’ dictionaries. Traces are 2D ugraph paths that define walls, extrusions and rooms. Normals indicate horizontal mitre direction for corners. Elevations indicate a ‘level’ id for each height in the model.
- topologist.cellcomplex.IndexTopology(self)¶
Index all cells and faces starting at zero
Graph¶
Overloads domain-specific methods onto topologic_core.Graph
- topologist.graph.Cells(self, cellcomplex)¶
Return all the Cells from a CellComplex corresponding to this Graph
- topologist.graph.Circulation(self, cellcomplex)¶
Reduce an adjacency Graph to a circulation Graph. Uses heuristics for connecting rooms and floors between stair cells
- topologist.graph.Dot(self, cellcomplex)¶
A generic GraphViz .dot file
- topologist.graph.Faces(self, cellcomplex)¶
Return all the Faces from a CellComplex corresponding to this Graph
- topologist.graph.GetEntity(self, cellcomplex, vertex)¶
Return the entity from a CellComplex (Face or Cell) corresponding to this Vertex)
- topologist.graph.IsConnected(self)¶
Checks that all Vertices can be reached from all other Vertices
- topologist.graph.Separation(self, table, cellcomplex)¶
Tags ‘cell’ vertices with average travel distance to all other cells
- topologist.graph.ShortestPathTable(self)¶
Calculates shortest path distance between all pairs of cells and returns a lookup table
Custom data structures¶
Traces¶
- class topologist.traces.Traces¶
Traces are 2D ugraph paths that define walls, extrusions and rooms
- add_axis(label, elevation, height, stylename, start_vertex=None, end_vertex=None, face=None, front_cell=None, back_cell=None)¶
add an edge defined by two vertices to graph, will split into distinct graphs later
- add_axis_simple(label, elevation, height, stylename, start_vertex=None, end_vertex=None, face=None, front_cell=None, back_cell=None)¶
append a graph consisting of a single edge defined by two vertices
- add_trace(label, elevation, height, stylename, graph=<topologist.ugraph.graph object>)¶
graph is already assembled, append
- process()¶
add_axis() leaves the trace as a single ugraph, split into a list of ugraph paths
Hulls¶
- class topologist.hulls.Hulls¶
Hulls are 3D shells that define planar building elements
- add_face(label, stylename, face=None, front_cell=None, back_cell=None)¶
Add a Topologic Face object, will split to contiguous shells later
- process()¶
add_face() leaves the hull as a single uhull, split into a list of uhull shells
Normals¶
- class topologist.normals.Normals¶
Normals are unit vectors indicating the local vertex orientation. Here they are used to tell walls and extrusions how to mitre properly.
- add_vector(label, vertex, vector)¶
Add a 3D vector to the location defined by a Topologic Vertex
- process()¶
add_vector() increments the magnitude, normalise to 1.0
ugraph¶
- class topologist.ugraph.graph¶
A simple directed graph that only supports linear chains and loops
- add_edge({'C': ['D', 'do']})¶
- edges()¶
Return edges as a list of node pairs
- ends()¶
Return a list of ending nodes
- find_chains()¶
Return a list of open chains as new graph objects. Results are removed from this graph
- find_cycles()¶
Return a list of closed cycles as new graph objects. Results are removed from this graph. This method assumes that find_chains() has already been run
- find_paths()¶
Return result of find_chains() and find_cycles() as a single list
- is_simple_cycle()¶
Does the last node connect to the first node?
- nodes()¶
Return nodes in use
- source_vertices()¶
Return a list of starting nodes that are not ends
- starts()¶
Return a list of starting nodes
ushell¶
- class topologist.ushell.shell¶
A simple append-only 3D shell
- add_facet(node_coors, data)¶
Add a face to this shell
- Args:
node_coors: List of 3D coordinates for the face vertices data: Associated data for the face
- decompose()¶
Identify contiguous regions and return a list of new shells
- Returns:
list: List of shell objects, each representing a contiguous region
- faces_all()¶
Get a list of faces as node ids for export
- nodes_all()¶
Get a list of node coordinates for export
- segment()¶
Utility to allocate index numbers to faces by contiguous region. Uses a breadth-first traversal to identify connected components.
Fitness assessors¶
159 LIGHT ON TWO SIDES OF EVERY ROOM
Problem: When they have a choice, people will always gravitate to those rooms which have light on two sides, and leave the rooms which are lit only from one side unused and empty.
Solution: Locate each room so that it has outdoor space outside it on at least two sides, and then place windows in these outdoor walls so that natural light falls into every room from more than one direction.
Higher patterns: - 106 POSITIVE OUTDOOR SPACE ** - 107 WINGS OF LIGHT ** - 109 LONG THIN HOUSE *
Lower patterns: - 106 POSITIVE OUTDOOR SPACE ** - 180 WINDOW PLACE ** - 192 WINDOWS OVERLOOKING LIFE * - 209 ROOF LAYOUT * - 221 NATURAL DOORS AND WINDOWS ** - 223 DEEP REVEALS - 238 FILTERED LIGHT *
- class topologist.fitness.p159_light_on_two_sides_of_every_room.Assessor(cellcomplex, circulation, shortest_path_table, **settings)¶
An Assessor for 159 LIGHT ON TWO SIDES OF EVERY ROOM
- execute(cell)¶
Evaluate a Cell using ‘crinkliness’ calculation
- external_wall_area(cell)¶
Calculate external wall area of a Cell