Jump to content

VEX problem / while loop


j00ey

Recommended Posts

Hi

 

I'm trying to make an asset that will generate some curved lines with corners so I've written a sort of curving raytracer. It works with most settings but changing some variables I quickly come across settings where houdini just gets stuck. I can ESC out of it without difficulty and I can generate the geometry I need but I'd like to understand what's causing the problem.

 

Attached is the hip. WIth the settings I've left it set at, it's quite happy to do 18 bounces but if you turn it up to 19 it sticks...

Thanks for reading.

 

* edit *

Maybe I should explain quickly what it's actually supposed to do -

 

for input points :

 

while bounces is less than max bounce :

 

using point normal, find intersection with second input geometry

calculate distance between start position and intersection

If distance is greater than step size, create a new point at step length away and rotate normal direction.

If distance is less than step size, create a point at intersection position and set the normal to the reflection vector between normal and intersection normal

curvetracer_v01.hip

Edited by j00ey
Link to comment
Share on other sites

Hi, your problem is in your while loop, hit_prim = -1 when you bounce 19 times and you haven't any statement in this case.

So the loop run over and over....and over.

 

You can check this with adding these lines just after your else if statement:

else {
        printf("hit_dist: %s | hit_prim: %s\n", hit_dist, hit_prim);
        break; // STOP the loop
    }
Edited by fsim
Link to comment
Share on other sites

Here the solution. I store the last hit_prim, hit_pos, hit_uv, and if hit_dist < steplength, i check if hitprim == -1.

In this case, i reflect curr_dir from the last_hitprim.

float steplength = chf("steplength");
float angle = radians(chf("angle"));
float bias = chf("bias");
int maxbounces = chi("bounces");
float bounce , hit_dist;
int newpoint , newprim , hit_prim;
vector start_pos , curr_pos , new_pos , curr_dir , new_dir , prim_uv , hit_pos , hit_n , reflect_dir, bend_dir , bitangent;
vector4 q;

newprim = addprim(0,"polyline");
addvertex(0,newprim,0);

start_pos = v@P;
curr_dir = normalize(v@N);

bounce = 0;
// printf("-S-\n\n");
int last_hitprim;
vector last_hitpos;
vector last_primuv;
while(bounce < maxbounces){

    curr_pos = start_pos + (curr_dir * bias);//offset ray start in case of self intersection
    

    hit_prim = intersect(1 , curr_pos , curr_dir * 10000 , hit_pos , prim_uv );//store hit details
    hit_dist = length(start_pos - hit_pos);//calc distance to hit
    
    
    
    // printf("Bou: %s | Cur.P: %s | curr_dir: %s ", bounce, curr_pos, curr_dir);

    if ( ( hit_dist > steplength ) && ( hit_prim != -1 ) ){//if hit a prim and it is further away than step size

        new_pos = start_pos + (curr_dir * steplength);
        newpoint = addpoint(0,new_pos);
        addvertex(0,newprim,newpoint);
        start_pos = new_pos;
        bitangent = set(-curr_dir.z , 0 , curr_dir.x);
        q = quaternion( angle , bitangent);
        bend_dir = qrotate( q , curr_dir);
        bend_dir = normalize(bend_dir);
        setpointattrib(0,"N",newpoint,bend_dir,"set");
        curr_dir = bend_dir;
        // printf("I'm in if...\n");
        last_hitprim = hit_prim;
        last_hitpos = hit_pos;
        last_primuv = prim_uv;
    }
    
    else if  ( ( hit_dist < steplength )  ){//if hit a prim and it is within step size

        if (hit_prim == -1) {
            hit_pos = last_hitpos;
            hit_prim = last_hitprim;
            prim_uv = last_primuv;
        }
        new_pos = hit_pos;
        newpoint = addpoint(0,new_pos);
        addvertex(0,newprim,newpoint);
        hit_n = primuv(1,"N",hit_prim,prim_uv);
        reflect_dir = normalize(reflect(curr_dir , hit_n));
        setpointattrib(0,"N",newpoint,reflect_dir,"set");
        setpointattrib(0,"corner",newpoint,1,"set");
        start_pos = hit_pos;
        curr_dir = reflect_dir;
        bounce += 1;
        // printf("I'm in else...\n");
        last_hitprim = hit_prim;
        last_hitpos = hit_pos;
        last_primuv = prim_uv;
    }
    else {
        printf("hit_dist: %s | hit_prim: %s\n", hit_dist, hit_prim);
        break;
    }
}
Link to comment
Share on other sites

Thanks very much for that Francois, I'll try it.

 

After your initial I put in a statement to say :

 

if hit_prim == -1 then break

 

which fixed the problem but this is good for debugging...

Edited by j00ey
Link to comment
Share on other sites

You're welcome.

In fact, the real problem is you add an offset to your curr_pos. And when hit_dist is close to your bias, the curr_pos is out of geometry, and you check 'if hit_dist < steplength', the solution is to check 'if hit_dist < (steplength + bias)'.

Edited by fsim
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...