How to select all block references within a closed polyline

Trying to select all the blocks within a closed polyline. I would like to be able to select the polyline, and have it return all the blocks contained within that polyline. Select the red polyline, yellow objects should be selected, blue objects should not.

Dynamo_Question

One approach is to use the closed poly to make a patch surface and then use ‘does intersect’ node with block insertion converted to points and use a bool filter to select the blocks. Welcome to the community!

2 Likes

Thank you Kirk!

I got it to work by the routine below. However, it’s very slow since it has to look through every block in the drawing.

I’ve been having trouble creating a patch surface from the closed polyline.

Thanks for your help!

The ContainmentTest is very slow. Maybe there are other solutions in external packages, but you can speed up this approach as well.

Create a BoundingBox of the Polygon and see if the Block position X and Y values are greater than the Bounding Box MinPoint and smaller than the MaxPoint. Comparing numeric values is much faster than a ContainmentTest.

The Blocks that are inside the BoundingBox can be processed in the ContainmentTest function, and because you already skipped lots of the Blocks, the remaining will process much faster.

2 Likes

Thank you both, I was able to get it to work much faster by figuring out the Surface.ByPatch.

My solution below in case anyone else needs it someday.

2 Likes

@Anton_Huizinga

Add-on question to this topic, the Geometry.DoesIntersect works really well for generating a boolean statement for each block reference inside a SINGLE polyline, but is there a way to do this where it will loop through multiple polylines?

Instead of using a surface created from the PolyCurve, use a list of surfaces created from a list of surfaces. From there you have options:

  • If you only have a small count of polycurves (call the count n) and objects (call the count m) so the total test count is under say 10000 (n*m <10000) you can configure the object input to be @L1 and the list of surfaces to be @L2 so you get a ‘surface intersections test for each object. Next use a List.AnyTrue node with lacing set to @L2 and this will let you know if any of the booleans were true - that becomes the filter into the List.FilterByBoolMask node.
  • If your numbers are higher memory management will be more important for quick execution than processing speed so you should build a PolySurface from the surfaces and test for an intersection with that one polysurface against each of the objects (m tests in total) and use that for the filter.

@jacob.small
This is getting me closer to my ultimate end result, but using these levels, I am still only getting the analysis of the “0 Surface” for each instance of the block reference. Where I really need it to repeat this test for each surface individually in the list. So, in this screenshot I should end up with a list of 54 true/false statements (18 block references X 3 surfaces). Any ideas how to accomplish this? Keeping in mind that the amount of surfaces and block references will vary ongoing. This is for testing purposes, but I don’t see this exceeding the 10,000 test count you mentioned. Thank you as always!!

Swap the inputs or the list levels. You want the ‘L1 to be the objects and the L2 to be the surfaces.

Did I do this correctly? The output only gives me 3 true/false statements.

Sorry - set lacing to longest too.

You want 3 outputs per block.

1 Like

That did it - thank you!