.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Tag Parameter Updating the Dynamically in all CAD Sessions

1 REPLY 1
Reply
Message 1 of 2
vivekanandanXVLYD
105 Views, 1 Reply

Tag Parameter Updating the Dynamically in all CAD Sessions

using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;


[assembly: CommandClass(typeof(DuctBlockTagger.Plugin))]

namespace DuctBlockTagger
{
public class Plugin
{
private Dictionary<ObjectId, ObjectId> blockToTextMap = new Dictionary<ObjectId, ObjectId>();
private ObjectId textStyleId;
private string layer;
private double textHeight;

[CommandMethod("DT")]
public void DuctTagger()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;

// Check if the sample MText properties are set
if (textStyleId == ObjectId.Null || string.IsNullOrEmpty(layer) || textHeight <= 0)
{
ed.WriteMessage("\nSample MText parameters not set. Use the ST command to set them.");
return;
}

using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Prompt user to select multiple duct block references
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.MessageForAdding = "\nSelect duct block references: ";
pso.RejectObjectsOnLockedLayers = true;
SelectionFilter filter = new SelectionFilter(new TypedValue[] { new TypedValue((int)DxfCode.Start, "INSERT") });
PromptSelectionResult psr = ed.GetSelection(pso, filter);

if (psr.Status != PromptStatus.OK)
{
ed.WriteMessage("\nNo valid duct block references selected.");
return;
}

// Process each selected block reference
foreach (SelectedObject selObj in psr.Value)
{
if (selObj != null)
{
BlockReference blkRef = tr.GetObject(selObj.ObjectId, OpenMode.ForRead) as BlockReference;
if (blkRef != null)
{
// Get duct parameters
double cfm = GetPropertyValue(blkRef, "CFM");
double width = GetPropertyValue(blkRef, "Width");
double height = GetPropertyValue(blkRef, "Height");

// Check if parameters are valid
if (cfm <= 0 || width <= 0 || height <= 0)
{
ed.WriteMessage($"\nError: Duct parameters for block {blkRef.Handle} cannot be zero or negative.");
continue;
}

// Construct tag value
string tagValue = $"{cfm} CFM,\n{width} x {height} mm";

// Calculate the center of the block reference
Point3d tagPosition = GetBlockReferenceCenter(blkRef);

// Create text annotation using MText
ObjectId mTextId = CreateTextAnnotation(tagValue, tagPosition, tr, db.BlockTableId, textStyleId, layer, textHeight);

// Map block reference to MText for future updates
blockToTextMap[blkRef.ObjectId] = mTextId;

// Subscribe to BlockReference modification event
blkRef.Modified += new EventHandler(OnBlockReferenceModified);
}
}
}

tr.Commit();
}
}

[CommandMethod("ST")]
public void SetSampleText()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;

// Ask user to select a sample MText for parameters
PromptEntityOptions mtextPeo = new PromptEntityOptions("\nSelect a sample MText for parameters: ");
mtextPeo.SetRejectMessage("\nInvalid selection. Please select an MText entity.");
mtextPeo.AddAllowedClass(typeof(MText), true);
PromptEntityResult mtextPer = ed.GetEntity(mtextPeo);

if (mtextPer.Status != PromptStatus.OK)
{
ed.WriteMessage("\nNo valid MText selected.");
return;
}

using (Transaction tr = db.TransactionManager.StartTransaction())
{
MText sampleMText = tr.GetObject(mtextPer.ObjectId, OpenMode.ForRead) as MText;

if (sampleMText == null)
{
ed.WriteMessage("\nInvalid MText entity selected.");
return;
}

// Store the MText properties for future use
textStyleId = sampleMText.TextStyleId;
layer = sampleMText.Layer;
textHeight = sampleMText.TextHeight;

ed.WriteMessage("\nSample MText parameters set successfully.");
tr.Commit();
}
}

private double GetPropertyValue(BlockReference blkRef, string propertyName)
{
foreach (DynamicBlockReferenceProperty prop in blkRef.DynamicBlockReferencePropertyCollection)
{
if (prop.PropertyName.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase))
{
return Convert.ToDouble(prop.Value);
}
}
return 0;
}

private Point3d GetBlockReferenceCenter(BlockReference blkRef)
{
Extents3d extents = blkRef.GeometricExtents;
Point3d center = new Point3d(
(extents.MinPoint.X + extents.MaxPoint.X) / 2,
(extents.MinPoint.Y + extents.MaxPoint.Y) / 2,
(extents.MinPoint.Z + extents.MaxPoint.Z) / 2
);
return center;
}

private ObjectId CreateTextAnnotation(string tagValue, Point3d tagPosition, Transaction tr, ObjectId blockTableId, ObjectId textStyleId, string layer, double textHeight)
{
BlockTable bt = tr.GetObject(blockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

// Create a new MText entity for the tag
using (MText mText = new MText())
{
mText.Location = tagPosition;
mText.TextHeight = textHeight;
mText.Contents = tagValue;
mText.TextStyleId = textStyleId;
mText.Layer = layer;
mText.SetDatabaseDefaults();

// Add the MText entity to the model space
btr.AppendEntity(mText);
tr.AddNewlyCreatedDBObject(mText, true);

return mText.ObjectId;
}
}

private void OnBlockReferenceModified(object sender, EventArgs e)
{
BlockReference blkRef = sender as BlockReference;
if (blkRef == null)
return;

Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;

using (Transaction tr = db.TransactionManager.StartTransaction())
{
try
{
UpdateTextAnnotation(blkRef, tr);
tr.Commit();
}
catch (System.Exception ex)
{
Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog($"Error updating annotation: {ex.Message}");
}
}
}

private void UpdateTextAnnotation(BlockReference blkRef, Transaction tr)
{
if (!blockToTextMap.ContainsKey(blkRef.ObjectId))
return;

ObjectId mTextId = blockToTextMap[blkRef.ObjectId];
MText mText = tr.GetObject(mTextId, OpenMode.ForWrite) as MText;

if (mText != null)
{
double cfm = GetPropertyValue(blkRef, "CFM");
double width = GetPropertyValue(blkRef, "Width");
double height = GetPropertyValue(blkRef, "Height");

if (cfm > 0 && width > 0 && height > 0)
{
mText.Contents = $"{cfm} CFM,\n{width} x {height} mm";
}
}
}
}
}

 

 

in this above code i can extract parameter value and i can modify the Mtext as a annotation dynamically but this plug in code only working in one time i need to work on Multiple Autocad Sessions. Kindly help anyone where i need to change and what line  i need to modify

1 REPLY 1
Message 2 of 2

If you post code here and you want someone to look at it, you need to use the insert code button on the toolbar so that the code is formatted and readable. 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report