소스 정보
- 저장소
- hebackus/c3d-api-plugin
- 최근 소스 활동
- 2026년 4월 9일 01:44
- 감지된 SKILL.md 언어
- 영어
- 스타
- 3
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
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