Hi,
I’m trying to make a copy of an offset alignment. I’ve already handled the lines and the curves between them, but I’m not sure how to deal with the spirals yet.
import clr
import traceback
clr.AddReference('ProtoGeometry')
clr.AddReference('AcMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AeccDbMgd')
import Autodesk.AutoCAD.ApplicationServices as acApp
import Autodesk.AutoCAD.DatabaseServices as db
import Autodesk.AutoCAD.Geometry as geo
import Autodesk.Civil as civil
import Autodesk.Civil.ApplicationServices as civilApp
import Autodesk.Civil.DatabaseServices as civilDb
doc = acApp.Application.DocumentManager.MdiActiveDocument
civilDoc = civilApp.CivilApplication.ActiveDocument
acDb = doc.Database
input_alignment_name = IN[0]
target_alignment = IN[1]
def to_point3d(p2d):
return geo.Point3d(p2d.X, p2d.Y, 0)
def get_alignment_by_name(name, tr):
alignment_ids = civilDoc.GetAlignmentIds()
for id in alignment_ids:
alignment = tr.GetObject(id, db.OpenMode.ForRead)
if alignment.Name == name:
return alignment
return None
def clear_alignment_entities(alignment, tr):
count = alignment.Entities.Count
for i in reversed(range(count)):
alignment.Entities.RemoveAt(i)
def copy_alignment_entities(source_alignment, target_alignment, tr):
unsupported_types = []
entityid_type_log = []
for i in range(source_alignment.Entities.Count):
ent = source_alignment.Entities[i]
prev_ent = source_alignment.Entities[i - 1] if i > 0 else None
next_ent = source_alignment.Entities[i + 1] if i < source_alignment.Entities.Count - 1 else None
if isinstance(ent, civilDb.AlignmentLine):
target_alignment.Entities.AddFixedLine(
to_point3d(ent.StartPoint),
to_point3d(ent.EndPoint)
)
elif isinstance(ent, civilDb.AlignmentArc):
if isinstance(prev_ent, civilDb.AlignmentLine) and isinstance(next_ent, civilDb.AlignmentLine):
try:
target_alignment.Entities.AddFixedCurve(
to_point3d(ent.StartPoint),
to_point3d(ent.EndPoint),
ent.Radius,
ent.Clockwise
)
except Exception as ex:
unsupported_types.append(f"{ent.GetType().Name} (error: {str(ex)})")
elif isinstance(prev_ent, civilDb.AlignmentSpiral) and isinstance(next_ent, civilDb.AlignmentSpiral):
try:
prev_id = ent.EntityBefore
next_id = ent.EntityAfter
spiral1_param = prev_ent.A
spiral2_param = next_ent.A
radius = ent.Radius
sp_type = civilDb.SpiralParamType.AValue
spiral_def = prev_ent.SpiralDefinition
target_alignment.Entities.AddFreeSCS(
prev_id,
next_id,
spiral1_param,
spiral2_param,
sp_type,
radius,
spiral_def
)
except Exception as ex:
unsupported_types.append(f"Error AddFreeSCS: {str(ex)}")
else:
unsupported_types.append("Arc ignored - not between tangents or spirals")
else:
unsupported_types.append(ent.GetType().Name)
if unsupported_types:
notice = "Entities not copied: " + ", ".join(set(unsupported_types))
else:
notice = "All entities copied successfully."
return notice, entityid_type_log
tr = acDb.TransactionManager.StartTransaction()
try:
original_alignment = get_alignment_by_name(input_alignment_name, tr)
destination_alignment = tr.GetObject(target_alignment.InternalObjectId, db.OpenMode.ForWrite)
if original_alignment and destination_alignment:
clear_alignment_entities(destination_alignment, tr)
notice, entity_types = copy_alignment_entities(original_alignment, destination_alignment, tr)
OUT = f"Alignment '{destination_alignment.Name}' successfully updated.\n{notice}"
else:
OUT = "Original or destination alignment not found."
tr.Commit()
except Exception as e:
OUT = f"Error executing script:\n{traceback.format_exc()}"
finally:
tr.Dispose()
I get the following error:
Entities not copied: AlignmentSpiral
Error AddFreeSCS: No method matches given arguments for AddFreeSCS:
(<class 'int'>, <class 'int'>, <class 'float'>, <class 'float'>, <class 'int'>, <class 'float'>, <class 'int'>)