No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

155 líneas
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. ob.scale = (8,8,8)
  48. # Link object to scene and make active
  49. scn = bpy.context.scene
  50. scn.objects.link(ob)
  51. scn.objects.active = ob
  52. ob.select = False
  53. # Create mesh from given verts, faces.
  54. me.from_pydata(verts, [], faces)
  55. # Update mesh with new data
  56. me.update()
  57. def subdivide(verts, faces, iteration):
  58. newFaces = []
  59. dividedEdges = {}
  60. def vecLen(vec):
  61. return sum([c**2 for c in vec])**.5
  62. def scaleVecToLen(vec, desiredLength):
  63. vecLen_now = vecLen(vec)
  64. return (
  65. vec[0] * desiredLength / vecLen_now,
  66. vec[1] * desiredLength / vecLen_now,
  67. vec[2] * desiredLength / vecLen_now
  68. )
  69. def getCenterPoint(p1, p2):
  70. vecLen_p1 = vecLen(verts[p1])
  71. vecLen_p2 = vecLen(verts[p2])
  72. vecLen_new = (vecLen_p1 + vecLen_p2)*.5
  73. heightDelta = random.gauss(0,.01*(.6**iteration))
  74. return scaleVecToLen ((
  75. (verts[p1][0] + verts[p2][0]) * .5,
  76. (verts[p1][1] + verts[p2][1]) * .5,
  77. (verts[p1][2] + verts[p2][2]) * .5
  78. ), vecLen_new + heightDelta)
  79. def divideEdge(edge):
  80. try:
  81. normalizedEdge = list(edge)
  82. normalizedEdge.sort()
  83. normalizedEdge = tuple(normalizedEdge)
  84. return dividedEdges[tuple(normalizedEdge)]
  85. except Exception as e:
  86. newVert = getCenterPoint(*edge)
  87. newIndex = len(verts)
  88. normalizedEdge = list(edge)
  89. normalizedEdge.sort()
  90. normalizedEdge = tuple(normalizedEdge)
  91. dividedEdges[normalizedEdge] = newIndex
  92. verts.append(newVert)
  93. return newIndex
  94. for face in faces:
  95. edge1 = (face[0], face[1])
  96. edge2 = (face[1], face[2])
  97. edge3 = (face[2], face[0])
  98. newFaces.append((
  99. face[0],
  100. divideEdge(edge1),
  101. divideEdge(edge3)
  102. ))
  103. newFaces.append((
  104. face[1],
  105. divideEdge(edge2),
  106. divideEdge(edge1)
  107. ))
  108. newFaces.append((
  109. face[2],
  110. divideEdge(edge3),
  111. divideEdge(edge2)
  112. ))
  113. newFaces.append((
  114. divideEdge(edge1),
  115. divideEdge(edge2),
  116. divideEdge(edge3)
  117. ))
  118. return verts, newFaces
  119. verts, faces = generateIcoSphere()
  120. for i in range(8):
  121. verts, faces = subdivide(verts, faces, i+1)
  122. createMeshFromData('ProcGenSphere', (0,0,0), verts, faces)