using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
[assembly: CommandClass(typeof(CombineBlocks.MyCommands))]
namespace CombineBlocks
{
public class MyCommands
{
[CommandMethod("CombineBlocks")]
public void CombineBlocksHandler() // This method can have any name
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null) return;
Editor ed = doc.Editor;
Database db = doc.Database;
PromptEntityOptions prOpt =
new PromptEntityOptions("\nВыберите первый блок: ");
prOpt.SetRejectMessage("Это не блок!");
prOpt.AddAllowedClass(typeof(BlockReference), true);
PromptEntityResult per1 = ed.GetEntity(prOpt);
if (per1.Status != PromptStatus.OK) return;
prOpt.Message = "\nВыберите второй блок: ";
PromptEntityResult per2 = ed.GetEntity(prOpt);
if (per2.Status != PromptStatus.OK) return;
PromptPointResult ppr =
ed.GetPoint("\nУкажите точку вставки нового блока: ");
if (ppr.Status != PromptStatus.OK) return;
Point3d pBase =
ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
PromptPointResult pprNew = ed.GetPoint("\nУкажите куда вставить этот блок: ");
if (pprNew.Status != PromptStatus.OK) return;
Point3d pIns = pprNew.Value.TransformBy(ed.CurrentUserCoordinateSystem);
PromptStringOptions prsOpt =
new PromptStringOptions("\nУкажите имя нового блока: ");
prsOpt.AllowSpaces = true;
PromptResult rss;
string blockName = "";
while ((rss = ed.GetString(prsOpt)) != null && rss.Status == PromptStatus.OK)
{
blockName = rss.StringResult;
if (SymbolUtilityServices.ValidateCompatibleSymbolName(blockName, true, false, false) != ErrorStatus.OK)
{
ed.WriteMessage("\nНедопустимое имя блока!");
continue;
}
else break;
}
if (rss.Status != PromptStatus.OK) return;
using (OpenCloseTransaction tr = new OpenCloseTransaction())
{
BlockTable bt =
tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
if (bt.Has(blockName))
{
ed.WriteMessage("\nБлок с таким именем уже есть!");
tr.Commit();
return;
}
BlockReference br1 = tr.GetObject(per1.ObjectId, OpenMode.ForRead) as BlockReference;
BlockReference br2 = tr.GetObject(per2.ObjectId, OpenMode.ForRead) as BlockReference;
DBObjectCollection col1 = new DBObjectCollection();
DBObjectCollection col2 = new DBObjectCollection();
DBObjectCollection col = new DBObjectCollection();
br1.Explode(col1); br2.Explode(col2);
List<string> tags = new List<string>();
foreach (DBObject obj in col1)
{
AttributeDefinition att = obj as AttributeDefinition;
if (att != null)
{
tags.Add(att.Tag);
}
col.Add(obj);
}
foreach (DBObject obj in col2)
{
AttributeDefinition att = obj as AttributeDefinition;
// Пропускаем одноименные атрибуты
if (att != null && tags.Contains(att.Tag)) continue;
col.Add(obj);
}
BlockTableRecord btr = new BlockTableRecord();
btr.Origin = Point3d.Origin;
btr.Name = blockName;
ObjectId btrId = bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, true);
foreach (DBObject obj in col)
{
Entity ent = obj as Entity;
if (ent != null)
{
Matrix3d mat = Matrix3d.Displacement(Point3d.Origin - pBase);
ent.TransformBy(mat);
btr.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
}
}
BlockTableRecord space =
tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
BlockReference br = new BlockReference(pIns, btrId);
space.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
foreach (ObjectId id in btr)
{
DBObject obj = tr.GetObject(id, OpenMode.ForRead);
if (obj is AttributeDefinition)
{
AttributeDefinition attDef = obj as AttributeDefinition;
if (!attDef.Constant)
{
using (AttributeReference attRef = new AttributeReference())
{
attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
br.AttributeCollection.AppendAttribute(attRef);
tr.AddNewlyCreatedDBObject(attRef, true);
}
}
}
}
tr.Commit();
}
}
}
}