using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(ArrayClassic.MyCommands))]
namespace ArrayClassic
{
public class MyCommands
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Использование: Создание Прямоугольного Ассоциативного Массива
/////////////////////////////////////////////////////////////////////////////////////////////////////////
[CommandMethod("CreateAssocArrayRect")]
public void CreateAssocArrayRect()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
int nRows = 5;
int nColumns = 5;
double dRowOffset = 1;
double dColumnOffset = 1;
using (Transaction Tx = db.TransactionManager.StartTransaction())
{
// Создаем исходный примитив - здесь простой круг (Circle)
Circle circle = new Circle(new Point3d(2, 2, 0), new Vector3d(0, 0, 1), 0.5);
circle.ColorIndex = 1;
ObjectIdCollection sourceEntities = new ObjectIdCollection();
// Исходный примитив должен быть в базе
AcHelper.PostToDatabase(circle);
sourceEntities.Add(circle.ObjectId);
// Базовая точка массива в VertexRef
VertexRef basePoint = new VertexRef(new Point3d(2, 2, 0));
// Параметры прямоугольного массива
double columnSpacing = dRowOffset;
double rowSpacing = dColumnOffset;
double levelSpacing = dColumnOffset;
int columnCount = 5;
int rowCount = 5;
int levelCount = 1;
double rowElevation = 0;
double axesAngle = 0;
Matrix3d curUCSMatrix = ed.CurrentUserCoordinateSystem;
CoordinateSystem3d curUCS = curUCSMatrix.CoordinateSystem3d;
Vector2d acVec2dAng = new Vector2d(curUCS.Xaxis.X, curUCS.Xaxis.Y);
axesAngle += acVec2dAng.Angle;
AssocArrayRectangularParameters parameters = new AssocArrayRectangularParameters(columnSpacing,
rowSpacing,
levelSpacing,
columnCount,
rowCount,
levelCount,
rowElevation,
axesAngle);
parameters.AxesAngle = acVec2dAng.Angle;
parameters.XAxisDirection = curUCS.Xaxis;
parameters.YAxisDirection = curUCS.Yaxis;
// Как показано ниже, параметры могут быть связаны с выражениями, включающими переменные
AcHelper.AddOrModifVariable("RowCount", rowCount.ToString());
AcHelper.AddOrModifVariable("RowSpacing", rowSpacing.ToString());
parameters.SetRowCount(rowCount, "RowCount", "");
parameters.SetRowSpacing(rowSpacing, "RowSpacing", "");
// Создаем массив. Возвращается AssocArray помещенный в базу
AssocArray array = Autodesk.AutoCAD.DatabaseServices.AssocArray.CreateArray(sourceEntities,
basePoint,
parameters);
// Если нужно переместить массив, то имея его свойство EntityId
// можно применить трансформацию как показано ниже
Entity arrayEnt = Tx.GetObject(array.EntityId, OpenMode.ForWrite) as Entity;
arrayEnt.TransformBy(Matrix3d.Displacement(new Vector3d(5, 5, 5)));
// Заставляем обновится все связи
AssocManager.EvaluateTopLevelNetwork(db, null, 0);
// Так как массив уже создан, то исходный круг можно удалить.
// Он уже содержится в массиве (фактически в анонимном блоке)
circle.Erase(true);
Tx.Commit();
}
}
}
public class AcHelper
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Helper method: Добавление примитива в пространство модели указанной базы данных
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
public static ObjectId PostToDatabase(Database db, Entity entity)
{
using (Transaction Tx = db.TransactionManager.StartTransaction())
{
BlockTable bt = Tx.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord model = Tx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
ObjectId newId = model.AppendEntity(entity);
Tx.AddNewlyCreatedDBObject(entity, true);
Tx.Commit();
return newId;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Helper method: Добавление примитива в пространство модели текущей базы данных
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
public static ObjectId PostToDatabase(Entity entity)
{
Database db = Application.DocumentManager.MdiActiveDocument.Database;
return PostToDatabase(db, entity);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Добавление новой переменной в ассоциативную сеть или модификация существующей
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
public static ObjectId AddOrModifVariable(string varName, string varExpression)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
ObjectId varid = ObjectId.Null;
using (Transaction Tx = db.TransactionManager.StartTransaction())
{
ObjectId networkId = AssocNetwork.GetInstanceFromObject(db.CurrentSpaceId, true, true, "ACAD_ASSOCNETWORK");
AssocNetwork network = Tx.GetObject(networkId, OpenMode.ForWrite) as AssocNetwork;
ObjectIdCollection actionIds = network.GetActions;
for (int i = 0; i < actionIds.Count; ++i)
{
try
{
AssocVariable var1 = Tx.GetObject(actionIds[i], OpenMode.ForWrite) as AssocVariable;
if (var1 != null)
{
if (var1.Name == varName)
{
String errMsg = "";
var1.SetExpression(varExpression, "", true, true, ref errMsg, false);
ResultBuffer rb = new ResultBuffer();
errMsg = var1.EvaluateExpression(ref rb);
var1.Value = rb;
Tx.Commit();
return var1.ObjectId;
}
}
}
catch
{
}
}
AssocVariable var = new AssocVariable();
varid = network.Database.AddDBObject(var);
network.AddAction(var.ObjectId, true);
Tx.AddNewlyCreatedDBObject(var, true);
Tx.Commit();
}
using (Transaction Tx = db.TransactionManager.StartTransaction())
{
AssocVariable var = (AssocVariable)Tx.GetObject(varid, OpenMode.ForWrite);
var.SetName(varName, true);
var.Value = new ResultBuffer(new TypedValue(1001, 5));
String errMsg = "";
var.SetExpression(varExpression, "", true, true, ref errMsg, false);
ResultBuffer rb = new ResultBuffer();
errMsg = var.EvaluateExpression(ref rb);
var.Value = rb;
Tx.Commit();
}
return varid;
}
}
}