Jump to content

Is there a way to get primitives using a point?


Recommended Posts

It can't speak for what exactly Houdini, and in this case HOM have to do under the hood, but GA is build around the idea of copy on write where it only needs to copy data when it wants to modify it. That said, when you're inside a Python SOP it needs to give you a hou.Geometry (HOM_Geometry) object. This object needs to be created somehow and populated with data that you can access and modify. Whether this is a full copy or not is probably only known by SESI.

Link to comment
Share on other sites

I think before I used a GB_PointRefArray to get connectivity information and did it that way.

You can get points connected by an edge by extending my previous code. You basically take your connected prims and check to see if if any of the primitives have an edge between the source point and each point belonging to the primitive.

IntArray connectedPoints(const GU_Detail *gdp, int pt_num)
{
    std::vector<int>            pt_nums;

    GA_Offset                   ptOff;
    GA_OffsetArray              prims;

    GA_Range                    pt_range;

    const GEO_Primitive *       prim;

    // The list of primitives in the geometry.
    const GA_PrimitiveList &prim_list = gdp->getPrimitiveList();

    ptOff = gdp->pointOffset(pt_num);

    // Get the primitives referencing the point.
    gdp->getPrimitivesReferencingPoint(prims, ptOff);

    // Build a range for those primitives.
    GA_Range pr_range(gdp->getPrimitiveMap(), prims);

    for (GA_Iterator pr_it(pr_range.begin()); !pr_it.atEnd(); ++pr_it)
    {
        prim = (GEO_Primitive *)prim_list.get(*pr_it);

        // Get the points referenced by the vertices of the primitive.
        pt_range = prim->getPointRange();

        for (GA_Iterator pt_it(pt_range.begin()); !pt_it.atEnd(); ++pt_it)
        {
            // Build an edge between the source point and this point on the
            // primitive.
            GA_Edge edge(ptOff, *pt_it);
            // If there is an edge between those 2 points, add the point
            // to the list.
            if (prim->hasEdge(edge))
                pt_nums.push_back(gdp->pointIndex(*pt_it));
        }
    }

    return pt_nums;
}

def connectedPoints(point):
    """
    Get all points that share an edge with the point.

    Args:
        point (hou.Point):
            The point whose whose connected points to find.

    Returns:
        (tuple):
            A tuple of hou.Point objects that share an edge with
            the point.

    Raises: None 

    """
    # Get the geometry the point belongs to.
    geometry = point.geometry()

    # Get a list of point numbers that are connected to the point.
    result = cpp_geo_methods.connectedPoints(geometry,
                                             point.number())

    # Glob for the points and return them.
    return geometry.globPoints(' '.join([str(i) for i in result]))

Edited by graham
Link to comment
Share on other sites

Thanks alot Graham, very helpful.

Btw when you said " It is more useful to reference geometry from another SOP where you can more easily get the geometry as read only and not have to incur any additional overhead.", how do you do that as you did in your tests? Do you mean hardcoding the geometry path inside the Python SOP just to test?

Link to comment
Share on other sites

Yes, basically instead of using geo = hou.pwd().geometry() I just used geo = hou.pwd().node("some path").geometry(). However, this is only useful if your Python SOP has no input. If you plug in your geometry into your SOP, even if you are still referencing your input node/another nodes geometry, you'll notice additional overhead even if you aren't specifically accessing the geometry of the Python SOP.

Link to comment
Share on other sites

Guest mantragora

I made also test on my spider rig model, where there are different polygons with 3,4, 5 or more points. Model = 198,610 polygons/204,156 points.

Mantragora's Python version = 10970 ms

Mantragora's inlineCpp = 234 ms

Gaham's Python = 17865 ms

Graham's inlineCpp = 40 ms

Now starts more interesting part. With Graham's trick, with accessing geometry from another node instead of directly from PythonSOP, there is one surprise:

Mantragora's Python = 14968 ms

Mantragora's inlineCpp = 198 ms

Graham's Python = 27828 ms

Graham's inlineCpp = 5 ms

Both inlineCpp versions speeded-up.. BUT... clear Python solution slowed down by almost half. Now why is that ?

Edited by mantragora
Link to comment
Share on other sites

  • 3 years later...

a quick update

 

I have have just come across this thread and had a similar problem

 

 

I managed to solve it with a vex function: pointprims

 

Returns the list of primitives containing a point.

Overview
  1. int [] pointprims(string geometry, int ptnum)

  2. int [] pointprims(int opinput, int ptnum)

Returns an empty array if failed to find the point or there are no primitives owning it.

This function returns an array of primitives that contain the given point. The order should not be relied on, but will be consistent.

geometry

The name of the geometry file to reference. Inside Houdini, this may be op:full_path_to_sop to reference a SOP.

ptnum

The point number to get a primitive from.

  • Like 1
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...