Python - Delete Elements Created & Recreate

Hi,
I’m writing a python script in dynamo and I want to have the script update the model and remove old elements.
I’m trying to write directly to revit by Wall.Create() .
All of the elements created in Dynamo are regenerated and not duplicated - which is what I want. The only exception is when I create an object with python via Wall.Create() . After creating anything with Wall.Create() the item does not update, but remains & another is created every time the script runs. Is there a way around this?

the part of the code that creates the wall is:

TransactionManager.Instance.EnsureInTransaction(doc)
wall_line = Line.CreateBound(lineCorridor.xyzC1, lineCorridor.xyzC2,)
wall = Wall.Create(doc, wall_line, level.Id, False)
TransactionManager.Instance.TransactionTaskDone()
OUT = wall

Thank you for any input.

Hey,

You might find this interesting… https://github.com/DynamoDS/Dynamo/wiki/Python-0.6.3-to-0.7.x-Migration

Hope that helps,

Mark

2 Likes

Thank you @Mark.Ackerley. I really appreciate your time.
If I’m reading the github correctly, I need to identify my revit output with the class - .ToDSType(False)
I’m taking this to mean:

OUT = wall.ToDSType(False)

This produces the same result ie walls are produced and left in place despite running the script again.
I’ve also tried integrating the call into a class I’m writing, but this also produces the same result. See below:

image

I’m using Dyanmo 1.3 if that makes a difference.

Thank you again for anyone’s time.

Hi Mike,

No worries, apologies I’m away from my PC, how about if you do the ToDSType inside the Transaction?

Cheers,

Mark

Hi @Mark.Ackerley ,
Thanks for the suggestions. I tested a few methods yesterday & today. See below. I am putting the ToDSType in several places, but unfortunatley I am still not getting the code to only create one instance.

Thank you for any following suggestions you may have.

image

Hey,

That’s a bit odd, I’ve tried this…

import clr
clr.AddReference('RevitNodes')

import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')

import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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


doc = DocumentManager.Instance.CurrentDBDocument

baseLevel = UnwrapElement(IN[0])

pt1 = XYZ(IN[1],0,0)
pt2 = XYZ(IN[2],0,0)

TransactionManager.Instance.EnsureInTransaction(doc)

line = Line.CreateBound(pt1, pt2)
wall = Wall.Create(doc, line, baseLevel.Id, False)

TransactionManager.Instance.TransactionTaskDone()

OUT = wall.ToDSType(False)

And it updates the wall length, no deleting here…

Can you try this simple example? If not could you post all of the code?

Cheers,

Mark

@Mark.Ackerley,
Thanks for writing out your code. Your code works the way I want mine to work, unfortunately I’m still having issues. I inserted my ‘for’ loop into your code and the walls do not get deleted / moved. Each time the parameters are changed and dyanmo is ran, a new set of walls appear.
Thanks for any guidance.

import clr
clr.AddReference('RevitNodes')

import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')

import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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


doc = DocumentManager.Instance.CurrentDBDocument



baseLevel = UnwrapElement(IN[0])

pt1 = XYZ(0,0,0)
pt2 = XYZ(IN[2],0,0)
pt3 = XYZ(IN[2],IN[1],0)
pt4 = XYZ(0,IN[1],0)

pts = [pt1, pt2, pt3, pt4]
walls = []
TransactionManager.Instance.EnsureInTransaction(doc)

for n, pt in enumerate(pts):
	try:
            wall_line = Line.CreateBound(pt, pts[n+1])
	except IndexError:
            wall_line = Line.CreateBound(pt, pts[0])
	wall = Wall.Create(doc, wall_line, baseLevel.Id, False)
	walls.append(wall)


TransactionManager.Instance.TransactionTaskDone()	

OUT = wall.ToDSType(False)


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

Hmmm…

I think you’ll need another for loop after the transaction to convert them… at the minute you’re just converting wall not walls?

Hope that helps,

Mark

@Mark.Ackerley,
Thanks, & that sounds reasonable but I’ve been trying multiple ways with no success. Logically the code below would seem to work.
Also - on a side note - I’ve noticed I don’t need the "OUT = ___ " line of code and the walls will still be produced. Do you know why / can you point me in the direction of more reading on this?

Thanks again,
MikeD

import clr
clr.AddReference('RevitNodes')

import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')

import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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


doc = DocumentManager.Instance.CurrentDBDocument



baseLevel = UnwrapElement(IN[0])

pt1 = XYZ(0,0,0)
pt2 = XYZ(IN[2],0,0)
pt3 = XYZ(IN[2],IN[1],0)
pt4 = XYZ(0,IN[1],0)

pts = [pt1, pt2, pt3, pt4]
walls = []
TransactionManager.Instance.EnsureInTransaction(doc)

for n, pt in enumerate(pts):
	try:
            wall_line = Line.CreateBound(pt, pts[n+1])
	except IndexError:
            wall_line = Line.CreateBound(pt, pts[0])
	wall = Wall.Create(doc, wall_line, baseLevel.Id, False)
	walls.append(wall)


TransactionManager.Instance.TransactionTaskDone()	

for n, pt in enumerate(pts):
	try:
		wall = walls[n+1]
	except IndexError:
		wall = walls[0]
	wall = wall.ToDSType(False)
	OUT = wall

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

The reason why you don’t need the OUT for things to still be produced is because you are affecting the doc directly inside the Python (with things like transaction manager and ensureintransaction). OUT is just used so the node has some output produced that can be used within Dynamo with other nodes.

When you do a transaction and commit on the doc, that change happens to your Revit file directly and instantly.

@kennyb6,
Thank you for the information. I appreciate it. I am still trying to manipulate the walls to regenerate every time I run the script as opposed to building multiple walls every time the script runs. Would you have any advice on how to modify the code below?

Thanks,
Mike

import clr
clr.AddReference('RevitNodes')

import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')

import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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


doc = DocumentManager.Instance.CurrentDBDocument



baseLevel = UnwrapElement(IN[0])

pt1 = XYZ(0,0,0)
pt2 = XYZ(IN[2],0,0)
pt3 = XYZ(IN[2],IN[1],0)
pt4 = XYZ(0,IN[1],0)

pts = [pt1, pt2, pt3, pt4]
walls = []
TransactionManager.Instance.EnsureInTransaction(doc)

for n, pt in enumerate(pts):
	try:
            wall_line = Line.CreateBound(pt, pts[n+1])
	except IndexError:
            wall_line = Line.CreateBound(pt, pts[0])
	wall = Wall.Create(doc, wall_line, baseLevel.Id, False).ToDSType(False)
	walls.append(wall)


TransactionManager.Instance.TransactionTaskDone()	


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

I am a bit confused on what you want to accomplish. Right now your script will create a new set of walls each time Dynamo runs the Python node. But you want to delete the walls first, and then recreate them? You do not have any delete part of your code, just create.

Running a transaction in python node is different than how Dynamo typically handles element creation. Normally, Dynamo does not commit anything until the script is closed. This means that every time Dynamo runs again, the previously made things are deleted and a new set will be made.

In the Python’s transaction manager, things are committed immediately, so there is no deletion of previous runs’ elements.

@kennyb6 Thanks for the reply & your time.
I would like all my walls to “update” their length on each run. I do not want new instances of the walls on every run.
@Mark.Ackerley wrote the code below as a response to my initial question. His code operates how I want mine to operate. Each time the code runs, the wall is updated / the previous instance is no longer there. Mark said this was because of the .ToDSType(False) on the OUT command.
I’m trying to accomplish the same “update” with my loop.

import clr
clr.AddReference('RevitNodes')

import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')

import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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


doc = DocumentManager.Instance.CurrentDBDocument

baseLevel = UnwrapElement(IN[0])

pt1 = XYZ(IN[1],0,0)
pt2 = XYZ(IN[2],0,0)

TransactionManager.Instance.EnsureInTransaction(doc)

line = Line.CreateBound(pt1, pt2)
wall = Wall.Create(doc, line, baseLevel.Id, False)

TransactionManager.Instance.TransactionTaskDone()

OUT = wall.ToDSType(False)

Hey,

Umm… It works for me? Let me know if I’m missing something!

#thanks to clockwork and Archi-lab

import clr
clr.AddReference('RevitNodes')

import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')

import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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


doc = DocumentManager.Instance.CurrentDBDocument

baseLevel = UnwrapElement(IN[0])

pt1 = XYZ(0,0,0)
pt2 = XYZ(IN[2],0,0)
pt3 = XYZ(IN[2],IN[1],0)
pt4 = XYZ(0,IN[1],0)

pts = [pt1, pt2, pt3, pt4]
walls = []


TransactionManager.Instance.EnsureInTransaction(doc)

for n, pt in enumerate(pts):
    try:
        wall_line = Line.CreateBound(pt, pts[n+1])
    except IndexError:
        wall_line = Line.CreateBound(pt, pts[0])
    wall = Wall.Create(doc, wall_line, baseLevel.Id, False).ToDSType(False)
    walls.append(wall)


TransactionManager.Instance.TransactionTaskDone()

OUT = walls
1 Like

@Mark.Ackerley,

Thanks so much! This is great! It does work. The OUT is necessary in this case & what I was missing.

All the best,
Mike

1 Like