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

read custom properties from object

15 REPLIES 15
SOLVED
Reply
Message 1 of 16
Anonymous
8140 Views, 15 Replies

read custom properties from object

Hi.

I have a program to read standard (line, mtext, etc) coordinates.

But, I need to read custom properties added to objects (I can see with right button, properties).

What is the method?

I'm writing a module in c#.

 

My code:

Database db=HostApplicationServices.WorkingDatabase;

Transaction tr=db.TransactionManager.StartTransaction();

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

BlockTableRecord btr=(BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);

foreach(ObjectId idobj in btr)

 {

  ed.WriteMessage(idobj.ObjectClass.DxfName);

  if(idobj.ObjectClass.DxfName.CompareTo("LINE")==0) 

   {

    Line e=tr.GetObject(idobj, OpenMode.ForRead, false) as Line;

    ed.WriteMessage(e.StartPoint+" "+e.EndPoint); // coordinates

   }

 }

 

You can see a printscreen with information of custom properties (title "Personalizado" and values "diamertro", "material", "espesor")

15 REPLIES 15
Message 2 of 16
norman.yuan
in reply to: Anonymous

It depends on what kind of "custom properties" you are talking about. For plain AutoCAD, a standard AutoCAD entity could be extend to have some kind of "custom properties" by using XData or ExtentionDisctionary, for example. You can use AutoCAD .NET API to access these kind of "properties", 

 

For AutoCAD vertical products (AutoCAD Map/Civil/MEP...), custom properties could be added to either standard AutoCAD entities, or Vertical products' custom entities. Basically, you need Vertical product-specific APIs (that only comes with the vertical product) to access them, well, only if the APIs support doing it.

 

So, you need to know what exactly the "custom properties" are from (plain AutoCAD, vertical products, or even third party add-ins...). From the picture you attached, (sorry, I do not know what language is shown in the picture), it seems you are using AutoCAD MAP, and the custom properties you are referring to look like ObjectData (or ObjectClass?). If that is the case, you need to use AutoCAD Map ObjectARX .NET API to access it. You can download AutoCAD Map ObjectARX SDK and learn how to access AutoAD Map specific data from the sample code coming with the SDK. 

 

Also, AutoCAD Map also has COM API available (not as powerful as its .NET API).

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 16
Anonymous
in reply to: norman.yuan

Thanks for your fast response.
I did download the objectarx 2016, before.
And, I can't see .cs samples about ObjectClass custom properties
manipulation.
There is another site where I can see a basic sample about it?

I did not create new objects (I'm creating them from the autocad map).
Only, I need read the custom properties created (label and value).

I did check this information is not xdata.
Message 4 of 16
norman.yuan
in reply to: Anonymous


...... I did download the objectarx 2016, ...

When you say objectarx 2016, probably, you mean AutoCAD ObjectARX SDK, which is only for PLAIN AutoCAD. To work with AutoCAD Map specific data (ObjectData/ObjectClass/..., there is AutoCAD Map ObjectARX SDK. You do not have to download to work with AutoCAD Map .NET API technically. All you need to do is to set reference of your project to ManagedMapApi.dll (found in [AutoCAD installation\\Map folder (make sure you set "Copy Local" to False).

 

However, if the custom properties you are after are from Map objects (created by connecting to FDO data source), then things are a lot more complicated, because these Map objects are not native AutoCAD entities. You then need to learn another set of .NET API - AutoCAD Map geospatial platform API. Hopefully, you are only interested in ObjectData/ObjectClass, thus the learning curve would be not as steep.

Norman Yuan

Drive CAD With Code

EESignature

Message 5 of 16
Anonymous
in reply to: norman.yuan

Thanks, again for your response.
I'm trying to read custom properties for a objectclass writted in a dwg
file, without fdo connection, then, this is a native element.
I did extract ObjectDataCS project from the "Autocad map 3d 2016 object
arx", but, when I compile (and run), I see "You have not create the
ObjectData table, yet". Then, this is not the method to read my custom
attributes from my custom object class.
The attributes ARE in the dwg (I can see it on the properties tool).
Message 6 of 16
norman.yuan
in reply to: Anonymous

ObjectData and ObjectClass (Object Classification) are different things. The latter was introduced into AutoCAD Map well later than ObjectData, and originally called Feature Class/Classification. It is not widely used as ObjectData.

 

You need to look at the code samples "ClassifactionCS/VB", if you indeed know the data you are after in ObjectClass data.

 

Before you write code to manipulate Object Class data, I strongly recommend you get familiar to it by manually create Object class definition, classifying and declassifying AutoCAD entities in AutoCAD Map as AutoCAD Map user

Norman Yuan

Drive CAD With Code

EESignature

Message 7 of 16
ActivistInvestor
in reply to: Anonymous

The example code below will display the properties shown in the Properties palette for a selected object:

 

 

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Internal.PropertyInspector;
using Autodesk.AutoCAD.Runtime;

namespace Namespace1
{
   public static class OPMPropsExample
   {
      
      /// Example: Dumps the OPM properties of a selected object to the console:
      
      [CommandMethod("OPMPROPS")]
      public static void ListOpmProps()
      {
         Document doc = Application.DocumentManager.MdiActiveDocument;
         Editor ed = doc.Editor;
         var psr = ed.GetEntity("\nSelect object: ");
         if(psr.Status != PromptStatus.OK)
            return;
         var props = GetOPMProperties(psr.ObjectId);
         if(props.Count == 0)
         {
            ed.WriteMessage("\nNo properties found.");
            return;
         }
         ed.WriteMessage("\n\n");
         foreach(var pair in props)
         {
            ed.WriteMessage("\n  {0} = {1}", pair.Key, pair.Value);
            if(Marshal.IsComObject(pair.Value))
               Marshal.ReleaseComObject(pair.Value);
         }
      }
      
      /// Gets the names and values of OPM properties for the given object

      public static IDictionary<string, object> GetOPMProperties(ObjectId id)
      {
         Dictionary<string, object> map = new Dictionary<string, object>();
         IntPtr pUnk = ObjectPropertyManagerPropertyUtility.GetIUnknownFromObjectId(id);
         if(pUnk != IntPtr.Zero)
         {
            using(CollectionVector properties = ObjectPropertyManagerProperties.GetProperties(id, false, false))
            {
               int cnt = properties.Count();
               if(cnt != 0)
               {
                  using(CategoryCollectable category = properties.Item(0) as CategoryCollectable)
                  {
                     CollectionVector props = category.Properties;
                     int propCount = props.Count();
                     for(int j = 0; j < propCount; j++)
                     {
                        using(PropertyCollectable prop = props.Item(j) as PropertyCollectable)
                        {
                           if(prop == null)
                              continue;
                           object value = null;
                           if(prop.GetValue(pUnk, ref value) && value != null)
                           {
                              if(!map.ContainsKey(prop.Name))
                                 map[prop.Name] = value;
                           }
                        }
                     }
                  }
               }
            }
            Marshal.Release(pUnk);
         }
         return map;
      }

   }
}
Message 8 of 16
SENL1362
in reply to: ActivistInvestor

Hello AI(short for Activist Investor),

 

Youre sample of OPM is returning a value of "Com Object" for Color and Hyperlink.

I could get the proper values directly from the ObjectId,

  but what would be the more generic way of returning the underlying values for those Com Objects.

I would rather like to convert based on if (value=="Com Object")... instead of if (name=="COLOR")...

See sample below.

 

For the Color Value i used a dynamic to get the Color value, but this approach failed for the Hyperlink

The Albert(AutoCAD Team) mentioned  using the FromAcadObject  methode to get properties of  "COM object" for  ".net object" and the other way around in : http://through-the-interface.typepad.com/through_the_interface/2007/02/using_the_com_i.html

 

Attached is the full source, a littlebit changed version of  your sample of OPM

 

 

 

...
if (prop.GetValue(pUnk, ref value)) //&& value != null)
 {
     //Color and Hyperlink Values are returned as Com Object
     if (propName.Equals("COLOR", StringComparison.OrdinalIgnoreCase))
     {
         //var x1 = DBObject.FromAcadObject(prop);
         dynamic propDisp = prop.DISP;
         value = propDisp.Color;
         var colorName = ColorNames.BYLAYER;
         if (Enum.TryParse<ColorNames>(value.ToString(), out colorName))
         {
             value = colorName;
         }
     }
     else if (propName.Equals("HYPERLINK", StringComparison.OrdinalIgnoreCase))
     {
         //var x1 = DBObject.FromAcadObject(prop);
         dynamic propDisp = prop.DISP;
         //value = ???;
     }
     map[$"{catName}.{propName}"] = value;
 }
...

 

Message 9 of 16
ActivistInvestor
in reply to: SENL1362

I'm afraid there's no more 'generic' way to convert COM objects to managed counterparts, other than for DBObjects.

 

The main purpose of reading OPM properties is as a quick/dirty way to access data that is either difficult or impossible to access via other means, so unless you're trying to reinvent the properties palette, for those things that are easily available through the managed API, that going to be the easiest way to use that data.

 


@SENL1362 wrote:

Hello AI(short for Activist Investor),

 

Youre sample of OPM is returning a value of "Com Object" for Color and Hyperlink.

I could get the proper values directly from the ObjectId,

  but what would be the more generic way of returning the underlying values for those Com Objects.

I would rather like to convert based on if (value=="Com Object")... instead of if (name=="COLOR")...

See sample below.

 

For the Color Value i used a dynamic to get the Color value, but this approach failed for the Hyperlink

The Albert(AutoCAD Team) mentioned  using the FromAcadObject  methode to get properties of  "COM object" for  ".net object" and the other way around in : http://through-the-interface.typepad.com/through_the_interface/2007/02/using_the_com_i.html

 

Attached is the full source, a littlebit changed version of  your sample of OPM

 

 

 

...
if (prop.GetValue(pUnk, ref value)) //&& value != null)
 {
     //Color and Hyperlink Values are returned as Com Object
     if (propName.Equals("COLOR", StringComparison.OrdinalIgnoreCase))
     {
         //var x1 = DBObject.FromAcadObject(prop);
         dynamic propDisp = prop.DISP;
         value = propDisp.Color;         var colorName = ColorNames.BYLAYER;
         if (Enum.TryParse<ColorNames>(value.ToString(), out colorName))
         {
             value = colorName;
         }
     }
     else if (propName.Equals("HYPERLINK", StringComparison.OrdinalIgnoreCase))
     {
         //var x1 = DBObject.FromAcadObject(prop);
         dynamic propDisp = prop.DISP;
         //value = ???;
     }
     map[$"{catName}.{propName}"] = value;
 }
...

 


 

Message 10 of 16
SENL1362
in reply to: ActivistInvestor

ok, thank you for your thoughts.

It was merely a question of interest and to learn about the more advanced subjects than as you stated "reinventing the properties palette".

In this case the missing information is easily available.

 

Again thanks.

Message 11 of 16
Anonymous
in reply to: SENL1362

Thanks to all.

I did try the solution, and works ok.

I'm trying to do a "saveas" from current dwg to wfs read/write service (I can't use the connection wfs, because is read only).

 

A difference of a connection to a database, which requires permissions on base tables, a wfs connection (in my case geoserver, authenticating users by ldap / ad) is much better.
But, for that, it has to obtain the list of graphic elements, but also the list of alphanumeric elements informed by the operator for the object.
For this last, I spent almost two weeks consulting a lot of specialists, and finally, you gave me the solution.
I'm going to try a little more, but I think I can convert all the objects in the model space.

 

TIA

Message 12 of 16
Anonymous
in reply to: ActivistInvestor

Thanks so much for sharing this code. It helped me a lot.

I was wondering how can I change the value of the custom property of a dynamic block?

Message 13 of 16
ActivistInvestor
in reply to: Anonymous

The AutoCAD managed API provides a way to manipulate Dynamic block properties without the need to use the OPM API. You can find plenty of examples for manipulating Dynamic block properties by searching this forum.

 

 


@Anonymous wrote:

Thanks so much for sharing this code. It helped me a lot.

I was wondering how can I change the value of the custom property of a dynamic block?


 

Message 14 of 16
Anonymous
in reply to: SENL1362

Hi,

 

Your cade seems a solution to a problem I have.

 

I could not implement it because I did not understand what ColorNames is. I could not find it in the API.

 

Can you please help?

 

Best Regards.

Modar Mayya

Message 15 of 16
SENL1362
in reply to: Anonymous

public enum ColorNames { BYLAYER = 256, BYBLOCK = 0, RED = 1, ROOD = 1, YELLOW = 2, GEEL = 2, GREEN = 3, GROEN = 3, CYAN = 4, CYAAN = 4, BLUE = 5, BLAUW = 5, MAGENTA = 6, WHITE = 7, WIT = 7, BLACK = 7, ZWART = 7, GRAY = 9, GRIJS = 9 };
Message 16 of 16

Hi ActivistInvestor,

Thanks for the code. It helped me at right time.

Can you please point me to some place where I can list required properties from multiple selected objects and write to xls!!!

Thanks in anticipation,

Samir.

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report