Does anyone know if there is a way to select all the object inside a solid?
I have a relatively simple solid that is L shaped, and so I can’t use SelBox. I also can’t use SelBoundary of the planar face, because I don’t want to select object above and below it.
depending on the situation/perspective, you might be able to do a SelVisible then Invert.
there are some other ways but that’s possibly the easiest/fastest way to try first.
Gavin, post this over in the scripting category. I’ll bet someone over there has a handy dandy one for you. At least I hope they do, 'cus I want it too. A ‘select all objects inside a selected solid volume’ script.
This is kinda complicated if you want to do it right…
Attached is a draft version done with Python, not tested much, not guaranteed…
If it works, will find points, curves, surfaces, polysurfaces and meshes that are completely enclosed by a volume - either a single surface or a polysurface. If you have meshes with a lot of points, that will be slow (I may be able to fix that later).
Let me know how/when it fails…
–Mitch
edit: Removed version previously attached, use the one below…
It is interesting that rhinoscript function rs.IsObjectSolid() does not treat closed extrusions as closed solids (cube, cylinder), which would technically be correct. Still those geometries are sort of closed bodies too:
def IsObjectSolid(object_id):
"""Verifies that an object is a closed, solid object
Parameters:
object_id: String or Guid. The identifier of an object
Returns:
True if the object is solid
False if the object is not solid
"""
rhobj = rhutil.coercerhinoobject(object_id, True, True)
if( isinstance(rhobj, Rhino.DocObjects.BrepObject) or isinstance(rhobj, Rhino.DocObjects.SurfaceObject) ):
return rhobj.Geometry.IsSolid
if( isinstance(rhobj, Rhino.DocObjects.MeshObject) ):
return rhobj.MeshGeometry.IsClosed
return False
So in order to use this function, one needs to either explode the extrusion and then join its parts (which will create a polysurface), or convert it to a brep.
Sigh, I thought I checked for extrusions… Actually I did, but I added the “is solid” check for the outer envelope at the last minute and didn’t check again.
I was just about to post another message about how painful dealing with extrusion objects still is, this will add to the list.
Attached is a revised version that should work with extrusions and has a couple of other bugfixes, let me know where it fails…
Edit: Please use the revised version further below.
Its selecting the 3 points, but not the two triangles or the text object. I know its asking a lot to find a planar curve that is right on the boundary of the solid, and likewise for the textobject. I may need to create another script to moveface each face 0.5mm in the direction of the normal first.
I manually enlarged the solid and then it found the triangles, but not the textobject.
OK, thanks for checking, the error was due to a false assumption on my part that if it was already a Brep, that sObj.ToBrep() would be transparent and just return the original Brep, instead, it errors out.
I hadn’t imagined you wanted to find text objects, I can add those - instead of meshing the text, which could be long if you have a lot of objects, I will try using the text object’s aligned bounding box and test for the 4 corners being in. There might be a few marginal cases where it will fail if it’s very close to the edge…
OK, here is a cleaned up and rationalized version with some more bells and whistles… I used it as a learning experience for some more RhinoCommon stuff.
Objects that can be found now include text objects and hatches in addition to points, curves, surfaces, polysurfaces and meshes.
Will only allow you to select a closed volume as input (custom object filter)
Hopefully should be “transparent” as concerns extrusion objects (treated like polysurfaces)
One limitation, volumes or surfaces that are coincident with (but not outside of) the outer selection envelope will not be selected. Since I am using the intersection of the objects to detect collisions, and an intersection is found if surfaces coincide, these objects get thrown out. There may be workarounds, but I think they will be a bit painful and I don’t have much time anymore…
Thanks Mitch, I really appreciate your help. That script is going to help me a ton.
I realized I don’t actually need to select the objects that are on the envelope because they are already part of the grouping that I’m using - its only extra objects for hinges, drawer runners etc that I need to capture, so it will work perfectly
Agree. Works like a charm. Added to a button immediately.
By the way: mesh has the same IsPointInside() method for checking on point inclusion, brep has. So with a little bit of work of copying parts of the current code and replacing brep.IsPointInside with its mesh counterpart, and adding an initial condition for separating the mesh instance from the rest of the code, one can get a nice additional option of checking for solid meshes too.
You’re talking about using a mesh as an outer envelope object? I had considered that, but for time reasons I gave up on the idea…
Since I use intersections to determine if the objects cross the envelope boundary, I would need to use mesh intersections. As there is no Brep-Mesh intersector, I would have to mesh all the breps. And, there is no Mesh-Curve intersector either, so NURBS curves would need to be converted to polylines. That’s when I decided to abandon the idea…
Exactly. That’s the way grasshopper’s Mesh Curve intersection works too
Do you think that would be inaccurate (converting to a polyline curve)? I think Rhino handles this conversion pretty nice.
Depends on the parameters used… I was more worried about Breps which, depending on the complexity, could take a long time to mesh. If they have a render mesh that can be extracted and used, but that’s not guaranteed.
Well, block instances are kind of a special case… They can contain (references to) any number of different types of objects; its also not possible to sub-select individual objects inside a block instance - it’s one entity…
So, it should be possible to check to see if ALL the objects inside the block are entirely inside the selection volume and select the block instance if that’s the case… Might be slow if there are a lot of objects. Is that what you are looking for?