소스 정보
- 저장소
- 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-sample-lines명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | c3d-sample-lines |
| description | Sample lines, sample line groups, section views, section network discovery |
Use this skill when working with sample line groups, sample lines, section views, or when labeling gravity/pressure pipe networks in cross-section views.
Alignment
└── SampleLineGroup (via GetSampleLineGroupIds())
└── SampleLine (via GetSampleLineIds())
├── .Station — chainage at which this sample line cuts
├── GetSectionIds() → Section objects (one per sampled source)
└── GetSectionViewIds() → SectionView objects (one per view at this station)
CivilDocument civilDoc = CivilApplication.ActiveDocument;
ObjectIdCollection alignmentIds = civilDoc.GetAlignmentIds();
foreach (ObjectId alignId in alignmentIds)
{
Alignment alignment = tr.GetObject(alignId, OpenMode.ForRead) as Alignment;
ObjectIdCollection slgIds = alignment.GetSampleLineGroupIds();
foreach (ObjectId slgId in slgIds)
{
SampleLineGroup slg = tr.GetObject(slgId, OpenMode.ForRead) as SampleLineGroup;
ed.WriteMessage("Group: {0}\n", slg.Name);
ObjectIdCollection sampleLineIds = slg.GetSampleLineIds();
ed.WriteMessage(" Sample lines: {0}\n", sampleLineIds.Count);
}
}
SampleLineGroup slg = tr.GetObject(slgId, OpenMode.ForRead) as SampleLineGroup;
foreach (ObjectId slId in slg.GetSampleLineIds())
{
SampleLine sl = tr.GetObject(slId, OpenMode.ForRead) as SampleLine;
double station = sl.Station; // chainage value along the alignment
ObjectIdCollection sectionIds = sl.GetSectionIds(); // Section objects
ObjectIdCollection sectionViewIds = sl.GetSectionViewIds(); // SectionView objects
}
Each SampleLine holds one Section per sampled source (surface, gravity network, pressure network, etc.). Cast to the appropriate subtype:
foreach (ObjectId sectionId in sampleLine.GetSectionIds())
{
Section section = tr.GetObject(sectionId, OpenMode.ForRead) as Section;
if (section is SectionPipeNetwork gravitySection)
{
// Gravity pipe network section
ObjectId networkId = gravitySection.SourceId; // links to Network
}
else if (section is SectionPressurePipeNetwork pressureSection)
{
// Pressure pipe network section
ObjectId networkId = pressureSection.SourceId; // links to PressurePipeNetwork
}
// Other types: SectionSurface, etc.
}
SourceId is the key link from a Section back to the model object (network, surface, etc.) that was sampled.
Before creating labels in a section view, you must find the Section object (SectionPipeNetwork or SectionPressurePipeNetwork) that corresponds to your chosen network. This ID is required by all section label Create() methods as the sectionNetworkId parameter:
// Gravity
ObjectId sectionPipeNetworkId = ObjectId.Null;
foreach (ObjectId sectionId in sampleLine.GetSectionIds())
{
Section section = tr.GetObject(sectionId, OpenMode.ForRead) as Section;
if (section is SectionPipeNetwork sn && sn.SourceId == targetNetworkId)
{
sectionPipeNetworkId = sectionId; // this is the sectionNetworkId for labels
break;
}
}
// Pressure
ObjectId sectionPressureNetworkId = ObjectId.Null;
foreach (ObjectId sectionId in sampleLine.GetSectionIds())
{
Section section = tr.GetObject(sectionId, OpenMode.ForRead) as Section;
if (section is SectionPressurePipeNetwork spn && spn.SourceId == pressureNetworkId)
{
sectionPressureNetworkId = sectionId;
break;
}
}
If sectionNetworkId is ObjectId.Null, the network is not sampled at this sample line — skip it.
Once you have a sectionViewId and sectionNetworkId, create labels for individual parts:
// ── Gravity section labels ────────────────────────────────────────────────
// PipeSectionLabel.Create(sectionViewId, pipeId, sectionNetworkId, partIndex, styleId)
ObjectId pipeLabelId = PipeSectionLabel.Create(
sectionViewId, pipeId, sectionPipeNetworkId, 0, pipeStyleId);
// StructureSectionLabel.Create(sectionViewId, structureId, sectionNetworkId, partIndex, styleId)
ObjectId structLabelId = StructureSectionLabel.Create(
sectionViewId, structureId, sectionPipeNetworkId, 0, structureStyleId);
// ── Pressure section labels ───────────────────────────────────────────────
// All three share the same long signature
ObjectId pressurePipeLabelId = PressurePipeSectionLabel.Create(
sectionViewId, pipeId, sectionPressureNetworkId,
0 /* partIndex */, 0.5 /* ratio */, new Vector3d(1, 0, 0),
labelStyleId, (DimensionAnchorOptionType)0, 0.0);
ObjectId fittingLabelId = PressureFittingSectionLabel.Create(
sectionViewId, fittingId, sectionPressureNetworkId,
0, 0.5, new Vector3d(1, 0, 0),
labelStyleId, (DimensionAnchorOptionType)0, 0.0);
ObjectId appurtLabelId = PressureAppurtenanceSectionLabel.Create(
sectionViewId, appurtId, sectionPressureNetworkId,
0, 0.5, new Vector3d(1, 0, 0),
labelStyleId, (DimensionAnchorOptionType)0, 0.0);
Note: If the part is not present in the section view, Create() throws ArgumentException — wrap in try/catch and treat as "not in this section".
Check before creating to avoid duplicates:
// Gravity — takes sectionViewId only
ObjectIdCollection existingPipeLabels = PipeSectionLabel.GetAvailableLabelIds(sectionViewId);
ObjectIdCollection existingStructureLabels = StructureSectionLabel.GetAvailableLabelIds(sectionViewId);
// Inspect each label's FeatureId to know which part it covers
foreach (ObjectId labelId in existingPipeLabels)
{
PipeSectionLabel label = tr.GetObject(labelId, OpenMode.ForRead) as PipeSectionLabel;
ObjectId featureId = label.FeatureId; // the pipe ObjectId
}
// Pressure — takes sectionViewId + partId + sectionNetworkId
// Returns label ids if part is in section; throws if part is not in section
ObjectIdCollection existingPressurePipe = PressurePipeSectionLabel.GetAvailableLabelIds(
sectionViewId, pipeId, sectionPressureNetworkId);
var labelStylesRoot = civilDoc.Styles.LabelStyles;
// Gravity pipe cross-section styles
var crossSectionStyles = labelStylesRoot.PipeLabelStyles.CrossSectionLabelStyles;
foreach (ObjectId styleId in crossSectionStyles) { /* pipe section styles */ }
// Gravity structure styles (same collection for all views)
var structStyles = labelStylesRoot.StructureLabelStyles.LabelStyles;
// Pressure pipe cross-section styles
var pressCrossSection = labelStylesRoot.GetPressurePipeLabelStyles().CrossingSectionLabelStyles;
// Pressure fitting and appurtenance styles (same collection for all views)
var fitStyles = labelStylesRoot.GetPressureFittingLabelStyles().LabelStyles;
var appStyles = labelStylesRoot.GetPressureAppurtenanceLabelStyles().LabelStyles;
Use this pattern to populate a "select network" list by scanning all sections:
var sampledNetworkIds = new HashSet<ObjectId>();
foreach (ObjectId slId in slg.GetSampleLineIds())
{
SampleLine sl = tr.GetObject(slId, OpenMode.ForRead) as SampleLine;
if (sl == null) continue;
foreach (ObjectId sectionId in sl.GetSectionIds())
{
Section section = tr.GetObject(sectionId, OpenMode.ForRead) as Section;
// Gravity
if (section is SectionPipeNetwork sn)
sampledNetworkIds.Add(sn.SourceId);
// Pressure
if (section is SectionPressurePipeNetwork spn)
sampledNetworkIds.Add(spn.SourceId);
}
}
Then open each discovered ObjectId as Network (gravity) or PressurePipeNetwork (pressure).
SampleLine.GetSectionIds() returns one Section per sampled source — a section view may have multiple sections (surface, gravity network, pressure network, etc.)SectionPipeNetwork.SourceId links to the Network, not to the SampleLine or SectionViewPipeSectionLabel.Create() throws ArgumentException (not returns Null) when a pipe has no crossing at that section view — always try/catchPressurePipeSectionLabel.GetAvailableLabelIds() also throws when the part is absent from the section — use the same try/catch pattern for detectionpartIndex is 0-based; passing 0 works for single-crossing scenariossectionNetworkId in label Create() is the SectionPipeNetwork/SectionPressurePipeNetwork ObjectId — NOT the model network ObjectIdc3d-root-objects - Accessing alignments through CivilDocumentc3d-pipe-networks - Gravity and pressure pipe network part IDs used in section labelsc3d-label-styles - Label style navigation for cross-section stylesc3d-alignments - Alignment and profile view conceptsSOC 직업 분류 기준