Jump to content

modifying VEX SOP from the PDF tutorials


mark

Recommended Posts

Hi all, I've started modifying the example VEX SOP from the PDF tutorials, and VEX isn't so scary when you start to work through it!

i'm trying to replicate the max noise operator for those who are familiar with it, as an exercise, but it will hopefully also be a useful SOP, it's something i missed in maya and now also houdini.

It works but not properly, for some reason it does not affect all points in the object, generally only the outer points, but i cant work out why.

i understand this line:

float r = random(ptnum+random(seed)*Npt);

calculates a random value for all points in the object? (ptnum = current point, Npt = total number of points).

The algorithm needs some fine tuning to make it work more like the max noise sop, but for now i want to at least get it working on all points as i thought it would! It has a similar result on a box and a sphere, the central points dont move at all. also i noticed on a grid this SOP does nothing which is strange..

Can anyone spot anything obviously wrong with this code?

sop
MaxStyleNoise (float x_mov = 1; 
   float y_mov = 1;
   float z_mov = 1;
   float scale = 1;
   int seed = 1;)

{ 

  vector Nf = normalize(N); 

  float r = random(ptnum+random(seed)*Npt); 


  // calculate X,Y,Z movement values

  MoveX = Nf * r * scale * x_mov;
  MoveY = Nf * r * scale * y_mov;
  MoveZ = Nf * r * scale * z_mov;


  // actually move the points

  P.x += MoveX;
  P.y += MoveY;
  P.z += MoveZ;

}

:)

Link to comment
Share on other sites

I no programmer but here's a shot in the dark.......

Since P is a vector wouldn't it be:

P += (MoveX, MoveY, MoveZ);

Then again, I'm probaly wrong. I'm just getting my feet wet with C/C++ so I don't know how to access the individual elements.

I hope you get it sorted.

Link to comment
Share on other sites

Why don't you just study the code from a VEX Mountain SOP?

In SOPs:

1. Put down a Grid SOP. Set the rows/columns to 50 by 50.

2. Append a VEX Mountain SOP. Turn on its display flag. Play with the roughness and height parameters.

3. Put down a Torus SOP. Set the rows/columns to 50 by 50. Pipe the output of the torus into the VEX Mountain. Play with the roughness and height parameters.

4. In the parameters for the VEX Mountain, click on "Edit VEX function". In the dialog that pops up, go to the VEX Code tab.

Link to comment
Share on other sites

Compile your Sop with VCC and use the -e option

Like so: vcc -e log.txt rand_move.vfl

It will create an text file called log.txt for you to read. Full of warning messages.

I tried to compile your Sop and here's what I got:

"rand_move.vfl" line 13 WARNING (2005) Implicit casting failed for random().
	This is because there are multiple versions of the function
	and the compiler cannot determine which version to use
	based solely on the arguments given.
	The compiler has chosen "float random(float)" instead of:
     float random(vector)
     float random(vector4)
 float r = random(ptnum+random(seed)*Npt); 
                                           ^
"rand_move.vfl" line 18 WARNING (2005) Implicit casting failed for set().
	The compiler has chosen "vector set(vector)" instead of:
     vector4 set(vector)
     float set(vector)
 MoveX = Nf * r * scale * x_mov;
                                ^
"rand_move.vfl" line 19 WARNING (2005) Implicit casting failed for set().
	The compiler has chosen "vector set(vector)" instead of:
     vector4 set(vector)
     float set(vector)
 MoveY = Nf * r * scale * y_mov;
                                ^
"rand_move.vfl" line 20 WARNING (2005) Implicit casting failed for set().
	The compiler has chosen "vector set(vector)" instead of:
     vector4 set(vector)
     float set(vector)
 MoveZ = Nf * r * scale * z_mov;
                                ^
"rand_move.vfl" line 25 WARNING (2005) Implicit casting failed for add=().
	The compiler has chosen "void add(float &; int)" instead of:
     void add(float &, float)
 P.x += MoveX;
              ^
"rand_move.vfl" line 26 WARNING (2005) Implicit casting failed for add=().
	The compiler has chosen "void add(float &; int)" instead of:
     void add(float &, float)
 P.y += MoveY;
              ^
"rand_move.vfl" line 27 WARNING (2005) Implicit casting failed for add=().
	The compiler has chosen "void add(float &; int)" instead of:
     void add(float &, float)
 P.z += MoveZ;
              ^
"rand_move.vfl" line 18 ERROR (1008) Undefined symbol "MoveX"
 MoveX = Nf * r * scale * x_mov;
                                ^
"rand_move.vfl" line 25 ERROR (1008) Undefined symbol "MoveX"
 P.x += MoveX;
              ^
"rand_move.vfl" line 26 ERROR (1008) Undefined symbol "MoveY"
 P.y += MoveY;
              ^
"rand_move.vfl" line 27 ERROR (1008) Undefined symbol "MoveZ"
 P.z += MoveZ;
              ^
REMARK (3003) 4 errors and 7 warnings encountered
REMARK (3007)
No output is generated due to errors in the source code

PS. For more compiler options type, vcc -help

Link to comment
Share on other sites

What everybody said ;)

But more specific to the code you posted, and in case those error messages make no sense.... please follow me to the dissection table... ;)

1. The random function comes in several different "flavours" (see the VEX function listings): some return floats, some vectors, and others vector4's. This means that the second random() call in the expression float r = random(ptnum+random(seed)*Npt); is ambiguous, since you can't determine, by context alone, which version should be used. The outer call is OK because it gets disambiguated by the assignment (i.e: you're assigning to a float, so you obviously mean the version of random() that returns a float; make sense?).

In order to fix this bit, you should add a function cast (see the docs) to tell the compiler *exactly* which version of random() you meant. So it would look like this:

float r = random(ptnum + float(random(seed))*Npt);

You are explicitely telling it to use the version that returns a float.

However; the version of the outer random function is, after all the smoke clears, this:

float random(int);

Notice the parameter type is int (not float). This may surprise you, but long-story-short, it follows the following logic (which is particular to VEX, and not C/C++ for example):

random(ptnum + float(random(seed))*Npt)
-> random(int + (float*int))
-> random(int + float)
-> random(int)

2. MoveX, MoveY, and MoveZ are never declared. In other words, we don't know if they are floats, vectors, matrices... what? So those lines should be changed to.... huh! what *should* they be changed to?!?

Let's see what type the right hand side resolves to first (I'll just use MoveX in the example, but it applies to all three):

MoveX = Nf * r * scale * x_mov;
-> (?) = vector * float * float * float;
-> (?) = vector * float;
-> (?) = vector;

Aha!; so MoveX should be a vector! (a vector can only be assigned to another vector, or a vector4). But it's pretty obvious that whatever type you had in mind for MoveX, MoveY, and MoveZ, it was a type with one component, not three... so there's a problem with your logic somewhere in there; which brings us to...

3. Make sure you have a very clear idea of what you want to do before you sit down and code it. In this case, if I had to say it in words, it would go something like this: "Move (displace) every P by a random amount along N". Which is equivalent to saying: "Add a randomly scaled unit-length N to every P". In symbols:

 P = P + normalize(N) * R(ptnum) * C

Where R(ptnum) is some random float based on the point number (ptnum), and C is some user-defined constant to dial the effect up and down.

Expanding it with what we already covered above, this single line (which is the entire functionality of your OP) becomes:

P += normalize(N) * random(ptnum+float(random(seed))*Npt) * C

Which leaves just one little bit dangling: the constant C.

4. In your case, C is made up of a global scaling "scale", and three per-component scalings (x_mov, y_mov, and z_mov). Combining them, the components of N will get scaled by scale*x_mov, scale*y_mov and scale*z_mov. This per-component thinking, however, lead you to write the final assignments in a way that is syntactically incorrect: P.x, P.y, and P.z cannot be assigned to! They are not "lvalues" -- they can never be placed on the left hand side of an assignment; ever.

The only "thing" that you can assign to here, is P, not its components. This means that your scaling factor needs to be a vector (whose components are formed as above); not three separate floats. So this user-defined scaling factor, as a vector, becomes:

vector C = set(scale*x_mov, scale*y_mov, scale*z_mov);

OK. Now that we have all the bits, we can put Humpty-Dumpty together again:

//---------------------------------------------------------

// Displaces points using white noise (random)

//

// Compile with:

//   vcc -L [otl_filename] [this_vfl_filename]

//

// And then import into houdini through

//   File -> Install Operator Type Library -> [otl_filename]

//

//---------------------------------------------------------

#pragma opmininputs 1

#pragma opmaxinputs 1

sop MaxStyleNoise (

Link to comment
Share on other sites

thanks so much fellas - heres some responses :D

renderpipe i thought that also! P += (MoveX, MoveY, MoveZ); but it didnt work, it only moved in X - so i tried the P.x etc. and it worked so i assumed it was ok..., i can now see where i was wrong.

stremik - i retyped the code because im at work and my actual code is at home i may have made an error today (and i did - not declaring the types :D) i'll check type casting, thanks to pointing me to more docs, i need em!

Dr. Mario at the dissecting table on your birthday, what can i say - thats just brilliant, i cant wait to try it, thanks =)

cheers all!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...