Kean Walmsley

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Twitter Updates

    follow me on Twitter



    « More fun with F# and AutoCAD: string extraction and manipulation | Main | Metaprogramming with AutoCAD - Part 1 »

    November 16, 2007

    Getting the total volume of 3D solids in an AutoCAD model using F#

    In one of my sessions at this year's AU, "There's More to .DWG Than AutoCAD®", I'll be showing some VB.NET code that goes through and collects information about solids, presenting it in a dialog along with the sum of the various volumes. You can get the code and the results from Part 1 of the session's handout.

    Just for fun, I thought I'd write some F# code to add the volumes of the 3D solid objects in the modelspace of the current drawing. I adopt a similar approach to the VB code - not caring about intersecting volumes, for instance - but obviously the code looks quite different.

    I won't step through the code line-by-line, as the last post introduced the fundamental concepts that also apply here.

    // Use lightweight F# syntax


    #light


    (* Declare a specific namespace

      and module name

    *)


    module MyNamespace.MyApplication


    // Import managed assemblies


    #I @"C:\Program Files\Autodesk\AutoCAD 2008"


    #r "acdbmgd.dll"

    #r "acmgd.dll"


    open System

    open System.Collections.Generic

    open Autodesk.AutoCAD.Runtime

    open Autodesk.AutoCAD.ApplicationServices

    open Autodesk.AutoCAD.DatabaseServices


    // Now we declare our command


    [<CommandMethod("volume")>]

    let listWords () =


      // Let's get the usual helpful AutoCAD objects


      let doc =

        Application.DocumentManager.MdiActiveDocument;

      let ed = doc.Editor;

      let db = doc.Database;


      // "use" has the same effect as "using" in C#


      use tr =

        db.TransactionManager.StartTransaction();


      // Get appropriately-typed BlockTable and BTRs


      let bt =

        tr.GetObject

          (db.BlockTableId,OpenMode.ForRead)

        :?> BlockTable

      let ms =

        tr.GetObject

          (bt.[BlockTableRecord.ModelSpace],

          OpenMode.ForRead)

        :?> BlockTableRecord


      // A function that accepts an ObjectId and returns

      // the volume of a 3D solid, if it happens to be one


      // Note the valid use of tr, as it is in scope


      let getVolume (x : ObjectId) =

        let obj = tr.GetObject(x,OpenMode.ForRead);

        match obj with

        | :? Solid3d -> (obj :?> Solid3d).MassProperties.Volume

        | _ -> 0.0


      // Use fold_left in a partial application to find

      // the sum of the contents of a list


      let sum =

        List.fold_left (fun x y -> x+y) 0.0


      // And here's where we plug everything together...


      let vol =

        Seq.untyped_to_list ms |> List.map getVolume |> sum


      ed.WriteMessage("\nTotal volume: " + vol.ToString());


      // As usual, committing is cheaper than aborting


      tr.Commit()

    The only tricky thing is the use of fold_left to apply an anonymous (or lambda, for the LISPers out there) addition function across the contents of the list containing the individual volumes of the objects in the modelspace.

    Here's what we see when we run the "volume" command:

    Command: volume

    Total volume: 15275.8711619534

    This is the same result as displayed by the previous example (although presented with a few more decimal places).

    TrackBack

    TrackBack URL for this entry:
    http://www.typepad.com/services/trackback/6a00d83452464869e200e54f9861108834

    Listed below are links to weblogs that reference Getting the total volume of 3D solids in an AutoCAD model using F#:

    » Getting the total volume of 3D solids in an Autocad model using F# from CadKicks.com
    You've been kicked (a good thing) - Trackback from CadKicks.com [Read More]

    Comments

    You've been kicked (a good thing) - Trackback from CadKicks.com
    http://cadkicks.com/adkautocad/Getting_the_total_volume_of_3D_solids_in_an_Autocad_model_using_F

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search