Safetensors
English
Files changed (1) hide show
  1. README.md +194 -2
README.md CHANGED
@@ -38,7 +38,8 @@ and structural design.
38
  This Hugging Face release contains **Bioinspired3D only**: a LoRA adapter that you load on top of the base model to generate **Blender Python scripts from natural-language prompts**.
39
 
40
  For the full **Bioinspired123D** agentic framework (retrieval + VLM critic + iterative repair), see the GitHub repo:
41
- https://github.com/lamm-mit/Bioinspired123D
 
42
 
43
  ## Usage
44
 
@@ -130,7 +131,198 @@ Output: A Blender Python script (intended to be executed in Blender) that constr
130
 
131
  To encourage explicit reasoning, append a variant of: “Think step by step.” to the end of your prompt. For example: "Write Blender code to make a tubular structure with z-aligned tubules. Think step by step."
132
 
133
- ### Notes:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  This adapter is meant to be used with the specified base model. Generated scripts should be treated like code: run in a sandboxed environment and validate geometry as needed.
135
 
136
  ## Citation
 
38
  This Hugging Face release contains **Bioinspired3D only**: a LoRA adapter that you load on top of the base model to generate **Blender Python scripts from natural-language prompts**.
39
 
40
  For the full **Bioinspired123D** agentic framework (retrieval + VLM critic + iterative repair), see the GitHub repo:
41
+ https://github.com/lamm-mit/Bioinspired123D . For training and evaluation scripts, see also the project GitHub.
42
+
43
 
44
  ## Usage
45
 
 
131
 
132
  To encourage explicit reasoning, append a variant of: “Think step by step.” to the end of your prompt. For example: "Write Blender code to make a tubular structure with z-aligned tubules. Think step by step."
133
 
134
+ ## Sample output #1
135
+
136
+ ### Example prompt
137
+ ```text
138
+ Write Blender code to make a cellular structure with smooth curves and layers on top and bottom
139
+ ```
140
+ ### Example model output (Blender Python)
141
+ ```python
142
+ import bpy
143
+ import addon_utils
144
+
145
+ # Clear the scene
146
+ bpy.ops.object.select_all(action='SELECT')
147
+ bpy.ops.object.delete(use_global=False)
148
+
149
+ # Parameters for the sandwich structure
150
+ strut_thickness = 0.2 # Thickness of the struts
151
+ smoothness_level = 3 # Level of smoothness
152
+ slab_thickness = 0.1 # Thickness of the top and bottom slabs
153
+
154
+ def create_cellular_sandwich():
155
+ # Function to create a smooth cellular sandwich structure.
156
+ # Steps:
157
+ # 1. Create a cube.
158
+ # 2. Fracture the cube into pieces.
159
+ # 3. Apply wireframe modifier for cellular effect.
160
+ # 4. Apply subsurface modifier for smoothing.
161
+ # 5. Create top and bottom slabs.
162
+
163
+ # Enable the Fracture Cell add-on
164
+ addon_utils.enable('object_fracture_cell')
165
+
166
+ # Create a cube
167
+ bpy.ops.mesh.primitive_cube_add()
168
+ cube = bpy.context.active_object
169
+
170
+ # Scale the cube
171
+ cube.scale = (1, 1, 0.75)
172
+ bpy.ops.object.transform_apply(scale=True)
173
+
174
+ # Fracture the cube
175
+ bpy.ops.object.add_fracture_cell_objects(
176
+ source={'PARTICLE_OWN'},
177
+ source_limit=100,
178
+ source_noise=0.5,
179
+ cell_scale=(1, 1, 1),
180
+ recursion=0,
181
+ recursion_source_limit=8,
182
+ recursion_clamp=250,
183
+ recursion_chance=0.25,
184
+ recursion_chance_select='SIZE_MIN',
185
+ use_smooth_faces=False,
186
+ use_sharp_edges=True,
187
+ use_sharp_edges_apply=True,
188
+ use_data_match=True,
189
+ use_island_split=True,
190
+ margin=0.001,
191
+ material_index=0,
192
+ use_interior_vgroup=False,
193
+ mass_mode='VOLUME',
194
+ mass=1,
195
+ use_recenter=True,
196
+ use_remove_original=True,
197
+ collection_name='',
198
+ use_debug_points=False,
199
+ use_debug_redraw=True,
200
+ use_debug_bool=False
201
+ )
202
+
203
+ # Remove the original cube
204
+ if cube and cube.name in bpy.data.objects:
205
+ bpy.data.objects.remove(cube, do_unlink=True)
206
+
207
+ # Join fractured pieces
208
+ bpy.ops.object.select_all(action='DESELECT')
209
+ for obj in bpy.context.scene.objects:
210
+ if obj.type == 'MESH':
211
+ obj.select_set(True)
212
+ bpy.context.view_layer.objects.active = obj
213
+ bpy.ops.object.join()
214
+
215
+ # Clean up geometry
216
+ active_mesh = bpy.context.view_layer.objects.active
217
+ bpy.ops.object.mode_set(mode='EDIT')
218
+ bpy.ops.mesh.select_all(action='SELECT')
219
+ bpy.ops.mesh.remove_doubles(threshold=0.2)
220
+ bpy.ops.mesh.dissolve_limited()
221
+ bpy.ops.object.mode_set(mode='OBJECT')
222
+
223
+ # Wireframe Modifier
224
+ wireframe_mod = active_mesh.modifiers.new(name='Wireframe', type='WIREFRAME')
225
+ wireframe_mod.thickness = strut_thickness
226
+ wireframe_mod.offset = -1
227
+ wireframe_mod.use_even_offset = False
228
+ wireframe_mod.use_relative_offset = True
229
+ wireframe_mod.use_replace = True
230
+ bpy.ops.object.convert(target='MESH')
231
+
232
+ # Subsurface Modifier
233
+ subsurf_mod = active_mesh.modifiers.new(name='Subdivision', type='SUBSURF')
234
+ subsurf_mod.levels = smoothness_level
235
+ subsurf_mod.render_levels = smoothness_level
236
+
237
+ # Create slabs
238
+ slab_height = 1.5
239
+ bottom_slab_z = -slab_height / 2 - slab_thickness / 2
240
+ top_slab_z = slab_height / 2 + slab_thickness / 2
241
+
242
+ # Bottom slab
243
+ bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, bottom_slab_z))
244
+ bottom_slab = bpy.context.active_object
245
+ bottom_slab.scale = (1, 1, slab_thickness / 2)
246
+ bpy.ops.object.transform_apply(scale=True)
247
+
248
+ # Top slab
249
+ bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, top_slab_z))
250
+ top_slab = bpy.context.active_object
251
+ top_slab.scale = (1, 1, slab_thickness / 2)
252
+ bpy.ops.object.transform_apply(scale=True)
253
+
254
+ # Create the sandwich structure
255
+ create_cellular_sandwich()
256
+ ```
257
+ ### Rendered example (image)
258
+ ![image](https://cdn-uploads.huggingface.co/production/uploads/63cad3071b705cc951e26b3a/Z3Xd-GleEmGgj4YL3Cg9N.png)
259
+
260
+
261
+ ## Sample output #2
262
+ ### Example prompt
263
+ ```text
264
+ Write Blender code to make a helical bioinspired structure with flat rectangular struts in each layer
265
+ ```
266
+ ### Example model output (Blender Python)
267
+ ```python
268
+ import bpy
269
+ import math
270
+
271
+ bpy.ops.object.select_all(action='SELECT')
272
+ bpy.ops.object.delete(use_global=False)
273
+
274
+ # Parameters for the helical fiber structure
275
+ ply_count = 7 # Number of plies in the structure
276
+ angle_increment = 10 # Rotation angle for each ply
277
+ fiber_form ='rect' # Shape of the fibers
278
+
279
+ # Dimensions of the structure
280
+ structure_height = 2 # Total height of the structure
281
+ plate_dimension = 2 # Width and length of each plate
282
+ thickness_per_ply = structure_height / ply_count # Thickness of each ply
283
+ fiber_gap = 0.01 # Gap between fibers
284
+
285
+ def create_fiber(form, diameter, x, y, z, thickness):
286
+ if form =='rect':
287
+ bpy.ops.mesh.primitive_cube_add(size=1.0, location=(x, y, z), rotation=(0, math.radians(90), 0))
288
+ fiber = bpy.context.object
289
+ fiber.dimensions = (thickness, diameter, plate_dimension)
290
+ return fiber
291
+
292
+ def generate_ply(index):
293
+ # Generate a ply of fibers in a helical arrangement.
294
+ z_position = index * thickness_per_ply
295
+ rotation_angle = index * angle_increment
296
+
297
+ bpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, z_position))
298
+ empty_object = bpy.context.object
299
+
300
+ fiber_diameter = thickness_per_ply
301
+ fiber_distance = fiber_diameter + fiber_gap
302
+ fiber_count = max(1, int(plate_dimension / fiber_distance))
303
+
304
+ total_fiber_space = fiber_count * fiber_distance
305
+ start_y_position = -plate_dimension / 2 + fiber_distance / 2 + (plate_dimension - total_fiber_space) / 2
306
+
307
+ for i in range(fiber_count):
308
+ fiber_y_center = start_y_position + i * fiber_distance
309
+ fiber_instance = create_fiber(fiber_form, fiber_diameter, 0, fiber_y_center, z_position, thickness_per_ply)
310
+ fiber_instance.parent = empty_object
311
+ fiber_instance.matrix_parent_inverse = empty_object.matrix_world.inverted()
312
+
313
+ empty_object.rotation_euler[2] = math.radians(rotation_angle)
314
+ return empty_object
315
+
316
+ # Create the helical structure
317
+ for i in range(ply_count):
318
+ generate_ply(i)
319
+ ```
320
+
321
+ ### Rendered example (image)
322
+ ![image](https://cdn-uploads.huggingface.co/production/uploads/63cad3071b705cc951e26b3a/d7c2kNs2uwqQk8zPOlea9.png)
323
+
324
+
325
+ ## Notes:
326
  This adapter is meant to be used with the specified base model. Generated scripts should be treated like code: run in a sandboxed environment and validate geometry as needed.
327
 
328
  ## Citation