topologicpy 0.4.55__py3-none-any.whl → 0.4.57__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.
Files changed (50) hide show
  1. topologicpy/Cell.py +95 -22
  2. topologicpy/CellComplex.py +36 -5
  3. topologicpy/DGL.py +4 -1
  4. topologicpy/Edge.py +1 -1
  5. topologicpy/Face.py +86 -64
  6. topologicpy/Graph.py +37 -34
  7. topologicpy/Helper.py +83 -44
  8. topologicpy/Plotly.py +15 -14
  9. topologicpy/Shell.py +70 -28
  10. topologicpy/Topology.py +155 -174
  11. topologicpy/Wire.py +64 -146
  12. topologicpy/__init__.py +22 -22
  13. topologicpy/bin/linux/topologic/__init__.py +2 -2
  14. topologicpy/bin/linux/topologic/topologic.cpython-310-x86_64-linux-gnu.so +0 -0
  15. topologicpy/bin/linux/topologic/topologic.cpython-311-x86_64-linux-gnu.so +0 -0
  16. topologicpy/bin/linux/topologic/topologic.cpython-38-x86_64-linux-gnu.so +0 -0
  17. topologicpy/bin/linux/topologic/topologic.cpython-39-x86_64-linux-gnu.so +0 -0
  18. topologicpy/bin/linux/topologic.libs/libTKBO-6bdf205d.so.7.7.0 +0 -0
  19. topologicpy/bin/linux/topologic.libs/libTKBRep-2960a069.so.7.7.0 +0 -0
  20. topologicpy/bin/linux/topologic.libs/libTKBool-c44b74bd.so.7.7.0 +0 -0
  21. topologicpy/bin/linux/topologic.libs/libTKFillet-9a670ba0.so.7.7.0 +0 -0
  22. topologicpy/bin/linux/topologic.libs/libTKG2d-8f31849e.so.7.7.0 +0 -0
  23. topologicpy/bin/linux/topologic.libs/libTKG3d-4c6bce57.so.7.7.0 +0 -0
  24. topologicpy/bin/linux/topologic.libs/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
  25. topologicpy/bin/linux/topologic.libs/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
  26. topologicpy/bin/linux/topologic.libs/libTKMath-72572fa8.so.7.7.0 +0 -0
  27. topologicpy/bin/linux/topologic.libs/libTKMesh-2a060427.so.7.7.0 +0 -0
  28. topologicpy/bin/linux/topologic.libs/libTKOffset-6cab68ff.so.7.7.0 +0 -0
  29. topologicpy/bin/linux/topologic.libs/libTKPrim-eb1262b3.so.7.7.0 +0 -0
  30. topologicpy/bin/linux/topologic.libs/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
  31. topologicpy/bin/linux/topologic.libs/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
  32. topologicpy/bin/linux/topologic.libs/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
  33. topologicpy/bin/linux/topologic.libs/libgcc_s-32c1665e.so.1 +0 -0
  34. topologicpy/bin/linux/topologic.libs/libstdc++-672d7b41.so.6.0.30 +0 -0
  35. topologicpy/bin/macos/topologic/__init__.py +2 -2
  36. topologicpy/bin/windows/topologic/topologic.cp310-win_amd64.pyd +0 -0
  37. topologicpy/bin/windows/topologic/topologic.cp311-win_amd64.pyd +0 -0
  38. topologicpy/bin/windows/topologic/topologic.cp38-win_amd64.pyd +0 -0
  39. topologicpy/bin/windows/topologic/topologic.cp39-win_amd64.pyd +0 -0
  40. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/METADATA +1 -1
  41. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/RECORD +44 -48
  42. topologicpy/bin/linux/topologic.libs/libgcc_s-b928ac34.so.1 +0 -0
  43. topologicpy/bin/linux/topologic.libs/libstdc++-e9ef912c.so.6.0.32 +0 -0
  44. topologicpy/bin/macos/topologic/topologic.cpython-310-darwin.so +0 -0
  45. topologicpy/bin/macos/topologic/topologic.cpython-311-darwin.so +0 -0
  46. topologicpy/bin/macos/topologic/topologic.cpython-38-darwin.so +0 -0
  47. topologicpy/bin/macos/topologic/topologic.cpython-39-darwin.so +0 -0
  48. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/LICENSE +0 -0
  49. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/WHEEL +0 -0
  50. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/top_level.txt +0 -0
topologicpy/Graph.py CHANGED
@@ -4183,6 +4183,12 @@ class Graph:
4183
4183
  for edge in Topology.Edges(temp_path):
4184
4184
  new_edges.append(g_edges[Edge.Index(edge, g_edges)])
4185
4185
  longest_path = Topology.SelfMerge(Cluster.ByTopologies(new_edges), tolerance=tolerance)
4186
+ sv = Topology.Vertices(longest_path)[0]
4187
+ if Vertex.Distance(sv, vertexB) < tolerance: # Wire is reversed. Re-reverse it
4188
+ if isinstance(longest_path, topologic.Edges):
4189
+ longest_path = Edge.Reverse(longest_path)
4190
+ if isinstance(longest_path, topologic.Wire):
4191
+ longest_path = Wire.Reverse(longest_path)
4186
4192
  if not costKey == None:
4187
4193
  lengths.sort()
4188
4194
  d = Dictionary.ByKeysValues([costKey], [cost])
@@ -4874,7 +4880,7 @@ class Graph:
4874
4880
  return graph
4875
4881
 
4876
4882
  @staticmethod
4877
- def ShortestPath(graph, vertexA, vertexB, vertexKey="", edgeKey="Length"):
4883
+ def ShortestPath(graph, vertexA, vertexB, vertexKey="", edgeKey="Length", tolerance=0.0001):
4878
4884
  """
4879
4885
  Returns the shortest path that connects the input vertices.
4880
4886
 
@@ -4890,13 +4896,19 @@ class Graph:
4890
4896
  The vertex key to minimise. If set the vertices dictionaries will be searched for this key and the associated value will be used to compute the shortest path that minimized the total value. The value must be numeric. The default is None.
4891
4897
  edgeKey : string , optional
4892
4898
  The edge key to minimise. If set the edges dictionaries will be searched for this key and the associated value will be used to compute the shortest path that minimized the total value. The value of the key must be numeric. If set to "length" (case insensitive), the shortest path by length is computed. The default is "length".
4893
-
4899
+ tolerance : float , optional
4900
+ The desired tolerance. The default is 0.0001.
4901
+
4894
4902
  Returns
4895
4903
  -------
4896
4904
  topologic.Wire
4897
4905
  The shortest path between the input vertices.
4898
4906
 
4899
4907
  """
4908
+ from topologicpy.Edge import Edge
4909
+ from topologicpy.Wire import Wire
4910
+ from topologicpy.Topology import Topology
4911
+
4900
4912
  if not isinstance(graph, topologic.Graph):
4901
4913
  print("Graph.ShortestPath - Error: The input graph is not a valid graph. Returning None.")
4902
4914
  return None
@@ -4910,7 +4922,16 @@ class Graph:
4910
4922
  if edgeKey.lower() == "length":
4911
4923
  edgeKey = "Length"
4912
4924
  try:
4913
- return graph.ShortestPath(vertexA, vertexB, vertexKey, edgeKey)
4925
+ gsv = Graph.NearestVertex(graph, vertexA, tolerance)
4926
+ gev = Graph.NearestVertex(graph, vertexB, tolerance)
4927
+ shortest_path = graph.ShortestPath(gsv, gev, vertexKey, edgeKey)
4928
+ sv = Topology.Vertices(shortest_path)[0]
4929
+ if Vertex.Distance(sv, gev) < tolerance: # Path is reversed. Correct it.
4930
+ if isinstance(shortest_path, topologic.Edges):
4931
+ shortest_path = Edge.Reverse(shortest_path)
4932
+ if isinstance(shortest_path, topologic.Wire):
4933
+ shortest_path = Wire.Reverse(shortest_path)
4934
+ return shortest_path
4914
4935
  except:
4915
4936
  return None
4916
4937
 
@@ -4936,62 +4957,49 @@ class Graph:
4936
4957
  The search time limit in seconds. The default is 10 seconds
4937
4958
  pathLimit: int , optional
4938
4959
  The number of found paths limit. The default is 10 paths.
4960
+ tolerance : float , optional
4961
+ The desired tolerance. The default is 0.0001.
4939
4962
 
4940
4963
  Returns
4941
4964
  -------
4942
- topologic.Wire
4965
+ list
4943
4966
  The list of shortest paths between the input vertices.
4944
4967
 
4945
4968
  """
4946
4969
  from topologicpy.Vertex import Vertex
4947
4970
  from topologicpy.Wire import Wire
4948
- def nearestVertex(g, v, tolerance):
4949
- vertices = Graph.Vertices(g)
4950
- for aVertex in vertices:
4951
- d = Vertex.Distance(v, aVertex)
4952
- if d < tolerance:
4953
- return aVertex
4954
- return None
4955
4971
 
4956
- def isUnique(paths, wire):
4972
+ def isUnique(paths, path):
4973
+ if path == None:
4974
+ return False
4957
4975
  if len(paths) < 1:
4958
4976
  return True
4959
4977
  for aPath in paths:
4960
4978
  copyPath = topologic.Topology.DeepCopy(aPath)
4961
- dif = copyPath.Difference(wire, False)
4979
+ dif = copyPath.Difference(path, False)
4962
4980
  if dif == None:
4963
4981
  return False
4964
4982
  return True
4965
4983
 
4966
4984
  if not isinstance(graph, topologic.Graph):
4967
- print("Graph.ShortestPaths - Error: The input graph is not a valid graph. Returning None.")
4985
+ print("Graph.ShortestPaths - Error: The input graph parameter is not a valid graph. Returning None.")
4968
4986
  return None
4969
4987
  if not isinstance(vertexA, topologic.Vertex):
4970
- print("Graph.ShortestPaths - Error: The input vertexA is not a valid vertex. Returning None.")
4988
+ print("Graph.ShortestPaths - Error: The input vertexA parameter is not a valid vertex. Returning None.")
4971
4989
  return None
4972
4990
  if not isinstance(vertexB, topologic.Vertex):
4973
- print("Graph.ShortestPaths - Error: The input vertexB is not a valid vertex. Returning None.")
4991
+ print("Graph.ShortestPaths - Error: The input vertexB parameter is not a valid vertex. Returning None.")
4974
4992
  return None
4975
4993
  shortestPaths = []
4976
4994
  end = time.time() + timeLimit
4977
4995
  while time.time() < end and len(shortestPaths) < pathLimit:
4978
- gsv = nearestVertex(graph, vertexA, tolerance)
4979
- gev = nearestVertex(graph, vertexB, tolerance)
4980
4996
  if (graph != None):
4981
4997
  if edgeKey:
4982
4998
  if edgeKey.lower() == "length":
4983
4999
  edgeKey = "Length"
4984
- wire = graph.ShortestPath(gsv,gev,vertexKey,edgeKey) # Find the first shortest path
4985
- wireVertices = []
4986
- flag = False
4987
- try:
4988
- wireVertices = Wire.Vertices(wire)
4989
- flag = True
4990
- except:
4991
- flag = False
4992
- if (flag):
4993
- if isUnique(shortestPaths, wire):
4994
- shortestPaths.append(wire)
5000
+ shortest_path = Graph.ShortestPath(graph, vertexA, vertexB, vertexKey=vertexKey, edgeKey=edgeKey, tolerance=tolerance) # Find the first shortest path
5001
+ if isUnique(shortestPaths, shortest_path):
5002
+ shortestPaths.append(shortest_path)
4995
5003
  vertices = Graph.Vertices(graph)
4996
5004
  random.shuffle(vertices)
4997
5005
  edges = Graph.Edges(graph)
@@ -5399,11 +5407,6 @@ class Graph:
5399
5407
  e = Topology.Boolean(e, boundaryFace, operation="intersect", tolerance=tolerance)
5400
5408
  if isinstance(e, topologic.Edge):
5401
5409
  edges = addEdge(e, edges, viewpointsA, viewpointsB, 0.0001)
5402
- elif isinstance(e, topologic.Cluster):
5403
- tempEdges = Cluster.Edges(e)
5404
- if tempEdges:
5405
- for tempEdge in tempEdges:
5406
- edges = addEdge(tempEdge, edges, viewpointsA, viewpointsB, 0.0001)
5407
5410
 
5408
5411
  except:
5409
5412
  for i in range(len(viewpointsA)):
topologicpy/Helper.py CHANGED
@@ -5,7 +5,7 @@ import math
5
5
 
6
6
  class Helper:
7
7
  @staticmethod
8
- def Flatten(l):
8
+ def Flatten(listA):
9
9
  """
10
10
  Flattens the input nested list.
11
11
 
@@ -21,22 +21,22 @@ class Helper:
21
21
 
22
22
  """
23
23
 
24
- if not isinstance(l, list):
25
- return [l]
24
+ if not isinstance(listA, list):
25
+ return [listA]
26
26
  flat_list = []
27
- for item in l:
27
+ for item in listA:
28
28
  flat_list = flat_list + Helper.Flatten(item)
29
29
  return flat_list
30
30
 
31
31
  @staticmethod
32
- def Iterate(l):
32
+ def Iterate(listA):
33
33
  """
34
34
  Iterates the input nested list so that each sublist has the same number of members. To fill extra members, the shorter lists are iterated from their first member.
35
35
  For example Iterate([[1,2,3],['m','n','o','p'],['a','b','c','d','e']]) yields [[1, 2, 3, 1, 2], ['m', 'n', 'o', 'p', 'm'], ['a', 'b', 'c', 'd', 'e']]
36
36
 
37
37
  Parameters
38
38
  ----------
39
- l : list
39
+ listA : list
40
40
  The input nested list.
41
41
 
42
42
  Returns
@@ -56,13 +56,13 @@ class Helper:
56
56
  base = base[1:]+[base[0]] # rotate
57
57
  return base
58
58
 
59
- maxLength = len(l[0])
59
+ maxLength = len(listA[0])
60
60
  iterated_list = []
61
- for aSubList in l:
61
+ for aSubList in listA:
62
62
  newLength = len(aSubList)
63
63
  if newLength > maxLength:
64
64
  maxLength = newLength
65
- for anItem in l:
65
+ for anItem in listA:
66
66
  for i in range(len(anItem), maxLength):
67
67
  anItem.append(None)
68
68
  y=[]
@@ -107,13 +107,13 @@ class Helper:
107
107
  return {'clusters': clusters, 'centroids': centroids}
108
108
 
109
109
  @staticmethod
110
- def MergeByThreshold(l, threshold=0.0001):
110
+ def MergeByThreshold(listA, threshold=0.0001):
111
111
  """
112
112
  Merges the numbers in the input list so that numbers within the input threshold are averaged into one number.
113
113
 
114
114
  Parameters
115
115
  ----------
116
- l : list
116
+ listA : list
117
117
  The input nested list.
118
118
  threshold : float , optional
119
119
  The desired merge threshold value. The default is 0.0001.
@@ -125,31 +125,31 @@ class Helper:
125
125
 
126
126
  """
127
127
  # Sort the list in ascending order
128
- l.sort()
128
+ listA.sort()
129
129
  merged_list = []
130
130
 
131
131
  # Initialize the first element in the merged list
132
- merged_list.append(l[0])
132
+ merged_list.append(listA[0])
133
133
 
134
134
  # Merge numbers within the threshold
135
- for i in range(1, len(l)):
136
- if l[i] - merged_list[-1] <= threshold:
135
+ for i in range(1, len(listA)):
136
+ if listA[i] - merged_list[-1] <= threshold:
137
137
  # Merge the current number with the last element in the merged list
138
- merged_list[-1] = (merged_list[-1] + l[i]) / 2
138
+ merged_list[-1] = (merged_list[-1] + listA[i]) / 2
139
139
  else:
140
140
  # If the current number is beyond the threshold, add it as a new element
141
- merged_list.append(l[i])
141
+ merged_list.append(listA[i])
142
142
 
143
143
  return merged_list
144
144
 
145
145
  @staticmethod
146
- def Normalize(l, mantissa: int = 6):
146
+ def Normalize(listA, mantissa: int = 6):
147
147
  """
148
148
  Normalizes the input list so that it is in the range 0 to 1
149
149
 
150
150
  Parameters
151
151
  ----------
152
- l : list
152
+ listA : list
153
153
  The input nested list.
154
154
  mantissa : int , optional
155
155
  The desired mantissa value. The default is 4.
@@ -160,12 +160,12 @@ class Helper:
160
160
  The normalized list.
161
161
 
162
162
  """
163
- if l == None:
163
+ if not isinstance(listA, list):
164
164
  print("Helper.Normalize - Error: The input list is not valid. Returning None.")
165
165
  return None
166
166
 
167
167
  # Make sure the list is numeric
168
- l = [x for x in l if type(x) == int or type(x) == float]
168
+ l = [x for x in listA if type(x) == int or type(x) == float]
169
169
  if len(l) < 1:
170
170
  print("Helper.Normalize - Error: The input list does not contain numeric values. Returning None.")
171
171
  return None
@@ -178,14 +178,14 @@ class Helper:
178
178
  return normalized_list
179
179
 
180
180
  @staticmethod
181
- def Repeat(l):
181
+ def Repeat(listA):
182
182
  """
183
183
  Repeats the input nested list so that each sublist has the same number of members. To fill extra members, the last item in the shorter lists are repeated and appended.
184
184
  For example Iterate([[1,2,3],['m','n','o','p'],['a','b','c','d','e']]) yields [[1, 2, 3, 3, 3], ['m', 'n', 'o', 'p', 'p'], ['a', 'b', 'c', 'd', 'e']]
185
185
 
186
186
  Parameters
187
187
  ----------
188
- l : list
188
+ listA : list
189
189
  The input nested list.
190
190
 
191
191
  Returns
@@ -194,9 +194,9 @@ class Helper:
194
194
  The repeated list.
195
195
 
196
196
  """
197
- if not isinstance(l, list):
197
+ if not isinstance(listA, list):
198
198
  return None
199
- repeated_list = [x for x in l if isinstance(x, list)]
199
+ repeated_list = [x for x in listA if isinstance(x, list)]
200
200
  if len(repeated_list) < 1:
201
201
  return None
202
202
  maxLength = len(repeated_list[0])
@@ -214,16 +214,27 @@ class Helper:
214
214
  return repeated_list
215
215
 
216
216
  @staticmethod
217
- def Sort(lA, lB):
217
+ def Sort(listA, *otherLists, reverseFlags=None):
218
218
  """
219
- Sorts the first input list according to the values in the second input list.
219
+ Sorts the first input list according to the values in the subsequent input lists in order. For example,
220
+ your first list can be a list of topologies and the next set of lists can be their volume, surface area, and z level.
221
+ The list of topologies will then be sorted first by volume, then by surface, and lastly by z level. You can choose
222
+ to reverse the order of sorting by including a list of TRUE/FALSE values in the reverseFlags input parameter.
223
+ For example, if you wish to sort the volume in reverse order (from large to small), but sort the other parameters
224
+ normally, you would include the following list for reverseFlag: [True, False, False].
220
225
 
221
226
  Parameters
222
227
  ----------
223
- lA : list
228
+ listA : list
224
229
  The first input list to be sorts
225
- lB : list
226
- The second input list to use for sorting the first input list.
230
+ *otherLists : any number of lists to use for sorting listA, optional.
231
+ Any number of lists that are used to sort the listA input parameter. The order of these input
232
+ parameters determines the order of sorting (from left to right). If no lists are included, the input list will be sorted as is.
233
+ reverseFlags : list, optional.
234
+ The list of booleans (TRUE/FALSE) to indicated if sorting based on a particular list should be conducted in reverse order.
235
+ The length of the reverseFlags list should match the number of the lists in the input otherLists parameter. If set to None,
236
+ a default list of FALSE values is created to match the number of the lists in the input otherLists parameter. The default
237
+ is None.
227
238
 
228
239
  Returns
229
240
  -------
@@ -231,17 +242,45 @@ class Helper:
231
242
  The sorted list.
232
243
 
233
244
  """
234
- lA.sort(key=dict(zip(lA, lB)).get)
235
- return lA
245
+
246
+ # If reverseFlags is not provided, assume all lists should be sorted in ascending order
247
+ if reverseFlags is None:
248
+ reverseFlags = [False] * len(otherLists)
249
+ if not isinstance(otherLists, tuple):
250
+ print("Helper.Sort - Error: No other lists to use for sorting have been provided. Returning None.")
251
+ return None
252
+ if len(otherLists) < 1:
253
+ print("Helper.Sort - Error: The otherLists input parameter does not contain any valid lists. Returning None.")
254
+ return None
255
+ if not len(reverseFlags) == len(otherLists):
256
+ print("Helper.Sort - Error: The length of the reverseFlags input parameter is not equal to the number of input lists. Returning None.")
257
+ return None
258
+ # Convert other_lists to numeric and reverse if needed.
259
+ sorting_lists = []
260
+ for i, a_list in enumerate(otherLists):
261
+ temp_list = []
262
+ temp_set = list(set(a_list))
263
+ temp_set = sorted(temp_set)
264
+ if reverseFlags[i] == True:
265
+ temp_set.reverse()
266
+ for item in a_list:
267
+ temp_list.append(temp_set.index(item))
268
+ sorting_lists.append(temp_list)
269
+
270
+ combined_lists = list(zip(listA, *sorting_lists))
271
+ # Sort the combined list based on all the elements and reverse the lists as needed
272
+ combined_lists.sort(key=lambda x: tuple((-val) if reverse else val for val, reverse in zip(x[1:], reverseFlags)))
273
+ sorted_listA = [item[0] for item in combined_lists]
274
+ return sorted_listA
236
275
 
237
276
  @staticmethod
238
- def Transpose(l):
277
+ def Transpose(listA):
239
278
  """
240
- Transposes (swaps rows and columns) the input list.
279
+ Transposes the input list (swaps rows and columns).
241
280
 
242
281
  Parameters
243
282
  ----------
244
- l : list
283
+ listA : list
245
284
  The input list.
246
285
 
247
286
  Returns
@@ -250,26 +289,26 @@ class Helper:
250
289
  The transposed list.
251
290
 
252
291
  """
253
- if not isinstance(l, list):
292
+ if not isinstance(listA, list):
254
293
  return None
255
- length = len(l[0])
294
+ length = len(listA[0])
256
295
  transposed_list = []
257
296
  for i in range(length):
258
297
  tempRow = []
259
- for j in range(len(l)):
260
- tempRow.append(l[j][i])
298
+ for j in range(len(listA)):
299
+ tempRow.append(listA[j][i])
261
300
  transposed_list.append(tempRow)
262
301
  return transposed_list
263
302
 
264
303
  @staticmethod
265
- def Trim(l):
304
+ def Trim(listA):
266
305
  """
267
306
  Trims the input nested list so that each sublist has the same number of members. All lists are trimmed to match the length of the shortest list.
268
307
  For example Trim([[1,2,3],['m','n','o','p'],['a','b','c','d','e']]) yields [[1, 2, 3], ['m', 'n', 'o'], ['a', 'b', 'c']]
269
308
 
270
309
  Parameters
271
310
  ----------
272
- l : list
311
+ listA : list
273
312
  The input nested list.
274
313
 
275
314
  Returns
@@ -278,13 +317,13 @@ class Helper:
278
317
  The repeated list.
279
318
 
280
319
  """
281
- minLength = len(l[0])
320
+ minLength = len(listA[0])
282
321
  returnList = []
283
- for aSubList in l:
322
+ for aSubList in listA:
284
323
  newLength = len(aSubList)
285
324
  if newLength < minLength:
286
325
  minLength = newLength
287
- for anItem in l:
326
+ for anItem in listA:
288
327
  anItem = anItem[:minLength]
289
328
  returnList.append(anItem)
290
329
  return returnList
topologicpy/Plotly.py CHANGED
@@ -391,7 +391,7 @@ class Plotly:
391
391
  edgeMinGroup=None, edgeMaxGroup=None,
392
392
  showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
393
393
  edgeLegendGroup=2,
394
- showFaces=True, faceOpacity=0.5, faceColor="white",
394
+ showFaces=True, faceOpacity=0.5, faceColor="#FAFAFA",
395
395
  faceLabelKey=None, faceGroupKey=None, faceGroups=[],
396
396
  faceMinGroup=None, faceMaxGroup=None,
397
397
  showFaceLegend=False, faceLegendLabel="Topology Faces", faceLegendRank=3,
@@ -478,7 +478,7 @@ class Plotly:
478
478
  - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
479
479
  - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
480
480
  - A named CSS color.
481
- The default is "white".
481
+ The default is "#FAFAFA".
482
482
  faceLabelKey : str , optional
483
483
  The dictionary key to use to display the face label. The default is None.
484
484
  faceGroupKey : str , optional
@@ -677,7 +677,7 @@ class Plotly:
677
677
  return eData
678
678
 
679
679
 
680
- def faceData(vertices, faces, dictionaries=None, color="white",
680
+ def faceData(vertices, faces, dictionaries=None, color="#FAFAFA",
681
681
  opacity=0.5, labelKey=None, groupKey=None,
682
682
  minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Faces",
683
683
  legendGroup=3, legendRank=3, showLegend=True, intensities=None, colorScale="Viridis"):
@@ -786,7 +786,7 @@ class Plotly:
786
786
  data = []
787
787
 
788
788
  if showVertices:
789
- tp_vertices = Topology.SubTopologies(topology, subTopologyType="vertex")
789
+ tp_vertices = Topology.Vertices(topology)
790
790
  if not (tp_vertices == None or tp_vertices == []):
791
791
  vertices = []
792
792
  v_dictionaries = []
@@ -812,7 +812,7 @@ class Plotly:
812
812
  intensities = None
813
813
 
814
814
  if showEdges and topology.Type() > topologic.Vertex.Type():
815
- tp_edges = Topology.SubTopologies(topology, subTopologyType="edge")
815
+ tp_edges = Topology.Edges(topology)
816
816
  if not (tp_edges == None or tp_edges == []):
817
817
  e_dictionaries = []
818
818
  if edgeLabelKey or edgeGroupKey:
@@ -825,23 +825,24 @@ class Plotly:
825
825
  data.append(edgeData(vertices, edges, dictionaries=e_dictionaries, color=edgeColor, width=edgeWidth, labelKey=edgeLabelKey, groupKey=edgeGroupKey, minGroup=edgeMinGroup, maxGroup=edgeMaxGroup, groups=edgeGroups, legendLabel=edgeLegendLabel, legendGroup=edgeLegendGroup, legendRank=edgeLegendRank, showLegend=showEdgeLegend, colorScale=colorScale))
826
826
 
827
827
  if showFaces and topology.Type() >= topologic.Face.Type():
828
- tp_faces = Topology.SubTopologies(topology, subTopologyType="face")
828
+ if isinstance(topology, topologic.Face):
829
+ tp_faces = [topology]
830
+ else:
831
+ tp_faces = Topology.Faces(topology)
829
832
  if not(tp_faces == None or tp_faces == []):
830
833
  f_dictionaries = []
831
834
  all_triangles = []
832
835
  for tp_face in tp_faces:
833
- shell = Topology.Triangulate(tp_face, transferDictionaries = False, tolerance=tolerance)
834
- if isinstance(shell, topologic.Face):
835
- triangles = [shell]
836
- else:
837
- triangles = Topology.SubTopologies(shell, subTopologyType="face")
836
+ triangles = Face.Triangulate(tp_face, tolerance=tolerance)
838
837
  for tri in triangles:
839
838
  if faceLabelKey or faceGroupKey:
840
839
  d = Topology.Dictionary(tp_face)
841
840
  f_dictionaries.append(d)
842
841
  if d:
843
842
  _ = Topology.SetDictionary(tri, d)
844
- all_triangles.append(tri)
843
+ c = Topology.Centroid(tri)
844
+ if Face.IsInternal(tp_face, c):
845
+ all_triangles.append(tri)
845
846
  if len(all_triangles) > 0:
846
847
  f_cluster = Cluster.ByTopologies(all_triangles)
847
848
  geo = Topology.Geometry(f_cluster, mantissa=mantissa)
@@ -1378,7 +1379,7 @@ class Plotly:
1378
1379
  showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
1379
1380
  edgeLegendGroup=2,
1380
1381
 
1381
- showFaces=True, faceOpacity=0.5, faceColor="white",
1382
+ showFaces=True, faceOpacity=0.5, faceColor="#FAFAFA",
1382
1383
  faceLabelKey=None, faceGroupKey=None, faceGroups=[],
1383
1384
  faceMinGroup=None, faceMaxGroup=None,
1384
1385
  showFaceLegend=False, faceLegendLabel="Topology Faces", faceLegendRank=3,
@@ -1473,7 +1474,7 @@ class Plotly:
1473
1474
  - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
1474
1475
  - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
1475
1476
  - A named CSS color.
1476
- The default is "white".
1477
+ The default is "#FAFAFA".
1477
1478
  faceLabelKey : str , optional
1478
1479
  The dictionary key to use to display the face label. The default is None.
1479
1480
  faceGroupKey : str , optional