Author Topic: Draw some lines with XRecord, how to judge a line has XRecord or not?  (Read 1850 times)

0 Members and 1 Guest are viewing this topic.

waterharbin

  • Guest
Hi,
With the help of gile, I learn how to draw some lines with XRecord in this post: http://www.theswamp.org/index.php?topic=42203.msg473381#msg473381.
Now I have a new question: how to judge a line has XRecord or not. Because I need to select all the lines in a drawing.
Here is how to draw lines with XRecord:
Code: [Select]
Public Shared Function AddLine(ByVal startPt As Point3d, ByVal endPt As Point3d, ByVal Color As Integer, _
                                   ByVal Name As String, ByVal Length As String, ByVal Top As String, ByVal Bottom As String) As ObjectId
        Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
        Dim db As Database = HostApplicationServices.WorkingDatabase

        'the objectId will be retured
        Dim retVal As ObjectId = ObjectId.Null()

        Using trans As Transaction = db.TransactionManager.StartTransaction

            'Define the line   
            Dim acLine As Line = New Line
            acLine.StartPoint = startPt
            acLine.EndPoint = endPt
            acLine.ColorIndex = Color

            Dim btr As BlockTableRecord = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
            retVal = btr.AppendEntity(acLine)
            trans.AddNewlyCreatedDBObject(acLine, True)


            Dim Xrec As New Xrecord()
            Xrec.Data = New ResultBuffer( _
                        New TypedValue(DxfCode.Text, Length), _
                        New TypedValue(DxfCode.Text, Top), _
                        New TypedValue(DxfCode.Text, Bottom))

            acLine.CreateExtensionDictionary()
            Dim xDict As DBDictionary = trans.GetObject(acLine.ExtensionDictionary, OpenMode.ForWrite)
            xDict.SetAt(Name, Xrec)
            trans.AddNewlyCreatedDBObject(Xrec, True)

            trans.Commit()
        End Using
        Return retVal

    End Function
Call the function to draw lines by something like:
Code: [Select]
Dim DoorIdCol As ObjectIdCollection = New ObjectIdCollection()
Dim WindowIdCol As ObjectIdCollection = New ObjectIdCollection()

'The arguments(Name not included) come form a form by user's inputing, that why they are String not Double
Dim DoorId = AddLine(pt1,pt2,1,"Door", "2000","400","800") 
DoorIdCol.Add(DoorId)
Dim WindowId = AddLine(pt3,pt4,2,"Window","2200","400","0")
WindowIdCol.Add(WindowId)
I used to define ObjectIdCollections to hold the returned Ids everytime I draw one line, and get the XRecord back via the Ids. Now I found there is a loophole in this way: I use the Ids to get the XRecord back for the firt time, and in some cases, the ObjectIdCollections need to be cleared.Then, all the Ids are lost, I can not get the XRecord back again for a second use. So I wonder can I get the XRecord back by selecting the lines on the screen?  Then I can get the XRecord back everytime I want.
Here is what I get at the present:
Code: [Select]
public void selectLine(ObjectIdCollection DoorIdCol,ObjectIdCollection WindowIdCol)
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                try
                {
                    TypedValue[] tv = new TypedValue[] { new TypedValue((int)DxfCode.Start, "LINE") };
                    SelectionFilter flt = new SelectionFilter(tv);

                    PromptSelectionOptions optSel = new PromptSelectionOptions();
                    optSel.MessageForAdding = "Select Lines";
                    PromptSelectionResult resSel = ed.GetSelection(optSel, flt);

                    if (resSel.Status != PromptStatus.OK)
                    {
                        return false;
                    }

                    SelectionSet selSet = resSel.Value;
                    ObjectId[] ids = selSet.GetObjectIds();

                    foreach (ObjectId sSetEntId in ids)
                    {
                        Entity ent = (Entity)trans.GetObject(sSetEntId, OpenMode.ForWrite);
                        if (ent.GetType().Name == "Line")
                        {
                            Line myLine = (Line)trans.GetObject(sSetEntId, OpenMode.ForWrite);  //get the line back
                            //How to judge this line has XRecord or not? If it has,how can I know it's a "Door" or a "Window"?
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage(ex.Message + "\n" + ex.StackTrace);
                    return false;
                }

                trans.Commit();               
            }
        }
Maybe I can get the Ids back by selcting the lines on the screen,everytime I need the Lines with XRecord, I select them on the screen, and get them Ids back.
« Last Edit: September 04, 2012, 09:11:09 AM by 闻仲 »

bargool

  • Guest
Re: Draw some lines with XRecord, how to judge a line has XRecord or not?
« Reply #1 on: September 04, 2012, 10:04:20 AM »
Here is my extension method to get XRecord from object
Code: [Select]
/// <summary>
/// Returns Xrecord
/// </summary>
/// <param name="o">Object with Xrecord</param>
/// <param name="xrecordName">The name of Xrecord</param>
/// <returns>ResultBuffer with values of given Xrecord, or null, if object has not given Xrecord</returns>
public static ResultBuffer GetXrecord(this DBObject o, string xrecordName)
{
if (xrecordName == null)
throw new ArgumentNullException("xrecordName is null");
if (o.ExtensionDictionary != ObjectId.Null &&
    !o.ExtensionDictionary.IsErased)
{
using (DBDictionary dict = (DBDictionary)o.ExtensionDictionary.GetObject(OpenMode.ForRead))
{
if (dict.Contains(xrecordName))
{
Xrecord xrecord = dict.GetAt(xrecordName).GetObject(OpenMode.ForRead) as Xrecord;
if (xrecord != null)
return xrecord.Data;
}
}
}
return null;
}
So, if it returns null - object hasn't given XRecord. Or you can iterate through ExtensionDictionary keys and see all XRecords