Hi everyone,
To clarify what I’m trying to achieve:
I have an Excel file that contains a list of rooms with their names, departments, and areas. The goal of this Dynamo script is to:
- Read the Excel data (room name, department, area)
- Calculate the side length of each room using √(Area)
- Place instances of a custom family (Famille4.rfa) in Revit as a grid — not a single row — where:
- Each department gets its own row (i want it by grid)
- Rooms are placed side by side within each row, sized according to their area
- Each department is displayed in a different color
Thanks!
Tableau Excel Surfaces.xlsx (7.9 KB)
Famille4.rfa (480 KB)
Excel_to_Block.dyn (35.3 KB)
this is the result that i need
Sooo, what problem(s) did you run into?
Please review the thread on how to best get help.
How to get help on the Dynamo forums - FAQ - Dynamo
There are also a ton of topics on this exact same workflow. Please read through them for suggestions or solutions before starting a new one.
Hi There, i edited the post
Hi, I really didn’t find them. I found one similar but it’s not resolved
i used chatgpt for that code
, i hope if someone can help me without using any code
So what does the Python do?
I’ll start by saying that you don’t need Python for what I am seeing.
Don’t ask chatgpt for help here - if you think you need an AI assistant you can use the Dynamo one as the answers will be more tailored to the context (though you’re at least 7 versions of Dynamo and therefore likely 3 versions of Revit behind being able to use that - it’s time to update to 2024 (skip 2023 as the usual timeline would have support for it ending in a few months).
But before you even do that, you need to write down the steps for your process.
Something like:
- Read the excel file into Dynamo (avoid Excel if you can it’ll do more harm than good - CSV would be preferred; you can always export the excel to CSV and work with the snapshot stored therein)
- Build a list of dictionaries of the object data contained in the excel file, with a key for each heading
- Sort each list of dictionaries by area
- Calculate the side length by the square root of the area and add to the respective dictionary
- Calculate the offset by adding a small value to the area (to get a gap)
- Group the dictionaries by department
- Use a mass addition method to pull the ‘summed offset’ distance of each family in sequence and write to the respective dictionary (remember the first should be zero)
- Get the largest offset from each list of dictionaries and use that as the ‘row offset’, writing it to all dictionaries in the associated sublist
- Use the row offset + summed offset of each dictionary to create a family instance for each dictionary
- Set the width and length of the family using the side length
I’m leaving material out of this - you’ll have to think though that process before you start the build or it’ll be quite difficult to insert after the fact.
a solution with pandas, but directly in Dynamo interface
need CPython3 (Revit 2023+) or PythonNet3
import clr
import sys
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('GeometryColor')
from Modifiers import GeometryColor
clr.AddReference('DSCoreNodes')
import DSCore
from DSCore import Color as DSColor
import math
import pandas as pd
path = IN[0]
level_height = 2.0
gap = 0.3
thickness = 1
df = pd.read_csv(path) # or pd.read_excel(path)
df['Side'] = df['Area'].apply(math.sqrt)
# compute X offset by Department
# shift(1) -> start at 0
df['X_Min'] = df.groupby('Department')['Side'].transform(lambda x: x.shift(1, fill_value=0).cumsum())
# add gap
df['X_Min'] += df.groupby('Department').cumcount() * gap
# create Z offset by Department
unique_depts = df['Department'].unique()
dept_to_z = {name: i * level_height for i, name in enumerate(unique_depts)}
df['Z_Base'] = df['Department'].map(dept_to_z)
# create color by Department
df['Color'] = df['Department'].map({dept: (250, i*137%255, i*89%255, i*233%255) for i, dept in enumerate(unique_depts)})
solids = []
for index, row in df.iterrows():
ds_color = DSColor.ByARGB(*row['Color'])
#
p_min = Point.ByCoordinates(row['X_Min'], 0, row['Z_Base'])
p_max = Point.ByCoordinates(
row['X_Min'] + row['Side'],
row['Side'],
row['Z_Base'] + thickness
)
#
cube = Cuboid.ByCorners(p_min, p_max)
solids.append(GeometryColor.ByGeometryColor(cube, ds_color))
OUT = solids
Hi thank you sir, is there a way to place them in revit? so i can locate them where i want?
The output is solids, so you can take the dimensions and coordinates from the Dynamo environment and plug the length/width/height into a rectangular-extruded family’s parameters, versus making directshapes or similar. Material parameter assignment or view overrides would handle the coloring.
you can use the variables :
p_min (need to convert with the conversion method ToXyz() ) for the insertion point
row['Side'] value to set dimensions (width and length)
thickness for the height
for the insertion you need to use these methods
you also need to modify your family