Convert Lisp to C#

Convert Lisp to C#

Anonymous
Not applicable
4,743 Views
12 Replies
Message 1 of 13

Convert Lisp to C#

Anonymous
Not applicable

Hello all,

 

I am newbie in .Net C# and learning. I have lisp wrote with att in block.

 

Can someone convert to C# so i can learn more in .Net

 

Thanks in advance.

This is my code lisp:
(defun c:tcount_att (/ ss ob start_num inc_num sum ename new_value OLDER *error*)
  (vl-load-com)
  (setq OLDER *error*
	*error* myerror)
  (if (setq ss (ssget '((0 . "INSERT"))))
    (progn
      (initget 1 "X Y Select")
      (setq ob (getkword "\nSort selected objects by [X/Y/Select-order] <Select-order>: "))
      (cond
	((= ob "X")
	 (setq ss (sort_x ss))
	 )
	((= ob "Y")
	 (setq ss (sort_y ss))
	 )
	((= ob "Select")
	 (setq ss (sort ss))
	 )
	);cond
      (setq start_num (getint "\nSpecify starting number <1>: "))
      (if (= start_num nil)
	(setq start_num 1)
	(setq start_num start_num)
	)
      (setq inc_num (getint "\nSpecify increment number <1>: "))
      (if (= inc_num nil)
	(setq inc_num 1)
	(setq inc_num inc_num)
	);if
      (setq sum 0)
      (setq sum (apply '+ (list sum start_num)))
      (setq ename (entnext (car ss)))
      (if (/= (cdr (assoc 0 (entget ename))) "SEQEND")
	(progn
	  (setq new_value (rtos sum 2 0))
	  (entmod (subst (cons 1 new_value) (assoc 1 (entget ename)) (entget ename)))
	  (entupd (car ss))
	  )
	)      
      (mapcar '(lambda (obj)
		 (setq sum (apply '+ (list sum inc_num)))
		 (setq ename (entnext obj))
		 (if (/= (cdr (assoc 0 (entget ename))) "SEQEND")
		   (progn
		     (setq new_value (rtos sum 2 0))
		     (entmod (subst (cons 1 new_value) (assoc 1 (entget ename)) (entget ename)))
		     (entupd obj)
		     )
		   )
		 )
	      (cdr ss)
	      )
      );progn
    );if
  (setq *error* OLDER)     
  (princ)  
  );defun
;;;;;;;;
(defun sort_x (sset / n ss1 )
  (setq ss1 nil)
  (setq n 0)
  (repeat (sslength ss)
    (setq ss1 (append ss1 (list (ssname ss n))))
    (setq n (1+ n))
    );repeat
  (setq ss1 (vl-sort ss1 '(lambda (e1 e2) (< (car (cdr (assoc 10 (entget e1))))
					     (car (cdr (assoc 10 (entget e2))))
					     )
			    )
		     )
	);setq
  )
;;;;;;;;
(defun sort_y (sset / n ss1 )
  (setq ss1 nil)
  (setq n 0)
  (repeat (sslength ss)
    (setq ss1 (append ss1 (list (ssname ss n))))
    (setq n (1+ n))
    )
  (setq ss1 (vl-sort ss1 '(lambda (e1 e2) (< (cadr (cdr (assoc 10 (entget e1))))
					     (cadr (cdr (assoc 10 (entget e2))))
					     )
			    )
		     )
	);setq
  )
;;;;;;;;
(defun sort (sset / n ss1 )
  (setq ss1 nil)
  (setq n 0)
  (repeat (sslength ss)
    (setq ss1 (append ss1 (list (ssname ss n))))
    (setq n (1+ n))
    )
  ss1
  )
;;;;;;;;;;;;;;;;;;;;;;
(defun myerror (s)                    
  (cond
    ((= s "quit / exit abort") (princ))
    ((/= s "Function cancelled") (princ (strcat "\nError: " s)))
  )
  (setq *error* OLDER)        
  (princ)
)

(princ "\nCommand: tcount_att ")
(princ)

      
0 Likes
Accepted solutions (1)
4,744 Views
12 Replies
Replies (12)
Message 2 of 13

kerry_w_brown
Advisor
Advisor

You'll get a better long term result if you attempt to make the translation yourself.

 

But first, have you tried writing C# code without the extra burden of translating lisp. ?

 

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
Message 3 of 13

_gile
Consultant
Consultant

Hi,

 

I totally agree with Kerry.


I could, like many others here, convert this LISP routine into C# but it would be the worst service to make you want to learn C# (.NET more accurately).


Learning .NET is a more difficult task than learning AutoLISP which cannot be content to read code written by others.


Start by learning the basics of .NET (Object Oriented Programming, Visual Studio,.NET Framework and C # syntax) outside of AutoCAD (standard Window programming) before trying to use
AutoCAD .NET API.

 

PS: Are the author of the LISP routine ?

If so, before trying to convert it to C#, you could simplify/optimize some expressions as:

(setq sum 0)
(setq sum (apply '+ (list sum start_num)))

or the way you iterate list of selected objects.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 13

_gile
Consultant
Consultant

@Anonymous

 

If you really want a C# code, I'd post one.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 13

Anonymous
Not applicable

Hi, 

 

I am reading some AutoCAD .NET Developer's Guide. And right some code: draw line, circle....function simple. Beginer 🙂

 

I know the way write C# different lisp.  

 

Can you have example code C#: select block , and modify value att in block by getstring.?

 

I am still learning about it. 

 

Thanks

 

0 Likes
Message 6 of 13

Anonymous
Not applicable

Hi Gile,

 

I am learning basics of .NET

 

I mean convert lisp to C# then see how can write C# for object ACAD.

And  simplify/optimize:

 

(setq sum 0)
(setq sum (apply '+ (list sum start_num)))

 change to: 

(setq sum 0)
(setq sum (+ sum start_num))

Thanks for repply. 

0 Likes
Message 7 of 13

_gile
Consultant
Consultant
Accepted solution

Here's a C# conversion of the LISP routine.

 

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

namespace TCountAttribute
{
    public class Commands
    {
        [CommandMethod("TCOUNT_ATT")]
        public void TCountAttCommand()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            
            // build a selection filter to select only block references with attributes
            // and prompt the user fo a selection
            TypedValue[] filter = { new TypedValue(0, "INSERT"), new TypedValue(66, 1) };
            PromptSelectionResult selResult = ed.GetSelection(new SelectionFilter(filter));
            // exit the command if none block selected
            if (selResult.Status != PromptStatus.OK)
                return;

            // start a transaction to open selected blocks
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                // build a list of block references from the selection set
                List<BlockReference> blocks = new List<BlockReference>();
                foreach (SelectedObject so in selResult.Value)
                {
                    BlockReference br = (BlockReference)tr.GetObject(so.ObjectId, OpenMode.ForRead);
                    blocks.Add(br);
                }

                // prompt the user for a sorting option
                PromptKeywordOptions kwordOptions = new PromptKeywordOptions(
                    "\nSort selected objects by [X/Y/Select-order]", 
                    "X Y Select-order");
                kwordOptions.Keywords.Default = "Select-order";
                PromptResult kwordResult = ed.GetKeywords(kwordOptions);
                if (kwordResult.Status != PromptStatus.OK) // <- cancel
                    return;
                // sort the list by X or Y (already done for select order)
                switch (kwordResult.StringResult)
                {
                    case "X":
                        blocks.Sort((b1, b2) => b1.Position.X.CompareTo(b2.Position.X));
                        break;
                    case "Y":
                        blocks.Sort((b1, b2) => b1.Position.Y.CompareTo(b2.Position.Y));
                        break;

                }

                // prompt the user for the starting number
                PromptIntegerOptions intOptions = new PromptIntegerOptions("\nSpecify starting number: ");
                intOptions.DefaultValue = 1;
                intOptions.UseDefaultValue = true;
                PromptIntegerResult intResult = ed.GetInteger(intOptions);
                if (intResult.Status != PromptStatus.OK) // <- cancel
                    return;
                int num = intResult.Value;

                // prompt the user for the increment number
                intOptions.Message = "\nSpecify increment number: ";
                intResult = ed.GetInteger(intOptions);
                if (intResult.Status != PromptStatus.OK) // <- cancel
                    return;
                int incNum = intResult.Value;

                // set the first attribute value of each block reference in the list
                foreach (BlockReference br in blocks)
                {
                    ObjectId firstAttId = br.AttributeCollection[0];
                    AttributeReference attRef = (AttributeReference)tr.GetObject(firstAttId, OpenMode.ForWrite);
                    attRef.TextString = num.ToString();
                    num += incNum; // increment the value
                }
                tr.Commit();
            }
        }
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 8 of 13

_gile
Consultant
Consultant

gametv.himo a écrit :
And  simplify/optimize:

 

(setq sum 0)
(setq sum (apply '+ (list sum start_num)))

 change to: 

(setq sum 0)
(setq sum (+ sum start_num))

Thanks for repply. 


Or, simply:

(setq sum start_sum)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 13

Anonymous
Not applicable

Perfect Gile, Smiley Very Happy

 

You are really expert. Very quick.

 

I can learn a lot of from your code.

 

Thank you very much.Heart

0 Likes
Message 10 of 13

Anonymous
Not applicable

yep, you are right. 😄

 

And 1 more question.

 

How can add print str "command: TCOUNT_ATT" when netload .dll ? I was combine to dll .

 

 

0 Likes
Message 11 of 13

Anonymous
Not applicable

i add line but not working

        public void Test()
        {
            Editor ed =
                Application.DocumentManager.MdiActiveDocument.Editor;
            ed.WriteMessage("Command: TCOUNT_ATT");
        }

 

0 Likes
Message 12 of 13

_gile
Consultant
Consultant

To execute some code at DLL loading, you should have a class in your project which implements the IExtensionApplication interface.

 

This may be either a separate class (as below) or the same class as the one where the command is defined (as in upper link sample).

 

    public class Initialization : IExtensionApplication
    {
        public void Initialize()
        {
            var ed = Application.DocumentManager.MdiActiveDocument.Editor;
            ed.WriteMessage("\nCommand: TCOUNT_ATT");
        }

        public void Terminate()
        {
            // do nothing here, but the Terminate() method must be explicitly implemented
        }
    }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 13 of 13

Anonymous
Not applicable

Okey

 

It is very useful.

 

Now time study your code.

 

Thank you again, Gile.

0 Likes