Want to select all holes in a model via a script


I’ve been asked to create a script that can find all of the holes in a model. I can do that fairly easily, however there are two issues for which I could not find a solution:

  1. When selecting cylinders using rs.IsCylinder() I’m also capturing fillets. Is there a way to only select cylinders that are complete (360°)?
  2. I would also like to capture the bottoms of the blind holes, but I really doubt that’s possible as the bottoms do not have enough uniqueness to make them different from other surfaces. Any suggestions? I don’t have much hope for this one.

Here is an illustration that may be helpful:

Thanks in advance for any suggestions.



Hi Dan, it seems you’ve asked this before some time ago here.

To get the bottoms you could find out from the edges of the cylinder if a planar surface is connected which has a circular border.



Hi Clement,

I thought this sounded familiar. I actually did a search to see if I had asked this question before but didn’t find anything.

Thank you for redirecting me back to my original question. I will look at what you posted as a response back then and see if I can make it work.

You’ve given me hope about those hole bottoms. It will take some head scratching to figure it out, but at least you’ve given me some place to start.




Hi @clement ,

I see this works on individually selected surfaces, but what if I want to select the whole model? I notice that the obj_ref.Surface() fails if trying to iterate through numerous surfaces with the message:

Message: ‘Guid’ object has no attribute ‘Surface’

I’m probably missing (or forgetting) something really basic here.




Perhaps for problem 1 you could check if there are 2 edges of the surface that are in the same position which would mean it’s a full cylinder?

(Dale Fugier) #6

Hi @DanBayn,

Do do this correctly, you’re going to need to dig through the Brep topology looking for inner loops, or where BrepLoop.LoopType == BrepLoopType.Inner. From here, there is a bit of work to determine the loop’s trim curve references edges that have an outer loop.

I’ve added a sample that lets you pick holes like the MoveHole command does. Perhaps this code is of interest to you.


– Dale


Hi @DanBayn, see if below is helpful, i’ve added a special case as well…

SelectCircularHoles.3dm (206.2 KB)
SelectCircularHoles.py (2.7 KB)



Hi @dale, @siemen and @clement,

Thank you for the suggestions and samples. This should be very helpful.

Take care,