| name | c3d-surfaces |
| description | TIN/Grid/Volume surfaces — creation, breaklines, contours, boundaries, analysis |
Civil 3D Surfaces
Use this skill when working with surface objects (TIN, Grid, Volume) - creating, modifying, querying, or analyzing surfaces.
Surface Class Hierarchy
Surface (base)
├── TinSurface - Triangulated Irregular Network
├── GridSurface - Regular grid of elevations
├── TinVolumeSurface - Volume between two TIN surfaces
└── GridVolumeSurface - Volume between two Grid surfaces
Namespace Conflict Warning
Surface exists in both Autodesk.AutoCAD.DatabaseServices and Autodesk.Civil.DatabaseServices. Use an alias:
using CivSurface = Autodesk.Civil.DatabaseServices.Surface;
Accessing Surfaces
ObjectIdCollection surfaceIds = doc.GetSurfaceIds();
foreach (ObjectId surfaceId in surfaceIds)
{
CivSurface oSurface = surfaceId.GetObject(OpenMode.ForRead) as CivSurface;
ed.WriteMessage("Surface: {0}, Type: {1}\n",
oSurface.Name, oSurface.GetType().ToString());
}
Prompt user to select a TIN surface:
PromptEntityOptions options = new PromptEntityOptions("\nSelect a TIN Surface: ");
options.SetRejectMessage("\nThe selected object is not a TIN Surface.");
options.AddAllowedClass(typeof(TinSurface), true);
PromptEntityResult result = editor.GetEntity(options);
if (result.Status == PromptStatus.OK)
return result.ObjectId;
Surface Properties
GeneralSurfaceProperties genProps = oSurface.GetGeneralProperties();
TinSurfaceProperties tinProps = ((TinSurface)oSurface).GetTinProperties();
GridSurfaceProperties gridProps = ((GridSurface)oSurface).GetGridProperties();
Querying Elevation, Slope, and Direction
double elev = oSurface.FindElevationAtXY(x, y);
double slope = oSurface.FindSlopeAtXY(x, y);
double direction = oSurface.FindDirectionAtXY(x, y);
Point3d hitPoint = oSurface.GetIntersectionPoint(startPoint, direction);
Point3dCollection crossings = oSurface.FindPointsAlongLine(lineSegment3d);
Creating Surfaces
TIN Surface (empty)
ObjectId surfaceStyleId = doc.Styles.SurfaceStyles[0];
ObjectId surfaceId = TinSurface.Create("MySurface", surfaceStyleId);
TinSurface surface = surfaceId.GetObject(OpenMode.ForWrite) as TinSurface;
Point3dCollection points = new Point3dCollection();
points.Add(new Point3d(x, y, z));
surface.AddVertices(points);
ts.Commit();
TIN Surface from .tin File
Database db = Application.DocumentManager.MdiActiveDocument.Database;
ObjectId tinSurfaceId = TinSurface.CreateFromTin(db, @"path\to\file.tin");
TIN Surface from LandXML
ObjectId surfaceId = TinSurface.CreateFromLandXML(
db,
"NewSurfaceName",
@"path\to\file.xml",
"LandXMLSurfaceName");
TIN Surface by Cropping
Create a new surface from a region of an existing surface:
ObjectId croppedId = TinSurface.CreateByCropping(
db, "CroppedSurface", srcSurfaceId,
new ObjectIdCollection(new[] { polylineId }),
new Point2d(insideX, insideY));
ObjectId croppedId = TinSurface.CreateByCropping(
db, "CroppedSurface", srcSurfaceId, point3dCollection);
ObjectId croppedId = TinSurface.CreateByCropping(
db, "CroppedSurface", srcSurfaceId, point2dCollection);
TIN Surface from Corridor Surface
ObjectId surfaceId = TinSurface.CreateFromCorridorSurface("MySurface", corridorSurface);
TIN Surface from IMX File
ObjectId surfaceId = TinSurface.CreateFromIMX(
db, surfaceStyleId, @"path\to\file.imx",
"SurfaceName", gitHash, query, doCoordSysConversion: true);
Grid Surface (empty)
ObjectId surfaceId = GridSurface.Create("MyGrid", 25, 25, 0.0, surfaceStyleId);
GridSurface surface = surfaceId.GetObject(OpenMode.ForWrite) as GridSurface;
GridLocation loc = new GridLocation(row, col);
surface.AddPoint(loc, elevation);
Grid Surface from DEM
ObjectId gridSurfaceId = GridSurface.CreateFromDEM(demFilePath, surfaceStyleId);
Volume Surface
ObjectId surfaceId = TinVolumeSurface.Create("VolSurface", baseId, comparisonId, styleId);
ObjectId surfaceId = GridVolumeSurface.Create(
"GridVolSurface", baseId, comparisonId, spacingX, spacingY, orientation, styleId);
Volume Surface Properties
TinVolumeSurface volSurface = surfaceId.GetObject(OpenMode.ForRead) as TinVolumeSurface;
volSurface.CutFactor = 1.0;
volSurface.FillFactor = 1.15;
VolumeSurfaceProperties volProps = volSurface.GetVolumeProperties();
Bounded Volume Calculation (Any Surface)
Point3dCollection polygon = new Point3dCollection();
polygon.Add(new Point3d(x1, y1, 0));
polygon.Add(new Point3d(x2, y2, 0));
polygon.Add(new Point3d(x3, y3, 0));
SurfaceVolumeInfo volInfo = oSurface.GetBoundedVolumes(polygon, datumElevation);
SurfaceVolumeInfo volInfo = oSurface.GetBoundedVolumes(polygon);
Adding Point Data
From Point Groups
TinSurface oSurface = surfaceId.GetObject(OpenMode.ForWrite) as TinSurface;
SurfaceOperationAddPointGroup op = oSurface.PointGroupsDefinition.AddPointGroup(pointGroupId);
oSurface.Rebuild();
From Point File
PointFileFormatCollection ptFileFormats =
PointFileFormatCollection.GetPointFileFormats(
HostApplicationServices.WorkingDatabase);
ObjectId ptFormatId = ptFileFormats["PENZD (space delimited)"];
oSurface.PointFilesDefinition.AddPointFile(penzdFile, ptFormatId);
From DEM Files
oSurface.DEMFilesDefinition.AddDEMFile(demFilePath);
Adding Boundaries
Boundaries are closed polygons that affect triangle visibility. Types: Data Clip, Outer, Hide, Show.
ObjectId[] boundaries = { polylineId };
TinSurface oSurface = surfaceId.GetObject(OpenMode.ForWrite) as TinSurface;
oSurface.BoundariesDefinition.AddBoundaries(
new ObjectIdCollection(boundaries),
100,
Autodesk.Civil.SurfaceBoundaryType.Outer,
true
);
oSurface.Rebuild();
Note: The rebuild icon in the GUI is NOT displayed when boundaries are modified via .NET API.
Breaklines
Standard Breakline
Adds points and recomputes triangles:
oSurface.BreaklinesDefinition.AddStandardBreaklines(
new ObjectIdCollection(lines),
1.0,
10,
5,
5
);
Non-Destructive Breakline
Does not remove triangle edges, places new points at intersections:
oSurface.BreaklinesDefinition.AddNonDestructiveBreaklines(
new ObjectIdCollection(lines), 1 );
Proximity Breakline
Uses nearest existing surface points:
oSurface.BreaklinesDefinition.AddProximityBreaklines(
new ObjectIdCollection(lines), 1 );
Import Breaklines from FLT File
oSurface.BreaklinesDefinition.ImportBreaklinesFromFile("file.flt");
Adding Contours
oSurface.ContoursDefinition.AddContours(
new ObjectIdCollection(polylineIds),
midOrdinateDistance, maximumDistance, weedingDistance, weedingAngle);
SurfaceMinimizeFlatAreaOptions flatOptions = new SurfaceMinimizeFlatAreaOptions();
oSurface.ContoursDefinition.AddContours(polyIds, midOrdDist, maxDist, weedDist, weedAngle, flatOptions);
Extracting Contours and Borders
Both TinSurface and GridSurface support contour and border extraction. These methods create AutoCAD geometry in the drawing and return the ObjectIds.
Extract Border
ObjectIdCollection borderIds = tinSurface.ExtractBorder(SurfaceExtractionSettingsType.Plan);
Extract Contours
ObjectIdCollection ids = tinSurface.ExtractContoursAt(elevation);
ObjectIdCollection ids = tinSurface.ExtractContoursAt(
elevation, ContourSmoothingType.SplineCurve, smoothFactor: 5);
ObjectIdCollection ids = tinSurface.ExtractContours(interval: 2.0);
ObjectIdCollection ids = tinSurface.ExtractContours(
interval: 2.0, ContourSmoothingType.AddVertices, smoothFactor: 3);
ObjectIdCollection ids = tinSurface.ExtractContours(
lowElev: 100.0, highElev: 200.0, interval: 5.0);
ObjectIdCollection ids = tinSurface.ExtractContours(
lowElev: 100.0, highElev: 200.0, interval: 5.0,
ContourSmoothingType.SplineCurve, smoothFactor: 4);
Extract Major/Minor Contours
ObjectIdCollection majorIds = tinSurface.ExtractMajorContours(
SurfaceExtractionSettingsType.Plan);
ObjectIdCollection minorIds = tinSurface.ExtractMinorContours(
SurfaceExtractionSettingsType.Plan);
ObjectIdCollection majorIds = tinSurface.ExtractMajorContours(
SurfaceExtractionSettingsType.Plan,
ContourSmoothingType.SplineCurve, smoothFactor: 5);
Extract Watershed and Gridded
ObjectIdCollection watershedIds = tinSurface.ExtractWatershed(
SurfaceExtractionSettingsType.Plan);
ObjectIdCollection griddedIds = tinSurface.ExtractGridded(
SurfaceExtractionSettingsType.Plan);
ContourSmoothingType Values
AddVertices - adds intermediate vertices for smoother appearance
SplineCurve - fits a spline curve through contour points
SurfaceExtractionSettingsType Values
Plan - extract for plan view
Model - extract for 3D model view
Vertex and Edge Manipulation (TIN)
TinSurface oSurface = surfaceId.GetObject(OpenMode.ForWrite) as TinSurface;
SurfaceOperationAddTinVertex op = oSurface.AddVertex(new Point2d(x, y));
SurfaceOperationAddTinVertex op = oSurface.AddVertex(new Point3d(x, y, z));
TinSurfaceVertex vertex = oSurface.FindVertexAtXY(x, y);
oSurface.MoveVertex(vertex, new Point2d(newX, newY));
oSurface.SetVertexElevation(vertex, newElevation);
oSurface.RaiseVertices(vertices, deltaElevation);
oSurface.DeleteVertex(vertex);
oSurface.DeleteVertices(vertexCollection);
TinSurfaceEdge edge = oSurface.FindEdgeAtXY(x, y);
oSurface.SwapEdge(edge);
oSurface.AddLine(vertex1, vertex2);
oSurface.DeleteLine(edge);
oSurface.DeleteLines(edgeCollection);
Grid Point Manipulation
GridSurface gridSurface = surfaceId.GetObject(OpenMode.ForWrite) as GridSurface;
gridSurface.AddPoint(new GridLocation(row, col), elevation);
gridSurface.SetPointElevation(new GridLocation(row, col), newElevation);
gridSurface.RaisePoints(locations, deltaElevation);
gridSurface.DeletePoint(new GridLocation(row, col));
gridSurface.DeletePoints(locationCollection);
Sampling Elevations
Point3dCollection pts = tinSurface.SampleElevations(pt1, pt2);
Point3dCollection pts = tinSurface.SampleElevations(curveObjectId);
Surface Operations
oSurface.RaiseSurface(deltaElevation);
oSurface.PasteSurface(otherSurfaceId);
SurfaceSimplifyOptions opts = new SurfaceSimplifyOptions();
oSurface.SimplifySurface(opts);
SurfaceMinimizeFlatAreaOptions flatOpts = new SurfaceMinimizeFlatAreaOptions();
oSurface.MinimizeFlatAreas(flatOpts);
SurfaceOperationCollection ops = oSurface.Operations;
Exporting Surfaces
Export to DEM
oSurface.ExportToDEM(
@"path\to\output.dem",
"coordinateSystemCode",
10.0,
ExportDetermineElevationType.SampleSurfaceAtGridPoint);
oSurface.ExportToDEM(
@"path\to\output.dem",
"coordinateSystemCode",
10.0,
ExportDetermineElevationType.Average,
true,
-9999.0f);
ExportDetermineElevationType Values
SampleSurfaceAtGridPoint - use the elevation at each grid point
Average - average surrounding elevations
Smoothing
Natural Neighbor Interpolation (NNI)
SurfacePointOutputOptions output = new SurfacePointOutputOptions();
output.OutputLocations = SurfacePointOutputLocationsType.Centroids;
output.OutputRegions = new Point3dCollection[] { regionPoints };
SurfaceOperationSmooth op = oSurface.SmoothSurfaceByNNI(output);
Kriging
KrigingMethodOptions krigingOpts = new KrigingMethodOptions();
krigingOpts.SemivariogramModel = KrigingSemivariogramType.Spherical;
krigingOpts.SampleVertices = oSurface.GetVerticesInsidePolylines(...);
SurfaceOperationSmooth op = oSurface.SmoothSurfaceByKriging(krigingOpts, output);
Output Location Types
EdgeMidPoints - requires Edges (array of TinSurfaceEdge)
RandomPoints - requires RandomPointsNumber and OutputRegions
Centroids - requires OutputRegions
GridBased - requires OutputRegions, GridSpacingX/Y, GridOrientation
3D Solids from TIN Surface
ObjectIdCollection solidIds = tinSurface.CreateSolidsAtDepth(depth, "LayerName", penIndex);
ObjectIdCollection solidIds = tinSurface.CreateSolidsAtFixedElevation(elevation, "LayerName", penIndex);
ObjectIdCollection solidIds = tinSurface.CreateSolidsAtSurface(bottomSurfaceId, "LayerName", penIndex);
ObjectIdCollection solidIds = tinSurface.CreateSolidsAtDepthToFile(
depth, "LayerName", penIndex, ref fileName);
Performance: Snapshots
if (oSurface.HasSnapshot)
oSurface.RemoveSnapshot();
oSurface.CreateSnapshot();
oSurface.RebuildSnapshot();
oSurface.RemoveSnapshot();
Warning: RebuildSnapshot() and CreateSnapshot() can error if surface is out-of-date. Check HasSnapshot first.
Gotchas
GetGeneralProperties() is resource-intensive - call once and reuse
- Surface must be rebuilt after boundary changes via API
- Wall breaklines cannot create perfectly vertical walls in TIN surfaces
- Contour altitude uses z-value of the FIRST point only, regardless of other vertices
CreateFromLandXML() 3-parameter overload is deprecated since Civil 2022; use the 4-parameter overload specifying the LandXML surface name
Related Skills
c3d-root-objects - Accessing surfaces through CivilDocument
c3d-profiles - Surface profiles along alignments
c3d-corridors - Corridor surfaces
c3d-catchments — Catchment areas derived from surface drainage analysis
c3d-grading — Grading groups that create and modify surfaces