3
0

Sphere.py 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. """
  2. Copyright (c) Contributors to the Open 3D Engine Project.
  3. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. """
  6. import Icosahedron
  7. import WhiteBoxMath as whiteBoxMath
  8. import WhiteBoxInit as init
  9. import argparse
  10. import azlmbr.legacy.general as general
  11. import azlmbr.bus as bus
  12. import azlmbr.whitebox.api as api
  13. # usage: pyRunFile path/to/file/sphere.py <subdivisions>
  14. # get the midpoint of v1 and v2 from created_midpoints if already made, otherwise create new one
  15. def get_midpoint_vertex(whiteBoxMesh, v1, v2, radius, created_midpoints):
  16. # get the index of the vertices to look them up
  17. index1 = v1.Index()
  18. index2 = v2.Index()
  19. # search created_midpoints to see if this midpoint has already been made
  20. # we store edges as tuples but keep in mind the edge (v1, v2) == (v2, v1) so we search both
  21. if (index1, index2) in created_midpoints:
  22. return created_midpoints.get((index1, index2))
  23. if (index2, index1) in created_midpoints:
  24. return created_midpoints.get((index2, index1))
  25. # create the new midpoint vertex and store in created_midpoints
  26. pos1 = whiteBoxMesh.VertexPosition(v1)
  27. pos2 = whiteBoxMesh.VertexPosition(v2)
  28. midpoint = whiteBoxMesh.AddVertex(whiteBoxMath.normalize_midpoint(pos1, pos2, radius))
  29. created_midpoints.update({(index1, index2): midpoint})
  30. return midpoint
  31. # divide each triangular face into four smaller faces
  32. def subdivide_faces(whiteBoxMesh, faces, radius):
  33. new_faces = []
  34. created_midpoints = dict()
  35. for faceVertHandles in faces:
  36. # get each vertex
  37. v0 = faceVertHandles.VertexHandles[0]
  38. v1 = faceVertHandles.VertexHandles[1]
  39. v2 = faceVertHandles.VertexHandles[2]
  40. # get the vertex representing the midpoint of each of the edges
  41. v3 = get_midpoint_vertex(whiteBoxMesh, v0, v1, radius, created_midpoints)
  42. v4 = get_midpoint_vertex(whiteBoxMesh, v1, v2, radius, created_midpoints)
  43. v5 = get_midpoint_vertex(whiteBoxMesh, v0, v2, radius, created_midpoints)
  44. # create four subdivided faces for each original face
  45. new_faces.append(api.util_MakeFaceVertHandles(v0, v3, v5))
  46. new_faces.append(api.util_MakeFaceVertHandles(v3, v1, v4))
  47. new_faces.append(api.util_MakeFaceVertHandles(v4, v2, v5))
  48. new_faces.append(api.util_MakeFaceVertHandles(v3, v4, v5))
  49. return new_faces
  50. # create sphere by subdividing an icosahedron
  51. def create_sphere(whiteBoxMesh, subdivisions=2, radius=0.55):
  52. # create icosahedron faces and subdivide them to create a sphere
  53. icosahedron_faces = Icosahedron.create_icosahedron_faces(whiteBoxMesh, radius)
  54. for division in range (0, subdivisions):
  55. icosahedron_faces = subdivide_faces(whiteBoxMesh, icosahedron_faces, radius)
  56. for face in icosahedron_faces:
  57. whiteBoxMesh.AddPolygon([face])
  58. if __name__ == "__main__":
  59. # cmdline arguments
  60. parser = argparse.ArgumentParser(description='Creates a sphere shaped white box mesh.')
  61. parser.add_argument('subdivisions', nargs='?', default=3, choices=range(0, 5), type=int, help='number of subdivisions to form sphere from icosahedron')
  62. parser.add_argument('radius', nargs='?', default=0.55, type=float, help='radius of the sphere')
  63. args = parser.parse_args()
  64. # initialize whiteBoxMesh
  65. whiteBoxEntity = init.create_white_box_entity("WhiteBox-Sphere")
  66. whiteBoxMeshComponent = init.create_white_box_component(whiteBoxEntity)
  67. whiteBoxMesh = init.create_white_box_handle(whiteBoxMeshComponent)
  68. # clear whiteBoxMesh to make a sphere from scratch
  69. whiteBoxMesh.Clear()
  70. create_sphere(whiteBoxMesh, args.subdivisions, args.radius)
  71. # update whiteBoxMesh
  72. init.update_white_box(whiteBoxMesh, whiteBoxMeshComponent)