Author Topic: GetPersistentReactorIds and RasterImageDef  (Read 3833 times)

0 Members and 1 Guest are viewing this topic.

T.Willey

  • Needs a day job
  • Posts: 5251
GetPersistentReactorIds and RasterImageDef
« on: August 24, 2010, 06:47:29 PM »
So I'm trying to update some code that I use to check images within a drawing, and since I've upgraded my Acad to '09, I thought I would use the native managed calls.  I can't seem to figure out how to get to the actual image that is inserted within the drawing from the RasterImageDef.  When I was trying this a couple of years ago Tony told me about ' GetPersistentReactorIds ', but I wasn't able to use this method back then, but now I can.  So I call that, and what gets returned is an ObjectIdCollection, and within that is object id's for the main image dictionary, and id's for an object that I don't seem to have a reference to, as it is calling it an ' ImpDBObject '.  I have searched the net, and the help, and haven't been able to figure out what I'm supposed to use it as.  I assume it is a reactor object, as with lisp I can follow it that way, but with .Net I can't.  Maybe if I reference the correct .dll file, but I'm not sure which one.

Any help is appreciated.  Thanks.  If code is needed, let me know, and I'll try any clean it up enough to post.
Tim

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

Please think about donating if this post helped you.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: GetPersistentReactorIds and RasterImageDef
« Reply #1 on: August 24, 2010, 08:52:58 PM »
Sorry but I am switching from VB to C# but here is a way to get it from the image dictionary
I will post how to get it through modelSpace

Code: [Select]
   [CommandMethod("Raster")]
        public static void Raster()
        {
            RasterImageDef rd;
            string imageName = "Capture1";
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;           
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                ObjectId imageDictId = RasterImageDef.GetImageDictionary(db);
                if (imageDictId == null)
                {
                    ed.WriteMessage("No images in Drawing");
                    return;
                }
                DBDictionary imageDict = (DBDictionary)tr.GetObject(imageDictId, OpenMode.ForRead);
                if (imageDict.Contains(imageName))
                {
                    imageDictId = imageDict.GetAt(imageName);
                    rd = (RasterImageDef)imageDictId.GetObject(OpenMode.ForRead);
                   
                }
                else
                {
                    ed.WriteMessage("That image is not in Drawing");
                    return;
                }
                ed.WriteMessage(rd.ColorDepth.ToString());

            }
        }

Jeff H

  • Needs a day job
  • Posts: 6150
Re: GetPersistentReactorIds and RasterImageDef
« Reply #2 on: August 24, 2010, 10:05:05 PM »
Grabbing it another way

Code: [Select]
    [CommandMethod("Raster2")]
        public static void Raster2()
        {
            RasterImageDef rd;
            RasterImage ri;
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;         
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForRead);
                BlockTableRecord msBtr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForRead);
                foreach (ObjectId objID in msBtr)
                {
                    Entity ent = (Entity)objID.GetObject(OpenMode.ForRead);
                    if (ent is RasterImage)
                    {
                        ri = (RasterImage)ent;
                        rd =(RasterImageDef) ri.ImageDefId.GetObject(OpenMode.ForRead);
                        string rdName = Path.GetFileNameWithoutExtension(rd.SourceFileName);
                        ed.WriteMessage("\n" + rdName);
                    }
                 }
            }
        }           

Jeff H

  • Needs a day job
  • Posts: 6150
Re: GetPersistentReactorIds and RasterImageDef
« Reply #3 on: August 24, 2010, 10:13:25 PM »
I'm sorry I thought you wanted the definition
When you say get the actual image do you mean the file location of the image

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8722
  • AKA Daniel
Re: GetPersistentReactorIds and RasterImageDef
« Reply #4 on: August 24, 2010, 10:17:54 PM »
...I am switching from VB to C# ...

YES!  8-)

Tip, use 'as' and test for null, its faster than 'is'
if your going to use a C-style cast, use try catch as they can throw

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: GetPersistentReactorIds and RasterImageDef
« Reply #5 on: August 24, 2010, 10:31:22 PM »
...I am switching from VB to C# ...

That's great to hear Jeff.
Will save the mental gymnastics when reading your code posts.


ps: not that I have any really rational objections to VB :)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: GetPersistentReactorIds and RasterImageDef
« Reply #6 on: August 24, 2010, 11:28:20 PM »

Tip, use 'as' and test for null, its faster than 'is'
if your going to use a C-style cast, use try catch as they can throw

Is this what you mean

Code: [Select]
   RasterImage ri = objID.GetObject(OpenMode.ForRead) as RasterImage;                   
                    if (ri != null)
                    {                       
                        rd = (RasterImageDef)ri.ImageDefId.GetObject(OpenMode.ForRead);
                        string rdName = Path.GetFileNameWithoutExtension(rd.SourceFileName);
                        ed.WriteMessage("\n" + rdName);
                    }

Instead of

Code: [Select]
                    Entity ent = (Entity)objID.GetObject(OpenMode.ForRead);
                    if (ent is RasterImage)
                    {
                        ri = (RasterImage)ent;
                        rd =(RasterImageDef) ri.ImageDefId.GetObject(OpenMode.ForRead);
                        string rdName = Path.GetFileNameWithoutExtension(rd.SourceFileName);
                        ed.WriteMessage("\n" + rdName);

Thanks alot that is less code and easier to read if this is right

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8722
  • AKA Daniel
Re: GetPersistentReactorIds and RasterImageDef
« Reply #7 on: August 25, 2010, 12:46:00 AM »
perfect,  this line as well.

Code: [Select]
rd = (RasterImageDef)ri.ImageDefId.GetObject(OpenMode.ForRead);

to

rd = ri.ImageDefId.GetObject(OpenMode.ForRead) as RasterImageDef;

FYI, there is nothing wrong with C-style casts, you just need to be prepared to handle the exception if it throws.
but IMO 'as' give you a bit more control

Jeff H

  • Needs a day job
  • Posts: 6150
Re: GetPersistentReactorIds and RasterImageDef
« Reply #8 on: August 25, 2010, 01:46:01 AM »
To have a RasterImage you must have a RasterImageDefinition
So if the RasterImage is not null then you know a RasterImageDef must exist is it still better to use the 'as'

Or you know every drawing will have a BlockTable would use

BlockTable bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;

or

BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForRead);

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: GetPersistentReactorIds and RasterImageDef
« Reply #9 on: August 25, 2010, 02:44:01 AM »
Personally I'd use the
BlockTable bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;

for no other reason than visual consistancy ; everything else already considered
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: GetPersistentReactorIds and RasterImageDef
« Reply #10 on: August 25, 2010, 05:00:29 AM »
What Tim is talking about is like the GetBlockReferenceIds function from a BlockTableRecord, but he's asking if you can go directly from an image defintion to an image reference inserted in the drawing that references the image definition.

Tim, I will look this evening (if noone else has solved it by then) as I'm at the dumb day place...

Jeff H

  • Needs a day job
  • Posts: 6150
Re: GetPersistentReactorIds and RasterImageDef
« Reply #11 on: August 25, 2010, 08:22:24 AM »
You need to clean this up but maybe this will help but looking at it with snoop this was only way I could find to get at it.

Code: [Select]
[CommandMethod("Raster3")]
        public static void Raster()
        {
            RasterImageDef rd;
            string imageName = "1";
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;           
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                ObjectId imageDictId = RasterImageDef.GetImageDictionary(db);
                if (imageDictId == null)
                {
                    ed.WriteMessage("No images in Drawing");
                    return;
                }
                DBDictionary imageDict = (DBDictionary)tr.GetObject(imageDictId, OpenMode.ForRead);
                if (imageDict.Contains(imageName))
                {
                    imageDictId = imageDict.GetAt(imageName);
                    rd = imageDictId.GetObject(OpenMode.ForRead) as RasterImageDef;
                    ObjectIdCollection recId = rd.GetPersistentReactorIds();
                    foreach (ObjectId rID in recId)
                    {
                        if (!rID.IsErased && !rID.IsEffectivelyErased)
                        {
                            string dfxstr = rID.ObjectClass.DxfName;
                            if (dfxstr == "IMAGEDEF_REACTOR")
                            {
                                DBObject dbr = rID.GetObject(OpenMode.ForRead) as DBObject;
                                RasterImage ri = dbr.OwnerId.GetObject(OpenMode.ForRead) as RasterImage;
                                ed.WriteMessage("\n" + ri.Name);
                            }
                        }
                    }
                }
                else
                {
                    ed.WriteMessage("That image is not in Drawing");
                    return;
                }
             
               
            }
        }

Bryco

  • Water Moccasin
  • Posts: 1883
Re: GetPersistentReactorIds and RasterImageDef
« Reply #12 on: August 25, 2010, 10:52:07 AM »
Code: [Select]
if (imageDict.Contains(imageName))
{
       imageDictId = imageDict.GetAt(imageName);
       RasterImageDef rd = (RasterImageDef)imageDictId.GetObject(OpenMode.ForRead);
       ObjectIdCollection ids = rd.GetPersistentReactorIds();
       foreach (ObjectId id in ids)
       {
           DBObject r = tr.GetObject(id, OpenMode.ForRead) as DBObject;
           if (r == null) continue;
           RasterImage ri = tr.GetObject(r.OwnerId, OpenMode.ForWrite) as RasterImage;
           if (ri == null) continue;
            ri.ColorIndex = 1;
         }
   }

T.Willey

  • Needs a day job
  • Posts: 5251
Re: GetPersistentReactorIds and RasterImageDef
« Reply #13 on: August 25, 2010, 11:42:57 AM »
Thanks fro2001 and Bryco for the help.  I got what I wanted with the code you provided.  I was looking at this too hard, and was trying to find what properties an ' ImageDef_Reactor ' had that I could use to get what I wanted.  I wouldn't have thought to go the route you did.
Tim

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

Please think about donating if this post helped you.