Creating an editable AutoCAD solid using .NET

This question came up recently on the AutoCAD .NET Discussion Group: how to create a Solid3d object which provides the user with the full set of grips to manipulate it (which I've abbreviated to "editable" in the title of this post :-). This comes down to a enhancements that were made in AutoCAD 2007 to allow better manipulation of solids via the user-interface via extended grips and a push-pull mechanism. These capabilities need to be enabled solids as you create them - and unfortunately cannot be retro-fitted to existing solid objects - by telling the solid that you would like it to record its history. And it's really that simple, you simply have to set the RecordHistory flag to true.

The below C# code demonstrates how this works, by exposing a command that prompts the user whether to set this flag to true, or not:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Geometry;

 

namespace SolidCreation

{

  public class Commands

  {

    [CommandMethod("CWH")]

    public void CylinderWithHistory()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Database db = doc.Database;

      Editor ed = doc.Editor;

 

      // Ask the user whether to create history

      // and where to place the cylinder

 

      bool createHistory = false;

 

      PromptKeywordOptions pko =

        new PromptKeywordOptions(

          "\nRecord history for this cylinder?"

        );

      pko.AllowNone = true;

      pko.Keywords.Add("Yes");

      pko.Keywords.Add("No");

      pko.Keywords.Default = "Yes";

 

      PromptResult pkr =

        ed.GetKeywords(pko);

 

      if (pkr.Status != PromptStatus.OK)

        return;

 

 &n
bsp;   
if (pkr.StringResult == "Yes")

        createHistory = true;

 

      PromptPointResult ppr =

        ed.GetPoint("\nSelect point: ");

 

      if (ppr.Status != PromptStatus.OK)

        return;

 

      Point3d pt = ppr.Value;

 

      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        // Create the solid and set the history flag

 

        Solid3d sol = new Solid3d();

        sol.RecordHistory = createHistory;

 

        // Hardcode the dimensions of the cylinder

        // for the purpose of this example

 

        sol.CreateFrustum(10, 3, 3, 3);

 

        // Add the Solid3d to the modelspace

 

        BlockTable bt =

          (BlockTable)tr.GetObject(

            db.BlockTableId,

            OpenMode.ForRead

          );

 

        BlockTableRecord ms =

          (BlockTableRecord)tr.GetObject(

            bt[BlockTableRecord.ModelSpace],

            OpenMode.ForWrite

          );

 

        ms.AppendEntity(sol);

        tr.AddNewlyCreatedDBObject(sol, true);

 

        // And transform it to the selected point

 

        sol.TransformBy(

          Matrix3d.Displacement(pt - Point3d.Origin)

        );

 

        tr.Commit();

      }

    }

  }

}

Let's see the results of the CWH command - in this case we run it twice, selecting "No" to the question about history creation for the cylinder on the left and "Yes" to the same question for the cylinder on the right:

Cyrilnders with (right) and without (left) history recording enabled

As pointed out in the thread on the discussion group, there are some limitations to the API around the history recording for solids: you cannot, for instance, programmatically manipulate the solid's history: it's only possible to create new solids that will then allow users to make use of editing operations that effect the history.

On a somewhat related note, back in this post I mentioned a hole in the .NET API around creating a swept solid. I've been informed by a friend in our Engineering team that we've now plugged it - and some other related holes - in the .NET API for AutoCAD 2010. You will now have the following methods available from the Solid3d class: CreateExtrudedSolid, CreateLoftedSolid, CreateRevolvedSolid and CreateSweptSolid (the equivalent .NET methods for Surfaces existed already, as well as the base C++ methods in ObjectARX). Thanks for the heads-up, Joel! ๐Ÿ™‚

2 responses to “Creating an editable AutoCAD solid using .NET”

  1. Thanks for the example, and yes I was mistaken about history for API-generated solids.

    That was an assumption on my part, partly because I expected SetDatabaseDefaults() to take care of that (using the current value of the SOLIDHIST system variable in the owning database).

    Now if you wouldn't mind, please demonstrate how to change the height or radius of an existing cylinder primitive with history ๐Ÿ™‚

  2. I did say there were limitations to the API... ๐Ÿ™‚

    I'm checking with Engineering to see whether anything related to this has changed with the work done for the freeform modeling feature.

    Kean

  3. Nikolay Poleshchuk Avatar
    Nikolay Poleshchuk

    Kean, you have touched a very noticeable topic. If I set RecordHistoty On and combine (unite or subtract) two solids then I get a new solid without editing grips though PROPERTIES palette still shows RecordHistory On. Are there any ideas to overcome this? With or without API?

  4. Nikolay,

    I assume this means that history can be recorded for such a composite solid, but AutoCAD isn't able to determine how best to show grips for the new solid (or allow grip editing).

    I don't have any suggestions on how to change this behaviour, I'm afraid.

    Kean

  5. Hi Kean. Would you be able to show how to extract the Height of the cylinder?

    Thanks

  6. Hi Hugh,

    Sorry - I don't know of a way to do that with the currently exposed APIs.

    Regards,

    Kean

  7. Hello every one for the same problem that i posted on autoCAD Discussion Group Cylinder (C# code) Vs Cylinder (AutoCAD).

    Problem little bit different but related to this post. Actually RecordHistory is workin fine for Built-in entities like Culinder, Box, Torus etc.
    But now problem is like when u create solid object using extrude/revolve API of C# we can not modify by setting RecordHistory to true.

    I am posting code snippet on which i was working..

    thanks

  8. Hi Kean, I am new to objectarx in .NET and am using Visual C++ .NET instead of c#. Is it possible to do the same above code in C++ rather than C#. I am having difficulty creating the Document and editor objects.

    thanks

  9. Hi Navin,

    It sounds as though you need an introduction to ObjectARX training. I suggest working through the material available on the AutoCAD Developer Center.

    Regards,

    Kean

  10. uploads.disquscdn.c... hi my problem is i cannot see the grip behind in conceptual mode

    1. Please post your support questions to the relevant online discussion group.

      Kean

  11. Hi Kean! When I create a Solid3d using the CreateLoftedSolid(...) method I got a significant time delay. Array of 300 polylines with elevation offset and rotation takes 10 second to Solid3d creation. Help me please to make this process faster.

    1. Hi Sergey,

      I'm sorry - I'm no longer working with AutoCAD. Please submit your technical support requests via the AutoCAD .NET forum.

      Thanks,

      Kean

Leave a Reply to Tony Tanzillo Cancel reply

Your email address will not be published. Required fields are marked *