Die Advance Steel-API kann mit der AutoCAD-API verwendet werden.
In dieser Übungslektion werden verschiedene Beispiele aufgeführt. Weitere Informationen zur AutoCAD-API finden Sie in der Online-Hilfe für die AutoCAD Managed .NET API.
Code-Region: UsingDocumentAccessToStartAndCommitTransaction
public void Create()
{
using (DocumentAccess da = new DocumentAccess(null, false))
{
}
}
Code-Region: UsingDocumentAccessToStartAndCommitTransaction
public void Create()
{
using (DocumentAccess da = new DocumentAccess(null, false))
{
da.Commit();
}
}
Erstellen Sie eine neue Klasse namens WorkingWithAutoCADAPI und fügen Sie den folgenden Code hinzu:
|
Code-Region: Befehlsklasse WorkingWithAutoCADAPI |
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
{
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();
}
}
}
}
|
Beachten Sie, dass für diese Übungslektion vier using-Anweisungen für AutoCAD-API-Namensbereiche erforderlich sind. Die AutoCAD-API und Advance Steel haben einige gemeinsame Klassennamen, beispielsweise ObjectId. Dadurch wird eine Unterscheidung im Code erforderlich. Anstatt den Namensbereich vor dem Klassennamen einzufügen, können Sie eine Richtlinie zur Verwendung eines Alias am Anfang der Datei verwenden, um einen kürzeren Namen für die Klassen zu erstellen. In dieser Übungslektion verwenden wir drei Richtlinien zur Verwendung eines Alias, wie im umgeschriebenen Code unten dargestellt.
|
Code-Region: Klassennamen eindeutig machen |
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();
}
}
}
}
|
Die anderen Richtlinien zum Verwenden eines Alias werden später im Lernprogramm verwendet.
In der Übungslektion Walkthrough: Erstellen Sie Träger und Blechbearbeitungen wurde die Verwendung der UserInteraction-Klasse erläutert, damit der Benutzer ein Objekt auswählen kann, das bearbeitet werden soll. In dieser Übungslektion wird beschrieben, wie das Auswahlfenster in AutoCAD verwendet wird, um Objekte basierend auf dem Standort automatisch auszuwählen.
Fügen Sie die Methode unterhalb der WorkingWithAutoCADAPI-Klasse ein. In dieser Methode wird ein kreuzendes Fenster verwendet, um Objekte innerhalb eines rechteckigen Bereichs zu finden. Dann wird überprüft, ob es sich dabei um gerade Träger handelt und es wird der erste gerade Träger angezeigt, der gefunden wird.
|
Code-Region: Auswählen eines Trägers |
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;
}
}
}
return beam;
}
|
Beachten Sie im Beispielcode oben, dass Autodesk.AutoCAD.DatabaseServices.ObjectId nach dem Abrufen in ein Autodesk.AdvanceSteel.CADLink.Database.ObjectId konvertiert wird, bevor überprüft wird, ob es sich um ein StraightBeam handelt. Das liegt an der Dualität von Advance Steel-Objekten. Advance Steel-Objekte bestehen allgemein aus zwei AutoCAD-Objekten: dem „internen“ Objekt und dem Darstellungsobjekt. Normalerweise kann ein Advance Steel-Benutzer nur auf das Darstellungsobjekt zugreifen. Das heißt, wenn ein Benutzer einen Träger in Advance Steel auswählt, wählt er die Darstellung des Trägers aus.
Um erfolgreich mit Advance Steel- und AutoCAD-API zu arbeiten, kommt es darauf an zu verstehen, welches Objekt erforderlich ist. Sie müssen bei AutoCAD-Aktionen für ein Objekt die „Darstellungs“-ID, für Aktionen der AdvanceSteel-API mit demselben Objekt hingegen die interne ID verwenden. Wenn Objekt-IDs durch Aufrufen von Methoden abgerufen werden, geben Advance Steel-Methoden immer IDs der internen Objekte zurück, während AutoCAD API-Aufrufe immer die IDs der Darstellungsobjekte zurückgeben. Die Advance Steel-API bietet Methoden zum Wechseln von einem ID-Typ zum anderen.
Als Nächstes wird beschrieben, wie die AutoCAD-API zum Auflösen eines Advance Steel-Objekts verwendet wird. Dies funktioniert ähnlich wie die Auswahl eines Advance Steel-Trägers und der Aufruf des Befehls „Auflösen“. So werden aufgelöste Linien zurückgegeben, aber dies wirkt sich nicht auf das Modell aus. Die resultierenden einfacheren Objekte können exportiert oder für Berechnungen oder andere Zwecke verwendet werden.
|
Code-Region: Auflösen eines Trägers |
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
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;
}
|
Beachten Sie, dass die oben beschriebene Methode zuerst die Advance Steel-ID in eine AutoCAD-ID umwandelt, da die AutoCAD-Methode zum Auflösen auf das Objekt angewendet werden soll.
Kehren Sie jetzt zur ursprünglichen Create()-Methode für WorkingWithAutoCADAPI zurück und rufen Sie beide Methoden auf – eine zum Abrufen eines geraden Trägers in Advance Steel und eine, um diesen aufzulösen.
|
Code-Region: Zusammensetzen |
public void Create()
{
using (DocumentAccess da = new DocumentAccess(null, true))
{
StraightBeam beam = GetStraightBeam();
if (beam != null)
{
ExplodeBeam(beam);
}
}
}
|
Sonderteile in Advance Steel sind generische 3D-Objekte, die zu einem Advance Steel-Modell hinzugefügt werden können, um Standardbauelemente zu ergänzen. Sonderteile können genau wie Blockreferenzen aus externen dwg-Dateien erstellt werden, die gültige AutoCAD-Objekte einschließlich Advance Steel-Objekte enthalten. Es wird zuerst ein Volumenkörper erstellt und dann dem Sonderteil zugewiesen.
In diesem Beispiel wird der AutoCAD-3D-Volumenkörper über Programmiercode erstellt; Sie können ihn aber auch manuell erstellen. Fügen Sie die folgende Methode der Klassendatei hinzu, um einen Keil zu erstellen.
|
Code-Region: Erstellen eines AutoCAD 3D-Volumenkörpers |
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;
}
|
Beachten Sie, dass die Methode eine ObjektId für BlockTableRecord zurückgibt. Diese wird zuerst in eine Advance Steel-ObjectId umgewandelt und dann für das Sonderteil verwendet. Fügen Sie die folgende Methode hinzu, um ein Sonderteil zu erstellen.
|
Code-Region: Erstellen eines Sonderteils |
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);
}
|
|
Code-Region: Zusammensetzen |
public void Create()
{
using (DocumentAccess da = new DocumentAccess(null, false))
{
StraightBeam beam = GetStraightBeam();
if (beam != null)
{
ExplodeBeam(beam);
}
CreateSpecialPart();
da.Commit();
}
}
|
Manchmal ist es hilfreich, auf einen Befehl in AutoCAD zu reagieren. Ein Advance Steel-Plugin kann ein CommandEnded-Ereignis abonnieren, sodass es benachrichtigt wird, wenn ein Befehl ausgeführt wurde und weitere Schritte erforderlich sind. In diesem Beispiel erstellen wir eine Methode, in der bei neuen Trägern, die zu einem Advance Steel-Modell hinzugefügt wurden, geprüft wird, ob alle Träger (einschließlich des neuen Trägers) die Mindestlänge für Träger aufweisen. (Ist dies nicht der Fall, wird eine Warnung ausgegeben).
|
Code-Region: CommandEnded-Reaktor |
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))
{
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);
}
}
}
}
|
Beachten Sie bei dieser Methode, dass GlobalCommandName geprüft wird, um sicherzustellen, dass es sich um ASTM4CRBEAMBYCLASS handelt, den Befehl, der angibt, dass ein neuer Advance Steel-Träger erstellt wurde. Der Befehlsname kann von einem anderen Plugin, zum Beispiel CREATEFEATURES, oder einem anderen integrierten Befehl aus Advance Steel oder AutoCAD erstellt worden sein. Wenn Sie den Namen des Befehls nicht kennen, für den Sie den Reaktor erstellen möchten, dann erstellen Sie einfach eine Befehlsreaktormethode wie oben und setzen Sie einen Haltepunkt in der Methode, um den Wert von e.GlobalCommandName zu prüfen, wenn der Befehl am Ende des gewünschten Befehls ausgelöst wird.
Da diese Methode aufgerufen wird, wenn ein Befehl beendet ist und sie sich nicht innerhalb des Umfangs der in der Create()-Methode gestarteten Transaktion befindet, muss CurrentDocument_CommandEnded eine eigene Transaktion sowie Aufrufe zum Sperren und Freigeben des aktuellen Dokuments aufweisen.
Damit Ihr Befehlsreaktor abgerufen wird, muss er innerhalb des aktuellen Dokuments registriert sein. Fügen Sie den folgenden Code zur WorkingWithAutoCADAPI-Klasse hinzu, um die Methode CurrentDocument_CommandEnded zu registrieren.
|
Code-Region: Registrieren eines Befehlsreaktors |
private void AddCommandEndedReactor()
{
DocumentCollection docs = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager;
ACDocument currDoc = docs.CurrentDocument;
currDoc.CommandEnded += CurrentDocument_CommandEnded;
}
|
|
Code-Region: Zusammensetzen |
public void Create()
{
using (DocumentAccess da = new DocumentAccess(null, false))
{
StraightBeam beam = GetStraightBeam();
if (beam != null)
{
ExplodeBeam(beam);
}
CreateSpecialPart();
AddCommandEndedReactor();
}
}
|
Nach dem Abrufen der WorkingWithAutoCADAPI-Methode in Advance Steel wird die Methode CurrentDocument_CommandEnded aufgerufen, wann immer ein Befehl in AutoCAD oder Advance Steel endet.