Hello.
I'm a quite newbie of Blender, but not for CG.
If I have lots of obj files generated from an external simulator like shot-001.obj, shot-002.obj ... shot-100.obj and the meshes don't share the same topology, how I can import these obj files into Blender to generate an animation?
Since the simulation results might be a fractured mesh or splitting/merging fluid mesh, in which the topology are changed, the scripts using shape_key don't seem to work well.
I just want to (1) import a list of simulated mesh files (.obj), (2) put a camera, some lamps, and some static objects, (4) assign some materials to them, and (4) render an animation in Blender.
Any good example script for step 1?
Thanks.
Hey,
there was a script called Meshfoot for blender 2.4x, but it doesn't seem to exist for 2.5x or 2.6x - too bad!
http://blenderartists.org/forum/showthread.php?154134-Meshfoot-OBJ-Sequencer-%28Release-v01a%29&highlight=meshfoot
but i found this:
http://blenderscripting.blogspot.de/2011/07/scripted-keyframing-of-hide-hide-render.html
it hides the object in viewport, if you wanna hide it in render, use
hide_render
e.g.
| Code: |
ob = bpy.context.active_object
ob.hide_render = True
ob.keyframe_insert(data_path="hide_render", frame=0)
ob.hide_render = False
ob.keyframe_insert(data_path="hide_render", frame=1)
|
This would keyframe the active object to be visible in frame 0, and hidden from frame 1 on.
I would reflect the hidden property by also keyframing the viewport visibility, like
| Code: |
ob.hide = False
ob.keyframe_insert(data_path="hide", frame=1)
# etc. |
(so that one model is visible per frame, in viewport as well as in render)
What you need is a batch script to import your OBJs and keyframe the hide and hide_render properties, so that the 1st model is visible on frame 0, 2nd on frame 1 and so on.
you can call the OBJ import script like:
| Code: |
| bpy.ops.import_scene.obj(filepath="", filter_glob="*.obj;*.mtl", use_ngons=True, use_edges=True, use_smooth_groups=True, use_split_objects=True, use_split_groups=True, use_groups_as_vgroups=False, use_image_search=True, split_mode='ON', global_clamp_size=0, axis_forward='-Z', axis_up='Y') |
this needs to happen in a loop, here's some pseudo-code:
| Code: |
# let user chose a directory where the OBJs are in
#filedir = file_selector(...)
file_list = os.listdir(filedir)
# remove all non-obj files from list here...
objects = []
for file in file_list:
bpy.ops.import_scene.obj(filepath=file, ...)
# get imported object, not active_object, as the script will select it, but not make it active!
objects.append(bpy.context.object)
# Hide all objects but the 1st
bpy.context.scene.frame_set(0)
for i, ob in enumerate(objects):
if i == 0:
continue
ob.hide = ob.hide_render = True
ob.keyframe_insert(data_path='hide')
ob.keyframe_insert(data_path='hide_render')
for f, ob in enumerate(objects):
if f == 0:
continue
# increment current frame to insert keyframe
bpy.context.scene.frame_set(f)
# Insert only as many keyframes as really needed
ob_prev = objects[f-1]
ob_prev.hide = ob_prev.hide_render = True
ob_prev.keyframe_insert(data_path='hide')
ob_prev.keyframe_insert(data_path='hide_render')
ob.hide = ob.hide_render = False
ob.keyframe_insert(data_path='hide')
ob.keyframe_insert(data_path='hide_render')
|
Files from dir see:
http://www.programmersheaven.com/mb/python/191482/191482/list-files-in-a-directory/#Reply191546
Maybe needed:
After keyframing, it's probably a good idea to walk through all objects, remove all materials but the mats of the 1st model and make all other models use the same mats as the 1st (this way, you only need to change material settings once for the entire series - if this is what you want!)
_________________
I'm sitting, waiting, wishing, building Blender in superstition...
Thanks for your reply.
With your comments, I tested some scripts and finally wrote mine as:
| Code: |
import glob
import bpy
base_dir = '... basedir'
obj_files = glob.glob(base_dir+'/*/result.obj')
object_name = 'result'
mesh_name = 'result'
material_name = 'mymaterial'
mat = bpy.data.materials[material_name]
for (i, file) in enumerate(obj_files):
if object_name in bpy.data.objects:
bpy.data.scenes['Scene'].objects.unlink(bpy.data.objects[object_name])
bpy.data.objects.remove(bpy.data.objects[object_name])
bpy.data.meshes.remove(bpy.data.meshes[mesh_name])
bpy.ops.import_scene.obj(filepath=file)
bpy.context.scene.objects.active = bpy.data.objects[object_name]
bpy.ops.object.shade_smooth()
bpy.data.objects[object_name].data.materials.append(mat)
bpy.data.scenes['Scene'].frame_start = i
bpy.data.scenes['Scene'].frame_end = i
bpy.ops.render.render(write_still=True)
bpy.data.images['Render Result'].file_format='PNG'
bpy.data.images['Render Result'].save_render(filepath=bpy.app.tempdir+str(i).zfill(4)+'.png') |
I have some questions with this:
1) The reason I do not import all obj files at once was it spend a lot of memory for my case in which there are a bunch of files. So I do import an obj file, render, and save the result in frame-by-frame. However, even though I put the object removing scripts as you can see above, the memory blender uses is gradually increasing. What's the problem? Am I missing something to free memory for blender?
2) I cannot stop or work other tasks in blender during the scripts are running unless I force to kill the process. Is there any efficient way for this during the script is running?
Thanks.
1. Dunno if Blender is smart enough to clean memory without file saving action or loading homefile. It does not remove certain datablocks unless you reload the .blend, so this might cause the problem. No clue if there is a hidden operator to clean up .blend without saving/reloading...
2. Python scripts run blocking, so it's normal that Blender won't respond in the meantime. Script could be threaded, but would cause Blender to crash sooner or later.
_________________
I'm sitting, waiting, wishing, building Blender in superstition...