AutoCAD Plant 3D Forum
Welcome to Autodesk’s AutoCAD Plant 3D Forums. Share your knowledge, ask questions, and explore popular AutoCAD Plant 3D topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Get the Start Point, Flow Arrows and Break Point properties (.NET API)

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
ti_eduardo
227 Views, 4 Replies

Get the Start Point, Flow Arrows and Break Point properties (.NET API)

Hi, I'm trying to get the properties for these 3 object types: IsoArrowSymbol; IsoSphereSymbol;
IsoStartPointSymbol;

Visibly in the drawing, they have properties, but when trying to obtain these properties through the API, it says that the object has no links to the Database, and the properties within PartSizeProperties are also empty/null.

I need a way to get this.

Does anyone know what could fix this?

My code:

if (acEnt is IsoArrowSymbol isoArrowSymbol)
{
System.Collections.Specialized.StringCollection propNames = isoArrowSymbol.PartSizeProperties.PropNames;

if (propNames.Count > 0)
{
foreach (var propName in propNames)
{
if (propName == "LineNumberTag")
{
string lineNumberTag = isoArrowSymbol.PartSizeProperties.PropValue(propName).ToString();
MessageBox.Show(lineNumberTag);
}
}
}
}

4 REPLIES 4
Message 2 of 5
quan_hm
in reply to: ti_eduardo

Hi,

The arrow informatino is not available to read in C#, you can only access it direction, length. A workaround is to read its through properties tab.

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;
      }

   }
}

 Credit: ActivistInvestor

Hoang Minh Quan - Piping design engineer
Autodesk Store for Python Catalog
Message 3 of 5
ti_eduardo
in reply to: quan_hm

Hello, thank you for your response regarding this issue. I was able to obtain the properties I needed; however, with my current code, which I adapted to use your provided method, the software is crashing, and I am unable to identify the problem. Can you take a look?

It performs a simple operation, in theory, it should obtain the value of the properties:

  • LineNumberTag
  • Service
  • Spec

And check if the value of each one exists in my list of strings (rowValues).

My code:

public static void IsolateSelectedObjects(List<string> rowValues)
{
    try
    {
        Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

        if (acDoc != null)
        {
            acDoc.LockDocument();

            Database db = acDoc.Database;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                foreach (ObjectId id in btr)
                {
                    try
                    {
                        Entity entity = tr.GetObject(id, OpenMode.ForWrite) as Entity;
                        if (entity == null)
                        {
                            continue;
                        }

                        bool found = false;
                        bool shouldBeVisible = false;

                        if (entity is IsoArrowSymbol || entity is IsoSphereSymbol || entity is IsoStartPointSymbol)
                        {
                            //MessageBox.Show("Entrou no bloco de verificação de IsoArrowSymbol, IsoSphereSymbol ou IsoStartPointSymbol");

                            try
                            {
                                IDictionary<string, object> properties = GetOPMProperties(id);
                                var propertyDictionary = new Dictionary<string, string>();

                                if (properties != null && properties.Count > 0)
                                {
                                    Thread.Sleep(1500);
                                    //MessageBox.Show("Propriedades obtidas com sucesso.");

                                    foreach (var property in properties)
                                    {
                                        string key = property.Key;
                                        string value = string.Empty;

                                        try
                                        {
                                            value = property.Value?.ToString();
                                            //MessageBox.Show($"Propriedade: {key} = {value}");
                                        }
                                        catch (System.Exception ex)
                                        {
                                            MessageBox.Show($"Erro ao converter valor da propriedade para string: {ex.Message}");
                                            continue;
                                        }

                                        if (key == "Line Number Tag" || key == "Service" || key == "Spec")
                                        {
                                            if (!string.IsNullOrEmpty(value))
                                            {
                                                if (rowValues.Contains(value))
                                                {
                                                    shouldBeVisible = true;
                                                    found = true;
                                                    //MessageBox.Show("Encontrou a propriedade necessária e está visível.");
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    MessageBox.Show("Nenhuma propriedade encontrada.");
                                }
                            }
                            catch (Autodesk.AutoCAD.Runtime.Exception ex)
                            {
                                MessageBox.Show($"Erro do AutoCAD ao processar propriedades: {ex.Message}", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                            catch (System.Exception ex)
                            {
                                MessageBox.Show($"Erro inesperado ao processar propriedades: {ex.Message}", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }

                        if (entity is Connector)
                        {
                            Connector connector = (Connector)entity;

                            if (connector != null)
                            {
                                SubPartCollection subPartsOfConnector = connector.AllSubParts;

                                foreach (SubPart subPart in subPartsOfConnector)
                                {
                                    if (subPart != null)
                                    {
                                        foreach (var prop in subPart.PartSizeProperties.PropNames)
                                        {
                                            if (prop == "LineNumberTag" || prop == "Spec" || prop == "Service")
                                            {
                                                try
                                                {
                                                    if (rowValues.Contains(subPart.PartSizeProperties.PropValue(prop).ToString()))
                                                    {
                                                        shouldBeVisible = true;
                                                        found = true;
                                                        break;
                                                    }
                                                }
                                                catch
                                                {
                                                    continue;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (!found)
                        {
                            PlantProject currentProj = PlantApplication.CurrentProject;
                            PipingProject pipingProj = currentProj.ProjectParts["Piping"] as PipingProject;
                            DataLinksManager dlm = pipingProj.DataLinksManager;

                            if (!dlm.HasLinks(id))
                            {
                                entity.Visible = false;
                                continue;
                            }

                            int rowId = dlm.FindAcPpRowId(id);
                            if (rowId == -1)
                            {
                                entity.Visible = false;
                                continue;
                            }

                            List<KeyValuePair<string, string>> properties = dlm.GetAllProperties(rowId, true);

                            foreach (var property in properties)
                            {
                                if (rowValues.Contains(property.Value))
                                {
                                    shouldBeVisible = true;
                                    break;
                                }
                            }
                        }

                        entity.Visible = shouldBeVisible;
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show($"Ocorreu um erro inesperado ao tentar listar na tabela o objeto com ID '{id}'.\nErro: {ex.Message}", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        continue;
                    }
                }

                tr.Commit();
            }

            acDoc.Editor.Regen();
        }
    }
    catch (System.Exception ex)
    {
        if (ex.Message != "eOnLockedLayer")
        {
            MessageBox.Show($"Ocorreu um erro ao tentar isolar os objetos selecionados.\nErro: {ex.Message}", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        else
        {
            MessageBox.Show("LineNumber selecionado(s) contém itens congelados/bloqueados.", "Item congelado/bloqueado", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
}

public static IDictionary<string, object> GetOPMProperties(ObjectId id)
{
    Dictionary<string, object> map = new Dictionary<string, object>();
    IntPtr pUnk = IntPtr.Zero;
    try
    {
        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)
                    {
                        if (category != null)
                        {
                            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;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    catch (Autodesk.AutoCAD.Runtime.Exception ex)
    {
        MessageBox.Show($"Erro do AutoCAD ao obter propriedades: {ex.Message}");
    }
    catch (System.Exception ex)
    {
        MessageBox.Show($"Erro inesperado ao obter propriedades: {ex.Message}");
    }
    finally
    {
        if (pUnk != IntPtr.Zero)
        {
            Marshal.Release(pUnk);
        }
    }
    return map;
}
Message 4 of 5
ti_eduardo
in reply to: quan_hm

Hello, it's me again.

I tested your code several times and discovered that the software crash was caused by this line:

 

Marshal.Release(pUnk);

 

After commenting out that line, I no longer experienced sudden crashes in the software. Thank you very much for your help; it was of great importance and allowed me to move forward with my project.

Message 5 of 5
quan_hm
in reply to: ti_eduardo

Great to hear that, you're welcome :))

Hoang Minh Quan - Piping design engineer
Autodesk Store for Python Catalog

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

Post to forums  

Autodesk Design & Make Report