From c3d-api
Editor prompts — point, entity, selection, string, keyword, TypedValue filters
How this skill is triggered — by the user, by Claude, or both
Slash command
/c3d-api:acad-editor-inputThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill when prompting users for input — picking points, selecting entities, building selection sets with filters, getting string/keyword/numeric input, and handling prompt results.
Use this skill when prompting users for input — picking points, selecting entities, building selection sets with filters, getting string/keyword/numeric input, and handling prompt results.
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
The Editor class lives in Autodesk.AutoCAD.EditorInput. All prompt methods return a result object with a Status property — always check it before accessing Value.
// Simple point pick
PromptPointResult result = ed.GetPoint("\nPick insertion point: ");
if (result.Status != PromptStatus.OK) return;
Point3d point = result.Value; // WCS coordinates
PromptPointOptions ppo = new PromptPointOptions("\nPick second point: ")
{
BasePoint = firstPoint, // rubber-band line from this point
UseBasePoint = true,
AllowNone = true // pressing Enter returns PromptStatus.None
};
PromptPointResult result = ed.GetPoint(ppo);
// Pick opposite corner of a rectangle (rubber-band box from base)
PromptCornerOptions pco = new PromptCornerOptions("\nPick opposite corner: ", basePoint);
PromptPointResult result = ed.GetCorner(pco);
PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
peo.SetRejectMessage("\nEntity must be a polyline.");
peo.AddAllowedClass(typeof(Polyline), true); // true = exact match only
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
ObjectId entityId = per.ObjectId;
Point3d pickedPoint = per.PickedPoint; // point where user clicked (UCS)
PromptEntityOptions peo = new PromptEntityOptions("\nSelect line or polyline: ");
peo.SetRejectMessage("\nMust be a line or polyline.");
peo.AddAllowedClass(typeof(Line), true);
peo.AddAllowedClass(typeof(Polyline), true);
// Select entity inside a block reference
PromptNestedEntityOptions pneo = new PromptNestedEntityOptions("\nSelect nested entity: ");
PromptNestedEntityResult pner = ed.GetNestedEntity(pneo);
if (pner.Status == PromptStatus.OK)
{
ObjectId nestedId = pner.ObjectId;
ObjectId[] containers = pner.GetContainers(); // block refs from outer to inner
Matrix3d transform = pner.Transform; // cumulative transform to WCS
}
PromptSelectionOptions pso = new PromptSelectionOptions
{
MessageForAdding = "\nSelect objects: ",
MessageForRemoval = "\nRemove objects: ",
AllowDuplicates = false
};
PromptSelectionResult psr = ed.GetSelection(pso);
if (psr.Status != PromptStatus.OK) return;
SelectionSet ss = psr.Value;
ObjectId[] ids = ss.GetObjectIds();
foreach (ObjectId id in ids)
{
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
// process entity
}
TypedValue[] filterValues = new TypedValue[]
{
new TypedValue((int)DxfCode.Start, "LINE,LWPOLYLINE,POLYLINE,ARC,AECC_FEATURE_LINE")
};
SelectionFilter filter = new SelectionFilter(filterValues);
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.MessageForAdding = "\nSelect line/polyline/arc/feature line objects: ";
PromptSelectionResult psr = ed.GetSelection(pso, filter);
if (psr.Status != PromptStatus.OK) return;
int count = psr.Value.Count;
// Select all matching entities in the drawing
PromptSelectionResult psr = ed.SelectAll(filter);
// Select by window (only fully enclosed)
PromptSelectionResult psr = ed.SelectWindow(corner1, corner2, filter);
// Select by crossing window (touching or enclosed)
PromptSelectionResult psr = ed.SelectCrossingWindow(corner1, corner2, filter);
// Select by fence (polyline crossing)
Point3dCollection fencePoints = new Point3dCollection { pt1, pt2, pt3 };
PromptSelectionResult psr = ed.SelectFence(fencePoints, filter);
// Select at a specific point
PromptSelectionResult psr = ed.SelectAtPoint(point, filter);
foreach (SelectedObject selObj in psr.Value)
{
if (selObj == null) continue;
ObjectId id = selObj.ObjectId;
// selObj.SelectionMethod tells how it was selected
}
// Single type
SelectionFilter filter = new SelectionFilter(
new TypedValue[] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") }
);
// Multiple types (comma-separated in one value)
SelectionFilter filter = new SelectionFilter(
new TypedValue[] { new TypedValue((int)DxfCode.Start, "LINE,ARC,LWPOLYLINE") }
);
SelectionFilter filter = new SelectionFilter(
new TypedValue[] { new TypedValue((int)DxfCode.LayerName, "C-ROAD-*") }
);
// Type AND layer
SelectionFilter filter = new SelectionFilter(new TypedValue[]
{
new TypedValue((int)DxfCode.Operator, "<and"),
new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
new TypedValue((int)DxfCode.LayerName, "C-ROAD-*"),
new TypedValue((int)DxfCode.Operator, "and>")
});
// Type1 OR Type2 (on specific layer)
SelectionFilter filter = new SelectionFilter(new TypedValue[]
{
new TypedValue((int)DxfCode.Operator, "<and"),
new TypedValue((int)DxfCode.Operator, "<or"),
new TypedValue((int)DxfCode.Start, "LINE"),
new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
new TypedValue((int)DxfCode.Operator, "or>"),
new TypedValue((int)DxfCode.LayerName, "C-ROAD-*"),
new TypedValue((int)DxfCode.Operator, "and>")
});
| DxfCode | Value | Filters by |
|---|---|---|
DxfCode.Start | 0 | DXF entity type name |
DxfCode.Text | 1 | Text content |
DxfCode.BlockName | 2 | Block name (for INSERT) |
DxfCode.Handle | 5 | Entity handle |
DxfCode.LayerName | 8 | Layer name |
DxfCode.LinetypeName | 6 | Linetype name |
DxfCode.Color | 62 | ACI color index |
DxfCode.ClassName | 100 | Managed class name (AcDb*) |
DxfCode.Operator | -4 | Compound filter operator |
"<and" / "and>" — all conditions must match"<or" / "or>" — any condition matches"<not" / "not>" — negate condition"<xor" / "xor>" — exactly one matchesUse with DxfCode.Operator:
"<", ">", "<=", ">=", "!=", "=" — compare numeric group codes"*" — wildcard match for string group codesPromptAngleOptions pao = new PromptAngleOptions("\nSpecify rotation angle <0>: ")
{
BasePoint = insertionPoint,
UseBasePoint = true, // rubber-band angle indicator
AllowNone = true // Enter accepts default
};
PromptDoubleResult result = ed.GetAngle(pao);
double radians = result.Status == PromptStatus.OK ? result.Value : 0.0;
double degrees = radians * 180.0 / Math.PI;
PromptDoubleOptions pdo = new PromptDoubleOptions("\nEnter scale factor <1.0>: ")
{
DefaultValue = 1.0,
UseDefaultValue = true,
AllowNegative = false,
AllowZero = false,
AllowNone = true
};
PromptDoubleResult result = ed.GetDouble(pdo);
PromptIntegerOptions pio = new PromptIntegerOptions("\nEnter count <5>: ")
{
DefaultValue = 5,
UseDefaultValue = true,
LowerLimit = 1,
UpperLimit = 100
};
PromptIntegerResult result = ed.GetInteger(pio);
PromptDistanceOptions pdist = new PromptDistanceOptions("\nSpecify offset distance: ")
{
BasePoint = startPoint,
UseBasePoint = true, // rubber-band from base
AllowNegative = false,
AllowZero = false
};
PromptDoubleResult result = ed.GetDistance(pdist);
PromptStringOptions pstro = new PromptStringOptions("\nEnter layer name: ")
{
AllowSpaces = true,
DefaultValue = "0",
UseDefaultValue = true
};
PromptResult result = ed.GetString(pstro);
if (result.Status == PromptStatus.OK)
string text = result.StringResult;
PromptKeywordOptions pko = new PromptKeywordOptions("\nSelect option [Yes/No/All]: ", "Yes No All");
pko.AllowNone = false;
pko.AllowArbitraryInput = false;
PromptResult result = ed.GetKeywords(pko);
if (result.Status == PromptStatus.OK)
{
switch (result.StringResult)
{
case "Yes": /* ... */ break;
case "No": /* ... */ break;
case "All": /* ... */ break;
}
}
// Add keywords to a point prompt
PromptPointOptions ppo = new PromptPointOptions("\nPick point or [Exit/Undo]: ", "Exit Undo");
PromptPointResult result = ed.GetPoint(ppo);
if (result.Status == PromptStatus.Keyword)
{
string keyword = result.StringResult;
// handle keyword
}
else if (result.Status == PromptStatus.OK)
{
Point3d point = result.Value;
// handle point
}
| Status | Meaning |
|---|---|
OK | User provided valid input |
Cancel | User pressed Escape |
None | User pressed Enter with AllowNone = true |
Keyword | User entered a keyword |
Error | Input error |
Modeless | Modeless operation |
Other | Other result |
Always check Status before accessing Value — Value is undefined when Status is not OK.
// Output to command line
ed.WriteMessage("\nProcessed {0} entities.", count);
ed.WriteMessage($"\nError: {ex.Message}");
// Note: \n prefix to start on a new line (not \r\n)
GetAngle returns radians, not degrees — multiply by 180.0 / Math.PI for degreesGetPoint returns WCS coordinates — use ed.CurrentUserCoordinateSystem for UCS conversionGetEntity PickedPoint is in UCS, not WCSPromptSelectionResult.Value is null when Status is not OK — always check Status firstAddAllowedClass second parameter (exactMatch): true = exact type only, false = includes derived types"LWPOLYLINE" = Polyline class (lightweight); "POLYLINE" = Polyline2d or Polyline3d"LINE,ARC,LWPOLYLINE"Keywords.Add has overloads — (globalName, localName, displayName) for localization supportGetSelection during a modeless command needs CommandFlags.UsePickSet or explicit user pick*, ?, #, @, ., ~), not regexSelectAll with no filter returns everything including entities on frozen/locked layersacad-layers — selection filters can filter by DxfCode.LayerName (8)acad-polylines — common selection target; use DxfCode.Start "LWPOLYLINE" or "POLYLINE"acad-geometry — GetPoint returns Point3d; geometry types used throughout promptsacad-blocks — GetEntity can select block references; filter with DxfCode.Start "INSERT"Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub hebackus/c3d-api-plugin --plugin c3d-api