Interesting little release by Dimitar Venkov on Github a few months ago. It is essentially a Python shell for Navisworks 2016. You install by unzipping as per instructions below. You may have heard about RevitPythonShell, but obviously this one is for Navis.

To install, simply extract the zip archive in the below folder:

%APPDATA%\Autodesk Navisworks Manage 2016\Plugins

Downloads

You can read more about the features at the main page here.

  • interactive IronPython interpreter for exploring the API
    • with syntax highlighting and autocompletion (in the console only)
    • based on the IronLab project
  • batteries included! (Python standard library is bundled as a resource in the RpsRuntime.dll)
  • full access to the .NET framework and the Navis API
  • configurable “environment” variables that can be used in your scripts
  • save “external scripts” for reuse and start collecting your awesome hacks!
  • run scripts at Navisworks startup

And some example/s are in a GitHub folder:

The Revit API is actually something pretty special. People will go on and on about how Revit needs this feature or that feature, but the fact is that you can build almost any feature you like with the API. Recently, I have been running quite a few batch operations from the scope of a federated Revit model: so I will have one RVT file, with hundreds of Revit links, and I will process them from that main federated model.

On one recent project, we had to deliver to a Client a linked dataset, with Revit link file paths resolving correctly. As you know, people work in many different IT environments, and the pathing of Revit links may vary widely.

I set up an ‘approved’ list of Revit file paths, that looked something like this:

I knew that in Dynamo with Python I could get a lot of information about linked files using the ExternalFileReference class. What I discovered during this process is that there is a TransmissionData API class that let’s you do some pretty interesting things…

You see, I was thinking I would have to set up a batch method to open this files, change the file paths, and close them. But the TransmissionData class is basically what is implemented in eTransmit for Revit – it allows you to ‘lightly touch’ the Revit file and simply change the Revit link paths, and also set a switch saying ‘this file has been transmitted’. This puts the file in an appropriate state for re-opening in the new path environment. Pretty cool huh?

Once I figured out how to implement those TransmissionData actions in Python, I just had to build a node that, running from the federated model:

  • examines each link for the links inside of it
  • replaces erroneous paths with the correct file path
  • sets the new paths to the file

I did this in the hacky way of a “counter with List.Map” in Dynamo. In the future I’ll probably fix it up to be a ‘proper’ Python script but this works for now. In about an hour it fixed the linked file paths of 600 Revit links, all with the click of a single button 🙂

You can download the main definition here:

External References FINAL

You can get the supporting nodes from GitHub here:

https://github.com/LukeyJohnson/BakeryForDynamo/tree/master/nodes

As usual, please use with care. And it is probably worth backing up your files before running something like this.

It is kinda more Python than Dynamo but hey, you get the picture 🙂

In fact, here is the Python code:

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

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

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

from System.Collections.Generic import *

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

from System import Guid

import System

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

import os.path

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

tempvalue = IN[0]
approvedFilenames = IN[1]
approvedFilepaths = IN[2]
targetfilepath = IN[5]

def stripquotes(string):
	string = string[1:-1]
	return string

transData = TransmissionData.ReadTransmissionData(tempvalue)
erefids = transData.GetAllExternalFileReferenceIds()
refdata = []
for x in erefids:
	refdata.append(transData.GetDesiredReferenceData(x))

currentpaths, currenterefType, currenterefPath, pstr = [], [], [], []

for e in refdata:
	currentpaths.append(ExternalFileReference.GetAbsolutePath(e))
	currenterefType.append(e.ExternalFileReferenceType)
	currenterefPath.append(e.PathType)
for s in currentpaths:
	pstr.append(ModelPathUtils.ConvertModelPathToUserVisiblePath(s))
	
filenames = []
for p in pstr:
	templist = os.path.split(p)
	filenames.append(templist[1])
	
newpath = []
indices = []
failpath = []
origcounter = 0
matchrefs = []
newpathtypes, newbools = [], []
pathtypevar = IN[3]
for f in filenames:
	tempindex = approvedFilenames.index(f) if f in approvedFilenames else -1
	indices.append(tempindex)
	if tempindex == -1:
		failpath.append(origcounter)
		pass
	else:
		newpath.append(ModelPathUtils.ConvertUserVisiblePathToModelPath(stripquotes(approvedFilepaths[tempindex])))
		matchrefs.append(erefids[origcounter])
		newpathtypes.append(pathtypevar)
		newbools.append(True)
	origcounter = origcounter + 1

currentfilepathstring=ModelPathUtils.ConvertModelPathToUserVisiblePath(targetfilepath)
elementcount = len(erefids)
hostfile = currentfilepathstring * elementcount
currentdata = []
#currentdata.append(transData)
currentdata.append(hostfile)
currentdata.append(erefids)
currentdata.append(refdata)
currentdata.append(currentpaths)
currentdata.append(currenterefType)
currentdata.append(currenterefPath)
currentdata.append(pstr)
currentdata.append(filenames)

newdata = []
newdata.append(indices)
newdata.append(newpath)
newdata.append(matchrefs)
newdata.append(newpathtypes)
newdata.append(newbools)

setlength = len(newpath)
setcounter = range(setlength)
successreport = []
setdata = IN[4]
if setdata:
	for s in setcounter:
		try:
			transData.SetDesiredReferenceData(matchrefs[s], newpath[s], newpathtypes[s], newbools[s])
			successreport.append("Success setting data")
		except:
			successreport.append("Failure setting data")
else:
	successreport.append("You need to set the switch to True")

if setdata:
	try:
		transData.IsTransmitted = True
		transData.WriteTransmissionData(targetfilepath, transData)
		successreport.append("Success WRITING data")
	except:
		successreport.append("Failure WRITING data")
		
#Assign your output to the OUT variable.
OUT = successreport, currentdata, newdata
 

If you want to read more about the API methods used:

TransmissionData

ModelPathUtils

ExternalFileReference

Have you ever wondered how to convert a Revit macro into an addin? You can follow Harry’s steps over at this post.

What about getting some sample code for Python and Ruby Revit projects? From AEC DevBlog:

… the code examples are hidden in the default macro projects created by macro manager, see below image, the project is the default python project, there are several “if False” statements, if you remove the line of “if False”, uncomment and unindent 4 spaces to methods below it, the methods will become available macros and appear in the macro manager, and you will see the same “if false” in Ruby projects too:

How to find python macro exmaples

Original post: http://adndevblog.typepad.com/aec/2016/03/revitapi-how-to-find-code-examples-for-macro-of-python-or-ruby.html

You may also be interested in the Revit Python Wrapper here http://revitpythonwrapper.readthedocs.io/en/latest/

Konrad and Mostapha are working on something, and the functionality does not look shrimpy at all. Check it out:

“Mantis Shrimp is a Dynamo (Revit) and Grasshopper (Rhino) interoperability project that allows you to read Rhino’s native *.3dm file type as well as export geometry from Grasshopper. It is written in Python in form of a user objects (on Grasshopper side for exporting) and custom Python nodes (on Dynamo side for importing). It’s an OPEN SOURCE project with all of the source code available on GitHub. At the moment it’s a collaboration project between myself and Mostapha Sadeghipour.

I decided to make this project an open source for multitude of reasons but most importantly because it was written on top of Dynamo (an open source project) using OpenNurbs (an open source project) and inspired by Rhynamo (an open source project to be in December 2014), and finally I was helped along the way by Mostapha who’s almost never written anything that he didn’t like to share. I think i got the “bug” – not Ladybug – for sharing from him.

Here’s how to get started with Mantis Shrimp…”

Read the rest at:
mantis shrimp – getting started… | archi-lab

Check out the solution suggested by Andreas Dieckmann:

“I ended up using one of Python’s abilities to handle lists which is called groupby() because I did not want my head to hurt thinking about how to go about this in Dynamo… 😉
Here’s how:
  1. Sort list by X values using the method Steve explains above
  2. Sort list by Z values 
    (Notice that within each group of equal Z values, the X values retain their order from the previous sort operation)
  3. Create a list of lists with XYZ values (sublist 0) and just Z values (sublist 1)
  4. Group that list of lists by the Z values (using a custom node with some Python code inside)
  5. Extract only the list of lists of XYZs by combining two map nodes
You will need the package Group List of Lists By Key for this to work.
(For what it’s worth, I also uploaded another package called Sort List Of Lists this week which was related to that project but isn’t needed here. But it might be worth checking out, too.)”

Heads-up:
https://twitter.com/Jbenoit44/status/420673580838293504

From the github page:
uses a python script to automatically generate Revit journal files. When run, these journal files handle opening a specified model, instigating the testing plugin, and running the specified test. This document outlines the components of the Dynamo Revit Test Framework and provides examples of how to run NUnit tests against Revit from the command line.

results file is a proper nunit results file and should be able to be parsed as such by continuous integration systems like Jenkins, etc.

via

… by using a very wild script from dp Stuff!

Comes with a disclaimer:
Warning! Make sure you don’t run this script on your central model – detach it from central first. Because once the views are gone – they are GONE! Don’t tell me that I didn’t warn you – use it at your own risk.
Download Revit IronPython Shell script
via
dp Stuff: Remove Working Views With Python Shell and Revit API

I have previously posted about RevitPythonShell a number of times. In this post Dima Chiriacov gives a real-world example on using the shell to change the case of text.

There are quite a number of free add-ins which can easily change case too, like this one or this one (which also allows merging of text).

Read how to use RevitPythonShell at:
DP stuff: Convert Revit Text to Upper Case