Jump to content


  • Content count

  • Donations

    0.00 CAD 
  • Joined

  • Last visited

Community Reputation

1 Neutral

About JoshJ

  • Rank

Personal Information

  • Name
  • Location
    New York
  1. well, even with inlinecpp (using python and ctypes), it looks like a new library name with a random string is created and reloaded. Is this a limitation of c or c++ itself, which prevents easy reloading of dynamic libraries? or is it a limitation of the way its implemented in houdini?
  2. I'm experimenting with processing data with cvex in a standalone application. Everything is working except for the following issue: Reloading an existing .vfl file doesn't seem to update. Loading a new .vfl file does update. Explanation: I load and run a hand-coded cvex .vfl file, then modify the .vfl file and resave. My application releases and cleans up the objects which held the cvex contexts, then creates new cvex contexts and loads the updated .vfl file. However, the cvex processing doesn't reflect the new resaved .vfl file, it still runs the originally loaded code. If I resave the .vfl file as a new name, and load that new file, the processing updates as expected. I've tried running cvex_context::clearAllFunctions(), but whether I call it in the destruction of the old cvex contexts, or right at the creation of new cvex contexts, I have only had it result in a crash.
  3. Authoring Interactive HLSL OpenGL shaders in Houdini

    This is very interesting, looking forward to seeing how this progresses.
  4. I'm experimenting with creating a sop, returning a polygon mesh from an implicit function, using GU_Detail::polyIsoSurface. The example density function works fine, returning a sphere. SPHERE_FUNCTION: static float densityFunction(const UT_Vector3 &P, void *data) { // Return the signed distance to the unit sphere return 1 - P.length(); } However, when I change the return value so that a level set function should return a plane, I only receive empty geometry. PLANE_FUNCTION: static float densityFunction(const UT_Vector3 &P, void *data) { // Return the signed distance to the unit sphere return P.y(); //or //return 1 - P.y(); //or //return -P.y(); } The bounds are set just like in the standalone example file, but in the cookMySop function: OP_ERROR SOP_IsoFunction::cookMySop(OP_Context &context) { OP_AutoLockInputs inputs(this); if (inputs.lock(context) >= UT_ERROR_ABORT) return error(); // Duplicate input geometry duplicateSource(0, context); // Flag the SOP as being time dependent (i.e. cook on time changes) flags().timeDep = 1; gdp->clearAndDestroy(); UT_BoundingBox bounds; bounds.setBounds(-1, -1, -1, 1, 1, 1); gdp->polyIsoSurface(densityFunction, NULL, bounds, 20, 20, 20); return error(); } Any ideas why this is returning a sphere with SPHERE_FUNCTION, but empty geometry with PLANE_FUNCTION? The levelset should be crossing the zero threshold on the xz plane, right? Edit: I found that when I add a slight noise to the plane function, it appears. But if the plane is perfectly flat, it returns empty geometry. Strange.
  5. A question: In a vex function multi-threading scenario, how can I determine which instance certain threads belong to? Background information: I've come up with a way to cache information for the threads throughout the Init, evaluate, cleanup vex function lifecycle. However, I'm running into a problem. When I advance frame by frame slowly, one by one, my function is stable with multi-threading on. When I play it back at realtime, it crashes after a couple of frames. However, if I cause each thread to print out information to the console during cleanup and init, it plays back without crashing. I believe I know the reason, but I can't think of a solution within the current architecture. Each thread has no awareness of whether the other threads have finished their cleanup. I also don't see any way to determine which instance different threads belong to. When some threads move on to the next init function, and other threads are still in the previous cleanup function, this causes a crash (since I've set it up so that all threads are sharing the same per-frame global data). I may have multiple instances of my custom vex function within the same process, and I don't see a way to deal with this per instance. Is there anything like getMyInstance() for the entire instance? The documentation states "The initialization/cleanup functions are called for each instance of your user function." However, I found instead that the initialization and cleanup functions are run per thread.
  6. Thanks edward, I'll look into it.
  7. /////////////////// I'm writing a custom c++ vex function. I have a somewhat expensive initial setup that only needs to be done once per instance(not per thread).I have the following scenarios working already: 1) multi-threaded off. Each time the vex function is instanced, my initial setup is called once. This is fine, but single-threaded. 2) multi-threaded on. Each time the vex function is instanced, each thread calls the initial setup once. This is working, but too heavy, not optimal. 3) multi-threaded on. Initial setup is done in a singleton class which is forced to be called only once. This is similar to the gamma table example in the help. Initial setup is called only once, but on subsequent instantiation, each instance shares the same initial setup. This is not correct, as each instance will require a different setup. What I'd like is: multi-threaded on. Initial setup is done once per instance, and shared among all the threads invoking that instance. Once the vex function is used again, initial setup is done only once again, not 1*numthreads. /////////////////// Also, is there any way to pass in input args data from parameters to the initialize function? Currently they only seem to be passed to the evaluate function.
  8. How do I use the enum values for the noise? UT_Vector3 x = {pos(0),0,pos(2)}; UT_Noise anoise; // set the noise type here to alligator using an enum, like: // anoise.setType(UT_Noise::UT_NoiseType(ALLIGATOR)); // which gives the error: ‘ALLIGATOR’ was not declared in this scope data[0] = -pos[1]+0.5+ anoise.turbulence(x,3,0.5,0.5)*0.1; Edit: Ok, I solved it, anoise.setType(UT_Noise::UT_NoiseType::ALLIGATOR);
  9. thanks ranxerox, that helps. I figured out that UT_Noise needs to be instanced as an object like this: UT_Noise anoise; data[0] = -pos[1]+0.5 + anoise.turbulence(pos,5,0.5,0.5); Now it works.
  10. Awesome, Thanks edward, it worked. Now I'm experimenting with UT_Noise::turbulence , which doesn't have the float x[3] input. Instead it has , for example: fpreal turbulence( const UT_Vector3 &pos, unsigned fractalDepth, fpreal rough = 0.5, fpreal atten = 1.0) const; I'm not sure what to put for the "const" entry after the end parenthesis. I've attempted to call it like this: const a = 0; fpreal x = UT_Noise::turbulence(pos,5) a; data[0] = -pos[1]+0.5 + x; which of course did not work, and I've tried a few variations and google searches about "error: cannot call member function ... const’ without object" So, what does it mean when "const" is after the function parenthesis, and how do I call this type of function correctly? also, for the void style of the function: void turbulence( const UT_Vector3 &pos, unsigned fractalDepth, UT_Vector3 &noise, fpreal rough = 0.5, fpreal atten = 1.0) const; Would I just create a UT_Vector3 variable beforehand, and enter it in like: UT_Vector3 dest; UT_Noise::turbulence(pos,5,dest); Then dest contains my noise as a UT_Vector3 object?
  11. Hi, So I'm making my first steps into the HDK, having very minimal, casual c++ experience over the years. I successfully compiled some of the examples, and I'm experimenting with changing the demoVolumeSphere into a custom VRAY volume procedural. It's going well, except I can't figure out how to get any 3d noise working. I'm currently adjusting the vray_VolumeSphere::evaluate function. Here's my current code: included at the top is: #include <UT/UT_PNoise.h> --------------------------------------------- void vray_VolumeSphere::evaluate(const UT_Vector3 &pos, const UT_Filter &, float, float, int idx, float *data) const { data[0] = -pos[1]+1 + UT_PNoise::noise1D(pos[0]); } --------------------------------------------- Correctly results in a 1d noise along the x axis. However, as soon as I attempt to use any of the 3d noise, I can't get the types, pointers, and references to cooperate. for example, when I use UT_PNoise::noise3D , I've tried every combination of * , &, etc I can think of for the inputs, but I always get an error message like: error: no matching function for call to ‘UT_PNoise::noise3D(UT_Vector3&, const UT_Vector3&, int)’ UT_PNoise::noise3D(dest,pos,1); I know I haven't mastered a lot of the c++ pointer concepts, but I'd like to learn by example and figuring it out, and I'll eventually get it. I looked through most of the HDK documentation though, and didn't find any example which could apply to this case. If someone could write out a simple example for UT_PNoise::noise3D with const UT_Vector3 &pos as an input, resulting in a 1d value, that would be awesome.
  12. HI Fathom, When you combine the high res and low res vdbs, do you upres the low res large surface to become high res? I have tried a few scenerios like this in the past and always felt it was fairly inefficient. What do you think? Do we need something like multi-res vdb, or are there ways to work with the current vdb toolset efficiently?
  13. Thanks Jim, great work, looking forward to it!
  14. So, I'm playing around with the new shading toys here, and they look fantastic. I'm wondering though, what's a good way to use these along with refraction? Would I add a physically based specular with refract label, and use the fresnel vop to blend between them? or add them together? or is there another more "intelligent/correct" way to implement refraction here?
  15. lookup vop?

    Oh, I just used the noise as a simple example... in another larger setup I had a value coming in that I really wanted to modify based on another calculated value, like one would with lookup cop or chop If that functionality wasn't built in, I thought it might be a good chance to look into the math behind a lookup operation, but I have yet to find a good explanation.