-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path__init__.py
155 lines (120 loc) · 4.62 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import bpy
import os
import mathutils
import struct
import numpy as np
import subprocess
import ctypes
import os
bl_info = {
"name": "RealScape",
"blender": (4, 3, 0), # Update this to your version
"category": "Object",
"author": "François DALL'ASTA",
"version": (1, 0),
"description": "Addon to simulate erosion and deposition on a landscape to make it more realistic",
"warning": "",
"wiki_url": "",
"tracker_url": "",
}
r=128
c=128
iter_max = 10000
rain = 0.00001
power_coef = 0.5
erosion_strength = 0.0001
deposition_strength = 0.001
diffusion_coef = 0.000000000
# This function will be executed when the button is clicked
def my_function():
print("Button clicked! Running the Python script...")
export_to_xyz(os .path.join("inout", "in.xyz"))
with open(os .path.join("inout", "param.txt"), 'w') as file:
# Write the values to the file, separated by spaces
file.write(' '.join(map(str, [r, c, iter_max, rain, power_coef, erosion_strength, deposition_strength, diffusion_coef])) + '\n')
os.system("docker run -v inout:/RealScape/inout -it realscape")
os.system("docker exec realscape ./simu")
xyz2mesh(os .path.join("inout", "out.bin"))
def export_to_xyz(file_path):
# Ensure the active object is a mesh
obj = bpy.context.active_object
if obj and obj.type == 'MESH':
# Get the mesh data
mesh = obj.data
# Open the file for writing
with open(file_path, 'w') as file:
# Iterate over the vertices and write their coordinates to the file
for vertex in mesh.vertices:
# Write the x, y, z coordinates of each vertex
file.write(f"{vertex.co.x:.8f} {vertex.co.y:.8f} {vertex.co.z:.8f}\n")
print(f"Mesh exported to {file_path}")
else:
print("Please select a mesh object.")
def xyz2mesh(file_path):
# Open the binary file
with open(file_path, "rb") as file:
# Read the entire content into bytes
binary_data = file.read()
# Unpack the data assuming it is a sequence of 4-byte floats
num_floats = len(binary_data) // 4 # Calculate how many floats are in the file
floats = struct.unpack(f"{num_floats}f", binary_data)
if len(floats) % 3 != 0:
print("Error: The number of floats in the file is not a multiple of 3.")
exit(1)
x = floats[0::3]
y = floats[1::3]
z = floats[2::3]
Nx = np.unique(x).shape[0]
Ny = np.unique(y).shape[0]
if Nx * Ny != len(x):
print("Error: x y z points are not gridded")
exit(1)
# Create a new mesh and object
mesh = bpy.data.meshes.new(name="CubeMesh")
obj = bpy.data.objects.new("Cube", mesh)
# Link the object to the scene
scene = bpy.context.scene
scene.collection.objects.link(obj)
vertices = []
faces = []
# Define vertices
for i in range(len(x)):
# Define the vertices (8 points for a cube)
vertices.append(mathutils.Vector((x[i], y[i], z[i])))
# Define faces
for i in range(Ny-1):
for j in range(Nx-1):
faces.append((i*Ny+j, i*Ny+j+1, (i+1)*Ny+j+1, (i+1)*Ny+j))
# Create the mesh from the data
mesh.from_pydata(vertices, [], faces)
# Update the mesh to reflect changes
mesh.update()
# Set the object to be active and selected
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
class SimpleButtonPanel(bpy.types.Panel):
bl_label = "Simple Button Panel"
bl_idname = "OBJECT_PT_simple_button"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Tool' # This defines which tab the panel will be in ("Tool", "Item", etc.)
def draw(self, context):
layout = self.layout
# Button to execute the function
layout.operator("object.simple_button_operator", text="Click to Run Script")
# Define the operator class that runs when the button is clicked
class SimpleButtonOperator(bpy.types.Operator):
bl_idname = "object.simple_button_operator"
bl_label = "Run Script"
def execute(self, context):
my_function() # Call the function when the button is clicked
return {'FINISHED'}
# Register the classes and the operator
def register():
bpy.utils.register_class(SimpleButtonPanel)
bpy.utils.register_class(SimpleButtonOperator)
def unregister():
bpy.utils.unregister_class(SimpleButtonPanel)
bpy.utils.unregister_class(SimpleButtonOperator)
if __name__ == "__main__":
register()