用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/hebackus/c3d-api-plugin --skill c3d-profiles命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Corridors, baselines, regions, assemblies, subassemblies, corridor surfaces
Custom subassembly .NET design — CorridorState, SubassemblyGenerator, targets, SATemplate
Stock-subassembly pattern catalog — need→file index, worked DrawImplement recipes, point/link/shape code reference, mined from Autodesk's 120 VB stock subassemblies
基于 SOC 职业分类
正在显示 SKILL.md
| name | c3d-profiles |
| description | Profiles (surface, layout, offset), profile views, PVIs, band sets, styles |
Use this skill when creating profiles from surfaces, building layout profiles with entities, creating profile views, or working with profile styles.
Profiles are the vertical analogue to alignments. Together, an alignment and profile represent a 3D path.
ObjectIdCollection profileIds = alignment.GetProfileIds();
foreach (ObjectId profileId in profileIds)
{
Profile profile = ts.GetObject(profileId, OpenMode.ForRead) as Profile;
ed.WriteMessage("Profile: {0}\n", profile.Name);
}
Profile profile = ts.GetObject(profileId, OpenMode.ForRead) as Profile;
// Read-only properties
double startSta = profile.StartingStation;
double endSta = profile.EndingStation;
double len = profile.Length;
double minElev = profile.ElevationMin;
double maxElev = profile.ElevationMax;
ProfileType pType = profile.ProfileType;
ObjectId alignId = profile.AlignmentId;
string dataSource = profile.DataSourceName;
double offset = profile.Offset;
// Query elevation and grade at any station
double elev = profile.ElevationAt(1000.0);
double grade = profile.GradeAt(1000.0);
Derives elevation data from a surface along an alignment path:
// ObjectId-based overload (preferred)
ObjectId profileId = Profile.CreateFromSurface(
"My Profile", alignId, surfaceId, layerId, styleId, labelSetId);
// With offset and station range
ObjectId profileId = Profile.CreateFromSurface(
"My Profile", alignId, surfaceId, layerId, styleId, labelSetId,
offset: 10.0, sampleStart: 0.0, sampleEnd: 500.0);
// String name-based overload
ObjectId profileId = Profile.CreateFromSurface(
"My Profile", doc, "Alignment Name", "Surface Name",
"Layer Name", "Style Name", "Label Set Name");
Creates an empty profile, then defines shape with entities:
// ObjectId-based overload (preferred)
ObjectId profileId = Profile.CreateByLayout(
"My Profile", alignId, layerId, styleId, labelSetId);
// String name-based overload
ObjectId profileId = Profile.CreateByLayout(
"My Profile", doc, "Alignment Name", "Layer Name",
"Style Name", "Label Set Name");
Profile oProfile = ts.GetObject(profileId, OpenMode.ForWrite) as Profile;
Extracts profile data from a corridor feature line:
ObjectId profileId = Profile.CreateFromFeatureLine(
"My Profile", corridorFeatureLine, alignId, layerId, styleId, labelSetId);
Creates a static (non-dynamic) finished ground profile from an existing profile:
// ObjectId-based
ObjectId profileId = Profile.CreateStaticFGFromProfile(
"Static Copy", srcProfileId, layerId, styleId, labelSetId);
// String name-based
ObjectId profileId = Profile.CreateStaticFGFromProfile(
"Static Copy", doc, "Source Profile", "Layer Name",
"Style Name", "Label Set Name");
Creates a profile on an offset alignment with a constant slope from the parent profile:
// ObjectId-based
ObjectId profileId = parentProfile.CreateOffsetProfileBySlope(
"Offset Profile", offsetAlignmentId, profileStyleId, slope: 0.02);
// String name-based
ObjectId profileId = parentProfile.CreateOffsetProfileBySlope(
"Offset Profile", "Offset Alignment Name", "Style Name", slope: 0.02);
// Access the offset parameters for station-based slope control
Profile.OffsetProfileParameters offsetParams = profile.OffsetParameters;
ObjectId parentProfileId = offsetParams.ParentProfileId;
ObjectId parentAlignId = offsetParams.ParentAlignmentId;
// Define variable slopes at specific stations
offsetParams.Stations = new List<Profile.OffsetProfileParametersStation>
{
new Profile.OffsetProfileParametersStation(0.0, 0.02, "Start"),
new Profile.OffsetProfileParametersStation(500.0, 0.04, "Steeper section"),
};
Profile entities define the geometry of layout profiles. Coordinates use (station, elevation) as Point2d.
// Fixed tangent between two points
Point2d startPoint = new Point2d(alignment.StartingStation, -40);
Point2d endPoint = new Point2d(758.2, -70);
ProfileTangent tangent1 = oProfile.Entities.AddFixedTangent(startPoint, endPoint);
// Fixed tangent specifying insertion after a previous entity
ProfileTangent tangent = oProfile.Entities.AddFixedTangentWithPreviousEntity(
prevEntity.EntityId, startPoint, endPoint);
// Floating tangent - attaches to an entity end and passes through a point
ProfileTangent floatTan = oProfile.Entities.AddFloatingTangent(
entityId, passPoint, EntityAttachType.End);
// Free tangent - connects two existing entities
ProfileTangent freeTan = oProfile.Entities.AddFreeTangent(
prevEntityId, nextEntityId);
// Free symmetric parabola by length (connects two entities)
oProfile.Entities.AddFreeSymmetricParabolaByLength(
tangent1.EntityId, tangent2.EntityId,
VerticalCurveType.Sag, 900.1, preferFlat: true);
// Free symmetric parabola by K value
oProfile.Entities.AddFreeSymmetricParabolaByK(
prevEntityId, nextEntityId, VerticalCurveType.Crest, k: 50.0);
// Free symmetric parabola by radius
oProfile.Entities.AddFreeSymmetricParabolaByRadius(
prevEntityId, nextEntityId, VerticalCurveType.Sag, radius: 1000.0);
// Free symmetric parabola at a PVI
oProfile.Entities.AddFreeSymmetricParabolaByPVIAndCurveLength(pvi, curveLength: 200.0);
oProfile.Entities.AddFreeSymmetricParabolaByPVIAndK(pvi, k: 50.0);
oProfile.Entities.AddFreeSymmetricParabolaByPVIAndThroughPoint(pvi, passPoint);
// Fixed symmetric parabola by three points
oProfile.Entities.AddFixedSymmetricParabolaByThreePoints(pt1, pt2, pt3);
// Fixed symmetric parabola by two points and constraint
oProfile.Entities.AddFixedSymmetricParabolaByTwoPointsAndK(pt1, pt2, VerticalCurveType.Sag, k);
oProfile.Entities.AddFixedSymmetricParabolaByTwoPointsAndRadius(pt1, pt2, VerticalCurveType.Sag, radius);
oProfile.Entities.AddFixedSymmetricParabolaByTwoPointsAndStartGrade(pt1, pt2, startGrade);
oProfile.Entities.AddFixedSymmetricParabolaByTwoPointsAndEndGrade(pt1, pt2, endGrade);
oProfile.Entities.AddFixedSymmetricParabolaByEntityEndAndThroughPoint(entityId, passPoint);
// Floating symmetric parabola (attaches to an existing entity)
oProfile.Entities.AddFloatingSymmetricParabolaByThroughPointAndK(entityId, passPoint, k, attachType);
oProfile.Entities.AddFloatingSymmetricParabolaByThroughPointAndRadius(entityId, passPoint, radius, attachType);
oProfile.Entities.AddFloatingSymmetricParabolaByThroughPointAndGrade(entityId, passPoint, grade, attachType);
// Free asymmetric parabola at a PVI with two different lengths
oProfile.Entities.AddFreeAsymmetricParabolaByPVIAndLengths(pvi, length1, length2);
// Free circular curve at a PVI
oProfile.Entities.AddFreeCircularCurveByPVIAndRadius(pvi, radius);
oProfile.Entities.AddFreeCircularCurveByPVIAndLength(pvi, length);
oProfile.Entities.AddFreeCircularCurveByPVIAndThroughPoint(pvi, passPoint);
// Iterate entities
foreach (ProfileEntity entity in oProfile.Entities)
{
ed.WriteMessage("Entity type: {0}\n", entity.EntityType);
}
// Access by index or ID
ProfileEntity ent = oProfile.Entities[0];
ProfileEntity entById = oProfile.Entities.EntityAtId(entityId);
uint first = oProfile.Entities.FirstEntity;
uint last = oProfile.Entities.LastEntity;
// Remove entities
oProfile.Entities.Remove(entity);
oProfile.Entities.RemoveAt(index);
oProfile.Entities.Clear();
The intersection point of two adjacent tangents:
// Find PVI closest to station 1000, elevation -70
ProfilePVI pvi = oProfile.PVIs.GetPVIAt(1000, -70);
ed.WriteMessage("PVI at station: {0}\n", pvi.RawStation);
// Add a plain PVI (sharp point, no vertical curve)
ProfilePVI newPvi = oProfile.PVIs.AddPVI(607.4, -64.3);
newPvi.Elevation -= 2.0; // Adjust elevation
// Add PVI with a vertical curve already attached
ProfilePVI arcPvi = oProfile.PVIs.AddPVIArc(station, elevation, radius);
ProfilePVI symPvi = oProfile.PVIs.AddPVISymParabola(station, elevation, curveLength);
ProfilePVI asymPvi = oProfile.PVIs.AddPVIAsymParabola(station, elevation, tangentLen1, tangentLen2);
// Remove PVI (multiple overloads)
oProfile.PVIs.RemoveAt(station, elevation); // by closest station+elevation
oProfile.PVIs.RemoveAt(index); // by index
oProfile.PVIs.Remove(pvi); // by object reference
ProfilePVI pvi = oProfile.PVIs[0];
double station = pvi.RawStation; // use RawStation (Station is deprecated since Civil 2024)
double elevation = pvi.Elevation;
double gradeIn = pvi.GradeIn;
double gradeOut = pvi.GradeOut;
ProfileEntityType pviType = pvi.PVIType;
uint entityBefore = pvi.EntityBefore;
uint entityAfter = pvi.EntityAfter;
ProfileEntity vertCurve = pvi.VerticalCurve;
// Sight distance properties
double stopping = pvi.StoppingSightDistance;
double passing = pvi.PassingSightDistance;
double headlight = pvi.HeadlightSightDistance;
Note: PVIs are identified by station+elevation (no name/ID). GetPVIAt and RemoveAt(station, elevation) find the CLOSEST match.
Point3d insertionPoint = new Point3d(100, 100, 0);
// Minimal overload (uses default styles)
ObjectId profileViewId = ProfileView.Create(alignId, insertionPoint);
// With name, band set, and style
ObjectId profileViewId = ProfileView.Create(
alignId, insertionPoint, "New Profile View",
bandSetStyleId, profileViewStyleId);
// With split options
ObjectId profileViewId = ProfileView.Create(
alignId, insertionPoint, "New Profile View",
bandSetStyleId, profileViewStyleId, splitOptions);
Returns multiple profile view IDs for stacked display:
// Stacked views
ObjectIdCollection pvIds = ProfileView.Create(
alignId, insertionPoint, stackedOptions);
// Stacked with name and band set
ObjectIdCollection pvIds = ProfileView.Create(
alignId, insertionPoint, "Profile View",
bandSetStyleId, stackedOptions);
// Stacked with split options
ObjectIdCollection pvIds = ProfileView.Create(
alignId, insertionPoint, "Profile View",
bandSetStyleId, stackedOptions, splitOptions);
Splits the alignment into multiple profile views by station range:
// Minimal
ObjectIdCollection pvIds = ProfileView.CreateMultiple(
alignId, insertionPoint, multipleOptions);
// With name, band set, style, split, and datum
ObjectIdCollection pvIds = ProfileView.CreateMultiple(
alignId, insertionPoint, "Profile View",
bandSetStyleId, profileViewStyleId,
multipleOptions, splitOptions, datumType);
// With stacked and multiple combined
ObjectIdCollection pvIds = ProfileView.CreateMultiple(
alignId, insertionPoint, stackedOptions, multipleOptions);
ProfileView pv = ts.GetObject(pvId, OpenMode.ForWrite) as ProfileView;
// Alignment info
ObjectId alignId = pv.AlignmentId;
string alignName = pv.AlignmentName;
// Station range
StationRangeType staMode = pv.StationRangeMode;
double staStart = pv.StationStart;
double staEnd = pv.StationEnd;
// Elevation range
ElevationRangeType elevMode = pv.ElevationRangeMode;
double elevMin = pv.ElevationMin;
double elevMax = pv.ElevationMax;
// Split profile view
pv.SplitProfileView = true;
pv.SplitHeight = 5.0;
pv.SplitStationMode = SplitStationType.Manual;
Convert between drawing XY coordinates and station/elevation:
double station = 0, elevation = 0;
bool found = pv.FindStationAndElevationAtXY(x, y, ref station, ref elevation);
double x = 0, y = 0;
bool found = pv.FindXYAtStationAndElevation(station, elevation, ref x, ref y);
// Available label collections
ObjectIdCollection pvLabels = pv.GetProfileViewLabelIds();
ObjectIdCollection pipeLabels = pv.GetAvailablePipeProfileLabelIds();
ObjectIdCollection spanLabels = pv.GetAvailableSpanningPipeProfileLabelIds();
ObjectIdCollection structLabels = pv.GetAvailableStructureProfileLabelIds();
ObjectIdCollection pressureParts = pv.GetPressureNetworkPartsInGraph();
Bands display tabular data below or above the profile view (station, elevation, cut/fill, etc.):
ProfileView pv = ts.GetObject(pvId, OpenMode.ForWrite) as ProfileView;
ProfileViewBandSet bandSet = pv.Bands;
// Get current band items
ProfileViewBandItemCollection topBands = bandSet.GetTopBandItems();
ProfileViewBandItemCollection bottomBands = bandSet.GetBottomBandItems();
// Modify band items
foreach (ProfileViewBandItem band in bottomBands)
{
band.Profile1Id = profileId;
band.Profile2Id = existingGroundProfileId;
band.AlignmentId; // read-only, set at creation
}
// Apply modified band items back
bandSet.SetBottomBandItems(bottomBands);
bandSet.SetTopBandItems(topBands);
// Create a new band item collection
ProfileViewBandItemCollection newBands = new ProfileViewBandItemCollection(
pvId, BandLocationType.Bottom);
// Profile display overrides in this view
ProfileOverrideCollection overrides = pv.GraphOverrides;
// Pipe and structure overrides
PipeOverrideCollection pipeOverrides = pv.PipeOverrides;
StructureOverrideCollection structOverrides = pv.StructureOverrides;
// Hatch areas between profiles
ProfileHatchAreaCollection hatchAreas = pv.HatchAreas;
ObjectId pvStyleId = doc.Styles.ProfileViewStyles.Add("New Style");
ProfileViewStyle pvStyle = ts.GetObject(pvStyleId, OpenMode.ForWrite)
as ProfileViewStyle;
Style components:
BottomAxis, TopAxis, LeftAxis, RightAxis (all AxisStyle type)GraphStyle - overall graph appearanceGetDisplayStylePlan(ProfileViewDisplayStyleType type) — e.g. GridAtHGP for horizontal geometry point grid lines, GridHorizontalMajor/GridHorizontalMinor/GridVerticalMajor/GridVerticalMinor for regular gridEach axis style controls:
AxisStyle bottomAxis = pvStyle.BottomAxis;
ObjectId styleId = doc.Styles.ProfileStyles.Add("My Profile Style");
ProfileStyle style = ts.GetObject(styleId, OpenMode.ForWrite) as ProfileStyle;
// Display style types for profiles
style.GetDisplayStyleProfile(ProfileDisplayStyleProfileType.Arrow).Visible = true;
style.GetDisplayStyleProfile(ProfileDisplayStyleProfileType.Line).Color =
Color.FromColorIndex(ColorMethod.ByAci, 50); // yellow
style.GetDisplayStyleProfile(ProfileDisplayStyleProfileType.Curve).Color =
Color.FromColorIndex(ColorMethod.ByAci, 80); // green
style.GetDisplayStyleProfile(ProfileDisplayStyleProfileType.SymmetricalParabola).Color =
Color.FromColorIndex(ColorMethod.ByAci, 81);
style.GetDisplayStyleProfile(ProfileDisplayStyleProfileType.AsymmetricalParabola).Color =
Color.FromColorIndex(ColorMethod.ByAci, 83);
// Extension styles (grey)
style.GetDisplayStyleProfile(ProfileDisplayStyleProfileType.LineExtension).Color =
Color.FromColorIndex(ColorMethod.ByAci, 251);
style.GetDisplayStyleProfile(ProfileDisplayStyleProfileType.ParabolicCurveExtension).Color =
Color.FromColorIndex(ColorMethod.ByAci, 251);
Arrow - direction arrowsLine - straight segmentsLineExtension - line extensions beyond profileCurve - curved segmentsParabolicCurveExtension - parabola extensionsSymmetricalParabola - symmetric parabolic curvesAsymmetricalParabola - asymmetric parabolic curvesCreateByLayout creates a profile with NO elevation data - must add entities or PVIsPoint2d(station, elevation) coordinates (the Point3d overloads are deprecated since Civil 2011)RawStation on PVI objects (Station is deprecated since Civil 2024)ProfileView.Create(CivilDocument, ...) overloads are deprecated since Civil 2013; use the Create(ObjectId alignmentId, ...) overloads insteadc3d-alignments - Alignments that profiles are based onc3d-surfaces - Surface profiles (CreateFromSurface)c3d-corridors - Corridors use alignment+profile as baselinesc3d-label-styles - Profile label styles