topologicpy 0.5.3__py3-none-any.whl → 0.5.5__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/Face.py CHANGED
@@ -230,7 +230,7 @@ class Face(Topology):
230
230
  for z in range(za,zb,zc):
231
231
  if flag:
232
232
  break
233
- t = Topology.Rotate(topology, origin=origin, x=0,y=0,z=1, degree=z)
233
+ t = Topology.Rotate(topology, origin=origin, axis=[0, 0, 1], angle=z)
234
234
  minX, minY, maxX, maxY = bb(t)
235
235
  w = abs(maxX - minX)
236
236
  l = abs(maxY - minY)
@@ -257,7 +257,7 @@ class Face(Topology):
257
257
 
258
258
  baseWire = Wire.ByVertices([vb1, vb2, vb3, vb4], close=True)
259
259
  baseFace = Face.ByWire(baseWire, tolerance=tolerance)
260
- baseFace = Topology.Rotate(baseFace, origin=origin, x=0,y=0,z=1, degree=-best_z)
260
+ baseFace = Topology.Rotate(baseFace, origin=origin, axis=[0, 0, 1], angle=-best_z)
261
261
  dictionary = Dictionary.ByKeysValues(["zrot"], [best_z])
262
262
  baseFace = Topology.SetDictionary(baseFace, dictionary)
263
263
  return baseFace
@@ -484,7 +484,7 @@ class Face(Topology):
484
484
  return None
485
485
 
486
486
  @staticmethod
487
- def ByVertices(vertices: list) -> topologic.Face:
487
+ def ByVertices(vertices: list, tolerance: float = 0.0001) -> topologic.Face:
488
488
 
489
489
  """
490
490
  Creates a face from the input list of vertices.
@@ -493,6 +493,8 @@ class Face(Topology):
493
493
  ----------
494
494
  vertices : list
495
495
  The input list of vertices.
496
+ tolerance : float , optional
497
+ The desired tolerance. The default is 0.0001.
496
498
 
497
499
  Returns
498
500
  -------
@@ -509,12 +511,12 @@ class Face(Topology):
509
511
  if len(vertexList) < 3:
510
512
  return None
511
513
 
512
- w = Wire.ByVertices(vertexList)
513
- f = Face.ByWire(w)
514
+ w = Wire.ByVertices(vertexList, tolerance=tolerance)
515
+ f = Face.ByWire(w, tolerance=tolerance)
514
516
  return f
515
517
 
516
518
  @staticmethod
517
- def ByVerticesCluster(cluster: topologic.Cluster) -> topologic.Face:
519
+ def ByVerticesCluster(cluster: topologic.Cluster, tolerance: float = 0.0001) -> topologic.Face:
518
520
  """
519
521
  Creates a face from the input cluster of vertices.
520
522
 
@@ -522,6 +524,8 @@ class Face(Topology):
522
524
  ----------
523
525
  cluster : topologic.Cluster
524
526
  The input cluster of vertices.
527
+ tolerance : float , optional
528
+ The desired tolerance. The default is 0.0001.
525
529
 
526
530
  Returns
527
531
  -------
@@ -533,7 +537,7 @@ class Face(Topology):
533
537
  if not isinstance(cluster, topologic.Cluster):
534
538
  return None
535
539
  vertices = Cluster.Vertices(cluster)
536
- return Face.ByVertices(vertices)
540
+ return Face.ByVertices(vertices, tolerance=tolerance)
537
541
 
538
542
  @staticmethod
539
543
  def ByWire(wire: topologic.Wire, tolerance: float = 0.0001, silent=False) -> topologic.Face:
@@ -705,7 +709,7 @@ class Face(Topology):
705
709
  return Face.ByWires(externalBoundary, internalBoundaries, tolerance=tolerance, silent=silent)
706
710
 
707
711
  @staticmethod
708
- def NorthArrow(origin: topologic.Vertex = None, radius: float = 0.5, sides: int = 16, direction: list = [0,0,1], northAngle: float = 0.0,
712
+ def NorthArrow(origin: topologic.Vertex = None, radius: float = 0.5, sides: int = 16, direction: list = [0, 0, 1], northAngle: float = 0.0,
709
713
  placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
710
714
  """
711
715
  Creates a north arrow.
@@ -713,13 +717,13 @@ class Face(Topology):
713
717
  Parameters
714
718
  ----------
715
719
  origin : topologic.Vertex, optional
716
- The location of the origin of the circle. The default is None which results in the circle being placed at (0,0,0).
720
+ The location of the origin of the circle. The default is None which results in the circle being placed at (0, 0, 0).
717
721
  radius : float , optional
718
722
  The radius of the circle. The default is 1.
719
723
  sides : int , optional
720
724
  The number of sides of the circle. The default is 16.
721
725
  direction : list , optional
722
- The vector representing the up direction of the circle. The default is [0,0,1].
726
+ The vector representing the up direction of the circle. The default is [0, 0, 1].
723
727
  northAngle : float , optional
724
728
  The angular offset in degrees from the positive Y axis direction. The angle is measured in a counter-clockwise fashion where 0 is positive Y, 90 is negative X, 180 is negative Y, and 270 is positive X.
725
729
  placement : str , optional
@@ -738,11 +742,11 @@ class Face(Topology):
738
742
  if not origin:
739
743
  origin = Vertex.Origin()
740
744
 
741
- c = Face.Circle(origin=origin, radius=radius, sides=sides, direction=[0,0,1], placement="center", tolerance=tolerance)
745
+ c = Face.Circle(origin=origin, radius=radius, sides=sides, direction=[0, 0, 1], placement="center", tolerance=tolerance)
742
746
  r = Face.Rectangle(origin=origin, width=radius*0.01,length=radius*1.2, placement="lowerleft")
743
747
  r = Topology.Translate(r, -0.005*radius,0,0)
744
748
  arrow = Topology.Difference(c, r, tolerance=tolerance)
745
- arrow = Topology.Rotate(arrow, Vertex.Origin(), 0,0,1,northAngle)
749
+ arrow = Topology.Rotate(arrow, origin=Vertex.Origin(), axis=[0, 0, 1], angle=northAngle)
746
750
  if placement.lower() == "lowerleft":
747
751
  arrow = Topology.Translate(arrow, radius, radius, 0)
748
752
  elif placement.lower() == "upperleft":
@@ -756,7 +760,7 @@ class Face(Topology):
756
760
  return arrow
757
761
 
758
762
  @staticmethod
759
- def Circle(origin: topologic.Vertex = None, radius: float = 0.5, sides: int = 16, fromAngle: float = 0.0, toAngle: float = 360.0, direction: list = [0,0,1],
763
+ def Circle(origin: topologic.Vertex = None, radius: float = 0.5, sides: int = 16, fromAngle: float = 0.0, toAngle: float = 360.0, direction: list = [0, 0, 1],
760
764
  placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
761
765
  """
762
766
  Creates a circle.
@@ -764,7 +768,7 @@ class Face(Topology):
764
768
  Parameters
765
769
  ----------
766
770
  origin : topologic.Vertex, optional
767
- The location of the origin of the circle. The default is None which results in the circle being placed at (0,0,0).
771
+ The location of the origin of the circle. The default is None which results in the circle being placed at (0, 0, 0).
768
772
  radius : float , optional
769
773
  The radius of the circle. The default is 1.
770
774
  sides : int , optional
@@ -774,7 +778,7 @@ class Face(Topology):
774
778
  toAngle : float , optional
775
779
  The angle in degrees at which to end creating the arc of the circle. The default is 360.
776
780
  direction : list , optional
777
- The vector representing the up direction of the circle. The default is [0,0,1].
781
+ The vector representing the up direction of the circle. The default is [0, 0, 1].
778
782
  placement : str , optional
779
783
  The description of the placement of the origin of the circle. This can be "center", "lowerleft", "upperleft", "lowerright", or "upperright". It is case insensitive. The default is "center".
780
784
  tolerance : float , optional
@@ -880,19 +884,19 @@ class Face(Topology):
880
884
  return edges
881
885
 
882
886
  @staticmethod
883
- def Einstein(origin: topologic.Vertex = None, radius: float = 0.5, direction: list = [0,0,1],
884
- placement: str = "center", tolerance: float=0.0001) -> topologic.Face:
887
+ def Einstein(origin: topologic.Vertex = None, radius: float = 0.5, direction: list = [0, 0, 1],
888
+ placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
885
889
  """
886
890
  Creates an aperiodic monotile, also called an 'einstein' tile (meaning one tile in German, not the name of the famous physist). See https://arxiv.org/abs/2303.10798
887
891
 
888
892
  Parameters
889
893
  ----------
890
894
  origin : topologic.Vertex , optional
891
- The location of the origin of the tile. The default is None which results in the tiles first vertex being placed at (0,0,0).
895
+ The location of the origin of the tile. The default is None which results in the tiles first vertex being placed at (0, 0, 0).
892
896
  radius : float , optional
893
897
  The radius of the hexagon determining the size of the tile. The default is 0.5.
894
898
  direction : list , optional
895
- The vector representing the up direction of the ellipse. The default is [0,0,1].
899
+ The vector representing the up direction of the ellipse. The default is [0, 0, 1].
896
900
  placement : str , optional
897
901
  The description of the placement of the origin of the hexagon determining the location of the tile. This can be "center", or "lowerleft". It is case insensitive. The default is "center".
898
902
  tolerance : float , optional
@@ -927,7 +931,8 @@ class Face(Topology):
927
931
  internal boundaries (holes). For example: [[270,270,270,270], [[270,270,270,270],[300,300,300]]]. If not, the returned list will be
928
932
  a simple list of interior angles of the external boundary. For example: [270,270,270,270]. Please note that that the interior angles of the
929
933
  internal boundaries are considered to be those interior to the original face. Thus, they are exterior to the internal boundary.
930
-
934
+ mantissa : int , optional
935
+ The desired length of the mantissa. The default is 6.
931
936
  Returns
932
937
  -------
933
938
  list
@@ -1054,7 +1059,7 @@ class Face(Topology):
1054
1059
  return harmonizedFace
1055
1060
 
1056
1061
  @staticmethod
1057
- def InteriorAngles(face: topologic.Face, includeInternalBoundaries=False, mantissa: int = 6) -> list:
1062
+ def InteriorAngles(face: topologic.Face, includeInternalBoundaries: bool = False, mantissa: int = 6) -> list:
1058
1063
  """
1059
1064
  Returns the interior angles of the input face in degrees. The face must be planar.
1060
1065
 
@@ -1068,7 +1073,8 @@ class Face(Topology):
1068
1073
  internal boundaries (holes). For example: [[90,90,90,90], [[90,90,90,90],[60,60,60]]]. If not, the returned list will be
1069
1074
  a simple list of interior angles of the external boundary. For example: [90,90,90,90]. Please note that that the interior angles of the
1070
1075
  internal boundaries are considered to be those interior to the original face. Thus, they are exterior to the internal boundary.
1071
-
1076
+ mantissa : int , optional
1077
+ The desired length of the mantissa. The default is 6.
1072
1078
  Returns
1073
1079
  -------
1074
1080
  list
@@ -1269,7 +1275,7 @@ class Face(Topology):
1269
1275
  normal = Face.Normal(face)
1270
1276
  flatFace = Topology.Flatten(face, origin=origin, direction=normal)
1271
1277
 
1272
- # Create a Vertex at the world's origin (0,0,0)
1278
+ # Create a Vertex at the world's origin (0, 0, 0)
1273
1279
  world_origin = Vertex.Origin()
1274
1280
 
1275
1281
  faceEdges = Face.Edges(flatFace)
@@ -1592,20 +1598,20 @@ class Face(Topology):
1592
1598
  return Face.Rectangle(origin=origin, width=width, length=length, direction = direction, placement=placement, tolerance=tolerance)
1593
1599
 
1594
1600
  @staticmethod
1595
- def Rectangle(origin: topologic.Vertex = None, width: float = 1.0, length: float = 1.0, direction: list = [0,0,1], placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
1601
+ def Rectangle(origin: topologic.Vertex = None, width: float = 1.0, length: float = 1.0, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
1596
1602
  """
1597
1603
  Creates a rectangle.
1598
1604
 
1599
1605
  Parameters
1600
1606
  ----------
1601
1607
  origin : topologic.Vertex, optional
1602
- The location of the origin of the rectangle. The default is None which results in the rectangle being placed at (0,0,0).
1608
+ The location of the origin of the rectangle. The default is None which results in the rectangle being placed at (0, 0, 0).
1603
1609
  width : float , optional
1604
1610
  The width of the rectangle. The default is 1.0.
1605
1611
  length : float , optional
1606
1612
  The length of the rectangle. The default is 1.0.
1607
1613
  direction : list , optional
1608
- The vector representing the up direction of the rectangle. The default is [0,0,1].
1614
+ The vector representing the up direction of the rectangle. The default is [0, 0, 1].
1609
1615
  placement : str , optional
1610
1616
  The description of the placement of the origin of the rectangle. This can be "center", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
1611
1617
  tolerance : float , optional
@@ -1680,18 +1686,18 @@ class Face(Topology):
1680
1686
  return Wire.Skeleton(face, tolerance=tolerance)
1681
1687
 
1682
1688
  @staticmethod
1683
- def Square(origin: topologic.Vertex = None, size: float = 1.0, direction: list = [0,0,1], placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
1689
+ def Square(origin: topologic.Vertex = None, size: float = 1.0, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
1684
1690
  """
1685
1691
  Creates a square.
1686
1692
 
1687
1693
  Parameters
1688
1694
  ----------
1689
1695
  origin : topologic.Vertex , optional
1690
- The location of the origin of the square. The default is None which results in the square being placed at (0,0,0).
1696
+ The location of the origin of the square. The default is None which results in the square being placed at (0, 0, 0).
1691
1697
  size : float , optional
1692
1698
  The size of the square. The default is 1.0.
1693
1699
  direction : list , optional
1694
- The vector representing the up direction of the square. The default is [0,0,1].
1700
+ The vector representing the up direction of the square. The default is [0, 0, 1].
1695
1701
  placement : str , optional
1696
1702
  The description of the placement of the origin of the square. This can be "center", "lowerleft", "upperleft", "lowerright", or "upperright". It is case insensitive. The default is "center".
1697
1703
  tolerance : float , optional
@@ -1706,14 +1712,14 @@ class Face(Topology):
1706
1712
  return Face.Rectangle(origin=origin, width=size, length=size, direction=direction, placement=placement, tolerance=tolerance)
1707
1713
 
1708
1714
  @staticmethod
1709
- def Star(origin: topologic.Vertex = None, radiusA: float = 1.0, radiusB: float = 0.4, rays: int = 5, direction: list = [0,0,1], placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
1715
+ def Star(origin: topologic.Vertex = None, radiusA: float = 1.0, radiusB: float = 0.4, rays: int = 5, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
1710
1716
  """
1711
1717
  Creates a star.
1712
1718
 
1713
1719
  Parameters
1714
1720
  ----------
1715
1721
  origin : topologic.Vertex, optional
1716
- The location of the origin of the star. The default is None which results in the star being placed at (0,0,0).
1722
+ The location of the origin of the star. The default is None which results in the star being placed at (0, 0, 0).
1717
1723
  radiusA : float , optional
1718
1724
  The outer radius of the star. The default is 1.0.
1719
1725
  radiusB : float , optional
@@ -1721,7 +1727,7 @@ class Face(Topology):
1721
1727
  rays : int , optional
1722
1728
  The number of star rays. The default is 5.
1723
1729
  direction : list , optional
1724
- The vector representing the up direction of the star. The default is [0,0,1].
1730
+ The vector representing the up direction of the star. The default is [0, 0, 1].
1725
1731
  placement : str , optional
1726
1732
  The description of the placement of the origin of the star. This can be "center", "lowerleft", "upperleft", "lowerright", or "upperright". It is case insensitive. The default is "center".
1727
1733
  tolerance : float , optional
@@ -1741,14 +1747,14 @@ class Face(Topology):
1741
1747
  return Face.ByWire(wire, tolerance=tolerance)
1742
1748
 
1743
1749
  @staticmethod
1744
- def Trapezoid(origin: topologic.Vertex = None, widthA: float = 1.0, widthB: float = 0.75, offsetA: float = 0.0, offsetB: float = 0.0, length: float = 1.0, direction: list = [0,0,1], placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
1750
+ def Trapezoid(origin: topologic.Vertex = None, widthA: float = 1.0, widthB: float = 0.75, offsetA: float = 0.0, offsetB: float = 0.0, length: float = 1.0, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001) -> topologic.Face:
1745
1751
  """
1746
1752
  Creates a trapezoid.
1747
1753
 
1748
1754
  Parameters
1749
1755
  ----------
1750
1756
  origin : topologic.Vertex, optional
1751
- The location of the origin of the trapezoid. The default is None which results in the trapezoid being placed at (0,0,0).
1757
+ The location of the origin of the trapezoid. The default is None which results in the trapezoid being placed at (0, 0, 0).
1752
1758
  widthA : float , optional
1753
1759
  The width of the bottom edge of the trapezoid. The default is 1.0.
1754
1760
  widthB : float , optional
@@ -1760,7 +1766,7 @@ class Face(Topology):
1760
1766
  length : float , optional
1761
1767
  The length of the trapezoid. The default is 1.0.
1762
1768
  direction : list , optional
1763
- The vector representing the up direction of the trapezoid. The default is [0,0,1].
1769
+ The vector representing the up direction of the trapezoid. The default is [0, 0, 1].
1764
1770
  placement : str , optional
1765
1771
  The description of the placement of the origin of the trapezoid. This can be "center", or "lowerleft". It is case insensitive. The default is "center".
1766
1772
  tolerance : float , optional
@@ -1780,7 +1786,7 @@ class Face(Topology):
1780
1786
  return Face.ByWire(wire, tolerance=tolerance)
1781
1787
 
1782
1788
  @staticmethod
1783
- def Triangulate(face:topologic.Face, tolerance: float = 0.0001) -> list:
1789
+ def Triangulate(face:topologic.Face, mode: str = "classic", meshSize: float = None, tolerance: float = 0.0001) -> list:
1784
1790
  """
1785
1791
  Triangulates the input face and returns a list of faces.
1786
1792
 
@@ -1790,6 +1796,13 @@ class Face(Topology):
1790
1796
  The input face.
1791
1797
  tolerance : float , optional
1792
1798
  The desired tolerance. The default is 0.0001.
1799
+ mode : str , optional
1800
+ The desired mode of meshing. Two options are available: "classic" and "mesh". They are case insensitive.
1801
+ The "mesh" option uses the gmsh library.
1802
+ WARNING: The "mesh" option can be very time consuming and can create very heavy geometry.
1803
+ meshSize : float , optional
1804
+ The desired size of the mesh when using the "mesh" option. If set to None, it will be
1805
+ calculated automatically and set to 10% of the overall size of the face.
1793
1806
 
1794
1807
  Returns
1795
1808
  -------
@@ -1803,6 +1816,135 @@ class Face(Topology):
1803
1816
  from topologicpy.Topology import Topology
1804
1817
  from topologicpy.Dictionary import Dictionary
1805
1818
 
1819
+ # This function was contributed by Yidan Xue.
1820
+ def generate_gmsh(face, meshSize = None, tolerance = 0.0001):
1821
+ """
1822
+ Creates a gmsh of triangular meshes from the input face.
1823
+
1824
+ Parameters
1825
+ ----------
1826
+ face : topologic.Face
1827
+ The input face.
1828
+ meshSize : float , optional
1829
+ The desired mesh size.
1830
+ tolerance : float , optional
1831
+ The desired tolerance. The default is 0.0001.
1832
+
1833
+ Returns
1834
+ ----------
1835
+ topologic.Shell
1836
+ The shell of triangular meshes.
1837
+
1838
+ """
1839
+ import os
1840
+ import warnings
1841
+ try:
1842
+ import numpy as np
1843
+ except:
1844
+ print("Face.Triangulate - Warning: Installing required numpy library.")
1845
+ try:
1846
+ os.system("pip install numpy")
1847
+ except:
1848
+ os.system("pip install numpy --user")
1849
+ try:
1850
+ import numpy as np
1851
+ print("Face.Triangulate - Warning: numpy library installed correctly.")
1852
+ except:
1853
+ warnings.warn("Face.Triangulate - Error: Could not import numpy. Please try to install numpy manually. Returning None.")
1854
+ return None
1855
+ try:
1856
+ import gmsh
1857
+ except:
1858
+ print("Face.Triangulate - Warning: Installing required gmsh library.")
1859
+ try:
1860
+ os.system("pip install gmsh")
1861
+ except:
1862
+ os.system("pip install gmsh --user")
1863
+ try:
1864
+ import gmsh
1865
+ print("Face.Triangulate - Warning: gmsh library installed correctly.")
1866
+ except:
1867
+ warnings.warn("Face.Triangulate - Error: Could not import gmsh. Please try to install gmsh manually. Returning None.")
1868
+ return None
1869
+
1870
+ import topologic
1871
+ from topologicpy.Vertex import Vertex
1872
+ from topologicpy.Wire import Wire
1873
+ from topologicpy.Face import Face
1874
+
1875
+ if not isinstance(face, topologic.Face):
1876
+ print("Shell.ByMeshFace - Error: The input face parameter is not a valid face. Returning None.")
1877
+ return None
1878
+ if not meshSize:
1879
+ bounding_face = Face.BoundingRectangle(face)
1880
+ bounding_face_vertices = Face.Vertices(bounding_face)
1881
+ bounding_face_vertices_x = [Vertex.X(i) for i in bounding_face_vertices]
1882
+ bounding_face_vertices_y = [Vertex.Y(i) for i in bounding_face_vertices]
1883
+ width = max(bounding_face_vertices_x)-min(bounding_face_vertices_x)
1884
+ length = max(bounding_face_vertices_y)-min(bounding_face_vertices_y)
1885
+ meshSize = max([width,length])//10
1886
+
1887
+ gmsh.initialize()
1888
+ face_external_boundary = Face.ExternalBoundary(face)
1889
+ external_vertices = Wire.Vertices(face_external_boundary)
1890
+ external_vertex_number = len(external_vertices)
1891
+ for i in range(external_vertex_number):
1892
+ gmsh.model.geo.addPoint(Vertex.X(external_vertices[i]), Vertex.Y(external_vertices[i]), Vertex.Z(external_vertices[i]), meshSize, i+1)
1893
+ for i in range(external_vertex_number):
1894
+ if i < external_vertex_number-1:
1895
+ gmsh.model.geo.addLine(i+1, i+2, i+1)
1896
+ else:
1897
+ gmsh.model.geo.addLine(i+1, 1, i+1)
1898
+ gmsh.model.geo.addCurveLoop([i+1 for i in range(external_vertex_number)], 1)
1899
+ current_vertex_number = external_vertex_number
1900
+ current_edge_number = external_vertex_number
1901
+ current_wire_number = 1
1902
+
1903
+ face_internal_boundaries = Face.InternalBoundaries(face)
1904
+ if face_internal_boundaries:
1905
+ internal_face_number = len(face_internal_boundaries)
1906
+ for i in range(internal_face_number):
1907
+ face_internal_boundary = face_internal_boundaries[i]
1908
+ internal_vertices = Wire.Vertices(face_internal_boundary)
1909
+ internal_vertex_number = len(internal_vertices)
1910
+ for j in range(internal_vertex_number):
1911
+ gmsh.model.geo.addPoint(Vertex.X(internal_vertices[j]), Vertex.Y(internal_vertices[j]), Vertex.Z(internal_vertices[j]), meshSize, current_vertex_number+j+1)
1912
+ for j in range(internal_vertex_number):
1913
+ if j < internal_vertex_number-1:
1914
+ gmsh.model.geo.addLine(current_vertex_number+j+1, current_vertex_number+j+2, current_edge_number+j+1)
1915
+ else:
1916
+ gmsh.model.geo.addLine(current_vertex_number+j+1, current_vertex_number+1, current_edge_number+j+1)
1917
+ gmsh.model.geo.addCurveLoop([current_edge_number+i+1 for i in range(internal_vertex_number)], current_wire_number+1)
1918
+ current_vertex_number = current_vertex_number+internal_vertex_number
1919
+ current_edge_number = current_edge_number+internal_vertex_number
1920
+ current_wire_number = current_wire_number+1
1921
+
1922
+ gmsh.model.geo.addPlaneSurface([i+1 for i in range(current_wire_number)])
1923
+ gmsh.model.geo.synchronize()
1924
+
1925
+ gmsh.model.mesh.generate(2) # For a 2D mesh
1926
+ nodeTags, nodeCoords, nodeParams = gmsh.model.mesh.getNodes(-1, -1)
1927
+ elemTypes, elemTags, elemNodeTags = gmsh.model.mesh.getElements(-1, -1)
1928
+ gmsh.finalize()
1929
+
1930
+ vertex_number = len(nodeTags)
1931
+ vertices = []
1932
+ for i in range(vertex_number):
1933
+ vertices.append(Vertex.ByCoordinates(nodeCoords[3*i],nodeCoords[3*i+1],nodeCoords[3*i+2]))
1934
+
1935
+ faces = []
1936
+ for n in range(len(elemTypes)):
1937
+ vn = elemTypes[n]+1
1938
+ et = elemTags[n]
1939
+ ent = elemNodeTags[n]
1940
+ if vn==3:
1941
+ for i in range(len(et)):
1942
+ face_vertices = []
1943
+ for j in range(vn):
1944
+ face_vertices.append(vertices[np.where(nodeTags==ent[i*vn+j])[0][0]])
1945
+ faces.append(Face.ByVertices(face_vertices))
1946
+ return faces
1947
+
1806
1948
  if not isinstance(face, topologic.Face):
1807
1949
  print("Face.Triangulate - Error: The input face parameter is not a valid face. Returning None.")
1808
1950
  return None
@@ -1812,14 +1954,17 @@ class Face(Topology):
1812
1954
  origin = Topology.Centroid(face)
1813
1955
  normal = Face.Normal(face)
1814
1956
  flatFace = Topology.Flatten(face, origin=origin, direction=normal)
1815
-
1816
- shell_faces = []
1817
- for i in range(0,5,1):
1818
- try:
1819
- _ = topologic.FaceUtility.Triangulate(flatFace, float(i)*0.1, shell_faces)
1820
- break
1821
- except:
1822
- continue
1957
+
1958
+ if "mesh" in mode.lower():
1959
+ shell_faces = generate_gmsh(flatFace, meshSize = meshSize, tolerance = tolerance)
1960
+ else:
1961
+ shell_faces = []
1962
+ for i in range(0,5,1):
1963
+ try:
1964
+ _ = topologic.FaceUtility.Triangulate(flatFace, float(i)*0.1, shell_faces)
1965
+ break
1966
+ except:
1967
+ continue
1823
1968
 
1824
1969
  if len(shell_faces) < 1:
1825
1970
  return []