PickElementsByRectangle twice in another view

How can I use the PickElementsByRectangle with the same Rectangle also in another view? 2 selections
I like to do de second one automatilly.

I really like some hints in the right direction(s)

Thanks in advance

@jwroelofs ,

to select one is fine… what is actually the usecase?

this is a start:


import sys
import clr


clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *


clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager



doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
selection = uidoc.Selection #type: Selection

# 🎯 PickElemnetsbyRectangle
selected_elements = selection.PickElementsByRectangle('anything')




OUT = selected_elements

Thanks for your responce

We have one complex family (with 3 or 4 layers) that we give dimesions and annotaions in different views.
We copy the elements with the dim en anno, and than change the type. ( Most of the time less effort then complete new dim and anno)
That is the use case. So how can I get the 2 pickpoints from the frist view to use in the second. At the moment I use to select elements nodes to select (and go to the other view every time again)

So you want to select annotations which are associated to the element itself? Perhaps getting the children elements and isolating to annotations category and then the host view? Moving a selected point between views is difficult due to the change in each view’s origin.

Thanks Jacob, difficult? But possible? How can i get the xyz from the pickpoints and transfer them to the rectangle? (We select everything we see in de part of the rectangle no filter just 3 model families and the dim and anno ) the pickpoints can be to origine?

Difficult enough and my intuition says slow enough that I am not sure I would go this way.

I don’t think you even have XYZ but rather a UV if I am recalling correctly… once you have that you have to transform it from one view’s coordinate system to the other, and then use that to get the contained elements.

@jwroelofs ,

can be a workaround to use “ScopeBoxes” , to use them as a reference?

grafik

I have dependent views, crop view? Never thought about scope boxes. The views I use are exactly the same orientet. I going to try select all elements in the dependent view again (first try failed got all model right but all annotains off the Dependency)

@jacob.small I forgot about UV thanks I heard about it never used it (till now only parameters stuff)

1 Like

If the tool is always intended to be dependent this is a bit easier, as I think the coordinates for the view might align… Makes it worth consideration anyway. I’d though an error on non-dependent views are used though.

Hi,

you can use PickBox instead

here an example to get tags in all open views inside a specific region


import clr
import sys
import System

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

#import Revit APIUI namespace
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
import itertools

def gen_boundingbox(minPt, maxPt):
    """
    Return a BoundingBoxXYZ object with corrected coordinates.
    
    Parameters:
    minPt (XYZ): Minimum point of the bounding box.
    maxPt (XYZ): Maximum point of the bounding box.
    
    Returns:
    BoundingBoxXYZ: BoundingBoxXYZ object with corrected coordinates.
    """
    lst_coord = ["minPt.X", "minPt.Y", "maxPt.X", "maxPt.Y" ]
    minZ = min(minPt.Z, maxPt.Z)
    maxZ = max(minPt.Z, maxPt.Z)
    permut_lst = list(itertools.permutations(lst_coord))
    for i,j,k,l in permut_lst:
        if all([ "X" in x for x in [i,k]]):
            bbox = BoundingBoxXYZ()
            bbox.Min = XYZ(eval(i), eval(j), minZ)
            bbox.Max = XYZ(eval(k), eval(l), maxZ)
            yield bbox

out_views = []
out_tags = []
TaskDialog.Show("Selection", "Select Region")
pick_box = uidoc.Selection.PickBox(PickBoxStyle.Crossing)
for fix_box in gen_boundingbox(pick_box.Min, pick_box.Max):
    try:
        myOutLn  = Outline(fix_box.Min, fix_box.Max) 
        # check the Outline
        filterBbxInside = BoundingBoxIsInsideFilter(myOutLn)
        break
    except Exception as ex:
        print(ex)

open_views = [doc.GetElement(ui_view.ViewId) for ui_view in uidoc.GetOpenUIViews()]
for v in open_views:
    out_views.append(v)
    tags = FilteredElementCollector(doc, v.Id).OfCategory(BuiltInCategory.OST_WallTags)
    for tag in tags:
        bbxtag = tag.get_BoundingBox(v)
        tagOutLn  = Outline(
                            XYZ(bbxtag.Min.X, bbxtag.Min.Y, myOutLn.MinimumPoint.Z), 
                            XYZ(bbxtag.Max.X, bbxtag.Max.Y, myOutLn.MaximumPoint.Z)
                            ) 
        if myOutLn.ContainsOtherOutline(tagOutLn, 0.1) or myOutLn.Intersects(tagOutLn, 0.1):
            out_tags.append(tag)

OUT = out_views, out_tags
3 Likes