Adding or Removing Vertices from an Object Emitter?

Discussion about scripting with Python
tolliverDry
Posts: 6
Joined: Tue Nov 12, 2013 5:00 am

Adding or Removing Vertices from an Object Emitter?

Postby tolliverDry » Tue Nov 12, 2013 5:33 am

Hi. I'm fairly new to scripting in realflow and I'm trying to emit particles from an animated object's vertices once they reach a certain velocity. I've somewhat been able to do this using addParticle(), but I can't seem to control the amount of particles it emits per substep. I want to try using an object emitter for this, but I can't seem to find out how to add or remove vertices from the object emitter using scripting. Can anyone help?


User avatar
tsn
Posts: 915
Joined: Fri Oct 27, 2006 10:36 am

Re: Adding or Removing Vertices from an Object Emitter?

Postby tsn » Tue Nov 12, 2013 10:49 am

Since you can't remove the vertices physically, the only way is to change the object emitter's vertex selection. First, you have to go through the object's vertices, select the ones you want to have for emission, and store them in a list. This list is then passed to the object emitter with the following statement:

Code: Select all

setSelectedVertices( list )


The main problem with this method is that you'll never know what you finally get, because you can't preview the object's vertex Ids. A good approach is therefore to use only every n-th particle. This can be done with the Modulo function:

Code: Select all

objEmitter = scene.get_PB_Emitter("Object01")
...
emitterSelection = []
for objectVertexId in vertexList:
   if (objectVertexId % 10 == 0):
      emitterSelection.append(objectVertexId)

objEmitter.setSelectedVertices(emitterSelection)


In the pseudo-code example above, every 10th vertex will be used. In the next step or frame you can change this to every 5th vertex etc.

tolliverDry
Posts: 6
Joined: Tue Nov 12, 2013 5:00 am

Re: Adding or Removing Vertices from an Object Emitter?

Postby tolliverDry » Wed Nov 13, 2013 3:38 am

Thanks for the reply. I didn't think there was a separate function just to set the vertices for an object emitter.

I tried the code you wrote, but now I'm getting an error. I'm guessing there's something wrong with how I'm getting my list of vertices?

Code: Select all

   danceObj = scene.getObject("dance1_skin")
   objEmitter = scene.get_PB_Emitter("Object01")
   vertList = danceObj.getVertices()
   emitterSelection = []
   for objectVertexId in vertList:
      vertVel = objectVertexId.getVelocity()
      if (objectVertexId % 5 == 0) and vertVel.module() > 70:
         emitterSelection.append(objectVertexId)
   objEmitter.setSelectedVertices(emitterSelection)


I get this error: WARNING: Script error: "unsupported operand type(s) for %: 'RealFlow Vertex' and 'int'" at line number 23.

I'm guessing getVertices() doesn't return a list of integers. How can I get a list of vertex indices as integers?

tolliverDry
Posts: 6
Joined: Tue Nov 12, 2013 5:00 am

Re: Adding or Removing Vertices from an Object Emitter?

Postby tolliverDry » Wed Nov 13, 2013 7:32 am

Ok, I've gotten roughly what I wanted, but with a few caveats. Here's my current code

Code: Select all

emitterSelection = [ ]
#--------------------------------------------------
# Function: onSimulationBegin
#--------------------------------------------------

def onSimulationBegin():
   global emitterSelection
   emitterSelection = [23]

#--------------------------------------------------
# Function: onSimulationFrame
#--------------------------------------------------

def onSimulationFrame():
   danceObj = scene.getObject("dance1_skin")
   objEmitter = scene.get_PB_Emitter("Object01")
   vertList = danceObj.getVertices()
   faceList = danceObj.getFaces()
   firstFace = faceList[1].getIndices()
   secondFace = faceList[2].getIndices()
   global emitterSelection
   #emitterSelection = [23]
   for singleVert in vertList:
      vertVel = singleVert.getVelocity()
      vertAdFaces = danceObj.getAdjoiningFacesToVertex(singleVert)
      if vertVel.module() > 70:
         for face in vertAdFaces:
            faceInd = face.getIndices()
            vert0 =  faceInd[0]
            vert1 =  faceInd[1]
            vert2 =  faceInd[2]
            if vert0 not in emitterSelection:
               emitterSelection.append(vert0)
            if vert1 not in emitterSelection:
               emitterSelection.append(vert1)
            if vert2 not in emitterSelection:
               emitterSelection.append(vert2)
      if vertVel.module() < 70:
         if len(emitterSelection) > 1:
            for face in vertAdFaces:
               faceInd = face.getIndices()
               vert0 =  faceInd[0]
               vert1 =  faceInd[1]
               vert2 =  faceInd[2]
               if vert0 in emitterSelection:
                  emitterSelection.remove(vert0)
               if vert1 in emitterSelection:
                  emitterSelection.remove(vert1)
               if vert2 in emitterSelection:
                  emitterSelection.remove(vert2)
         else:
            emitterSelection = [23]

   objEmitter.setSelectedVertices(emitterSelection)


The problem with this is that I have to go through the adjacent faces of the vertex I want to emit from and use the indices of the vertices of those faces to add to the object emitter. I still have no idea how to get the index of a single vertex.

User avatar
tsn
Posts: 915
Joined: Fri Oct 27, 2006 10:36 am

Re: Adding or Removing Vertices from an Object Emitter?

Postby tsn » Wed Nov 13, 2013 8:17 am

Sorry. I made a mistake in my pseudo-code, because there's really no function to get the Id of a vertex. Only particles and polygons have Ids, and I just forgot that. The code you wrote will cut it, but there's an easier way to do that from the list of vertices directly. What you can do is creating your own "Id" with a counter to access the entries of the vertex list. This code example prints out the x position of an object's vertices for each 5th point:

Code: Select all

obj = scene.getObject("Torus01")
vertexList = obj.getVertices()
vertexId = 0
for vertex in vertexList:
   if (vertexId % 5 == 0):
      scene.message(str(vertex.getPosition().x))
   vertexId += 1


The counter (vertexId) is simply incremented after each cycle of the loop. This way you get each 5th vertex as well and it's actually the same as if you're accessing a vertex with its Id directly.

tolliverDry
Posts: 6
Joined: Tue Nov 12, 2013 5:00 am

Re: Adding or Removing Vertices from an Object Emitter?

Postby tolliverDry » Wed Nov 13, 2013 9:25 am

Thanks a lot. That seemed to do it. Here's what my code looks like now:

Code: Select all


emitterSelection = [ ]
#--------------------------------------------------
# Function: onSimulationBegin
#--------------------------------------------------

def onSimulationBegin():
   global emitterSelection
   emitterSelection = [23]


#--------------------------------------------------
# Function: onSimulationFrame
#--------------------------------------------------

def onSimulationFrame():
   danceObj = scene.getObject("dance1_skin")
   objEmitter = scene.get_PB_Emitter("Object01")
   vertList = danceObj.getVertices()
   global emitterSelection
   vertID = 0
   if len(emitterSelection) < 2:
      objEmitter.setParameter("Speed", 0.0)
   else:
      objEmitter.setParameter("Speed", 5.0)
   for singleVert in vertList:
      vertVel = singleVert.getVelocity()
      if vertVel.module() > 70:
         if vertID not in emitterSelection:
            emitterSelection.append(vertID)
      if len(emitterSelection) > 1:
         if vertVel.module() < 70:
               if vertID in emitterSelection:
                  emitterSelection.remove(vertID)
      vertID += 1

   objEmitter.setSelectedVertices(emitterSelection)



User avatar
tsn
Posts: 915
Joined: Fri Oct 27, 2006 10:36 am

Re: Adding or Removing Vertices from an Object Emitter?

Postby tsn » Wed Nov 13, 2013 10:18 am

Yes, this looks much better. Glad to hear that it's working now as expected :D


Return to “Python-Scripting”

Who is online

Users browsing this forum: No registered users and 3 guests