topologicpy 0.8.17__py3-none-any.whl → 0.8.19__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/Graph.py CHANGED
@@ -8850,7 +8850,7 @@ class Graph:
8850
8850
  return max_flow
8851
8851
 
8852
8852
  @staticmethod
8853
- def MeshData(graph, tolerance: float = 0.0001):
8853
+ def MeshData(graph, mantissa: int = 6, tolerance: float = 0.0001):
8854
8854
  """
8855
8855
  Returns the mesh data of the input graph.
8856
8856
 
@@ -8858,6 +8858,8 @@ class Graph:
8858
8858
  ----------
8859
8859
  graph : topologic_core.Graph
8860
8860
  The input graph.
8861
+ mantissa : int , optional
8862
+ The desired length of the mantissa. The default is 6.
8861
8863
  tolerance : float , optional
8862
8864
  The desired tolerance. The default is 0.0001.
8863
8865
 
@@ -8880,7 +8882,7 @@ class Graph:
8880
8882
  m_vertices = []
8881
8883
  v_dicts = []
8882
8884
  for g_vertex in g_vertices:
8883
- m_vertices.append(Vertex.Coordinates(g_vertex))
8885
+ m_vertices.append(Vertex.Coordinates(g_vertex, mantissa=mantissa))
8884
8886
  d = Dictionary.PythonDictionary(Topology.Dictionary(g_vertex))
8885
8887
  v_dicts.append(d)
8886
8888
  g_edges = Graph.Edges(graph)
@@ -9778,6 +9780,31 @@ class Graph:
9778
9780
  _ = graph.RemoveEdges([edge], tolerance) # Hook to Core
9779
9781
  return graph
9780
9782
 
9783
+ @staticmethod
9784
+ def RemoveIsolatedVertices(graph, tolerance=0.0001):
9785
+ """
9786
+ Removes all isolated vertices from the input graph.
9787
+
9788
+ Parameters
9789
+ ----------
9790
+ graph : topologic_core.Graph
9791
+ The input graph.
9792
+ tolerance : float , optional
9793
+ The desired tolerance. The default is 0.0001.
9794
+
9795
+ Returns
9796
+ -------
9797
+ topologic_core.Graph
9798
+ The input graph with all isolated vertices removed.
9799
+
9800
+ """
9801
+ from topologicpy.Topology import Topology
9802
+
9803
+ vertices = Graph.Vertices(graph)
9804
+ edges = Graph.Edges(graph)
9805
+ vertices = [v for v in vertices if Graph.VertexDegree(graph, v) > 0]
9806
+ return Graph.ByVerticesEdges(vertices, edges)
9807
+
9781
9808
  @staticmethod
9782
9809
  def RemoveVertex(graph, vertex, tolerance=0.0001):
9783
9810
  """
@@ -10299,6 +10326,125 @@ class Graph:
10299
10326
  v = Topology.SetDictionary(v, d)
10300
10327
  return return_graph
10301
10328
 
10329
+ @staticmethod
10330
+ def SubGraphMatches(subGraph, superGraph, strict=False, vertexMatcher=None, vertexKey: str = "id", mantissa: int = 6, tolerance: float = 0.0001):
10331
+ """
10332
+ Finds all subgraph matches from `subgraph` into `supergraph`.
10333
+ A match is valid if:
10334
+ - Each subgraph vertex maps to a unique supergraph vertex either by the vertexMatcher function or through matching the vertexKey values.
10335
+ - Each subgraph edge is represented either by an edge (if strict is set to True) or by an edge or a path (if strict is set to False) in the supergraph.
10336
+
10337
+ Parameters
10338
+ ----------
10339
+ subGraph : topologic_core.Graph
10340
+ The input subgraph.
10341
+ superGraph : topologic_core.Graph
10342
+ The input supergraph.
10343
+ strict : bool , optional
10344
+ If set to True, each subgraph edge must be represented by a single edge in the supergraph. Otherwise, an edge in the subgraph can be represented either with an edge or a path in the supergraph. The default is False.
10345
+ vertexMatcher : callable, optional
10346
+ If specified, this function is called to check if two vertices are matched. The format must be vertex_matcher(sub_vertex, super_vertex, mantissa, tolerance) -> bool.
10347
+ vertexKey : str , optional
10348
+ The dictionary key to use for vertex matching if the vertexMatcher input parameter is set to None. The default is "id".
10349
+ mantissa : int , optional
10350
+ The desired length of the mantissa. The default is 6.
10351
+ tolerance : float , optional
10352
+ The desired tolerance. The default is 0.0001.
10353
+
10354
+ Returns
10355
+ -------
10356
+ list
10357
+ A list of subgraphs matched to the supergraph. Each vertex in the matched subgraph has a dictionary that merges the keys and values from both the subgraph and the supergraph.
10358
+ """
10359
+
10360
+ from topologicpy.Vertex import Vertex
10361
+ from topologicpy.Edge import Edge
10362
+ from topologicpy.Dictionary import Dictionary
10363
+ from topologicpy.Topology import Topology
10364
+ import itertools
10365
+
10366
+ sub_vertices = Graph.Vertices(subGraph)
10367
+ super_vertices = Graph.Vertices(superGraph)
10368
+
10369
+ sub_ids = [Dictionary.ValueAtKey(Topology.Dictionary(v), vertexKey) for v in sub_vertices]
10370
+
10371
+ # Map vertex instance to index in sub_vertices
10372
+ sub_vertex_indices = {vid: i for i, vid in enumerate(sub_ids)}
10373
+
10374
+ # Default matcher by dictionary vertexKey
10375
+ if vertexMatcher is None:
10376
+ def vertexMatcher(v1, v2, mantissa=mantissa, tolerance=tolerance):
10377
+ d1 = Topology.Dictionary(v1)
10378
+ d2 = Topology.Dictionary(v2)
10379
+ id1 = Dictionary.ValueAtKey(d1, vertexKey) if d1 else None
10380
+ id2 = Dictionary.ValueAtKey(d2, vertexKey) if d2 else None
10381
+ return id1 == id2 and id1 is not None
10382
+
10383
+ # Step 1: Build candidate list for each subgraph vertex (by index)
10384
+ candidate_map = {}
10385
+ for i, sv in enumerate(sub_vertices):
10386
+ candidates = [v for v in super_vertices if vertexMatcher(sv, v, mantissa=mantissa, tolerance=tolerance)]
10387
+ if not candidates:
10388
+ return [] # No match for this vertex
10389
+ candidate_map[i] = candidates
10390
+
10391
+ # Step 2: Generate all injective mappings
10392
+ all_matches = []
10393
+ sub_indices = list(candidate_map.keys())
10394
+ candidate_lists = [candidate_map[i] for i in sub_indices]
10395
+
10396
+ for combo in itertools.product(*candidate_lists):
10397
+ if len(set(combo)) < len(combo):
10398
+ continue # Not injective
10399
+
10400
+ mapping = dict(zip(sub_indices, combo))
10401
+
10402
+ # Step 3: Check that each subgraph edge corresponds to a path in supergraph
10403
+ valid = True
10404
+ for edge in Graph.Edges(subGraph):
10405
+ sv1 = Edge.StartVertex(edge)
10406
+ sv2 = Edge.EndVertex(edge)
10407
+ d1 = Topology.Dictionary(sv1)
10408
+ d2 = Topology.Dictionary(sv2)
10409
+ id1 = Dictionary.ValueAtKey(d1, vertexKey) if d1 else None
10410
+ id2 = Dictionary.ValueAtKey(d2, vertexKey) if d2 else None
10411
+ if id1 == None or id2 == None:
10412
+ continue
10413
+ else:
10414
+ i1 = sub_vertex_indices[id1]
10415
+ i2 = sub_vertex_indices[id2]
10416
+ gv1 = mapping[i1]
10417
+ gv2 = mapping[i2]
10418
+
10419
+ path = Graph.ShortestPath(superGraph, gv1, gv2)
10420
+ if not path:
10421
+ valid = False
10422
+ break
10423
+ elif strict:
10424
+ if Topology.IsInstance(path, "Wire"):
10425
+ if len(Topology.Edges(path)) > 1:
10426
+ valid = False
10427
+ break
10428
+
10429
+ if valid:
10430
+ all_matches.append(mapping)
10431
+
10432
+ matched_subgraphs = []
10433
+ if len(all_matches) > 0:
10434
+ vertex_dictionaries = []
10435
+ d = Graph.MeshData(subGraph)
10436
+ subgraph_edges = d['edges']
10437
+ edge_dictionaries = d['edgeDictionaries']
10438
+ positions = []
10439
+ for i, mapping in enumerate(all_matches, 1):
10440
+ for svid, gv in mapping.items():
10441
+ positions.append(Vertex.Coordinates(gv))
10442
+ sd = Topology.Dictionary(sub_vertices[svid])
10443
+ gd = Topology.Dictionary(gv)
10444
+ vertex_dictionaries.append(Dictionary.ByMergedDictionaries(sd, gd))
10445
+ matched_subgraphs.append(Graph.ByMeshData(positions, subgraph_edges, vertexDictionaries=vertex_dictionaries, edgeDictionaries=edge_dictionaries))
10446
+ return matched_subgraphs
10447
+
10302
10448
  @staticmethod
10303
10449
  def _topological_distance(g, start, target):
10304
10450
  from collections import deque
topologicpy/Plotly.py CHANGED
@@ -282,6 +282,10 @@ class Plotly:
282
282
  vertexSize: float = 10,
283
283
  vertexSizeKey: str = None,
284
284
  vertexLabelKey: str = None,
285
+ vertexBorderColor: str = "black",
286
+ vertexBorderWidth: float = 1,
287
+ vertexBorderColorKey: str = None,
288
+ vertexBorderWidthKey: float = None,
285
289
  vertexGroupKey: str = None,
286
290
  vertexGroups: list = [],
287
291
  vertexMinGroup = None,
@@ -422,6 +426,10 @@ class Plotly:
422
426
  colorKey=vertexColorKey,
423
427
  size=vertexSize,
424
428
  sizeKey=vertexSizeKey,
429
+ borderColor=vertexBorderColor,
430
+ borderWidth=vertexBorderWidth,
431
+ borderColorKey=vertexBorderColorKey,
432
+ borderWidthKey=vertexBorderWidthKey,
425
433
  labelKey=vertexLabelKey,
426
434
  showVertexLabel=showVertexLabel,
427
435
  groupKey=vertexGroupKey,
@@ -433,24 +441,7 @@ class Plotly:
433
441
  legendRank=vertexLegendRank,
434
442
  showLegend=showVertexLegend,
435
443
  colorScale=colorScale)
436
-
437
- # v_data = Plotly.DataByTopology(e_cluster,
438
- # vertexColor=vertexColor,
439
- # vertexColorKey=vertexColorKey,
440
- # vertexSize=vertexSize,
441
- # vertexSizeKey=vertexSizeKey,
442
- # vertexLabelKey=vertexLabelKey,
443
- # showVertexLabel=showVertexLabel,
444
- # vertexGroupKey=vertexGroupKey,
445
- # vertexMinGroup=vertexMinGroup,
446
- # vertexMaxGroup=vertexMaxGroup,
447
- # vertexGroups=vertexGroups,
448
- # showVertexLegend=showVertexLegend,
449
- # vertexLegendLabel=vertexLegendLabel,
450
- # vertexLegendGroup=vertexLegendGroup,
451
- # vertexLegendRank=vertexLegendRank,
452
- # colorScale=colorScale)
453
- data += [v_data]
444
+ data += v_data
454
445
 
455
446
  if showEdges:
456
447
  e_dictionaries = []
@@ -486,17 +477,45 @@ class Plotly:
486
477
  return data
487
478
 
488
479
  @staticmethod
489
- def vertexData(vertices, dictionaries=[], color="black", colorKey=None, size=1.1, sizeKey=None, labelKey=None, showVertexLabel = False, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Vertices", legendGroup=1, legendRank=1, showLegend=True, colorScale="Viridis"):
480
+ def vertexData(vertices,
481
+ dictionaries=[],
482
+ color="black",
483
+ colorKey=None,
484
+ size=1.1,
485
+ sizeKey=None,
486
+ borderColor="black",
487
+ borderWidth=0,
488
+ borderColorKey=None,
489
+ borderWidthKey=None,
490
+ labelKey=None,
491
+ showVertexLabel = False,
492
+ groupKey=None,
493
+ minGroup=None,
494
+ maxGroup=None,
495
+ groups=[],
496
+ legendLabel="Topology Vertices",
497
+ legendGroup=1,
498
+ legendRank=1,
499
+ showLegend=True,
500
+ colorScale="Viridis"):
490
501
  from topologicpy.Dictionary import Dictionary
491
502
  from topologicpy.Color import Color
492
503
  x = []
493
504
  y = []
494
505
  z = []
495
506
  n = len(str(len(vertices)))
496
- sizes = [size for i in range(len(vertices))]
497
- labels = ["Vertex_"+str(i+1).zfill(n) for i in range(len(vertices))]
498
- colors = [Color.AnyToHex(color) for i in range(len(vertices))]
499
- if colorKey or sizeKey or labelKey or groupKey:
507
+ sizes = []
508
+ labels = []
509
+ colors = []
510
+ borderColors = []
511
+ borderSizes = []
512
+ for i in range(len(vertices)):
513
+ sizes.append(size)
514
+ labels.append("Vertex_"+str(i+1).zfill(n))
515
+ colors.append(Color.AnyToHex(color))
516
+ borderColors.append(borderColor)
517
+ borderSizes.append(size+borderWidth*2)
518
+ if colorKey or sizeKey or borderColorKey or borderWidthKey or labelKey or groupKey:
500
519
  if groups:
501
520
  if len(groups) > 0:
502
521
  if type(groups[0]) == int or type(groups[0]) == float:
@@ -515,10 +534,8 @@ class Plotly:
515
534
  x.append(v[0])
516
535
  y.append(v[1])
517
536
  z.append(v[2])
518
- #colors.append(Color.AnyToHex(color))
519
- #labels.append("Vertex_"+str(m+1).zfill(n))
520
- #sizes.append(max(size, 1.1))
521
537
  if len(dictionaries) > 0:
538
+
522
539
  d = dictionaries[m]
523
540
  if d:
524
541
  if not colorKey == None:
@@ -533,6 +550,16 @@ class Plotly:
533
550
  sizes[m] = size
534
551
  if sizes[m] <= 0:
535
552
  sizes[m] = 1.1
553
+ if not borderColorKey == None:
554
+ temp_color = Dictionary.ValueAtKey(d, key=borderColorKey)
555
+ if not temp_color == None:
556
+ borderColors[m] = Color.AnyToHex(temp_color)
557
+ if not borderWidthKey == None:
558
+ temp_width = Dictionary.ValueAtKey(d, key=borderWidthKey)
559
+ if temp_width == None or temp_width <= 0:
560
+ borderSizes[m] = 0
561
+ else:
562
+ borderSizes[m] = sizes[m] + temp_width*2
536
563
  if not groupKey == None:
537
564
  c_value = Dictionary.ValueAtKey(d, key=groupKey)
538
565
  if not c_value == None:
@@ -565,14 +592,16 @@ class Plotly:
565
592
  mode = "markers+text"
566
593
  else:
567
594
  mode = "markers"
568
- vData= go.Scatter3d(x=x,
595
+ vData2 = go.Scatter3d(x=x,
569
596
  y=y,
570
597
  z=z,
571
598
  name=legendLabel,
572
599
  showlegend=showLegend,
573
600
  marker=dict(color=colors,
574
- size=sizes,
575
- opacity=1),
601
+ size=sizes,
602
+ symbol="circle",
603
+ opacity=1,
604
+ sizemode="diameter"),
576
605
  mode=mode,
577
606
  legendgroup=legendGroup,
578
607
  legendrank=legendRank,
@@ -580,7 +609,24 @@ class Plotly:
580
609
  hoverinfo='text',
581
610
  hovertext=labels
582
611
  )
583
- return vData
612
+ if borderWidth > 0 or borderWidthKey:
613
+ vData1 = go.Scatter3d(x=x,
614
+ y=y,
615
+ z=z,
616
+ name=legendLabel,
617
+ showlegend=showLegend,
618
+ marker=dict(color=borderColors,
619
+ size=borderSizes,
620
+ symbol="circle",
621
+ opacity=1,
622
+ sizemode="diameter"),
623
+ mode=mode
624
+ )
625
+
626
+ return_value = [vData1]+[vData2]
627
+ else:
628
+ return_value = [vData2]
629
+ return return_value
584
630
 
585
631
  @staticmethod
586
632
  def edgeData(vertices, edges, dictionaries=None, color="black", colorKey=None, width=1, widthKey=None, labelKey=None, showEdgeLabel = False, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Edges", legendGroup=2, legendRank=2, showLegend=True, colorScale="Viridis"):
@@ -716,11 +762,15 @@ class Plotly:
716
762
  @staticmethod
717
763
  def DataByTopology(topology,
718
764
  showVertices=True,
719
- vertexSize=1.1,
765
+ vertexSize=2.8,
720
766
  vertexSizeKey=None,
721
767
  vertexColor="black",
722
768
  vertexColorKey=None,
723
769
  vertexLabelKey=None,
770
+ vertexBorderColor: str = "black",
771
+ vertexBorderWidth: float = 0,
772
+ vertexBorderColorKey: str = None,
773
+ vertexBorderWidthKey: float = None,
724
774
  showVertexLabel=False,
725
775
  vertexGroupKey=None,
726
776
  vertexGroups=[],
@@ -771,7 +821,7 @@ class Plotly:
771
821
  showVertices : bool , optional
772
822
  If set to True the vertices will be drawn. Otherwise, they will not be drawn. The default is True.
773
823
  vertexSize : float , optional
774
- The desired size of the vertices. The default is 1.1.
824
+ The desired size of the output vertices. The default is 1.1.
775
825
  vertexSizeKey : str , optional
776
826
  The dictionary key under which to find the vertex size.The default is None.
777
827
  vertexColor : str , optional
@@ -784,6 +834,16 @@ class Plotly:
784
834
  The default is "black".
785
835
  vertexColorKey : str , optional
786
836
  The dictionary key under which to find the vertex color.The default is None.
837
+ vertexBorderWidth : float , optional
838
+ The desired width of the border of the output vertices. The default is 1.
839
+ vertexBorderColor : str , optional
840
+ The desired color of the border of the output vertices. This can be any plotly color string and may be specified as:
841
+ - A hex string (e.g. '#ff0000')
842
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
843
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
844
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
845
+ - A named CSS color.
846
+ The default is "black".
787
847
  vertexLabelKey : str , optional
788
848
  The dictionary key to use to display the vertex label. The default is None.
789
849
  vertexGroupKey : str , optional
@@ -1066,11 +1126,31 @@ class Plotly:
1066
1126
  if showVertices:
1067
1127
  if len(vertices) == 0:
1068
1128
  for i, tp_v in enumerate(tp_vertices):
1069
- if vertexColorKey or vertexSizeKey or vertexLabelKey or vertexGroupKey:
1129
+ if vertexColorKey or vertexSizeKey or vertexBorderColorKey or vertexBorderWidthKey or vertexLabelKey or vertexGroupKey:
1070
1130
  d = Topology.Dictionary(tp_v)
1071
1131
  v_dictionaries.append(d)
1072
1132
  vertices.append([Vertex.X(tp_v, mantissa=mantissa), Vertex.Y(tp_v, mantissa=mantissa), Vertex.Z(tp_v, mantissa=mantissa)])
1073
- data.append(Plotly.vertexData(vertices, dictionaries=v_dictionaries, color=vertexColor, colorKey=vertexColorKey, size=vertexSize, sizeKey=vertexSizeKey, labelKey=vertexLabelKey, showVertexLabel=showVertexLabel, groupKey=vertexGroupKey, minGroup=vertexMinGroup, maxGroup=vertexMaxGroup, groups=vertexGroups, legendLabel=vertexLegendLabel, legendGroup=vertexLegendGroup, legendRank=vertexLegendRank, showLegend=showVertexLegend, colorScale=colorScale))
1133
+ data.extend(Plotly.vertexData(vertices,
1134
+ dictionaries=v_dictionaries,
1135
+ color=vertexColor,
1136
+ colorKey=vertexColorKey,
1137
+ size=vertexSize,
1138
+ sizeKey=vertexSizeKey,
1139
+ borderColor=vertexBorderColor,
1140
+ borderWidth=vertexBorderWidth,
1141
+ borderColorKey=vertexBorderColorKey,
1142
+ borderWidthKey=vertexBorderWidthKey,
1143
+ labelKey=vertexLabelKey,
1144
+ showVertexLabel=showVertexLabel,
1145
+ groupKey=vertexGroupKey,
1146
+ minGroup=vertexMinGroup,
1147
+ maxGroup=vertexMaxGroup,
1148
+ groups=vertexGroups,
1149
+ legendLabel=vertexLegendLabel,
1150
+ legendGroup=vertexLegendGroup,
1151
+ legendRank=vertexLegendRank,
1152
+ showLegend=showVertexLegend,
1153
+ colorScale=colorScale))
1074
1154
 
1075
1155
  if showEdges and Topology.Type(topology) > Topology.TypeID("Vertex"):
1076
1156
  if Topology.Type(topology) == Topology.TypeID("Edge"):
topologicpy/Topology.py CHANGED
@@ -3438,7 +3438,7 @@ class Topology():
3438
3438
  elif parts[0] == 'usemtl':
3439
3439
  current_material = parts[1]
3440
3440
  elif parts[0] == 'g' or parts[0] == 'o':
3441
- current_group = parts[1] if len(parts) > 1 else None
3441
+ current_group = ' '.join(parts[1:]) if len(parts) > 1 else None
3442
3442
 
3443
3443
  obj_data = {
3444
3444
  'vertices': vertices,
@@ -7383,7 +7383,7 @@ class Topology():
7383
7383
  return topology.RemoveContents(contents)
7384
7384
 
7385
7385
  @staticmethod
7386
- def RemoveCoplanarFaces(topology, epsilon=0.01, tolerance=0.0001):
7386
+ def RemoveCoplanarFaces(topology, epsilon=0.01, tolerance=0.0001, silent: bool = False):
7387
7387
  """
7388
7388
  Removes coplanar faces in the input topology
7389
7389
 
@@ -7395,6 +7395,8 @@ class Topology():
7395
7395
  The desired epsilon (another form of tolerance) for finding if two faces are coplanar. The default is 0.01.
7396
7396
  tolerance : float , optional
7397
7397
  The desired tolerance. The default is 0.0001.
7398
+ silent : bool , optional
7399
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
7398
7400
 
7399
7401
  Returns
7400
7402
  -------
@@ -7410,7 +7412,8 @@ class Topology():
7410
7412
  from topologicpy.Cluster import Cluster
7411
7413
 
7412
7414
  if not Topology.IsInstance(topology, "Topology"):
7413
- print("Topology.RemoveCoplanarFaces - Error: The input topology parameter is not a valid topologic topology. Returning None.")
7415
+ if not silent:
7416
+ print("Topology.RemoveCoplanarFaces - Error: The input topology parameter is not a valid topologic topology. Returning None.")
7414
7417
  return None
7415
7418
  t = Topology.Type(topology)
7416
7419
  if (t == Topology.TypeID("Vertex")) or (t == Topology.TypeID("Edge")) or (t == Topology.TypeID("Wire")) or (t == Topology.TypeID("Face")):
@@ -7459,7 +7462,8 @@ class Topology():
7459
7462
  if Topology.IsInstance(f, "Face"):
7460
7463
  final_faces.append(f)
7461
7464
  else:
7462
- print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
7465
+ if not silent:
7466
+ print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
7463
7467
  final_faces += Shell.Faces(t)
7464
7468
  else: # It is a cluster
7465
7469
  shells = Topology.Shells(t)
@@ -7468,7 +7472,8 @@ class Topology():
7468
7472
  if Topology.IsInstance(f, "Face"):
7469
7473
  final_faces.append(f)
7470
7474
  else:
7471
- print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
7475
+ if not silent:
7476
+ print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
7472
7477
  final_faces += Shell.Faces(shell)
7473
7478
  if len(shells) == 0:
7474
7479
  faces = Topology.Faces(t)
@@ -7477,16 +7482,16 @@ class Topology():
7477
7482
  final_faces += faces
7478
7483
  return_topology = None
7479
7484
  if Topology.IsInstance(topology, "CellComplex"):
7480
- return_topology = CellComplex.ByFaces(final_faces, tolerance=tolerance)
7485
+ return_topology = CellComplex.ByFaces(final_faces, tolerance=tolerance, silent=silent)
7481
7486
  elif Topology.IsInstance(topology, "Cell"):
7482
- return_topology = Cell.ByFaces(final_faces, tolerance=tolerance)
7487
+ return_topology = Cell.ByFaces(final_faces, tolerance=tolerance, silent=silent)
7483
7488
  elif Topology.IsInstance(topology, "Shell"):
7484
7489
  if len(final_faces) == 1:
7485
7490
  return_topology = final_faces[0]
7486
7491
  else:
7487
- return_topology = Shell.ByFaces(final_faces, tolerance=tolerance)
7492
+ return_topology = Shell.ByFaces(final_faces, tolerance=tolerance, silent=silent)
7488
7493
  if not Topology.IsInstance(return_topology, "Topology"):
7489
- return_topology = Cluster.ByTopologies(final_faces)
7494
+ return_topology = Cluster.ByTopologies(final_faces, silent=silent)
7490
7495
  return return_topology
7491
7496
 
7492
7497
  @staticmethod
@@ -8495,10 +8500,14 @@ class Topology():
8495
8500
  nameKey = "name",
8496
8501
  opacityKey = "opacity",
8497
8502
  showVertices=True,
8498
- vertexSize=None,
8503
+ vertexSize=2.8,
8499
8504
  vertexSizeKey = None,
8500
8505
  vertexColor="black",
8501
8506
  vertexColorKey = None,
8507
+ vertexBorderWidth=0,
8508
+ vertexBorderColor="black",
8509
+ vertexBorderWidthKey=None,
8510
+ vertexBorderColorKey=None,
8502
8511
  vertexLabelKey=None,
8503
8512
  showVertexLabel= False,
8504
8513
  vertexGroupKey=None,
@@ -8597,6 +8606,16 @@ class Topology():
8597
8606
  The default is "black".
8598
8607
  vertexColorKey : str , optional
8599
8608
  The key under which to find the color of the vertex. The default is None.
8609
+ vertexBorderWidth : float , optional
8610
+ The desired width of the borders of the output vertices. The default is 0.
8611
+ vertexBorderColor : str , optional
8612
+ The desired color of the borders of the output vertices. This can be any plotly color string and may be specified as:
8613
+ - A hex string (e.g. '#ff0000')
8614
+ - An rgb/rgba string (e.g. 'rgb(255,0,0)')
8615
+ - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
8616
+ - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
8617
+ - A named CSS color.
8618
+ The default is "black".
8600
8619
  vertexLabelKey : str , optional
8601
8620
  The dictionary key to use to display the vertex label. The default is None.
8602
8621
  showVertexLabels : bool , optional
@@ -8793,7 +8812,7 @@ class Topology():
8793
8812
  vll = name+" ("+vertexLegendLabel+")"
8794
8813
  ell = name+" ("+edgeLegendLabel+")"
8795
8814
 
8796
- data += Plotly.DataByGraph(topology,
8815
+ data.extend(Plotly.DataByGraph(topology,
8797
8816
  sagitta=sagitta,
8798
8817
  absolute=absolute,
8799
8818
  sides=sides,
@@ -8802,6 +8821,10 @@ class Topology():
8802
8821
  vertexColorKey=vertexColorKey,
8803
8822
  vertexSize=vSize,
8804
8823
  vertexSizeKey=vertexSizeKey,
8824
+ vertexBorderColor= vertexBorderColor,
8825
+ vertexBorderWidth=vertexBorderWidth,
8826
+ vertexBorderColorKey= vertexBorderColorKey,
8827
+ vertexBorderWidthKey=vertexBorderWidthKey,
8805
8828
  vertexLabelKey=vertexLabelKey,
8806
8829
  vertexGroupKey=vertexGroupKey,
8807
8830
  vertexGroups=vertexGroups,
@@ -8829,7 +8852,7 @@ class Topology():
8829
8852
  edgeLegendRank= (graph_counter+2),
8830
8853
  edgeLegendGroup=(graph_counter+2),
8831
8854
  colorScale=colorScale,
8832
- silent=silent)
8855
+ silent=silent))
8833
8856
  graph_counter += offset
8834
8857
  else:
8835
8858
  name = Dictionary.ValueAtKey(d, nameKey) or "Untitled"
@@ -8847,12 +8870,16 @@ class Topology():
8847
8870
  eColor = edgeColor
8848
8871
  if not d == None:
8849
8872
  faceOpacity = Dictionary.ValueAtKey(d, opacityKey) or faceOpacity
8850
- data += Plotly.DataByTopology(topology=topology,
8873
+ data.extend(Plotly.DataByTopology(topology=topology,
8851
8874
  showVertices=showVertices,
8852
8875
  vertexSize=vSize,
8853
8876
  vertexSizeKey=vertexSizeKey,
8854
8877
  vertexColor=vertexColor,
8855
8878
  vertexColorKey=vertexColorKey,
8879
+ vertexBorderWidth=vertexBorderWidth,
8880
+ vertexBorderColor=vertexBorderColor,
8881
+ vertexBorderColorKey= vertexBorderColorKey,
8882
+ vertexBorderWidthKey=vertexBorderWidthKey,
8856
8883
  vertexLabelKey=vertexLabelKey,
8857
8884
  showVertexLabel=showVertexLabel,
8858
8885
  vertexGroupKey=vertexGroupKey,
@@ -8896,7 +8923,7 @@ class Topology():
8896
8923
  intensities=intensities,
8897
8924
  colorScale=colorScale,
8898
8925
  mantissa=mantissa,
8899
- tolerance=tolerance)
8926
+ tolerance=tolerance))
8900
8927
  topology_counter += offset
8901
8928
  figure = Plotly.FigureByData(data=data, width=width, height=height,
8902
8929
  xAxis=xAxis, yAxis=yAxis, zAxis=zAxis, axisSize=axisSize,
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.8.17'
1
+ __version__ = '0.8.19'
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: topologicpy
3
- Version: 0.8.17
3
+ Version: 0.8.19
4
4
  Summary: An AI-Powered Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: AGPL v3 License
@@ -40,6 +40,7 @@ Requires-Dist: webcolors
40
40
  Requires-Dist: topologic_core>=7.0.1
41
41
  Provides-Extra: test
42
42
  Requires-Dist: pytest-xdist>=2.4.0; extra == "test"
43
+ Dynamic: license-file
43
44
 
44
45
  # topologicpy
45
46
 
@@ -11,26 +11,26 @@ topologicpy/Dictionary.py,sha256=7h-Gszgnt2OEOvOSADJ4pa-mTNlhQ9cuIiB5WHEW6aY,339
11
11
  topologicpy/Edge.py,sha256=yxkCVDYBflJNEYxnjMmlyvbkpg8TNy7y5bSH3yQ4jzs,71418
12
12
  topologicpy/EnergyModel.py,sha256=UoQ9Jm-hYsN383CbcLKw-y6BKitRHj0uyh84yQ-8ACg,53856
13
13
  topologicpy/Face.py,sha256=SlhB8L7BpDjd4a9YZE4UJ3zoGuF1oq9MSpuesEWro_Q,184847
14
- topologicpy/Graph.py,sha256=FBmiMObzztPwZFJ2T846Ivz0Y1kpzMF0sF-PDUMPk4o,498946
14
+ topologicpy/Graph.py,sha256=FOG3TyXfA1K9c4V3PXKP2vbO2L7HOnGj28pAVnuVRqo,505547
15
15
  topologicpy/Grid.py,sha256=2s9cSlWldivn1i9EUz4OOokJyANveqmRe_vR93CAndI,18245
16
16
  topologicpy/Helper.py,sha256=4H5KPiv_eiEs489UOOyGLe9RaeoZIfmMh3mk_YCHmXg,29100
17
17
  topologicpy/Honeybee.py,sha256=uDVtDbloydNoaBFcSNukKL_2PLyD6XKkCp1VHz1jtaU,21751
18
18
  topologicpy/Matrix.py,sha256=i22RLP5ebUAMuU7V1tZ__Z4lf1pg9fzq9nENsDZUV74,22779
19
19
  topologicpy/Neo4j.py,sha256=BKOF29fRgXmdpMGkrNzuYbyqgCJ6ElPPMYlfTxXiVbc,22392
20
- topologicpy/Plotly.py,sha256=RU_VioIRLGIYzwyKI9OQHOx9OxxGppdpagysgTbdxIE,115942
20
+ topologicpy/Plotly.py,sha256=gSe3tWLgF75-rPDjqw7riUIJpv0j_K7hedoxi3-OptE,119244
21
21
  topologicpy/Polyskel.py,sha256=ro5in--VT_uag55r5xymU5ufyAahsovIiJwyiqG_qH8,27082
22
22
  topologicpy/PyG.py,sha256=LU9LCCzjxGPUM31qbaJXZsTvniTtgugxJY7y612t4A4,109757
23
23
  topologicpy/Shell.py,sha256=--dJoSdz6BapxVEyG2DI0W5apO_xwLORj5qmR15yl2Y,87983
24
24
  topologicpy/Speckle.py,sha256=AlsGlSDuKRtX5jhVsPNSSjjbZis079HbUchDH_5RJmE,18187
25
25
  topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
26
- topologicpy/Topology.py,sha256=gkKLazHKrSwrCt4lZckNuUlXQ1e9rUvK2XqjUMscFGM,476658
26
+ topologicpy/Topology.py,sha256=QY195KZ5EostlGRnsPGSFglRIU0tunD2CiwsFPfpOqY,478447
27
27
  topologicpy/Vector.py,sha256=GkGt-aJ591IJ2IPffMAudvITLDPi2qZibZc4UAav6m8,42407
28
28
  topologicpy/Vertex.py,sha256=q99IrWwdNlvVfUXz6iP8icmP8NzP2nsiqtgnF9Jnpx8,80913
29
29
  topologicpy/Wire.py,sha256=IVPzBKsckuxC-rHvwxmvtVF7PpApz2lhPHomtQMo_kg,228499
30
30
  topologicpy/__init__.py,sha256=vlPCanUbxe5NifC4pHcnhSzkmmYcs_UrZrTlVMsxcFs,928
31
- topologicpy/version.py,sha256=jgMQSjzTF3zegQBB2-KO1QeuJ1ufZ8T-ts7A2g5atuc,23
32
- topologicpy-0.8.17.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
- topologicpy-0.8.17.dist-info/METADATA,sha256=KNPPFYSnLPlGCabjuBHARXEBTvQQFuFlUtH7ZutDPJ8,10513
34
- topologicpy-0.8.17.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
35
- topologicpy-0.8.17.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
- topologicpy-0.8.17.dist-info/RECORD,,
31
+ topologicpy/version.py,sha256=-CEaM_uLk3M3OyXlLqkLmTj4IViw6vFkTKIRWVX31LI,23
32
+ topologicpy-0.8.19.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
+ topologicpy-0.8.19.dist-info/METADATA,sha256=pFjIJ2TfH28CMrW4rFY9OZMo-4ROp3hzpRns8o6CF08,10535
34
+ topologicpy-0.8.19.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
35
+ topologicpy-0.8.19.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
+ topologicpy-0.8.19.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.1.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5