// divide.cs
// © Andrey Bushman, 2014
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using App = Autodesk.AutoCAD.ApplicationServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Gem = Autodesk.AutoCAD.Geometry;
using Rtm = Autodesk.AutoCAD.Runtime;
[assembly: Rtm.CommandClass(typeof(Bushman.CAD.Commands.Divide))]
namespace Bushman.CAD.Commands {
public class Divide : Rtm.IExtensionApplication {
const String ns = "Bushman";
static Int32 div_count = 2; // по умолчанию предлагаю делить линии на две части.
const String msg0 = "Указанный набор не содержит объектов Line.\n";
const String msg = "Выполнение команды прервано.\n";
/// <summary>
/// заменяет указанные пользователем линии 3D-полилиниями, поделив
/// каждую из этих полилиний на заданное количество равных сегментов
/// посредством дополнительных вершин.
/// </summary>
[Rtm.CommandMethod(ns, "divide2", Rtm.CommandFlags.UsePickSet | Rtm.CommandFlags.Redraw
| Rtm.CommandFlags.Modal | Rtm.CommandFlags.NoPaperSpace)]
public void Divide2() {
App.Document doc = cad.DocumentManager.MdiActiveDocument;
Ed.Editor ed = doc.Editor;
Db.Database db = doc.Database;
Ed.PromptSelectionResult psr;
psr = ed.SelectImplied();
Db.ObjectId[] ids = null;
if (psr.Status == Ed.PromptStatus.OK) {
ids = psr.Value.GetObjectIds().Where(id => id.ObjectClass.Name == "AcDbLine")
.ToArray();
if (ids != null && ids.Length > 0) ed.SetImpliedSelection(ids);
else {
ed.WriteMessage(msg0);
ed.WriteMessage(msg);
return;
}
}
else {
Db.TypedValue[] typeValues = new Db.TypedValue[1];
typeValues.SetValue(new Db.TypedValue((Int32)Db.DxfCode.Start, "LINE"), 0);
Ed.SelectionFilter filter = new Ed.SelectionFilter(typeValues);
psr = ed.GetSelection(filter);
}
if (psr.Status != Ed.PromptStatus.OK) {
ed.WriteMessage(msg);
return;
}
if (ids == null) ids = psr.Value.GetObjectIds();
Ed.PromptIntegerOptions pio = new Ed.PromptIntegerOptions("Количество сегментов");
pio.AllowNegative = false;
pio.AllowNone = false;
pio.AllowZero = false;
pio.DefaultValue = div_count;
Ed.PromptIntegerResult result = ed.GetInteger(pio);
if (result.Status != Ed.PromptStatus.OK) {
ed.WriteMessage(msg);
return;
}
else {
div_count = result.Value;
}
List<Db.ObjectId> resultIds = new List<Db.ObjectId>();
using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
foreach (Db.ObjectId id in ids) {
Db.Line line = (Db.Line)tr.GetObject(id, Db.OpenMode.ForWrite);
Gem.Point3dCollection points = new Gem.Point3dCollection();
Gem.Point3d point = line.StartPoint;
points.Add(line.StartPoint);
Double dx = line.Delta.X / div_count;
Double dy = line.Delta.Y / div_count;
Double dz = line.Delta.Z / div_count;
for (int i = 1; i < div_count; i++) {
point = new Gem.Point3d(point.X + dx, point.Y + dy, point.Z + dz);
points.Add(point);
}
points.Add(line.EndPoint);
Db.Polyline3d pline = new Db.Polyline3d(Db.Poly3dType.SimplePoly, points,
false);
pline.SetDatabaseDefaults();
pline.LayerId = line.LayerId;
pline.Color = line.Color;
pline.ColorIndex = line.ColorIndex;
pline.LinetypeId = line.LinetypeId;
pline.LinetypeScale = line.LinetypeScale;
pline.LineWeight = line.LineWeight;
line.Erase(true);
Db.BlockTable bt = (Db.BlockTable)tr.GetObject(db.BlockTableId,
Db.OpenMode.ForRead);
Db.BlockTableRecord btr = (Db.BlockTableRecord)tr.GetObject(
bt[Db.BlockTableRecord.ModelSpace], Db.OpenMode.ForWrite);
btr.AppendEntity(pline);
tr.AddNewlyCreatedDBObject(pline, true);
resultIds.Add(pline.ObjectId);
}
tr.Commit();
}
// Результат преобразования выделяю "ручками"
ed.SetImpliedSelection(resultIds.ToArray());
}
#region IExtensionApplication Members
public void Initialize() {
App.Document doc = cad.DocumentManager.MdiActiveDocument;
Ed.Editor ed = doc.Editor;
ed.WriteMessage("\n{0}. © Andrey Bushman, 2014\n\n",
Path.GetFileName(this.GetType().Assembly.Location));
}
public void Terminate() {
// throw new NotImplementedException();
}
#endregion
}
}