AutoCAD API C# detach xref current drawing

AutoCAD API C# detach xref current drawing

Anonymous
Not applicable
3,678 Views
7 Replies
Message 1 of 8

AutoCAD API C# detach xref current drawing

Anonymous
Not applicable

Hello All,

 

 Here is what I am trying,

I am tryign to get the list of all th xref in the current drawing and then detach broken and resolved xref from a wpf ui.

 

Examples specified everywhere makes the user select the xref from the drawing not geting the objId from the db.

 

When i try to pick from the screen.

 

Xref ID: (8796084459232)
Xref Handle: 28BDE

 

when i get object id using code I get differnt handle and object ID

XREF ID >>: (8796084449504) || 28A8E

 

if i try to detach xref usign this handle or object id it shows fatal exception.

Could someone help me with some code snippet on how to get the right handle for the xref in the current drawing using code and detach without user interaction to pick the xref from the screen.

0 Likes
3,679 Views
7 Replies
Replies (7)
Message 2 of 8

Jeff_M
Consultant
Consultant
This reply to a post of yours a few years ago looks like it should work with the current drawing as well, and does not require user to select the xref.
http://forums.autodesk.com/t5/net/net-c-unable-to-detaching-filenotfound-xref-without-opening-the/m-...
Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 3 of 8

Anonymous
Not applicable

Thanks Jeff,

 

 Here is what I am trying to do,

 

My plugin when runs it gets the list of xrefs in the current drawing using the following code

 

public static void printchildren1(GraphNode i_root, string i_indent, Editor i_ed, Transaction i_Tx, Database db,  Document doc)
	{
	int workingcount = 0;
	string host = ZACAD14GenHelper.getDWGPath(doc);
	for (int r = 0; r < i_root.NumOut; r++)
	{
		
		XrefGraphNode child = i_root.Out(r) as XrefGraphNode;
		
		string xref = child.Name + child.XrefStatus.ToString();
		Global.variables.ed.WriteMessage("\n : " + xref);
		
		if (child.XrefStatus == XrefStatus.Resolved)
		{
			BlockTableRecord blk = i_Tx.GetObject(child.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
			printchildren1(child, "| " + i_indent, i_ed, i_Tx, db, doc);
			workingcount += 1;
			Global.XrefObj.XrefItem item = new Global.XrefObj.XrefItem() { FileName = child.Name, FileStatus = child.XrefStatus.ToString(), XrefNode = child, xrefHandle = child.BlockTableRecordId.Handle };
			Global.variables.Xreflist.Add(item);
			Global.variables.ed.WriteMessage("\nXREF ID >>: " + blk.ObjectId + " || " + blk.Handle);
		}
		else
		{
			continue;
		}
		Global.variables.ed.WriteMessage("\n=======================================================\n");
	}

 

Which is displayed in a wpf window where user can pick an xref and detach if he wants to.

Now when i try to detach usign the object id from the stored node its giving fatal exception.

 

 

0 Likes
Message 4 of 8

Anonymous
Not applicable

Jeff,

 

 If you take a look at my previous post where I am opening the parent drawing in another another drawing and then i am detaching. All the examples doing the same. 

 

I want to detach in the drawing which is currently open and the plugin runs in the current open drawing.

 

I tried several way and none of them work. Atleast of you let me know how to get the correct object id of the xref object that would be fine.

0 Likes
Message 5 of 8

Jeff_M
Consultant
Consultant
It appears that you are attempting to delete nested Xrefs. I don't think that is possible without opening the source database and deleting from there.
Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 6 of 8

Anonymous
Not applicable

Jeff,

 

 Here is the image of the app.

 

As you can see the xref are in the current drawing not nested within another xref drawing.

 I want detach the xref in the main drawing.

 

4-17-2015 11-35-54 AM.png

 

I am able to do it picking the xref using the following code but not using the wpf window.

 

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

            // Select an external reference

            Transaction tr =
              db.TransactionManager.StartTransaction();
            using (tr)
            {
                BlockTableRecord btr = null;
                ObjectId xrefId = ObjectId.Null;

                // We'll loop, as we need to open the block and
                // underlying definition to check the block is
                // an external reference during selection

                do
                {
                    PromptEntityOptions peo =
                      new PromptEntityOptions(
                        "\nSelect an external reference:"
                      );
                    peo.SetRejectMessage("\nMust be a block reference.");
                    peo.AddAllowedClass(typeof(BlockReference), true);

                    PromptEntityResult per = ed.GetEntity(peo);
                    if (per.Status != PromptStatus.OK)
                        return;

                    // Open the block reference

                    BlockReference br =
                      (BlockReference)tr.GetObject(
                        per.ObjectId,
                        OpenMode.ForRead
                      );

                    // And the underlying block table record

                    btr =
                      (BlockTableRecord)tr.GetObject(
                        br.BlockTableRecord,
                        OpenMode.ForRead
                      );

                    // If it's an xref, store its ObjectId

                    if (btr.IsFromExternalReference)
                    {
                        ed.WriteMessage("\nXref ID: " + br.BlockTableRecord.ToString());
                        xrefId = br.BlockTableRecord;
                    }
                    else
                    {
                        // Otherwise print a message and loop

                        ed.WriteMessage(
                          "\nMust be an external reference."
                        );
                    }
                }
                while (!btr.IsFromExternalReference);

                // If we have a valid ObjectID for the xref, detach it

                if (xrefId != ObjectId.Null)
                {
                    db.DetachXref(xrefId);
                    ed.WriteMessage("\nExternal reference detached.");
                }

                // We commit the transaction simply for performance
                // reasons, as the detach is independent

                tr.Commit();
            }
        }

 

I want to select the Xref from the WPF window and detach.

Let me know if you have any ideas.

0 Likes
Message 7 of 8

Jeff_M
Consultant
Consultant

This simple code worked for me to detach Unresolved Xrefs.

        [CommandMethod ("DetachBadXrefs")]
        public void detachbadxrefs()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForRead);
                foreach (ObjectId id in bt)
                {
                    BlockTableRecord btr = (BlockTableRecord)id.GetObject(OpenMode.ForRead);
                    if(btr.XrefStatus != XrefStatus.NotAnXref && btr.XrefStatus != XrefStatus.Resolved)
                    {
                        db.DetachXref(id);
                    }
                }
                tr.Commit();
            }
        }

 

Jeff_M, also a frequent Swamper
EESignature
Message 8 of 8

antonio.leonardo
Advocate
Advocate

Hi,

 

Tested from Plant 2018 and after.

 

For detach xrefs that's classified as Autodesk files (like .dwg, .dwt etc), I use this code:

Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.Command("-XREF", "D", "*");

For Point Cloud References, I use this code:

Database db = Application.DocumentManager.MdiActiveDocument;
Transaction tr = db.TransactionManager.StartTransaction();
ObjectIdCollection pointCloudIds = null;
ObjectIdCollection pointCloudIds = null;
DBDictionary nos = null;
DBDictionary subDictionaryPointCloudDefExDic = null;
try
{
    this._listenerLog.Info("    Obtém os objetos responsáveis pelos Xrefs Nuvens de Pontos, para o DWG " + _acDoc.Name);
    pointCloudIds = new ObjectIdCollection();
    nos = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
    if (nos.Contains("ACAD_POINTCLOUD_EX_DICT"))
    {
        subDictionaryPointCloudDefExDic =
        (DBDictionary)tr.GetObject(nos.GetAt("ACAD_POINTCLOUD_EX_DICT"), OpenMode.ForRead);

        this._listenerLog.Info("    Inicia iteração sob todos os Xrefs do tipo Nuvem de Pontos para o DWG " + _acDoc.Name);
        foreach (DBDictionaryEntry entry in subDictionaryPointCloudDefExDic)
        {
            pointCloudIds.Add(entry.Value);
        }
        this._listenerLog.Info("    Remove todos as Nuvens de Pontos (através de 'Erase' e 'Purge'), para o DWG " + _acDoc.Name);
        if (pointCloudIds.Count > 0)
        {
            foreach (ObjectId id in pointCloudIds)
            {
                DBObject obj = tr.GetObject(id, OpenMode.ForWrite);
                obj.Erase();
            }
            db.Purge(pointCloudIds);
        }
    }
}
catch (Exception ex)
{
    this._listenerLog.Error("    Surgiu uma falha inesperada durante a iteração sob os Xrefs do tipo Nuvem de Pontos para o DWG " + _acDoc.Name);
    this._listenerLog.FatalError(ex);
    throw new Exception("Falha durante operação de remoção de XREFs do tipo Nuvem de Pontos.", ex);
}
finally
{
    if (null != pointCloudIds)
    {
        pointCloudIds.Dispose();
    }
}

 

To remove raster image, is recommended use this StackOverflow link:
How to delete a RasterImage in autocad using .NET [closed]

 

Att,

Antonio Leonardoexam-483-programming-in-c.png