Object Emitter - Assigning faces for emission per Frame

Discussion about scripting with Python
Anaxarchos
Posts: 843
Joined: Wed Mar 19, 2008 4:21 pm
Contact:

Object Emitter - Assigning faces for emission per Frame

Postby Anaxarchos » Mon Apr 11, 2011 2:30 pm

Hi,,

I was just playing a bit with a script that's supposed to assigne faces for emission based on the obejct's movement direction.

Somehow, I don't understand how to assign a group of faces...the faces are wildly jumping during the frame, finyllay crashing RF. Can anyone give me a hint, pleas:

Code: Select all

ball = scene.getObject('RocketMan')
bubs = scene.get_PB_Emitter('Bubbles')
#bubs = scene.getObject('Bubbles')

# get ball velocity
vel = ball.getVelocity()
velNorm = vel.normalize()
ballFaces = ball.getFaces()
 # scene.message('Velocity=  ' + str(vel.x) + ',' + str(vel.y) + ',' + str(vel.z) + 'n')

emissionFaces = []

for f in ballFaces:
   # get face normal and determine if it pointing towards negative velocity direction
   n = f.getNormal()
   #first, create dot product between velNorm and and n
   dotProduct = (velNorm.getX() * n.getX()) + (velNorm.getY() * n.getY()) + (velNorm.getZ() * n.getZ())
   # if dotProduct < 0, the vecors are pointing in opposite directions
   if(dotProduct < 0.0):
      emissionFaces.append(f.getIndices())
   if(len(emissionFaces) > 0):
      for idx in emissionFaces:
         bubs.setSelectedFaces(idx)
www.fk-fx.com


User avatar
D&Esign
Posts: 112
Joined: Thu Oct 15, 2009 7:44 am
Contact:

Object Emitter - Assigning faces for emission per Frame

Postby D&Esign » Mon Apr 11, 2011 3:09 pm

Hi! Try this, but i don't know if it's right, let me know :)

ball = scene.getObject('RocketMan')
bubs = scene.get_PB_Emitter('Bubbles')
#bubs = scene.getObject('Bubbles')

# get ball velocity
vel = ball.getVelocity()
velNorm = vel.normalize()
ballFaces = ball.getFaces()
# scene.message('Velocity= ' + str(vel.x) + ',' + str(vel.y) + ',' + str(vel.z) + 'n')

emissionFaces = []

for f in ballFaces:
# get face normal and determine if it pointing towards negative velocity direction
n = f.getNormal()
#first, create dot product between velNorm and and n
dotProduct = (velNorm.getX() * n.getX()) + (velNorm.getY() * n.getY()) + (velNorm.getZ() * n.getZ())
# if dotProduct < 0, the vecors are pointing in opposite directions
if(dotProduct < 0.0):
emissionFaces.append(f.getIndices())
if(len(emissionFaces) > 0):
for idx in emissionFaces:
bubs.setSelectedFaces(idx)

Anaxarchos
Posts: 843
Joined: Wed Mar 19, 2008 4:21 pm
Contact:

Object Emitter - Assigning faces for emission per Frame

Postby Anaxarchos » Mon Apr 11, 2011 3:38 pm

Thanks for helping me out, but what did you change? I cannot see any difference.
Oh, I see- you removed an indent.

Unfortunately, this is still the same- instead of selecting a bunch of Faces per Frame it is still jumping heavily.

The problem is insted of being able to select all the Faces for which the condition is valid once per frame, setSelectedFaces() seems only to accept the indices for one Face after another, so all the faces are selected subsequently in the very same frame.
www.fk-fx.com

User avatar
D&Esign
Posts: 112
Joined: Thu Oct 15, 2009 7:44 am
Contact:

Object Emitter - Assigning faces for emission per Frame

Postby D&Esign » Mon Apr 11, 2011 4:13 pm

Yes, i have changed the last 3 lines, last "if" now is out of this FOR: for f in ballFaces.

You want to emit from all faces selected by the script for each frame right?

I'm trying now

Anaxarchos
Posts: 843
Joined: Wed Mar 19, 2008 4:21 pm
Contact:

Object Emitter - Assigning faces for emission per Frame

Postby Anaxarchos » Mon Apr 11, 2011 4:32 pm

Looks like this is the way:

Code: Select all

ball = scene.getObject('RocketMan')
bubs = scene.get_PB_Emitter('Bubbles')
#bubs = scene.getObject('Bubbles')

# get ball velocity
vel = ball.getVelocity()
velNorm = vel.normalize()
ballFaces = ball.getFaces()
 # scene.message('Velocity=  ' + str(vel.x) + ',' + str(vel.y) + ',' + str(vel.z) + 'n')

emissionFaces = []

for f in ballFaces:
   # get face normal and determine if it pointing towards negative velocity direction
   n = f.getNormal()
   #first, create dot product between velNorm and and n
   dotProduct = (velNorm.getX() * n.getX()) + (velNorm.getY() * n.getY()) + (velNorm.getZ() * n.getZ())
   # if dotProduct < 0, the vecors are pointing in opposite directions
   if(dotProduct < 0.0):
      emissionFaces.append(f.getIndices())

facesToSelect = []
if(len(emissionFaces) > 0):
    for idx in emissionFaces:
      # bubs.setSelectedFaces(emissionFaces)
      for i in idx:
         facesToSelect.append(i)

      bubs.setSelectedFaces(facesToSelect)

The only thing that's still annoying me is that the faces are selected subsequently (one can see this in the viewport), but maybe it's just like that.
www.fk-fx.com


Anaxarchos
Posts: 843
Joined: Wed Mar 19, 2008 4:21 pm
Contact:

Object Emitter - Assigning faces for emission per Frame

Postby Anaxarchos » Tue Apr 12, 2011 11:23 am

Well, it's not really working. The faces are selected, then an emission's taking place but the particles keep exploding all the time, no matter what I set as Substeps.

The thing is, even though the Script is hooked to the Pre Frame, I can see how the faces are getting selected a bit subsequently. Maybe this makes the solver a bit nuts?
www.fk-fx.com

User avatar
D&Esign
Posts: 112
Joined: Thu Oct 15, 2009 7:44 am
Contact:

Object Emitter - Assigning faces for emission per Frame

Postby D&Esign » Wed Apr 13, 2011 7:02 am

To get a face with script, generally is necessary the indices of vertices for the specific face. But maybe "setSelectedFaces" want a right number of face.. The problem is: i don't know how to get a number of face.

Your script selects the faces with the number of vertices (get.indices). But the script don't select a correct number of faces. Look this output of facesToSelect.

[0, 2, 1, 1, 4, 3, 4, 1, 2, 4, 2, 5, 3, 7, 6, 4, 7, 3, 35, 37, 36, 36, 39, 38, 39, 36, 37, 39, 37, 40, 38, 42, 41, 41, 28, 30, 28, 41, 42, 28, 42, 26, 26, 42, 43, 43, 39, 40, 39, 43, 42, 39, 42, 38, 26, 43, 25, 25, 44, 8, 44, 25, 43, 44, 43, 40, 0, 1, 45, 45, 47, 46, 47, 45, 1, 47, 1, 3, 46, 49, 48, 48, 37, 35, 37, 48, 49, 37, 49, 40, 40, 49, 50, 50, 47, 3, 47, 50, 49, 47, 49, 46, 40, 50, 44, 44, 6, 8, 6, 44, 50, 6, 50, 3, 0, 45, 51, 51, 53, 52, 53, 51, 45, 53, 45, 46, 52, 55, 54, 54, 57, 56, 57, 54, 55, 57, 55, 58, 58, 55, 59, 59, 53, 46, 53, 59, 55, 53, 55, 52, 58, 59, 60, 60, 48, 35, 48, 60, 59, 48, 59, 46, 56, 57, 61, 61, 63, 62, 63, 61, 57, 63, 57, 58, 62, 65, 64, 64, 67, 66, 67, 64, 65, 67, 65, 68, 68, 65, 69, 69, 63, 58, 63, 69, 65, 63, 65, 62, 68, 69, 70, 70, 60, 35, 60, 70, 69, 60, 69, 58, 35, 36, 70, 70, 71, 68, 71, 70, 36, 71, 36, 38, 68, 72, 67, 67, 73, 66, 73, 67, 72, 73, 72, 74, 74, 72, 75, 75, 71, 38, 71, 75, 72, 71, 72, 68, 74, 75, 76, 76, 41, 30, 41, 76, 75, 41, 75, 38, 66, 73, 77, 77, 79, 78, 79, 77, 73, 79, 73, 74, 85, 79, 74, 79, 85, 81, 79, 81, 78, 86, 76, 30, 76, 86, 85, 76, 85, 74, 66, 77, 87, 87, 89, 88, 89, 87, 77, 89, 77, 78, 88, 91, 90, 90, 93, 92, 93, 90, 91, 95, 89, 78, 89, 95, 91, 89, 91, 88, 66, 87, 64, 64, 97, 62, 97, 64, 87, 97, 87, 88, 62, 98, 61, 61, 99, 56, 99, 61, 98, 99, 98, 100, 100, 98, 101, 101, 97, 88, 97, 101, 98, 97, 98, 62, 100, 101, 102, 102, 90, 92, 90, 102, 101, 90, 101, 88, 56, 99, 103, 103, 105, 104, 105, 103, 99, 105, 99, 100, 104, 107, 106, 106, 109, 108, 109, 106, 107, 109, 107, 110, 110, 107, 111, 111, 105, 100, 105, 111, 107, 105, 107, 104, 110, 111, 112, 112, 102, 92, 102, 112, 111, 102, 111, 100, 132, 134, 133, 133, 136, 135, 135, 2, 0, 2, 135, 136, 2, 136, 5, 134, 136, 133, 56, 103, 54, 54, 138, 52, 138, 54, 103, 138, 103, 104, 52, 139, 51, 51, 135, 0, 135, 51, 139, 135, 139, 133, 133, 139, 140, 140, 138, 104, 138, 140, 139, 138, 139, 52, 133, 140, 132, 132, 106, 108, 106, 132, 140, 106, 140, 104]


I'm using a normal sphere with 162 V and 320 F. Now, in the scene message U can look the numbers always < of 162.
The list is not a list of faces number, but is a list of the indices of vertices for each face.

Maybe is this the problem?
I'm not sure, because i don't have more experience with objects, but maybe you are not selecting the correct faces.


With this command

bubs = scene.get_PB_Emitter('Circle01')
bubs.setSelectedFaces([319])

The script select the last face number 319 without vertices indices.


Ok, maybe it's right now, let me know!


Code: Select all

def onSimulationFrame():
    ball = scene.getObject('RocketMan')
    bubs = scene.get_PB_Emitter('Bubbles')
#bubs = scene.getObject('Bubbles')

# get ball velocity
    vel = ball.getVelocity()
    velNorm = vel.normalize()
    ballFaces = ball.getFaces()
# scene.message('Velocity=  ' + str(vel.x) + ',' + str(vel.y) + ',' + str(vel.z) + 'n')

    emissionFaces = []
    countt = 0
    for f in ballFaces:
    # get face normal and determine if it pointing towards negative velocity direction
        n = f.getNormal()
    #first, create dot product between velNorm and and n
        dotProduct = (velNorm.getX() * n.getX()) + (velNorm.getY() * n.getY()) + (velNorm.getZ() * n.getZ())
    # if dotProduct < 0, the vecors are pointing in opposite directions
        if(dotProduct < 0.0):
            emissionFaces.append(countt)
        countt+=1
    bubs.setSelectedFaces(emissionFaces)

Anaxarchos
Posts: 843
Joined: Wed Mar 19, 2008 4:21 pm
Contact:

Object Emitter - Assigning faces for emission per Frame

Postby Anaxarchos » Wed Apr 13, 2011 5:08 pm

Hi,

unfortunately I haven't tried your attempt, yet. But now the thing is working pretty fast and stable, but based on Vertex emission:

Code: Select all

ball = scene.getObject('RocketMan')
bubs = scene.get_PB_Emitter('Bubbles')

ballVelocity = ball.getVelocity()
ballVelNorm = ballVelocity.normalize()

ballVertices = ball.getVertices()
ballFaces = ball.getFaces()

# get faces opposing to the object's velocity
emissionFaces = []

for face in ballFaces:
   faceNormal = face.getNormal()
   dotProduct = (ballVelNorm.getX() * faceNormal.getX()) + (ballVelNorm.getY() * faceNormal.getY()) + (ballVelNorm.getZ() * faceNormal.getZ())

   # if dotProduct < 0, the vecors are pointing in opposite directions
   if(dotProduct < 0.0):
      emissionFaces.append(face)
      
# select the vertices to emit from, first create List of Indices
idxList = []
for face in emissionFaces:
   vertexIndices = face.getIndices()
   idxList.append(vertexIndices[0])
   idxList.append(vertexIndices[1])
   idxList.append(vertexIndices[2])

# for i in idxList:
   # scene.message(str(i) + ';')

bubs.setSelectedVertices(idxList)
www.fk-fx.com


Return to “Python-Scripting”

Who is online

Users browsing this forum: No registered users and 2 guests