Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

158 řádky
3.7 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,.05*(.5**iteration))
  73. # heightDelta = 0
  74. # if heightDelta < 0:
  75. # heightDelta = -(heightDelta**iteration)
  76. # else:
  77. # heightDelta = heightDelta**iteration
  78. return expandVecToLen ((
  79. (verts[p1][0]+ verts[p2][0])*.5,
  80. (verts[p1][1]+ verts[p2][1])*.5,
  81. (verts[p1][2]+ verts[p2][2])*.5
  82. ), vecLen_new + heightDelta)
  83. def divideEdge(edge):
  84. try:
  85. normalizedEdge = list(edge)
  86. normalizedEdge.sort()
  87. normalizedEdge = tuple(normalizedEdge)
  88. return dividedEdges[tuple(normalizedEdge)]
  89. except Exception as e:
  90. newVert = getCenterPoint(*edge)
  91. newIndex = len(verts)
  92. normalizedEdge = list(edge)
  93. normalizedEdge.sort()
  94. normalizedEdge = tuple(normalizedEdge)
  95. dividedEdges[normalizedEdge] = newIndex
  96. verts.append(newVert)
  97. return newIndex
  98. for face in faces:
  99. edge1 = (face[0], face[1])
  100. edge2 = (face[1], face[2])
  101. edge3 = (face[2], face[0])
  102. newFaces.append((
  103. face[0],
  104. divideEdge(edge1),
  105. divideEdge(edge3)
  106. ))
  107. newFaces.append((
  108. face[1],
  109. divideEdge(edge2),
  110. divideEdge(edge1)
  111. ))
  112. newFaces.append((
  113. face[2],
  114. divideEdge(edge3),
  115. divideEdge(edge2)
  116. ))
  117. newFaces.append((
  118. divideEdge(edge1),
  119. divideEdge(edge2),
  120. divideEdge(edge3)
  121. ))
  122. return verts, newFaces
  123. verts, faces = generateIcoSphere()
  124. for i in range(9):
  125. verts, faces = subdivide(verts, faces, i+1)
  126. createMeshFromData('ProcGenSphere', (0,0,0), verts, faces)