[Bf-extensions-cvs] [aa7da429] master: initial commit particle hair net: T35062 T51145

meta-androcto noreply at git.blender.org
Mon Apr 17 04:39:22 CEST 2017


Commit: aa7da429c89f00c1bec93bd231675cbf87a6c111
Author: meta-androcto
Date:   Mon Apr 17 12:38:22 2017 +1000
Branches: master
https://developer.blender.org/rBACaa7da429c89f00c1bec93bd231675cbf87a6c111

initial commit particle hair net: T35062 T51145

===================================================================

A	object_particle_hair_net.py

===================================================================

diff --git a/object_particle_hair_net.py b/object_particle_hair_net.py
new file mode 100644
index 00000000..f0d4f852
--- /dev/null
+++ b/object_particle_hair_net.py
@@ -0,0 +1,972 @@
+# ---------------------------------------------------
+# File HairNet.py
+# Written by Rhett Jackson April 1, 2013
+# Some routines were copied from "Curve Loop" by Bart Crouch
+# Some routines were copied from other sources
+# Very limited at this time:
+# NB 1) After running the script to create hair,
+# the user MUST manually enter Particle Mode on the Head object
+# and "touch" each point of each hair guide.
+# Using a large comb brish with very low strength is a good way to do this.
+# If it's not done, the hair strands are likely to:
+# be reset to a default/straight-out position during editing.
+# NB 2) All meshes must have the same number of vertices:
+#  in the direction that corresponds to hair growth
+# ---------------------------------------------------
+
+bl_info = {
+        "name": "HairNet",
+        "author": "Rhett Jackson",
+        "version": (0, 5, 1),
+        "blender": (2, 7, 4),
+        "location": "Properties",
+        "category": "Object",
+        "description": "Creates a particle hair system with hair guides from mesh edges which start at marked seams",
+        "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.6/Py/Scripts/Objects/HairNet",
+        "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=35062&group_id=153&atid=467"
+        }
+
+import bpy
+import mathutils
+from mathutils import Vector
+from bpy.utils import register_module, unregister_module
+from bpy.props import *
+
+bpy.types.Object.hnMasterHairSystem=StringProperty(
+        name= "hnMasterHairSystem",
+        description= "Name of the hair system to be copied by this proxy object",
+        default="")
+
+bpy.types.Object.hnIsHairProxy=BoolProperty(
+        name="hnIsHairProxy",
+        description="Is this object a hair proxy object?",
+        default=False)
+
+bpy.types.Object.hnIsEmitter=BoolProperty(
+        name="hnIsEmitter",
+        description="Is this object a hair emitter object?",
+        default=False)
+
+bpy.types.Object.hnSproutHairs=IntProperty(
+        name="hnSproutHairs",
+        description="Number of additional hairs to add.",
+        default=0)
+
+# bpy.types.Object.hnSubdivideHairSections=IntProperty(
+#         name="hnSubdivideHairSections",
+#         description="Number of subdivisions to add along the guide hairs",
+#         default=0)
+
+
+def debPrintVertEdges(vert_edges):
+    print("vert_edges: ")
+    for vert in vert_edges:
+        print(vert, ": ", vert_edges[vert])
+
+def debPrintEdgeFaces(edge_faces):
+    print("edge_faces: ")
+    for edge in edge_faces:
+        print(edge, ": ", edge_faces[edge])
+
+def debPrintEdgeKeys(edges):
+    print("edge_keys")
+    for edge in edges:
+        print(edge, " : ", edge.key)
+
+def debPrintHairGuides(hairGuides):
+    print("Hair Guides:")
+    guideN=0
+
+    for group in hairGuides:
+        print("Guide #",guideN)
+        i=0
+        for guide in group:
+            print(i, " : ", guide)
+            i += 1
+        guideN+=1
+
+def debPrintSeams(seamVerts, seamEdges):
+    print("Verts in the seam: ")
+    for vert in seamVerts:
+        print(vert)
+    print("Edges in the seam: ")
+    for edge in seamEdges:
+        print(edge.key)
+
+def debPrintLoc(func=""):
+    obj = bpy.context.object
+    print(obj.name, " ", func)
+    print("Coords", obj.data.vertices[0].co)
+
+def getEdgeFromKey(mesh,key):
+    v1 = key[0]
+    v2 = key[1]
+    theEdge = 0
+    for edge in mesh.edges:
+        if v1 in edge.vertices and v2 in edge.vertices:
+            #print("Found edge :", edge.index)
+            return edge
+    return 0
+
+# returns all edge loops that a vertex is part of
+def getLoops(obj, v1, vert_edges, edge_faces, seamEdges):
+    debug = False
+
+    me = obj.data
+    if not vert_edges:
+        # Create a dictionary with the vert index as key and edge-keys as value
+        #It's a list of verts and the keys are the edges the verts belong to
+        vert_edges = dict([(v.index, []) for v in me.vertices if v.hide!=1])
+        for ed in me.edges:
+            for v in ed.key:
+                if ed.key[0] in vert_edges and ed.key[1] in vert_edges:
+                    vert_edges[v].append(ed.key)
+        if debug: debPrintVertEdges(vert_edges)
+    if not edge_faces:
+        # Create a dictionary with the edge-key as key and faces as value
+        # It's a list of edges and the faces they belong to
+        edge_faces = dict([(ed.key, []) for ed in me.edges if (me.vertices[ed.vertices[0]].hide!=1 and me.vertices[ed.vertices[1]].hide!=1)])
+        for f in me.polygons:
+            for key in f.edge_keys:
+                if key in edge_faces and f.hide!=1:
+                    edge_faces[key].append(f.index)
+        if debug : debPrintEdgeFaces(edge_faces)
+
+    ed_used = [] # starting edges that are already part of a loop that is found
+    edgeloops = [] # to store the final results in
+    for ed in vert_edges[v1.index]: #ed is all the edges v1 is a part of
+        if ed in ed_used:
+            continue
+        seamTest = getEdgeFromKey(me, ed)
+        if seamTest.use_seam:
+            #print("Edge ", seamTest.index, " is a seam")
+            continue
+
+        vloop = [] # contains all verts of the loop
+        poles = [] # contains the poles at the ends of the loop
+        circle = False # tells if loop is circular
+        n = 0 # to differentiate between the start and the end of the loop
+
+        for m in ed: # for each vert in the edge
+            n+=1
+            active_ed = ed
+            active_v  = m
+            if active_v not in vloop:
+                vloop.insert(0,active_v)
+            else:
+                break
+            stillGrowing = True
+            while stillGrowing:
+                stillGrowing = False
+                active_f = edge_faces[active_ed] #List of faces the edge belongs to
+                new_ed = vert_edges[active_v] #list of edges the vert belongs to
+                if len(new_ed)<3: #only 1 or 2 edges
+                    break
+                if len(new_ed)>4: #5-face intersection
+                    # detect poles and stop growing
+                    if n>1:
+                        poles.insert(0,vloop.pop(0))
+                    else:
+                        poles.append(vloop.pop(-1))
+                    break
+                for i in new_ed: #new_ed - must have 3 or 4 edges coming from the vert
+                    eliminate = False # if edge shares face, it has to be eliminated
+                    for j in edge_faces[i]: # j is one of the face indices in edge_faces
+                        if j in active_f:
+                            eliminate = True
+                            break
+                    if not eliminate: # it's the next edge in the loop
+                        stillGrowing = True
+                        active_ed = i
+                        if active_ed in vert_edges[v1.index]: #the current edge contains v1
+
+                            ed_used.append(active_ed)
+                        for k in active_ed:
+                            if k != active_v:
+                                if k not in vloop:
+
+                                    if n>1:
+                                        vloop.insert(0,k)
+                                    else:
+                                        vloop.append(k)
+
+
+                                    active_v = k
+                                    break
+                                else:
+                                    stillGrowing = False # we've come full circle
+                                    circle = True
+                        break
+        #TODO: Function to sort vloop. Use v1 and edge data to walk the ring in order
+        vloop = sortLoop(obj, vloop, v1, seamEdges, vert_edges)
+        edgeloops.append([vloop, poles, circle])
+    for loop in edgeloops:
+        for vert in loop[0]:
+            me.vertices[vert].select=True
+            #me.edges[edge].select=True
+    return edgeloops, vert_edges, edge_faces
+
+
+
+
+def getSeams(obj):
+    debug = False
+    #Make a list of all edges marked as seams
+    error = 0
+    seamEdges = []
+    for edge in obj.data.edges:
+        if edge.use_seam:
+            seamEdges.append(edge)
+
+    #Sort the edges in seamEdges
+#     seamEdges = sortEdges(seamEdges)
+
+    #Make a list of all verts in the seam
+    seamVerts = []
+    for edge in seamEdges:
+        for vert in edge.vertices:
+            if vert not in seamVerts:
+                seamVerts.append(vert)
+
+    if(len(seamEdges) < 2):
+        error = 2
+        return 0, 0, error
+
+    seamVerts = sortSeamVerts(seamVerts, seamEdges)
+    if debug: debPrintSeams(seamVerts, seamEdges)
+
+    if(len(seamEdges) == 0):
+        error = 2
+
+    return seamVerts, seamEdges, error
+
+def getNextVertInEdge(edge, vert):
+    if vert == edge.vertices[0]:
+        return edge.vertices[1]
+    else:
+        return edge.vertices[0]
+
+def makeNewHairSystem(headObject,systemName):
+    bpy.ops.object.mode_set(mode='OBJECT')
+    #Adding a particle modifier also works but requires pushing/pulling the active object and selection.
+    headObject.modifiers.new("HairNet", 'PARTICLE_SYSTEM')
+
+    #Set up context override
+#    override = {"object": headObject, "particle_system": systemName}
+#    bpy.ops.object.particle_system_add(override)
+    headObject.particle_systems[-1].name = systemName
+    return headObject.particle_systems[systemName]
+
+def makePolyLine(objName, curveName, cList):
+    #objName and curveName are strings cList is a list of vectors
+    curveData = bpy.data.curves.new(name=curveName, type='CURVE')
+    curveData.dimensions = '3D'
+
+#     objectData = bpy.data.objects.new(objName, curveData)
+#     objectData.location = (0,0,0) #object origin
+#     bpy.context.scene.objects.link(objectData)
+
+    polyline = curveData.splines.new('BEZIER')
+    polyline.bezier_points.add(len(cList)-1)
+    for num in range(len(cList)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list