- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I can reproduce a bug in which Civil 3D throws me "Unable to create Surface" even when it really shouldn't. Here's how to reproduce on the attached DWG and the xml file ( the surface file). Note that the xml file has to be located at a folder above the DWG file.
Now try to run the below code
[CommandMethod(nameof(UnableAddSurface))]
public void UnableAddSurface()
{
Transact(tr =>
{
var civilDoc = CivilApplication.ActiveDocument;
var typicalRoadAssemblyId = civilDoc.AssemblyCollection.First();
var typicalRoadAssembly = tr.GetObject<Assembly>(typicalRoadAssemblyId);
var centerAlignment = civilDoc.GetAlignmentIds().FirstOrDefaultEntity<Alignment>(tr, OpenMode.ForWrite);
var roadProfile = centerAlignment.GetProfileIds().FirstOrDefaultEntity<Profile>(tr, OpenMode.ForWrite);
var tinSurface = civilDoc.GetSurfaceIds().FirstOrDefaultEntity<TinSurface>(tr, OpenMode.ForWrite);
var corridorSurface = AddCorridorSimple(tr, centerAlignment, roadProfile, typicalRoadAssembly);
var corridorDatum = tr.GetObject<TinSurface>(corridorSurface.SurfaceId);
});
//you need to comment out this method, and call it manually from the
//autocad command line to solve the issue
CreateTinComparisonSurfacePost();
//uncomment the below code WONT solve the issue
//Application.DocumentManager.ExecuteInCommandContextAsync(async (o) =>
//{
// CreateTinComparisonSurfacePost();
// await Task.CompletedTask;
//}, null);
}
[CommandMethod(nameof(CreateTinComparisonSurfacePost))]
public void CreateTinComparisonSurfacePost()
{
Transact(CreateTinComparisonSurfacePost);
}
private void CreateTinComparisonSurfacePost(Transaction ts)
{
var surveySurface = ActiveCivil3DDocument.GetSurfaceIds().SingleEntity<TinSurface>(ts,
ss => ss.Name.Contains("EG"));
var datumSurface = ActiveCivil3DDocument.GetSurfaceIds().SingleEntity<TinSurface>(ts,
ss => ss.Name.Contains("RoadDatum"));
var surfaceName = $"{surveySurface.Name}-{datumSurface.Name}-comparison";
var tinCompare = TinVolumeSurface.Create(surfaceName, surveySurface.ObjectId,
datumSurface.ObjectId);
}
private CorridorSurface AddCorridorSimple(Transaction tr, Alignment centerAlignment,
Profile roadProfile, Assembly typicalRoadAssembly)
{
var corridorId = CivilApplication.ActiveDocument.CorridorCollection.Add("Corr1");
var corridor = tr.GetObject<Corridor>(corridorId, OpenMode.ForWrite);
var baseLine = corridor.Baselines.Add("First Baseline", centerAlignment.ObjectId,
roadProfile.ObjectId);
baseLine.BaselineRegions.Add("Road 1 Full Region",
typicalRoadAssembly.ObjectId);
corridor.Rebuild();
var datumSurface = corridor.CorridorSurfaces.Add("RoadDatum");
datumSurface.AddLinkCode("Datum", true);
datumSurface.OverhangCorrection = OverhangCorrectionType.TopLinks;
corridor.RebuildAutomatic = false;
corridor.Rebuild();
return datumSurface;
}
private static void Transact(Action<Transaction> action)
{
var doc = Application.DocumentManager.MdiActiveDocument;
using var tr = doc.TransactionManager.StartTransaction();
action(tr);
tr.Commit();
}
public static T GetObject<T>(this Transaction ts, ObjectId objectId, OpenMode openMode = OpenMode.ForRead)
where T:DBObject
{
return ts.GetObject(objectId, openMode) as T;
}
public static T FirstOrDefaultEntity<T>(this ObjectIdCollection objectIds, Transaction ts,
OpenMode openMode = OpenMode.ForRead)
where T : DBObject
{
return FirstOrDefaultEntity<T>(objectIds, ts, openMode, o => true);
}
public static T FirstOrDefaultEntity<T>(this ObjectIdCollection objectIds,
Transaction ts, OpenMode openMode, Func<T, bool> filterFunc)
where T : DBObject
{
return FirstOrDefaultEntity(objectIds.Cast<ObjectId>(), ts, openMode, filterFunc);
}
public static T FirstOrDefaultEntity<T>(this IEnumerable<ObjectId> objectIds,
Transaction ts, OpenMode openMode, Func<T, bool> filterFunc)
where T : DBObject
{
foreach (ObjectId objectId in objectIds)
{
var theObj = ts.GetObject<T>(objectId, openMode);
if (theObj != null && filterFunc(theObj))
return theObj;
}
return null;
}
You will find that it throws you a "unable to add surface" exception.
The solution is to comment out the CreateTinComparisonSurfacePost method, and manually call it from the command line. Then the TinVolumeSurface will be created.
This seems like a bug to me?
You might think that this is similar to the one here, and by adding the
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.ExecuteInCommandContextAsync(async (o) =>
{
CreateTinComparisonSurfacePost();
await Task.CompletedTask;
}, null);
You can solve the issue. But no, even if you add it at the end of the code ( or uncomment the above code), it still won't work.
Ngu Soon Hui
##########
I'm the Benevolent Dictator for Life for MiTS Software. Read more here
I also setup Civil WHIZ in order to share what I learnt about Civil 3D
Solved! Go to Solution.