topologicpy 0.7.17__py3-none-any.whl → 0.7.18__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
topologicpy/Cell.py CHANGED
@@ -377,6 +377,8 @@ class Cell():
377
377
  If set to True, the last wire in the list of input wires will be connected to the first wire in the list of input wires. The default is False.
378
378
  triangulate : bool , optional
379
379
  If set to True, the faces will be triangulated. The default is True.
380
+ planarize : bool, optional
381
+ If set to True, the created faces are planarized before building the cell. Otherwise, they are not. The default is False.
380
382
  mantissa : int , optional
381
383
  The desired length of the mantissa. The default is 6.
382
384
  tolerance : float , optional
@@ -908,7 +910,7 @@ class Cell():
908
910
  from topologicpy.Topology import Topology
909
911
 
910
912
  def angleCode(f, up, tiltAngle):
911
- dirA = Face.NormalAtParameters(f)
913
+ dirA = Face.Normal(f)
912
914
  ang = round(Vector.Angle(dirA, up), 2)
913
915
  if abs(ang - 90) < tiltAngle:
914
916
  code = 0
@@ -467,7 +467,7 @@ class CellComplex():
467
467
  from topologicpy.Topology import Topology
468
468
 
469
469
  def angleCode(f, up, tiltAngle):
470
- dirA = Face.NormalAtParameters(f)
470
+ dirA = Face.Normal(f)
471
471
  ang = round(Vector.Angle(dirA, up), 2)
472
472
  if abs(ang - 90) < tiltAngle:
473
473
  code = 0
topologicpy/Face.py CHANGED
@@ -131,8 +131,8 @@ class Face():
131
131
  if not Topology.IsInstance(faceB, "Face"):
132
132
  print("Face.Angle - Warning: The input faceB parameter is not a valid topologic face. Returning None.")
133
133
  return None
134
- dirA = Face.NormalAtParameters(faceA, 0.5, 0.5, "xyz", 3)
135
- dirB = Face.NormalAtParameters(faceB, 0.5, 0.5, "xyz", 3)
134
+ dirA = Face.Normal(faceA, outputType="xyz", mantissa=3)
135
+ dirB = Face.Normal(faceB, outputType="xyz", mantissa=3)
136
136
  return round((Vector.Angle(dirA, dirB)), mantissa)
137
137
 
138
138
  @staticmethod
@@ -439,7 +439,9 @@ class Face():
439
439
  if not Topology.IsInstance(wire, "Wire"):
440
440
  print("Face.ByThickenedWire - Error: The input wire parameter is not a valid wire. Returning None.")
441
441
  return None
442
-
442
+ if not Wire.IsManifold(wire):
443
+ print("Face.ByThickenedWire - Error: The input wire parameter is not a manifold wire. Returning None.")
444
+ return None
443
445
  three_vertices = Wire.Vertices(wire)[0:3]
444
446
  temp_w = Wire.ByVertices(three_vertices, close=True)
445
447
  flat_face = Face.ByWire(temp_w, tolerance=tolerance)
@@ -858,7 +860,7 @@ class Face():
858
860
  return None
859
861
  if not north:
860
862
  north = Vector.North()
861
- dirA = Face.NormalAtParameters(face,mantissa=mantissa)
863
+ dirA = Face.Normal(face, outputType="xyz", mantissa=mantissa)
862
864
  return Vector.CompassAngle(vectorA=dirA, vectorB=north, mantissa=mantissa, tolerance=tolerance)
863
865
 
864
866
  @staticmethod
@@ -1041,12 +1043,9 @@ class Face():
1041
1043
 
1042
1044
  eb = face.ExternalBoundary()
1043
1045
  f_dir = Face.Normal(face)
1044
- faceVertices = Topology.Vertices(eb)
1045
- temp_face = Face.ByWire(eb)
1046
- temp_dir = Face.Normal(temp_face)
1047
- if Vector.IsAntiParallel(f_dir, temp_dir):
1048
- faceVertices.reverse()
1049
- eb = Wire.ByVertices(faceVertices)
1046
+ w_dir = Wire.Normal(eb)
1047
+ if Vector.IsAntiParallel(f_dir, w_dir):
1048
+ eb = Wire.Reverse(eb)
1050
1049
  return eb
1051
1050
 
1052
1051
  @staticmethod
@@ -1648,7 +1647,7 @@ class Face():
1648
1647
  return medialAxis
1649
1648
 
1650
1649
  @staticmethod
1651
- def Normal(face, outputType: str = "xyz", mantissa: int = 6) -> list:
1650
+ def Normal(face, outputType="xyz", mantissa=6):
1652
1651
  """
1653
1652
  Returns the normal vector to the input face. A normal vector of a face is a vector perpendicular to it.
1654
1653
 
@@ -1661,55 +1660,86 @@ class Face():
1661
1660
  mantissa : int , optional
1662
1661
  The desired length of the mantissa. The default is 6.
1663
1662
 
1664
- Returns
1665
- -------
1666
- list
1667
- The normal vector to the input face. This is computed at the approximate center of the face.
1668
-
1669
- """
1670
- return Face.NormalAtParameters(face, u=0.5, v=0.5, outputType=outputType, mantissa=mantissa)
1671
-
1672
- @staticmethod
1673
- def NormalAtParameters(face, u: float = 0.5, v: float = 0.5, outputType: str = "xyz", mantissa: int = 6) -> list:
1674
- """
1675
- Returns the normal vector to the input face. A normal vector of a face is a vector perpendicular to it.
1676
-
1677
- Parameters
1678
- ----------
1679
- face : topologic_core.Face
1680
- The input face.
1681
- u : float , optional
1682
- The *u* parameter at which to compute the normal to the input face. The default is 0.5.
1683
- v : float , optional
1684
- The *v* parameter at which to compute the normal to the input face. The default is 0.5.
1685
- outputType : string , optional
1686
- The string defining the desired output. This can be any subset or permutation of "xyz". It is case insensitive. The default is "xyz".
1687
- mantissa : int , optional
1688
- The desired length of the mantissa. The default is 6.
1689
-
1690
1663
  Returns
1691
1664
  -------
1692
1665
  list
1693
1666
  The normal vector to the input face.
1694
1667
 
1695
1668
  """
1696
- returnResult = []
1669
+ from topologicpy.Topology import Topology
1670
+ from topologicpy.Vertex import Vertex
1671
+ import os
1672
+ import warnings
1697
1673
  try:
1698
- coords = topologic.FaceUtility.NormalAtParameters(face, u, v) # Hook to Core
1699
- x = round(coords[0], mantissa)
1700
- y = round(coords[1], mantissa)
1701
- z = round(coords[2], mantissa)
1702
- outputType = list(outputType.lower())
1703
- for axis in outputType:
1704
- if axis == "x":
1705
- returnResult.append(x)
1706
- elif axis == "y":
1707
- returnResult.append(y)
1708
- elif axis == "z":
1709
- returnResult.append(z)
1674
+ import numpy as np
1710
1675
  except:
1711
- returnResult = None
1712
- return returnResult
1676
+ print("Face.Normal - Warning: Installing required numpy library.")
1677
+ try:
1678
+ os.system("pip install numpy")
1679
+ except:
1680
+ os.system("pip install numpy --user")
1681
+ try:
1682
+ import numpy as np
1683
+ print("Face.Normal - Warning: numpy library installed correctly.")
1684
+ except:
1685
+ warnings.warn("Face.Normal - Error: Could not import numpy. Please try to install numpy manually. Returning None.")
1686
+ return None
1687
+
1688
+ if not Topology.IsInstance(face, "Face"):
1689
+ print("Face.Normal - Error: The input face parameter is not a valid face. Returning None.")
1690
+ return None
1691
+
1692
+ vertices = Topology.Vertices(face)
1693
+ vertices = [Vertex.Coordinates(v, mantissa=mantissa) for v in vertices]
1694
+
1695
+ if len(vertices) < 3:
1696
+ print("Face.Normal - Error: At least three vertices are required to define a plane. Returning None.")
1697
+ return None
1698
+
1699
+ # Convert vertices to numpy array for easier manipulation
1700
+ vertices = np.array(vertices)
1701
+
1702
+ # Try to find two non-collinear edge vectors
1703
+ vec1 = None
1704
+ vec2 = None
1705
+ for i in range(1, len(vertices)):
1706
+ for j in range(i + 1, len(vertices)):
1707
+ temp_vec1 = vertices[i] - vertices[0]
1708
+ temp_vec2 = vertices[j] - vertices[0]
1709
+ cross_product = np.cross(temp_vec1, temp_vec2)
1710
+ if np.linalg.norm(cross_product) > 1e-6: # Check if the cross product is not near zero
1711
+ vec1 = temp_vec1
1712
+ vec2 = temp_vec2
1713
+ break
1714
+ if vec1 is not None and vec2 is not None:
1715
+ break
1716
+
1717
+ if vec1 is None or vec2 is None:
1718
+ print("Face.Normal - Error: The given vertices do not form a valid plane (all vertices might be collinear). Returning None.")
1719
+ return None
1720
+
1721
+ # Calculate the cross product of the two edge vectors
1722
+ normal = np.cross(vec1, vec2)
1723
+
1724
+ # Normalize the normal vector
1725
+ normal_length = np.linalg.norm(normal)
1726
+ if normal_length == 0:
1727
+ print("Face.Normal - Error: The given vertices do not form a valid plane (cross product resulted in a zero vector). Returning None.")
1728
+ return None
1729
+
1730
+ normal = normal / normal_length
1731
+ normal = normal.tolist()
1732
+ normal = [round(x, mantissa) for x in normal]
1733
+ return_normal = []
1734
+ outputType = list(outputType.lower())
1735
+ for axis in outputType:
1736
+ if axis == "x":
1737
+ return_normal.append(normal[0])
1738
+ elif axis == "y":
1739
+ return_normal.append(normal[1])
1740
+ elif axis == "z":
1741
+ return_normal.append(normal[2])
1742
+ return return_normal
1713
1743
 
1714
1744
  @staticmethod
1715
1745
  def NormalEdge(face, length: float = 1.0, tolerance: float = 0.0001, silent: bool = False):
@@ -1744,43 +1774,10 @@ class Face():
1744
1774
  return None
1745
1775
  iv = Face.InternalVertex(face)
1746
1776
  u, v = Face.VertexParameters(face, iv)
1747
- vec = Face.NormalAtParameters(face, u=u, v=v)
1777
+ vec = Face.Normal(face)
1748
1778
  ev = Topology.TranslateByDirectionDistance(iv, vec, length)
1749
1779
  return Edge.ByVertices([iv, ev], tolerance=tolerance, silent=silent)
1750
1780
 
1751
- @staticmethod
1752
- def NormalEdgeAtParameters(face, u: float = 0.5, v: float = 0.5, length: float = 1.0, tolerance: float = 0.0001):
1753
- """
1754
- Returns the normal vector to the input face as an edge with the desired input length. A normal vector of a face is a vector perpendicular to it.
1755
-
1756
- Parameters
1757
- ----------
1758
- face : topologic_core.Face
1759
- The input face.
1760
- u : float , optional
1761
- The *u* parameter at which to compute the normal to the input face. The default is 0.5.
1762
- v : float , optional
1763
- The *v* parameter at which to compute the normal to the input face. The default is 0.5.
1764
- length : float , optional
1765
- The desired length of the normal edge. The default is 1.
1766
- tolerance : float , optional
1767
- The desired tolerance. The default is 0.0001.
1768
-
1769
- Returns
1770
- -------
1771
- topologic_core.Edge
1772
- The created normal edge to the input face. This is computed at the approximate center of the face.
1773
-
1774
- """
1775
- from topologicpy.Edge import Edge
1776
- from topologicpy.Topology import Topology
1777
- if not Topology.IsInstance(face, "Face"):
1778
- return None
1779
- sv = Face.VertexByParameters(face=face, u=u, v=v)
1780
- vec = Face.NormalAtParameters(face, u=u, v=v)
1781
- ev = Topology.TranslateByDirectionDistance(sv, vec, length)
1782
- return Edge.ByVertices([sv, ev], tolerance=tolerance, silent=True)
1783
-
1784
1781
  @staticmethod
1785
1782
  def PlaneEquation(face, mantissa: int = 6) -> dict:
1786
1783
  """
topologicpy/Graph.py CHANGED
@@ -269,6 +269,88 @@ class _DrawTree(object):
269
269
  return self.__str__()
270
270
 
271
271
  class Graph:
272
+ def AdjacencyDictionary(graph, vertexLabelKey: str = "label", edgeKey: str = "Length", reverse: bool = False, mantissa: int = 6):
273
+ """
274
+ Returns the adjacency dictionary of the input Graph.
275
+
276
+ Parameters
277
+ ----------
278
+ graph : topologic_core.Graph
279
+ The input graph.
280
+ vertexLabelKey : str , optional
281
+ The returned vertices are labelled according to the dictionary values stored under this key.
282
+ If the vertexLabelKey does not exist, it will be created and the vertices are labelled numerically and stored in the vertex dictionary under this key. The default is "label".
283
+ edgeWeightKey : str , optional
284
+ If set, the edges' dictionaries will be searched for this key to set their weight. If the key is set to "length" (case insensitive), the length of the edge will be used as its weight. If set to None, a weight of 1 will be used. The default is "Length".
285
+ reverse : bool , optional
286
+ If set to True, the vertices are sorted in reverse order (only if vertexKey is set). Otherwise, they are not. The default is False.
287
+ mantissa : int , optional
288
+ The desired length of the mantissa. The default is 6.
289
+
290
+ Returns
291
+ -------
292
+ dict
293
+ The adjacency dictionary.
294
+ """
295
+ from topologicpy.Vertex import Vertex
296
+ from topologicpy.Edge import Edge
297
+ from topologicpy.Dictionary import Dictionary
298
+ from topologicpy.Topology import Topology
299
+ from topologicpy.Helper import Helper
300
+
301
+ if not Topology.IsInstance(graph, "Graph"):
302
+ print("Graph.AdjacencyDictionary - Error: The input graph is not a valid graph. Returning None.")
303
+ return None
304
+ if not isinstance(vertexLabelKey, str):
305
+ print("Graph.AdjacencyDictionary - Error: The input vertexLabelKey is not a valid string. Returning None.")
306
+ return None
307
+ vertices = Graph.Vertices(graph)
308
+ labels = []
309
+ n = max(len(str(len(vertices))), 3)
310
+ for i, v in enumerate(vertices):
311
+ d = Topology.Dictionary(v)
312
+ value = Dictionary.ValueAtKey(d, vertexLabelKey)
313
+ if value == None:
314
+ value = str(i).zfill(n)
315
+ if d == None:
316
+ d = Dictionary.ByKeyValue(vertexLabelKey, value)
317
+ else:
318
+ d = Dictionary.SetValueAtKey(d, vertexLabelKey, value)
319
+ v = Topology.SetDictionary(v, d)
320
+ labels.append(value)
321
+ vertices = Helper.Sort(vertices, labels)
322
+ labels.sort()
323
+ if reverse == True:
324
+ vertices.reverse()
325
+ labels.reverse()
326
+ order = len(vertices)
327
+ adjDict = {}
328
+ for i in range(order):
329
+ v = Graph.NearestVertex(graph, vertices[i])
330
+ vertex_label = labels[i]
331
+ adjVertices = Graph.AdjacentVertices(graph, v)
332
+ temp_list = []
333
+ for adjVertex in adjVertices:
334
+ if edgeKey == None:
335
+ weight = 1
336
+ elif "length" in edgeKey.lower():
337
+ edge = Graph.Edge(graph, v, adjVertex)
338
+ weight = Edge.Length(edge, mantissa=mantissa)
339
+ else:
340
+ edge = Graph.Edge(graph, v, adjVertex)
341
+ weight = Dictionary.ValueAtKey(Topology.Dictionary(edge), edgeKey)
342
+ if weight == None:
343
+ weight = Edge.Length(edge, mantissa=mantissa)
344
+ else:
345
+ weight = round(weight, mantissa)
346
+ adjIndex = Vertex.Index(adjVertex, vertices)
347
+ adjLabel = labels[adjIndex]
348
+ if not adjIndex == None:
349
+ temp_list.append((adjLabel, weight))
350
+ temp_list.sort()
351
+ adjDict[vertex_label] = temp_list
352
+ return adjDict
353
+
272
354
  @staticmethod
273
355
  def AdjacencyMatrix(graph, vertexKey=None, reverse=False, edgeKeyFwd=None, edgeKeyBwd=None, bidirKey=None, bidirectional=True, useEdgeIndex=False, useEdgeLength=False, tolerance=0.0001):
274
356
  """
topologicpy/Topology.py CHANGED
@@ -3236,7 +3236,7 @@ class Topology():
3236
3236
  _ = topology.Faces(None, faces)
3237
3237
  normals = []
3238
3238
  for aFace in faces:
3239
- normals.append(Face.NormalAtParameters(aFace, 0.5, 0.5, "XYZ", 3))
3239
+ normals.append(Face.Normal(aFace, outputType="XYZ", mantissa=3))
3240
3240
  # build a matrix of similarity
3241
3241
  mat = buildSimilarityMatrix(normals, angTolerance)
3242
3242
  categories = categorizeIntoClusters(mat)
@@ -4799,17 +4799,6 @@ class Topology():
4799
4799
  _ = topology.CellComplexes(None, topologies)
4800
4800
  return topologies
4801
4801
 
4802
- def triangulateFace(face):
4803
- faceTriangles = []
4804
- for i in range(0, 5, 1):
4805
- try:
4806
- _ = topologic.FaceUtility.Triangulate(face, float(i)*0.1, faceTriangles)
4807
- return faceTriangles
4808
- except:
4809
- continue
4810
- faceTriangles.append(face)
4811
- return faceTriangles
4812
-
4813
4802
  vertices = []
4814
4803
  edges = []
4815
4804
  faces = []
@@ -4858,14 +4847,10 @@ class Topology():
4858
4847
  ib = []
4859
4848
  _ = aFace.InternalBoundaries(ib)
4860
4849
  if(len(ib) > 0):
4861
- triFaces = triangulateFace(aFace)
4850
+ triFaces = Face.Triangulate(aFace)
4862
4851
  for aTriFace in triFaces:
4863
- wire = aTriFace.ExternalBoundary()
4852
+ wire = Face.ExternalBoundary(aTriFace)
4864
4853
  faceVertices = getSubTopologies(wire, topologic.Vertex)
4865
- temp_face = Face.ByWire(wire)
4866
- temp_dir = Face.Normal(temp_face)
4867
- if Vector.IsAntiParallel(f_dir, temp_dir):
4868
- faceVertices.reverse()
4869
4854
  f = []
4870
4855
  for aVertex in faceVertices:
4871
4856
  try:
@@ -4876,13 +4861,8 @@ class Topology():
4876
4861
  f.append(fVertexIndex)
4877
4862
  faces.append(f)
4878
4863
  else:
4879
- wire = aFace.ExternalBoundary()
4880
- #wire = topologic.WireUtility.RemoveCollinearEdges(wire, 0.1) #This is an angle Tolerance
4864
+ wire = Face.ExternalBoundary(aFace)
4881
4865
  faceVertices = getSubTopologies(wire, topologic.Vertex)
4882
- temp_face = Face.ByWire(wire)
4883
- temp_dir = Face.Normal(temp_face)
4884
- if Vector.IsAntiParallel(f_dir, temp_dir):
4885
- faceVertices.reverse()
4886
4866
  f = []
4887
4867
  for aVertex in faceVertices:
4888
4868
  try:
topologicpy/Wire.py CHANGED
@@ -1953,6 +1953,101 @@ class Wire(Topology):
1953
1953
  return_wire = Topology.Unflatten(flat_wire, origin=Vertex.Origin(), direction=normal)
1954
1954
  return return_wire
1955
1955
 
1956
+ @staticmethod
1957
+ def Normal(wire, outputType="xyz", mantissa=6):
1958
+ """
1959
+ Returns the normal vector to the input wire. A normal vector of a wire is a vector perpendicular to it.
1960
+
1961
+ Parameters
1962
+ ----------
1963
+ wire : topologic_core.Wire
1964
+ The input wire.
1965
+ outputType : string , optional
1966
+ The string defining the desired output. This can be any subset or permutation of "xyz". It is case insensitive. The default is "xyz".
1967
+ mantissa : int , optional
1968
+ The desired length of the mantissa. The default is 6.
1969
+
1970
+ Returns
1971
+ -------
1972
+ list
1973
+ The normal vector to the input face.
1974
+
1975
+ """
1976
+ from topologicpy.Topology import Topology
1977
+ from topologicpy.Vertex import Vertex
1978
+ import os
1979
+ import warnings
1980
+ try:
1981
+ import numpy as np
1982
+ except:
1983
+ print("Wire.Normal - Warning: Installing required numpy library.")
1984
+ try:
1985
+ os.system("pip install numpy")
1986
+ except:
1987
+ os.system("pip install numpy --user")
1988
+ try:
1989
+ import numpy as np
1990
+ print("Wire.Normal - Warning: numpy library installed correctly.")
1991
+ except:
1992
+ warnings.warn("Wire.Normal - Error: Could not import numpy. Please try to install numpy manually. Returning None.")
1993
+ return None
1994
+
1995
+ if not Topology.IsInstance(wire, "Wire"):
1996
+ print("Wire.Normal - Error: The input wire parameter is not a valid wire. Returning None.")
1997
+ return None
1998
+
1999
+ vertices = Topology.Vertices(wire)
2000
+ vertices = [Vertex.Coordinates(v, mantissa=mantissa) for v in vertices]
2001
+
2002
+ if len(vertices) < 3:
2003
+ print("Wire.Normal - Error: At least three vertices are required to define a plane. Returning None.")
2004
+ return None
2005
+
2006
+ # Convert vertices to numpy array for easier manipulation
2007
+ vertices = np.array(vertices)
2008
+
2009
+ # Try to find two non-collinear edge vectors
2010
+ vec1 = None
2011
+ vec2 = None
2012
+ for i in range(1, len(vertices)):
2013
+ for j in range(i + 1, len(vertices)):
2014
+ temp_vec1 = vertices[i] - vertices[0]
2015
+ temp_vec2 = vertices[j] - vertices[0]
2016
+ cross_product = np.cross(temp_vec1, temp_vec2)
2017
+ if np.linalg.norm(cross_product) > 1e-6: # Check if the cross product is not near zero
2018
+ vec1 = temp_vec1
2019
+ vec2 = temp_vec2
2020
+ break
2021
+ if vec1 is not None and vec2 is not None:
2022
+ break
2023
+
2024
+ if vec1 is None or vec2 is None:
2025
+ print("Wire.Normal - Error: The given vertices do not form a valid plane (all vertices might be collinear). Returning None.")
2026
+ return None
2027
+
2028
+ # Calculate the cross product of the two edge vectors
2029
+ normal = np.cross(vec1, vec2)
2030
+
2031
+ # Normalize the normal vector
2032
+ normal_length = np.linalg.norm(normal)
2033
+ if normal_length == 0:
2034
+ print("Wire.Normal - Error: The given vertices do not form a valid plane (cross product resulted in a zero vector). Returning None.")
2035
+ return None
2036
+
2037
+ normal = normal / normal_length
2038
+ normal = normal.tolist()
2039
+ normal = [round(x, mantissa) for x in normal]
2040
+ return_normal = []
2041
+ outputType = list(outputType.lower())
2042
+ for axis in outputType:
2043
+ if axis == "x":
2044
+ return_normal.append(normal[0])
2045
+ elif axis == "y":
2046
+ return_normal.append(normal[1])
2047
+ elif axis == "z":
2048
+ return_normal.append(normal[2])
2049
+ return return_normal
2050
+
1956
2051
  @staticmethod
1957
2052
  def OrientEdges(wire, vertexA, tolerance=0.0001):
1958
2053
  """
@@ -2106,7 +2201,7 @@ class Wire(Topology):
2106
2201
  if not Topology.IsInstance(face, "Face"):
2107
2202
  return None
2108
2203
  if not direction:
2109
- direction = -1*Face.NormalAtParameters(face, 0.5, 0.5, "XYZ", mantissa)
2204
+ direction = -1*Face.Normal(face, outputType="xyz", mantissa=mantissa)
2110
2205
  large_face = Topology.Scale(face, face.CenterOfMass(), 500, 500, 500)
2111
2206
  edges = []
2112
2207
  _ = wire.Edges(None, edges)
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.17'
1
+ __version__ = '0.7.18'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.17
3
+ Version: 0.7.18
4
4
  Summary: An Advanced Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: MIT License
@@ -108,6 +108,42 @@ topologicpy depends on the following python libraries which will be installed au
108
108
  ## API Documentation
109
109
  API documentation can be found at [https://topologicpy.readthedocs.io](https://topologicpy.readthedocs.io)
110
110
 
111
+ ## How to cite topologicpy
112
+ If you wish to cite the actual software, you can use:
113
+
114
+ **Jabi, W. (2024). topologicpy. pypi.org. http://doi.org/10.5281/zenodo.11555172**
115
+
116
+ To cite one of the main papers that defines topologicpy, you can use:
117
+
118
+ **Jabi, W., & Chatzivasileiadi, A. (2021). Topologic: Exploring Spatial Reasoning Through Geometry, Topology, and Semantics. In S. Eloy, D. Leite Viana, F. Morais, & J. Vieira Vaz (Eds.), Formal Methods in Architecture (pp. 277–285). Springer International Publishing. https://doi.org/10.1007/978-3-030-57509-0_25**
119
+
120
+ Or you can import the following .bib formatted references into your favourite reference manager
121
+ ```
122
+ @misc{Jabi2024,
123
+ author = {Wassim Jabi},
124
+ doi = {https://doi.org/10.5281/zenodo.11555173},
125
+ title = {topologicpy},
126
+ url = {http://pypi.org/projects/topologicpy},
127
+ year = {2024},
128
+ }
129
+ ```
130
+ ```
131
+ @inbook{Jabi2021,
132
+ abstract = {Topologic is a software modelling library that supports a comprehensive conceptual framework for the hierarchical spatial representation of buildings based on the data structures and concepts of non-manifold topology (NMT). Topologic supports conceptual design and spatial reasoning through the integration of geometry, topology, and semantics. This enables architects and designers to reflect on their design decisions before the complexities of building information modelling (BIM) set in. We summarize below related work on NMT starting in the late 1980s, describe Topologic’s software architecture, methods, and classes, and discuss how Topologic’s features support conceptual design and spatial reasoning. We also report on a software usability workshop that was conducted to validate a software evaluation methodology and reports on the collected qualitative data. A reflection on Topologic’s features and software architecture illustrates how it enables a fundamental shift from pursuing fidelity of design form to pursuing fidelity of design intent.},
133
+ author = {Wassim Jabi and Aikaterini Chatzivasileiadi},
134
+ city = {Cham},
135
+ doi = {10.1007/978-3-030-57509-0_25},
136
+ editor = {Sara Eloy and David Leite Viana and Franklim Morais and Jorge Vieira Vaz},
137
+ isbn = {978-3-030-57509-0},
138
+ journal = {Formal Methods in Architecture},
139
+ pages = {277-285},
140
+ publisher = {Springer International Publishing},
141
+ title = {Topologic: Exploring Spatial Reasoning Through Geometry, Topology, and Semantics},
142
+ url = {https://link.springer.com/10.1007/978-3-030-57509-0_25},
143
+ year = {2021},
144
+ }
145
+ ```
146
+
111
147
  topologicpy: © 2024 Wassim Jabi
112
148
 
113
149
  Topologic: © 2024 Cardiff University and UCL
@@ -1,6 +1,6 @@
1
1
  topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
2
- topologicpy/Cell.py,sha256=JYP0Qv61Sxgni5nCTd7Hx9pjoUE4F4lje0iMUgDxDO4,99704
3
- topologicpy/CellComplex.py,sha256=ZxTfpV0Worgnwj4tz-qk2a6OmAtctG_8CnHKnwoVzJU,47452
2
+ topologicpy/Cell.py,sha256=FNmDHdNkJYaM982MLktfSipqFnfJBQmdxKp3kmuBKjA,99861
3
+ topologicpy/CellComplex.py,sha256=Fd70Dj7E4LqV5O-7kcCCYnrFEyqheZvxc0YWktm0EL8,47440
4
4
  topologicpy/Cluster.py,sha256=HvomWm_V4bx76YMxqOEhAUrsvcU6z5e_zry6WxMuV2M,54819
5
5
  topologicpy/Color.py,sha256=UlmRcCSOhqcM_OyMWz4t3Kr75KcgXDhz3uctAJ2n7Ic,18031
6
6
  topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
@@ -8,8 +8,8 @@ topologicpy/DGL.py,sha256=5jNn1L8F8REx1-oAh9sr_cfil0R5kUuueCNDKwNU_GM,138991
8
8
  topologicpy/Dictionary.py,sha256=pMbfE2RYGCNpVr2x58qiHRc-aBWnp1jLlyzwS9nz6-w,25891
9
9
  topologicpy/Edge.py,sha256=f7LjP662_yoqopAXBh1Gqv8DvdzvfM_heJTP2XnFskY,58447
10
10
  topologicpy/EnergyModel.py,sha256=ni0H1JgvLl1-q90yK9Sm1qj5P1fTuidlimEIcwuj6qE,53287
11
- topologicpy/Face.py,sha256=3sMhe86QCo8qLSLlw2CdWkwzVuMNegmnAhUSe__h0iQ,108351
12
- topologicpy/Graph.py,sha256=90D_G90RBkJ1ZDCLFR2XG2juwnWKfADd0YPIFqIjsck,387669
11
+ topologicpy/Face.py,sha256=1J1dnS3tNnaoFQyWdWjn9YnHldyiN-J67IjytIT0-R4,108142
12
+ topologicpy/Graph.py,sha256=JM4N6EShvDspFcE9_E027HKAkHhZ5e5UD4I9LxlRfmA,391560
13
13
  topologicpy/Grid.py,sha256=Cpzs9l5-SptMQbUR8AvbbIOHrGMGlK0Qx8FWmQBgvX0,18497
14
14
  topologicpy/Helper.py,sha256=07V9IFu5ilMpvAdZVhIbdBOjBJSRTtJ0BfR1IoRaRXU,17743
15
15
  topologicpy/Honeybee.py,sha256=dlr5OEH93q51ZmEgvi8PXGfCHBDAjIZ1cm38Rft1Bz4,20235
@@ -20,14 +20,14 @@ topologicpy/Polyskel.py,sha256=pNawz5lnvy4oTzCL91fGY2PblW2hmcYBdT5268m2RZs,19743
20
20
  topologicpy/Shell.py,sha256=fdMhCKH5Oq2id16XjTWRe8-06jZ8z8LnrVqMR-33F3s,79144
21
21
  topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
22
22
  topologicpy/Sun.py,sha256=mN3RzlslcZT3APUtwmWIXVbPkJ6OcKTaTf6338gbMJE,37152
23
- topologicpy/Topology.py,sha256=O79RJPcMV0-id-1CSRtBdrJHWHLLWdNIAPdfGbPn_qI,339720
23
+ topologicpy/Topology.py,sha256=Y0McJCx_eH6y92bMbRfG82Foe0A9K7j3Fp8w-dD9h4k,338825
24
24
  topologicpy/Vector.py,sha256=G4mIIcE5Y-EHfiNV_rxiOz8pJeV3NMEwLu5EOgM0gKA,32653
25
25
  topologicpy/Vertex.py,sha256=bD3JnNhizbp6HFhHRve2LK_y5w27jytCbsagOLxKjZQ,71198
26
- topologicpy/Wire.py,sha256=L9RsS6kmmmF5n7QNNNebQRR6Rg2bFdUaF2RZjyGdRuY,139799
26
+ topologicpy/Wire.py,sha256=OtqCUmZeqeNF3baBLmUjB8yBZ3gmzzpSPcD-zzKzz4k,143577
27
27
  topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
28
- topologicpy/version.py,sha256=wcUsHaWS0KncOllDb6GdknQP3quV24cgTSGaGPX-yX0,23
29
- topologicpy-0.7.17.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
30
- topologicpy-0.7.17.dist-info/METADATA,sha256=UP-ISL841EAJkgEPB48Zz9SV52tRttTKCt0DyuIh9xI,8410
31
- topologicpy-0.7.17.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
32
- topologicpy-0.7.17.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
33
- topologicpy-0.7.17.dist-info/RECORD,,
28
+ topologicpy/version.py,sha256=JKTQ-L90z9YkGvUYq8IRiy8FeivJmY_tDcKgSZ-ssw4,23
29
+ topologicpy-0.7.18.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
30
+ topologicpy-0.7.18.dist-info/METADATA,sha256=NiOC_LjQzxSER_rnY5Kz05fNWAbiEOuGxcoFAh2-_VA,10916
31
+ topologicpy-0.7.18.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
32
+ topologicpy-0.7.18.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
33
+ topologicpy-0.7.18.dist-info/RECORD,,