graham Posted June 25, 2012 Share Posted June 25, 2012 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. Quote Link to comment Share on other sites More sharing options...
graham Posted June 25, 2012 Share Posted June 25, 2012 (edited) 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 June 25, 2012 by graham Quote Link to comment Share on other sites More sharing options...
magneto Posted June 25, 2012 Author Share Posted June 25, 2012 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? Quote Link to comment Share on other sites More sharing options...
graham Posted June 25, 2012 Share Posted June 25, 2012 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. Quote Link to comment Share on other sites More sharing options...
magneto Posted June 25, 2012 Author Share Posted June 25, 2012 Thanks alot man, I understand your technique now Quote Link to comment Share on other sites More sharing options...
Guest mantragora Posted June 25, 2012 Share Posted June 25, 2012 (edited) 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 June 26, 2012 by mantragora Quote Link to comment Share on other sites More sharing options...
rdg Posted June 25, 2012 Share Posted June 25, 2012 I think Graham's inlinecpp wrapper for getPrimitivesReferencingPoint() should be faster. So it comes to down to reading the manual first?! 1 2 Quote Link to comment Share on other sites More sharing options...
edward Posted June 28, 2012 Share Posted June 28, 2012 Well, I don't know if reading GEO_Detail.h counts as a "manual". 2 1 Quote Link to comment Share on other sites More sharing options...
glassman3d Posted October 2, 2015 Share Posted October 2, 2015 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 int [] pointprims(string geometry, int ptnum) 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. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.