// Основной модуль
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using App = Autodesk.AutoCAD.ApplicationServices;
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Gem = Autodesk.AutoCAD.Geometry;
using Rtm = Autodesk.AutoCAD.Runtime;
using Gi = Autodesk.AutoCAD.GraphicsInterface;
namespace QuickSelect
{
public class Commands
{
public static List<string> AttList = new List<string>();
public static string AttValue = "";
private static string Exit = "Exit";
static public void ClearAttListValue()
{
AttValue = "";
AttList.Clear();
AttList.Add(Exit);
}
[Rtm.CommandMethod("bx_quickselect", Rtm.CommandFlags.UsePickSet |
Rtm.CommandFlags.Redraw |
Rtm.CommandFlags.Modal)]
static public void bx_quickselect()
{
// Получение текущего документа и базы данных
App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
Db.Database acCurDb = acDoc.Database;
Ed.Editor acEd = acDoc.Editor;
ClearAttListValue();
//Секция предварительного выбора
Ed.PromptSelectionResult acSSPrompt = acEd.SelectImplied();
Ed.SelectionSet acSSet = null;
// Если статус запроса OK, объекты были выбраны перед запуском команды
if (acSSPrompt.Status == Ed.PromptStatus.OK)
acSSet = acSSPrompt.Value;
Dictionary<Db.ObjectId, string> ObjID_Dic = new Dictionary<Db.ObjectId, string>();
Ed.PromptEntityOptions EntOpt = new Ed.PromptEntityOptions("\n Select block:");
EntOpt.SetRejectMessage("\n Entity must be a block.");
EntOpt.AddAllowedClass(typeof(Db.BlockReference), false);
EntOpt.AllowObjectOnLockedLayer = true;
Ed.PromptEntityResult EntRes = acEd.GetEntity(EntOpt);
if (EntRes.Status != Ed.PromptStatus.OK)
{
acEd.WriteMessage("\n Cencel.");
return;
}
String acBlockName = "0";
// старт транзакции
// Ищу истенное имя выбранного блока и читаю его атрибуты
using (Db.Transaction acTrans = acCurDb.TransactionManager.StartOpenCloseTransaction())
{
// Открытие таблицы Блоков для чтения
Db.BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
Db.OpenMode.ForRead) as Db.BlockTable;
// Открытие записи таблицы Блоков пространства Модели для записи
Db.BlockTableRecord acBlkTblRecMS = acTrans.GetObject(acBlkTbl[Db.BlockTableRecord.ModelSpace],
Db.OpenMode.ForRead) as Db.BlockTableRecord;
//Получаю выбранный блок
Db.BlockReference acBlock = acTrans.GetObject(EntRes.ObjectId, Db.OpenMode.ForRead) as Db.BlockReference;
//Получаю определение блока в таблице блоков
Db.BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlock.BlockTableRecord, Db.OpenMode.ForRead)
as Db.BlockTableRecord;
// Получаю определение блока в таблице динамических блоков
// Запоминаю истинное имя блока
acBlockName = acBlock.Name;
if (acBlock.IsDynamicBlock)
{
acBlkTblRec = acTrans.GetObject(acBlock.DynamicBlockTableRecord, Db.OpenMode.ForRead) as Db.BlockTableRecord;
Db.BlockTableRecord blr_nam = acTrans.GetObject(acBlkTblRec.ObjectId, Db.OpenMode.ForRead) as Db.BlockTableRecord;
acBlockName = blr_nam.Name;
}
if (acBlkTblRec.HasAttributeDefinitions)
{
foreach (Db.ObjectId objID in acBlkTblRec)
{
Db.DBObject dbObj = acTrans.GetObject(objID, Db.OpenMode.ForRead) as Db.DBObject;
if (dbObj is Db.AttributeDefinition)
{
Db.AttributeDefinition acAtt = dbObj as Db.AttributeDefinition;
if (AttList.Contains(acAtt.Tag) != true)
AttList.Add(acAtt.Tag);
}
}
}
//Я в этой транзакции ничего не меняю, Все открываю только для чтения.
//соответственно и вносить изменения не нужно.
//acTrans.Commit();
}
if (AttList.Count == 1)
return;
QuickSelect.Form1 myform_name = new QuickSelect.Form1();
Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(myform_name);
if (AttValue == Exit)
return;
string AttName = AttValue;
// Вот тут нужно очистить переменные
ClearAttListValue();
//// тут получить все возможние значения данного атрибута и
//// заполним массив AttList снова вызвать форму
using (Db.Transaction acTrans = acCurDb.TransactionManager.StartOpenCloseTransaction())
{
if (acSSet == null)
{
Db.TypedValue[] acTypValAr = new Db.TypedValue[1];
Db.TypedValue typedValue = new Db.TypedValue(0, "INSERT");
acTypValAr.SetValue(typedValue, 0);
Ed.SelectionFilter acSelFtr = new Ed.SelectionFilter(acTypValAr);
acSSPrompt = acEd.SelectAll(acSelFtr);
acSSet = acSSPrompt.Value;
}
foreach (Db.ObjectId objID in acSSet.GetObjectIds())
{
// Проверка, нужно убедится в правильности полученного объекта
if (objID != null)
{
// Открытие объекта для
Db.Entity dbObj = acTrans.GetObject(objID, Db.OpenMode.ForRead) as Db.Entity;
if (dbObj != null)
{
if (dbObj is Db.BlockReference)
{
Db.BlockReference acBlock = dbObj as Db.BlockReference;
Db.BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlock.BlockTableRecord, Db.OpenMode.ForRead) as Db.BlockTableRecord;
String BlockName = acBlock.Name;
if (acBlock.IsDynamicBlock)
{
acBlkTblRec = acTrans.GetObject(acBlock.DynamicBlockTableRecord, Db.OpenMode.ForRead) as Db.BlockTableRecord;
Db.BlockTableRecord blr_nam = acTrans.GetObject(acBlkTblRec.ObjectId, Db.OpenMode.ForRead) as Db.BlockTableRecord;
BlockName = blr_nam.Name;
}
if (BlockName == acBlockName)
{
if (acBlkTblRec.HasAttributeDefinitions)
{
foreach (Db.ObjectId objID_In_Block in acBlock.AttributeCollection)
{
Db.DBObject dbObj_In_Block = acTrans.GetObject(objID_In_Block, Db.OpenMode.ForRead) as Db.DBObject;
if (dbObj_In_Block is Db.AttributeReference)
{
Db.AttributeReference acAtt = dbObj_In_Block as Db.AttributeReference;
if (acAtt.Tag == AttName)
{
ObjID_Dic.Add(acBlock.ObjectId, acAtt.TextString);
if (AttList.Contains(acAtt.TextString) == false)
AttList.Add(acAtt.TextString);
}
}
}
}
}
}
}
}
}
//Я в этой транзакции ничего не меняю, Все открываю только для чтения.
//соответственно и вносить изменения не нужно.
//acTrans.Commit();
}
//Выводим форму для выбора значения
QuickSelect.Form1 myform_value = new QuickSelect.Form1();
Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(myform_value);
if (AttValue == Exit)
return;
// Добавляем в набор выбираемых объекты удовлетворяющие условию
IEnumerable<Db.ObjectId> L = from KeyValuePair<Db.ObjectId, string> q in ObjID_Dic
where q.Value.ToString() == AttValue.ToString()
select q.Key;
//Подсвечиваем объекты
Db.ObjectId[] idarrayEmpty = L.ToArray();
acEd.SetImpliedSelection(idarrayEmpty);
}
}
}