|
|||||||
![]() |
|
|
Thread Tools |
|
||||
|
Over a year ago, I drafted an initial proposal for a "Blender Python Consortium" and the creation of an associated central online repository for blender scripts. You can find my post here (although I warn you it's a little long):
http://blenderartists.org/forum/showthread?t=45591 Last month, I took some time to slap together a prototype incorporating many of the essential features of my vision for such a repository, and I am continuing to gather and draft ideas for an eventual system. I posted the prototype to the bf-python mailing list the beginning of this month. So far most of the feedback has been positive. Now, I am posting the prototype to the community. http://www.hhofministries.org/bpyc If you are a script author: Please, help me by signing up for an account and uploading your scripts to the repository. Along the way, jot down some notes (trouble spots, bad pages, missing features, etc.), and submit them to me as feedback (you can post it here, if you want). For best results, read the scripts FAQ first. I need to know what you need to best host, update, and maintain your scripts in the repository in a way that the users can easily find, install, and locate updates. For everyone else (and authors too): Download the BPyMan script, and test out its limited possibilities. Hopefully more authors will get their scripts in the repository, so you will have a better selection (there are only two scripts in there right now). I am also gathering ideas for what is needed in an ideal "package manager" for Blender's scripts. So post those here too. Some quick points: 1. The repository is author maintained (the authors are responsible for the maintenance of and updates to their scripts in the repository). 2. This is just a prototype. Test it like the real thing, but let me know when it breaks. Also, this is a temporary online location. 3. Documentation is limited, I didn't have a lot of time. Did I mention that this was a prototype? I'm a nice guy. Contact me if you can't figure something out. Everything (e-mail, names, etc.) will remain formal and confidential, as well as prompt and friendly. That's it! Try it out and post your musings here. Thanks! Levi
............................................
BPyC script repository: http://www.hhofministries.org/bpyc Last edited by reD_Fox; 12-Sep-06 at 23:02. |
||||
|
#1
|
||||
|
|
|
|||
|
wow. really neat stuff.
i think if the GUI was made so that it went bottom/up instead of top/down that it would work better within blender as the GUI (at least on mine) always aligns everything to the bottom first (the bottom left of the panel being 0,0) because with a small panel i almost missed that there was a GUI! otherwise again neat stuff. I think this could be a great application for everyone and should be standard!! The only thing I can think of is I wonder how it handles scripts containing multiple scripts that are distributed with a zip (eg the hotspots script) and I wonder if it could made to pull scripts from other servers via yours so that yours would be like traffic control but wouldn't have to worry about licensing and copyrights and things like that.. in other words maybe a bit like a torrent server.. you would send to the users the link that would get them the script but not the actual script? |
|||
|
#2
|
|
|||
|
# THIS SCRIPT IS BROKEN INTO 4 PARTS IT IS TOO BIG TO FIT IN ONE POST
# THIS PART 1 # script work with blender 2.42, python 2.4 and winXP # this script is messy but it works for me :> # -- the list box, new button, and the sel button is used for # storing selections in face selection mode # select 1 of 3 in the list box then select some faces # and click the new button the face will unselect # you can then reselect the face by clicking the sel button # -- the shell tool works like the shell tool in Silo # -- the bridge face tool works the the bridge face tool in wings import Blender from Blender import * from Blender.Draw import * from Blender.Mathutils import * from Blender.BGL import * Ang= Mathutils.AngleBetweenVecs global dist SMALL_NUM=0.00001 dist = Create(0.2) left = Create(0.0) right = Create(1.0) num = Create(2) EVENT_NOEVENT = 1 EVENT_BEVEL = 2 EVENT_UPDATE = 3 EVENT_RECURS = 4 EVENT_EXIT = 5 Menu1 = None Menu1_Value = 1 ToggleEvent=[0,0,0] MeshSelectST = [0,0,0] def event(evt, val): if (evt == Blender.Draw.ESCKEY and not val): Blender.Draw.Exit() def Flatten_Mesh(): global ToggleEvent if Blender.Window.EditMode() == 0: Blender.Draw.PupMenu("run this script in edit mode") return user_object = Blender.Scene.GetCurrent().getActiveObject() if user_object.getType() != "Mesh": Blender.Draw.PupMenu("this object is not a mesh") return Blender.Window.EditMode(0) SelectedVerts = [] Mesh = user_object.getData() for verts in Mesh.verts: if verts.sel == 1: SelectedVerts.append(verts) if len(SelectedVerts) > 1: if ToggleEvent[0] == 1: vertSum =0 for vert in SelectedVerts: vertSum += vert[0] vertSum = vertSum / len(SelectedVerts) for vert in SelectedVerts: vert[0] = vertSum if ToggleEvent[1] == 1: vertSum =0 for vert in SelectedVerts: vertSum += vert[1] vertSum = vertSum / len(SelectedVerts) for vert in SelectedVerts: vert[1] = vertSum if ToggleEvent[2] == 1: vertSum =0 for vert in SelectedVerts: vertSum += vert[2] vertSum = vertSum / len(SelectedVerts) for vert in SelectedVerts: vert[2] = vertSum Mesh.update() Blender.Window.EditMode(1) |
|||
|
#3
|
|
|||
|
# PART 2
def AddMesh(): global MeshSelectST,Menu1_Value SEL = Blender.NMesh.FaceFlags['SELECT'] if Blender.Window.EditMode() == 0: Blender.Draw.PupMenu("run this script in edit mode") return user_object = Blender.Scene.GetCurrent().getActiveObject() if user_object.getType() != "Mesh": Blender.Draw.PupMenu("this object is not a mesh") return Blender.Window.EditMode(0) SelectedFases = [] Mesh = user_object.getData() Mesh = Blender.NMesh.GetRaw(Mesh.name) for faces in Mesh.faces: if faces.sel == 1: SelectedFases.append(faces) faces.sel = 0 MeshSelectST[Menu1_Value -1] = SelectedFases Mesh.update() Blender.Window.EditMode(1) def SelectStoreMesh(): global MeshSelectST,Menu1_Value if Blender.Window.EditMode() == 0: Blender.Draw.PupMenu("run this script in edit mode") return user_object = Blender.Scene.GetCurrent().getActiveObject() if user_object.getType() != "Mesh": Blender.Draw.PupMenu("this object is not a mesh") return Blender.Window.EditMode(0) Mesh = user_object.getData() Mesh = Blender.NMesh.GetRaw(Mesh.name) StoredMesh = MeshSelectST[Menu1_Value -1] if StoredMesh != 0: for faces in Mesh.faces: Boolean1 = False for sel_faces in StoredMesh: if len(faces.v) == len(sel_faces.v): if len(faces.v) == 3: if faces.v[0].co == sel_faces.v[0].co and faces.v[1].co == sel_faces.v[1].co and faces.v[2].co == sel_faces.v[2].co: Boolean1 = True if len(faces.v) == 4: if faces.v[0].co == sel_faces.v[0].co and faces.v[1].co == sel_faces.v[1].co and faces.v[2].co == sel_faces.v[2].co and faces.v[3].co == sel_faces.v[3].co: Boolean1 = True if Boolean1 == True: faces.sel = 1 Mesh.update() Blender.Window.EditMode(1) BIG_NUM = 1<<30 global CULL_METHOD CULL_METHOD = 0 |
|||
|
#4
|
|
|||
|
# PART 3
class edge: def __init__(self, v1,v2): self.v1 = v1 self.v2 = v2 self.length = (v1.co - v2.co).length self.removed = 0 self.match = None class edgeLoop: def __init__(self, loop): self.centre = Mathutils.Vector() f = 1.0/len(loop) for v in loop: self.centre += v.co * f self.edges = [] vIdx = 0 while vIdx < len(loop): self.edges.append( edge(loop[vIdx-1], loop[vIdx]) ) vIdx += 1 for eIdx in range(len(self.edges)-1): self.edges[eIdx].next = self.edges[eIdx+1] self.edges[eIdx].prev = self.edges[eIdx-1] self.edges[-1].next = self.edges[0] self.edges[-1].prev = self.edges[-2] self.normal = Mathutils.Vector() for e in self.edges: n = Mathutils.CrossVecs(self.centre-e.v1.co, self.centre-e.v2.co) n.normalize() self.normal += n self.normal.normalize() for e in self.edges: n1 = e.v1.co n2 = e.v2.co n3 = e.prev.v1.co a = n1-n2 b = n1-n3 normal1 = Mathutils.CrossVecs(a,b) normal1.normalize() n1 = e.v2.co n3 = e.next.v2.co n2 = e.v1.co a = n1-n2 b = n1-n3 normal2 = Mathutils.CrossVecs(a,b) normal2.normalize() normal1 += normal1 + normal2 normal1.normalize() e.normal = normal1 def backup(self): self.backupEdges = self.edges[:] def restore(self): self.edges = self.backupEdges[:] for e in self.edges: e.removed = 0 def reverse(self): self.edges.reverse() for e in self.edges: e.normal = -e.normal e.v1, e.v2 = e.v2, e.v1 self.normal = -self.normal def removeSmallest(self, cullNum, otherLoopLen): global CULL_METHOD if CULL_METHOD == 0: eloopCopy = self.edges[:] eloopCopy.sort(lambda e1, e2: cmp(e1.length, e2.length )) eloopCopy = eloopCopy[:cullNum] for e in eloopCopy: e.removed = 1 self.edges.remove( e ) else: culled = 0 step = int(otherLoopLen / float(cullNum)) currentEdge = self.edges[0] while culled < cullNum: while currentEdge.removed == 1: currentEdge = currentEdge.next smallestEdge = currentEdge for i in range(step): currentEdge = currentEdge.next while currentEdge.removed == 1: currentEdge = currentEdge.next if smallestEdge.length > currentEdge.length: smallestEdge = currentEdge smallestEdge.removed = 1 self.edges.remove(smallestEdge) culled+=1 |
|||
|
#5
|
|
|||
|
# PART 4
def faceEdges(me, f): if len(f) == 3: return [\ me.findEdge(f[0], f[1]),\ me.findEdge(f[1], f[2]),\ me.findEdge(f[2], f[0])\ ] elif len(f) == 4: return [\ me.findEdge(f[0], f[1]),\ me.findEdge(f[1], f[2]),\ me.findEdge(f[2], f[3]),\ me.findEdge(f[3], f[0])\ ] def getSelectedEdges(me, ob): SEL_FLAG = NMesh.EdgeFlags['SELECT'] FGON_FLAG = NMesh.EdgeFlags['FGON'] edges = [e for e in me.edges if e.flag & SEL_FLAG if (e.flag & FGON_FLAG) == 0 ] edgeFromSelFaces = [] for f in me.faces: if len(f) >2 and f.sel: edgeFromSelFaces.extend(faceEdges(me, f)) for e in edgeFromSelFaces: if edgeFromSelFaces.count(e) > 1: me.removeEdge(e.v1, e.v2) fIdx = len(me.faces) while fIdx: fIdx-=1 if len(me.faces[fIdx]) > 2: if me.faces[fIdx].sel: me.faces.pop(fIdx) return [e for e in edges if edgeFromSelFaces.count(e) < 2] def getVertLoops(selEdges): mainVertLoops = [] while selEdges: e = selEdges.pop() contextVertLoop= [e.v1, e.v2] eIdx = 1 while eIdx: eIdx = len(selEdges) while eIdx: eIdx-=1 if contextVertLoop[0] == selEdges[eIdx].v1: contextVertLoop.insert(0, selEdges.pop(eIdx).v2) elif contextVertLoop[0] == selEdges[eIdx].v2: contextVertLoop.insert(0, selEdges.pop(eIdx).v1) elif contextVertLoop[-1] == selEdges[eIdx].v1: contextVertLoop.append(selEdges.pop(eIdx).v2) elif contextVertLoop[-1] == selEdges[eIdx].v2: contextVertLoop.append(selEdges.pop(eIdx).v1) else: continue break if contextVertLoop[0].index == contextVertLoop[-1].index: contextVertLoop.pop() mainVertLoops.append(contextVertLoop) return mainVertLoops def skin2EdgeLoops(eloop1, eloop2, me, ob, MODE): if len(eloop1.edges) != len(eloop2.edges): if len(eloop1.edges) < len(eloop2.edges): eloop1, eloop2 = eloop2, eloop1 eloop1.backup() CULL_FACES = len(eloop1.edges) - len(eloop2.edges) eloop1.removeSmallest(CULL_FACES, len(eloop1.edges)) else: CULL_FACES = 0 skinVector = eloop1.centre - eloop2.centre loopDist = skinVector.length angleBetweenLoopNormals = Mathutils.AngleBetweenVecs(eloop1.normal, eloop2.normal) if angleBetweenLoopNormals > 90: eloop2.reverse() bestEloopDist = BIG_NUM bestOffset = 0 eLoopIdxs = range(len(eloop1.edges)) for offset in range(len(eloop1.edges)): totEloopDist = 0 offsetIndexLs = eLoopIdxs[offset:] + eLoopIdxs[: offset] for e1Idx, e2Idx in enumerate(offsetIndexLs): totEloopDist += ((eloop1.edges[e1Idx].v1.co - eloop2.edges[e2Idx].v1.co).length / loopDist) totEloopDist += ((eloop1.edges[e1Idx].v2.co - eloop2.edges[e2Idx].v2.co).length / loopDist) if totEloopDist > bestEloopDist: break if totEloopDist < bestEloopDist: bestOffset = offset bestEloopDist = totEloopDist eloop2.edges = eloop2.edges[bestOffset:] + eloop2.edges[:bestOffset] for loopIdx in range(len(eloop2.edges)): e1 = eloop1.edges[loopIdx] e2 = eloop2.edges[loopIdx] e1.match = e2; e2.match = e1 f = NMesh.Face([e1.v1, e1.v2, e2.v2, e2.v1]) f.sel = 1 me.faces.append(f) if CULL_FACES: FAN_FILLED_FACES = 0 contextEdge = eloop1.edges[0] while FAN_FILLED_FACES < CULL_FACES: while contextEdge.next.removed == 0: contextEdge = contextEdge.next vertFanPivot = contextEdge.match.v2 while contextEdge.next.removed == 1: f = NMesh.Face([contextEdge.next.v1, contextEdge.next.v2, vertFanPivot] ) f.sel = 1 me.faces.append(f) contextEdge.next.removed = 1 contextEdge = contextEdge.next FAN_FILLED_FACES += 1 eloop1.restore() Last edited by oilbane; 13-Sep-06 at 19:39. |
|||
|
#6
|
|
|||
|
Hi...when I heard "BPyMan" I was reminded of Samadam's script (which it is now an outgrowth of). Anyhow, I've long felt that there should be a central repository for Blender Python (something where you can select the scripts from within Blender) so I wish you the best of luck!
Hopefully, one day we will have a fully fledged way of managing Python scripts off the internet while working. Koba
............................................
[Sanity is not statistical] |
|||
|
#7
|
|
|||
|
# part 5
def main(): global CULL_METHOD is_editmode = Window.EditMode() if is_editmode: Window.EditMode(0) ob = Scene.GetCurrent().getActiveObject() if ob == None or ob.getType() != 'Mesh': return me = ob.getData() if not me.edges: Draw.PupMenu('Error, add edge data first') if is_editmode: Window.EditMode(1) return selEdges = getSelectedEdges(me, ob) vertLoops = getVertLoops(selEdges) if len(vertLoops) > 2: choice = Draw.PupMenu('Loft '+str(len(vertLoops))+' edge loops%t|loop|segment') if choice == -1: if is_editmode: Window.EditMode(1) return elif len(vertLoops) < 2: PupMenu('Error, No Vertloops found%t|if you have a valid selection, go in and out of face edit mode to update the selection state.') if is_editmode: Window.EditMode(1) return else: choice = 2 if False in [len(v) == len(vertLoops[0]) for v in vertLoops]: CULL_METHOD = PupMenu('Small to large edge loop distrobution method%t|remove edges evenly|remove smallest edges edges') if CULL_METHOD == -1: if is_editmode: Window.EditMode(1) return if CULL_METHOD ==1: CULL_METHOD = 0 else: CULL_METHOD = 1 time1 = sys.time() edgeLoops = [] for vloop in vertLoops: edgeLoops.append(edgeLoop(vloop)) edgeOrderedList = [edgeLoops.pop()] bestSoFar = BIG_NUM bestIdxSoFar = None for edLoopIdx, edLoop in enumerate(edgeLoops): l =(edgeOrderedList[-1].centre - edLoop.centre).length if l < bestSoFar: bestIdxSoFar = edLoopIdx bestSoFar = l edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) ) while edgeLoops: bestSoFar = BIG_NUM bestIdxSoFar = None first_or_last = 0 for edLoopIdx, edLoop in enumerate(edgeLoops): l1 =(edgeOrderedList[-1].centre - edLoop.centre).length if l1 < bestSoFar: bestIdxSoFar = edLoopIdx bestSoFar = l1 first_or_last = 1 l2 =(edgeOrderedList[0].centre - edLoop.centre).length if l2 < bestSoFar: bestIdxSoFar = edLoopIdx bestSoFar = l2 first_or_last = 0 if first_or_last: edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) ) else: edgeOrderedList.insert(0, edgeLoops.pop(bestIdxSoFar) ) for i in range(len(edgeOrderedList)-1): skin2EdgeLoops(edgeOrderedList[i], edgeOrderedList[i+1], me, ob, 0) if choice == 1 and len(edgeOrderedList) > 2: skin2EdgeLoops(edgeOrderedList[0], edgeOrderedList[-1], me, ob, 0) me.update(1, 1, 0) if is_editmode: Window.EditMode(1) |
|||
|
#8
|
|
||||
|
Quote:
![]() Quote:
To Koba: Thanks! I hope so too. oilbane: Sorry, maybe it wasn't clear. Do not post your script here. Sign up for an account with the prototype, follow the guidelines in the BPyC faq, and upload your files to the repository. Then, you can add simple documentation and point others to your script. Also, whenever you update your script, add a new version for the updated files, and users of the BPyMan script will be able to update your script on their machine. PM me or contact me if you have trouble, and I can walk you through the process. Thanks!Levi
............................................
BPyC script repository: http://www.hhofministries.org/bpyc Last edited by reD_Fox; 14-Sep-06 at 03:04. |
||||
|
#9
|
|
||||
|
oilbane: try CODE tags next time
![]() reD_Fox: it would be cool if the best and still relevant of what exists now were rounded up. http://blender.org/cms/Python_Scripts.3.0.html http://alienhelpdesk.com/index.php?id=39 http://members.iinet.net.au/~cpbarton/ideasman/index_old.html http://uselessdreamer.byethost32.com/ http://jmsoler.free.fr/didacticiel/b.../eng_index.htm http://www.harkyman.com/scripts.html there are definately more... Hope that helps...
............................................
Blend On! Last edited by lucidMonkey; 14-Sep-06 at 02:27. |
||||
|
#10
|
|
||||
|
Quote:
It is a similar concept, but I'm planning for a more long-term solution. Also, I won't be doing any of the "rounding up" myself. It has been my philosophy that it is better to put that power in the hands of the authors than to depend on a select few to do it. However, I am a little disheartened at the lack of response from authors (but it's only been a couple of days). I'll see if I can personally contact a few of them in the next few days. oilbane: I got your e-mail and sent you a reply, are you still having trouble? Thanks! Levi
............................................
BPyC script repository: http://www.hhofministries.org/bpyc |
||||
|
#11
|
|
||||
|
After talking a bit with patrick7, I realized that it may be good to post a few directions here, so that people know something about the process involved with putting their scripts in the repository. You can sign up for an account, see if it works for you, and if it doesn't, you can delete your script and no one will be the wiser.
Levi
............................................
BPyC script repository: http://www.hhofministries.org/bpyc |
||||
|
#12
|
![]() |
| Bookmarks |
| Thread Tools | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| VirtualUndo Script - Anyone want to Help? | mthoenes | Python & Plugins | 26 | 12-Nov-06 17:09 |
| NEW: Aligner/Displacer/Randomizer Script | RobertT | Python & Plugins | 19 | 07-Nov-06 16:24 |
| New Script List | theeth | Python & Plugins | 28 | 07-Mar-06 00:56 |
| .blend append and link script | zenoscope | Python & Plugins | 0 | 16-Jan-06 12:25 |
| auto UV mapping python script -> speeds up level texturin | lizard809 | Game Engine Support and Discussion | 7 | 25-Mar-03 01:38 |