You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 line
3.7 KiB

  1. import bpy
  2. import random
  3. print("- - "*20)
  4. random.seed(27051996)
  5. def generateIcoSphere():
  6. verts = [
  7. (0,0,1),
  8. (0.89442, 0, 0.44721),
  9. (0.27639, 0.85064, 0.44721),
  10. (-0.7236, 0.52572, 0.44721),
  11. (-0.7236, -0.52572, 0.44721),
  12. (0.27639, -0.85064, 0.44721),
  13. ( 0.7236, 0.52572, -0.44721),
  14. (-0.27639, 0.85064, -0.44721),
  15. (-0.89442, 0, -0.44721),
  16. (-0.27639, -0.85064, -0.44721),
  17. ( 0.7236, -0.52572, -0.44721),
  18. (0,0,-1)
  19. ]
  20. faces = (
  21. (0,1,2),
  22. (0,2,3),
  23. (0,3,4),
  24. (0,4,5),
  25. (0,5,1),
  26. (1,6,2),
  27. (2,7,3),
  28. (3,8,4),
  29. (4,9,5),
  30. (5,10,1),
  31. (10,6,1),
  32. (6,7,2),
  33. (7,8,3),
  34. (8,9,4),
  35. (9,10,5),
  36. (10,11,6),
  37. (6,11,7),
  38. (7,11,8),
  39. (8,11,9),
  40. (9,11,10)
  41. )
  42. return (verts, faces)
  43. def createMeshFromData(name, origin, scale, verts, faces):
  44. # Create mesh and object
  45. me = bpy.data.meshes.new(name+'Mesh')
  46. ob = bpy.data.objects.new(name, me)
  47. ob.location = origin
  48. ob.scale = scale
  49. # Link object to scene and make active
  50. scn = bpy.context.scene
  51. scn.objects.link(ob)
  52. scn.objects.active = ob
  53. # ob.select = False
  54. # Create mesh from given verts, faces.
  55. me.from_pydata(verts, [], faces)
  56. # Update mesh with new data
  57. me.update()
  58. def subdivide(verts, faces, iteration):
  59. newFaces = []
  60. dividedEdges = {}
  61. def vecLen(vec):
  62. return sum([c**2 for c in vec])**.5
  63. def scaleVecToLen(vec, desiredLength):
  64. vecLen_now = vecLen(vec)
  65. return (
  66. vec[0] * desiredLength / vecLen_now,
  67. vec[1] * desiredLength / vecLen_now,
  68. vec[2] * desiredLength / vecLen_now
  69. )
  70. def getCenterPoint(p1, p2, q1):
  71. vecLen_p1 = vecLen(verts[p1])
  72. vecLen_p2 = vecLen(verts[p2])
  73. vecLen_q1 = vecLen(verts[q1])
  74. vecLen_new = (vecLen_p1 + vecLen_p2) + (3**.5)*vecLen_q1
  75. vecLen_new /= 2 + (3**.5)
  76. heightDelta = random.gauss(0,.01*(.6**iteration))
  77. return scaleVecToLen ((
  78. (verts[p1][0] + verts[p2][0]) * .5,
  79. (verts[p1][1] + verts[p2][1]) * .5,
  80. (verts[p1][2] + verts[p2][2]) * .5
  81. ), vecLen_new + heightDelta)
  82. def divideEdge(edge, q1):
  83. try:
  84. normalizedEdge = list(edge)
  85. normalizedEdge.sort()
  86. normalizedEdge = tuple(normalizedEdge)
  87. return dividedEdges[tuple(normalizedEdge)]
  88. except Exception as e:
  89. newVert = getCenterPoint(*edge, q1)
  90. newIndex = len(verts)
  91. normalizedEdge = list(edge)
  92. normalizedEdge.sort()
  93. normalizedEdge = tuple(normalizedEdge)
  94. dividedEdges[normalizedEdge] = newIndex
  95. verts.append(newVert)
  96. return newIndex
  97. for face in faces:
  98. edge1 = (face[0], face[1])
  99. edge2 = (face[1], face[2])
  100. edge3 = (face[2], face[0])
  101. newFaces.append((
  102. face[0],
  103. divideEdge(edge1, face[2]),
  104. divideEdge(edge3, face[1])
  105. ))
  106. newFaces.append((
  107. face[1],
  108. divideEdge(edge2, face[0]),
  109. divideEdge(edge1, face[2])
  110. ))
  111. newFaces.append((
  112. face[2],
  113. divideEdge(edge3, face[1]),
  114. divideEdge(edge2, face[0])
  115. ))
  116. newFaces.append((
  117. divideEdge(edge1, face[2]),
  118. divideEdge(edge2, face[0]),
  119. divideEdge(edge3, face[1])
  120. ))
  121. return verts, newFaces
  122. verts, faces = generateIcoSphere()
  123. for i in range(6):
  124. verts, faces = subdivide(verts, faces, i+1)
  125. createMeshFromData('ProcGenSphere', (0,0,0), (8,8,8), verts, faces)