Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

153 рядки
3.5 KiB

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