topologicpy 0.7.62__py3-none-any.whl → 0.7.63__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/Cluster.py CHANGED
@@ -165,29 +165,50 @@ class Cluster():
165
165
  from topologicpy.Dictionary import Dictionary
166
166
  from topologicpy.Topology import Topology
167
167
  from topologicpy.Helper import Helper
168
+ import inspect
168
169
 
169
170
  if len(args) == 0:
170
- print("Cluster.ByTopologies - Error: The input topologies parameter is an empty list. Returning None.")
171
+ if not silent:
172
+ print("Cluster.ByTopologies - Error: The input topologies parameter is an empty list. Returning None.")
173
+ curframe = inspect.currentframe()
174
+ calframe = inspect.getouterframes(curframe, 2)
175
+ print('caller name:', calframe[1][3])
171
176
  return None
172
177
  if len(args) == 1:
173
178
  topologies = args[0]
174
179
  if isinstance(topologies, list):
175
180
  if len(topologies) == 0:
176
- print("Cluster.ByTopologies - Error: The input topologies parameter is an empty list. Returning None.")
181
+ if not silent:
182
+ print("Cluster.ByTopologies - Error: The input topologies parameter is an empty list. Returning None.")
183
+ curframe = inspect.currentframe()
184
+ calframe = inspect.getouterframes(curframe, 2)
185
+ print('caller name:', calframe[1][3])
177
186
  return None
178
187
  else:
179
188
  topologyList = [x for x in topologies if Topology.IsInstance(x, "Topology")]
180
189
  if len(topologies) == 0:
181
- print("Cluster.ByTopologies - Error: The input topologies parameter does not contain any valid topologies. Returning None.")
190
+ if not silent:
191
+ print("Cluster.ByTopologies - Error: The input topologies parameter does not contain any valid topologies. Returning None.")
192
+ curframe = inspect.currentframe()
193
+ calframe = inspect.getouterframes(curframe, 2)
194
+ print('caller name:', calframe[1][3])
182
195
  return None
183
196
  else:
184
- print("Cluster.ByTopologies - Warning: The input topologies parameter contains only one topology. Returning the same topology.")
197
+ if not silent:
198
+ print("Cluster.ByTopologies - Warning: The input topologies parameter contains only one topology. Returning the same topology.")
199
+ curframe = inspect.currentframe()
200
+ calframe = inspect.getouterframes(curframe, 2)
201
+ print('caller name:', calframe[1][3])
185
202
  return topologies
186
203
  else:
187
204
  topologyList = Helper.Flatten(list(args))
188
205
  topologyList = [x for x in topologyList if Topology.IsInstance(x, "Topology")]
189
206
  if len(topologyList) == 0:
190
- print("Cluster.ByTopologies - Error: The input parameters do not contain any valid topologies. Returning None.")
207
+ if not silent:
208
+ print("Cluster.ByTopologies - Error: The input parameters do not contain any valid topologies. Returning None.")
209
+ curframe = inspect.currentframe()
210
+ calframe = inspect.getouterframes(curframe, 2)
211
+ print('caller name:', calframe[1][3])
191
212
  return None
192
213
  cluster = topologic.Cluster.ByTopologies(topologyList, False) # Hook to Core
193
214
  dictionaries = []
topologicpy/Face.py CHANGED
@@ -665,7 +665,7 @@ class Face():
665
665
  from topologicpy.Cluster import Cluster
666
666
  from topologicpy.Topology import Topology
667
667
  from topologicpy.Dictionary import Dictionary
668
- import random
668
+ import inspect
669
669
 
670
670
  def triangulateWire(wire):
671
671
  wire = Topology.RemoveCollinearEdges(wire)
@@ -678,10 +678,16 @@ class Face():
678
678
  if not Topology.IsInstance(wire, "Wire"):
679
679
  if not silent:
680
680
  print("Face.ByWire - Error: The input wire parameter is not a valid topologic wire. Returning None.")
681
+ curframe = inspect.currentframe()
682
+ calframe = inspect.getouterframes(curframe, 2)
683
+ print('caller name:', calframe[1][3])
681
684
  return None
682
685
  if not Wire.IsClosed(wire):
683
686
  if not silent:
684
687
  print("Face.ByWire - Error: The input wire parameter is not a closed topologic wire. Returning None.")
688
+ curframe = inspect.currentframe()
689
+ calframe = inspect.getouterframes(curframe, 2)
690
+ print('caller name:', calframe[1][3])
685
691
  return None
686
692
 
687
693
  edges = Wire.Edges(wire)
topologicpy/Neo4j.py CHANGED
@@ -42,8 +42,8 @@ class Neo4j:
42
42
 
43
43
  Parameters
44
44
  ----------
45
- neo4jGraph : neo4j._sync.driver.BoltDriver
46
- The input neo4j bolt driver.
45
+ neo4jGraph : neo4j._sync.driver.BoltDriver or neo4jGraph, neo4j._sync.driver.Neo4jDriver
46
+ The input neo4j driver.
47
47
  cypher : str, optional
48
48
  If set to a non-empty string, a Cypher query will be run on the neo4j graph database to return a sub-graph. Default is None.
49
49
  xMin : float, optional
@@ -164,8 +164,8 @@ class Neo4j:
164
164
 
165
165
  Returns
166
166
  -------
167
- neo4j._sync.driver.BoltDriver
168
- The returned neo4j bolt driver.
167
+ neo4j._sync.driver.BoltDriver or neo4jGraph, neo4j._sync.driver.Neo4jDriver
168
+ The returned neo4j driver.
169
169
 
170
170
  """
171
171
  return GraphDatabase.driver(url, auth=(username, password))
@@ -177,13 +177,13 @@ class Neo4j:
177
177
 
178
178
  Parameters
179
179
  ----------
180
- neo4jGraph : neo4j._sync.driver.BoltDriver
181
- The input neo4j bolt driver.
180
+ neo4jGraph : neo4j._sync.driver.BoltDriver or neo4jGraph, neo4j._sync.driver.Neo4jDriver
181
+ The input neo4j driver.
182
182
 
183
183
  Returns
184
184
  -------
185
- neo4j._sync.driver.BoltDriver
186
- The returned neo4j bolt driver.
185
+ neo4j._sync.driver.BoltDriver or neo4jGraph, neo4j._sync.driver.Neo4jDriver
186
+ The returned neo4j driver.
187
187
 
188
188
  """
189
189
  with neo4jGraph.session() as session:
@@ -223,8 +223,8 @@ class Neo4j:
223
223
 
224
224
  Parameters
225
225
  ----------
226
- neo4jGraph : neo4j._sync.driver.BoltDriver
227
- The input neo4j bolt driver.
226
+ neo4jGraph : neo4j._sync.driver.BoltDriver or neo4jGraph, neo4j._sync.driver.Neo4jDriver
227
+ The input neo4j driver.
228
228
  vertexLabelKey : str , optional
229
229
  The returned vertices are labelled according to the dictionary values stored under this key.
230
230
  If the vertexLabelKey does not exist, it will be created and the vertices are labelled numerically using the format defaultVertexLabel_XXX. The default is "label".
@@ -254,8 +254,8 @@ class Neo4j:
254
254
 
255
255
  Returns
256
256
  -------
257
- neo4j._sync.driver.BoltDriver
258
- The returned neo4j bolt driver.
257
+ neo4j._sync.driver.BoltDriver or neo4jGraph, neo4j._sync.driver.Neo4jDriver
258
+ The returned neo4j driver.
259
259
 
260
260
  """
261
261
  from topologicpy.Vertex import Vertex
@@ -279,7 +279,7 @@ class Neo4j:
279
279
 
280
280
  return sanitized
281
281
 
282
- if not isinstance(neo4jGraph, neo4j._sync.driver.BoltDriver):
282
+ if not isinstance(neo4jGraph, neo4j._sync.driver.BoltDriver) and not isinstance(neo4jGraph, neo4j._sync.driver.Neo4jDriver):
283
283
  if not silent:
284
284
  print("Neo4j.ByGraph - Error: The input neo4jGraph is not a valid neo4j graph. Returning None.")
285
285
  return None
topologicpy/Topology.py CHANGED
@@ -6252,7 +6252,7 @@ class Topology():
6252
6252
  return newTopology
6253
6253
 
6254
6254
  @staticmethod
6255
- def RemoveCollinearEdges(topology, angTolerance=0.1, tolerance=0.0001):
6255
+ def RemoveCollinearEdges(topology, angTolerance: float = 0.1, tolerance: float = 0.0001, silent: bool = False):
6256
6256
  """
6257
6257
  Removes the collinear edges of the input topology
6258
6258
 
@@ -6264,6 +6264,8 @@ class Topology():
6264
6264
  The desired angular tolerance. The default is 0.1.
6265
6265
  tolerance : float , optional
6266
6266
  The desired tolerance. The default is 0.0001.
6267
+ silent : bool , optional
6268
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
6267
6269
 
6268
6270
  Returns
6269
6271
  -------
@@ -6284,7 +6286,7 @@ class Topology():
6284
6286
  if Topology.IsInstance(topology, "Vertex") or Topology.IsInstance(topology, "Edge"): #Vertex or Edge or Cluster, return the original topology
6285
6287
  return return_topology
6286
6288
  elif Topology.IsInstance(topology, "Wire"):
6287
- return_topology = Wire.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance)
6289
+ return_topology = Wire.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance, silent=silent)
6288
6290
  return return_topology
6289
6291
  elif Topology.IsInstance(topology, "Face"):
6290
6292
  return_topology = Face.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance)
topologicpy/Wire.py CHANGED
@@ -471,15 +471,15 @@ class Wire():
471
471
  print("Wire.ByOffset - Error: The input wire parameter is not a valid wire. Returning None.")
472
472
  return None
473
473
 
474
- temp_face = Face.ByWire(wire)
475
- original_area = Face.Area(temp_face)
474
+ #temp_face = Face.ByWire(wire)
475
+ #original_area = Face.Area(temp_face)
476
476
  if reverse == True:
477
477
  fac = -1
478
478
  else:
479
479
  fac = 1
480
480
  origin = Topology.Centroid(wire)
481
481
  temp_vertices = [Topology.Vertices(wire)[0], Topology.Vertices(wire)[1], Topology.Centroid(wire)]
482
- temp_face = Face.ByWire(Wire.ByVertices(temp_vertices, close=True))
482
+ temp_face = Face.ByWire(Wire.ByVertices(temp_vertices, close=True), silent=silent)
483
483
  temp_normal = Face.Normal(temp_face)
484
484
  flat_wire = Topology.Flatten(wire, direction=temp_normal, origin=origin)
485
485
  normal = Face.Normal(temp_face)
@@ -648,38 +648,204 @@ class Wire():
648
648
  if not Wire.IsManifold(return_wire) and bisectors == False:
649
649
  if not silent:
650
650
  print("Wire.ByOffset - Warning: The resulting wire is non-manifold, please check your offsets.")
651
- print("Wire.ByOffset - Warning: Pursuing a workaround, but it might take a longer to complete.")
651
+ print("Wire.ByOffset - Warning: Pursuing a workaround, but it might take longer to complete.")
652
652
 
653
653
  #cycles = Wire.Cycles(return_wire, maxVertices = len(final_vertices))
654
654
  temp_wire = Topology.SelfMerge(Cluster.ByTopologies(wire_edges))
655
655
  cycles = Wire.Cycles(temp_wire, maxVertices = len(final_vertices))
656
- distances = []
657
- for cycle in cycles:
658
- cycle_centroid = Topology.Centroid(cycle)
659
- distance = Vertex.Distance(origin, cycle_centroid)
660
- distances.append(distance)
661
- cycles = Helper.Sort(cycles, distances)
662
- # Get the top three or less
663
- cycles = cycles[:min(3, len(cycles))]
664
- areas = [Face.Area(Face.ByWire(cycle)) for cycle in cycles]
665
- cycles = Helper.Sort(cycles, areas)
666
- return_cycle = Wire.Reverse(cycles[-1])
667
- return_cycle = Wire.Simplify(return_cycle, tolerance=epsilon)
668
- return_cycle = Wire.RemoveCollinearEdges(return_cycle)
669
- sel_edges = []
670
- for temp_edge in wire_edges:
671
- x = Topology.Centroid(temp_edge)
672
- d = Topology.Dictionary(temp_edge)
673
- x = Topology.SetDictionary(x, d, silent=True)
674
- sel_edges.append(x)
675
- return_cycle = Topology.TransferDictionariesBySelectors(return_cycle, Topology.Vertices(return_wire), tranVertices=True, tolerance=tolerance, numWorkers=numWorkers)
676
- return_cycle = Topology.TransferDictionariesBySelectors(return_cycle, sel_edges, tranEdges=True, tolerance=tolerance, numWorkers=numWorkers)
677
- return_wire = return_cycle
656
+ if len(cycles) > 0:
657
+ distances = []
658
+ for cycle in cycles:
659
+ cycle_centroid = Topology.Centroid(cycle)
660
+ distance = Vertex.Distance(origin, cycle_centroid)
661
+ distances.append(distance)
662
+ cycles = Helper.Sort(cycles, distances)
663
+ # Get the top three or less
664
+ cycles = cycles[:min(3, len(cycles))]
665
+ areas = [Face.Area(Face.ByWire(cycle)) for cycle in cycles]
666
+ cycles = Helper.Sort(cycles, areas)
667
+ return_cycle = Wire.Reverse(cycles[-1])
668
+ test_cycle = Wire.Simplify(return_cycle, tolerance=epsilon)
669
+ if Topology.IsInstance(test_cycle, "Wire"):
670
+ return_cycle = test_cycle
671
+ return_cycle = Wire.RemoveCollinearEdges(return_cycle, silent=silent)
672
+ sel_edges = []
673
+ for temp_edge in wire_edges:
674
+ x = Topology.Centroid(temp_edge)
675
+ d = Topology.Dictionary(temp_edge)
676
+ x = Topology.SetDictionary(x, d, silent=True)
677
+ sel_edges.append(x)
678
+ return_cycle = Topology.TransferDictionariesBySelectors(return_cycle, Topology.Vertices(return_wire), tranVertices=True, tolerance=tolerance, numWorkers=numWorkers)
679
+ return_cycle = Topology.TransferDictionariesBySelectors(return_cycle, sel_edges, tranEdges=True, tolerance=tolerance, numWorkers=numWorkers)
680
+ return_wire = return_cycle
681
+
678
682
  return_wire = Topology.Unflatten(return_wire, direction=normal, origin=origin)
679
683
  if transferDictionaries == True:
680
684
  return_wire = Topology.SetDictionary(return_wire, Topology.Dictionary(wire), silent=True)
681
685
  return return_wire
682
686
 
687
+ @staticmethod
688
+ def ByOffsetArea(wire,
689
+ area,
690
+ offsetKey="offset",
691
+ minOffsetKey="minOffset",
692
+ maxOffsetKey="maxOffset",
693
+ defaultMinOffset=0,
694
+ defaultMaxOffset=1,
695
+ maxIterations = 1,
696
+ tolerance=0.0001,
697
+ silent = False):
698
+ """
699
+ Creates an offset wire from the input wire based on the input area.
700
+
701
+ Parameters
702
+ ----------
703
+ wire : topologic_core.Wire
704
+ The input wire.
705
+ area : float
706
+ The desired area of the created wire.
707
+ offsetKey : str , optional
708
+ The edge dictionary key under which to store the offset value. The default is "offset".
709
+ minOffsetKey : str , optional
710
+ The edge dictionary key under which to find the desired minimum edge offset value. If a value cannot be found, the defaultMinOffset input parameter value is used instead. The default is "minOffset".
711
+ maxOffsetKey : str , optional
712
+ The edge dictionary key under which to find the desired maximum edge offset value. If a value cannot be found, the defaultMaxOffset input parameter value is used instead. The default is "maxOffset".
713
+ defaultMinOffset : float , optional
714
+ The desired minimum edge offset distance. The default is 0.
715
+ defaultMaxOffset : float , optional
716
+ The desired maximum edge offset distance. The default is 1.
717
+ maxIterations: int , optional
718
+ The desired maximum number of iterations to attempt to converge on a solution. The default is 1.
719
+ tolerance : float , optional
720
+ The desired tolerance. The default is 0.0001.
721
+ silent : bool , optional
722
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
723
+
724
+ Returns
725
+ -------
726
+ topologic_core.Wire
727
+ The created wire.
728
+
729
+ """
730
+ from topologicpy.Wire import Wire
731
+ from topologicpy.Face import Face
732
+ from topologicpy.Topology import Topology
733
+ from topologicpy.Dictionary import Dictionary
734
+ import numpy as np
735
+ from scipy.optimize import minimize
736
+
737
+ def compute_offset_amounts(wire,
738
+ area,
739
+ offsetKey="offset",
740
+ minOffsetKey="minOffset",
741
+ maxOffsetKey="maxOffset",
742
+ defaultMinOffset=0,
743
+ defaultMaxOffset=1,
744
+ maxIterations = 10000,
745
+ maxTime = 10,
746
+ tolerance=0.0001):
747
+
748
+ initial_offsets = []
749
+ bounds = []
750
+ for edge in edges:
751
+ d = Topology.Dictionary(edge)
752
+ minOffset = Dictionary.ValueAtKey(d, minOffsetKey) or defaultMinOffset
753
+ maxOffset = Dictionary.ValueAtKey(d, maxOffsetKey) or defaultMaxOffset
754
+ # Initial guess: small negative offsets to shrink the polygon, within the constraints
755
+ initial_offsets.append((minOffset + maxOffset) / 2)
756
+ # Bounds based on the constraints for each edge
757
+ bounds.append((minOffset, maxOffset))
758
+
759
+ # Convert initial_offsets to np.array for efficiency
760
+ initial_offsets = np.array(initial_offsets)
761
+ iteration_count = [0] # List to act as a mutable counter
762
+
763
+ def objective_function(offsets):
764
+ for i, edge in enumerate(edges):
765
+ d = Topology.Dictionary(edge)
766
+ d = Dictionary.SetValueAtKey(d, offsetKey, offsets[i])
767
+ edge = Topology.SetDictionary(edge, d)
768
+
769
+ # Offset the wire
770
+ new_wire = Wire.ByOffset(wire, offsetKey=offsetKey, silent=silent)
771
+ # Check for an illegal wire. In that case, return a very large loss value.
772
+ if not Topology.IsInstance(new_wire, "Wire"):
773
+ return (float("inf"))
774
+ if not Wire.IsManifold(new_wire):
775
+ return (float("inf"))
776
+ if not Wire.IsClosed(new_wire):
777
+ return (float("inf"))
778
+ new_face = Face.ByWire(new_wire)
779
+ # Calculate the area of the new wire/face
780
+ new_area = Face.Area(new_face)
781
+
782
+ # The objective is the difference between the target hole area and the actual hole area
783
+ # We want this difference to be as close to 0 as possible
784
+ loss = (new_area - area) ** 2
785
+ # If the loss is less than the tolerance, accept the result and return a loss of 0.
786
+ if loss < tolerance:
787
+ return 0
788
+ # Otherwise, return the actual loss value.
789
+ return loss
790
+
791
+ # Callback function to track and display iteration number
792
+ def iteration_callback(xk):
793
+ iteration_count[0] += 1 # Increment the counter
794
+ if not silent:
795
+ print(f"Wire.ByOffsetArea - Information: Iteration {iteration_count[0]}")
796
+
797
+ # Use scipy optimization/minimize to find the correct offsets, respecting the min/max bounds
798
+ result = minimize(objective_function,
799
+ initial_offsets,
800
+ method = "Powell",
801
+ bounds=bounds,
802
+ options={ 'maxiter': maxIterations},
803
+ callback=iteration_callback
804
+ )
805
+
806
+ # Return the offsets
807
+ return result.x
808
+
809
+ if not Topology.IsInstance(wire, "Wire"):
810
+ if not silent:
811
+ print("Wire.OffsetByArea - Error: The input wire parameter is not a valid wire. Returning None.")
812
+ return None
813
+
814
+ if not Wire.IsManifold(wire):
815
+ if not silent:
816
+ print("Wire.OffsetByArea - Error: The input wire parameter is not a manifold wire. Returning None.")
817
+ return None
818
+
819
+ if not Wire.IsClosed(wire):
820
+ if not silent:
821
+ print("Wire.OffsetByArea - Error: The input wire parameter is not a closed wire. Returning None.")
822
+ return None
823
+
824
+ edges = Topology.Edges(wire)
825
+ # Compute the offset amounts
826
+ offsets = compute_offset_amounts(wire,
827
+ area = area,
828
+ offsetKey = offsetKey,
829
+ minOffsetKey = minOffsetKey,
830
+ maxOffsetKey = maxOffsetKey,
831
+ defaultMinOffset = defaultMinOffset,
832
+ defaultMaxOffset = defaultMaxOffset,
833
+ maxIterations = maxIterations,
834
+ tolerance = tolerance)
835
+ # Set the edge dictionaries correctly according to the specified offsetKey
836
+ for i, edge in enumerate(edges):
837
+ d = Topology.Dictionary(edge)
838
+ d = Dictionary.SetValueAtKey(d, offsetKey, offsets[i])
839
+ edge = Topology.SetDictionary(edge, d)
840
+
841
+ # Offset the wire
842
+ return_wire = Wire.ByOffset(wire, offsetKey=offsetKey, silent=silent)
843
+ if not Topology.IsInstance(wire, "Wire"):
844
+ if not silent:
845
+ print("Wire.OffsetByArea - Error: Could not create the offset wire. Returning None.")
846
+ return None
847
+ return return_wire
848
+
683
849
  @staticmethod
684
850
  def ByVertices(vertices: list, close: bool = True, tolerance: float = 0.0001):
685
851
  """
@@ -1869,7 +2035,7 @@ class Wire():
1869
2035
  return status
1870
2036
 
1871
2037
  @staticmethod
1872
- def IsManifold(wire) -> bool:
2038
+ def IsManifold(wire, silent: bool = False) -> bool:
1873
2039
  """
1874
2040
  Returns True if the input wire is manifold. Returns False otherwise. A manifold wire is one where its vertices have a degree of 1 or 2.
1875
2041
 
@@ -1877,6 +2043,8 @@ class Wire():
1877
2043
  ----------
1878
2044
  wire : topologic_core.Wire
1879
2045
  The input wire.
2046
+ silent : bool , optional
2047
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
1880
2048
 
1881
2049
  Returns
1882
2050
  -------
@@ -1885,9 +2053,14 @@ class Wire():
1885
2053
 
1886
2054
  """
1887
2055
  from topologicpy.Vertex import Vertex
2056
+ import inspect
1888
2057
 
1889
2058
  if not Topology.IsInstance(wire, "Wire"):
1890
- print("Wire.IsManifold - Error: The input wire parameter is not a valid topologic wire. Returning None.")
2059
+ if not silent:
2060
+ print("Wire.IsManifold - Error: The input wire parameter is not a valid topologic wire. Returning None.")
2061
+ curframe = inspect.currentframe()
2062
+ calframe = inspect.getouterframes(curframe, 2)
2063
+ print('caller name:', calframe[1][3])
1891
2064
  return None
1892
2065
 
1893
2066
  vertices = Wire.Vertices(wire)
@@ -2578,7 +2751,7 @@ class Wire():
2578
2751
  return baseWire
2579
2752
 
2580
2753
  @staticmethod
2581
- def RemoveCollinearEdges(wire, angTolerance: float = 0.1, tolerance: float = 0.0001):
2754
+ def RemoveCollinearEdges(wire, angTolerance: float = 0.1, tolerance: float = 0.0001, silent: bool = False):
2582
2755
  """
2583
2756
  Removes any collinear edges in the input wire.
2584
2757
 
@@ -2590,6 +2763,8 @@ class Wire():
2590
2763
  The desired angular tolerance. The default is 0.1.
2591
2764
  tolerance : float , optional
2592
2765
  The desired tolerance. The default is 0.0001.
2766
+ silent : bool , optional
2767
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
2593
2768
 
2594
2769
  Returns
2595
2770
  -------
@@ -2602,6 +2777,7 @@ class Wire():
2602
2777
  from topologicpy.Wire import Wire
2603
2778
  from topologicpy.Cluster import Cluster
2604
2779
  from topologicpy.Topology import Topology
2780
+ import inspect
2605
2781
 
2606
2782
  def cleanup(wire, tolerance):
2607
2783
  vertices = Topology.Vertices(wire)
@@ -2615,8 +2791,9 @@ class Wire():
2615
2791
  ev = vertices[Vertex.Index(ev, vertices, tolerance=tolerance)]
2616
2792
  if Vertex.Distance(sv, ev) > tolerance:
2617
2793
  new_edges.append(Edge.ByVertices([sv,ev]))
2618
- new_wire = Topology.SelfMerge(Cluster.ByTopologies(new_edges), tolerance=tolerance)
2619
- return new_wire
2794
+ if len(new_edges) > 0:
2795
+ return Topology.SelfMerge(Cluster.ByTopologies(new_edges, silent=silent), tolerance=tolerance)
2796
+ return wire
2620
2797
 
2621
2798
  def rce(wire, angTolerance=0.1):
2622
2799
  if not Topology.IsInstance(wire, "Wire"):
@@ -2645,6 +2822,13 @@ class Wire():
2645
2822
  final_wire = Edge.ByStartVertexEndVertex(wire_verts[0], wire_verts[1], tolerance=tolerance, silent=True)
2646
2823
  return final_wire
2647
2824
 
2825
+ if not Topology.IsInstance(wire, "Wire"):
2826
+ if not silent:
2827
+ print("Wire.RemoveCollinearEdges - Error: The input wire parameter is not a valid wire. Returning None.")
2828
+ curframe = inspect.currentframe()
2829
+ calframe = inspect.getouterframes(curframe, 2)
2830
+ print('caller name:', calframe[1][3])
2831
+ return None
2648
2832
  new_wire = cleanup(wire, tolerance=tolerance)
2649
2833
  if not Wire.IsManifold(new_wire):
2650
2834
  wires = Wire.Split(new_wire)
@@ -2665,7 +2849,7 @@ class Wire():
2665
2849
  else:
2666
2850
  return wire
2667
2851
  elif len(returnWires) > 1:
2668
- returnWire = Topology.SelfMerge(Cluster.ByTopologies(returnWires))
2852
+ returnWire = Topology.SelfMerge(Cluster.ByTopologies(returnWires, silent=silent))
2669
2853
  if Topology.IsInstance(returnWire, "Edge"):
2670
2854
  return Wire.ByEdges([returnWire], tolerance=tolerance)
2671
2855
  elif Topology.IsInstance(returnWire, "Wire"):
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.62'
1
+ __version__ = '0.7.63'
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.62
4
- Summary: An Advanced Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
3
+ Version: 0.7.63
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: MIT License
7
7
 
@@ -3,34 +3,34 @@ topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
3
3
  topologicpy/BVH.py,sha256=dfVQyn5OPN1_50nusS0AxAcmUfqTzpl0vWT7RBEz-WM,12870
4
4
  topologicpy/Cell.py,sha256=_vEYx1kNc3JZJUCCS8nhLM_j8EV4SyZYt3DjNHNRoDw,107707
5
5
  topologicpy/CellComplex.py,sha256=YNmNkH6IUplM9f7agZQd6IL2xnHf5ds3JkGQk4jiSXQ,48029
6
- topologicpy/Cluster.py,sha256=TZXuxzdaUr6OHSWnjWpjCOMlVj6YHBH8aUVbDVsncVA,54999
6
+ topologicpy/Cluster.py,sha256=P9hAtZQjPugnIRJcviQNFBbdDqpMFADJK87_tR0CIAI,56108
7
7
  topologicpy/Color.py,sha256=FrxX2yILqWvYrqD8kBaknfMfOR_phJOmhvTvFc07bY4,18065
8
8
  topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
9
9
  topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
10
10
  topologicpy/Dictionary.py,sha256=cURg452wwk2WeSxWY46ncgAUo5XD1c2c5EtO6ESZHaY,27304
11
11
  topologicpy/Edge.py,sha256=FACD8Bm2nL2uTHIeRMVXfRF0cYeqhZ-lCZPHAfjAIPg,66927
12
12
  topologicpy/EnergyModel.py,sha256=NM3_nAdY9_YDtbp9CaEZ0x0xVsetTqVDzm_VSjmq_mI,53746
13
- topologicpy/Face.py,sha256=YjU6TxxW2Mf5InumMvzXUXVVRdtjxyRGauRIhGXzkao,116411
13
+ topologicpy/Face.py,sha256=OyzEWdXl8yScHlyG3jDqcI31d_QlAt3SDma8AtkLQFs,116746
14
14
  topologicpy/Graph.py,sha256=4b8bzlyXmh0Ef9rjiEjl8wmh_9vAxoE5xiSiGvGjG9Q,411392
15
15
  topologicpy/Grid.py,sha256=3-sn7CHWGcXk18XCnHjsUttNJTWwmN63g_Insj__p04,18218
16
16
  topologicpy/Helper.py,sha256=i-AfI29NMsZXBaymjilfvxQbuS3wpYbpPw4RWu1YCHs,16358
17
17
  topologicpy/Honeybee.py,sha256=Oc8mfGBNSjs6wxkPzCKmEw1ZPQPbp9XtiYWaAF62oSk,21893
18
18
  topologicpy/Matrix.py,sha256=umgR7An919-wGInXJ1wpqnoQ2jCPdyMe2rcWTZ16upk,8079
19
- topologicpy/Neo4j.py,sha256=BezQ-sdpU8B0W4X_kaF7alZrlN0-h4779HFrB3Fsn-w,22033
19
+ topologicpy/Neo4j.py,sha256=t52hgE9cVsqkGc7m7fjRsLnyfRHakVHwdvF4ms7ow78,22342
20
20
  topologicpy/Plotly.py,sha256=k-gluqX4Na3zlYCDl_6A0gqeFoGR-0Oy6fLiT-Zqlyk,108362
21
21
  topologicpy/Polyskel.py,sha256=EFsuh2EwQJGPLiFUjvtXmAwdX-A4r_DxP5hF7Qd3PaU,19829
22
22
  topologicpy/PyG.py,sha256=LU9LCCzjxGPUM31qbaJXZsTvniTtgugxJY7y612t4A4,109757
23
23
  topologicpy/Shell.py,sha256=joahFtpRQTWJpQOmi3qU4Xe0Sx2XXeayHlXTNx8CzMk,87610
24
24
  topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
25
25
  topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
26
- topologicpy/Topology.py,sha256=5Vnn9oMEQ__ta_ew9XhnZExMPbHsj9QN91v-6pxdrJg,397934
26
+ topologicpy/Topology.py,sha256=DsRPV0iWUY2NIlxdvLLDBkkDY3xw8oYvmzQEEfJUusQ,398136
27
27
  topologicpy/Vector.py,sha256=A1g83zDHep58iVPY8WQ8iHNrSOfGWFEzvVeDuMnjDNY,33078
28
28
  topologicpy/Vertex.py,sha256=bLY60YWoMsgCgHk7F7k9F93Sq2FJ6AzUcTfJ83NZfHA,71107
29
- topologicpy/Wire.py,sha256=nRD_TqDpgbdQ1-YrMqrxVq_sYwi91Ad83mflFGL4Na4,162578
29
+ topologicpy/Wire.py,sha256=x2ut3Pej3fTBv1nPzQMsJ8asWFy4WKIjrAUPA0boesU,171628
30
30
  topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
31
- topologicpy/version.py,sha256=zE7Ne5ringVmSmv9eQ1aDQ5rppXqGLcX_FCGFkD0JoU,23
32
- topologicpy-0.7.62.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
33
- topologicpy-0.7.62.dist-info/METADATA,sha256=awRKe419hWCdlGWl5t1Yrt-Hkm4E6BYxSJFzvcYKpSE,10918
34
- topologicpy-0.7.62.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
35
- topologicpy-0.7.62.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
- topologicpy-0.7.62.dist-info/RECORD,,
31
+ topologicpy/version.py,sha256=MZJ0DcglO3LqgTS4xIW_NWvmDzvvzxd1VdjKOHudVIk,23
32
+ topologicpy-0.7.63.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
33
+ topologicpy-0.7.63.dist-info/METADATA,sha256=EsGaYJ2wOBoqKTUUzAmNE_G0taxa5TW-Eg7UJzZqyYs,10920
34
+ topologicpy-0.7.63.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
35
+ topologicpy-0.7.63.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
+ topologicpy-0.7.63.dist-info/RECORD,,