Jan-Hendrik Müller commited on
Commit
40bcc93
1 Parent(s): 9eddefb
Files changed (2) hide show
  1. app.py +98 -77
  2. marimo_california.py +0 -123
app.py CHANGED
@@ -1,96 +1,117 @@
1
- # /// script
2
- # dependencies = [
3
- # "bpy==4.2.0",
4
- # "marimo",
5
- # "numpy==2.1.2",
6
- # ]
7
- # ///
8
-
9
  import marimo
10
 
11
- __generated_with = "0.9.9"
12
- app = marimo.App(width="medium")
13
-
14
-
15
- @app.cell
16
- def __():
17
- import numpy
18
- import bpy
19
- import time
20
- import random
21
- import marimo as mo
22
- import sys
23
- import tempfile
24
- print(sys.version)
25
- return bpy, mo, numpy, random, sys, tempfile, time
26
 
27
 
28
  @app.cell
29
  def __(mo):
30
- w = mo.ui.file(kind="area")
31
- w
32
- return (w,)
33
 
34
 
35
  @app.cell
36
- def __(tempfile, w):
37
- file_content = w.contents()
38
-
39
- # Create a temporary file to save the content
40
- if file_content:
41
- with tempfile.NamedTemporaryFile(suffix=".blend", delete=False) as temp_file:
42
- temp_file.write(file_content)
43
- temp_file_path = temp_file.name
44
- return file_content, temp_file, temp_file_path
45
-
46
 
47
- @app.cell
48
- def __(mo):
49
- dropdown = mo.ui.dropdown(
50
- options={
51
- "workbench": "BLENDER_WORKBENCH",
52
- "eevee": "BLENDER_EEVEE_NEXT",
53
- "cycles": "CYCLES"},
54
- value="workbench",
55
- label="choose renderer",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  )
57
- dropdown
58
- return (dropdown,)
59
 
60
 
61
  @app.cell
62
- def __(bpy, dropdown, file_content, mo, temp_file_path, time):
63
- start_time = time.time()
64
-
65
- # Ensure Cycles is selected as the render engine for all view layers
66
- for layer in bpy.context.scene.view_layers:
67
- layer.cycles.use_denoising = False
68
-
69
- # Set render samples to 10 for all view layers and the scene
70
- bpy.context.scene.cycles.samples = 10
71
-
72
- # Ensure to sync all settings
73
- bpy.context.view_layer.update()
74
 
75
 
76
- # Load the temporary .blend file into Blender
77
- if file_content:
78
- bpy.ops.wm.open_mainfile(filepath=temp_file_path)
79
-
80
- # Set render engine and resolution
81
- bpy.context.scene.render.engine = dropdown.value
82
- bpy.context.scene.render.resolution_x = 500
83
- bpy.context.scene.render.resolution_y = 400
84
- bpy.context.scene.cycles.samples = 5
85
- # Render and save the image without any rotation
86
- bpy.ops.render.render()
87
- bpy.data.images["Render Result"].save_render(filepath="test.png")
88
-
89
- end_time = time.time()
90
- print(f"Script execution time: {end_time - start_time:.4f} seconds")
91
-
92
- mo.image(src="test.png")
93
- return end_time, layer, start_time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
 
96
  @app.cell
 
 
 
 
 
 
 
 
 
1
  import marimo
2
 
3
+ __generated_with = "0.9.20"
4
+ app = marimo.App()
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
 
7
  @app.cell
8
  def __(mo):
9
+ mo.md("""# Marimo + Blender""")
10
+ return
 
11
 
12
 
13
  @app.cell
14
+ def __():
15
+ #run with
16
+ #cd california_housing
17
+ #uv run marimo edit marimo_california.py
18
+ import marimo as mo
19
+ import numpy as np
20
+ import polars as pl
21
+ import quak
22
+ import bpy
 
23
 
24
+ blend_file_path = "housing_data_igor.blend"
25
+ bpy.ops.wm.open_mainfile(filepath=blend_file_path)
26
+
27
+ bpy.context.scene.render.engine = "BLENDER_EEVEE_NEXT"
28
+ bpy.context.scene.render.resolution_x = 800
29
+ bpy.context.scene.render.resolution_y = 500
30
+
31
+ df = pl.read_csv("a_df.csv")
32
+ reference_frame = pl.read_csv("b_reference_frame.csv")
33
+
34
+ vertices = [(row["longitude_normalized"], row["latitude_normalized"], 0) for row in reference_frame.iter_rows(named=True)]
35
+
36
+ mesh = bpy.data.meshes.new("NormalizedMesh")
37
+ obj = bpy.data.objects.new("CaliforninaNormalizedObject", mesh)
38
+ bpy.context.collection.objects.link(obj)
39
+
40
+ mesh.from_pydata(vertices, [], [])
41
+ mesh.update()
42
+ obj.modifiers.new(name="GeometryNodes", type='NODES').node_group = bpy.data.node_groups["geo_house"]
43
+ bpy.context.view_layer.objects.active = obj
44
+ obj.select_set(True)
45
+ reference_frame.head()
46
+
47
+ def render_result():
48
+
49
+ bpy.ops.render.render()
50
+ bpy.data.images['Render Result'].save_render(filepath="img.png")
51
+ return mo.image(src="img.png")
52
+ return (
53
+ blend_file_path,
54
+ bpy,
55
+ df,
56
+ mesh,
57
+ mo,
58
+ np,
59
+ obj,
60
+ pl,
61
+ quak,
62
+ reference_frame,
63
+ render_result,
64
+ vertices,
65
  )
 
 
66
 
67
 
68
  @app.cell
69
+ def __(df, mo, quak):
70
+ widget = mo.ui.anywidget(quak.Widget(df))
71
+ widget
72
+ return (widget,)
 
 
 
 
 
 
 
 
73
 
74
 
75
+ @app.cell
76
+ def __(np, obj, pl, reference_frame, render_result, widget):
77
+ widget_df = widget.data().pl()
78
+
79
+ plotting_frame = reference_frame.with_columns(
80
+ pl.lit(0).alias("custom_plotting")
81
+ ).join(
82
+ widget_df.select(["short_id", "median_house_value"]),
83
+ on="short_id",
84
+ how="left"
85
+ ).with_columns(
86
+ pl.when(pl.col("median_house_value").is_not_null())
87
+ .then(pl.col("median_house_value"))
88
+ .otherwise(pl.col("custom_plotting"))
89
+ .alias("custom_plotting")
90
+ ).select(["short_id", "custom_plotting"])
91
+
92
+ custom_plotting_list = plotting_frame["custom_plotting"].to_list()
93
+ normalized_values = list(np.interp(custom_plotting_list,
94
+ (min(custom_plotting_list), max(custom_plotting_list)),
95
+ (0.1, 3)))
96
+
97
+ attr_name = 'median_house_value'
98
+ attr = obj.data.attributes.get(attr_name) or obj.data.attributes.new(
99
+ name=attr_name,
100
+ type='FLOAT',
101
+ domain='POINT'
102
+ )
103
+ attr.data.foreach_set('value', normalized_values)
104
+ obj.data.update()
105
+
106
+ render_result()
107
+ return (
108
+ attr,
109
+ attr_name,
110
+ custom_plotting_list,
111
+ normalized_values,
112
+ plotting_frame,
113
+ widget_df,
114
+ )
115
 
116
 
117
  @app.cell
marimo_california.py DELETED
@@ -1,123 +0,0 @@
1
- import marimo
2
-
3
- __generated_with = "0.9.20"
4
- app = marimo.App()
5
-
6
-
7
- @app.cell
8
- def __(mo):
9
- mo.md("""# Marimo + Blender""")
10
- return
11
-
12
-
13
- @app.cell
14
- def __():
15
- #run with
16
- #cd california_housing
17
- #uv run marimo edit marimo_california.py
18
- import marimo as mo
19
- import numpy as np
20
- import polars as pl
21
- import quak
22
- import bpy
23
-
24
- blend_file_path = "housing_data_igor.blend"
25
- bpy.ops.wm.open_mainfile(filepath=blend_file_path)
26
-
27
- bpy.context.scene.render.engine = "BLENDER_EEVEE_NEXT"
28
- bpy.context.scene.render.resolution_x = 800
29
- bpy.context.scene.render.resolution_y = 500
30
-
31
- df = pl.read_csv("a_df.csv")
32
- reference_frame = pl.read_csv("b_reference_frame.csv")
33
-
34
- vertices = [(row["longitude_normalized"], row["latitude_normalized"], 0) for row in reference_frame.iter_rows(named=True)]
35
-
36
- mesh = bpy.data.meshes.new("NormalizedMesh")
37
- obj = bpy.data.objects.new("CaliforninaNormalizedObject", mesh)
38
- bpy.context.collection.objects.link(obj)
39
-
40
- mesh.from_pydata(vertices, [], [])
41
- mesh.update()
42
- obj.modifiers.new(name="GeometryNodes", type='NODES').node_group = bpy.data.node_groups["geo_house"]
43
- bpy.context.view_layer.objects.active = obj
44
- obj.select_set(True)
45
- reference_frame.head()
46
-
47
- def render_result():
48
-
49
- bpy.ops.render.render()
50
- bpy.data.images['Render Result'].save_render(filepath="img.png")
51
- return mo.image(src="img.png")
52
- return (
53
- blend_file_path,
54
- bpy,
55
- df,
56
- mesh,
57
- mo,
58
- np,
59
- obj,
60
- pl,
61
- quak,
62
- reference_frame,
63
- render_result,
64
- vertices,
65
- )
66
-
67
-
68
- @app.cell
69
- def __(df, mo, quak):
70
- widget = mo.ui.anywidget(quak.Widget(df))
71
- widget
72
- return (widget,)
73
-
74
-
75
- @app.cell
76
- def __(np, obj, pl, reference_frame, render_result, widget):
77
- widget_df = widget.data().pl()
78
-
79
- plotting_frame = reference_frame.with_columns(
80
- pl.lit(0).alias("custom_plotting")
81
- ).join(
82
- widget_df.select(["short_id", "median_house_value"]),
83
- on="short_id",
84
- how="left"
85
- ).with_columns(
86
- pl.when(pl.col("median_house_value").is_not_null())
87
- .then(pl.col("median_house_value"))
88
- .otherwise(pl.col("custom_plotting"))
89
- .alias("custom_plotting")
90
- ).select(["short_id", "custom_plotting"])
91
-
92
- custom_plotting_list = plotting_frame["custom_plotting"].to_list()
93
- normalized_values = list(np.interp(custom_plotting_list,
94
- (min(custom_plotting_list), max(custom_plotting_list)),
95
- (0.1, 3)))
96
-
97
- attr_name = 'median_house_value'
98
- attr = obj.data.attributes.get(attr_name) or obj.data.attributes.new(
99
- name=attr_name,
100
- type='FLOAT',
101
- domain='POINT'
102
- )
103
- attr.data.foreach_set('value', normalized_values)
104
- obj.data.update()
105
-
106
- render_result()
107
- return (
108
- attr,
109
- attr_name,
110
- custom_plotting_list,
111
- normalized_values,
112
- plotting_frame,
113
- widget_df,
114
- )
115
-
116
-
117
- @app.cell
118
- def __():
119
- return
120
-
121
-
122
- if __name__ == "__main__":
123
- app.run()