Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk

Walkthrough: Working with AutoCAD and AS API

The Advance Steel API works with the AutoCAD API.

Since Advance Steel runs on top of AutoCAD, the AutoCAD API can be used in conjunction with the Advance
Steel API in an Advance Steel plugin. Common uses of the AutoCAD API from an Advance Steel plugin
include:

Using AutoCAD selection with Advance Steel objects


Using AutoCAD command reactors to work with Advance Steel objects
Exploding an Advance Steel object
Creating an Advance Steel special part using an AutoCAD solid

This tutorial will look at several examples. For more information on the AutoCAD API, see the online help
for the AutoCAD Managed .NET API (https://help.autodesk.com/view/OARX/2019/ENU/?guid=GUID-C3F3C736-40CF-
44A0-9210-55F6A939B6F2) .

Working with AutoCAD API


Create a new Advance Steel plugin as demonstrated in earlier tutorials. In addition to the Advance Steel
assemblies that need to be referenced, several AutoCAD assemblies must be referenced from the project as
well:

AcCoreMgd
AcDbMgd
AcMgd

Create a new class called WorkingWithAutoCADAPI and add the following code:

Code Region: WorkingWithAutoCADAPI command class

using Autodesk.AdvanceSteel.CADAccess;

using Autodesk.AdvanceSteel.DocumentManagement;

using Autodesk.AdvanceSteel.Modelling;

using Autodesk.AdvanceSteel.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using System.Windows.Forms;

namespace WorkingWithAutoCADandASAPI

https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 1/9
11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk
{

class WorkingWithAutoCADAPI

[CommandMethodAttribute("TEST_GROUP", "WorkingWithAutoCADAPI",
"WorkingWithAutoCADAPI",

CommandFlags.Modal |
CommandFlags.UsePickSet | CommandFlags.Redraw)]

public void Create()

using (DocumentAccess da = new DocumentAccess(null, false))

da.Commit();

Note that this tutorial will require 4 using statements for AutoCAD API namespaces. The AutoCAD API has
several class names in common with Advance Steel, such as ObjectId. This requires disambiguation in the
code. Rather than including the namespace in front of the class name, we can use a 'using alias directive'
at the top of the file to create a shorter name for one of the classes. For this tutorial, we will use three
using alias directives as shown in the rewritten code below.

Code Region: Disambiguating class names

using Autodesk.AdvanceSteel.CADAccess;

using Autodesk.AdvanceSteel.DocumentManagement;

using Autodesk.AdvanceSteel.Modelling;

using Autodesk.AdvanceSteel.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using System.Windows.Forms;

using ACTransaction = Autodesk.AutoCAD.DatabaseServices.Transaction;

using ASObjectId = Autodesk.AdvanceSteel.CADLink.Database.ObjectId;

using ACDocument = Autodesk.AutoCAD.ApplicationServices.Document;

using Autodesk.AutoCAD.Geometry;

namespace WorkingWithAutoCADandASAPI

class WorkingWithAutoCADAPI

[CommandMethodAttribute("TEST_GROUP", "WorkingWithAutoCADAPI",
"WorkingWithAutoCADAPI",

CommandFlags.Modal |
CommandFlags.UsePickSet | CommandFlags.Redraw)]

public void Create()

using (DocumentAccess da = new DocumentAccess(null, false))

da.Commit();

https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 2/9
11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk

The using alias directives will be used later in the tutorial.

Using AutoCAD area selection


In the Walkthrough: Create beam and plate features tutorial, we looked a using the UserInteraction class
to have the user select an object on which to act. In this tutorial, we will look at using an AutoCAD
selection window to automatically select some objects based on location.

Add the method below to the WorkingWithAutoCADAPI class. This method uses a crossing window to find
objects within a rectangular area. It then checks if any of them are straight beams and returns he first
straight beam it finds.

Code Region: Selecting a beam

private StraightBeam GetStraightBeam()

StraightBeam beam = null;

//Try to get a beam repr using AutoCad selection window

PromptSelectionResult acSSPrompt;

Editor ed =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
acSSPrompt = ed.SelectCrossingWindow(new Point3d(0, 0, 0), new Point3d(1000, 0, 0));

if (acSSPrompt.Status == PromptStatus.OK)

SelectionSet acSSet = acSSPrompt.Value;

ObjectId[] ids = acSSet.GetObjectIds();

//Iterate through the selected objects, and check if we have a straight beam

foreach (ObjectId id in ids)

//Get the beam filer object

ASObjectId idDbObject =

DatabaseManager.GetFilerObjectId(new ASObjectId(id.OldIdPtr), false);

FilerObject obj = DatabaseManager.Open(idDbObject);

//If we have a straight beam

if (obj.Type() == FilerObject.eObjectType.kStraightBeam)

beam = obj as StraightBeam;

break;

https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 3/9
11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk

return beam;

Duality of Advance Steel entities


In the sample code above, note that after getting the Autodesk.AutoCAD.DatabaseServices.ObjectId, it is
converted to a Autodesk.AdvanceSteel.CADLink.Database.ObjectId before checking to see if it is a
StraightBeam. This is due to a duality of Advance Steel entities. Advance Steel objects are, in general,
composed of two AutoCAD entities: the "internal" entity and the "representation" entity. Normally an
Advance Steel user can only interface with the "representation" entity. That is, when a user selects a beam
inside Advance Seel they select the representation of the beam.

In order to successfully work with Advance Steel and AutoCAD API it is necessary to understand which
entity is required. Whenever you want AutoCAD to act on an object you need to use the "representation" id,
while in the cases when you want the AdvanceSteel API to act on the same object the "internal" id must be
used. Whenever object ids are obtained by calling methods, Advance Steel methods always return ids of
the "internal" objects, while AutoCAD API calls always return ids of the "representation" objects. The
Advance Steel API has methods to go from one type of id to the other.

Exploding an Advance Steel entity


Next, let's look at using the AutoCAD API to explode an Advance Steel entity. This works similarly to
selecting an Advance Steel beam and calling the "explode" command on it. It will return the exploded lines,
but does not affect the model. The resulting simpler entities can be exported or used for calculations or
other uses.

Code Region: Exploding a beam

private int ExplodeBeam(StraightBeam beam)

int nExplodedEnts = 0;

// get the "representation" id - the id that AutoCAD understands as being the


object drawn on the screen

ASObjectId reprId = DatabaseManager.GetReprId(beam);

// convert this id from "AdvanceSteel" id to "Acad" id

ObjectId acadIdBeam = new ObjectId(reprId.AsOldId());

// start an AutoCAD transaction

DocumentCollection docs =
Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager;

ACDocument currDoc = docs.CurrentDocument;

Autodesk.AutoCAD.DatabaseServices.Transaction trans =
currDoc.TransactionManager.StartTransaction();

// use the transaction to gain access to the beam representation as an AutoCAD


entity

https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 4/9
11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk
DBObject objBeam = trans.GetObject(acadIdBeam,
Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite);

if (objBeam is Autodesk.AutoCAD.DatabaseServices.Entity)

Entity ent = (Entity)objBeam;

// ask autoCAD to "explode" this beam - equivalent of selecting an advance


steel beam from the screen and calling "explode" command

DBObjectCollection explodedEnts = new DBObjectCollection();

ent.Explode(explodedEnts);

nExplodedEnts = explodedEnts.Count;

trans.Commit();

return nExplodedEnts;

Note that the method above first converts the Advance Steel id to an AutoCAD id since we want the
AutoCAD Explode method to act on the entity.

Now return to the original Create() method for the WorkingWithAutoCADAPI and call our two methods -
one to get an Advance Steel straight beam and one to explode it.

Code Region: Putting it together

public void Create()

using (DocumentAccess da = new DocumentAccess(null, true))

StraightBeam beam = GetStraightBeam();

if (beam != null)

ExplodeBeam(beam);

Creating an Advance Steel special part from an AutoCAD solid


Advance Steel special parts are generic 3d objects that can be added to an Advance Steel model to
complement standard construction elements. Special parts can be created just like block references from
external dwg files containing any valid AutoCAD objects including other Advance Steel objects. A solid is
created first and then assigned to the special part.

In this example, we will create the AutoCAD 3d solid with code, but it could also be created manually. Add
the following method to the class file to create a wedge.
https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 5/9
11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk

Code Region: Creating an AutoCAD 3d solid

private ObjectId CreateAutoCADWedge()

ObjectId ret;

// Get the current document and database, and start an AutoCAD transaction

ACDocument acDoc =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

using (ACTransaction acTrans = acCurDb.TransactionManager.StartTransaction())

// Open the Block table record for read

BlockTable acBlkTbl;

acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForWrite) as


BlockTable;

// Open the Block table record Model space for write

BlockTableRecord acBlkTblRec = new BlockTableRecord();

acBlkTblRec.Name = "wedge";

// Create a 3D solid wedge

Solid3d acSol3D = new Solid3d();

acSol3D.SetDatabaseDefaults();

acSol3D.CreateWedge(10, 15, 20);

// Position the center of the 3D solid at (5,5,0)

acSol3D.TransformBy(Matrix3d.Displacement(new Point3d(5, 5, 0) -
Point3d.Origin));

// Add the new object to the block table record and the transaction

acBlkTblRec.AppendEntity(acSol3D);

acBlkTbl.Add(acBlkTblRec);

acTrans.AddNewlyCreatedDBObject(acBlkTblRec, true);

// Save the new objects to the database

acTrans.Commit();

ret = acBlkTblRec.Id;

return ret;

Note that the method returns an ObjectId for the BlockTableRecord. We will use this for our special part,
after converting it to an Advance Steel ObjectId. Add the following method to create a new special part.

Code Region: Creating a special part

https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 6/9
11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk

private void CreateSpecialPart()

SpecialPart specialPart = new SpecialPart(new


Autodesk.AdvanceSteel.Geometry.Matrix3d());

specialPart.WriteToDb();

ObjectId newBlock = CreateAutoCADWedge();

specialPart.SetBlock(new ASObjectId(newBlock.OldIdPtr), 1.0);

Now add a call to this method to the Create() method.

Code Region: Putting it together

public void Create()

using (DocumentAccess da = new DocumentAccess(null, false))

StraightBeam beam = GetStraightBeam();

if (beam != null)

ExplodeBeam(beam);

CreateSpecialPart();

da.Commit();

Command Reactors
Sometimes it is useful to respond to a command in AutoCAD. An Advance Steel plugin can subscribe to the
CommandEnded event to be notified with a command has completed so some action can be taken. In this
example, we will create a method that looks for when a new beam has been added to the Advance Steel
model and checks to make sure all beams (which would include the new one) meet some minimum beam
length (and issue a warning if one does not).

Code Region: CommandEnded reactor

void CurrentDocument_CommandEnded(object sender,


Autodesk.AutoCAD.ApplicationServices.CommandEventArgs e)

// If a beam has just been created

if (e.GlobalCommandName == "ASTM4CRBEAMBYCLASS")

using (DocumentAccess da = new DocumentAccess(null, true))

https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 7/9
11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk

try

ASObjectId[] ids;

ClassTypeFilter filter = new ClassTypeFilter();

filter.AppendAcceptedClass(FilerObject.eObjectType.kStraightBeam);

//Get all the beams from the database

DatabaseManager.GetModelObjectIds(out ids, filter);

foreach (ASObjectId id in ids)

FilerObject obj = DatabaseManager.Open(id);

if (obj != null)

StraightBeam sb = obj as StraightBeam;

// check that beam meets minimum length for project

double length = sb.GetLength();

if (length < 305)

MessageBox.Show("Minimum beam length is 305 mm. Please


adjust beam.");

catch(System.Exception ex)

MessageBox.Show(ex.Message);

Note that in this method, it checks the GlobalCommandName to see if it is ASTM4CRBEAMBYCLASS, the
command indicating that a new Advance Steel beam has been created. The command name may be one
created by another plugin, such as CREATEFEATURES, or any built in command from Advance Steel or
AutoCAD. If you do not know the name of the command you want to create a reactor for, simply create a
command reactor method similar to above and place a breakpoint in the method to check the value of
e.GlobalCommandName when the command is triggered at the end of the desired command.

Since this method will be called when a command has ended and is not going to be within the scope of the
transaction started in the Create() method, it is necessary for CurrentDocument_CommandEnded to have
it's own transaction, as well as calls to lock and unlock the current document.

To have your command reactor called, it must be registered with the current document. Add the following
code to the WorkingWithAutoCADAPI class to register the CurrentDocument_CommandEnded method.

Code Region: Registering a command reactor

https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 8/9
11/10/21, 4:30 PM Help | Walkthrough: Working with AutoCAD and AS API | Autodesk

private void AddCommandEndedReactor()

DocumentCollection docs =
Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager;

ACDocument currDoc = docs.CurrentDocument;

currDoc.CommandEnded += CurrentDocument_CommandEnded;

Now add a call to this method to the Create() method.

Code Region: Putting it together

public void Create()

using (DocumentAccess da = new DocumentAccess(null, false))

StraightBeam beam = GetStraightBeam();

if (beam != null)

ExplodeBeam(beam);

CreateSpecialPart();

AddCommandEndedReactor();

After invoking the WorkingWithAutoCADAPI method in Avance Steel, the


CurrentDocument_CommandEnded method will be called whenever a command ends in AutoCAD or
Advance Steel.

Parent topic: Walkthroughs

Except where otherwise noted, this work is licensed under a Creative Commons Attribution-
NonCommercial-ShareAlike 3.0 Unported License. Please see the Autodesk Creative Commons FAQ
for more information.
© 2021 Autodesk Inc. All rights reserved

https://help.autodesk.com/view/ADSTPR/2021/ENU/?guid=GUID-0AFEFD2B-EED4-4F6A-8F97-BA0814E99643 9/9

You might also like