Object spray script

http://blenderartists.org/home/patrick/spay_test_137.jpghere is a spacehandler script i made it allows you to “spray” an object onto a mesh

# SPACEHANDLER.VIEW3D.EVENT

import Blender, bpy, BPyWindow, BPyMesh
from Blender import *
from Blender.Window import *
from Blender.Mathutils import *
from math import sin, cos, sqrt
import math

"""
Name: 'Mesh Spray'
Blender: 248
Group: 'Spacehandeler'
Tip: 'add an object called "Sphere" select another object paint with RMB'
"""


# HOW TO USE:
# 1 - load the script in Blender's text editor
# 2 - enable it as spacehandelr in the 3dview menu
# 3 - add an object caled "Sphere" this can be any object just rename if necesary (hardcoded when i make the gui you will be abel to use any Linked object in the scene)
# 4 - use RMB to spray the "Sphere" over the selected object

"""
#for now this script only draws objects caled "Sphere" and 
#links them to the layer of the object we are drawing on 

"""
#if you want to change the num of copys change Max to the num of copys 
#to change the "brush" size change radius 
#to make the object to use the orientation of the face change normal to "TRUE"

#personaly i use the select with "Left Mouse" option if you use "Right Mouse" you may want to change "mouse_buttons == 4:" to "mouse_buttons == 1:"

#i still nead to coment the code and add a GUI 
#any feedback welcomed at [email protected] or LinkCanabico at the #blendercoders forum 



radius=100
CenterX=0
CenterY=0
Max=50
RAND_MAX=1

randX=[]
randY=[]
copy=[]
normal=True
sel=2
evt = Blender.event

def meshIntersects(me, Origin, Direction):
    def faceIntersects(f):
        isect = Intersect(f.v[0].co, f.v[1].co, f.v[2].co, Direction, Origin, 1) # Clipped.
        if isect:
            return isect
        elif len(f.v) == 4:
            isect = Intersect(f.v[0].co, f.v[2].co, f.v[3].co, Direction, Origin, 1) # Clipped.
        return isect
    
    
    ''' Ray is a tuple of vectors (Origin, Direction) '''
    isect= best_isect= None
    dist_from_orig= 1<<30
    
    for f in me.faces:
        isect= faceIntersects(f)
        if isect:
            return TRUE
        
def randInCircle (num, radi):
    X=[]
    Y=[]
    for x in xrange(0, num):
        X.append(0)
        Y.append(0)
    for x in xrange(0, num):
        Angle = Rand(0,1)*6.283185307
        Mag = Rand(0,1)*radi
        Mag = radi-(Mag * Mag)/radi
        X[x]=int((cos(Angle) * Mag))
        Y[x]=int((sin(Angle) * Mag))
    return X, Y

def Circle (num, radi):
    X=[]
    Y=[]
    Angle=0
    for x in xrange(0, num):
        X.append(0)
        Y.append(0)
    for x in range(0, num):    
        Angle = x * math.pi * 2.0 / num
        X[x]= int(radi * cos(Angle))
        Y[x]= int(radi * sin(Angle))
    return X, Y

def Spiral (num, radi, inv=FALSE):
    X=[]
    Y=[]
    step=radi/num
    radi=0    
    for x in xrange(0, num):
        X.append(0)
        Y.append(0)
    for x in xrange( 0,num):
        if not inv:
            X[x]=int(radi*cos(x))
            Y[x]=int(radi*sin(x))
        else:
            X[x]=int(radi*sin(x))
            Y[x]=int(radi*cos(x))
        radi=radi-step
    return X, Y

def closedShel (num, radi, inv=FALSE):
    X=[]
    Y=[]
    step=radi/num    
    radi=0
    for x in xrange(0, num):
        X.append(0)
        Y.append(0)
    for x in xrange( 0,num):
        Angle = x * math.pi * 2.0 / num
        X[x]= int(radi * cos(Angle))
        Y[x]= int(radi * sin(Angle))
        if not inv:
            radi=radi+step
        else:
            radi=radi+step
    return X, Y

def openShel (num, radi, inv=FALSE):
    X=[]
    Y=[]
    step=radi/num    
    radi=0
    for x in xrange(0, num):
        X.append(0)
        Y.append(0)
    for x in xrange( 0,num):
        Angle = radi * math.pi * 2.0 / num
        X[x]= int(radi * cos(Angle))
        Y[x]= int(radi * sin(Angle))
        if not inv:
            radi=radi+step
        else:
            radi=radi+step
    return X, Y



mouse_buttons = Window.GetMouseButtons()
if mouse_buttons == 4:

    scn = Scene.GetCurrent()
    terrain = scn.objects.active
    m=terrain.getData()
    me=terrain.getData(mesh=1)
    
    for x in xrange(0, Max):
        copy.append(Object.New('Mesh'))
        
    
    for i in range(0, Max):
        copy[i].link(bpy.data.objects["Sphere"].getData(mesh=1))
        scn.objects.link(copy[i])
    if sel==0:    
        randX, randY = randInCircle(Max,radius)
    elif sel==1:    
        randX, randY = Circle(Max,radius)
    elif sel==2:    
        randX, randY = Spiral(Max,radius)
    elif sel==3:    
        randX, randY = closedShel(Max,radius)
    elif sel==4:    
        randX, randY = openShel(Max,radius)
        
        
    while mouse_buttons==4:
        mouse_buttons=Window.GetMouseButtons()
        mc=GetMouseCoords()       
        for i in range(0, Max):
            X = randX[i]+mc[0]
            Y = randY[i]+mc[1]
            
            ray    =    BPyWindow.mouseViewRay(X,Y,terrain.matrix)
            ori,dir= ray[1],ray[2]
            if meshIntersects(m,ori,dir):
                f=BPyMesh.pickMeshRayFace(m,ori,dir)
    
            if f[0]:
                M0=terrain.matrix
                vs=f[0].v
                v0=Vector(vs[0])*M0
                v1=Vector(vs[1])*M0
                v2=Vector(vs[2])*M0
                eX, e=(v1-v0).normalize(), v2-v0
                eZ=CrossVecs(eX,e).normalize()
                eY=CrossVecs(eX,eZ)
                M=Matrix(-eX,eY,eZ)
                if normal:
                    copy[i].setMatrix(M)
                copy[i].setLocation(f[1]*M0)
                copy[i].sel=0
                terrain.sel=1
            else:
                print "not on mesh"

            #Blender.event=None
        Redraw()
    Blender.event=None

http://img361.imageshack.us/img361/7146/spraytest137qg4.th.jpg

id like to see it work but tried it and not working but no error

now i do select with the RMB !

what do you mean spacehandler in 3Dview ?

Thanks for any help

Salutations

Ricky: in the view-menu of the 3d space. View->Space Handler Scripts

It is working fine, only a little slow.

Thanks for sharing!

i never used this feature before
so what do i do with this?

i check and put the cursor over it - the spacehandler
and get a name like spraobject… py

then what do i do ?

like ot learn more about it
what does it do this spacehandler thing ?
any good doc on this subject ?

by the way when using 4 viewports you don’t see this menu when selecting menu
in 3D veiwport you have to go full screen to see it !

Thanks

be aware, this is known issue with blender menus. to be corrected in 2.50, i hope

hi linkcanabico,
nice script, works well with 2.48 on winXP.
unfortunately it slows dramatically down if terrain mesh-objects bigger than 1000faces or MAX value bigger than 10 (tested on intel2.7MHz/1GB/geforce4200)
migius

to use LMB select open user preferences click “View & Controls” and click “Left Mouse”.

about the slowing down i supose its normal since the script can increase the num of objects in scene realy fast (i will try to improve it, after i add a GUI and some more bugs i mean “Fetures”:evilgrin:)

what does it do in life?

i mean do i need it ot make this script work ?
and any doc on this feature?

Thanks

linkcanabico, do you know HandWriting script: http://blenderartists.org/forum/showthread.php?t=101883
it would be nice to combine both scripts => painting profiles on the surface

this handnwrite script might be interesting

can you explain about the brush in the other program if you know how to use it
i mean what brush is this the one in the sclupt tool or other brush ?

how to set it up

and any doc on this script available to knwo what the variables do ?

Thanks

sorry, i cant help with HandWriting script. I had no time for intensive testing and making it working stable in 2.48.
You can find last version on blenderwiki: http://wiki.blender.org/index.php/Scripts/Manual/Misc/Hand_Writing_Tool

what about this spacehandler thing

how does it work?
any doc on this feature?

i’v never used this feature before so not certain how to go about it ?

Thanks

all what i know is here:
http://www.blender.org/documentation/248PythonDoc/API_related-module.html

but have you use it and make it work ?

i cannot even get it to do anything at all

so would be nice if anybody could tell me how to start and run this thing

Thanks

HOW TO USE:

1 - load the script in Blender’s text editor and rename to sprayMesh.py

2 - activate sprayMesh script for each 3d-view window individually: menu View → Space Handler Scripts → Event: sprayMesh.py

3 - For proper work, the “Scriptlinks” option in Script Panel must be enabled.

4 - add an object caled “Sphere” this can be any object just rename if necesary (hardcoded when i make the gui you will be abel to use any Linked object in the scene)

5 - use RMB to spray the “Sphere” over the selected object

hope this helps
migius

would it not be easier to rename the py file with the proper name ?

if not i simply change the name of the script in the bottom header of the text viewport

Thanks

Hi i would like to know what you prefer speed or interactivity?
Speed: would mean that you no longer see the objects while holding the mouse button and changing the drawtype to boundingbox.
Interactivity: would mean that you can see the final location in “Real Time” and change the radius with MMB.

I need to know since as far as i know this two options require totaly different aproches.

I would prefer interactivity, visual control is important, because the script makes no collision check.

Isn’t what you want already possible, using particles?
There is an excellent video tutorial on it by CoyHot. He posted it here (don’t be scared by the thread title, it has nothing to do with fire, he’s painting flowers onto a mesh)

i will try to improve interactivity and will try to add collision detection

i know something similar is posible with particles but my scripl makes linked objects (same mesh name) and i nead that for a level exporter since that way the game engine needs less instances of the mesh in memory

thanks anyway