Help Retrieving Line Pattern Settings from Object Styles

I have been trying to retrieve a selected categories’ Object Style line pattern setting. See image below. I have searched this forum many times over and have not yet found any post that provides a solution. I greatly appreciate any help or guidance anyone has to offer.

LinePatterns

2 Likes

Please read this post and see note 7. How to get help on the Dynamo forums

I am only going to give you minimal information:

You need to look into the revit sdk, but do note that the api for this only got added into revit 2017.

I have coded something that was all in python that gets/sets this information but it was all python orientated(below video of it running) I currently have no plan on releasing this script.

1 Like

I apologize if it came across as if I was looking for someone else to do my work. that was not my intention. I have tried to write a piece of python script to attempt to extract the information I am after. Unfortunately coding is not my strongest skill. my script gives a warning when I try to run it. See image and code below.

The Python Code:

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

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *

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

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

# Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

PipeAccessory = doc.Settings.Categories.get_Item(BuiltInCategory.OST_PipeAccessory)
PipeAccessorySubTypes = PipeAccessory.SubCategories

listNames = []
listPattern = []
for i in PipeAccessorySubTypes:
	name = i.Name
	pattern = i.GetLinePatternID()
	listNames.append(name)
	listPattern.append(pattern)
	

# End Transaction
TransactionManager.Instance.TransactionTaskDone()

OUT = PipeAccessorySubTypes, listNames, listPattern

Have you check what items you are getting from the “Pipeaccessorysubtypes” because you may be getting more than the items you see in your original box. And therefore will need to create some sort of filtering by using if statements to just do what you want on the correct elements.

You don’t really need to start a transaction for this. You can use this to get you started:

listNames = []
listPattern = []
listPatternCut = []
for i in PipeAccessorySubTypes:
	name = i.Name
	listPattern.append(i.GetLinePatternId(GraphicsStyleType.Projection))
	listPatternCut.append(i.GetLinePatternId(GraphicsStyleType.Cut))
	

OUT = listPattern, listPatternCut

Thank You for the for the help @T_Pover. I feel it has gotten me much closer to my goal. The script now runs successfully with no errors and extracts information. However, I seem unable to use the outputs from the python script. See below for image, code and attached graph. I feel I am something missing from the Python script. After doing some research I think I need to unwarp the elements. Not sure if I am on the right path or not. Again, any advice or assistance that anyone could offer would be appreciated.

GetLinePattern_Beta.dyn (8.1 KB)

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

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *

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

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


PipeAccessory = doc.Settings.Categories.get_Item(BuiltInCategory.OST_PipeAccessory)
PipeAccessorySubTypes = PipeAccessory.SubCategories

listNames = []
listPattern = []
listPatternCut = []

for i in PipeAccessorySubTypes:
	name = i.Name
	listPattern.append(i.GetLinePatternId(GraphicsStyleType.Projection))
	listPatternCut.append(i.GetLinePatternId(GraphicsStyleType.Cut))


OUT = PipeAccessorySubTypes, listPattern, listPatternCut

Not sure exactly what you are after but this will yield the pattern and graphic styles:
Apparently there’s no pattern for ‘Solid’ so that returns a null.

listNames = []
listPattern = []
patname = []
listout = []

for i in PipeAccessorySubTypes:
	name = i.Name
	listNames.append(name)
	id = i.GetLinePatternId(GraphicsStyleType.Projection)
	pat = LinePatternElement.GetLinePattern(doc,id)
	listPattern.append(pat)
	try:
		patname.append(pat.Name)
	except:
		patname.append("Solid")
		
	style = i.GetGraphicsStyle(GraphicsStyleType.Projection)
	listout.append(style)


OUT = listNames, listPattern, patname, listout

I would suggest you do the following which is a little bit more compact than @T_Pover solution

LineStyleOutput = []

#Get Solid Line Pattern ID for checking
SolidLinePatternId=LinePatternElement.GetSolidPatternId()

#Get relevant Info
for i in PipeAccessorySubTypes:
	LineStyleName = i.Name
	LineStyleWeight=i.GetLineWeight(GraphicsStyleType.Projection)
	LineStyleRGBRed=i.LineColor.Red
	LineStyleRGBGreen=i.LineColor.Green
	LineStyleRGBBlue=i.LineColor.Blue
	LineStylePatternId = i.GetLinePatternId(GraphicsStyleType.Projection)
	
	#checks if id matches solid line pattern id.
	if LineStylePatternId == SolidLinePatternId;
		LinePatternName= "Solid"
	else:
		LinePatternName=doc.GetElement(LineStylePatternId).Name
	LineStyleOutput.append(LineStyleName,LineStyleRGBRed,LineStyleRGBGreen,LineStyleRGBBlue,LineStyleWeight,LinePatternName)

OUT = LineStyleOutput

Full Code output for you to copy

#LineStyle extraction added by Brendan Cassidy    

import clr

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *

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

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


PipeAccessory = doc.Settings.Categories.get_Item(BuiltInCategory.OST_PipeAccessory)
PipeAccessorySubTypes = PipeAccessory.SubCategories

LineStyleOutput = []

#Get Solid Line Pattern ID for checking
SolidLinePatternId=LinePatternElement.GetSolidPatternId()

#Get relevant Info
for i in PipeAccessorySubTypes:
	LineStyleName = i.Name
	LineStyleWeight=i.GetLineWeight(GraphicsStyleType.Projection)
	LineStyleRGBRed=i.LineColor.Red
	LineStyleRGBGreen=i.LineColor.Green
	LineStyleRGBBlue=i.LineColor.Blue
	LineStylePatternId = i.GetLinePatternId(GraphicsStyleType.Projection)
	
	#checks if id matches solid line pattern id.
	if LineStylePatternId == SolidLinePatternId;
		LinePatternName= "Solid"
	else:
		LinePatternName=doc.GetElement(LineStylePatternId).Name
	LineStyleOutput.append(LineStyleName,LineStyleRGBRed,LineStyleRGBGreen,LineStyleRGBBlue,LineStyleWeight,LinePatternName)

OUT = LineStyleOutput

Thank you @T_Pover & @Brendan_Cassidy for your excellent responses. I am now very close to achieving my over all goal. I have been able to complete the graph I have been beta testing my concept on. The goal of this beta graph was to be able to extract the line patterns for a category/subcategory then delete all the other line patterns not used from the project. See below for image of my current graph’s workspace, current dyn file and current code. I would now like to work on allowing the python script to except a list of categories from which to pull the subcategories from. I have made several unsuccessful attempts at this. Does anyone have any suggestions on how to best accomplish this?

GetLinePattern_Beta_V2.dyn (13.0 KB)

Python Code:

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

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *

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

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


PipeAccessory = doc.Settings.Categories.get_Item(BuiltInCategory.OST_PipeAccessory)
PipeAccessorySubTypes = PipeAccessory.SubCategories

listNames = []
listPattern = []
patname = []
listout = []
listpatid = []

for i in PipeAccessorySubTypes:
	name = i.Name
	listNames.append(name)
	id = i.GetLinePatternId(GraphicsStyleType.Projection)
	pat = LinePatternElement.GetLinePattern(doc,id)
	listPattern.append(pat)
	listpatid.append(id)
	try:
		patname.append(pat.Name)
	except:
		patname.append("Solid")
		
	style = i.GetGraphicsStyle(GraphicsStyleType.Projection)
	listout.append(style)


OUT = listout, listNames, listPattern, patname, listpatid

I have been able write some code that will pull all of the categories and subcategories from the project. See code below. I am now struggling to figure out how to incorporate this into my original code.

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

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *

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

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

cats = doc.Settings.Categories
elementlist = list()

for cat in cats:
	try:
		sublist = []
		for subcat in cat.SubCategories:
			sublist.append(Revit.Elements.Category.ById(subcat.Id.IntegerValue))
		elementlist.append(sublist)
	except:
		elementlist.append(list())
		
OUT = cats, elementlist

I have unsuccessful in my attempts in trying to generate the proper Python code necessary to achieve my goal. My end goal is to be able to feed in a list of categories into the Python script and then retrieve line pattern settings for the category and it’s subcategories. Please see below for my current code and example graph. I would be grateful for anyone willing to provide me assistance and help me reach my goal. Thank you.

GetLinePattern_Beta.dyn (4.0 KB)

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

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *

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

doc = DocumentManager.Instance.CurrentDBDocument
cats = UnwrapElement(IN[0])
elementlist = list()

for cat in cats:
	try:
		sublist = []
		for subcat in cat.SubCategories:
			sublist.append(Revit.Elements.Category.ById(subcat.Id.IntegerValue))
		elementlist.append(sublist)
		
	except:
		elementlist.append(list())
		
output = []

listNames = list()
listPattern = list()
patname = list()
listout = list()
listpatid = list()
		
for i in subcat:
	name = i.Name
	listNames.append(name)
	id = i.GetLinePatternId(GraphicsStyleType.Projection)
	pat = LinePatternElement.GetLinePattern(doc,id)
	listPattern.append(pat)
	listpatid.append(id)
	try:
		patname.append(pat.Name)
	except:
		patname.append("Solid")
		
	style = i.GetGraphicsStyle(GraphicsStyleType.Projection)
	listout.append(style)
	
OUT = listout, listNames, listPattern, patname, listpatid

I happy to announce that I was finally able to achieve my goal. It took a lot of trial and error, but I did it. Thank you @T_Pover & @Brendan_Cassidy for pointing me in the right direction. I ultimately created a custom node to get the job done. Please see below for final python code and screen shot of final graph.

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

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

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

doc = DocumentManager.Instance.CurrentDBDocument
cat = UnwrapElement(IN[0])
subcat = cat.SubCategories

listNames = []
listPattern = []
patname = []
listout = []
listpatid = []

for i in subcat:
	name = i.Name
	listNames.append(name)
	id = i.GetLinePatternId(GraphicsStyleType.Projection)
	pat = LinePatternElement.GetLinePattern(doc,id)
	listPattern.append(pat)
	listpatid.append(id)
	try:
		patname.append(pat.Name)
	except:
		patname.append("Solid")
		
	style = i.GetGraphicsStyle(GraphicsStyleType.Projection)
	listout.append(style)


OUT = listout, listNames, listPattern, patname, listpatid
3 Likes

Greetings,

Thanks to everyone for posting all of this information (and code). I wanted share what I cobbled together from these posts to fit what I was trying to accomplish.

I needed to export all of the Line Patterns to an Excel file. This would then be used to facilitate DWG export settings.

Since I’m really not adept at Dynamo, I bootstrapped this solution and left it at that. So, please excuse the less-than-optimal workspace.

This takes a slightly modified version of the script above and exports the all of the Line Styles into a spreadsheet with columns for the Line Style Name, the RGB color, the Lineweight, and the Line Pattern Name.

Excel Output

Export Line Styles.dyn (24.2 KB)

Thanks again to everyone who posted code and information that got me to where I needed to go.

-Thom K.

5 Likes

Is the Get Categories node in your graph a custom node you made or is it part of a package?

Awesome Thanks for shaing