Revit DirectShape from Curve

Hi!

Does anyone know if it’s possible to create a Directshape from a curve element?

GH has a specific node for it, possible in Dynamo?

I’m aware that I can create model lines from curves (lines) and group them but in this situation, I’m looking to create a singular element.

Hi!

I’m back on that topic, I have tried to use the node “ImportInstance.ByGeometry” but no success for curve elements (lines)

In the description of the node, it looks like we can input curve?

Anyone have a idea?

RVT2023_Import_Curve.dyn (62.9 KB)

Which Revit release are you in?

i’m using Revit 2023

From what I can see you’re doing more massing oriented stuff, and as such it’s likely you should be generating Revit points and curves using the ReferencePoint.ByPoint node and the Curve.ByPoints.ByReferencePoints node, however I can’t see the end goal here to know what you’re really after here.

A bit of background : I’m working in the infrastructure sector (bridges)

For now I’m doing some exploration about the creation of “linear elements” For example low LOD can be represented only by a 3d curve with a parameter for “Lenght” so it can be quantified.

I have explored your suggestion in the past about using ReferencePoint.ByPoint, but this can only work in the family editor if I’m not wrong? I would like to stay " in context" in the revit project, shared coordinates…

My real question is more about the node “ImportInstance.ByGeometry”, can it really import curves as stated in the description??

Thanks for help!

Apparently not - please submit a sample failing case (basically your rvt and dyn above) as a new issue in the Dynamo for Revit GitHub so we can get this onto that team’s radar. Issues · DynamoDS/DynamoRevit · GitHub

For what it’s worth, building in the adaptive component or massing environment will be far better for bridge work - like lightyears better. The shapes are just too complex otherwise. It’ll take some getting used to but you’ll thank me in the end, and you can still work with your coordinates without issue. I’ve shown a few companies to show ‘how’ this can work in the past, and each time they’ve gone that route as it’s more robust.

For now the Python below will generate a new family type in your project with the curves as you pass them in. It creates a new direct shape in a new family document and loads that direct shape into the file. It’s a direct shape so you won’t be able to edit it and snapping will be limited, but it gets the job done for even corkscrew geometry display. Parametric data (the length of the curve) is better in the adaptive environment though.

Edited the python below as I missed an import on copy/paste

New Direct Shape Family Instance
########################################
############## Properties ##############
########################################
__author__ = 'Jacob Small'
__version__ = '0.1.0'
__description__ = " generates a family instance from a new family type containing a direct shape consisting of the provided Dynamo geometry "
__RevitBuilds__ = "2024.1"
__DynamoBuilds__ = "2.18"
__ReleaseNotes__ = "-"
__Dependancies__ = "none"
__Copyright__ = "2024, Autodesk Inc"
__License__ = "Apache 3"



########################################
### Configure the Python environment ###
########################################
### standard imports ###
import sys #add the sys class to the Python environment so we can work with the sys objects
import clr #add the CLR (common language runtime) class to the Python environment so we can work with .net libraries
### Dynamo Revit imports ###
clr.AddReference("RevitNodes") #add Dynamo's Revit nodes library to the clr
import Revit #import Dynamo's Revit node class
clr.ImportExtensions(Revit.Elements) #add the element conversion methods to the CLR
clr.ImportExtensions(Revit.GeometryConversion) #add the geometry conversion methods to the CLR
clr.AddReference("RevitServices") #add the Revit services library to the CLR
import RevitServices #import the Revit services class to the Python environment
from RevitServices.Persistence import DocumentManager #import the document manager class to the Python environment 
from RevitServices.Transactions import TransactionManager #import the transaction manager class to the Python environment 
### Revit API imports ###
clr.AddReference("RevitAPI") #add the Revit API to the CLR
import Autodesk #add the Autodesk class to the Python environment 
from Autodesk.Revit.DB import * #import every class of the Revit API to the Python environment
from Autodesk.Revit.DB.Structure import StructuralType #import the structural type class from the structure library
### .net imports ###
clr.AddReference("System") #add the .net System library to the CLR
from System.Collections.Generic import List as NetList #imports the .net list module to the Python environment as the alias NetList



#########################################
######## Classes and Definitions ########
#########################################
def flatten_list(lst): #define the flatten_list function
    flat_list = [] #an output for the flat list
    for item in lst: #for every item in the list 
        if isinstance(item, list): #if it is a list 
            flat_list.extend(flatten_list(item)) #extend the the flatten list command to run the function on the new list 
        else: #otherwise 
            flat_list.append(item) #add the item to the flat list
    return flat_list #return the flat list 



#########################################
###### Global variables and inputs ######
#########################################
### documents and standard variables ###
doc = DocumentManager.Instance.CurrentDBDocument #the current Revit document
app = DocumentManager.Instance.CurrentUIApplication.Application #the current Revit application
TransactionManager.Instance.ForceCloseTransaction() #close any open transaction

### geometry imports and preparation ###
geometries = IN[0] #import the geometry from IN[0] of the Dynamo environment 
if not geometries.__class__ == list : geometries = [geometries] #ensure that geometries is a list, not an individual object, so that we can always prepare for a loop
geometries = flatten_list(geometries) #flatten the list
geometries = [g.ToRevitType() for g in geometries] #convert the gemoetries to Revit object types
geometries = flatten_list(geometries) #flatten the list
geometryList = NetList[GeometryObject](geometries) #crate a .net list from the revit geometries

### category import and preparation ###
category = UnwrapElement(IN[1]) #the category which the direct shape shoudl be created in. should align to the category of the template provided.
categoryId = category.Id #the ID of the category

### family template path import ###
familyTemplatePath = IN[2] #the family template to use when creating the new family

### gather existing document elements for use ###
existingFamilies = FilteredElementCollector(doc).OfClass(Family).ToElementIds() #get all existing families from the document before we make any changes
existingFamilies = NetList[ElementId] (existingFamilies) #convert the existing families list into a .net list
level = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).FirstElement() #get the first level in the document


#########################################
####### build and load the family #######
#########################################
familyDoc = app.NewFamilyDocument(familyTemplatePath) #start a new family document
familyTransaction = Transaction(familyDoc, "new direct shape") #create a transaction in the new family document
familyTransaction.Start() #start the family document transaction
directShape = DirectShape.CreateElement(familyDoc,categoryId) #create the new direct shape
directShape.AppendShape(geometryList) #append the geomtry to it
familyTransaction.Commit() #commit hte family document transaction
familyDoc.LoadFamily(doc) #load the family document into the active project
familyDoc.Close(False) #cloase the family document


#########################################
######### create a new instance #########
#########################################
docTransaction = Transaction(doc, "new family instance") #create a transaction in the document
docTransaction.Start() #start the transaction in the document
families = FilteredElementCollector(doc).OfClass(Family).Excluding(existingFamilies).ToElements() #get any new families
familySymbols = [doc.GetElement(i) for family in families for i in family.GetFamilySymbolIds() ] #get the family symbols (types) from the new families
[i.Activate() for i in familySymbols] #activate the family symbols (types) so we can create an instance
familyInstances = [doc.Create.NewFamilyInstance(XYZ(0,0,0), i, level, StructuralType.NonStructural) for i in familySymbols] #create an instance of the new family types
docTransaction.Commit() #comit the transaction



#########################################
##### Return the results to Dynamo ######
#########################################
OUT = familyInstances #return the new family instance into the Dynamo environment
2 Likes

thanks for that python code work great!

100% agree, we have a nice library of adaptive components for the volumetric items.

I was thinking about what you propose erlier about using the Curve.ByPoints.ByReferencePoints node, can it be possible to feed a python code with a collection of points and use those points to create a spline in the adaptive environment, assuming I’m feeding the appropriate template?

Yes, and in fact that is likely the best path forward… we’ll that plus a dozen or so other features to flesh things all the way out.

Great thanks for the answer. I will explore that.

In the python you share would it be possible to skip the creation of the family instance and insert the directshape directly in the project?

Yes - modify the code so the creation of the direct shape happens directly in the project.

I don’t recommend this as there is no way to add ANY parameters or other data to the form. It’s just something you can see at that point.

Modify the code, works like a charm!

adding the data to a project parameter…

RVT2023_Import_Curve_Python.dyn (62.3 KB)

thank you very much for the help!!!