When I try to insert a block with attributes in a side loaded dwg with the following code I get the error wrong database at the line brBlock.AttributeCollection.AppendAttribute(ar); . Can someone point me in the right direction of what I'm doing wrong? I have tried getting the getting the blocktablerecord from the blockreference but with no luck.
Thanks in advance.
using (Database targetDb = new Database(false, true))
{
using (Transaction tr = targetDb.TransactionManager.StartTransaction())
{
targetDb.ReadDwgFile(file, FileOpenMode.OpenForReadAndAllShare, true, "");
targetDb.CloseInput(true);
bool bFixErrors = true;
bool becho = true;
ImportAlstomFiles.TransformDwg.InsertTbmBlock(targetDb);
targetDb.Audit(bFixErrors, becho);
targetDb.SaveAs(file, DwgVersion.Current);
tr.Commit();
}
}
public class TransformDwg
{
public static void InsertTbm(Database db)
{
string[] files = Directory.GetFiles(@"C:\ProgramData\Autodesk\ApplicationPlugins\SpNwDo.bundle\Contents\Block\Alstom\", "*.dwg");
foreach (string file in files)
{
string blockname = Path.GetFileNameWithoutExtension(file);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Database tmpDb = new Database(false, true);
tmpDb.ReadDwgFile(file, FileShare.Read, true, "");
db.Insert(blockname, tmpDb, true);
tr.Commit();
}
}
Point3d insPoint = new Point3d();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open BlockTable and BlockTableRecord
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
// Retrieve the inserted block definition
BlockTableRecord btrBlock = tr.GetObject(bt["Alstom_TBM_DATA01_S_N"], OpenMode.ForRead) as BlockTableRecord;
// Loop through the inserted block references and retrieve attribute values
foreach (ObjectId btrId in btr)
{
if (btrId.ObjectClass.DxfName == "INSERT")
{
BlockReference br = tr.GetObject(btrId, OpenMode.ForWrite) as BlockReference;
SymbolTableRecord str = tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead) as SymbolTableRecord;
using (BlockReference brBlock = new BlockReference(insPoint, btrBlock.ObjectId))
{
btr.UpgradeOpen();
// Append the new BlockReference to PaperSpace
btr.AppendEntity(brBlock);
tr.AddNewlyCreatedDBObject(brBlock, true);
// Loop through BlockTableRecord to create AttributeReferences
foreach (ObjectId btrBlockId in btrBlock)
{
AttributeDefinition ad = tr.GetObject(btrBlockId, OpenMode.ForWrite) as AttributeDefinition;
if (ad != null)
{
// Create a new AttributeReference in the correct database (db)
using (AttributeReference ar = new AttributeReference())
{
// Set the attribute values and transformation
ar.SetAttributeFromBlock(ad, brBlock.BlockTransform);
// Update the text for each attribute based on collected values
if (ar.Tag == "AT_DATA_ZONE_N")
ar.TextString = zone;
if (ar.Tag == "AT_DATA_STATION_N")
ar.TextString = station;
if (ar.Tag == "AT_DATA_BLOCKNUM_N")
ar.TextString = blocknum;
if (ar.Tag == "AT_DATA_DESC3_S_N")
ar.TextString = lijn1;
if (ar.Tag == "AT_DATA_DESC4_S_N")
ar.TextString = lijn2;
if (ar.Tag == "AT_DATA_DESC5_S_N")
ar.TextString = lijn3;
// Add the AttributeReference to the BlockReference's AttributeCollection
brBlock.AttributeCollection.AppendAttribute(ar);
// Ensure the attribute is added to the transaction
tr.AddNewlyCreatedDBObject(ar, true);
}
}
}
}
}
}
}
}
}
When I try to insert a block with attributes in a side loaded dwg with the following code I get the error wrong database at the line brBlock.AttributeCollection.AppendAttribute(ar); . Can someone point me in the right direction of what I'm doing wrong? I have tried getting the getting the blocktablerecord from the blockreference but with no luck.
Thanks in advance.
using (Database targetDb = new Database(false, true))
{
using (Transaction tr = targetDb.TransactionManager.StartTransaction())
{
targetDb.ReadDwgFile(file, FileOpenMode.OpenForReadAndAllShare, true, "");
targetDb.CloseInput(true);
bool bFixErrors = true;
bool becho = true;
ImportAlstomFiles.TransformDwg.InsertTbmBlock(targetDb);
targetDb.Audit(bFixErrors, becho);
targetDb.SaveAs(file, DwgVersion.Current);
tr.Commit();
}
}
public class TransformDwg
{
public static void InsertTbm(Database db)
{
string[] files = Directory.GetFiles(@"C:\ProgramData\Autodesk\ApplicationPlugins\SpNwDo.bundle\Contents\Block\Alstom\", "*.dwg");
foreach (string file in files)
{
string blockname = Path.GetFileNameWithoutExtension(file);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Database tmpDb = new Database(false, true);
tmpDb.ReadDwgFile(file, FileShare.Read, true, "");
db.Insert(blockname, tmpDb, true);
tr.Commit();
}
}
Point3d insPoint = new Point3d();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Open BlockTable and BlockTableRecord
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
// Retrieve the inserted block definition
BlockTableRecord btrBlock = tr.GetObject(bt["Alstom_TBM_DATA01_S_N"], OpenMode.ForRead) as BlockTableRecord;
// Loop through the inserted block references and retrieve attribute values
foreach (ObjectId btrId in btr)
{
if (btrId.ObjectClass.DxfName == "INSERT")
{
BlockReference br = tr.GetObject(btrId, OpenMode.ForWrite) as BlockReference;
SymbolTableRecord str = tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead) as SymbolTableRecord;
using (BlockReference brBlock = new BlockReference(insPoint, btrBlock.ObjectId))
{
btr.UpgradeOpen();
// Append the new BlockReference to PaperSpace
btr.AppendEntity(brBlock);
tr.AddNewlyCreatedDBObject(brBlock, true);
// Loop through BlockTableRecord to create AttributeReferences
foreach (ObjectId btrBlockId in btrBlock)
{
AttributeDefinition ad = tr.GetObject(btrBlockId, OpenMode.ForWrite) as AttributeDefinition;
if (ad != null)
{
// Create a new AttributeReference in the correct database (db)
using (AttributeReference ar = new AttributeReference())
{
// Set the attribute values and transformation
ar.SetAttributeFromBlock(ad, brBlock.BlockTransform);
// Update the text for each attribute based on collected values
if (ar.Tag == "AT_DATA_ZONE_N")
ar.TextString = zone;
if (ar.Tag == "AT_DATA_STATION_N")
ar.TextString = station;
if (ar.Tag == "AT_DATA_BLOCKNUM_N")
ar.TextString = blocknum;
if (ar.Tag == "AT_DATA_DESC3_S_N")
ar.TextString = lijn1;
if (ar.Tag == "AT_DATA_DESC4_S_N")
ar.TextString = lijn2;
if (ar.Tag == "AT_DATA_DESC5_S_N")
ar.TextString = lijn3;
// Add the AttributeReference to the BlockReference's AttributeCollection
brBlock.AttributeCollection.AppendAttribute(ar);
// Ensure the attribute is added to the transaction
tr.AddNewlyCreatedDBObject(ar, true);
}
}
}
}
}
}
}
}
}
Share
Improve this question
asked Mar 19 at 8:29
PluribusPluribus
154 bronze badges
2 Answers
Reset to default 0The transaction used to insert the new block reference is not commited.
public static ObjectId InsertBlockReference(Database db, string blockName, Point3d position, Dictionary<string, string> attribValues)
{
var brId = ObjectId.Null;
using (var tr = db.TransactionManager.StartTransaction())
{
// Get the BlockTable
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
// Check if the BlockTable contains the block definition
if (bt.Has(blockName))
{
// Get the model space
var modelSpace = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
// Insert a new block reference
var br = new BlockReference(position, bt[blockName]);
brId = modelSpace.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
// Add attribute references to the block reference
// Get the block definition
var btr = (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead);
// Get all attribute definitions in the block definition
var attDefClass = RXObject.GetClass(typeof(AttributeDefinition));
foreach (ObjectId id in btr)
{
if (id.ObjectClass == attDefClass)
{
var attDef = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead);
// if the attribute definition is not constant, create a new attribute reference
if (!attDef.Constant)
{
var attRef = new AttributeReference();
attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
if (attribValues != null && attribValues.ContainsKey(attDef.Tag))
{
attRef.TextString = attribValues[attDef.Tag];
}
br.AttributeCollection.AppendAttribute(attRef);
tr.AddNewlyCreatedDBObject(attRef, true);
}
}
}
}
tr.Commit();
}
return brId;
}
public static void InsertTbm(Database db)
{
string[] files = Directory.GetFiles(@"C:\ProgramData\Autodesk\ApplicationPlugins\SpNwDo.bundle\Contents\Block\Alstom\", "*.dwg");
foreach (string file in files)
{
string blockname = Path.GetFileNameWithoutExtension(file);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Database tmpDb = new Database(false, true);
tmpDb.ReadDwgFile(file, FileShare.Read, true, "");
db.Insert(blockname, tmpDb, true);
tr.Commit();
}
}
var attribValues = new Dictionary<string, string>
{
["AT_DATA_ZONE_N"] = zone,
["AT_DATA_STATION_N"] = station,
["AT_DATA_BLOCKNUM_N"] = blocknum,
["AT_DATA_DESC3_S_N"] = lijn1,
["AT_DATA_DESC4_S_N"] = lijn2,
["AT_DATA_DESC4_S_N"] = lijn3
};
InsertBlockReference(db, "Alstom_TBM_DATA01_S_N", Point3d.Origin, attribValues);
}
Added the line ar.SetDatabaseDefaults(db); problem is now resolved