sidebar features
sidebar content

Go Back   Blender Artists Forums > General Forums > Python & Plugins

Reply
 
Thread Tools
varkenvarken's Avatar
varkenvarken varkenvarken is offline
Member
 
Join Date: Mar 2007
Posts: 211
This is a rather long post. Because I connot access my own webserver yet want to share to code I will include the full code in the next post in this thread (otherwise I'll exceed 10k characters)

What was needed to port it from 2.49 -> 2.50 alpha 0?

The basic functions that calculate the geometry (verts and faces) are unchanged
( add_tooth(), add_spoke2(), add_gear() )
These functions were designed to return lists of tuples (x,y,z) (for the vertices) and
lists of lists [i,k,l,m] (for the faces). Because the Blender 2.50 API does not provide
facilties to alter individual elements of the the verts and faces attributes of a mesh
directly we have to add the calculated vertices and faces in bulk by using the
mesh.add_geometry(nverts,nedges,nfaces) methodfolowed by
mesh.verts.foreach_set("co", verts_loc) and mesh.faces.foreach_set("verts_raw", faces).
Both the foreach_set() methods take flattened lists as arguments, not lists of tuples, so we
added a simple function to flatten a list of lists or tuples.
Also, the vertex group API is changed a little bit but the concepts are the same:
Code:
vertexgroup = ob.add_vertex_group('NAME_OF_VERTEXGROUP') # add a vertex group for i in vertexgroup_vertex_indices: ob.add_vertex_to_group(i, vertexgroup, weight, 'ADD')
Now for some reason the name does not 'stick' and we have to set it this way:
Code:
vertexgroup.name = 'NAME_OF_VERTEXGROUP'
Conversion to 2.50 also meant we could simply do away with our crude user interface.
Just definining the appropriate properties in the AddGear() operator will display the
properties in the Blender GUI with the added benefit of making it interactive: changing
a property will redo the AddGear() operator providing the user with instant feedback.
FInally we had to convert/throw away some print statements to print functions as Blender
nows uses Python 3.x
The most puzzling issue was that the built in Python zip() function changed its behavior.
In 3.x it returns a zip object (that can be iterated over) instead of a list of tuples. This meant
we could no longer use deepcopy(zip(...)) but had to convert the zip object to a list of tuples
first.
The code to actually implement the AddGear() function is mostly copied from add_mesh_torus()
(distributed with Blender).

Unresolved issues:
- removing doubles:
the code that produces the teeth of the gears produces some duplicate vertices. The original
script just called remove_doubles() but if we do that in 2.50 we have a problem. To apply
the bpy.ops.mesh.remove_doubles() operator we have to change to edit mode. The moment
we do that we loose to possibilty to interactively change the properties. Also changing back
to object mode raises a strange exception (to investigate). So for now, removing doubles is left
to the user once satisfied with the chosen setting for a gear,
- no suitable icon:
a rather minor point but I reused the torus icon for the add->mesh->gear menu entry as there
doesn't seem to be a generic mesh icon or a way to add custom icons. Too bad, but as this is
just eye candy it's no big deal.
............................................
My Blender Scrpting book
https://www.packtpub.com/blender-2-4...ign=mdb_003338
current work on Pynodes http://www.swineworld.org/blender/pynodes.shtml
current work on Network Rendering http://www.swineworld.org/blender/networkrender
Other Blender stuff (gears/cogwheels, tips and tricks) http://www.swineworld.org/blender
#1   Old 28-Nov-09, 17:33   
Reply With Quote


varkenvarken's Avatar
varkenvarken varkenvarken is offline
Member
 
Join Date: Mar 2007
Posts: 211
the code:
Code:
# add_mesh_gear.py (c) 2009, Michel J. Anders (varkenvarken) # # add gears/cogwheels to the blender 2.50 add->mesh menu # # tested with the official blender 2.50 alpha 0 32-bit windows # # ##### BEGIN GPL LICENSE BLOCK ##### # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ##### END GPL LICENSE BLOCK ##### import bpy import Mathutils from math import cos, sin, tan, atan, asin, pi,radians as rad from copy import deepcopy as dc def flatten(alist): "Flatten a list of lists or tuples." return sum([list(a) for a in alist],[]) #constants faces=[[0,5,6,1],[1,6,7,2],[2,7,8,3],[3,8,9,4],[6,10,11,7],[7,11,12,8],[10,13,14,11],[11,14,15,12]] L=16 # number of vertices #edgefaces ef = [5,6,10,13,14,15,12,8,9] ef2 = [i+L for i in ef] # in python 3, zip() returns a zip object so we have to force the result into a list of lists to keep # deepcopy happy later on in the script. efc = [ [i,j,k,l] for i,j,k,l in zip(ef[:-1],ef2[:-1],ef2[1:],ef[1:])] vv = [5,6,8,9,21,22,24,25] #vertices in a valley tv = [13,14,15,29,30,31] #vertices on a tooth spokefaces=((0,1,2,5),(2,3,4,7),(5,2,7,6),(5,6,9,8),(6,7,10,9),(11,8,13,12),(8,9,10,13),(13,10,15,14))
Code:
def add_tooth(a,t,d,r,Ad,De,b,p,rack=0,crown=0.0): """ private function: calculate the vertex coords for a single side section of a gear tooth. returns them as a list of lists. """ A=[a,a+t/4,a+t/2,a+3*t/4,a+t] C=[cos(i) for i in A] S=[sin(i) for i in A] Ra=r+Ad Rd=r-De Rb=Rd-b #Pressure angle calc O =Ad*tan(p) p =atan(O/Ra) if r<0 : p = -p if rack : S =[sin(t/4)*I for I in range(-2,3)] Sp=[0,sin(-t/4+p),0,sin(t/4-p)] v=[(Rb,r*S[i],d) for I in range(5)] v.extend([(Rd,r*S[i],d) for I in range(5)]) v.extend([(r,r*S[i],d) for I in range(1,4)]) v.extend([(Ra,r*Sp[i],d) for I in range(1,4)]) else : Cp=[0,cos(a+t/4+p),cos(a+t/2),cos(a+3*t/4-p)] Sp=[0,sin(a+t/4+p),sin(a+t/2),sin(a+3*t/4-p)] v=[(Rb*C[i],Rb*S[i],d) for I in range(5)] v.extend([(Rd*C[i],Rd*S[i],d) for I in range(5)]) v.extend([(r*C[i],r*S[i],d+crown/3) for I in range(1,4)]) v.extend([(Ra*Cp[i],Ra*Sp[i],d+crown) for I in range(1,4)]) return v
Code:
def add_spoke2(a,t,d,r,De,b,s,w,l,gap=0,width=19): Rd=r-De Rb=Rd-b Rl=Rb v =[] ef =[] ef2=[] sf =[] if not gap : for N in range(width,1,-2) : ef.append(len(v)) ts = t/4 tm = a + 2*ts te = asin(w/Rb) td = te - ts t4 = ts+td*(width-N)/(width-3.0) A=[tm+(i-int(N/2))*t4 for i in range(N)] C=[cos(i) for i in A] S=[sin(i) for i in A] v.extend([ (Rb*I,Rb*J,d) for (I,J) in zip(C,S)]) ef2.append(len(v)-1) Rb= Rb-s n=0 for N in range(width,3,-2) : sf.extend([(i+n,i+1+n,i+2+n,i+N+n) for i in range(0,N-1,2)]) sf.extend([(i+2+n,i+N+n,i+N+1+n,i+N+2+n) for i in range(0,N-3,2)]) n = n + N return v,ef,ef2,sf
Code:
def add_gear(N,r,Ad,De,b,p,D=1,skew=0,conangle=0,rack=0,crown=0.0, spoke=0,spbevel=0.1,spwidth=0.2,splength=1.0,spresol=9): """ """ worm =0 if N<5 : (worm,N)=(N,24) t =2*pi/N if rack: N=1 p =rad(p) conangle=rad(conangle) skew =rad(skew) scale = (r - 2*D*tan(conangle) )/r f =[] v =[] tg=[] #vertexgroup of top vertices. vg=[] #vertexgroup of valley vertices M=[0] if worm : (M,skew,D)=(range(32),rad(11.25),D/2) for W in M: fl=W*N*L*2 l=0 #number of vertices for I in range(int(N)): a=I*t for(s,d,c,first) in ((W*skew,W*2*D-D,1,1),((W+1)*skew,W*2*D+D,scale,0)): if worm and I%(int(N)/worm)!=0: v.extend(add_tooth(a+s,t,d,r-De,0.0,0.0,b,p)) else: v.extend(add_tooth(a+s,t,d,r*c,Ad*c,De*c,b*c,p,rack,crown)) if not worm or (W==0 and first) or (W==(len(M)-1) and not first) : f.extend([ [j+l+fl for j in i]for i in dc(faces)]) l += L print (len(f)) print (dc(efc)) f.extend([ [j+I*L*2+fl for j in i] for i in dc(efc)]) print (len(f)) tg.extend([i+I*L*2 for i in tv]) vg.extend([i+I*L*2 for i in vv]) # EXPERIMENTAL: add spokes if not worm and spoke>0 : fl=len(v) for I in range(int(N)): a=I*t s=0 # for test if I%spoke==0 : for d in (-D,D) : (sv,ef,ef2,sf) = add_spoke2(a+s,t,d,r*c,De*c,b*c,spbevel,spwidth,splength,0,spresol) v.extend(sv) f.extend([ [j+fl for j in i]for i in sf]) fl += len(sv) d1 = fl-len(sv) d2 = fl-2*len(sv) f.extend([(i+d2,j+d2,j+d1,i+d1) for (i,j) in zip(ef[:-1],ef[1:])]) f.extend([(i+d2,j+d2,j+d1,i+d1) for (i,j) in zip(ef2[:-1],ef2[1:])]) else : for d in (-D,D) : (sv,ef,ef2,sf) = add_spoke2(a+s,t,d,r*c,De*c,b*c,spbevel,spwidth,splength,1,spresol) v.extend(sv) fl += len(sv) d1 = fl-len(sv) d2 = fl-2*len(sv) #f.extend([(i+d2,i+1+d2,i+1+d1,i+d1) for (i) in (0,1,2,3)]) #f.extend([(i+d2,i+1+d2,i+1+d1,i+d1) for (i) in (5,6,7,8)]) return flatten(v), flatten(f), tg, vg
Code:
from bpy.props import * class AddGear(bpy.types.Operator): '''Add a gear mesh.''' bl_idname = "mesh.gear_add" bl_label = "Add Gear" bl_register = True bl_undo = True number_of_teeth = IntProperty(name="Number of Teeth", description="Number of teeth on the gear", default=12,min=4,max=200) radius = FloatProperty(name="Radius", description="Radius of the gear, negative for crown gear", default=1.0, min=-100.0, max=100.0) addendum = FloatProperty(name="Addendum", description="Addendum, extent of tooth above radius", default=0.1, min=0.01, max=100.0) dedendum = FloatProperty(name="Dedendum", description="Dedendum, extent of tooth below radius", default=0.1, min=0.0, max=100.0) angle = FloatProperty(name="Pressure Angle", description="Pressure angle, skewness of tooth tip (degrees)", default=20.0, min=0.0, max=45.0) base = FloatProperty(name="Base", description="Base, extent of gear below radius", default=0.2, min=0.0, max=100.0) width = FloatProperty(name="Width", description="Width, thickness of gear", default=0.2, min=0.05, max=100.0) skew = FloatProperty(name="Skewness", description="Skew of teeth (degrees)", default=0.0, min=-90.0, max=90.0) conangle = FloatProperty(name="Conical angle", description="Conical angle of gear (degrees)", default=0.0, min=0.0, max=90.0) crown = FloatProperty(name="Crown", description="Inward pointing extend of crown teeth", default=0.0, min=0.0, max=100.0) def execute(self, context): verts_loc, faces, tip_vertices, valley_vertices = add_gear(self.properties.number_of_teeth, self.properties.radius, self.properties.addendum, self.properties.dedendum, self.properties.base, self.properties.angle, self.properties.width, skew=self.properties.skew, conangle=self.properties.conangle, crown=self.properties.crown) print(len(verts_loc)/3,faces) mesh = bpy.data.add_mesh("Gear") mesh.add_geometry(int(len(verts_loc) / 3), 0, int(len(faces) / 4)) mesh.verts.foreach_set("co", verts_loc) mesh.faces.foreach_set("verts_raw", faces) scene = context.scene # ugh for ob in scene.objects: ob.selected = False mesh.update() ob_new = bpy.data.add_object('MESH', "Gear") ob_new.data = mesh tipgroup = ob_new.add_vertex_group('Tips') # for some reason the name does not 'stick' and we have to set it this way: tipgroup.name = 'Tips' for i in tip_vertices: ob_new.add_vertex_to_group(i, tipgroup, 1.0, 'ADD') valleygroup = ob_new.add_vertex_group('Valleys') # for some reason the name does not 'stick' and we have to set it this way: valleygroup.name = 'Valleys' for i in valley_vertices: ob_new.add_vertex_to_group(i, valleygroup, 1.0, 'ADD') scene.objects.link(ob_new) scene.objects.active = ob_new ob_new.selected = True #bpy.ops.object.mode_set(mode='EDIT') #bpy.ops.mesh.remove_doubles() #bpy.ops.object.mode_set('OBJECT') ob_new.location = tuple(context.scene.cursor_location) return ('FINISHED',) # Register the operator bpy.ops.add(AddGear) # Add to a menu import dynamic_menu menu_func = (lambda self, context: self.layout.operator(AddGear.bl_idname, text="Gear", icon='ICON_MESH_DONUT')) menu_item = dynamic_menu.add(bpy.types.INFO_MT_mesh_add, menu_func) if __name__ == "__main__": bpy.ops.mesh.gear_add()
............................................
My Blender Scrpting book
https://www.packtpub.com/blender-2-4...ign=mdb_003338
current work on Pynodes http://www.swineworld.org/blender/pynodes.shtml
current work on Network Rendering http://www.swineworld.org/blender/networkrender
Other Blender stuff (gears/cogwheels, tips and tricks) http://www.swineworld.org/blender
#2   Old 28-Nov-09, 17:39   
Reply With Quote
RickyBlender's Avatar
RickyBlender RickyBlender is offline
Member
 
Join Date: Jan 2008
Posts: 7,328
there seems to be 4 scripts here

how do we organise this

is it all put into the same script file and run it

and where will this new panel appears in tool sidebar may be ?


do you think with the addition of Bmesh it will change the script again ?



Thanks
#3   Old 28-Nov-09, 17:47   
Reply With Quote
eggnot eggnot is offline
Member
 
Join Date: Mar 2006
Location: moscow, russia
Posts: 52
ok, working with replaced upper case I to i at "for I in range" in second block. and it's nice gear.

ps.
it's pity that tweaking parameters is possible just at adding(as i wrote it already in another post)
............................................
http://eggnot.com/
#4   Old 28-Nov-09, 19:18   
Reply With Quote
dudecon dudecon is offline
Member
 
Join Date: Sep 2007
Posts: 98
Sweet! Beautiful script, easy to use, fast, I love it! Very handy for making quick gears. I'll have to study the code more closely to see what's going on under the hood.

You may want to fix the loops in "def add_tooth...", the mix of lowercase and capitilized "i" doesn't make blender happy on my end. Once that was changed it worked fine.

Oh, and there are some issues with the normals of the final object. The lower surface is facing out, but all the other faces are pointed inward. Other than that it looks perfect!
#5   Old 28-Nov-09, 19:20   
Reply With Quote
FourMadMen FourMadMen is offline
Member
 
Join Date: Jan 2004
Posts: 584
When porting a few of my scripts to 2.50 I noticed this as well. Just add the vertices of the face (i.e. when you call faces.extend) in counter-clockwise order and the normals will point outward.
#6   Old 28-Nov-09, 19:27   
Reply With Quote
Atom's Avatar
Atom Atom is online now
Member
 
Join Date: Jan 2006
Location: Ohio
Posts: 5,129
Why don't you use pasteall.org? This forum is notorious for mangling code that you get out of a code box. Post it on shareCG, anywhere...

I don't understand why this forum does not allow attachments...?

Dang, no scriptlinks?

What a loss....
............................................
Windows XP 64, 3Gb RAM, nVidia 9500M GS

Blender 2.49.2, Python 2.64

2.49b Scripts:
Blendgraph
Meshfoot
Cubic Transition
APE

2.49b Scenes:
After Effects Stroke
Sea Tubes
Page Rip or Tear
Opening A Book
Single Page Turn
3DSMax Super Spray


Last edited by Atom; 30-Nov-09 at 14:02.
#7   Old 29-Nov-09, 13:58   
Reply With Quote
varkenvarken's Avatar
varkenvarken varkenvarken is offline
Member
 
Join Date: Mar 2007
Posts: 211
@dudecon & @atom:

I put the script on my website:http://www.swineworld.org/blender/gears/ (navigation to your right for download or direct link: http://www.swineworld.org/blender/ge...d_mesh_gear.py , just plonk it into the .blender/scripts/op/ directory)

Concerning those normals: I will try the clockwise trick. In the 2.49 version I just did a recalc_normals() but just like removing doubles that can only be done in edit mode and edit mode destroys the redo options of the tools window so that clearly not the way to go. I'll have to check the source code of those operators to see if there is some way around this.
............................................
My Blender Scrpting book
https://www.packtpub.com/blender-2-4...ign=mdb_003338
current work on Pynodes http://www.swineworld.org/blender/pynodes.shtml
current work on Network Rendering http://www.swineworld.org/blender/networkrender
Other Blender stuff (gears/cogwheels, tips and tricks) http://www.swineworld.org/blender

Last edited by varkenvarken; 30-Nov-09 at 19:28. Reason: install instructions
#8   Old 30-Nov-09, 15:55   
Reply With Quote
littleneo's Avatar
littleneo littleneo is offline
Member
 
Join Date: Jul 2007
Location: paris, france
Posts: 667
well done !
do you think it could be possible to call the dedicated gui panel again, when one clic again on a parametric-made object like your gears ?
an object tag defined by the user/script, linked to parametric values somewhere in the registry and to the add_xx script.. mmm well. it would need a dedicated object class property for that I suppose.. and also to check if the object is still eligible for parametric config.
............................................
Littleneo
city engine - tuTube
zen :eufloria - osmos
#9   Old 02-Dec-09, 02:45   
Reply With Quote
Crouch's Avatar
Crouch Crouch is offline
Member
 
Join Date: Oct 2004
Location: the Netherlands
Posts: 1,112
The script works great, taking 2.5 limitations into account. The only strange thing I encountered was when you set the Number of Teeth to 4 (all other parameters at default).

About a suitable icon: how about using ICON_SCRIPTWIN? It looks like a gear to me.
............................................
My Python Scripts - Blog - Vimeo Page
#10   Old 02-Dec-09, 08:28   
Reply With Quote
Atom's Avatar
Atom Atom is online now
Member
 
Join Date: Jan 2006
Location: Ohio
Posts: 5,129
So how do I activate the script? I have placed it here .blender/scripts/op/

I just realized that the scripts window no longer exists in Blender 2.5. How do I activate it?
............................................
Windows XP 64, 3Gb RAM, nVidia 9500M GS

Blender 2.49.2, Python 2.64

2.49b Scripts:
Blendgraph
Meshfoot
Cubic Transition
APE

2.49b Scenes:
After Effects Stroke
Sea Tubes
Page Rip or Tear
Opening A Book
Single Page Turn
3DSMax Super Spray

#11   Old 02-Dec-09, 14:14   
Reply With Quote
DProber DProber is offline
Member
 
Join Date: Nov 2009
Posts: 10
Quick note, as of at least revision 25295 This script no longer works. In fact it also breaks the add->Torus feature. I think someone changed a command in the API making this script out of date. However I love it when it works.

EDIT: Ok slight correction. The script works but it just prevents both it and add Torus from showing up in the Add->Mesh menu.

EDIT2: Fix found. O line 359 replace icon='ICON_MESH_DONUT' with icon='MESH_DONUT'. Credit goes to Theeth.

Last edited by DProber; 10-Dec-09 at 21:32.
#12   Old 10-Dec-09, 20:52   
Reply With Quote
PKHG's Avatar
PKHG PKHG is offline
Member
 
Join Date: Sep 2009
Posts: 72
Wow, again nice for me. Good work! And an example how to do it ...

In Blender 2.5 alpha 0 trying to set the number teeth to 1 (one) it needs some time, but works.
(first I thought it doesn't)

Last edited by PKHG; 11-Dec-09 at 10:13. Reason: problem with teeth 1 no, needs time!
#13   Old 11-Dec-09, 09:54   
Reply With Quote
ideasman42's Avatar
ideasman42 ideasman42 is offline
Member
 
Join Date: Mar 2004
Location: Australia
Posts: 3,488
hey varkenvarken, would you be interested in including this script for 2.5 alpha-1 ?

Ill try have remove doubles working by having a way to run an operator without registering or undo'ing.
............................................
BPython Cookbook * How to get features into Blender * Code Metrics
Hire Me
ideasman42<at>gmail.com
#14   Old 13-Dec-09, 10:34   
Reply With Quote
varkenvarken's Avatar
varkenvarken varkenvarken is offline
Member
 
Join Date: Mar 2007
Posts: 211
Quote:
Originally Posted by ideasman42 View Post
hey varkenvarken, would you be interested in including this script for 2.5 alpha-1 ?

Ill try have remove doubles working by having a way to run an operator without registering or undo'ing.

Sorry for my late reply but sure, I'd love to. Just tell me what you need.
............................................
My Blender Scrpting book
https://www.packtpub.com/blender-2-4...ign=mdb_003338
current work on Pynodes http://www.swineworld.org/blender/pynodes.shtml
current work on Network Rendering http://www.swineworld.org/blender/networkrender
Other Blender stuff (gears/cogwheels, tips and tricks) http://www.swineworld.org/blender
#15   Old 13-Jan-10, 12:21   
Reply With Quote
Meta-Androcto's Avatar
Meta-Androcto Meta-Androcto is offline
Member
 
Join Date: Aug 2006
Location: australia
Posts: 2,562
this script seems not to be working in current svn.
is any chance of updating it?
#16   Old 06-Feb-10, 01:40   
Reply With Quote
varkenvarken's Avatar
varkenvarken varkenvarken is offline
Member
 
Join Date: Mar 2007
Posts: 211
Quote:
Originally Posted by Meta-Androcto View Post
this script seems not to be working in current svn.
is any chance of updating it?
Actually, I already did Only I forgot to replace the script on my website. The one mentioned now for 2.50 is tested against svn 26208. (it fixed the return values and the way a menu os registered).

Let me know if you find any difficulties still and I'll try to fix it.
............................................
My Blender Scrpting book
https://www.packtpub.com/blender-2-4...ign=mdb_003338
current work on Pynodes http://www.swineworld.org/blender/pynodes.shtml
current work on Network Rendering http://www.swineworld.org/blender/networkrender
Other Blender stuff (gears/cogwheels, tips and tricks) http://www.swineworld.org/blender
#17   Old 07-Feb-10, 15:40   
Reply With Quote
Meta-Androcto's Avatar
Meta-Androcto Meta-Androcto is offline
Member
 
Join Date: Aug 2006
Location: australia
Posts: 2,562
thanks, it works now.
#18   Old 07-Feb-10, 15:58   
Reply With Quote
bleber bleber is offline
Member
 
Join Date: May 2009
Posts: 15
How to increase the diameter without change the teeth size?? These is a necessary thing to make that gears ruining together.
#19   Old 31-Mar-10, 16:30   
Reply With Quote
Spudmn's Avatar
Spudmn Spudmn is offline
Member
 
Join Date: Jan 2008
Location: New Zealand
Posts: 26
Hi Varkenvarken

I noticed that you needed a Remove Doubles function for your Gears script.

I needed the same thing for my “Bolt Factory”.
With help from Guillaum I have a function that will do what you need.
I hope it helps.

Code:
# -------------------------------------------------------------------------- # Test Remove Doubles.py # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # # Copyright (C) 2010: Aaron Keith # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- import bpy # next two utility functions are stolen from import_obj.py def unpack_list(list_of_tuples): l = [] for t in list_of_tuples: l.extend(t) return l def unpack_face_list(list_of_tuples): l = [] for t in list_of_tuples: face = [i for i in t] if len(face) != 3 and len(face) != 4: raise RuntimeError("{0} vertices in face.".format(len(face))) # rotate indices if the 4th is 0 if len(face) == 4 and face[3] == 0: face = [face[3], face[0], face[1], face[2]] if len(face) == 3: face.append(0) l.extend(face) return l #Remove Doubles takes a list on Verts and a list of Faces and #removes the doubles, much like Blender does in edit mode. #It doesn’t have the range function so it will only remove #verts that are in exactly the same position. The function #is useful because you can perform a “Remove Doubles” with out #having to enter Edit Mode. Having to enter edit mode has the #disadvantage of not being able to interactively change the properties. def RemoveDoubles(verts,faces): # print('verts') # for i in verts: # print(i) # print('faces') # for i in faces: # print(i) new_verts = [] new_faces = [] dict_verts = {} for face in faces: new_face = [] for face in face: co = tuple(verts[face]) if co not in dict_verts: dict_verts[co] = len(dict_verts) new_verts.append(co) if dict_verts[co] not in new_face: new_face.append(dict_verts[co]) if len(new_face) == 3 or len(new_face) == 4: new_faces.append(new_face) # print('new verts') # for i in new_verts: # print(i) # print('new faces') # for i in new_faces: # print(i) return new_verts,new_faces def Create_Mesh(context): # 1------2 # |\ / | # | \ / | # | 4 | # | / \ | # |/ \| # 0------3 # # 0 = [0.0, 0.0, 0.0] # 1 = [0.0, 1.0, 0.0] # 2 = [1.0, 1.0, 0.0] # 3 = [1.0, 0.0, 0.0] # 4 = [0.5,0.5,1.0] verts = [] faces = [] verts += [[0.0, 0.0, 0.0] , [0.0, 1.0, 0.0],[1.0, 1.0, 0.0],[1.0, 0.0, 0.0]] faces += [[0, 1, 2, 3]] #0 1 2 3 offset = len(verts) verts += [[0.0, 0.0, 0.0],[1.0, 0.0, 0.0],[0.5,0.5,1.0]] faces += [[offset+0,offset+1,offset+2]] #0 3 4 offset = len(verts) verts += [[1.0, 0.0, 0.0],[1.0, 1.0, 0.0],[0.5,0.5,1.0]] faces += [[offset+0,offset+1,offset+2]] # 3 2 4 offset = len(verts) verts += [[1.0, 1.0, 0.0],[0.0, 1.0, 0.0],[0.5,0.5,1.0]] faces += [[offset+0,offset+1,offset+2]] # 2 1 4 offset = len(verts) verts += [[0.0, 1.0, 0.0],[0.0, 0.0, 0.0],[0.5,0.5,1.0],[0.5,0.5,1.0]] #4 points with 2 of them are the same faces += [[offset+0,offset+1,offset+2,offset+3]] # 1 0 4 4 offset = len(verts) verts += [[0.5,0.5,1.0],[0.5,0.5,1.0],[0.5,0.5,1.0]] #3 points all of them the same faces += [[offset+0,offset+1,offset+2]] # 4 4 4 offset = len(verts) verts += [[0.0, 0.0, 0.0],[0.0, 0.0, 0.0],[0.5,0.5,1.0],[0.5,0.5,1.0]] #4 points, 2 pairs are the same faces += [[offset+0,offset+1,offset+2,offset+3]] # 0 0 4 4 print('Mesh verts') for i in verts: print(i) print('Mesh faces') for i in faces: print(i) verts, faces = RemoveDoubles(verts,faces) print('Mesh verts after Remove Doubles') for i in verts: print(i) print('Mesh faces after Remove Doubles') for i in faces: print(i) mesh = bpy.data.meshes.new("Test") mesh.add_geometry((len(verts)), 0, int(len(faces))) mesh.verts.foreach_set("co", unpack_list(verts)) mesh.faces.foreach_set("verts_raw", unpack_face_list(faces)) scene = context.scene # ugh for ob in scene.objects: ob.selected = False mesh.update() ob_new = bpy.data.objects.new("Test_ob", mesh) scene.objects.link(ob_new) ob_new.selected = True obj_act = scene.objects.active class ObjectButtonsPanel(bpy.types.Panel): bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" bl_label = "Remove Doubles Test V1.00" def draw_header(self, context): layout = self.layout layout.label(text="", icon='PLUGIN') def draw(self,context): layout = self.layout row = layout.row() row.operator("custom.Create_Button") class CUSTOM_OT_Create_Button(bpy.types.Operator): bl_idname = "CUSTOM_OT_Create_Button" bl_label = "Create" __doc__ = "Create Test" def invoke(self, context, event): Create_Mesh(context) return('FINISHED') def register(): bpy.types.register(ObjectButtonsPanel) bpy.types.register(CUSTOM_OT_Create_Button) def unregister(): bpy.types.unregister(ObjectButtonsPanel) bpy.types.unregister(CUSTOM_OT_Create_Button) if __name__ == "__main__": register()
#20   Old 20-Apr-10, 20:55   
Reply With Quote
Reply

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT. The time now is 23:19.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Logo and website design copyright © 2006 by froodee design bureau. All rights reserved.
Other Blender Sites
new icon Blender Homepage »
The official Blender homepage
new icon BlenderNation »
Fresh Blender News, Every Day
new icon Blenderart Magazine »
Blender articles, tutorials and images.
Blender Headlines
Featured Artwork
Short animation: Barrel by Phlopper
Woolly mammoth by sebastian_k
Photorealistic classic furniture by eMirage
Social BlenderArtists