Table of Contents
This post is inspired by Autodesk employee @mooglam, who has always been very helpful — thank you!
Motivation #
This is written for the following people:
- My future self, when I need to post an API question on the Autodesk Civil 3D forum. I can simply link to this post as a supplement to my question.
- Autodesk developers who have the (mis)fortune of investigating my queries or bug reports, so they don’t have to fill in the gaps themselves.
- Other Civil 3D developers looking to add some utility methods to their repertoire.
The template for CommandMethod
#
This is the core of the method. It contains the code whose behavior I want to illustrate:
public class Cmd
{
private static CivilDocument CivilDoc => CivilApplication.ActiveDocument;
private static void Transact(Action<Transaction> action)
{
var doc = Application.DocumentManager.MdiActiveDocument;
using var tr = doc.TransactionManager.StartTransaction();
action(tr);
tr.Commit();
}
[CommandMethod(nameof(YourMethod))]
public void YourMethod()
{
Transact(()=>
{
// add your method here
}
);
}
}
The extension methods #
This is the helper methods that make the main code more readable and succinct.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using DBObject = Autodesk.AutoCAD.DatabaseServices.DBObject;
public static class CivilUtilsExtensions
{
public static T GetObject<T>(this Transaction ts, ObjectId objectId, OpenMode mode = OpenMode.ForRead)
where T : DBObject
{
return ts != null && !objectId.IsNull
? ts.GetObject(objectId, mode) as T
: null;
}
public static T FirstOrDefaultEntity<T>(this ObjectIdCollection ids, Transaction ts, OpenMode mode = OpenMode.ForRead)
where T : DBObject
=> ids.FirstOrDefaultEntity<T>(ts, mode, (t) => true);
public static T FirstOrDefaultEntity<T>(this ObjectIdCollection ids, Transaction ts, OpenMode mode, Func<T, bool> filter)
where T : DBObject
=> ids?.Cast<ObjectId>().FirstOrDefaultEntity(ts, mode, filter);
public static T FirstOrDefaultEntity<T>(this IEnumerable<ObjectId> ids, Transaction ts, OpenMode mode, Func<T, bool> filter)
where T : DBObject
{
if (ids == null || ts == null || filter == null) return null;
foreach (var id in ids)
{
var obj = ts.GetObject<T>(id, mode);
if (obj != null && filter(obj))
return obj;
}
return null;
}
public static T SingleEntity<T>(this ObjectIdCollection ids, Transaction ts, Func<T, bool> predicate)
where T : DBObject
{
return ids?
.Cast<ObjectId>()
.Select(id => ts.GetObject<T>(id))
.Where(obj => obj != null)
.SingleOrDefault(predicate);
}
}