Pick elements by either drag or click on the elements

Hi all I am trying to use the following python script to pick the objects by clicking on the objects. Reference has been taken from Node for Picking Elements in Order with Revit UI @c.poupin

I wanted include both drag and click option for the user to pick the elements exactly like the node called “Element.PickObjectsByCategory” from DynaMEP. Kindly let me know what should I add to have drag option also in the script.

import clr
import sys
import System

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

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

from System.Collections.Generic import List

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

def overridecolor(elementId, reset = False):
	t = Transaction(doc, "Selection")
	t.Start()
	view = doc.ActiveView
	color_rgb = DB.Color(30,144,255)
	gSettings = OverrideGraphicSettings()
	if not reset: 
		gSettings.SetSurfaceForegroundPatternColor(color_rgb) 
		gSettings.SetProjectionLineColor(color_rgb)
		gSettings.SetCutLineColor(color_rgb)
		gSettings.SetCutForegroundPatternColor(color_rgb)
		gSettings.SetProjectionLineWeight(8)
	view.SetElementOverrides(elementId, gSettings)
	doc.Regenerate()
	uidoc.RefreshActiveView()
	t.Commit()
	t.Dispose()
				
flag = IN[0]
selectId = []
TransactionManager.Instance.ForceCloseTransaction()
TaskDialog.Show('Selection', 'Pick elements in the desired order (re-select to Remove), hit ESC to stop picking.')
tg = TransactionGroup(doc, "Selection")
tg.Start()
	
while flag:
	try:
		ref = uidoc.Selection.PickObject(ObjectType.Element, 'Pick elements in the desired order (re-select to Remove), hit ESC to stop picking.')
		e_id = ref.ElementId
		if e_id not in selectId:
			overridecolor(e_id)
			selectId.append(e_id)
		else:
			overridecolor(e_id, True)
			selectId.pop(selectId.index(e_id))
	
	except Exception as ex:
		flag = False
		break		
tg.RollBack()
elemenSelect = [doc.GetElement(xId) for xId in selectId]
	
OUT = elemenSelect

Thanks in advance

@shashank.baganeACM try this:

mSel = IN[0]
sel = []
if mSel == True:
	ref = uidoc.Selection.PickElementsByRectangle()
	elemenSelect = ref
else:
	ref = uidoc.Selection.PickObject(ObjectType.Element)
	sel.append(ref)
	elemenSelect = [doc.GetElement(xId) for xId in sel]

OUT = elemenSelect

or this:

mSel = IN[0]
sel = []
if mSel == True:
	ref = uidoc.Selection.PickObjects(ObjectType.Element)
	elemenSelect = [doc.GetElement(xId) for xId in ref]
else:
	ref = uidoc.Selection.PickObject(ObjectType.Element)
	sel.append(ref)
	elemenSelect = [doc.GetElement(xId) for xId in sel]

OUT = elemenSelect

image

@Elie.Trad thanks for your response. No its not working I mean I am not able to select the elements by drag option.

above scripts only allow me to pick the elements but I want both the options like drag and pick elements

@shashank.baganeACM you can do only one task at a time, either pick or drag-select by specifying the Bool node, I do not know if it is possible to do both at the same time, maybe someone else knows.

1 Like

@Elie.Trad thanks for your response.

Hi @Elie.Trad I found it. I have used part of yous and part of select model elements from Datashapes package and merged it.

It works fine for me and thank you so much for giving me part of the solution. So now I can select elements either by drag or click on the elements.

Thanks once again I really appreciate that you took time for this. The script something looks like below

import clr
import sys
import System

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

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

from System.Collections.Generic import List

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

def overridecolor(elementId, reset = False):
	t = Transaction(doc, "Selection")
	t.Start()
	view = doc.ActiveView
	color_rgb = DB.Color(30,144,255)
	gSettings = OverrideGraphicSettings()
	if not reset: 
		gSettings.SetSurfaceForegroundPatternColor(color_rgb) 
		gSettings.SetProjectionLineColor(color_rgb)
		gSettings.SetCutLineColor(color_rgb)
		gSettings.SetCutForegroundPatternColor(color_rgb)
		gSettings.SetProjectionLineWeight(8)
	view.SetElementOverrides(elementId, gSettings)
	doc.Regenerate()
	uidoc.RefreshActiveView()
	t.Commit()
	t.Dispose()

class uiselectelements():

    def __init__(self,inputname,buttontext,multi):
        self.inputname = inputname
        self.buttontext = buttontext
        self.multi = multi

    def __repr__(self):
        return 'UI.SelectElements input'

class uiselectelementsofcat():

    def __init__(self,inputname,buttontext,category,multi):
        self.inputname = inputname
        self.buttontext = buttontext
        self.category = category
        self.multi = multi

    def __repr__(self):
        return 'UI.SelectElementsOfCategory input'
				
if IN[2] == [""]:
	x = uiselectelements(IN[0],IN[1],IN[3])
else:
	if isinstance(IN[2],list):
		catnames = ', '.join([UnwrapElement(i).Name for i in IN[2]])
		if IN[1] == "Select Model Element(s)":
			buttontext = 'Select %s' %(catnames)
		else:
			buttontext = IN[1]
	else:
		buttontext = IN[1]
		
	x = uiselectelementsofcat(IN[0],buttontext,IN[2],IN[3])

flag = IN[4]
selectId = []
TransactionManager.Instance.ForceCloseTransaction()
#TaskDialog.Show('Selection', 'Pick elements in the desired order (re-select to Remove), hit ESC to stop picking.')
tg = TransactionGroup(doc, "Selection")
tg.Start()

while flag:
	try:
		#ref = uidoc.Selection.PickObject(ObjectType.Element, 'Pick elements in the desired order (re-select to Remove), hit ESC to stop picking.')
		e_id = ref.ElementId
		if e_id not in selectId:
			overridecolor(e_id)
			selectId.append(e_id)
		else:
			overridecolor(e_id, True)
			selectId.pop(selectId.index(e_id))
	
	except Exception as ex:
		flag = False
		break		
tg.RollBack()
elemenSelect = [doc.GetElement(xId) for xId in selectId]

#OUT = elemenSelect
OUT = x

and the inputs are

image

Hay @Elie.Trad if you could reduce the script by removing unwanted things, please post it here the final one which will be fine tuned.

Thanks in advance

Hi,
It’s necessary to implement a ISelectionFilter class
image

import clr
import sys
import System

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

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

from System.Collections.Generic import List

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

def overridecolor(elementId, reset = False):
	t = Transaction(doc, "Selection")
	t.Start()
	view = doc.ActiveView
	color_rgb = DB.Color(30,144,255)
	gSettings = OverrideGraphicSettings()
	if not reset: 
		gSettings.SetSurfaceForegroundPatternColor(color_rgb) 
		gSettings.SetProjectionLineColor(color_rgb)
		gSettings.SetCutLineColor(color_rgb)
		gSettings.SetCutForegroundPatternColor(color_rgb)
		gSettings.SetProjectionLineWeight(8)
	view.SetElementOverrides(elementId, gSettings)
	doc.Regenerate()
	uidoc.RefreshActiveView()
	t.Commit()
	t.Dispose()

class CustomSelectionElem(ISelectionFilter):
	def __init__(self, bic_cat):
		self.bic_cat = bic_cat
	def AllowElement(self, e):
		if e.Category.Id == self.bic_cat.Id:
			return True
		else:
			return False
	def AllowReference(self, ref, point):
		return True 
				
flag = IN[0]
bic = UnwrapElement(IN[1])
selectId = []
TransactionManager.Instance.ForceCloseTransaction()
TaskDialog.Show('Selection', 'Pick elements in the desired order (re-select to Remove), hit ESC to stop picking.')
tg = TransactionGroup(doc, "Selection")
tg.Start()
	
while flag:
	try:
		ref = uidoc.Selection.PickObject(ObjectType.Element, CustomSelectionElem(bic), 'Pick elements in the desired order (re-select to Remove), hit ESC to stop picking.')
		e_id = ref.ElementId
		if e_id not in selectId:
			overridecolor(e_id)
			selectId.append(e_id)
		else:
			overridecolor(e_id, True)
			selectId.pop(selectId.index(e_id))
	
	except Exception as ex:
		flag = False
		break		
tg.RollBack()
elemenSelect = [doc.GetElement(xId) for xId in selectId]
	
OUT = elemenSelect
2 Likes