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

Convert Lisp to C#

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
Anonymous
3518 Views, 12 Replies

Convert Lisp to C#

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)

      
12 REPLIES 12
Message 2 of 13
kdub_nz
in reply to: Anonymous

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 in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

Message 3 of 13
_gile
in reply to: kdub_nz

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

Message 4 of 13
_gile
in reply to: _gile

@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
in reply to: kdub_nz

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

 

Message 6 of 13
Anonymous
in reply to: _gile

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. 

Message 7 of 13
_gile
in reply to: Anonymous

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
in reply to: Anonymous


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
in reply to: _gile

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

Message 10 of 13
Anonymous
in reply to: _gile

yep, you are right. 😄

 

And 1 more question.

 

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

 

 

Message 11 of 13
Anonymous
in reply to: Anonymous

i add line but not working

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

 

Message 12 of 13
_gile
in reply to: Anonymous

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

Message 13 of 13
Anonymous
in reply to: _gile

Okey

 

It is very useful.

 

Now time study your code.

 

Thank you again, Gile.

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