Notifications
Clear all

[Closed] print count = pCont.NumParticles() gives 2 numbers ?

Hi all, hopefully this is a simple question …

Im scripting in particle flow and I am getting an issue with pCOnt.NumParticles()

I have a standard particle flow, add a collison test with a deflector, this leads to event 2 which has a display node different color so I know they are going to next event and my script operator.

Here is my script, its just an example to show what I mean.

on ChannelsUsed pCont do
(
pCont.useTime = true
pCont.useSpeed = true
)

on Init pCont do

(

)

on Proceed pCont do

(

count = pCont.NumParticles()

print count

)

on Release pCont do
(

)

now when I scrub time line for each frame it prints 2 numbers ?

From examining them the 2 numbers added together make the current particle count in the particle container (event 2)

if I scrub again, of the next 2 numbers the first will be the previous 2 numbers added together ( previous particle count in event) and the next number is the ammount of particles that have been added this frame.

I dont understand why this the .count of this array is updating itself number twice per frame. I have intergration step per frame but dont think it has anything to do with that.

If I use this script in the first event with no collision I get a single number every frame printed and need this to happen in event 2.

Any help will be much apprechiated, and just in case you are interested, below is the script Im trying to get to work and think the above query is why it isnt. It basically spawns or deletes omni lights depending on the particle count and moves the omnis to the particles position. Its works great in event 1, but when moved to event 2 its not working and I think I have narrowed it down to the the above issue.

Anyway here it is.

Thanks for your time guys

on ChannelsUsed pCont do
(
pCont.useTM = true
)

on Init pCont do
(

)

on Proceed pCont do
(
count = pCont.NumParticles()
mylights = $omni* as array
mylights.pos = [0,0,0]

if mylights.count < count do

(

	for i = 1 to (count - mylights.count) do

		(
			myomni = omnilight()
			myomni.pos = [0,100,0]
		)
)

if mylights.count > count do

(

	for i = 0 to (mylights.count - count) do

		(
			 delete mylights[mylights.count - i]
		)

)

mylights = $omni* as array

for i in 1 to mylights.count do
(
	pCont.particleindex = i
	mylights[i].transform = pCOnt.particleTM
)

)

on Release pCont do
(

)

6 Replies

Also, when I go backwards a frame it prints every number of the array from frame 0 to current frame. Very strange …

Well I dunno about the former, but the latter – going back a frame printing everything up to the current frame – makes sense.

In 3ds Max, particle systems have their data cached for the current frame. That way, when you go to the next frame, all it has to do is apply speed, rotation, etc. as a difference to the last frame, instead of having to calculate all of the preceding frames again.
However, when you go -back- a frame, the last frame is not valid… so it calculates all preceding frames again.

Ah ok, well that makes sense. basically Im after a single number for
my pCont.NumParticles() so work out if I have more or less lights than particles and create or delete them accordingly.

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

What is your Integration step? The Operator can be evaluated multiple times per frame, depending on the integration step settings. Viewport is usually 1 per frame, Render 2 per frame by default, but who knows what your settings are…

PFlow updates as often as it needs to, there is no rule that says it should call the handler just once per frame. And scrubbing backwards without a Cache operator generally means updating the whole range from start to current frame again and again, which is a BAD idea.

And before I forget – NEVER EVER create objects inside a Proceed handler of a PFLow operator! You are likely to crash the renderer if you try to do that. Especially with meshes, but lights might not work as expected either. Creation of objects should be performed in the on Init handler.

cheers bobo. my integration step is set to 1 per frame. Basically instead of giving me the total as a single number, as it would if the script opertaor was in the first event, it is instead give me the number of particles that were in the event in the previous frame and then the ammount of particles that have moved into the event during that frame giving a total of the ammount. I dont understand why it would do it in this way in the second event but just giving one number in the first event.

Oh and just another question, if yous houdlnt create objects in the Proceed handeler, is there a way to access the pCont.NumParticles() with the oninit handler as when I put

on Init pCont do

(
count = pCont.NumParticles()
print count
)

it wont print anything and so I am assuming it cant read this data in there ?