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