See the top rated post in this thread. Click here

Results 1 to 10 of 10

Thread: Extending the power of LISP through .NET

  1. #1
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,028
    Login to Give a bone
    1

    Default Extending the power of LISP through .NET

    I think it would be good to start a thread on adding functionality to LISP from .NET.

    This is like the wishlist.

    What functionality would you like to see in LISP that .NET has?

    Or just general wishes.

    I prefer to write code in VB.NET but I think the solutions should be in both.

    We are all programmers, so LISP is the topic... but the code will be in other languages.

    Also general template files and 2012 vb.net c# express editors download links would be useful.

    Ideas?

    P=
    AutomateCAD

  2. #2
    Certifiable AUGI Addict
    Join Date
    2001-03
    Location
    Tallahassee, FL
    Posts
    3,047
    Login to Give a bone
    0

    Default Re: Extending the power of LISP through .NET

    Viewports cannot be modified in lisp. Is it possible in NET? Functions to set Height, Width, Center, etc... would be nice. A library of yours which adds lisp functions saved somewhere we could check for updates would be even better. Some type of help file would make it perfect!
    Tom Beauford P.S.M. - Civil 2019 on Windows 10 Enterprise
    Design Analysis - Leon County Public Works/Engineering Wrap [CODE] tags around selected text
    2280 Miccosukee Rd. Tallahassee, FL 32308-5310
    Ph# (850)606-1516 Home Page

  3. #3
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,028
    Login to Give a bone
    0

    Default Re: Extending the power of LISP through .NET

    Well using activeX you can change some of the properties of viewports

    (vla-put-width objViewport 1.0)

    Works

    But just to start the conversation...

    Using VB.Net the following also works to change the width of a viewport.



    Code:
    Imports Autodesk.AutoCAD.ApplicationServices
    Imports Autodesk.AutoCAD.DatabaseServices
    Imports Autodesk.AutoCAD.Runtime
    
    Public Class LISPClass
        ' syntax (ViewportWidthPut (entlast) 10.0)
        <LispFunction("ViewportWidthPut")> _
        Public Function ViewportWidthPut(ByVal rbfLISPArguments As ResultBuffer)
            On Error GoTo OnError
            Dim arrLISPArguments As TypedValue() = rbfLISPArguments.AsArray
            If arrLISPArguments.Length = 2 Then
    
                Dim oidSelection As ObjectId = arrLISPArguments(0).Value
                Dim dblWidth As Double = arrLISPArguments(1).Value
                Dim objDocument As Document = Application.DocumentManager.MdiActiveDocument
    
                Using objTransaction As Transaction = objDocument.Database.TransactionManager.StartTransaction()
                    Dim objViewport As Viewport = CType(oidSelection.GetObject(OpenMode.ForWrite), Viewport)
                    objViewport.Width = dblWidth
                    objTransaction.Commit()
                End Using
                Return New TypedValue(LispDataType.T_atom, -1)
            End If
    OnError: Return New TypedValue(LispDataType.Nil, -1)
        End Function
    
    End Class
    AutomateCAD

  4. #4
    Programming Moderator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,385
    Login to Give a bone
    0

    Default Re: Extending the power of LISP through .NET

    Quote Originally Posted by Tom Beauford View Post
    Viewports cannot be modified in lisp. Is it possible in NET? Functions to set Height, Width, Center, etc... would be nice. A library of yours which adds lisp functions saved somewhere we could check for updates would be even better. Some type of help file would make it perfect!
    Here's a loosely related example of a .NET LispFunction Method, which modifies the Active Page Setup of a given Layout... Downloadable files here:

    http://forums.augi.com/showthread.ph...=1#post1219546



    Quote:

    Quote Originally Posted by BlackBox View Post
    Building on my earlier post, here's an incremental update which makes available a LispFunction Method named vla-SetActivePageSetup.

    A help file for this function is attached to the bottom of this post. 2011 .chm colors used. The help file is in HTM format, but a .TXT extension has been added, as .HTM is not a supported upload file format here at AUGI.

    Please note that while I have tested this enough to determine that it functions as designed (tested for 2010-2012, using Civil 3D), I have not yet had an opportunity to test this via ObjectDBX, etc., so constructive criticism is welcomed.



    vla-SetActivePageSetup

    Sets a named page setup active for a given layout by name

    Code:
    (vla-SetActivePageSetup layoutName pageSetupName)


    Arguments

    layoutName

    A string specifying the name of a layout to apply the named page setup.


    pageSetupName

    A string specifying the page setup to apply to the layout.



    Return Values

    Nil if either the layoutName, or pageSetupName cannot be found. Otherwise, T if successful.



    Example

    Code:
    (foreach layoutname (layoutlist)
      (vla-SetActivePageSetup layoutname “YourPageSetupName”)
    )


    Like me, most of you would prefer to compile the .NET assembly yourself, so here's the source code for your use:

    Code:
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.EditorInput;
    using Autodesk.AutoCAD.Runtime;
    
    using acApp = Autodesk.AutoCAD.ApplicationServices.Application;
    
    [assembly: CommandClass(typeof(BlackBox.AutoCAD.PageSetup.Commands))]
    
    namespace BlackBox.AutoCAD.PageSetup
    {
        public class Commands
        {
            [LispFunction("vla-SetActivePageSetup")]
            public bool vlaSetActivePageSetup(ResultBuffer resbuf)
            {
                Document doc = acApp.DocumentManager.MdiActiveDocument;
    
                Database db = doc.Database;
    
                bool ret = false;
    
                try
                {
                    if (resbuf == null)
                        throw new TooFewArgsException();
    
                    TypedValue[] args = resbuf.AsArray();
                    if (args.Length < 1)
                        throw new TooFewArgsException();
    
                    if (args.Length > 2)
                        throw new TooManyArgsException();
    
                    if (args[0].TypeCode != (int)LispDataType.Text)
                        throw new ArgumentTypeException("stringp", args[0]);
    
                    if (args.Length == 2 && args[1].TypeCode != (int)LispDataType.Text)
                        throw new ArgumentTypeException("stringp", args[1]);
    
                    string layoutName = args[0].Value.ToString().ToUpper();
                    string pageSetupName = args[1].Value.ToString().ToUpper();
    
                    using (DocumentLock dl = doc.LockDocument())
                    {
                        using (Transaction tr =
                            doc.Database.TransactionManager.StartOpenCloseTransaction())
                        {
                            DBDictionary layoutDic =
                                tr.GetObject(doc.Database.LayoutDictionaryId,
                                OpenMode.ForRead, false) as DBDictionary;
    
                            if (layoutDic != null)
                            {
                                foreach (DBDictionaryEntry entry in layoutDic)
                                {
                                    Layout layout =
                                        tr.GetObject(entry.Value,
                                        OpenMode.ForRead) as Layout;
    
                                    if (layout != null && 
                                        layout.LayoutName.ToUpper() == layoutName)
                                    {
                                        DBDictionary acPlotSettings =
                                            tr.GetObject(db.PlotSettingsDictionaryId,
                                            OpenMode.ForRead) as DBDictionary;
    
                                        if (acPlotSettings.Contains(pageSetupName))
                                        {
                                            PlotSettings ps =
                                                (PlotSettings)tr.GetObject(
                                                    acPlotSettings.GetAt(pageSetupName), OpenMode.ForRead);
    
                                            layout.UpgradeOpen();
    
                                            layout.CopyFrom(ps);
    
                                            ret = true;
                                        }
                                    }
                                }
                            }
    
                            tr.Commit();
                        }
                    }
                }
    
                catch (LispException ex)
                {
                    doc.Editor.WriteMessage("\n; error: LispException: " + ex.Message);
                }
    
                catch (System.Exception ex)
                {
                    doc.Editor.WriteMessage("\n; error: System.Exception: " + ex.Message);
                }
    
                return ret;
            }
        }
    
        // Special thanks to Gile, for his work on the following Exception helpers
        class LispException : System.Exception
        {
            public LispException(string msg) : base(msg) { }
        }
    
        class TooFewArgsException : LispException
        {
            public TooFewArgsException() : base("too few arguments") { }
        }
    
        class TooManyArgsException : LispException
        {
            public TooManyArgsException() : base("too many arguments") { }
        }
    
        class ArgumentTypeException : LispException
        {
            public ArgumentTypeException(string s, TypedValue tv)
                : base(string.Format(
                "invalid argument type: {0}: {1}",
                s, tv.TypeCode == (int)LispDataType.Nil ? "nil" : tv.Value))
            { }
        }
    }
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3620, Core i7-7700K 4.2GHz, 32GB RAM, Samsung 970 Pro M.2, 8GB NVIDIA Quadro P4000

  5. #5
    Programming Moderator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,385
    Login to Give a bone
    1

    Default Re: Extending the power of LISP through .NET

    Peter,

    I have a small library of LispFunctions I use, or have coded for others... At one point I started to compile them into a single Visual LISP Xpanded (VLX) project (to be punny)... When I have some time (over the Christmas break?), I'll try to post some.

    Cheers

    [Edit] - I've made this thread a sticky for the time being; it is unique from the other LISP threads. I'll clean it up if it gets too cluttered.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3620, Core i7-7700K 4.2GHz, 32GB RAM, Samsung 970 Pro M.2, 8GB NVIDIA Quadro P4000

  6. #6
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,028
    Login to Give a bone
    0

    Default Re: Extending the power of LISP through .NET

    I prefer to code the solution myself... Although I do look for examples sometimes...

    It's like having someone else solve your Soduko puzzle

    Here are two general functions to get and put .net properties from lisp using .net.

    Code:
    Imports System
    Imports System.Reflection
    Imports Autodesk.AutoCAD.ApplicationServices
    Imports Autodesk.AutoCAD.DatabaseServices
    Imports Autodesk.AutoCAD.Runtime
    
    Public Class LISPClass
    
        ' syntax (PropertyPut (entlast) "width" 10.0)
    
        <LispFunction("PropertyPut")> _
    Public Function PropertyPut(ByVal rbfLISPArguments As ResultBuffer)
            On Error GoTo OnError
            Dim arrLISPArguments As TypedValue() = rbfLISPArguments.AsArray
            If arrLISPArguments.Length = 3 Then
    
                Dim oidSelection As ObjectId = arrLISPArguments(0).Value
                Dim strPropertyName As String = arrLISPArguments(1).Value
                Dim objValue As Object = arrLISPArguments(2).Value
                Dim objDocument As Document = Application.DocumentManager.MdiActiveDocument
    
                Using objTransaction As Transaction = objDocument.Database.TransactionManager.StartTransaction()
                    Dim objSelection As Entity = CType(oidSelection.GetObject(OpenMode.ForWrite), Entity)
    
                    Dim lstProperties As IList(Of PropertyInfo) = New List(Of PropertyInfo)(objSelection.GetType().GetProperties())
                    Dim intIndex As Integer = PropertyInfoAvailable(lstProperties, strPropertyName)
    
                    If Not intIndex = Nothing Then
                        Dim infProperty As PropertyInfo = lstProperties.Item(intIndex)
                        If infProperty.CanRead = True And infProperty.CanWrite = True Then
                            infProperty.SetValue(objSelection, objValue, Nothing)
                            objTransaction.Commit()
                            objTransaction.Dispose()
                            Return New TypedValue(LispDataType.T_atom, -1)
                        End If
                    End If
                    objTransaction.Dispose()
                End Using
    
            End If
    OnError: Return New TypedValue(LispDataType.Nil, -1)
        End Function
    
    
        ' syntax (PropertyGet (entlast) "width")
    
        <LispFunction("PropertyGet")> _
    Public Function PropertyGet(ByVal rbfLISPArguments As ResultBuffer)
            On Error GoTo OnError
            Dim arrLISPArguments As TypedValue() = rbfLISPArguments.AsArray
            If arrLISPArguments.Length = 2 Then
                Dim oidSelection As ObjectId = arrLISPArguments(0).Value
                Dim strPropertyName As String = arrLISPArguments(1).Value
                Dim objDocument As Document = Application.DocumentManager.MdiActiveDocument
    
                Using objTransaction As Transaction = objDocument.Database.TransactionManager.StartTransaction()
                    Dim objSelection As Entity = CType(oidSelection.GetObject(OpenMode.ForRead), Entity)
                    Dim lstProperties As IList(Of PropertyInfo) = New List(Of PropertyInfo)(objSelection.GetType().GetProperties())
    
                    Dim intIndex As Integer = PropertyInfoAvailable(lstProperties, strPropertyName)
                    If Not intIndex = Nothing Then
                        Dim infProperty As PropertyInfo = lstProperties.Item(intIndex)
                        If infProperty.CanRead = True And infProperty.CanWrite = True Then
                            Dim objValue As Object = infProperty.GetValue(objSelection, Nothing, Nothing, Nothing, Nothing)
                            objTransaction.Commit()
                            objTransaction.Dispose()
                            Return objValue
                        End If
                    End If
                    objTransaction.Dispose()
                End Using
    
            End If
    OnError: Return New TypedValue(LispDataType.Nil, -1)
        End Function
    
    
        Public Shared Function PropertyInfoAvailable(ByVal lstProperties As IList(Of PropertyInfo), ByVal strProperty As String)
            On Error GoTo OnError
            For Each infProperty As PropertyInfo In lstProperties
                If infProperty.Name.ToString.ToUpper = strProperty.ToUpper Then
                    Return lstProperties.IndexOf(infProperty)
                End If
            Next
    OnError: Return Nothing
        End Function
    It is a place to start.
    Last edited by peter; 2013-12-18 at 06:43 AM.
    AutomateCAD

  7. #7
    Programming Moderator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,385
    Login to Give a bone
    0

    Default Re: Extending the power of LISP through .NET

    Unless being done as purely a learning example (which would make sense), how is this different from Vital(?) LISP syntax?

    Code:
    (vlax-put <Object> <Property> <Value>)
    
    (vlax-get <Object> <Property>)
    Cheers
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3620, Core i7-7700K 4.2GHz, 32GB RAM, Samsung 970 Pro M.2, 8GB NVIDIA Quadro P4000

  8. #8
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,028
    Login to Give a bone
    0

    Default Re: Extending the power of LISP through .NET

    Well it is similar except it does not change "com" properties. (Like Color is a com property)
    It changes .net properties. (Although Color is a .net property, Colorindex is the corresponding property)

    Also it is intended to make multiple function calls in the same transaction.

    vital lisp uses the com and initiates one call per transaction.

    When this function could be used multiple times inside one transaction.

    When you make multiple calls it can drastically affect performance.

    P=
    AutomateCAD

  9. #9
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,028
    Login to Give a bone
    0

    Default Re: Extending the power of LISP through .NET

    I was thinking a better name might be

    LISP Extensions (VB.NET, C# and ARX)

    Peter
    AutomateCAD

  10. #10
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,028
    Login to Give a bone
    0

    Default Re: Extending the power of LISP through .NET

    For those who want to participate and play with these code examples

    You can download Visual Studio Express 2013 for free!

    http://www.microsoft.com/en-us/downl....aspx?id=40787

    I will try to find some template files for you to play with.
    AutomateCAD

Similar Threads

  1. MA223-2: AutoCAD® Electrical Power Tools for Power Users
    By Autodesk University in forum Manufacturing
    Replies: 0
    Last Post: 2015-08-07, 05:32 PM
  2. MA118-4: AutoCAD Electrical Power Tools for Power Users
    By Autodesk University in forum Manufacturing
    Replies: 0
    Last Post: 2014-12-01, 03:16 AM
  3. MA301-2: AutoCAD Electrical© Power Tools for Power Users
    By Autodesk University in forum Manufacturing
    Replies: 0
    Last Post: 2013-05-06, 01:20 AM
  4. CP34-3: AUGI Power LISP
    By Autodesk University in forum Customization and Programming
    Replies: 0
    Last Post: 2013-04-17, 04:26 AM
  5. CP31-3: The AUGI® LISP Forums Greatest Hits for "Power LISPers"
    By Autodesk University in forum Customization and Programming
    Replies: 0
    Last Post: 2013-04-10, 02:28 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •