topologicpy 0.7.24__py3-none-any.whl → 0.7.26__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/ANN.py CHANGED
@@ -110,7 +110,7 @@ import numpy as np
110
110
  class _ANN(nn.Module):
111
111
  def __init__(self, input_size, hyperparameters, dataset=None):
112
112
  super(_ANN, self).__init__()
113
- self.title = hyperparameters['title']
113
+ self.title = hyperparameters.get('title', 'Untitled')
114
114
  self.task_type = hyperparameters['task_type']
115
115
  self.cross_val_type = hyperparameters['cross_val_type']
116
116
  self.k_folds = hyperparameters.get('k_folds', 5)
@@ -576,6 +576,10 @@ class ANN():
576
576
  interval = 1,
577
577
  mantissa = 6):
578
578
  """
579
+ Returns a Hyperparameters dictionary based on the input parameters.
580
+
581
+ Parameters
582
+ ----------
579
583
  title : str , optional
580
584
  The desired title for the dataset. The default is "Untitled".
581
585
  taskType : str , optional
@@ -623,6 +627,7 @@ class ANN():
623
627
  -------
624
628
  dict
625
629
  Returns a dictionary with the following keys:
630
+ 'title'
626
631
  'task_type'
627
632
  'test_ratio'
628
633
  'validation_ratio'
@@ -632,13 +637,14 @@ class ANN():
632
637
  'batch_size'
633
638
  'early_stopping'
634
639
  'patience'
635
- 'random_tate'
640
+ 'random_state'
636
641
  'cross_val_type'
637
642
  'kFolds'
638
643
  'interval'
639
644
  'mantissa'
640
645
  """
641
646
  return {
647
+ 'title': title,
642
648
  'task_type': taskType,
643
649
  'test_ratio': testRatio,
644
650
  'validation_ratio': validationRatio,
topologicpy/Edge.py CHANGED
@@ -475,6 +475,8 @@ class Edge():
475
475
  The first input edge. This edge will be extended to meet edgeB.
476
476
  edgeB : topologic_core.Edge
477
477
  The second input edge. This edge will be used to extend edgeA.
478
+ mantissa : int , optional
479
+ The desired length of the mantissa. The default is 6.
478
480
  tolerance : float , optional
479
481
  The desired tolerance. The default is 0.0001.
480
482
  silent : bool , optional
@@ -764,8 +766,8 @@ class Edge():
764
766
  The second input edge.
765
767
  mantissa : int , optional
766
768
  The desired length of the mantissa. The default is 6.
767
- angTolerance : float , optional
768
- The angular tolerance used for the test. The default is 0.1.
769
+ tolerance : float , optional
770
+ The desired tolerance. The default is 0.0001.
769
771
 
770
772
  Returns
771
773
  -------
topologicpy/Face.py CHANGED
@@ -133,6 +133,10 @@ class Face():
133
133
  return None
134
134
  dirA = Face.Normal(faceA, outputType="xyz", mantissa=3)
135
135
  dirB = Face.Normal(faceB, outputType="xyz", mantissa=3)
136
+ if dirA == None or dirB == None:
137
+ Topology.Show(faceA, faceB)
138
+ print("Face.Angle - Error: Could not compute the angle between the two input faces. Returning None.")
139
+ return None
136
140
  return round((Vector.Angle(dirA, dirB)), mantissa)
137
141
 
138
142
  @staticmethod
@@ -1684,6 +1688,7 @@ class Face():
1684
1688
  from topologicpy.Vertex import Vertex
1685
1689
  import os
1686
1690
  import warnings
1691
+
1687
1692
  try:
1688
1693
  import numpy as np
1689
1694
  except:
@@ -1703,60 +1708,64 @@ class Face():
1703
1708
  print("Face.Normal - Error: The input face parameter is not a valid face. Returning None.")
1704
1709
  return None
1705
1710
 
1706
- #vertices = Topology.Vertices(face)
1707
- v1 = Face.VertexByParameters(face, u=0, v=0)
1708
- v2 = Face.VertexByParameters(face, u=1, v=0)
1709
- v3 = Face.VertexByParameters(face, u=1, v=1)
1710
- vertices = [v1, v2, v3]
1711
- vertices = [Vertex.Coordinates(v, mantissa=mantissa) for v in vertices]
1712
-
1713
- if len(vertices) < 3:
1714
- print("Face.Normal - Error: At least three vertices are required to define a plane. Returning None.")
1715
- return None
1716
-
1717
- # Convert vertices to numpy array for easier manipulation
1718
- vertices = np.array(vertices)
1719
-
1720
- # Try to find two non-collinear edge vectors
1721
- vec1 = None
1722
- vec2 = None
1723
- for i in range(1, len(vertices)):
1724
- for j in range(i + 1, len(vertices)):
1725
- temp_vec1 = vertices[i] - vertices[0]
1726
- temp_vec2 = vertices[j] - vertices[0]
1727
- cross_product = np.cross(temp_vec1, temp_vec2)
1728
- if np.linalg.norm(cross_product) > 1e-6: # Check if the cross product is not near zero
1729
- vec1 = temp_vec1
1730
- vec2 = temp_vec2
1711
+ return_normal = None
1712
+ try:
1713
+ return_normal = list(topologic.FaceUtility.NormalAtParameters(face, 0.5, 0.5))
1714
+ except:
1715
+ vertices = Topology.Vertices(face)+Topology.Centroid(face)
1716
+ #v1 = Face.VertexByParameters(face, u=0, v=0)
1717
+ #v2 = Face.VertexByParameters(face, u=1, v=0)
1718
+ #v3 = Face.VertexByParameters(face, u=1, v=1)
1719
+ #vertices = [v1, v2, v3]
1720
+ vertices = [Vertex.Coordinates(v, mantissa=mantissa) for v in vertices]
1721
+
1722
+ if len(vertices) < 3:
1723
+ print("Face.Normal - Error: At least three vertices are required to define a plane. Returning None.")
1724
+ return None
1725
+
1726
+ # Convert vertices to numpy array for easier manipulation
1727
+ vertices = np.array(vertices)
1728
+
1729
+ # Try to find two non-collinear edge vectors
1730
+ vec1 = None
1731
+ vec2 = None
1732
+ for i in range(1, len(vertices)):
1733
+ for j in range(i + 1, len(vertices)):
1734
+ temp_vec1 = vertices[i] - vertices[0]
1735
+ temp_vec2 = vertices[j] - vertices[0]
1736
+ cross_product = np.cross(temp_vec1, temp_vec2)
1737
+ if np.linalg.norm(cross_product) > 1e-6: # Check if the cross product is not near zero
1738
+ vec1 = temp_vec1
1739
+ vec2 = temp_vec2
1740
+ break
1741
+ if vec1 is not None and vec2 is not None:
1731
1742
  break
1732
- if vec1 is not None and vec2 is not None:
1733
- break
1734
-
1735
- if vec1 is None or vec2 is None:
1736
- print("Face.Normal - Error: The given vertices do not form a valid plane (all vertices might be collinear). Returning None.")
1737
- return None
1738
-
1739
- # Calculate the cross product of the two edge vectors
1740
- normal = np.cross(vec1, vec2)
1743
+
1744
+ if vec1 is None or vec2 is None:
1745
+ print("Face.Normal - Error: The given vertices do not form a valid plane (all vertices might be collinear). Returning None.")
1746
+ return None
1747
+
1748
+ # Calculate the cross product of the two edge vectors
1749
+ normal = np.cross(vec1, vec2)
1741
1750
 
1742
- # Normalize the normal vector
1743
- normal_length = np.linalg.norm(normal)
1744
- if normal_length == 0:
1745
- print("Face.Normal - Error: The given vertices do not form a valid plane (cross product resulted in a zero vector). Returning None.")
1746
- return None
1747
-
1748
- normal = normal / normal_length
1749
- normal = normal.tolist()
1750
- normal = [round(x, mantissa) for x in normal]
1751
- return_normal = []
1752
- outputType = list(outputType.lower())
1753
- for axis in outputType:
1754
- if axis == "x":
1755
- return_normal.append(normal[0])
1756
- elif axis == "y":
1757
- return_normal.append(normal[1])
1758
- elif axis == "z":
1759
- return_normal.append(normal[2])
1751
+ # Normalize the normal vector
1752
+ normal_length = np.linalg.norm(normal)
1753
+ if normal_length == 0:
1754
+ print("Face.Normal - Error: The given vertices do not form a valid plane (cross product resulted in a zero vector). Returning None.")
1755
+ return None
1756
+
1757
+ normal = normal / normal_length
1758
+ normal = normal.tolist()
1759
+ normal = [round(x, mantissa) for x in normal]
1760
+ return_normal = []
1761
+ outputType = list(outputType.lower())
1762
+ for axis in outputType:
1763
+ if axis == "x":
1764
+ return_normal.append(normal[0])
1765
+ elif axis == "y":
1766
+ return_normal.append(normal[1])
1767
+ elif axis == "z":
1768
+ return_normal.append(normal[2])
1760
1769
  return return_normal
1761
1770
 
1762
1771
  @staticmethod
topologicpy/Graph.py CHANGED
@@ -158,7 +158,7 @@ class WorkerProcess(Process):
158
158
  continue
159
159
  if Vertex.Distance(source, destination) > self.tolerance:
160
160
  edge = Edge.ByVertices([source, destination])
161
- e = Topology.Boolean(edge, face, operation="intersect")
161
+ e = Topology.Intersect(edge, face)
162
162
  if Topology.IsInstance(e, "Edge"):
163
163
  edges.append(edge)
164
164
  self.used[i + self.start_index][j] = 1
topologicpy/Topology.py CHANGED
@@ -24,6 +24,9 @@ import math
24
24
  from collections import namedtuple
25
25
  from multiprocessing import Process, Queue
26
26
 
27
+ # This is for View3D as not to open new browser windows
28
+ opened_urls = set()
29
+
27
30
  try:
28
31
  import numpy as np
29
32
  from numpy import arctan, pi, signbit
@@ -968,18 +971,44 @@ class Topology():
968
971
  results = []
969
972
  if Topology.IsInstance(topologyA, "CellComplex"):
970
973
  cellsA = Topology.Cells(topologyA)
974
+ elif Topology.IsInstance(topologyA, "Cluster"):
975
+ cellsA = Cluster.FreeTopologies(topologyA)
971
976
  else:
972
977
  cellsA = [topologyA]
973
- for cellA in cellsA:
974
- if Topology.IsInstance(topologyB, "CellComplex"):
978
+ if Topology.IsInstance(topologyB, "CellComplex"):
975
979
  cellsB = Topology.Cells(topologyB)
980
+ elif Topology.IsInstance(topologyB, "Cluster"):
981
+ cellsB = Cluster.FreeTopologies(topologyB)
982
+ else:
983
+ cellsB = [topologyB]
984
+ cellsA_2 = []
985
+ cellsB_2 = []
986
+ for cellA in cellsA:
987
+ if Topology.IsInstance(cellA, "CellComplex"):
988
+ cellsA_2 += Topology.Cells(cellA)
989
+ elif Topology.IsInstance(cellA, "Shell"):
990
+ cellsA_2 += Topology.Faces(cellA)
991
+ else:
992
+ cellsA_2.append(cellA)
993
+
994
+ for cellB in cellsB:
995
+ if Topology.IsInstance(cellB, "CellComplex"):
996
+ cellsB_2 += Topology.Cells(cellB)
997
+ elif Topology.IsInstance(cellB, "Shell"):
998
+ cellsB_2 += Topology.Faces(cellB)
976
999
  else:
977
- cellsB = [topologyB]
978
- for cellB in cellsB:
1000
+ cellsB_2.append(cellB)
1001
+
1002
+ print("cellsA_2", cellsA_2)
1003
+ print("cellsB_2", cellsB_2)
1004
+ for cellA in cellsA_2:
1005
+ for cellB in cellsB_2:
979
1006
  cellC = cellA.Intersect(cellB)
980
1007
  results.append(cellC)
981
- results = [x for x in results if results is not None]
982
- if len(results) == 1:
1008
+ results = [x for x in results if x is not None]
1009
+ if len(results) == 0:
1010
+ return None
1011
+ elif len(results) == 1:
983
1012
  return results[0]
984
1013
  else:
985
1014
  return Topology.SelfMerge(Topology.SelfMerge(Cluster.ByTopologies(results)))
@@ -4686,7 +4715,7 @@ class Topology():
4686
4715
  return json_string
4687
4716
 
4688
4717
  @staticmethod
4689
- def OBJString(topology, color, vertexIndex, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, mantissa: int = 6, tolerance: float = 0.0001):
4718
+ def _OBJString(topology, color, vertexIndex, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, mantissa: int = 6, tolerance: float = 0.0001):
4690
4719
  """
4691
4720
  Returns the Wavefront string of the input topology. This is very experimental and outputs a simple solid topology.
4692
4721
 
@@ -4757,6 +4786,7 @@ class Topology():
4757
4786
  finalLines = finalLines + "\n" + lines[i]
4758
4787
  return finalLines, len(vertices)
4759
4788
 
4789
+
4760
4790
  @staticmethod
4761
4791
  def ExportToOBJ(*topologies, path, nameKey="name", colorKey="color", opacityKey="opacity", defaultColor=[256,256,256], defaultOpacity=0.5, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, overwrite: bool = False, mantissa: int = 6, tolerance: float = 0.0001):
4762
4792
  """
@@ -4809,7 +4839,6 @@ class Topology():
4809
4839
 
4810
4840
  """
4811
4841
  from topologicpy.Helper import Helper
4812
- from topologicpy.Dictionary import Dictionary
4813
4842
  from os.path import exists
4814
4843
 
4815
4844
  if isinstance(topologies, tuple):
@@ -4820,7 +4849,7 @@ class Topology():
4820
4849
  print("Topology.ExportToOBJ - Error: the input topologies parameter does not contain any valid topologies. Returning None.")
4821
4850
  return None
4822
4851
  if not isinstance(new_topologies, list):
4823
- print("Dictionary.ByMergedDictionaries - Error: The input dictionaries parameter is not a valid list. Returning None.")
4852
+ print("Topology.ExportToOBJ - Error: The input topologies parameter is not a valid list. Returning None.")
4824
4853
  return None
4825
4854
 
4826
4855
  if not overwrite and exists(path):
@@ -4834,39 +4863,126 @@ class Topology():
4834
4863
  status = False
4835
4864
 
4836
4865
  mtl_path = path[:-4] + ".mtl"
4837
-
4866
+
4867
+ obj_string, mtl_string = Topology.OBJString(new_topologies,
4868
+ nameKey=nameKey,
4869
+ colorKey=colorKey,
4870
+ opacityKey=opacityKey,
4871
+ defaultColor=defaultColor,
4872
+ defaultOpacity=defaultOpacity,
4873
+ transposeAxes=transposeAxes,
4874
+ mode=mode,
4875
+ meshSize=meshSize,
4876
+ mantissa=mantissa,
4877
+ tolerance=tolerance)
4838
4878
  # Write out the material file
4839
- n = max(len(str(len(topologies))), 3)
4840
4879
  with open(mtl_path, "w") as mtl_file:
4841
- for i in range(len(new_topologies)):
4842
- d = Topology.Dictionary(new_topologies[i])
4843
- name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
4844
- color = Dictionary.ValueAtKey(d, colorKey) or defaultColor
4845
- color = [c/255 for c in color]
4846
- opacity = Dictionary.ValueAtKey(d, opacityKey) or defaultOpacity
4847
- mtl_file.write("newmtl color_" + str(i).zfill(n) + "\n")
4848
- mtl_file.write("Kd " + ' '.join(map(str, color)) + "\n")
4849
- mtl_file.write("d " + str(opacity) + "\n")
4850
-
4880
+ mtl_file.write(mtl_string)
4851
4881
  # Write out the obj file
4852
4882
  with open(path, "w") as obj_file:
4853
- vertex_index = 1 # global vertex index counter
4854
- obj_file.writelines("# topologicpy "+Helper.Version()+"\n")
4855
- obj_file.writelines("mtllib " + mtl_path.split('/')[-1]) # reference the MTL file
4856
- for i in range(len(topologies)):
4857
- d = Topology.Dictionary(topologies[i])
4858
- name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
4859
- name = name.replace(" ", "_")
4860
- obj_file.writelines("\ng "+name+"\n")
4861
- result = Topology.OBJString(topologies[i], "color_" + str(i).zfill(n), vertex_index, transposeAxes=transposeAxes, mode=mode,
4862
- meshSize=meshSize,
4863
- mantissa=mantissa, tolerance=tolerance)
4864
-
4865
- obj_file.writelines(result[0])
4866
- vertex_index += result[1]
4867
- obj_file.close()
4868
- status = True
4869
- return status
4883
+ obj_file.write(obj_string)
4884
+ return True
4885
+
4886
+ @staticmethod
4887
+ def OBJString(*topologies, nameKey="name", colorKey="color", opacityKey="opacity", defaultColor=[256,256,256], defaultOpacity=0.5, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, mantissa: int = 6, tolerance: float = 0.0001):
4888
+ """
4889
+ Exports the input topology to a Wavefront OBJ file. This is very experimental and outputs a simple solid topology.
4890
+
4891
+ Parameters
4892
+ ----------
4893
+ topologies : list or comma separated topologies
4894
+ The input list of topologies.
4895
+ path : str
4896
+ The input file path.
4897
+ nameKey : str , optional
4898
+ The topology dictionary key under which to find the name of the topology. The default is "name".
4899
+ colorKey : str, optional
4900
+ The topology dictionary key under which to find the color of the topology. The default is "color".
4901
+ opacityKey : str , optional
4902
+ The topology dictionary key under which to find the opacity of the topology. The default is "opacity".
4903
+ defaultColor : list , optional
4904
+ The default color to use if no color is stored in the topology dictionary. The default is [255,255, 255] (white).
4905
+ defaultOpacity : float , optional
4906
+ The default opacity to use of no opacity is stored in the topology dictionary. This must be between 0 and 1. The default is 1 (fully opaque).
4907
+ transposeAxes : bool , optional
4908
+ If set to True the Z and Y coordinates are transposed so that Y points "up"
4909
+ mode : int , optional
4910
+ The desired mode of meshing algorithm (for triangulation). Several options are available:
4911
+ 0: Classic
4912
+ 1: MeshAdapt
4913
+ 3: Initial Mesh Only
4914
+ 5: Delaunay
4915
+ 6: Frontal-Delaunay
4916
+ 7: BAMG
4917
+ 8: Fontal-Delaunay for Quads
4918
+ 9: Packing of Parallelograms
4919
+ All options other than 0 (Classic) use the gmsh library. See https://gmsh.info/doc/texinfo/gmsh.html#Mesh-options
4920
+ WARNING: The options that use gmsh can be very time consuming and can create very heavy geometry.
4921
+ meshSize : float , optional
4922
+ The desired size of the mesh when using the "mesh" option. If set to None, it will be
4923
+ calculated automatically and set to 10% of the overall size of the face.
4924
+ mantissa : int , optional
4925
+ The desired length of the mantissa. The default is 6.
4926
+ tolerance : float , optional
4927
+ The desired tolerance. The default is 0.0001.
4928
+ overwrite : bool , optional
4929
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't. The default is False.
4930
+
4931
+ Returns
4932
+ -------
4933
+ list
4934
+ Return the OBJ and MTL strings as a list.
4935
+
4936
+ """
4937
+ from topologicpy.Helper import Helper
4938
+ from topologicpy.Dictionary import Dictionary
4939
+ import io
4940
+
4941
+ obj_file = io.StringIO()
4942
+ mtl_file = io.StringIO()
4943
+
4944
+ if isinstance(topologies, tuple):
4945
+ topologies = Helper.Flatten(list(topologies))
4946
+ if isinstance(topologies, list):
4947
+ new_topologies = [d for d in topologies if Topology.IsInstance(d, "Topology")]
4948
+ if len(new_topologies) == 0:
4949
+ print("Topology.OBJString - Error: the input topologies parameter does not contain any valid topologies. Returning None.")
4950
+ return None
4951
+ if not isinstance(new_topologies, list):
4952
+ print("Topology.OBJString - Error: The input dictionaries parameter is not a valid list. Returning None.")
4953
+ return None
4954
+
4955
+ # Write out the material file
4956
+ n = max(len(str(len(topologies))), 3)
4957
+ for i in range(len(new_topologies)):
4958
+ d = Topology.Dictionary(new_topologies[i])
4959
+ name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
4960
+ color = Dictionary.ValueAtKey(d, colorKey) or defaultColor
4961
+ color = [c/255 for c in color]
4962
+ opacity = Dictionary.ValueAtKey(d, opacityKey) or defaultOpacity
4963
+ mtl_file.write("newmtl color_" + str(i).zfill(n) + "\n")
4964
+ mtl_file.write("Kd " + ' '.join(map(str, color)) + "\n")
4965
+ mtl_file.write("d " + str(opacity) + "\n")
4966
+
4967
+ vertex_index = 1 # global vertex index counter
4968
+ obj_file.writelines("# topologicpy "+Helper.Version()+"\n")
4969
+ obj_file.writelines("mtllib example.mtl")
4970
+ for i in range(len(topologies)):
4971
+ d = Topology.Dictionary(topologies[i])
4972
+ name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
4973
+ name = name.replace(" ", "_")
4974
+ obj_file.writelines("\ng "+name+"\n")
4975
+ result = Topology._OBJString(topologies[i], "color_" + str(i).zfill(n), vertex_index, transposeAxes=transposeAxes, mode=mode,
4976
+ meshSize=meshSize,
4977
+ mantissa=mantissa, tolerance=tolerance)
4978
+
4979
+ obj_file.writelines(result[0])
4980
+ vertex_index += result[1]
4981
+ obj_string = obj_file.getvalue()
4982
+ mtl_string = mtl_file.getvalue()
4983
+ obj_file.close()
4984
+ mtl_file.close()
4985
+ return obj_string, mtl_string
4870
4986
 
4871
4987
  @staticmethod
4872
4988
  def Filter(topologies, topologyType="any", searchType="any", key=None, value=None):
@@ -8003,4 +8119,105 @@ class Topology():
8003
8119
  predefined_namespace_dns = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
8004
8120
  namespace_uuid = uuid.uuid5(predefined_namespace_dns, namespace)
8005
8121
  brep_string = Topology.BREPString(topology)
8006
- return uuid.uuid5(namespace_uuid, brep_string)
8122
+ return uuid.uuid5(namespace_uuid, brep_string)
8123
+
8124
+ @staticmethod
8125
+ def View3D(*topologies, uuid = None, nameKey="name", colorKey="color", opacityKey="opacity", defaultColor=[256,256,256], defaultOpacity=0.5, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, overwrite: bool = False, mantissa: int = 6, tolerance: float = 0.0001):
8126
+ """
8127
+ Sends the input topologies to 3dviewer.net. The topologies must be 3D meshes.
8128
+
8129
+ Parameters
8130
+ ----------
8131
+ topologies : list or comma separated topologies
8132
+ The input list of topologies.
8133
+ uuid : UUID , optional
8134
+ The UUID v5 to use to identify these topologies. The default is a UUID based on the topologies themselves.
8135
+ nameKey : str , optional
8136
+ The topology dictionary key under which to find the name of the topology. The default is "name".
8137
+ colorKey : str, optional
8138
+ The topology dictionary key under which to find the color of the topology. The default is "color".
8139
+ opacityKey : str , optional
8140
+ The topology dictionary key under which to find the opacity of the topology. The default is "opacity".
8141
+ defaultColor : list , optional
8142
+ The default color to use if no color is stored in the topology dictionary. The default is [255,255, 255] (white).
8143
+ defaultOpacity : float , optional
8144
+ The default opacity to use of no opacity is stored in the topology dictionary. This must be between 0 and 1. The default is 1 (fully opaque).
8145
+ transposeAxes : bool , optional
8146
+ If set to True the Z and Y coordinates are transposed so that Y points "up"
8147
+ mode : int , optional
8148
+ The desired mode of meshing algorithm (for triangulation). Several options are available:
8149
+ 0: Classic
8150
+ 1: MeshAdapt
8151
+ 3: Initial Mesh Only
8152
+ 5: Delaunay
8153
+ 6: Frontal-Delaunay
8154
+ 7: BAMG
8155
+ 8: Fontal-Delaunay for Quads
8156
+ 9: Packing of Parallelograms
8157
+ All options other than 0 (Classic) use the gmsh library. See https://gmsh.info/doc/texinfo/gmsh.html#Mesh-options
8158
+ WARNING: The options that use gmsh can be very time consuming and can create very heavy geometry.
8159
+ meshSize : float , optional
8160
+ The desired size of the mesh when using the "mesh" option. If set to None, it will be
8161
+ calculated automatically and set to 10% of the overall size of the face.
8162
+ mantissa : int , optional
8163
+ The desired length of the mantissa. The default is 6.
8164
+ tolerance : float , optional
8165
+ The desired tolerance. The default is 0.0001.
8166
+ overwrite : bool , optional
8167
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't. The default is False.
8168
+
8169
+ Returns
8170
+ -------
8171
+ bool
8172
+ True if the export operation is successful. False otherwise.
8173
+
8174
+ """
8175
+ from topologicpy.Helper import Helper
8176
+ from topologicpy.Cluster import Cluster
8177
+ import requests
8178
+ import webbrowser
8179
+
8180
+ if isinstance(topologies, tuple):
8181
+ topologies = Helper.Flatten(list(topologies))
8182
+ if isinstance(topologies, list):
8183
+ new_topologies = [d for d in topologies if Topology.IsInstance(d, "Topology")]
8184
+ if len(new_topologies) == 0:
8185
+ print("Topology.View3D - Error: the input topologies parameter does not contain any valid topologies. Returning None.")
8186
+ return None
8187
+ if not isinstance(new_topologies, list):
8188
+ print("Topology.View3D - Error: The input topologies parameter is not a valid list. Returning None.")
8189
+ return None
8190
+
8191
+ if uuid == None:
8192
+ cluster = Cluster.ByTopologies(new_topologies)
8193
+ uuid = Topology.UUID(cluster)
8194
+ obj_string, mtl_string = Topology.OBJString(new_topologies,
8195
+ nameKey=nameKey,
8196
+ colorKey=colorKey,
8197
+ opacityKey=opacityKey,
8198
+ defaultColor=defaultColor,
8199
+ defaultOpacity=defaultOpacity,
8200
+ transposeAxes=transposeAxes,
8201
+ mode=mode,
8202
+ meshSize=meshSize,
8203
+ mantissa=mantissa,
8204
+ tolerance=tolerance)
8205
+
8206
+
8207
+ file_contents = {}
8208
+ file_contents['example.obj'] = obj_string
8209
+ file_contents['example.mtl'] = mtl_string
8210
+
8211
+ try:
8212
+ response = requests.post('https://3dviewer.deno.dev/upload/'+str(uuid), files=file_contents)
8213
+ if response.status_code != 200:
8214
+ print(f'Failed to upload file(s): {response.status_code} {response.reason}')
8215
+ # Open the web page in the default web browser
8216
+ # URL of the web page you want to open
8217
+ url = "https://3dviewer.deno.dev/#channel="+str(uuid)
8218
+ if not url in opened_urls:
8219
+ opened_urls.add(url)
8220
+ webbrowser.open(url)
8221
+ except requests.exceptions.RequestException as e:
8222
+ print(f'Error uploading file(s): {e}')
8223
+ return True
topologicpy/Vector.py CHANGED
@@ -77,6 +77,12 @@ class Vector(list):
77
77
  The angle in degrees between the two input vectors.
78
78
 
79
79
  """
80
+ if vectorA == None:
81
+ print("Vector.Angle - Error: The input vectorA is None. Returning None.")
82
+ return None
83
+ if vectorB == None:
84
+ print("Vector.Angle - Error: The input vectorB is None. Returning None.")
85
+ return None
80
86
  n_v1=la.norm(vectorA)
81
87
  n_v2=la.norm(vectorB)
82
88
  if n_v1 == 0 or n_v2 == 0:
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.24'
1
+ __version__ = '0.7.26'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.24
3
+ Version: 0.7.26
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
@@ -1,4 +1,4 @@
1
- topologicpy/ANN.py,sha256=CLK6kPV28ag-hc60pyqoXt4GPiYQDUL8N48tjAbZ9Do,48981
1
+ topologicpy/ANN.py,sha256=A7k3RZ6rVccLLzJhQMz_5xaDUnLJDgJMQTtnG_Bsc-s,49166
2
2
  topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
3
3
  topologicpy/Cell.py,sha256=NjcKAqZywkr7DouYP4MGLhG6grWrXYfEpzDgUN-qAC0,99802
4
4
  topologicpy/CellComplex.py,sha256=x474N-lo1krpdIGrWRAFRdDup5a_1V-mLORTS6ZGZ7M,48227
@@ -7,10 +7,10 @@ topologicpy/Color.py,sha256=UlmRcCSOhqcM_OyMWz4t3Kr75KcgXDhz3uctAJ2n7Ic,18031
7
7
  topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
8
8
  topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
9
9
  topologicpy/Dictionary.py,sha256=4VtIT1p4UHWButzRUnajj16V0DY-d5RaENbXLNTbCYU,27097
10
- topologicpy/Edge.py,sha256=QHXb0R9bdPHfHhi64rXrCeeFoLv8iaMeBxqvocBm1XI,58327
10
+ topologicpy/Edge.py,sha256=H5UVhdQ9hjBdipx0AL6U8XQXula_1pBajFB_JI_LIak,58409
11
11
  topologicpy/EnergyModel.py,sha256=ni0H1JgvLl1-q90yK9Sm1qj5P1fTuidlimEIcwuj6qE,53287
12
- topologicpy/Face.py,sha256=XS2ODccQRQvIdeuKAydjyAJmNqkwm8-RJJ5M1l4gt68,109523
13
- topologicpy/Graph.py,sha256=eKGKgfXFeTHOuKUTVfCjuRcHZLElE-nNNWhaJ2eZ4LM,391684
12
+ topologicpy/Face.py,sha256=gJNOzaTBxMcd71A-FAzQ3sQFKbsL35cpkGzgtNu6tmo,110131
13
+ topologicpy/Graph.py,sha256=rYUhw7XP6LVogbIZfAsrYEZoilN1BabloZHdcWskrMo,391663
14
14
  topologicpy/Grid.py,sha256=Q-2WNBkvIsJks7pbGkzzkRWVB4fTMYgWipG3lcDXbpE,18496
15
15
  topologicpy/Helper.py,sha256=mLwJmhyc-d-JqW82MBf7JwM91zWHVx8RzOmndPWHm-k,17717
16
16
  topologicpy/Honeybee.py,sha256=vcBECJlgWVjNNdD9ZmjNik_pA1Y_ZNoOorsQb2CiyGA,21965
@@ -21,14 +21,14 @@ topologicpy/Polyskel.py,sha256=4R5_DEdfrmi-4gR6axHNoHTCSAE2TCekOyN8jvb7bHQ,19722
21
21
  topologicpy/Shell.py,sha256=szuwRbQeHH9jd2X-DA9UhYAL_mzgfr_ctGrrQL2reWg,79917
22
22
  topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
23
23
  topologicpy/Sun.py,sha256=_gZfVyH0SDLQmmt775UeeAJ_BtwXO1STQnUMV1qkU0s,37161
24
- topologicpy/Topology.py,sha256=OcNf5bZunNwLlJ8IiFPjcWmUBbtr3idgwYDazyBK4Pk,350515
25
- topologicpy/Vector.py,sha256=JAIeOZplh7sQD46K4eP3gMgvK6iB1wwpZ0sC9-FFGq8,32803
24
+ topologicpy/Topology.py,sha256=PkuCetAUADmEuu17-R19ACoub7iZijA8S_v3t0YLL3s,361467
25
+ topologicpy/Vector.py,sha256=WQQUbwrg7VKImtxuBUi2i-FRiPT77WlrzLP05gdXKM8,33079
26
26
  topologicpy/Vertex.py,sha256=deOrCOvvGJYAludUE4Tm_L4Bx0ykQzO_ddnYSrUzsBs,71157
27
27
  topologicpy/Wire.py,sha256=_-0s6lFCStTGEjK5M-_w79UCQoPVFH1Ou8PdH_urvT0,145180
28
28
  topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
29
- topologicpy/version.py,sha256=V0wSjRUUY2SPu2U3wOLkXUyScb5-aD_z0apG3LR4-SY,23
30
- topologicpy-0.7.24.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
31
- topologicpy-0.7.24.dist-info/METADATA,sha256=C2gipIo8TAoRMeSosO1tXrLPkY5xPEiIprMpiku3JUI,10916
32
- topologicpy-0.7.24.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
33
- topologicpy-0.7.24.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
34
- topologicpy-0.7.24.dist-info/RECORD,,
29
+ topologicpy/version.py,sha256=mExVIZTppRZKivnNYLkY3fXqANuLsLtYbD1gMqdgaXM,23
30
+ topologicpy-0.7.26.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
31
+ topologicpy-0.7.26.dist-info/METADATA,sha256=s84QUjxqFTjnzTZGzBs-L1GzOLxH63nzrUVVx7DrC2I,10916
32
+ topologicpy-0.7.26.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
33
+ topologicpy-0.7.26.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
34
+ topologicpy-0.7.26.dist-info/RECORD,,