Author Topic: Something about Xref functions...  (Read 9010 times)

0 Members and 1 Guest are viewing this topic.

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Something about Xref functions...
« Reply #15 on: November 03, 2008, 01:07:04 AM »
Each Layout has property Autodesk.AutoCAD.DatabaseServices.Layout.BlockTableRecordId
Open BlockTableRecord with this Id and iterate it.

cadpro

  • Guest
Re: Something about Xref functions...
« Reply #16 on: November 04, 2008, 02:04:09 AM »
The code given in this thread does not change the attached xrefs to overlayed if it is inserted in multiple layouts. Any solution to this issue?

Bryco

  • Water Moccasin
  • Posts: 1850
Re: Something about Xref functions...
« Reply #17 on: November 12, 2008, 12:34:11 AM »
Luis I've added a bit to your code and this seems to work.
The array is the only way I could figure out how to do it, as I didn't want to do the whole mum, dad, orphan thing (Get,set).
I would cringe at using object in vba but I don't know if that is costly in C#.
Xclip is something I'll have to learn next.
If you have a better way please let me know.

Code: [Select]
        [CommandMethod("OVERLAY")]
        public void attachTooverlay()
        {
            Document doc =acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            PromptEntityOptions peo = new PromptEntityOptions("\nSelect xref: ");
            peo.SetRejectMessage("Must be an x-ref");
            peo.AddAllowedClass(typeof(BlockReference), true);

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

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {               
                BlockReference br = tr.GetObject
                    (res.ObjectId, OpenMode.ForWrite) as BlockReference;
                BlockTableRecord btr = tr.GetObject
                    (br.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                if (!btr.IsFromExternalReference)
                {
                    MessageBox.Show("not an x-ref");
                    return;
                }
                if (btr.IsFromOverlayReference) return;

                XrefStatus xstatus=btr.XrefStatus;
                BlockScaling bs=btr.BlockScaling;
                bool bLoaded=btr.IsUnloaded;   
                UnitsValue uv = btr.Units;
                string fileName =btr.PathName;
                string blockName = btr.Name;

                ObjectIdCollection ids = btr.GetBlockReferenceIds(true, true);
                int ct = ids.Count;
                object[][] ob =new object[ct][];

                for (int i = 0; i < ct; i++)
                {
                    BlockReference xref = tr.GetObject
                        (ids[i], OpenMode.ForRead) as BlockReference;
                    BlockTableRecord xtr = tr.GetObject(
                        xref.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                    ob[i] = new object[7];
                    ob[i][0] = xref.Position;
                    ob[i][ 1] = xref.Rotation;
                    ob[i][ 2] = xref.Layer;
                    ob[i][ 3] = xref.ColorIndex;
                    ob[i][ 4] = xref.ScaleFactors;
                    ob[i][5] = xref.OwnerId;
                    ob[i][6] = xref.Normal;
                   //db.XclipFrame
   
                    xref.UpgradeOpen();
                    xref.Erase();

                }
                db.DetachXref(btr.Id);


                for (int i = 0; i < ct; i++)
                {
                    using(Transaction tr2=db.TransactionManager.StartTransaction())
                    {
                        ObjectId xrefId = db.OverlayXref(fileName, blockName);
                        btr = (BlockTableRecord)tr2.GetObject(xrefId, OpenMode.ForWrite);
                        BlockTableRecord space = (BlockTableRecord)tr2.GetObject(
                            (ObjectId)ob[i][5], OpenMode.ForWrite);
                        br = new BlockReference((Point3d)ob[i][0], btr.ObjectId);
                        br.Rotation = (double)ob[i][1];
                        br.Layer = (string)ob[i][2];   
                        br.ColorIndex = (int)ob[i][3];
                        br.ScaleFactors=(Scale3d) ob[i][4];
                        br.Normal = (Vector3d)ob[i][6];
                        space.AppendEntity(br);
                        tr.AddNewlyCreatedDBObject(br, true);
                        db.ResolveXrefs(true, true);
                        tr2.Commit();
                    }   
                }


                tr.Commit();
            }
        }//end attachTooverlay

T.Willey

  • Needs a day job
  • Posts: 5218
Re: Something about Xref functions...
« Reply #18 on: November 12, 2008, 01:05:22 AM »
Can't think of another way to do it right now, but with Lisp the xclip information is store within the extension dictionary, so I would figure its the same with .Net, but haven't looked into it yet.  Here is the Lisp code to get the xclip information.]

Code: [Select]
(defun GetSpatialFilter (ename / Data Dict tempDict)
    ; Get the xclip boundry
   
    (if
        (and
            (setq Data (entget ename))
            (setq Dict (cdr (assoc 360 Data)))
            (setq tempDict (dictsearch Dict "ACAD_FILTER"))
            (setq tempDict (dictsearch (cdr (assoc -1 tempDict)) "SPATIAL"))
        )
        (cons '(0 . "SPATIAL_FILTER") (member (assoc 100 tempDict) tempDict))
    )
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Bryco

  • Water Moccasin
  • Posts: 1850
Re: Something about Xref functions...
« Reply #19 on: November 15, 2008, 03:25:35 PM »
Well this took a while, I was messing with xrecords when I shouldn't have bothered. Tim I don't know lisp but it looks like your lisp is looking for a dictionary within a dictionary (rather than an xrecord within a dictionary). I still can't figure out how to copyfrom or make the new dictionary=the old dictionary (this doesn't work maybe because the old dictionary is being deleted), there should be a more direct way than below.


Code: [Select]
        [CommandMethod("OVERLAY")]
        public void attachTooverlay()
        {
            Document doc =acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            PromptEntityOptions peo = new PromptEntityOptions("\nSelect xref: ");
            peo.SetRejectMessage("Must be an x-ref");
            peo.AddAllowedClass(typeof(BlockReference), true);

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

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {               
                BlockReference br = tr.GetObject
                    (res.ObjectId, OpenMode.ForWrite) as BlockReference;
                BlockTableRecord btr = tr.GetObject
                    (br.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                if (!btr.IsFromExternalReference)
                {
                    MessageBox.Show("not an x-ref");
                    return;
                }
                if (btr.IsFromOverlayReference) return;

                XrefStatus xstatus=btr.XrefStatus;
                BlockScaling bs=btr.BlockScaling;
                bool bLoaded=btr.IsUnloaded;   
                UnitsValue uv = btr.Units;
                string fileName =btr.PathName;
                string blockName = btr.Name;

                ObjectIdCollection ids = btr.GetBlockReferenceIds(true, true);
                int ct = ids.Count;
                object[][] ob =new object[ct][];

                for (int i = 0; i < ct; i++)
                {
                    BlockReference xref = tr.GetObject
                        (ids[i], OpenMode.ForRead) as BlockReference;
                    BlockTableRecord xtr = tr.GetObject(
                        xref.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
                    ob[i] = new object[8];
                    ob[i][0] = xref.Position;
                    ob[i][ 1] = xref.Rotation;
                    ob[i][ 2] = xref.Layer;
                    ob[i][ 3] = xref.ColorIndex;
                    ob[i][ 4] = xref.ScaleFactors;
                    ob[i][5] = xref.OwnerId;
                    ob[i][6] = xref.Normal;
                    ob[i][7] = xref.ExtensionDictionary;

                    ObjectId xclipId = xref.ExtensionDictionary;
                    xref.UpgradeOpen();
                    xref.Erase();
                    xref.DowngradeOpen();
                }
                db.DetachXref(btr.Id);

                ObjectId xrefId = db.OverlayXref(fileName, blockName);
                for (int i = 0; i < ct; i++)
                {

                    btr = (BlockTableRecord)tr.GetObject(xrefId, OpenMode.ForWrite);
                    BlockTableRecord space = (BlockTableRecord)tr.GetObject(
                        (ObjectId)ob[i][5], OpenMode.ForWrite);
                    br = new BlockReference((Point3d)ob[i][0], btr.ObjectId);
                    br.Rotation = (double)ob[i][1];
                    br.Layer = (string)ob[i][2];   
                    br.ColorIndex = (int)ob[i][3];
                    br.ScaleFactors=(Scale3d) ob[i][4];
                    br.Normal = (Vector3d)ob[i][6];
                    ObjectId xclipId =(ObjectId) ob[i][7];
                    space.AppendEntity(br);
                    tr.AddNewlyCreatedDBObject(br, true);
                    if (! xclipId.IsNull)
                    {
                        br.CreateExtensionDictionary();
                        DBDictionary XclipDic = tr.GetObject
                            (br.ExtensionDictionary,OpenMode.ForWrite) as DBDictionary;

                        DBDictionary dic = tr.GetObject(xclipId, OpenMode.ForRead) as DBDictionary;       
                        DBDictionary FilterDic = tr.GetObject
                            (dic.GetAt("ACAD_FILTER"), OpenMode.ForRead) as DBDictionary;                       
                        DBDictionary nd = new DBDictionary();
                        foreach (DictionaryEntry de in FilterDic)
                        {
                            nd.SetAt((string)de.Key, tr.GetObject((ObjectId) de.Value,OpenMode.ForWrite ) as DBObject);
                        }

                        XclipDic.SetAt("ACAD_FILTER", nd);
                        tr.AddNewlyCreatedDBObject(nd, true);

                    }
                }

                db.ResolveXrefs(true, true);
                tr.Commit();
             
            }
        }//end attachTooverlay

Bryco

  • Water Moccasin
  • Posts: 1850
Re: Something about Xref functions...
« Reply #20 on: November 15, 2008, 03:27:52 PM »
Cadpro did this work for you?

cadpro

  • Guest
Re: Something about Xref functions...
« Reply #21 on: November 16, 2008, 05:20:16 AM »
Cadpro did this work for you?

This works fine. But I need to overlay all attached xrefs inserted in layouts, without picking each xref. How do I go about it?

Thanks

Spike Wilbury

  • Guest
Re: Something about Xref functions...
« Reply #22 on: November 16, 2008, 10:19:32 AM »
Cadpro did this work for you?

This works fine. But I need to overlay all attached xrefs inserted in layouts, without picking each xref. How do I go about it?

Thanks

Have you done any code?

Spike Wilbury

  • Guest
Re: Something about Xref functions...
« Reply #23 on: November 16, 2008, 10:46:25 AM »
Luis I've added a bit to your code and this seems to work.
The array is the only way I could figure out how to do it, as I didn't want to do the whole mum, dad, orphan thing (Get,set).
I would cringe at using object in vba but I don't know if that is costly in C#.
Xclip is something I'll have to learn next.
If you have a better way please let me know.


Hi Bryco,

I just noticed your message.... I have been doing all of my code in C++/ARX - no time to play with C#, as soon I can, I will try to participate with some coding... if possible.

Cheers!

Bryco

  • Water Moccasin
  • Posts: 1850
Re: Something about Xref functions...
« Reply #24 on: November 16, 2008, 07:46:44 PM »
Hi Luis, no problem, I think I've taken that code far enough, of course I didn't give it any rigorous testing so it may be crap.
Also didn't try nested clips.

T.Willey

  • Needs a day job
  • Posts: 5218
Re: Something about Xref functions...
« Reply #25 on: November 17, 2008, 11:16:28 AM »
I'll see what I can do when I have some time.  I haven't really copied anything dictionary with C# yet, so it would be a good learning exercise.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Bryco

  • Water Moccasin
  • Posts: 1850
Re: Something about Xref functions...
« Reply #26 on: November 17, 2008, 02:38:39 PM »
Looking forward to seeing your findings Tim

T.Willey

  • Needs a day job
  • Posts: 5218
Re: Something about Xref functions...
« Reply #27 on: November 17, 2008, 07:47:04 PM »
This is all I had time for today.  Not sure if I will be able to get to it tomorrow, and I didn't test this, but it should show you want the process is that I'm thinking of going.  Hope it helps.  The idea was to use a test drawing with only one xref in it, and is inserted as many times as you want, and has an xclip associated with it ( which is the SpatialFilter object ).

Code: [Select]
public void TestXrefXClip {

DBDictionary tempDict;
ObjectId tempId;

Document Doc = AcadApp.DocumentManager.MdiActiveDocument;
Database Db = Doc.Database;
Editor Ed = Doc.Editor;
using ( Transaction Trans = Db.TransactionManager.StartTransaction() ) {
XrefGraph XrGph = Db.GetHostDwgXrefGraph(false);
XrefGraphNode XrNode = XrGph.GetXrefNode( 1 ) as XrefGraphNode;
BlockTableRecord BlkTblRec = Trans.GetObject( XrNode.BlockTableRecordId, OpenMode.ForRead ) as BlockTableRecord;
foreach ( ObjectId objId in BlkTblRec.GetBlockReferenceIds( true, true ) ) {
BlockReference BlkRef = Trans.GetObject( objId, OpenMode.ForRead ) as BlockReference;
tempDict = Trans.GetObject( BlkRef.ExtensionDictionary, OpenMode.ForRead ) as DBDictionary;
tempId = tempDict.GetAt( "ACAD_FILTER" ) as ObjectId;
if ( tempId == ObjectId.Null )
return;
tempDict = Trans.GetObject( tempId, OpenMode.ForRead ) as DBDictionary;
tempId = tempDict.GetAt( "SPATIAL" ) as ObjectId;
if ( tempId == ObjectId.Null )
return;
SpatialFilter SpFtr = Trans.GetObject( tempId, OpenMode.ForRead ) as SpatialFilter;
}
}
}
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Bryco

  • Water Moccasin
  • Posts: 1850
Re: Something about Xref functions...
« Reply #28 on: November 18, 2008, 10:58:19 PM »
Tim I had got that far ( the thing works) but I couldn't make the new dic=the old dic and get it to take.

cadpro

  • Guest
Re: Something about Xref functions...
« Reply #29 on: November 19, 2008, 01:37:58 AM »
This is all I had time for today.  Not sure if I will be able to get to it tomorrow, and I didn't test this, but it should show you want the process is that I'm thinking of going.  Hope it helps.  The idea was to use a test drawing with only one xref in it, and is inserted as many times as you want, and has an xclip associated with it ( which is the SpatialFilter object ).

Code: [Select]
public void TestXrefXClip {

DBDictionary tempDict;
ObjectId tempId;

Document Doc = AcadApp.DocumentManager.MdiActiveDocument;
Database Db = Doc.Database;
Editor Ed = Doc.Editor;
using ( Transaction Trans = Db.TransactionManager.StartTransaction() ) {
XrefGraph XrGph = Db.GetHostDwgXrefGraph(false);
XrefGraphNode XrNode = XrGph.GetXrefNode( 1 ) as XrefGraphNode;
BlockTableRecord BlkTblRec = Trans.GetObject( XrNode.BlockTableRecordId, OpenMode.ForRead ) as BlockTableRecord;
foreach ( ObjectId objId in BlkTblRec.GetBlockReferenceIds( true, true ) ) {
BlockReference BlkRef = Trans.GetObject( objId, OpenMode.ForRead ) as BlockReference;
tempDict = Trans.GetObject( BlkRef.ExtensionDictionary, OpenMode.ForRead ) as DBDictionary;
tempId = tempDict.GetAt( "ACAD_FILTER" ) as ObjectId;
if ( tempId == ObjectId.Null )
return;
tempDict = Trans.GetObject( tempId, OpenMode.ForRead ) as DBDictionary;
tempId = tempDict.GetAt( "SPATIAL" ) as ObjectId;
if ( tempId == ObjectId.Null )
return;
SpatialFilter SpFtr = Trans.GetObject( tempId, OpenMode.ForRead ) as SpatialFilter;
}
}
}

I did not understand a word.  :cry:

My code to loop through the xrefs.

     
Code: [Select]
BlockTable bt=tr.GetObject(db.BlockTableId,OpenMode.ForRead,false) as BlockTable;

                foreach (ObjectId btrId in bt)
                {
                    BlockTableRecord btr=tr.GetObject(btrId,OpenMode.ForRead,false) as BlockTableRecord;

                    ObjectIdCollection blkRefIds = btr.GetBlockReferenceIds(true, false);

                    foreach (ObjectId blkRefId in blkRefIds)
                    {
                        BlockReference blkRef = tr.GetObject(blkRefId, OpenMode.ForRead, false) as BlockReference;
                        MessageBox.Show(blkRef.Name.ToString());
                    }
                }

But how do I filter the xrefs inserted in layouts?

Thanks