As we’ve been seeing lately, Jay Peak adds some additional functionality to the Surfaces API that was missing in previous releases. One of the most requested feature was the ability to extract surface contours. In the COM API, this functionality was very rudimentary and inflexible. With the new .NET implementation, we are giving you the power, so you can work with surface contours in any way you want.
I decided to create a series of posts instead of humongous article, so it is easier to follow the samples and understand the functionality. Bear with me through the series as I explain how this functionality works.
As you probably know, the Surface object in Civil 3D can be represented by major and minor contours. You can make this contours visible and control their parameters through the Surface style. However, this doesn’t give you any information about the contours unless you extract them.
The API defines two methods to extract these contours: ‘ExtractMajorContours()’ and ‘ExtractMinorContours()’. These two methods are declared in the ‘ITerrainSurface’ interface, which is implemented by ‘TinSurface’ and ‘GridSurface’; therefore, you can extract contour information from both of them. The following example implements a command that extracts these contours from a selected surface.
C#
using System;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil;
using Autodesk.Civil.DatabaseServices;
using CivilSurface = Autodesk.Civil.DatabaseServices.Surface;
using AcadEntity = Autodesk.AutoCAD.DatabaseServices.Entity;
[assembly: CommandClass(
typeof(Autodesk.CivilizedDevelopment.SurfaceExtractContoursCommands))]
namespace Autodesk.CivilizedDevelopment
{
public class SurfaceExtractContoursCommands : SimpleDrawingCommand
{
[CommandMethod("CDS_ExtractSurfceContours")]
public void CDS_ExtractSurfceContours()
{
ObjectId surfaceId = promptForTinSurface();
if (surfaceId.IsNull)
{
write("\nNo Surface selected.");
return;
}
using (Transaction tr = startTransaction())
{
CivilSurface surface = surfaceId.GetObject(OpenMode.ForRead)
as CivilSurface;
showGeneralProperties(surface.Name,
surface.GetGeneralProperties());
ITerrainSurface terrainSurface = surface as ITerrainSurface;
if (terrainSurface != null)
{
extractMajorContours(terrainSurface);
extractMinorContours(terrainSurface);
}
tr.Commit();
}
}
private void showGeneralProperties(string name,
GeneralSurfaceProperties props)
{
_editor.WriteMessage("\nSurface name: " + name);
_editor.WriteMessage("\n- Max elevation: " +
props.MaximumElevation);
_editor.WriteMessage("\n- Min elevation: " +
props.MinimumElevation);
}
private void extractMajorContours(ITerrainSurface surface)
{
ObjectIdCollection contours = surface.ExtractMajorContours(
SurfaceExtractionSettingsType.Model);
AutoCAD.Colors.Color blue =
AutoCAD.Colors.Color.FromRgb(0, 0, 255);
customizeContours(contours, blue);
}
private void extractMinorContours(ITerrainSurface surface)
{
ObjectIdCollection contours = surface.ExtractMinorContours(
SurfaceExtractionSettingsType.Model);
AutoCAD.Colors.Color lightblue =
AutoCAD.Colors.Color.FromRgb(0, 255, 255);
customizeContours(contours, lightblue);
}
private void customizeContours(ObjectIdCollection contours,
AutoCAD.Colors.Color color)
{
foreach (ObjectId id in contours)
{
AcadEntity entity = id.GetObject(OpenMode.ForWrite)
as AcadEntity;
entity.Color = color;
}
}
private ObjectId promptForTinSurface()
{
PromptEntityOptions options = new PromptEntityOptions(
"\nSelect a Surface: ");
options.SetRejectMessage(
"\nThe selected object is not a Surface.");
options.AddAllowedClass(typeof(CivilSurface), false);
PromptEntityResult result = _editor.GetEntity(options);
if (result.Status == PromptStatus.OK)
{
// Everything is cool; we return the selected
// surface ObjectId.
return result.ObjectId;
}
return ObjectId.Null; // Indicating error.
}
}
}
VB.NET
Imports System
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.Civil
Imports Autodesk.Civil.DatabaseServices
Imports CivilSurface = Autodesk.Civil.DatabaseServices.Surface
Imports AcadEntity = Autodesk.AutoCAD.DatabaseServices.Entity
<Assembly: CommandClass(
GetType(Autodesk.CivilizedDevelopment.SurfaceExtractContoursCommands))>
Namespace Autodesk.CivilizedDevelopment
Public Class SurfaceExtractContoursCommands
Inherits SimpleDrawingCommand
<CommandMethod("CDS_ExtractSurfceContours")> _
Public Sub CDS_ExtractSurfceContours()
Dim surfaceId As ObjectId = promptForTinSurface()
If surfaceId.IsNull Then
write(vbLf & "No Surface selected.")
Return
End If
Using tr As Transaction = startTransaction()
Dim surface As CivilSurface =
TryCast(surfaceId.GetObject(OpenMode.ForRead), CivilSurface)
showGeneralProperties(surface.Name,
surface.GetGeneralProperties())
Dim terrainSurface As ITerrainSurface =
TryCast(surface, ITerrainSurface)
If terrainSurface IsNot Nothing Then
extractMajorContours(terrainSurface)
extractMinorContours(terrainSurface)
End If
tr.Commit()
End Using
End Sub
Private Sub showGeneralProperties(name As String,
props As GeneralSurfaceProperties)
_editor.WriteMessage(vbLf & "Surface name: " + name)
_editor.WriteMessage(vbLf & "- Max elevation: " +
props.MaximumElevation)
_editor.WriteMessage(vbLf & "- Min elevation: " +
props.MinimumElevation)
End Sub
Private Sub extractMajorContours(surface As ITerrainSurface)
Dim contours As ObjectIdCollection =
surface.ExtractMajorContours(SurfaceExtractionSettingsType.Model)
Dim blue As AutoCAD.Colors.Color =
AutoCAD.Colors.Color.FromRgb(0, 0, 255)
customizeContours(contours, blue)
End Sub
Private Sub extractMinorContours(surface As ITerrainSurface)
Dim contours As ObjectIdCollection =
surface.ExtractMinorContours(SurfaceExtractionSettingsType.Model)
Dim lightblue As AutoCAD.Colors.Color =
AutoCAD.Colors.Color.FromRgb(0, 255, 255)
customizeContours(contours, lightblue)
End Sub
Private Sub customizeContours(contours As ObjectIdCollection,
color As AutoCAD.Colors.Color)
For Each id As ObjectId In contours
Dim entity As AcadEntity =
TryCast(id.GetObject(OpenMode.ForWrite), AcadEntity)
entity.Color = color
Next
End Sub
Private Function promptForTinSurface() As ObjectId
Dim options As New PromptEntityOptions(
vbLf & "Select a TIN Surface: ")
options.SetRejectMessage(
vbLf & "The selected object is not a TIN Surface.")
options.AddAllowedClass(GetType(CivilSurface), False)
Dim result As PromptEntityResult = _editor.GetEntity(options)
If result.Status = PromptStatus.OK Then
' Everything is cool; we return the selected
' surface ObjectId.
Return result.ObjectId
End If
Return ObjectId.Null
' Indicating error.
End Function
End Class
End Namespace
For illustration purposes, we retrieve all the contours and edit the returned polylines to change their color. If you don’t care about keeping the polylines, you can process the information and not commit the transaction at the end, which will remove them from the drawing.
NOTE: I am showing the entire source file, so you can follow some of the using aliases I created. The name ‘Surface’ creates a conflict between the Civil API and the AutoCAD API, and I declare an alias that I use in the code. This is also true of the ‘Entity’ name.
I have a general VB.NET civil 3d question.How can I find information about civil 3d events?
I have searched the net quite a bit & can't find any info. I've looked in the object browser in VS2010 express for a project with AecBaseMgd & AeccDbMgd references into it, did a search for "event" and no events for civil 3d were returned, only autocad, etc.
Specifically, I want to handle structures in a pipe network being modified (moved, renamed, added, deleted,(& pipe connected or disconnected perhaps))
Generally, all event info (how to find it) would be usefull for future projects.
thanks.
Posted by: steve | 09/05/2012 at 07:55 AM
@steve,
The Civil 3D API does not exposes any events for Civil objects. I believe this is true of AecBaseMgd (OMF). OMF and Civil objects are quite complex with many interdependencies and use a slightly different notification system than AutoCAD to avoid circular reactors. This makes very difficult to integrate events with this notification system reliably.
Posted by: Isaac Rodriguez | 09/05/2012 at 08:02 AM