Aller au contenu

Messages recommandés

Posté(e)

Salut,

 

Je commande, via une boite de dialogue, un lisp.

Ce lisp génére une valeur que je veux ensuite récupérer dans ma BD....

 

Pour l'instant, je le fais avec

 

Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("USERR1")

 

... Mais l'un de me problème est que le lisp est plus lent que ma boite de dialogue... donc la valeur est en retard d'un cycle pour se mettre à jour...

Je suis obligé de bidouiller un truc pas génial...

 

Question donc :

 

Pensez-vous qu'il est possible, et comment, de renvoyer dans ma BD une valeur de AutoCAD ?

 

Merci d'avance.

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Salut,

 

Si j'ai bien compris, tu as un boite de dialogue, un "bouton" qui appel un lisp

qui lui renvoie une valeur que tu affiche dans la boite de dialogue.

 

Mais le lisp est trop long...

 

et par "un valeur d'autocad" tu veux dire quoi ?

 

HS: c'est là que je vois, que ce n'est pas toujours facile de se faire comprendre...

 

Tous pour lisp, Lisp pour tous!

Avec Revit, cela ne vas trop vite...

Posté(e)

Salut,

En fait, ce n'est pas le lisp qui est trop long, c'est que lorsque je lance la commande lisp en .net via mon boutin de BD, le code de la boite de dialogue continus... même si le lisp tourne rapidement, il est toujours plus lent que le .net....

 

La valeur est ici un réel.

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

si je comprends bien tu as un prg .net externe, qui recupere la valeur USER1 d'AutoCAD. Mais celui ci va plus vite que la musique et AutoCAD a pas fini de mettre à jour la variable que tu est deja parti...

 

Idée .... Charge USER1 avec un valeur quelqu'on (Genre = "WAIT"), et dans ton prg tant que USER1 est a WAIT tu boucles....

 

Je sais pas si ca peut t'aider ...et si j'ai bien compris le pb ...

Developpement C++, C/CLI, .NET, ObjectARX, OpenDWG, O.D.A., Teigha ...

Posté(e)

Re,

Merci, ce que tu décris est la solution que j'ai mis en place, mais je voudrais trouver quelque chose de plus "direct"....

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Salut,

 

Il me semblait avoir répondu hier soir, mais j'ai dû faire une fausse manip...

 

À ma connaissance ce n'est pas (encore*) possible.

 

L'interaction entre LISP est .NET ne fonctionne que dans un sens : en définissant une fonction LISP en .NET, on peut faire passer des données LISP au programme .NET et en récupérer en retour, mais pas l'inverse.

 

Donc, si tu utilise .NET pour des boites de dialogues, il faut faire tout le traitement en .NET et renvoyer les valeurs (dans un ResultBuffer) au LISP.

 

Tu as donc deux solutions, soit utiliser ObjectDCL ou OpenDCL (si tu as pratiqué Visual Studio, tu vas vite piger), soit te plonger un plus profondément dans .NET en traduisant ce que fait ton LISP, je peux peut-être t'aider (je me sentirais moins seul...)

 

* C'est le souhait de 26% de ceux qui ont répondu au AutoCAD API Wishlist survey (un sondage sur les souhait des développeurs AutoCAD) : Improved .NETLISP Interop (e.g. invoke LISP code from .NET)

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

Posté(e)

Merci pour ta réponse... je le pressentais bien sûr, mais on ne sait jamais...

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

  • 2 mois après...
Posté(e)

À ma connaissance ce n'est pas (encore*) possible.

 

L'interaction entre LISP est .NET ne fonctionne que dans un sens : en définissant une fonction LISP en .NET, on peut faire passer des données LISP au programme .NET et en récupérer en retour, mais pas l'inverse.

 

Salut,

je pense que c'est possible, et surtout pour toi, Gile, qui bosse en c#

Il y a qq années, j'avais récupéré VLAX de Franck ockendo, et j'avais diffusé sa mise à jour, avec des exemples concrets d'utilisation.

Tout marchait bien sous VBA.

Maintenant, j'ai essayé de le mettre à jour sous VB.Net, et là, ça plante systématiquement.

par contre, je t'ai trouvé une version en c# , avec des exemples :

fait mois savoir si ça marche ...

Pas de commentaire possible, le site est en japonais :

 

http://fr.wrs.yahoo.com/_ylt=A03uv8qhQHBLuggB0JRjAQx.;_ylu=X3oDMTBzN25kaGFvBHNlYwNzcgRwb3MDMTAEY29sbwNpcmQEdnRpZAM-/SIG=12klg7hff/EXP=1265734177/**http%3a//www1.harenet.ne.jp/~hanafusa/mt/memo/archives/000236.html

 

Comme ma version, elle est basée sur interrop

 

 

 

 

 
#region Using directives

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Reflection;

using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;

using AcRx = Autodesk.AutoCAD.Runtime;
using AcEd = Autodesk.AutoCAD.ApplicationServices;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcDb = Autodesk.AutoCAD.DatabaseServices;

#endregion

namespace HLIB.Utils
{
 /// 
 /// VisualLISP????
 /// (vl-load-com)???????????
 /// 
 public class Lisp : IDisposable
 {
   private bool Disposed = false;
   private object m_vlObj;
   private object m_vlFunc;
   private AcadApplication m_app;

   /// 
   /// ???????
   /// 
   /// AutoCAD????????
   public Lisp ( AcadApplication acadApp )
   {
     m_app = acadApp;
     try {
       m_vlObj = acadApp.GetInterfaceObject( "VL.Application.16" );
       object acDoc = GetProperty( m_vlObj, "ActiveDocument" );
       m_vlFunc = GetProperty( acDoc, "Functions" );
     } catch {
       AcEd.CommandLinePrompts.Message( "\nVL????????????????." );
     }
   }

   ~Lisp ()
   {
     Dispose();
   }

   /// 
   /// VlApp ??????????????????????
   /// 
   public void Dispose ()
   {
     if ( Disposed == false ) {
       m_vlFunc = null;
       m_vlObj = null;
       m_app = null;
       Disposed = true;
     }
   }

   /// 
   /// COM????????????????????
   /// 
   /// ??????????
   /// ??????
   /// 
   private object GetProperty ( object obj, string propName )
   {
     return obj.GetType().InvokeMember( propName,
       BindingFlags.GetProperty, null, obj, null );
   }

   /// 
   /// COM????????????????????
   /// 
   /// ???????????
   /// ???????
   /// 
   private object GetIndexer ( object obj, string index )
   {
     return obj.GetType().InvokeMember( "Item",
       BindingFlags.GetProperty, null, obj, new object[] { index } );
   }

   /// 
   /// LISP????????????????
   /// 
   /// LISP???
   /// ??
   /// 
   private object InvokeLispFunction ( string funcName, object[] args )
   {
     object sym = GetIndexer( m_vlFunc, funcName );
     return sym.GetType().InvokeMember( "funcall",
       BindingFlags.InvokeMethod, null, sym, args );
   }

   /// 
   /// LISP????????
   /// 
   /// LISP?
   /// 
   public object Eval ( string lispStatement )
   {
     try {
       object sym = InvokeLispFunction( "read", new object[] { lispStatement } );
       return InvokeLispFunction( "eval", new object[] { sym } );
     } catch {
       AcEd.CommandLinePrompts.Message( "\nLISP???????????." );
       return null;
     }
   }

   /// 
   /// LISP????????????
   /// 
   /// ???
   /// 
   public object GetValue ( string symbolName )
   {
     try {
       return Eval( symbolName );
     } catch {
       return null;
     }
   }

   /// 
   /// LISP???????????
   /// 
   /// ???
   /// ?
   public void SetValue ( string symbolName, object val )
   {
     Eval( "(vl-load-com)" );
     Eval( "(defun translate-variant (data) (cond ((= (type data) 'list) (mapcar 'translate-variant data)) ((= (type data) 'variant) (translate-variant (vlax-variant-value data))) ((= (type data) 'safearray) (mapcar 'translate-variant (vlax-safearray->list data))) (t data)))" );
     Eval( "(setq " + symbolName + " (translate-variant " + val + "))" );
     Eval( "(setq translate-variant nil)" );
   }

   /// 
   /// LISP???nil??????
   /// 
   /// ???
   public void SetSymbolsToNil ( params string[] symbolName )
   {
     for ( int i = 0; i < symbolName.Length; i++ ) {
       Eval( "(setq " + symbolName[ i ] + " nil)" );
     }
   }

   /// 
   /// LIST?ArrayList???????
   /// 
   /// LIST???????
   /// 
   public ArrayList GetLispList ( string symList )
   {
     ArrayList ret = new ArrayList();
     object list;
     long len;
     try {
       list = Eval( symList );
       len = ( long )InvokeLispFunction( "length", new object[] { list } );
       for ( long i = 0; i < len; i++ ) {
         ret.Add( InvokeLispFunction( "nth", new object[] { i, list } ) );
       }
     } catch {
     }
     return ret;
   }

   /// 
   /// DXF??????????????
   /// 
   /// DXF???
   /// ???
   /// 
   private object getDxfData ( int code, object symEname )
   {
     object ent = InvokeLispFunction( "entget", new object[] { symEname } );
     object val = InvokeLispFunction( "assoc", new object[] { code, ent } );
     return InvokeLispFunction( "cdr", new object[] { val } );
   }

   /// 
   /// LSIP???????AcadEntity??????????
   /// 
   /// ??????????????
   /// AcadEntity??????
   /// 
   public bool PickSetToSelectionSet ( string symSS, ref AcadEntity[] ents )
   {
     bool ret = false;
     try {
       object ss = Eval( symSS );
       long sslength = ( long )InvokeLispFunction( "sslength", new object[] { ss } );
       ents = new AcadEntity[ sslength ];
       for ( long i = 0; i < sslength; i++ ) {
         object en = InvokeLispFunction( "ssname", new object[] { ss, i } );
         ents[ i ] = ( AcadEntity )( m_app.ActiveDocument.HandleToObject( ( string )getDxfData( 5, en ) ) );
       }
       ret = true;
     } catch {
     }
     return ret;
   }

   /// 
   /// LSIP???????ActiveX?????????????
   /// 
   /// ??????????????
   /// AcadSelectionSet????
   /// 
   public bool PickSetToSelectionSet ( string symSS, ref AcadSelectionSet acadSS )
   {
     bool ret = false;
     acadSS.Clear();
     AcadEntity[] ents = null;
     if ( PickSetToSelectionSet( symSS, ref ents ) ) {
       acadSS.AddItems( ents );
       ret = true;
     }
     return ret;
   }

   /// 
   /// LSIP???????ObjectIdCollection???????
   /// 
   /// ??????????????
   /// ObjectIdCollection????
   /// 
   public bool PickSetToSelectionSet ( string symSS, ref AcDb.ObjectIdCollection objIds )
   {
     bool ret = false;
     objIds.Clear();
     AcadEntity[] ents = null;
     if ( PickSetToSelectionSet( symSS, ref ents ) ) {
       foreach ( AcadEntity en in ents ) {
         AcDb.ObjectId id = new AcDb.ObjectId();
         id.OldId = en.ObjectID;
         objIds.Add( id );
       }
       ret = true;
     }
     return ret;
   }

   /// 
   /// ObjectIdCollection?LISP?????????????
   /// 
   /// ObjectIdCollection
   /// ????????????
   /// 
   public bool SelectionSetToPickSet ( AcDb.ObjectIdCollection objIds, string symSS )
   {
     bool ret = false;
     try {
       Eval( "(setq " + symSS + " (ssadd))" );
       foreach ( AcDb.ObjectId id in objIds )
         Eval( "(ssadd (handent \"" + id.Handle + "\")" + symSS + ")" );
       ret = true;
     } catch {
     }
     return ret;
   }

   /// 
   /// AcadSelectionSet?LISP?????????????
   /// 
   /// AcadSelectionSet
   /// ????????????
   /// 
   public bool SelectionSetToPickSet ( AcadSelectionSet acadSS, string symSS )
   {
     bool ret = false;
     try {
       Eval( "(setq " + symSS + " (ssadd))" );
       foreach ( AcadEntity en in acadSS )
         Eval( "(ssadd (handent \"" + en.Handle + "\")" + symSS + ")" );
       ret = true;
     } catch {
     }
     return ret;
   }
 }
}

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

Salut,

 

J'ai fait quelques corrections et ça semble fonctionner (avec A2007).

Inconvénient : le retour est de type System.__ComObject qu'il faut donc traduire en fonction de son type pour une utilisation avec.NET

Mais je vois que tu as trouvé mieux...

using System;
using System.Collections;
using System.Reflection;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using Autodesk.AutoCAD.Runtime;

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(HLIB.Utils.Commands))]

namespace HLIB.Utils
{
   public class Lisp : IDisposable
   {
       private bool Disposed = false;
       private object m_vlObj;
       private object m_vlFunc;
       private AcadApplication m_app;

       public Lisp(AcadApplication AutoCAD)
       {
           m_app = acad;
           try
           {
               m_vlObj = m_app.GetInterfaceObject("VL.Application.16");
               object acDoc = GetProperty(m_vlObj, "ActiveDocument");
               m_vlFunc = GetProperty(acDoc, "Functions");
           }
           catch
           {
               acadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                   "\nErreur instanciation Lisp");
           }
       }

       ~Lisp()
       {
           Dispose();
       }

       public void Dispose()
       {
           if (Disposed == false)
           {
               m_vlFunc = null;
               m_vlObj = null;
               m_app = null;
               Disposed = true;
           }
       }

       private object GetProperty(object obj, string propName)
       {
           return obj.GetType().InvokeMember(propName,
             BindingFlags.GetProperty, null, obj, null);
       }

       private object GetIndexer(object obj, string index)
       {
           return obj.GetType().InvokeMember("Item",
             BindingFlags.GetProperty, null, obj, new object[] { index });
       }

       private object InvokeLispFunction(string funcName, object[] args)
       {
           object sym = GetIndexer(m_vlFunc, funcName);
           return sym.GetType().InvokeMember("funcall",
             BindingFlags.InvokeMethod, null, sym, args);
       }

       public object Eval(string lispStatement)
       {
           try
           {
               object sym = InvokeLispFunction("read", new object[] { lispStatement });
               return InvokeLispFunction("eval", new object[] { sym });
           }
           catch
           {
               Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                   "\nExpression LISP non valide");
               return null;
           }
       }

       public object GetValue(string symbolName)
       {
           try
           {
               return Eval(symbolName);
           }
           catch
           {
               return null;
           }
       }

       public void SetValue(string symbolName, object val)
       {
           Eval("(vl-load-com)");
           Eval("(defun translate-variant (data) (cond ((= (type data) 'list) (mapcar 'translate-variant data)) ((= (type data) 'variant) (translate-variant (vlax-variant-value data))) ((= (type data) 'safearray) (mapcar 'translate-variant (vlax-safearray->list data))) (t data)))");
           Eval("(setq " + symbolName + " (translate-variant " + val + "))");
           Eval("(setq translate-variant nil)");
       }

       public void SetSymbolsToNil(params string[] symbolName)
       {
           for (int i = 0; i             {
               Eval("(setq " + symbolName[i] + " nil)");
           }
       }

       public ArrayList GetLispList(string symList)
       {
           ArrayList ret = new ArrayList();
           object list;
           long len;
           try
           {
               list = Eval(symList);
               len = (long)InvokeLispFunction("length", new object[] { list });
               for (long i = 0; i                 {
                   ret.Add(InvokeLispFunction("nth", new object[] { i, list }));
               }
           }
           catch
           {
           }
           return ret;
       }

       private object getDxfData(int code, object symEname)
       {
           object ent = InvokeLispFunction("entget", new object[] { symEname });
           object val = InvokeLispFunction("assoc", new object[] { code, ent });
           return InvokeLispFunction("cdr", new object[] { val });
       }

       public bool PickSetToSelectionSet(string symSS, ref AcadEntity[] ents)
       {
           bool ret = false;
           try
           {
               object ss = Eval(symSS);
               long sslength = (long)InvokeLispFunction("sslength", new object[] { ss });
               ents = new AcadEntity[sslength];
               for (long i = 0; i                 {
                   object en = InvokeLispFunction("ssname", new object[] { ss, i });
                   ents[i] = (AcadEntity)(m_app.ActiveDocument.HandleToObject((string)getDxfData(5, en)));
               }
               ret = true;
           }
           catch
           {
           }
           return ret;
       }

       public bool PickSetToSelectionSet(string symSS, ref AcadSelectionSet acadSS)
       {
           bool ret = false;
           acadSS.Clear();
           AcadEntity[] ents = null;
           if (PickSetToSelectionSet(symSS, ref ents))
           {
               acadSS.AddItems(ents);
               ret = true;
           }
           return ret;
       }

       public bool PickSetToSelectionSet(string symSS, ref ObjectIdCollection objIds)
       {
           bool ret = false;
           objIds.Clear();
           AcadEntity[] ents = null;
           if (PickSetToSelectionSet(symSS, ref ents))
           {
               foreach (AcadEntity en in ents)
               {
                   ObjectId id = new ObjectId((int)en.ObjectID);
                   objIds.Add(id);
               }
               ret = true;
           }
           return ret;
       }

       public bool SelectionSetToPickSet(ObjectIdCollection objIds, string symSS)
       {
           bool ret = false;
           try
           {
               Eval("(setq " + symSS + " (ssadd))");
               foreach (ObjectId id in objIds)
                   Eval("(ssadd (handent \"" + id.Handle + "\")" + symSS + ")");
               ret = true;
           }
           catch
           {
           }
           return ret;
       }

       public bool SelectionSetToPickSet(AcadSelectionSet acadSS, string symSS)
       {
           bool ret = false;
           try
           {
               Eval("(setq " + symSS + " (ssadd))");
               foreach (AcadEntity en in acadSS)
                   Eval("(ssadd (handent \"" + en.Handle + "\")" + symSS + ")");
               ret = true;
           }
           catch
           {
           }
           return ret;
       }
   }

   public class Commands
   {
       [CommandMethod("TEST")]
       public static void Test()
       {
           Document doc = acadApp.DocumentManager.MdiActiveDocument;
           Editor ed = doc.Editor;
           PromptStringOptions pso = new PromptStringOptions("\nEntrez une expression LISP: ");
           pso.AllowSpaces = true;
           PromptResult pr = ed.GetString(pso);
           if (pr.Status != PromptStatus.OK)
               return;
           try
           {
               AcadApplication AutoCAD = acadApp.AcadApplication as AcadApplication;
               using (Lisp lsp = new Lisp(acad))
               {
                   object result = lsp.Eval(pr.StringResult);
                   if (result == null)
                       ed.WriteMessage("\nRésultat : nil");
                   else
                   ed.WriteMessage("\nRésultat : " + result.ToString());
               }
           }
           catch (System.Exception ex)
           {
               ed.WriteMessage("\nErreur: " + ex.Message);
           }
       }
   }
}

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

Posté(e)
Salut,

 

J'ai fait quelques corrections et ça semble fonctionner (avec A2007).

Inconvénient : le retour est de type System.__ComObject qu'il faut donc traduire en fonction de son type pour une utilisation avec.NET

Mais je vois que tu as trouvé mieux...

 

Super, mais j'ai essayé de voir ce que tu avais changé, et de compiler ce code, mais il semble que ce ne soit pas le code original que tu as compilé :

si je faits un copié collé, je retrouve les erreurs que j'avais péniblement corrigés :

peut tu m'envoyer le code source original, (et peut être à minima) que je puisse le tester ?

 

Je ne sais pas si l'autre solution est mieux : j'aime mieux une solution qui marche sur plusieurs versions, plusieurs plateformes, comme le lisp !

 

merci d'avance !

PS : le formatage code de ce site est chiaznt, avec l'ajout d'interligne :

ça peu pas être corrigé ?

 

Gégé

 

 

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

Si si, c'est bien le code que j'ai fait marcher sur 2007.

 

Pour 2010 il faut remplacer :

ObjectId id = new ObjectId((int)en.ObjectID);

par :

ObjectId id = new ObjectId((IntPtr)en.ObjectID);

 

À part l'expression ci-dessus, je me rappelle avoir corrigé des :

AcEd.CommandLinePrompts.Message()

et modifié les instructions using (j'en oublie peut-être)

 

Et je viens de tester, ça fonctionne sur 2010.

 

Je suis d'accord le formatage des codes sur CADxp n'est pas top (il est mieux que ce qu'il a été).

Viens sur AcadLabs (le seul site francophone dédié à AutoCAD où le forum .NET est le forum le plus actif).

Sinon pour éviter les interlignages, je fait "Citer" sur le message qui contient le code et j'ai accès au message originel.

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

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é