Python revit geometry to dynamo / dynamo geometry to revit


        

So far,

    # Load the Python Standard  Libraries

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

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

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

    clr.AddReference('ProtoGeometry')
    from Autodesk.DesignScript.Geometry import *


    # Current doc/app/ui
    doc = DocumentManager.Instance.CurrentDBDocument

    #Filtered element collector (all rooms)
    rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms)

    #walls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls)

    #Filter rooms to those with area more than 0 (Unplaced)
    placed , unplaced  = [], []

    for rm in rooms:
    	if rm.Area > 0:
    		placed.append(rm)		
    	else:
    		unplaced.append(rm.Id)

    #Delete unplaced rooms

    TransactionManager.Instance.EnsureInTransaction(doc)

    delrooms = [doc.Delete(i) for i in unplaced ]

    TransactionManager.Instance.TransactionTaskDone()

    #Convert Revit elements to dynamo elements

    dyrooms = placed.ToProtoType()

    # Assign your output to the OUT variable.
    OUT = placed

Hello @_Vijay
you can only convert Revit GeomtryElement to Dynamo geometry (not an element or iterable), so it is necessary to get the Revit geometry before converting it.

Here is the most common method, but there are others in Revit API

# Load the Python Standard  Libraries
import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

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

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

from System.Collections.Generic import List
# Current doc/app/ui
doc = DocumentManager.Instance.CurrentDBDocument

#Filtered element collector (all rooms)
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms)

#Filter rooms to those with area more than 0 (Unplaced)
placed , unplacedIds  = [], []

for rm in rooms:
	if rm.Area > 0:
		placed.append(rm)		
	else:
		unplacedIds.append(rm.Id)

#Delete unplaced rooms
if len(unplacedIds) > 0:
	iLstdel = List[ElementId](unplacedIds)
	TransactionManager.Instance.EnsureInTransaction(doc)
	doc.Delete(iLstdel)
	TransactionManager.Instance.TransactionTaskDone()

#Convert Revit elements to dynamo elements
outDSGeo = []
opt = Options()
for _room in placed:
	#get Revit Geometry (Inherited from Element Class)
	lstgeoRvt = _room.get_Geometry(opt)
	#transform geometry (Solid) to Dynamo Geometry
	lstgeoDS = [x.ToProtoType() for x in lstgeoRvt]
	outDSGeo.append(lstgeoDS)

# Assign your output to the OUT variable.
OUT = outDSGeo
1 Like

@c.poupin thank you for the help. I am trying to add the two more nodes here. I tried to take reference from here.

# Load the Python Standard  Libraries
import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

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


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

from System.Collections.Generic import List

clr.AddReference("DSCoreNodes")
import DSCore
from DSCore import *

# Current doc/app/ui
doc = DocumentManager.Instance.CurrentDBDocument

#Filtered element collector (all rooms)
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms)

#Filter rooms to those with area more than 0 (Unplaced)
placed , unplacedIds  = [], []

for rm in rooms:
	if rm.Area > 0:
		placed.append(rm)		
	else:
		unplacedIds.append(rm.Id)

#Delete unplaced rooms
if len(unplacedIds) > 0:
	iLstdel = List[ElementId](unplacedIds)
	TransactionManager.Instance.EnsureInTransaction(doc)
	doc.Delete(iLstdel)
	TransactionManager.Instance.TransactionTaskDone()

#Convert Revit elements to dynamo elements
outDSGeo = []
opt = Options()
for _room in placed:
	#get Revit Geometry (Inherited from Element Class)
	geoRvt = _room.get_Geometry(opt)
	#transform geometry (Solid) to Dynamo Geometry
	geoDS = [x.ToProtoType() for x in geoRvt]
	outDSGeo.append(geoDS)

#rcpoints = Solid.ComputeCentroid(fl)
#Finding center point of the room


#Flatten the outputs

placedrooms = List.Flatten(outDSGeo, 1)	
roomsolids = List.Flatten(placed, 1)
# Assign your output to the OUT variable.
OUT = placedrooms, roomsolids

Update: room tag centred done with help of @Alban_de_Chasteigner 's “Tag Set Location”.

# Load the Python Standard  Libraries
import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

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

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

from System.Collections.Generic import List

clr.AddReference("DSCoreNodes")
import DSCore
from DSCore import *

# Current doc/app/ui
doc = DocumentManager.Instance.CurrentDBDocument

#Filtered element collector (all rooms)
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms)

#Filtered element collector (all rooms tags)
roomtags = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_RoomTags).WhereElementIsNotElementType().ToElements()


	
#Filter rooms to those with area more than 0 (Unplaced)
placed , unplacedIds  = [], []

for rm in rooms:
	if rm.Area > 0:
		placed.append(rm)		
	else:
		unplacedIds.append(rm.Id)

#Delete unplaced rooms
if len(unplacedIds) > 0:
	iLstdel = List[ElementId](unplacedIds)
	TransactionManager.Instance.EnsureInTransaction(doc)
	doc.Delete(iLstdel)
	TransactionManager.Instance.TransactionTaskDone()

#Convert Revit elements to dynamo elements
outDSGeo = []
opt = Options()
for _room in placed:
	#get Revit Geometry (Inherited from Element Class)
	geoRvt = _room.get_Geometry(opt)
	#transform geometry (Solid) to Dynamo Geometry
	geoDS = [x.ToProtoType() for x in geoRvt]
	outDSGeo.append(geoDS)

#rcpoints = Solid.ComputeCentroid(fl)
#Finding center point of the room


#Relocate room tags to centre
tags = UnwrapElement(roomtags)
locations = UnwrapElement(IN[1])

TransactionManager.Instance.EnsureInTransaction(doc)
for tag,location in zip(tags,locations):
	tag.TagHeadPosition = location.ToRevitType()
TransactionManager.Instance.TransactionTaskDone()
#Flatten the outputs

placedrooms = List.Flatten(outDSGeo, 1)	
roomsolids = List.Flatten(placed, 1)

# Assign your output to the OUT variable.
OUT = roomtags

point = Autodesk.Solid.Centroid(outDSGeo);

why is not working?

Hello @_Vijay
wrong namespace and method (Autodesk.Solid namespace doesn’t exist in Revit API or Dynamo API)


try this
lstCenterPtsDs = [solid.Centroid() for solid in outDSGeo]

The node “Solid.Centroid” is under “Autodesk.DesignScript.Geometry.Solid.Centroid” or something similar. It is under the “DynamoCore” which you have referenced as “DSCore”

1 Like

# Load the Python Standard  Libraries
import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

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

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

from System.Collections.Generic import List

clr.AddReference("DSCoreNodes")
import DSCore
from DSCore import *

# Current doc/app/ui
doc = DocumentManager.Instance.CurrentDBDocument

#Filtered element collector (all rooms)
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms)

#Filtered element collector (all rooms tags)
roomtags = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_RoomTags).WhereElementIsNotElementType().ToElements()


	
#Filter rooms to those with area more than 0 (Unplaced)
placed , unplacedIds  = [], []

for rm in rooms:
	if rm.Area > 0:
		placed.append(rm)		
	else:
		unplacedIds.append(rm.Id)

#Delete unplaced rooms
if len(unplacedIds) > 0:
	iLstdel = List[ElementId](unplacedIds)
	TransactionManager.Instance.EnsureInTransaction(doc)
	doc.Delete(iLstdel)
	TransactionManager.Instance.TransactionTaskDone()

#Convert Revit elements to dynamo elements
outDSGeo = []
opt = Options()
for _room in placed:
	#get Revit Geometry (Inherited from Element Class)
	geoRvt = _room.get_Geometry(opt)
	#transform geometry (Solid) to Dynamo Geometry
	geoDS = [x.ToProtoType() for x in geoRvt]
	outDSGeo.append(geoDS)

rcpoints = [solid.Centroid() for solid in outDSGeo]

#Finding center point of the room

#point1 = Autodesk.Solid.Centroid(outDSGeo);

#Relocate room tags to centre
tags = UnwrapElement(roomtags)
locations = UnwrapElement(rcpoints)

TransactionManager.Instance.EnsureInTransaction(doc)
for tag,location in zip(tags,locations):
	tag.TagHeadPosition = location.ToRevitType()
TransactionManager.Instance.TransactionTaskDone()
#Flatten the outputs

placedrooms = List.Flatten(outDSGeo, 1)	
roomsolids = List.Flatten(placed, 1)

# Assign your output to the OUT variable.
OUT = roomtags

The warning explains that you have given it a list and not a single solid, therefore you need to iterate over this list and then input each element into this.

Check the data structure for outGeo, because it may be a list of a list and you need to iterate over this correctly to then grab the centroid.

Or you may need to do some solid joining then get its centroid, it all depends on what the solid information you are getting and how it is structured in a list.

1 Like

Hello, here are 2 solutions

opt = Options()
#a solution with extend 
outDSGeoA = []
for _room in placed:
    #get Revit Geometry (Inherited from Element Class)
    geoRvt = _room.get_Geometry(opt)
    #transform geometry (Solid) to Dynamo Geometry
    geoDS = [x.ToProtoType() for x in geoRvt]
    outDSGeoA.extend(geoDS)

rcpointsA = [solid.Centroid() for solid in outDSGeoA]

#another solution to preserve list structure 
outDSGeoB = []
for _room in placed:
    #get Revit Geometry (Inherited from Element Class)
    geoRvt = _room.get_Geometry(opt)
    #transform geometry (Solid) to Dynamo Geometry
    geoDS = [x.ToProtoType() for x in geoRvt]
    outDSGeoB.append(geoDS)

rcpointsB = [[solid.Centroid() for solid in listsolid ] for listsolid in outDSGeoB]

Note;
it’s better to learn Python first and then IronPython (environment Net) and understand Revit API :wink:

1 Like

Very thank you @c.poupin.

This is my 1st python and Revit api attempt .

You helped and motivated me lot. I will keep learning.

1 Like

I would also add that it is sometimes worth while outputting your data out of python and reading what the structure is. This will help you understand what you need to do.

If you know that the geo from revit is a list you could even possibly do the following as long as you want geoDS out as well as the centroid.

geoDS = [x.ToProtoType() for x in geoRvt]
centriodOutput = [solid.Centroid() for solid in geoDS]
outDSGeo.append([geoDS,centriodOutput])

If you only want the centroid out then i would do this

geoDS = [x.ToProtoType() for x in geoRvt]
centriodOutput = [solid.Centroid() for solid in geoDS]
outDSGeo.append(centriodOutput)
1 Like