I know that maybe this issue had been discussed in thousands of topics and posts, and i did really spent a huge time trying to solve this problem before i post it here…
And i think it may be too simple for an expert person.
Simply, i need this script to help me joining this list of walls, with this list of floors.
I mean that (list 0) in walls to Join (list 0) of floors , so this wall will join 4 floors
and (list 1) of walls to Join (list 1) of floors, so this wall will join 4 floors
and so on …
so, please help
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitAPI")
import Autodesk
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
elementA = UnwrapElement(IN[0])
elementB = UnwrapElement(IN[1])
doc = DocumentManager.Instance.CurrentDBDocument
results = []
TransactionManager.Instance.EnsureInTransaction(doc)
for A in elementA:
for B in elementB:
try:
result = Autodesk.Revit.DB.JoinGeometryUtils.JoinGeometry(doc,A,B)
results.append(result)
except:
pass
TransactionManager.Instance.TransactionTaskDone()
# Assign your output to the OUT variable.
OUT = results
The problem is in your for second for loop B is a list of floors, not just a single floor. You have to go one level deeper in the list of floors
One possible solution is to use the enumerate function on the first list, then you can select the corresponding sublist in the second for loop. Here is the official documentation for enumerate:
Inside the transaction use something like this:
for i, A in enumerate(elementA):
# i is 0,1,2
for B in elementB[i]:
# elementB[i] is the corresponding sublist of floors
try:
result = Autodesk.Revit.DB.JoinGeometryUtils.JoinGeometry(doc,A,B)
results.append(result)
except:
pass
and here is the script after update, if you can please check and advice
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from System.Collections.Generic import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
items1 = UnwrapElement(IN[0])
items2 = UnwrapElement(IN[1])
def JoinGeometry(doc, item1, item2):
try:
JoinGeometryUtils.JoinGeometry(doc,item1,item2)
return True
except: return False
TransactionManager.Instance.EnsureInTransaction(doc)
for i, A in enumerate(elementA):
# i is 0,1,2
for B in elementB[i]:
# elementB[i] is the corresponding sublist of floors
try:
result = Autodesk.Revit.DB.JoinGeometryUtils.JoinGeometry(doc,A,B)
results.append(result)
except:
pass
TransactionManager.Instance.TransactionTaskDone()
If you don’t know python why don’t you do this in plain Dynamo, simply with nodes and wires, without coding? This code doesn’t contain anything not doable with OOTB nodes:
Learn about List@Level and advances list management to do the same for loop without Python, the primer has a very good tutorial about this, read full chapter 6:
There is the node Revit.Element.JoiGeometry, doing the joining. Under the hood they are doing exactly the same thing.
There is also a node called Geometry.Geometry.DoesIntersect, combine it with a FilterByBoolMask and you recreated something similar to the trycatch flow.
Dear infeeeee, i’ll tell you why i do this, and maybe you’re correct.
i’m trying to avoid using custom nodes, because i believe that if i loaded this script in another computer, it will not work properly as we must have the packages in all of our computers, and we used to corporate with another companies which i cannot update the packages on there system regularly.
However, recently i started to use pyrevit, and i learned how to run dynamo scripts from it through this genus youtuber (Run Dynamo scripts using pyRevit! - YouTube), then i thought what if i attached the custom node file with the script file in the same folder? will the script run properly even if the computer doesn’t have the full package contains this custom node…
I made some custom nodes of my own and did some test, and maybe this will work, do you think so?
anyway, if this is true, then yes, i may head back to use dynamo native nodes instead of python scripts.
However, i am trying to do some efforts to understand how python works, through such questions and issues, day by day i learn how does it work before get involved in a full course one day.
Some answers and advices not only solve my current problem, but also give me a closer perspective of how does python works.
Anyway, i appreciate your help, i don’t want to consume more time and effort from you…
All of my recommended nodes in my previous reply are OOTB, built-in nodes, not custom, so they should be included in every Revit installation, OOTB means Out Of The Box. There shouldn’t be any issue with them on any computer. If same Revit version installed, than they should work the same way.
The source code of pyrevit loading a dynamo script is available here: Github. I don’t see anything related to dependency checking, so it seems to me it doesn’t solve dependency issues, it just opens the file in Dynamo, that’s all. You should get the same problems as you would get with manually opening the file in Dynamo, unfortunately no magic happens here. I think your scripts were working because you already set up custom nodes and packages in Dynamo.
You can write python scripts in pyrevit, but they are completely unrelated of Dynamo. You can’t use dynamo packages there, but if pyrevit is installed, they should work everywhere.
If you want fully portable scripts, without any dependencies, you have 2 options:
Write full python scripts in pyrevit, but first learn python
Use only Dynamo OOTB nodes and python nodes in Dynamo. This way you can go slower, and you only need to use python if something is not possible with OOTB nodes. You can also ‘explode’ downloaded nodes and include them in your files: just edit the custom node, in the node editor copy the nodes and paste them in your script.
Dynamo should load custom nodes if they are located in the same folder as the graph; so if you copy the custom nodes into the folder which contains the graph they should load just fine. This is likely how the PyRevit solution is working.
However this may cause some copyright issues, so before doing so be careful in doing so; deploying the packages is within the terms of the copyright, and therefore shouldn’t be an issue.
Note that since about Revit 2021 Dynamo has a built in workspace references manager, which will automate the installation of packages from package manager if a user opens the graph and needs the dependency. Taking ~2 minutes to explain that to the users in the office will likely resolve the issue for the user and solve most of the concerns with this.
Thanks for the comment, and i totally agree with you, i usually use a custom node i created myself, and sometimes i go for the hard way doing things, 1st to learn doing things not only use, 2nd because i dont feel ok to just copy from others efforts.
However, for data-shapes UI nodes, they are allowing us to change the logo and so on, but i also always write on the node title (MyOfficeName - powered by data-shapes), i dont know if this is the prefect and most professional way to respect copy rights but that is what i do, while i am not selling these script at the end, they all are for our internal use just to facilitate our work.
Again thanks to you, and i am open for any advice regarding this issue