Bulk applying LinePattern to multiple GraphicsStyle

python
api
bimorph

#1

Hi

I’m trying to automate some Line Style generation for template creation.

I have a basic graph working which takes an Excel sheet and generates new Line Styles (‘GraphicsStyle’ items) using a Bimorph node. Unfortunately, the Bimorph node does not allow the user to specify a Line Pattern (‘LinePatternElement’) for the GraphicsStyle.

I built a second, simpler, graph to apply Line Patterns to existing Line Styles and I have it 90% of the way there, I think. I’m not very experiences in Python but a complete API novice so I’m a little stumped by the code requirements and the precise meanings of some of the terms.

This is the application test graph.

It’s completing the script for each instance passed through if I comment out lines 40 & 41. But 40 gives this error message:

Error

Here’s my code.

Python Script v1.py (1.5 KB)

This seems to be some of the process in Design Script (I think):

Unfortunately, I’m just not familiar enough with the background processes and wrapping/unwrapping elements etc. or Design Script generally to get it to work.

Any help would be greatly appreciated.

Also, if anyone has any idea how to assign ‘Solid’ (the Revit built-in value) as a pattern (the error at the bottom of the Generate … graph), or any thoughts on the API language required to automating the generation of Line Patterns themselves, that’s my next project and it would be very welcome too. I’ve not built it yet but I’m pretty confident I can get a graph to pass sequential dash/gap requirements to a Python script.

Thanks as always for the great resource and community that is the DynamoBIM forum!

(first time uploading attachments - I hope I’ve managed)


#2

The attribute is SetLinePatternId and requires the Id of the line pattern. Give that a try.


#3

Hi Nick

Thanks for the response. I’ve tried a few things with this pointer.

I amended the code to:

patternID = linePatternElement.GetLinePatternId

where linePatternElement is LinePatternElement that I haven’t unwrapped. This was trying to get the ID from the LinePatternElement object I passed to the script.

AttributeError: ‘LinePatternElement’ object has no attribute ‘GetLinePatternId’

I then stopped trying to resolve the pattern ID issue inside the script and instead I passed it patternID - an integer from an Element.Id node outside the script:

unwrappedGraphicsStyle.SetLinePatternId(patternID)

AttributeError: ‘GraphicsStyle’ object has no attribute ‘SetLinePatternId’

It doesn’t seem to matter if it is wrapped or not - I used unwrapping as I had copied some code from elsewhere for another task looking to pull information from families.

Maybe I am misunderstanding but surely each ‘Line Style’ element (which I understand to be GraphicsStyle) must store a value for LinePatternElement (‘Line Pattern’)?

Interestingly, I’ve just run the graph with some additional check nodes: Object.Type, Category.Id, Category.Name on the outputs from the Bimorph node and they’re not listing as ‘GraphicsStyle’ as expected - they’re listing as Revit.Elements.UnknownElement

[Edit: I’ve just twigged the error messages are in fact picking it up as a GraphicsStyle object]

Object Types

As before, any guidance welcome.


#4

Following Jeremy’s example I was able to get it to work for a newly created graphics style but I get the same error when trying the same method on an existing graphics style. I’ll have to keep looking.


#5

SetLinePatternId is a method that takes two inputs and is a member of the Category class, not GraphicsStyle. GraphicsStyle instances are useful in Dynamo as Dynamo RevitNodes library provides support for them (i.e. it includes a wrapper class, whereas Category does not).

To use the GraphicsStyle then, first, get its category using the GraphicsStyleCategory property, then call the SetLinePatternId() method ensuring you satisfy the inputs linePattern.Id and GraphicsStyleType. Since LineStyles in an RVT dont have a Cut property, Projection should always be used:

graphicStyle = UnwrapElement(IN[0])
linePattern = UnwrapElement(IN[1])
# "Start" the transaction
TransactionManager.Instance.EnsureInTransaction(doc)

cat = graphicStyle.GraphicsStyleCategory
cat.SetLinePatternId(linePattern.Id, GraphicsStyleType.Projection)

# "End" the transaction
TransactionManager.Instance.TransactionTaskDone()


OUT = graphicStyle


#6

So Line Styles are more or less defined via Subcategories of Lines? I always assumed Graphic Styles drove Subcategories but it sounds like you’re saying it’s the other way around. That makes more sense with what the code is doing. Thanks for the clarification.


#7

Essentially yes, imagine it more like a tree of categories, where you have a parent category at the top of the tree (Lines) and children/sub categories (stored in the CategoryNameMap class) that spawn from it. CategoryNameMap has methods to retrieve each sub-category, which returns the ‘child’ Category instance. The GraphicsStyle is a property of the Category, which has properties to retrieve the category it refers to, and that’s the relationship between the two.


#8

Hi again

I couldn’t get your code to work - I got

NameError: name ‘GraphicsStyleType’ is not defined

With a little bit of trial and error, I managed to get it working as follows:

cat.SetLinePatternId(linePatternElement.Id, graphicsStyle.GraphicsStyleType)

This works … though it feels like I’m cheating a little. However, I noticed a separate problem (I’m about to post it separately and file a bug report). LinePatternElement.GetByName seem to delete Line Patterns as it selects them.

Can I ask did you get your original code suggestion to work, .i.e, am I missing something in my code that would have got your snippet to work without my cheat?