[Durian-svn] [4973] Save and load hairstyles as OBJ.

campbell institute at blender.org
Fri Jun 11 16:57:06 CEST 2010


Revision: 4973
          https://blenderinstitute.dyndns.org/durian-svn/?do=log&project=durian&path=/&rev=4973
Author:   campbell
Date:     2010-06-11 16:57:06 +0200 (Fri, 11 Jun 2010)
Log Message:
-----------
Save and load hairstyles as OBJ. support for per shot hair

Modified Paths:
--------------
    pro/scripts/modules/finals_config.py
    pro/scripts/modules/hairutils.py

Modified: pro/scripts/modules/finals_config.py
===================================================================
--- pro/scripts/modules/finals_config.py	2010-06-11 14:47:45 UTC (rev 4972)
+++ pro/scripts/modules/finals_config.py	2010-06-11 14:57:06 UTC (rev 4973)
@@ -764,6 +764,8 @@
 
 
         preset = -1
+        hair_style = ""
+
         if   base_name.startswith("01.a"): preset = 12
         elif base_name.startswith("02.a"): preset = -1
         elif base_name.startswith("02.b"): preset = 18
@@ -810,7 +812,7 @@
         elif base_name.startswith("03.4e"): preset = 12
         elif base_name.startswith("03.4f"): preset = 13
         elif base_name.startswith("03.4g"): preset = 51
-        elif base_name.startswith("03.4h"): preset = 25
+        elif base_name.startswith("03.4h"): preset = 25; hair_style = "sintel_hair_more_face.obj"
         elif base_name.startswith("03.4i"): preset = 18
         elif base_name.startswith("03.4l"): preset = -1
         elif base_name.startswith("03.4m"): preset = 18
@@ -1046,6 +1048,22 @@
             sintal_preset_hair_func = sintal_preset_18
         '''
         
+        # load hair if set
+        hair_style = "sintel_hair_more_face.obj"
+        
+        if hair_style:
+            import hairutils
+            reload(hairutils)
+            hair_dir = getattr(obj.library, "filepath", None)
+            if hair_dir is None: # local, unlikely
+                hair_dir = bpy.data.filepath
+            hair_dir = os.path.dirname(bpy.utils.expandpath(hair_dir))
+            hair_filepath = os.path.join(hair_dir, hair_style)
+
+            # load the new style
+            hairutils.load_hair_style(hair_filepath, psys)
+            # obj.update(bpy.context.scene)
+
         if preset == -1:
             psys.hair_dynamics = False
             return

Modified: pro/scripts/modules/hairutils.py
===================================================================
--- pro/scripts/modules/hairutils.py	2010-06-11 14:47:45 UTC (rev 4972)
+++ pro/scripts/modules/hairutils.py	2010-06-11 14:57:06 UTC (rev 4973)
@@ -1,86 +1,46 @@
 import bpy, sys
 
-def ob_no_psys_edit(ob):
-	if ob.mode == 'PARTICLE_EDIT':
-		bpy.ops.object.mode_set()
-		return 1
-	return 0
+def save_hair_style(filepath, psys):
+    file = open(filepath, "w")
+    fw = file.write
+    for p in psys.particles:
+        for k in p.hair:
+            fw("v %f %f %f\n" % k.location.to_tuple(6)) # location_hairspace
+        for i in range(len(p.hair) - 1):
+            fw("f %d %d\n" % (i ^ -1, (i + 1) ^ -1))
+    file.close()
 
-def ob_restore_psys_edit(ob, state):
-	if state:
-		bpy.ops.object.mode_set(mode='PARTICLE_EDIT')
+def load_hair_style(filepath, psys):
+    file = open(filepath, "r")
+    locations = []
+    for l in file.readlines():
+        if l.startswith("v "):
+            x, y, z = l.split()[1:4] # first 3
+            locations.append((float(x), float(y), float(z)))
 
-def save_hair_weights(psys):
-	print (psys)
-	
-	w = []
-	for p in psys.particles:
-		w.append([])
-		for k in p.hair:
-			w[-1].append(k.weight)
-	
-	s = b""
-	i = 0
-	for p in w:
-		s += bytes(repr(i), "ascii") + b"|"
-		for k in p:
-			s += bytes(repr(k), "ascii") + b";"
-			
-		i += 1
-		s += b"\n"
-		
-	return s
+    keys = []
+    for p in psys.particles:
+        for k in p.hair:
+            keys.append(k)
 
-class HairLoadException (RuntimeError):
-	pass
+    if len(locations) != len(keys):
+        raise RuntimeError("can't load hair %d != %d" % (len(locations), len(keys)))
 
-def load_hair_weights(buf, psys):
-	w = []
-	for l in buf.split(b"\n"):
-		i = 0
-		num = b""
-		while i < len(l):
-			if l[i:i+1] == b"|":
-				w.append([])
-				num = b""
-			elif l[i:i+1] == b";":
-				w[-1].append(float(num))
-				num = b""
-			else:
-				num += l[i:i+1]
-			
-			i += 1
-	
-	if len(w) != len(psys.particles):
-		raise HairLoadException("Number of hairs differs in weight file from active object!")
-		return
-	
-	ps = psys.particles
-	for i in range(len(w)):
-		if not ps[i].hair:
-			raise HairLoadException("Particle system lacks hair keys")
-			return
-		
-		ks = w[i]
-		p = ps[i]
-		for j in range(len(ks)):
-			if j >= len(ks):
-				print("Warning: one or more hair strands in object had more keys then in weight file")
-				break
-			elif j >= len(p.hair):
-				print("Warning: weight file had more keys then one or more hair strands")
-				break
-            
-			sys.stdout.flush()
-			p.hair[j].weight = ks[j]
-		
+    for i, k in enumerate(keys):
+        k.location = locations[i]
+
+    file.close()
+
+
 if __name__ == "__main__":
-	ob = bpy.context.active_object
-	if ob and ob.active_particle_system:
-		state = ob_no_psys_edit(ob)
-		
-		buf = save_hair_weights(ob.active_particle_system);
-		load_hair_weights(buf, ob.active_particle_system);
-		
-		ob_restore_psys_edit(ob, state)
 
+    obj = bpy.context.active_object
+    if obj and obj.active_particle_system:
+        filepath = bpy.data.filepath.replace(".blend", "_hair.obj")
+
+        save_hair_style(filepath, obj.active_particle_system)
+        load_hair_style(filepath, obj.active_particle_system)
+    '''
+import hairutils
+hairutils.save_hair_style("/d/pro/chars/sintel_hair_more_face.obj", bpy.context.active_object.active_particle_system)
+    '''



More information about the Durian-svn mailing list