Aller au contenu

Dynamic Block


bazoul

Messages recommandés

Salut,

 

Voila& alors je travail avec un bloc dynamique et je voudrais récupérer la géométrie présente dans le dessin.

Mais pour le moment j'ai juste réussi a récupérer toutes les entités présente dans la définition de bloc .... en faisant un explode de ma référence de bloc je me retrouve également avec toutes les entités présentes dans la définition de bloc ....

 

Esce que quelqu'un aurait une idée?

 

Ps : langage .NET

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Je ne comprends pas bien ce que tu cherches, mais tu peux accéder aux propriétés dynamiques d'une référence de bloc avec la méthode BlockReference.DynamicBlockReferencePropertyCollection tu devras ensuite chercher dans la collection les valeurs des propriétés qui modifient la géométrie du bloc.

 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

hey hey je m'expliques un peu plus bien

 

J'ai un bloc dynamique,admettons une voiture ( 37 entités ) .

dans ce bloc j'ai 3 vue différentes:

- vue de face ( 15 entités )

- vue de coté ( 12 entités )

- vue de dessus ( 10 entités )

 

A chaque vu est associé des entités qui seront ou non visible.

Je sais que chaque vu,lorsqu'elle est inséré dans le dessin corresponds a un bloc anonyme.

Ce que je ne sais pas,c'est juste récupérer les entités qui sont visible dans la référence de bloc.

A chaque fois je me retrouve avec les entités contenues dans la définition a savoir 37 entités au lieu de 15 entités ( je travaille dirons nous avec la vue de face ) .

 

Je n'ai aucun paramètres de dimensionnement ou autre,c'est juste un bloc dynamique multi-vues.

 

Voili voilo,merci giles ^^

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Je crains que ça ne soit pas si simple.

Je n'ai pas trouvé de méthode ou de propriété en .NET qui permette d'accéder aux entités visible suivant l'état de visibilité.

Je suis tombé sur une discussion ici qui traite du même sujet.

à la fin du sujet, Tony Tanzillo y explique qu'il n'y a pas d'API .NET pour ça et qu'il faut utiliser la méthode non managée acdbEntGet() avec P/Invoke.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Re,

 

Je pense avoir réussi à faire quelque chose qui fonctionne.

 

Comme on appelle des fonction ObjectARX 'non managées', on a des problèmes de compatibilité :

- dans l'attribut DllImport, pour les versions 32 bits, il faut mettre "acdb17.dll" pour les versions 2007 2008 et 2009 ou "acdb18.dll" pour 2010. Pour les versions 64 bits, c'est probablement différent aussi pour l'alias (voir ce message pour la recherche des alias des fonctions ObjectARX).

 

Le code ci-dessous définit :

- une fonction EntGet (de Tony Tanzillo) qui appelle la fonction ObjectARX acdbEntGet et qui retourne un ResultBuffer (comme la fonction LISP entget qui retourne une liste de paires pointées).

- une fonction GetVisibleEntities (surchargée) qui retourne une ObjectIdCollection contenant les ObjectId des entités visibles en fonction de l'état de visibilité de la référence de bloc (premier argument). Le second argument, s'il est spécifié est l'étiquette du paramètre de visibilité "Visisbilité" par défaut.

 

En l'état, il fonctionne pour AutoCAD 2007, 2008, 2009. J'ai mis en commentaire ce qu'il faudrait remplacer pour AutoCAD 2010 32 bits (ainsi que l'utilisation de la nouvelle propriété ObjectClass qui permet d'obtenir la RxClass d'un ObjectId sans avoir à l'ouvrir)

 

//++-- TonyT
//++-- http://discussion.autodesk.com/forums/thread.jspa?messageID=5656222

// 2007
[DllImport("acdb17.dll", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z")]
public static extern ErrorStatus acdbGetAdsName(out Int64 entres, ObjectId id);

// 2010
//[DllImport("acdb18.dll", CallingConvention = CallingConvention.Cdecl,
//EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z")]
//public static extern ErrorStatus acdbGetAdsName(out Int64 entres, ObjectId id);

[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr acdbEntGet(out Int64 e);

public static ResultBuffer EntGet(ObjectId id)
{
   Int64 e;
   if (acdbGetAdsName(out e, id) == ErrorStatus.OK)
   {
       IntPtr res = acdbEntGet(out e);
       if (res != IntPtr.Zero)
           return ResultBuffer.Create(res, true);
   }
   return null;
}

private static ObjectIdCollection GetVisibleEntities(ObjectId blockRefId)
{
   return GetVisibleEntities(blockRefId, "Visibilité");
}

private static ObjectIdCollection GetVisibleEntities(ObjectId blockRefId, string dynPropName)
{
   Document doc = Application.DocumentManager.MdiActiveDocument;
   Database db = doc.Database;
   ObjectIdCollection result = new ObjectIdCollection();
   using (Transaction tr = db.TransactionManager.StartTransaction())
   {
       BlockReference br =
           (BlockReference)tr.GetObject(blockRefId, OpenMode.ForRead);
       if (br == null || !br.IsDynamicBlock)
           return result; // n'est pas un bloc dynamique

       DynamicBlockReferencePropertyCollection propCol = br.DynamicBlockReferencePropertyCollection;
       string state = string.Empty;
       for (int i = 0; i         {
           if (propCol[i].PropertyName == dynPropName)
           {
               state = propCol[i].Value.ToString();
               break;
           }
       }
       if (state == string.Empty)
           return result; // n'a pas le paramètre spécifié ("Visibilité")

       BlockTableRecord btr =
           (BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead);
       DBDictionary xdict =
           (DBDictionary)tr.GetObject(btr.ExtensionDictionary, OpenMode.ForRead);
       ObjectId id = ObjectId.Null;
       ResultBuffer res = EntGet((ObjectId)xdict["ACAD_ENHANCEDBLOCK"]);
       foreach (TypedValue tv in res)
       {
           if (tv.TypeCode != 360)
               continue;
           id = (ObjectId)tv.Value;

           // 2007
           RXObject obj = (RXObject)tr.GetObject((ObjectId)tv.Value, OpenMode.ForRead);
           if (obj.GetRXClass().DxfName == "BLOCKVISIBILITYPARAMETER")
               break;

           // 2010
           //if ((ObjectId)tv.Value.ObjectClass.DxfName == "BLOCKVISIBILITYPARAMETER")
           //    break;
       }
       res = EntGet(id);
       TypedValue[] tValues = res.AsArray();
       for (int i = 0; i         {
           if (tValues[i].TypeCode != 303 || (string)tValues[i].Value != state)
               continue;
           for (int j = i + 2; j             {
               result.Add((ObjectId)tValues[j].Value);
           }
           break;
       }
   }
   return result;
}

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Arf,je suis en vb.net et j'ai pas acces a acdbEntGet ...

J'ai remplacé acdbEntget par oldidptr qui a la meme valeur décimal que l'id de mon objet ... mais pas moyen de parcourir mon ResultBuffer qui n'a de toute évidence pas de TypeValue ....

 

Je me repencherais sur le pb demain.... la méthode asarray chez moi plante ... j'ai encore de quoi a chercher !

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Je m'étais trompé de lien dans le message précédent, vas y voir, tu verras des exemples en VB.

 

J'avais oublié de préciser, il faut aussi faire :

 

Imports System.Runtime.InteropServices

 

Je m'essaye à une traduction en VB des Attributs, des signatures de fonctions externes et de la fonction Entget (je ne suis pas sûr de moi...)

 

Public Declare Auto  Function acedGetUserFavoritesDir Lib "acdb17.dll" 
Alias "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z"
(ByRef entres As Int64, ByVal id As ObjectId) As ErrorStatus

Public Declare Auto  Function acdbEntGet Lib "acad.exe" 
(ByRef e As Int64) As IntPtr

Public Shared Function EntGet(ByVal id As ObjectId) As ResultBuffer
   Dim e As Int64
   If acdbGetAdsName(e, id) = ErrorStatus.OK Then
       Dim res As IntPtr = acdbEntGet(e)
       If res  IntPtr.Zero Then
           Return ResultBuffer.Create(res, True)
       End If
   End If
   Return Nothing
End Function

 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité