Shortest path.

   1568   12   1
User Avatar
Member
16 posts
Joined: 4月 2020
Offline
Good day.
I have a question for modelers, I have problems with selection of edges along a short path (shift + a). The short path algorithm is very poorly written. Please tell me what are the ways to solve the problem. Maybe someone knows a plugin that solves this problem?
Thanks.

Attachments:
Screenshot_57.jpg (246.3 KB)

User Avatar
Member
143 posts
Joined: 5月 2017
Offline
Hi,
it could be due to the geomtry used, maybe there are overlaps or points that are not used. This can cause the shortest path to be misleading. Try the Fuse SOP or the Clean SOP (Delete unused Points).
User Avatar
Member
474 posts
Joined: 7月 2005
Offline
If you are looking for a path like this, you should probably add an angle multiplier (turning cost).

Attachments:
shortest_path_angle_multiplier.hipnc (163.4 KB)

User Avatar
Member
16 posts
Joined: 4月 2020
Offline
vik_lc
Hi,
it could be due to the geomtry used, maybe there are overlaps or points that are not used. This can cause the shortest path to be misleading. Try the Fuse SOP or the Clean SOP (Delete unused Points).

I checked, the problem is still in the written algorithm. In other programs this function works much better and it's frustrating because Houdini is super powerful and I like its procedural structure.

Attachments:
Screenshot_479.png (816.5 KB)

User Avatar
Member
16 posts
Joined: 4月 2020
Offline
Aizatulin
If you are looking for a path like this, you should probably add an angle multiplier (turning cost).
Thanks, your method works great for edge sampling in splines, but I need a simple edge sampling along a shorter path for fast modeling.
User Avatar
Member
4500 posts
Joined: 2月 2012
Offline
Hi,

You can also select edge loops using VEX:

function int [ ] GetPrimsFromEdge ( int input; int pt0; int pt1 )
{
    int prims [ ];
    int hedge = pointedge ( input, pt0, pt1 );
    if ( hedge != -1 )
    {
        int count = hedge_equivcount ( input, hedge );
        for ( int i = 0; i < count; ++i )
        {
            int pr = hedge_prim ( input, hedge );
            if ( pr != -1 )
            {
                append ( prims, pr );
                hedge = hedge_nextequiv ( input, hedge );
            }
        }
    }
    return prims;
}



int GetNextPoint ( int input; int edgept0; int edgept1; int currentpt )
{
    int ptneighbours [ ] = neighbours ( input, currentpt );
    
    int primpts [ ];
    int prims [ ] = GetPrimsFromEdge ( input, edgept0, edgept1 );
    for ( int i = 0; i < len ( prims ); ++i )
    {
        int count = primvertexcount ( input, prims [ i ] );
        for ( int f = 0; f < count; ++f )
        {
            int vertIndex = vertexindex ( input, prims [ i ], f );
            int pointIndex = vertexpoint ( input, vertIndex );
            append ( primpts, pointIndex );
        }
    }
    
    int uniquepts [ ];
    foreach ( int pt; ptneighbours )
    {
        if ( find ( primpts, pt ) < 0 )
            append ( uniquepts, pt );
    }
    
    if ( len ( uniquepts ) == 1 )
        return uniquepts [ 0 ];

    return -1;
}



void GroupEdgeLoops ( int input; string edgegroup, groupname )
{
    if ( edgegroup == "" )
    {
        setedgegroup ( geoself ( ), groupname, 0, 0, 0 );
        return;
    }
        
    int loopedgepts [ ] = { };
    int edges [ ] = expandedgegroup ( input, edgegroup );
    if ( len ( edges ) == 0 )
    {
        setedgegroup ( geoself ( ), groupname, 0, 0, 0 );
        return;
    }
        
    int count = int ( 0.5 * len ( edges ) );
    for ( int i = 0; i < count; ++i )
    {
        int edgepts [ ] = sort ( array ( edges [ 2 * i ], edges [ 1 + 2 * i ] ) );
        
        int index0 = find ( loopedgepts, edgepts [ 0 ] );
        int index1 = find ( loopedgepts, edgepts [ 1 ] );
        int edgefound = index0 % 2 == 0 && index1 % 2 == 1 && index1 == 1 + index0;
        if ( !edgefound )
        {
            for ( int c = 0; c < 2; ++c )
            {
                int points [ ];
                int pt0 = edgepts [ c ];
                int pt1 = edgepts [ 1 - c ];
                int currentpt = pt0;
                int lastPoint = pt0;
                append ( points, currentpt );
                int nextPoint = GetNextPoint ( input, pt0, pt1, currentpt );
                while ( nextPoint != -1 && nextPoint != lastPoint )
                {
                    pt0 = currentpt;
                    pt1 = nextPoint;
                    currentpt = pt1;
                    append ( points, currentpt );
                    nextPoint = GetNextPoint ( input, pt0, pt1, currentpt );
                }
                
                int ptcount = len ( points ) - 1;
                for ( int f = 0; f < ptcount; ++f )
                    setedgegroup ( geoself ( ), groupname, points [ f ], points [ 1 + f ], 1 );
            }
            setedgegroup ( geoself ( ), groupname, edgepts [ 0 ], edgepts [ 1 ], 1 );
        }
    }
}

GroupEdgeLoops ( 0, chs("edge_group"), chs("group_name") );

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
User Avatar
Member
16 posts
Joined: 4月 2020
Offline
animatrix_
Hi,

You can also select edge loops using VEX:

function int [ ] GetPrimsFromEdge ( int input; int pt0; int pt1 )
{
    int prims [ ];
    int hedge = pointedge ( input, pt0, pt1 );
    if ( hedge != -1 )
    {
        int count = hedge_equivcount ( input, hedge );
        for ( int i = 0; i < count; ++i )
        {
            int pr = hedge_prim ( input, hedge );
            if ( pr != -1 )
            {
                append ( prims, pr );
                hedge = hedge_nextequiv ( input, hedge );
            }
        }
    }
    return prims;
}



int GetNextPoint ( int input; int edgept0; int edgept1; int currentpt )
{
    int ptneighbours [ ] = neighbours ( input, currentpt );
    
    int primpts [ ];
    int prims [ ] = GetPrimsFromEdge ( input, edgept0, edgept1 );
    for ( int i = 0; i < len ( prims ); ++i )
    {
        int count = primvertexcount ( input, prims [ i ] );
        for ( int f = 0; f < count; ++f )
        {
            int vertIndex = vertexindex ( input, prims [ i ], f );
            int pointIndex = vertexpoint ( input, vertIndex );
            append ( primpts, pointIndex );
        }
    }
    
    int uniquepts [ ];
    foreach ( int pt; ptneighbours )
    {
        if ( find ( primpts, pt ) < 0 )
            append ( uniquepts, pt );
    }
    
    if ( len ( uniquepts ) == 1 )
        return uniquepts [ 0 ];

    return -1;
}



void GroupEdgeLoops ( int input; string edgegroup, groupname )
{
    if ( edgegroup == "" )
    {
        setedgegroup ( geoself ( ), groupname, 0, 0, 0 );
        return;
    }
        
    int loopedgepts [ ] = { };
    int edges [ ] = expandedgegroup ( input, edgegroup );
    if ( len ( edges ) == 0 )
    {
        setedgegroup ( geoself ( ), groupname, 0, 0, 0 );
        return;
    }
        
    int count = int ( 0.5 * len ( edges ) );
    for ( int i = 0; i < count; ++i )
    {
        int edgepts [ ] = sort ( array ( edges [ 2 * i ], edges [ 1 + 2 * i ] ) );
        
        int index0 = find ( loopedgepts, edgepts [ 0 ] );
        int index1 = find ( loopedgepts, edgepts [ 1 ] );
        int edgefound = index0 % 2 == 0 && index1 % 2 == 1 && index1 == 1 + index0;
        if ( !edgefound )
        {
            for ( int c = 0; c < 2; ++c )
            {
                int points [ ];
                int pt0 = edgepts [ c ];
                int pt1 = edgepts [ 1 - c ];
                int currentpt = pt0;
                int lastPoint = pt0;
                append ( points, currentpt );
                int nextPoint = GetNextPoint ( input, pt0, pt1, currentpt );
                while ( nextPoint != -1 && nextPoint != lastPoint )
                {
                    pt0 = currentpt;
                    pt1 = nextPoint;
                    currentpt = pt1;
                    append ( points, currentpt );
                    nextPoint = GetNextPoint ( input, pt0, pt1, currentpt );
                }
                
                int ptcount = len ( points ) - 1;
                for ( int f = 0; f < ptcount; ++f )
                    setedgegroup ( geoself ( ), groupname, points [ f ], points [ 1 + f ], 1 );
            }
            setedgegroup ( geoself ( ), groupname, edgepts [ 0 ], edgepts [ 1 ], 1 );
        }
    }
}

GroupEdgeLoops ( 0, chs("edge_group"), chs("group_name") );



I don't understand how it works and how it can help me to quickly selection edges along the shortest path.

I did not think that such a familiar, already practiced to the point of automatism operation could put me in a stupor in such an advanced program. It's a bit weird and I haven't found a way around it yet, sometimes I have to select the edges one at a time. It is quite slow and unproductive.

Attachments:
Screenshot_480.png (1.3 MB)

User Avatar
Member
4500 posts
Joined: 2月 2012
Offline
There are a few things:

This code only selects edge loops using the connectivity of quad polygons.

The wrangle should be set to detail run over mode.

If the result is like in your screenshot, there is disconnected polygons in that region of your geometry.

So attaching the geo here would help to identify the issue.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
User Avatar
Member
16 posts
Joined: 4月 2020
Offline
animatrix_
There are a few things:

This code only selects edge loops using the connectivity of quad polygons.

The wrangle should be set to detail run over mode.

If the result is like in your screenshot, there is disconnected polygons in that region of your geometry.

So attaching the geo here would help to identify the issue.


This is very simple geometry. There are no disconnected polygons here. I noticed that the algorithm only needs quad polygons to work correctly. I noticed that the shortest path goes to the place with the triangle, it chooses the path where the quad polygon is.

Attachments:
Test geometry 111.obj (2.8 KB)

User Avatar
Member
4500 posts
Joined: 2月 2012
Offline
petipet
animatrix_
There are a few things:

This code only selects edge loops using the connectivity of quad polygons.

The wrangle should be set to detail run over mode.

If the result is like in your screenshot, there is disconnected polygons in that region of your geometry.

So attaching the geo here would help to identify the issue.


This is very simple geometry. There are no disconnected polygons here. I noticed that the algorithm only needs quad polygons to work correctly. I noticed that the shortest path goes to the place with the triangle, it chooses the path where the quad polygon is.

I just tried your geometry, selecting the edge loops works as expected. Make sure to set the Run Over parameter to Detail.

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
User Avatar
Member
4500 posts
Joined: 2月 2012
Offline
Find Shortest Path also works in my test:

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | animatrix2k7.gumroad.com
User Avatar
Member
16 posts
Joined: 4月 2020
Offline
animatrix_
Find Shortest Path also works in my test:


Thanks.
User Avatar
Member
16 posts
Joined: 4月 2020
Offline
I found a way to correctly work the tool (True Path), you need to re-press the key (A). It's a pity that such a large community didn't know this.
Problem solved.
Thank you all for your help.

Attachments:
Screenshot_4.jpg (76.8 KB)

  • Quick Links