
Not applicable
05-12-2021
05:22 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello,
I'm currenty facing to an issue, I'm able to create a block, more precisely the user can select the type of tree, and insert into the drawing (it is a cercle with a specific label inside). To do that, I use the code below :
- I get the tree type, the current layout
- Then I initialise my tree class which contains some properties.
- I check if the block already exist in the drawing, if it not the case I create a new block.
- Finaly I create a block reference base on the previous step and I add it to the model space.
I would like offer the possibily to the user to change the type of tree if he clics on a specific block in drawing. To do that the easy way I think, should be to erase the current block reference and re-create another one with the new parameters but I could not find a way to do that.
public static void DrawTreeInsert(LA_Layout la_layout, TypeLOD1 treeType)
{
// Get the current document and database
Document doc = AcAp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
//Change le focus Palette vers Viewport
doc.Window.Focus();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
using (doc.LockDocument())
{
#region Initialization
//Create tree
S_Tree tree = new S_Tree(treeType.Type, la_layout);
//Parameters
tree.typeLOD1 = treeType;
double treeRadius = 5;
string blkName = treeType.Type + "_Arbre";
Matrix3d matrixLayout = Matrix_Helper.MatrixAcad_BuilderFromS_Matrix(la_layout.Matrix);
//Create or get layer
S_Layer layer = Layers_Helper.CreateLayer(db,
la_layout.Name + ".Arbre",
Autodesk.AutoCAD.Colors.Color.FromRgb(23, 54, 232),
ObjectId.Null
);
#endregion
#region coordinate
// Prompt the user for 1 point
PromptPointResult pPtRes;
PromptPointOptions pPtOpts = new PromptPointOptions("\nInsertion d'arbre en ");
pPtRes = doc.Editor.GetPoint(pPtOpts);
if (pPtRes == null) return;
Point3d pointInsert = new Point3d(pPtRes.Value.X, pPtRes.Value.Y, pPtRes.Value.Z);
S_Point3D s_pointInsert = new S_Point3D(pointInsert.X, pointInsert.Y, pointInsert.Z);
// Exit if the user presses ESC or cancels the command
if (pPtRes.Status == PromptStatus.Cancel) return;
#endregion
#region Block
//---------------------- Get or create custum Block ----------------------//
//
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
bool blkExist = Blocks_Helper.BlockExistsInDrawing(blkName, db, out ObjectId blockId);
// Retourn True if the block exist,
// ObjectId out : if block exist return block's id, else return ObjectId.Null
if (blkExist == false)
{
// Create new block and set properties
using (BlockTableRecord btr = new BlockTableRecord())
{
btr.Name = blkName;
// Add the new block to the block table
bt.UpgradeOpen();
bt.Add(btr);
blockId = btr.Id;
tr.AddNewlyCreatedDBObject(btr, true);
// Add the entities belong directly to the block
DBObjectCollection ents = DrawBlockTree(treeRadius, tree.Type, Point3d.Origin);
foreach (Entity ent in ents)
{
btr.UpgradeOpen();
btr.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
tree.BlckEntitiesHandle.Add(ent.Handle.ToString());
}
// Report
ed.WriteMessage("\nCreated block named \"{0}\" containing {1} entities.", blkName, ents.Count);
}
}
//---------------------- Add block reference to the model space ----------------------//
if (blockId != ObjectId.Null)
{
using (BlockReference BlkRef = new BlockReference(pointInsert, blockId))
{
BlockTableRecord curentSpaceBTR = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
// Edit block reference
BlkRef.LayerId = layer.LayerId.Value;
BlkRef.TransformBy(matrixLayout);
// Add block reference to model space
curentSpaceBTR.AppendEntity(BlkRef);
tr.AddNewlyCreatedDBObject(BlkRef, true);
#region Data Management
//Update tree data
ObjectId objId = BlkRef.Id;
tree.BlkRefHandle = objId.Handle.ToString();
//Associate element's Id to AutoCAD block thanks to Xdata
LA_Data_Helper.WriteLADataXML_to_AcadObject(doc, objId, tree);
#endregion
#region EventHandler
BlkRef.Erased += (s, e) => EventHandler_Actions.EraseTree(la_layout, tree);
#endregion
}
}
#endregion
//Add the new tree to the database
tree.Point = s_pointInsert;
la_layout.Trees.Add(tree);
}
tr.Commit();
}
}
Here is my try to erase the bock selected by the user but it does not work, I did many try but I think I miss an important point :
public static void DrawTreeChange(LA_Layout la_layout, TypeLOD1 newTreeType)
{
// Get the current document and database
Document doc = AcAp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
doc.Window.Focus();
var options = new PromptEntityOptions("\nSelectionner le block définissant l'objet : ");
var result = ed.GetEntity(options);
if (result.Status == PromptStatus.OK)
{
FindTree(result.ObjectId.Handle.ToString(), out LA_Layout layoutTree, out S_Tree drewTree);
// Get from the prompt result the layout and the tree
if (drewTree != null)
{
using (doc.LockDocument())
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// open the block table which contains all the BlockTableRecords (block definitions and spaces)
var blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
// open the model space BlockTableRecord
var modelSpace = (BlockTableRecord)tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);
// try to erase the entities wich belong to the old tree block
BlockTableRecord btRecord = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
foreach (ObjectId id in btRecord)
{
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
foreach (string entHdl in drewTree.BlckEntitiesHandle)
{
if (entity.Handle.ToString() == entHdl)
{
entity.Erase();
}
}
}
// iterate through the model space to erase the block referense to
foreach (ObjectId id in modelSpace)
{
// check if the current ObjectId is a block reference wich belong to the old tree block
if (id.ObjectClass.DxfName == "INSERT")
{
// open the block reference
var blckRef = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
if (blckRef.Handle.ToString() == drewTree.BlkRefHandle)
{
// print the block name to the command line
ed.WriteMessage("\n" + blckRef.Name);
blckRef.UpgradeOpen();
blckRef.Erase();
}
}
}
}
}
}
}
}
Thanks for your help,
Alexis
Solved! Go to Solution.