Select multiple

Have I missed it or is there not a node to manually select multiple objects from model space? I only see a node to select a single object. I found nodes to select multiple in various packages, but this seem like a really basic thing that should be in core dynamo.

I think this will be even more important if Civil 3D ever includes a Dynamo Player like Revit.

2 Likes

Hi @keith.sowinski ,

You are not alone. I wanted to have select multiple objects as well but as of now I can’t find it so end up using All Objects of Type or All Objects on Layer. :slight_smile:

All Object 2

Cheers,
Jowenn

1 Like

Sadly only Revit has this node, maybe you could ask the Dynamo developers if they could add this in an upcoming version :slight_smile:

1 Like

I’m wondering if anyone has had success doing this by using a pickfirst selection set.

Select the objects in Civil 3D, then run the Dynamo script.

1 Like
  • 1

I’m also looking for this select multiple objects. Did anyone found?

1 Like

Yes, but it is not great:

Python script: SelectImplied.dyn (4.4 KB)

It works as follows:

  • Select objects
  • Start this script

The objects are now shown in Dynamo but they need to be DesignScript objects instead of AutoCAD objects. This way you can’t do anything with it.

Also the SelectImplied only works when you open Dynamo, not in Automatic or Run mode. I think SelectImplied is not the best way to select objects. It is better to manually select objects or by a filter (object type, window, property, whatever). These functions need to be programmed off course.

This is my first attempt to write a Python script. So don’t ask me to make it better :slight_smile:

Hope it helps others to improve it.

2 Likes

Thanks Anton. I’m at a similar state. Here is my code to prompt you to select the multiple objects. Like yours, the output includes the ACAD entities, but I don’t know how to change the ACAD entities to Dynamo objects.

image

Load the Python Standard and DesignScript Libraries
import sys
import clr

# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')


# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

adoc = Application.DocumentManager.MdiActiveDocument
ed = adoc.Editor

def select_objects():
	
	global adoc
	global ed
	
	output = []
	
	with adoc.LockDocument():
		with adoc.Database as db:
			with db.TransactionManager.StartTransaction() as t:

				acSSPrompt = ed.GetSelection()
	
				if acSSPrompt.Status == PromptStatus.OK:
					acSSet = acSSPrompt.Value
					for s in acSSet:
						if s:
							obj = t.GetObject(s.ObjectId, OpenMode.ForRead)
							output.append(obj)

				t.Commit()
	return output	

OUT = select_objects()
2 Likes

Probably the safest way for now is to return the handles or the ObjectIds and use the Civil 3D Toolkit to select the objects.
image

10 Likes

That works. Thanks Paolo!

output.append(str(obj.Handle))

image

7 Likes

Good job Keith!

Thanks for figuring this out, Keith!

Awesome and thank you for sharing @keith.sowinski, @Anton_Huizinga and @Paolo_Emilio_Serra1

I’ve added a toggle option so you can select multiple objects again. :slight_smile:

Cheers,
Jowenn

7 Likes

It would be great if we can set nodes to a no-cache setting in a future release of Dynamo. The example above proves there is need for non-cachable nodes.

Thanks for this workaround!

1 Like

FYI…If you do now want to use the separate select object from handle node from the toolkit, I figured out how to do this with just the python script.

# Load the Python Standard and DesignScript Libraries
import sys
import clr

# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
clr.AddReference('AutoCADNodes')


# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

# Import references from Dynamo
from Autodesk.AutoCAD.DynamoNodes import SelectionByQuery

adoc = Application.DocumentManager.MdiActiveDocument
ed = adoc.Editor

def select_objects():
	
	global adoc
	global ed
	
	output = []
	
	with adoc.LockDocument():
		with adoc.Database as db:
			with db.TransactionManager.StartTransaction() as t:

				acSSPrompt = ed.GetSelection()
	
				if acSSPrompt.Status == PromptStatus.OK:
					acSSet = acSSPrompt.Value
					hndl = []
					for s in acSSet:
						if s:
							obj = t.GetObject(s.ObjectId, OpenMode.ForRead)
							hndl.append(str(obj.Handle))
							
				t.Commit()
	for h in hndl:
		output.append(SelectionByQuery.GetObjectByObjectHandle(h))
	return output	

if IN[0] == True:
	OUT = select_objects()
else:
	OUT = "nothing"

(IN[0] is just a bool to run the script or not)

8 Likes

I have been trying to add selection filtering to this, but I can’t figure out how to convert this C# TypedValue array creation to python.

#Create a TypedValue array to define the filter criteria
TypedValue[] acTypValAr = new TypedValue[1];
acTypValAr.SetValue(new TypedValue((int)DxfCode.Start, "CIRCLE"), 0);

This example is from the AutoCAD Developers guide

As a workaround, I’ve been filtering the selection downstream using the object DxfName. That works fine, but I think it would be more efficient to use the filtering capabilities of the selection set.

1 Like

If anyone is curious, here is how you handle the TypeValue array for the selection filter with ironpython.

include:
from System import Array

tv = TypedValue(0, dxfNames)
tva = Array[TypedValue]([tv])

Where dxfNames is a string with comma separated object types. Example: “POLYLINE,AECC_ALIGNMENT,CIRCLE”

The rest is just like the Developers Guide example.

Corrected: DXF Name, not Class Name.

3 Likes

Hello @keith.sowinski AND @zachri.jensen
Is it possible to solve the problem that appeared in the filter?
Thank you so much

# Load the Python Standard and DesignScript Libraries
import sys
import clr

# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
clr.AddReference('AutoCADNodes')

from System import Array
# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

# Import references from Dynamo
from Autodesk.AutoCAD.DynamoNodes import SelectionByQuery

adoc = Application.DocumentManager.MdiActiveDocument
ed = adoc.Editor

def select_objects():
	
	global adoc
	global ed
	
	outputQ = []
	
	with adoc.LockDocument():
		with adoc.Database as db:
			with db.TransactionManager.StartTransaction() as t:

				#acSSPrompt = ed.GetSelection()
				tv = TypedValue(0, "POLYLINE")
				tva = Array[TypedValue]([tv])
				acSSPrompt = ed.GetSelection(tva)
	
				if acSSPrompt.Status == PromptStatus.OK:
					acSSet = acSSPrompt.Value
					hndl = []
					for s in acSSet:
						if s:
							obj = t.GetObject(s.ObjectId, OpenMode.ForRead)
							hndl.append(str(obj.Handle))
							
				t.Commit()
	for h in hndl:
		outputQ.append(SelectionByQuery.GetObjectByObjectHandle(h))
	return outputQ	
OUT = select_objects()
#if IN[0] == True:
	#OUT = select_objects()
#else:
	#OUT = "nothing"

tv = TypedValue(0, "POLYLINE")
tva = Array[TypedValue]([tv])
selFltr = SelectionFilter(tva)
acSSPrompt = ed.GetSelection(selFltr)
1 Like