用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/hebackus/c3d-api-plugin --skill c3d-points命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | c3d-points |
| description | COGO points, point groups, UDPs, description keys, point styles, bulk editing |
Use this skill when working with COGO points - creating, querying, grouping, styling, or using description keys.
All points are in CivilDocument.CogoPoints (CogoPointCollection):
CogoPointCollection cogoPoints = doc.CogoPoints;
// Add individual point (useNextPointNumSetting: true = auto-assign number)
ObjectId pointId = cogoPoints.Add(new Point3d(4958, 4079, 200), true);
// Add with description
ObjectId pointId2 = cogoPoints.Add(new Point3d(100, 200, 225), "GRND", true);
// Add with description + description key matching
ObjectId pointId3 = cogoPoints.Add(
new Point3d(100, 200, 225), "GRND",
useDescriptionKey: true, matchOnParams: true, useNextPointNumSetting: true);
// Add multiple points
Point3dCollection pts = new Point3dCollection(
new[] { new Point3d(4927, 3887, 150), new Point3d(5101, 3660, 250) });
ObjectIdCollection ids = cogoPoints.Add(pts, true);
// Add multiple with description
ObjectIdCollection ids2 = cogoPoints.Add(pts, "GRND", true);
// Lookup and membership
ObjectId found = cogoPoints.GetPointByPointNumber(100);
bool exists = cogoPoints.Contains(100); // check by point number
uint total = cogoPoints.Count;
// Iterate
foreach (ObjectId pid in cogoPoints)
{
CogoPoint pt = pid.GetObject(OpenMode.ForRead) as CogoPoint;
ed.WriteMessage("Point #{0}: Elev={1}\n", pt.PointNumber, pt.Elevation);
}
// Remove
cogoPoints.Remove(779); // by point number
cogoPoints.Remove(pointId); // by ObjectId
cogoPoints.Clear(); // remove all points
CogoPoint pt = pointId.GetObject(OpenMode.ForWrite) as CogoPoint;
// Identity
pt.PointName = "point1";
pt.RawDescription = "Point description";
pt.DescriptionFormat = "$*"; // Format string ($* = raw description)
pt.PointNumber = 100; // Throws if number already exists
pt.Renumber(100); // Uses default conflict resolution
pt.Renumber(100, PointNumberResolveType.UseNext); // Explicit resolution type
// Read-only descriptors
string fullDesc = pt.FullDescription; // Computed from DescriptionFormat + RawDescription
Point3d location = pt.Location; // Read-only, use Easting/Northing/Elevation
ObjectId primaryGroup = pt.PrimaryPointGroupId;
bool movable = pt.IsMovable;
bool survey = pt.IsSurveyPoint;
// Position (read/write)
double easting = pt.Easting;
double northing = pt.Northing;
double elevation = pt.Elevation;
// Grid coordinates (read/write)
double gridE = pt.GridEasting;
double gridN = pt.GridNorthing;
// Geographic coordinates (read/write)
double lat = pt.Latitude;
double lon = pt.Longitude;
double conv = pt.Convergence; // read-only
// Display properties
pt.IsLocked = true; // Lock/unlock point
pt.ShowToolTip = true;
pt.MarkerRotation = 0.785; // radians
pt.LabelRotation = 0.0;
pt.LabelLocation = new Point3d(, , );
pt.ScaleXY = ;
pt.ScaleZ = ;
scale = pt.Scale;
pt.IsLabelVisible = ;
pt.IsLabelPinned = ;
dragged = pt.IsLabelDragged;
pt.LeaderVisibility = LeaderVisibilityType.Always;
pt.LeaderAttachment = LeaderAttachmentBehaviorType.TopOfText;
pt.LeaderTailVisibility = LeaderTailVisibilityType.UseStyle;
ObjectIdCollection compIds = pt.GetLabelTextComponentIds();
pt.SetLabelTextComponentOverride(compIds[], );
overrideText = pt.GetLabelTextComponentOverride(compIds[]);
isOverridden = pt.IsLabelTextComponentOverriden(compIds[]);
pt.ClearLabelTextComponentOverrides(compIds[]);
pt.ClearAllLabelTextComponentOverrides();
pt.ResetLabel();
pt.ResetLabelLocation();
pt.ResetLabelRotation();
pt.StyleId = pointStyleId;
pt.LabelStyleId = labelStyleId;
(pt.IsProjectPoint)
{
checkedOut = pt.IsCheckedOut;
version = pt.ProjectVersion;
}
pt.ApplyDescriptionKeys();
CogoPointCollection provides bulk methods with three overloads each:
// Set elevation offset for all points
cogoPoints.SetElevationByOffset(cogoPoints, 3.00);
// Set raw description for all points
cogoPoints.SetRawDescription(cogoPoints, "NEW_DESC");
// Set full description format ($* = same as raw description)
cogoPoints.SetDescriptionFormat(cogoPoints, "$*");
// Set elevation from a surface
cogoPoints.SetElevationBySurface(cogoPoints, surfaceId);
// Set position components
cogoPoints.SetEasting(cogoPoints, 1000.0);
cogoPoints.SetNorthing(cogoPoints, 2000.0);
// Set scale
cogoPoints.SetScaleXY(cogoPoints, 1.0);
cogoPoints.SetScaleZ(cogoPoints, 1.0);
// Set rotation
cogoPoints.SetMarkerRotation(cogoPoints, 0.785);
cogoPoints.SetLabelRotation(cogoPoints, 0.0);
// Set point name (single point only, or list with individual values)
cogoPoints.SetPointName(pointId, "PT1");
// Lock/unlock and tooltips
cogoPoints.SetIsLocked(cogoPoints, true);
cogoPoints.SetShowTooltips(cogoPoints, true);
// Also available: SetPointNumber, SetStyleId, SetLabelStyleId
Point groups define subsets of points. All groups in doc.PointGroups.
PointGroupCollection pgCollection = doc.PointGroups;
// Create
ObjectId pgId = pgCollection.Add("My Point Group");
PointGroup pg = pgId.GetObject(OpenMode.ForWrite) as PointGroup;
pg.Description = "Optional description";
// Lookup
bool exists = pgCollection.Contains("My Point Group");
ObjectId existingId = pgCollection["My Point Group"]; // by name
ObjectId byIndex = pgCollection[0]; // by index
int count = pgCollection.Count;
// Special group: all points
ObjectId allPtsId = pgCollection.AllPointsPointGroupId;
string allPtsName = PointGroup.AllPointsGroupName; // static property
// Remove
pgCollection.Remove(pgId);
pgCollection.Remove("My Point Group");
// Check membership and get points
if (pg.ContainsPoint(cogoPoint.PointNumber))
ed.WriteMessage("Point is in group\n");
uint[] pointNumbers = pg.GetPointNumbers();
uint pointCount = pg.PointsCount;
bool isAllPoints = pg.IsAllPointsGroup;
// Lock/unlock all points in group
pg.LockPoints();
pg.UnlockPoints();
pg.IsLocked = true; // lock the group itself
// Delete all points in group
pg.DeletePoints();
// Point style/label style overrides for group
pg.PointStyleId = styleId;
pg.IsPointStyleOverridden = true;
pg.PointLabelStyleId = labelStyleId;
pg.IsPointLabelStyleOverridden = true;
// Override elevations for all points in group
pg.ElevationOverride.FixedElevation = 100;
pg.ElevationOverride.ActiveOverrideType = PointGroupOverrideType.FixedValue;
pg.IsElevationOverridden = true;
// Override raw descriptions for all points in group
pg.RawDescriptionOverride.FixedRawDescription = ;
pg.RawDescriptionOverride.ActiveOverrideType = PointGroupOverrideType.FixedValue;
pg.IsRawDescriptionOverridden = ;
ObjectIdCollection drawOrder = pgCollection.DrawOrder;
pgCollection.DrawOrder = drawOrder;
outOfDate = pg.IsOutOfDate;
ObjectIdCollection staleGroups = pgCollection.GetOutOfDatePointGroupIds();
pgCollection.UpdateAllPointGroups();
Match points by descriptions, elevations, names, numbers:
StandardPointGroupQuery query = new StandardPointGroupQuery();
query.IncludeElevations = "100-200"; // Range
query.IncludeFullDescriptions = "FLO*"; // Wildcard
query.IncludeNumbers = ">2200"; // Greater than
query.ExcludeElevations = "150-155";
query.ExcludeNames = "BRKL";
pg.SetQuery(query);
pg.Update(); // Apply the query
ed.WriteMessage("Selected: {0} points\nQuery: {1}\n",
pg.PointsCount, query.QueryString);
// Output query: (FullDescription='FLO*' OR PointElevation=100-200 OR
// PointNumber>2200) AND NOT(Name='BRKL' OR PointElevation=150-155)
Include/Exclude property values:
"110.01""1-100"">200", "<-100""<-100,1-100,110.01,>200""IP*", "?X*"All Include* properties are ORed; all Exclude* properties are ORed. Final query = (Includes) AND NOT (Excludes).
For nested queries not expressible with StandardQuery:
CustomPointGroupQuery customQuery = new CustomPointGroupQuery();
customQuery.QueryString =
"(RawDescription='GR*') AND (PointElevation>=100 AND PointElevation<=300)";
pg.SetQuery(customQuery);
pg.Update();
Operators: =, >, <, >=, <=, AND, OR, NOT, parentheses for grouping.
PointGroupChangeInfo changes = pg.GetPendingChanges();
ed.WriteMessage("To add: {0}, To remove: {1}\n",
changes.PointsToAdd.Length, changes.PointsToRemove.Length);
pg.Update(); // Apply pending changes
Changes are registered when points matching the query are added/removed, NOT when the query itself changes.
UDPs attach custom data to points, organized in classifications:
// Create classification
UDPClassification udpClass = doc.PointUDPClassifications.Add("Example");
// Create UDP (integer with bounds)
AttributeTypeInfoInt attrInfo = new AttributeTypeInfoInt("Int UDP");
attrInfo.DefaultValue = 15;
attrInfo.UpperBoundValue = 20;
attrInfo.LowerBoundValue = 10;
UDPInteger udp = udpClass.CreateUDP(attrInfo);
// Assign classification to point group
PointGroup pg = pgId.GetObject(OpenMode.ForWrite) as PointGroup;
pg.UseCustomClassification("Example");
| Type | Class | Extra Properties |
|---|---|---|
| Integer | UDPInteger | UpperBoundValue, LowerBoundValue, *Inclusive |
| Double | UDPDouble | UpperBoundValue, LowerBoundValue, *Inclusive |
| String | UDPString | (none) |
| Boolean | UDPBoolean | (none) |
| Enumeration | UDPEnumeration | GetEnumValues() |
AttributeTypeInfoInt - integer with boundsAttributeTypeInfoDouble - double with boundsAttributeTypeInfoString - stringAttributeTypeInfoBool - booleanAttributeTypeInfoEnum - enumerationCreateUDP() accepts an optional GUID parameter to create identical UDPs across drawings.
foreach (UDPClassification udpClass in doc.PointUDPClassifications)
{
foreach (UDP udp in udpClass.UDPs)
{
ed.WriteMessage("UDP: {0}, GUID: {1}, Default: {2}\n",
udp.Name, udp.Guid, udp.DefaultValue);
}
}
ObjectId styleId = doc.Styles.PointStyles.Add("My Point Style");
PointStyle style = styleId.GetObject(OpenMode.ForWrite) as PointStyle;
// Marker type
style.MarkerType = PointMarkerDisplayType.UseCustomMarker;
style.CustomMarkerStyle = CustomMarkerType.CustomMarkerPlus;
style.CustomMarkerSuperimposeStyle = CustomMarkerSuperimposeType.Square;
// For symbol markers
style.MarkerSymbolName = "BLOCK_NAME"; // AutoCAD block in drawing
// Assign to point
cogoPoint.StyleId = styleId;
Display settings accessed via GetDisplay*(), GetLabelDisplay*(), GetMarkerDisplay*() methods for Model, Plan, Profile, or Section views.
// Access via
var labelStyles = doc.Styles.LabelStyles.PointLabelStyles;
// Assign to point
cogoPoint.LabelStyleId = labelStyleId;
<[Name(CP)]>
<[Point Number]>
<[Northing(Uft|P4|RN|AP|Sn|OF)]>
<[Easting(Uft|P4|RN|AP|Sn|OF)]>
<[Raw Description(CP)]>
<[Full Description(CP)]>
<[Point Elevation(Uft|P3|RN|AP|Sn|OF)]>
<[Latitude(Udeg|FDMSdSp|P6|RN|DPSn|CU|AP|OF)]>
<[Longitude(Udeg|FDMSdSp|P6|RN|DPSn|CU|AP|OF)]>
<[Grid Northing(Uft|P4|RN|AP|Sn|OF)]>
<[Grid Easting(Uft|P4|RN|AP|Sn|OF)]>
<[Scale Factor(P3|RN|AP|OF)]>
<[Convergence(Udeg|FDMSdSp|P6|RN|AP|OF)]>
<[Survey Point]>
Automatically apply styles and settings to points by matching descriptions:
// Create key set
ObjectId keySetId = PointDescriptionKeySetCollection
.GetPointDescriptionKeySets(acaddoc.Database)
.Add("My Key Set");
PointDescriptionKeySet keySet = keySetId.GetObject(OpenMode.ForWrite)
as PointDescriptionKeySet;
// Create key matching "GRND*"
ObjectId keyId = keySet.Add("GRND*");
PointDescriptionKey key = keyId.GetObject(OpenMode.ForWrite) as PointDescriptionKey;
// Apply style and label style
key.StyleId = pointStyleId;
key.ApplyStyleId = true;
key.LabelStyleId = labelStyleId;
key.ApplyLabelStyleId = true;
// Scale from description parameter
key.ApplyDrawingScale = false;
key.ScaleParameter = 1;
key.ApplyScaleParameter = true;
key.ApplyScaleXY = true;
// Fixed rotation
key.FixedMarkerRotation = 0.785398163; // radians (45 degrees)
key.RotationDirection = RotationDirType.Clockwise;
key.ApplyFixedMarkerRotation = true;
// Set search order (priority)
var allKeySets = PointDescriptionKeySetCollection
.GetPointDescriptionKeySets(acaddoc.Database);
ObjectIdCollection searchOrder = allKeySets.SearchOrder;
// Rearrange searchOrder as needed
allKeySets.SearchOrder = searchOrder;
// Apply to point group
pointGroup.ApplyDescriptionKeys();
Wildcards ? and * are supported in the Code property.
// Add point group as surface data source
TinSurface surface = surfaceId.GetObject(OpenMode.ForWrite) as TinSurface;
surface.PointGroupsDefinition.AddPointGroup(pointGroupId);
// Set elevation from surface (bulk, on CogoPointCollection)
cogoPoints.SetElevationBySurface(pointId, surfaceId);
cogoPoints.SetElevationBySurface(pointIds, surfaceId);
// Get available file formats
PointFileFormatCollection formats =
PointFileFormatCollection.GetPointFileFormats(acaddoc.Database);
PointFileFormat pnezd = formats["PNEZD (comma delimited)"];
// Import points from file
uint importedCount = CogoPointCollection.ImportPoints(
@"C:\points.csv", pnezd);
// Import into a specific point group
uint importedCount2 = CogoPointCollection.ImportPoints(
@"C:\points.csv", pnezd, pointGroupId);
// Import with coordinate options
uint importedCount3 = CogoPointCollection.ImportPoints(
@"C:\points.csv", pnezd,
useAdjustedElevation: false,
shouldTransformCoordinate: false,
shouldExpandCoordinateData: false);
// Export points to file
uint exportedCount = CogoPointCollection.ExportPoints(
@"C:\output.csv", pnezd);
// Export specific point group
uint exportedCount2 = CogoPointCollection.ExportPoints(
@"C:\output.csv", pnezd, pointGroupId);
CogoPoint pt = pointId.GetObject(OpenMode.ForWrite) as CogoPoint;
// Set UDP values (typed overloads)
pt.SetUDPValue(udpInteger, 42);
pt.SetUDPValue(udpDouble, 3.14);
pt.SetUDPValue(udpString, "hello");
pt.SetUDPValue(udpBoolean, true);
pt.SetUDPValue(udpEnumeration, "ValueName");
// Get UDP values (typed overloads)
int intVal = pt.GetUDPValue(udpInteger);
double dblVal = pt.GetUDPValue(udpDouble);
string strVal = pt.GetUDPValue(udpString);
bool boolVal = pt.GetUDPValue(udpBoolean);
string enumVal = pt.GetUDPValue(udpEnumeration);
PointNumber setter throws if number exists; use Renumber() for conflict resolutionFullDescription is read-only (computed from DescriptionFormat + RawDescription)Location is read-only; modify via Easting, Northing, ElevationIsCheckedOut/ProjectVersion on non-project points throwsAdd overloads on CogoPointCollection require a bool useNextPointNumSetting parameterStandardPointGroupQuery ORs all includes and ORs all excludesSetPointName on CogoPointCollection has no "set all to same value" overload (unlike other bulk methods)c3d-label-styles - Point label style creationc3d-surfaces - Points as surface datac3d-root-objects - Accessing point collectionsacad-editor-input - Selection sets for COGO point operationsc3d-survey — Survey points imported as COGO points