Python Script for L-System Rule based columns

ı want tree dendriform columns and ı want design the columns based on L-System rules. Each iteration will be a separate column and ı want all columns which are separate each other with iteration level will gather an grid structural plan. For doing this I’m using following code :

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

# L-system üreteci
def generate_lsystem(axiom, rules, iterations):
    result = axiom
    for i in range(iterations):
        new_result = ''
        for char in result:
            if char in rules:
                new_result += rules[char]
            else:
                new_result += char
        result = new_result
    return result

# L-system kuralları tanımlama
rules = {
    'F': 'FF+[+F-F-F]-[-F+F+F]',
    'X': 'F[+X]F'
}

# Aksiom (başlangıç durumu)
axiom = 'X'

# L-system iterasyon sayısı
iterations = 2

# L-system üretimi
lsystem_result = generate_lsystem(axiom, rules, iterations)

# Kolon geometrisi oluşturma
column_geometry = []
paths = []
stack = []
current_path = []
position = Point.Origin()
heading = Vector.ZAxis()
first_branch_position = None  # İlk dallanma noktasını tutacak değişken

for char in lsystem_result:
    if char == 'F':
        new_position = position.Add(heading)
        line = Line.ByStartPointEndPoint(position, new_position)
        current_path.append(line)
        position = new_position
    elif char == '+':
        heading = heading.Rotate(Vector.YAxis(), 65)
    elif char == '-':
        heading = heading.Rotate(Vector.YAxis(), -65)
    elif char == '[':
        if first_branch_position is None:
            first_branch_position = position  # İlk dallanma noktasını kaydet
        stack.append((position, heading, list(current_path)))
        current_path = []
    elif char == ']':
        if current_path:
            paths.append(PolyCurve.ByJoinedCurves(current_path))
        position, heading, current_path = stack.pop()
        current_path = list(current_path)
    elif char == 'X':
        pass

# Eğer bir dallanma bulunamadıysa, orijinal pozisyonu kullan
if first_branch_position is None:
    first_branch_position = Point.Origin()

# İlk dallanma noktasında profil oluşturma
profile_circle = Circle.ByCenterPointRadius(first_branch_position, 0.15)

# Her bir yol için ayrı ayrı sweep yapma
swept_solids = []
for path in paths:
    # Yolu ilk dallanma noktasına göre yeniden konumlandır
    transformed_path = path.Translate(Vector.ByTwoPoints(Point.Origin(), first_branch_position))
    swept_solids.append(profile_circle.SweepAsSolid(transformed_path))

# Çıktı
OUT = swept_solids

how can ı fix this code the way it will be work that ı’ve wrote above this code.

Have a looky at this thread: Christmas script :D

This one may help too:

how can ı turn this code for generating column heads which are each one have different iteration level and gathered gridal structures. Also I have to export this code into Revit environment as a column structure which I ve been able to change material, measures or something like that. Could you help me ?

I’d get a list of “letters” at each iteration level I wanted to use.

Then I’d decide what each letter meant.

Then I’d decide which iteration level was to go with which columns.

Then I’d translate these into instructions in Revit (A = draw 100mm pipe from x1,y1,z1 to x2,y2,z2) , (B = draw 50mm pipe from x2, y2, z2 to x3, y3, z3) etc, etc

You want all the column heads to be the same?
Your lsystem_result is only one set iteration length.

So why not create 1 column head then copy to the others?

I translated
‘F’: ‘FF+[+F-F-F]-[-F+F+F]’
into
‘F’: “FFRSRFLFLFPLSLFRFRFP”

Seems a little OTT for a column head :astonished:

In the beginning I’ve created same tree with just lines just like your did. But I couldn’t transform this line into solid geometry by sweeping or lofting lines. Cause the tree is complexing after 3 iteration and it didn’t generate. Then I ask to Chatgpt for necessiated fixes and it gave me that code after 10-15 times trying. But still I couldn’t make it.

The code you placed seemed to place all the geometry in 1-2 places.

I’d be wary of creating a lot of individual solid geometry in Revit.

How about getting the lines in Dynamo for 1 column head (I’d keep it very simple to start with).
Sending those to a family and creating sweeps along the lines.

Then you’ve got a family to place in Revit, not 1000 elements.

It sounds logical actually. Could you send me this all code with nodes ? And addition to this, could you tell me about how can I export this lines to Revit Family Environment ?

I recommend you look into the TSpline tools, which you can call in Python or via nodes. If you haven’t used them before I recommend starting with the node version for now - the methods have a LOT of complex inputs and you’ll likely get lost trying to configure things otherwise. The nodes can be enabled by going into your Dynamo preferences. The resulting geometry will likely only move into your host application as a mesh after conversion, but it’ll likely look a lot better too.

I’ve investigated right now the T-Spline tool. I’m wondering If you rewrite my all code for enable to using this technic. Cause I don’t want to keep going with nodes I just want to get everything inside PythonScript.

Do we have a contract I can log hours against? If not feel free to reach out to my employer to arrange for custom code production.

1 Like

I’m new to Dynamo, Python and here and ı was just looking for a urgent help for my troubles. Sorry but I thought this forum services are intended to reach to all over the world to help each learner, starter, student, employer, employees by experts.
Thanks for your time and advice.

As noted here, there are some guidelines in terms of how to get help efficiently. How to get help on the Dynamo forums

Two of your posts in a row came across as “do my work for me” (see #7) rather than “help me learn”.

In the topic of 'help me learn", there is Python which Alien posted a link to above. From there you will have lines. Those lines can be used to build a TSpline surface using the TSplineSurface.BuildPipes node. There are 13 inputs into that node and only one of them is clear from what you have (the curves list).

Many of us provide full solutions when we have time. Sadly we all have our own deadlines and workload so it’s on the individually to build up the base solution. Short of what you got from chat GPT I haven’t seen any of that. While I am able to spare enough time to say “you can get around the issue you noted above by outputting lines and using this tool you might not have known about” I can’t build a solution for you today.

Exactly the same way I’ve shown in the screen grab and that is in the code I posted the link to earlier.

Happy Dynamoing :slight_smile:

You’re right. Thanks for supports both of you. I’ll be careful next time. I just want learn and that’s all ı want. Searching for internet sources for doing this is my only way to achieve my goal cause I have no supervisor or advicer or employer or ınstructor to help me. I’m all alone and believe me I just searching for information with all of my pation for learning.
Happy Dynamoing too you… :slight_smile:

1 Like

For what it’s worth, the GitHub linked in Alien’s first linked post (here) has a pretty good tree building graph which can generate the lines quite readily. You can then use those as the curves input of the BuildPipes TSpline node.

Once you have an understanding of that and how you would move the results into your Revit model you can start to consider using Python exclusively. Jumping directly into Python will make it much harder to understand though.

Good luck with the exploration and let us know how it goes!

This is looking great!

After FamilyType.ByGeometry do you see a family in the structural columns section of your project browser called “Dendrilform column”? If so try creating an instance of that manually, or via the Dynamo environment by using a FamilyInstance constructor (in the Dynamo library expand “Revit”, then “Elements”, then “FamilyInstance”, then look at your options for constructors which is the green + sign and green line). If that doesn’t work you can check the options for placing columns via Dynamo as well.

Can you preview the “FamilyType.ByGeometry” data?

image