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

Is it possible to convert from Lisp to C# code?

13 REPLIES 13
Reply
Message 1 of 14
thenndral
4008 Views, 13 Replies

Is it possible to convert from Lisp to C# code?

Hi,

 

I'm using Autocad 2013 with C#

I don't have an idea about Lisp, so I'm looking for convert Lisp code.
Is it possible to convert from Lisp to C#?
Any free tools or Link available?

 

I need to convert the following code.

 

(defun c:xx ()
(vl-load-com)
 
  (acet-error-init
   (list (list  "cmdecho" 0
		"osmode" (getvar "osmode")
                "highlight" (getvar "highlight")
                "limcheck" 0
                "pickstyle" 0
		"orthomode" (getvar "orthomode")
         );list
         T
   );list
  );acet-error-init
 
 
 
  (setvar "osmode" 0)
  (setq ss (ssget "X" '((0 . "LINE") (67 . 0))))
  (setq index 0 Xmin 1E10 Xmax 0 Ymin 1E10 Ymax 0)
  (repeat (sslength ss)
    (setq ename (ssname ss index)
          obj   (vlax-ename->vla-object ename))
    (if (= (strcase (vla-get-layer obj)) "CENTER")
      (setq index (1+ index))
      (progn
	(setq spt_x (car  (vlax-curve-getstartpoint obj))
	      spt_y (cadr (vlax-curve-getstartpoint obj))
	      ept_x (car  (vlax-curve-getendpoint obj))
	      ept_y (cadr (vlax-curve-getendpoint obj))
	)
	(if (<= Xmin spt_x) (if (<= Xmin ept_x) (setq Xmin Xmin) (setq Xmin ept_x)) (setq Xmin spt_x))
	(if (>= Xmax spt_x) (if (>= Xmax ept_x) (setq Xmax Xmax) (setq Xmax ept_x)) (setq Xmax spt_x))
	(if (<= Ymin spt_y) (if (<= Ymin ept_y) (setq Ymin Ymin) (setq Ymin ept_y)) (setq Ymin spt_y))
	(if (>= Ymax spt_y) (if (>= Ymax ept_y) (setq Ymax Ymax) (setq Ymax ept_y)) (setq Ymax spt_y))
	(setq index (1+ index))
       )
    )
  )
  (setq TOP   (list Xmin Ymax)
	FRONT (list Xmin Ymin)
	RIGHT (list Xmax Ymin)
  )
 
  (setq fname (vl-filename-base (getvar "dwgname")))
  (setq index_test (substr fname 5 2))
  (setq bname_T (strcat "c:/Mark/20140204" index_test "T.dwg"))
  (setq bname_F (strcat "c:/Mark/20140204" index_test "F.dwg"))
  (setq bname_R (strcat "c:/Mark/20140204" index_test "R.dwg"))
 
  (command "-insert" bname_T TOP "" "" "")
  (command "-insert" bname_F FRONT "" "" "")
  (command "-insert" bname_R RIGHT "" "" "")
 
 
  (setq mblock (ssget "X" '((0 . "INSERT"))))
  (setq time (rtos (getvar "cdate") 2 8))
  (setq name (substr time 10 6))
  (command "-group" "c" name name mblock "")
 
 
 
  (acet-error-restore)
  (princ)
);;defun
 

 

 

Please give me some suggestion to convert from Lisp to C#.

 

Thanks in advance,
thenndral

13 REPLIES 13
Message 2 of 14
_gile
in reply to: thenndral

Hi,

 

As far as know there's none tool to automatically convert LISP to .NET.

 

Anyway, I think there's no need to convert a LISP routine which works fine. You can call it from the command line or from a .NET application:

Application.Invoke(new ResultBuffer(new TypedValue((int)LispDataType.Text, "c:xx")));

 The other way should be re-writing the LISP routine in C# from scratch.

 

 

PS: I do not know where you found this LISP routine neither who wrote it but I notice some "not so good practices" in it:

- none local variable declarations

- using of sub-routines defined in a third part application (Express Tools)



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 14
thenndral
in reply to: _gile

Hi gile,

 

Thanks for your quick reply.
I agree. Lisp routines works fine. If the user give the command from commandline XX, It works.

 

for ex. I have 200 or more drawings, If the user open one by one drawing and type XX command. It is a tedious work because of many drawing file.

I don't know how to modify the lisp rountine works for folder selection, so I asked a question in forum for convertion tool.

 

I think, need to modify the code in C#, open folder[sub-folder] and load a drawing file in memory and call this code will work for the entire folder.

Application.Invoke(new ResultBuffer(new TypedValue((int)LispDataType.Text, "c:xx")));

 

If I want to open drawing in memory, I guess need some modification in lisp code, ie. pass drawing file name to lisp command.

 

Is there is any possible solution or suggestion much appreciated.

 

Thanks in advance,
thenndral

Message 4 of 14
_gile
in reply to: thenndral

IMO, the best way should be writing a .NET method which does the same as this LISP routine does (this wouldn't be so difficult) and use this method in you batch process.

Interactions between different programming environment is rarely the easier and safer way.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 14
thenndral
in reply to: _gile

Hi gile,

 

Thanks for your reply.

Let me try to do this by manually.

So first I need to learn Lisp routine.

 

Thanks a lot,

thenndral.

Message 6 of 14
thenndral
in reply to: thenndral

Hi,

 

I know its not fair to ask this but I can't able to find the solution/ how to convert in maually from lisp to c#.

because lack of knowledge in lisp and c# as well.

 

Could any one help this code convert from lisp to c#? 

It will be very grateful.

 

Thanks in advance,

thenndral

Message 7 of 14
thenndral
in reply to: thenndral

Hi gile,

 

Thanks for your code.

 

I use your code in C#.

Lisp Routine is in "C:\Test" folder

file name: exam.LSP

 

Application.Invoke(new ResultBuffer(new TypedValue((int)LispDataType.Text, "c:xx")));

 

My code:

       [CommandMethod("OpenDrawing", CommandFlags.Session)]
        public static void OpenDrawing()
        {
            string strFileName = @"D:\AutoCAD\testing\Stu49.dwg"; 
            DocumentCollection acDocMgr = Application.DocumentManager;
    
            if (File.Exists(strFileName))
            {
                acDocMgr.Open(strFileName, false);
                Document doc = acDocMgr.MdiActiveDocument;
                Editor ed = doc.Editor;
                
                //get titlemode
                short tilemode = (short)Application.GetSystemVariable("TILEMODE");
                using (DocumentLock docLock = doc.LockDocument())
                {
                    //check Model space or paperspace
                    if (tilemode == 0)
                    {
                        try 
                        {
                            //If paperspace switch to modelspace.
                            HostApplicationServices.WorkingDatabase.TileMode = true;

                            //insert block from Lisp routines.
                            Application.Invoke(new ResultBuffer(new TypedValue((int)LispDataType.Text, "c:xx")));
                        }
                        catch (Exception ex)
                        {
                            AcadApp.ShowAlertDialog(ex.Message);
                        }
                    }
                }
            }
            else
            {
                acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " + strFileName + " does not exist.");
            }
        }

 

I getting the following error.

error.png

 

Could you please tell me how to solve this.

I dont know, any syntax error in lisp calling line.

 

Thanks in advance,

thenndral

 

Message 8 of 14
JamesMaeding
in reply to: thenndral

I ran accross this, though its months old.

The problem here is you cannot invoke a lisp function that makes COMMAND calls.

Its a major limitation of trying to mix lisp with .net, so you really have to look at your lisp functions before assuming they can be mixed.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 9 of 14
JamesMaeding
in reply to: JamesMaeding

I know I'm a "party of one" on this thread, but I figured out how to get around this limitation of not using command calls in the lisp function.

Dale gave a kudos so there is more to the story here.

 

The problem lies in the fact that you can only send so much text to the command line using doc.SendStringToExecute.

I know 2016 has another function you use, but I think the issue is the same.

 

So how do you get all your paramenters over to lisp, if you cannot send them on command line?

You send them ahead of time.

There are a few ways to do this, such as writing all parameter info needed to a text file that the lisp function could read when called.

Then you fire the lisp function using SendStringToExecute, and it reads the text file to get its params.

 

What I have found to work the best is to make a lisp funtion that sets a lisp global variable.

You run the lisp in .net using AcAp.Invoke

The function is this:

;testing... (C:SET-CTGLOBALVAR "(\"test123\" ( 1 2 3))")


(DEFUN C:SET-CTGLOBALVAR (NAME-VAL / TMP)
 (SETQ TMP (READ NAME-VAL))
 (SET (READ (CAR TMP)) (CADR TMP))
)

 

 

That takes in a string, which is read into a list. The first item in the list is the global var name I want set.

The next is the list of info to be set.

 

so you will notice the read statement in there. What I do in .net is serialize my info to a string, which lisp reads into a list.

That allows for super fast deserializing in lisp, which is critical as I send a lot of info, like 1200 civil engineering alignments.

That serialization function is not trivial, but you can adapt functions out there that loop through a list of objects and make linear.

 

Then my lisp function uses the global var to do its stuff.

Its worked great. Just note that it runs async - after the .net code that calls it.

 

so the partial .net code generally looks like this:

//prep var list
            List<object> pLst = new List<object>() { "IMPORT3DALIGNSCTNET-GVAR", infoLst };
            string xmlstr = HANestedAList.ObjPropListToListReadString(pLst);

            //set lisp global var with string
            ResultBuffer pargs = new ResultBuffer();
            pargs.Add(new TypedValue(5005, "C:SET-CTGLOBALVAR"));
            pargs.Add(new TypedValue(5005, xmlstr));
            //focus command line
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            using (DocumentLock doclock = doc.LockDocument()) {
                FocusToDwgView();
#if ACAD
                AcAp.Invoke(pargs); //send data
                doc.SendStringToExecute("IMPORT3DALIGNSCTNET ", true, false, false); //run command

 I can explain more if anyone needs, but this technique allows you to use those lisp functions with command in them.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 10 of 14

Hi, No you are not a party of one. This is really interesting and valuable research/information so thank you very much. I haven't got an immediate need, but will work through your examples when I get a minute. I'll revisit this post if (when) I hit snags. Regards, Dale




______________
Yes, I'm Satoshi.
Message 11 of 14

I will start a new thread, as I figured out how to go full circle from .net, to lisp, and back with return info now.

That is something I have not seen anyone talk about so far.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 12 of 14
thenndral
in reply to: JamesMaeding

Hi,

 

Thanks for your research and for your valuable time. Actually I move to another project. Anyhow I will use this information for my future use. Thanks again.

 

 

Cheers,
Thenndral

Message 13 of 14

jmaeding, Brilliant. Please include a link on this thread when you do so. Thanks, Dale.




______________
Yes, I'm Satoshi.
Message 14 of 14

Hi jmaeding, Did you proceed with this project at all? Dale




______________
Yes, I'm Satoshi.

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost