Hello,
can I use Python to set profile 1 or profile 2 in ProfileView Band to new value using Python?
I tried this:
myProfViewBands = profView.Bands
myProfViewBandsBottomItems = myProfViewBands.GetBottomBandItems()[0]
myProfViewBandsBottomItemsTest1 = myProfViewBands.GetBottomBandItems()[0].Profile1Id = newProfileid
I changed id in Dynamo
but not in Civil 3D in profile view properties
Did you ever find a way to do this with Python?
would be great to be able too
Hi @Drbohlav,
Bumping this thread.
This seems to be a key component to speed up the tedious and repetitive task of editing databands.
1 Like
Hi All
Did anyone make any progress on this?
Would be very useful
Si no me equivoco, esta resulto en una instrucción en Visual. Basic
Hi
Looking at this it may help you
2 Likes
Hola;
No creo que lo que indicas resuelve el tema, he visto esto en Visual Basic
please
write in english
The post is for changing the profile
Not addition
ok, no, the post refers to being able to change the one with a single click in all the profile views at least one profile such as the design one
Back in the day (as python and dynamo newbie, so it is messy) I was experimenting with this without succes.
I remember it ran without warnings, but it did not set the profiles as it should have, and it made the profile views buggy as well. All show label ticks disappeared for some reason, thus the show label part in the code, but after the first run the views got buddy and the labels always disappeared. So here’s that code, but use it at your own risk:
# Load the Python Standard and DesignScript Libraries
import sys
import clr
# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *
# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
from Autodesk.Civil import *
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor
civdoc = CivilApplication.ActiveDocument
def switch_bandset(pv,bandset,n,pp,sp):
global adoc
# Get the active document in the AutoCAD session:
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
#band set
if bandset == 1:
bs = civdoc.Styles.ProfileViewBandSetStyles["UNI_hsz_F&L_út+geotech"]
elif bandset == 2:
bs = civdoc.Styles.ProfileViewBandSetStyles["UNI_D_hsz"]
elif bandset == 3:
bs = civdoc.Styles.ProfileViewBandSetStyles["UNI_hsz_F&L_út+víz+geotech"]
elif bandset == 4:
bs = civdoc.Styles.ProfileViewBandSetStyles["UNI_hsz_F&LL_út+víz2+geotech"]
else:
print("Nincs ilyen típus")
for i in range(0,n):
# Get profileview id
pvId = pv[i].InternalObjectId
# Get profileID Proposed
ppId = pp[i].InternalObjectId
# Get profileID Surface
spId = sp[i].InternalObjectId
# Open Profileview
pvo = pvId.GetObject(OpenMode.ForWrite)
# Open and import Bands
pvbs = pvo.Bands
pvbs.ImportBandSetStyle(bs)
# Set BandItem properties
pvbsi = pvbs.GetBottomBandItems()
pvtsi = pvbs.GetTopBandItems()
pvbsc = pvbsi.Count
pvbscc = pvbsc-1
for k in range(0,pvbscc):
pvbsii = pvbsi.Item[k]
pvbsii.ShowLabels = True
pvbsipr = pvbsi.Item [0]
pvbsipr.Profile1Id = ppId
pvbsiex = pvbsi.Item [1]
pvbsiex.Profile1Id = spId
pvbsi = pvbs.GetBottomBandItems()
pvtsi = pvbs.GetTopBandItems()
t.Commit()
return pvtsi
pv = IN[0]
bandset = IN[1]
n = IN[2]
pp = IN[3]
sp = IN[4]
OUT = switch_bandset(pv,bandset,n,pp,sp)
1 Like
Oh thanks, maybe I try this again some time, I guess I missed the last step.
After changin the profile, the bandset should be set
“profview.Bands.SetBottomBandItems(bottomBands)”
1 Like
Had this problem for ages and finally got a working solution, really wish it hadnt been this complicated, but hopefully it helps others on the path
# Add references to the required dlls
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AeccDbMgd')
# Import references from AutoCAD
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.DatabaseServices import *
# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
# Function to find a profile by name within an alignment
def find_profile_by_name(alignment, profile_name, trans):
for prof_id in alignment.GetProfileIds():
profile = trans.GetObject(prof_id, OpenMode.ForRead)
if profile.Name == profile_name:
return prof_id
return None
# Get the current document and the civil document
adoc = Application.DocumentManager.MdiActiveDocument
civdoc = CivilApplication.ActiveDocument
# Get input values from Dynamo
alignmentNames = IN[0]
profile1Names = IN[1]
profile2Names = IN[2]
# Initialize the output variables
debugMessages = [] # List to collect debug messages
results = [] # List to collect results
# Start a transaction
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
debugMessages.append("Starting transaction...")
for alignmentName, profile1Name, profile2Name in zip(alignmentNames, profile1Names, profile2Names):
debugMessages.append(f"Processing alignment: {alignmentName}")
# Find the alignment by the input name
alignmentId = None
for oid in civdoc.GetAlignmentIds():
align = t.GetObject(oid, OpenMode.ForRead)
if align.Name == alignmentName:
alignmentId = oid
debugMessages.append(f"Alignment '{alignmentName}' found.")
break
if alignmentId is None:
debugMessages.append(f"Alignment '{alignmentName}' not found.")
results.append(None)
continue
else:
alignment = t.GetObject(alignmentId, OpenMode.ForRead)
# Find the profiles by their input names within the found alignment
profile1Id = find_profile_by_name(alignment, profile1Name, t)
profile2Id = find_profile_by_name(alignment, profile2Name, t)
debugMessages.append(f"Found profile1Id: {profile1Id}")
debugMessages.append(f"Found profile2Id: {profile2Id}")
# Get the profile view associated with the alignment
profileViewId = alignment.GetProfileViewIds()[0] # Assuming first profile view
profileView = t.GetObject(profileViewId, OpenMode.ForWrite)
debugMessages.append(f"Profile view associated with alignment '{alignmentName}' found.")
# Access and modify the band items
bottomBandItems = profileView.Bands.GetBottomBandItems()
for bandItem in bottomBandItems:
bandItem.Profile1Id = profile1Id
bandItem.Profile2Id = profile2Id
bandItem.ShowLabels = True # Ensure labels are shown
# Set the band items back to the profile view
profileView.Bands.SetBottomBandItems(bottomBandItems)
debugMessages.append("Updated band items and ensured labels are shown for the profile view.")
results.append((profile1Id, profile2Id))
# Commit the transaction to apply changes
t.Commit()
debugMessages.append("Transaction committed.")
# Assign the results to the OUT variable
OUT = (results, debugMessages)
4 Likes
Thanks @kelvin.j for sharing
Unfortunately, when I try to use the python script I got the following:
Can you help? Do we need to use the alignment and profiles itself or just their name string?
Looks like that Python code is built to iterate over matching depth lists, but you’re providing single objects. Either edit the code to ensure a list is provided for each input variable or use a three List.Create nodes before the Python node (one for each input).
1 Like