Author Topic: AU 2005 code - Part 7 "Digging into the Database"  (Read 5084 times)

0 Members and 1 Guest are viewing this topic.

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
AU 2005 code - Part 7 "Digging into the Database"
« on: December 28, 2005, 02:59:28 PM »
Get out yer' shovels and start diggin'

This is the basics of the Database.  Nothing new to most of you.

Code: [Select]

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace AU2005.AcadApi
{

//Pages 13 to 17
public class DatabaseExamples
{

//Page14
//Digging into the database, symbol tables, and ObjectId's
[CommandMethod("ShowAllLayers")]
public void ShowAllLayers()
{
//Get the current editor object
Editor currentEditor = AcadApp.DocumentManager.MdiActiveDocument.Editor;

//Get the current database object
Database activeDatabase = currentEditor.Document.Database;

//Start a transaction
using(Transaction trans = activeDatabase.TransactionManager.StartTransaction())
{
//Open the layer table
ObjectId layertableId = activeDatabase.LayerTableId;
LayerTable layers = (LayerTable)trans.GetObject(layertableId,OpenMode.ForRead);

//Iterate the layerId's in the layer table
foreach (ObjectId layerId in layers)
{
//Open the layer for reading
LayerTableRecord layer = (LayerTableRecord)trans.GetObject(layerId, OpenMode.ForRead);

//Print the layer name to the command line
currentEditor.WriteMessage("\n" + layer.Name);
}
}
}


//Page 15
//Accessing databases in the editor and from a file
[CommandMethod("InsertBlock")]
public void InsertBlock()
{
string sourceFileName = @"C:\OftenUsedBlock.dwg";
string newBlockName = "OftenUsedBlock";

try
{
using(Database sourceDatabase = GetDatabaseFromFile(sourceFileName))
{
//Insert the entities from modelspace of the sourceDatabase into
//a new block table record of the working database
HostApplicationServices.WorkingDatabase.Insert(newBlockName, sourceDatabase, false);
}
}
catch (System.Exception e)
{
Application.ShowAlertDialog(e.Message);
}
}

public Database GetDatabaseFromFile(string fileName)
{
Database databaseFromFile = new Database(false, true);
databaseFromFile.ReadDwgFile(fileName, System.IO.FileShare.None, false, null);
return databaseFromFile;
}



//Page 15 lists the steps, Page 17 lists the code
//Adding objects to a database
//The six steps revealed!
[CommandMethod("CreateCircle")]
public void DrawCircle ()
{
//Step one - Start a transaction
using (Transaction trans = StartActiveDatabaseTransaction())
{
//Step two - Create the new object
Circle newCircle = CreateCircle();

//Step three - Open the symbol table
BlockTableRecord modelSpace = OpenActiveModelSpaceForWrite(trans);

//Step four - Append the object to the symbol table
modelSpace.AppendEntity(newCircle);

//Step five - Inform the transactionmanager of the new object
trans.TransactionManager.AddNewlyCreatedDBObject(newCircle, true);

//Step six - Commit the transaction
trans.Commit();
}
}

private Transaction StartActiveDatabaseTransaction()
{
return HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction();
}

private Circle CreateCircle()
{
Point3d centerPoint = new Point3d(0, 0, 0);
Vector3d normal = new Vector3d(0, 0, 1);
double radius = 4.5;
return new Circle(centerPoint, normal, radius);
}

private BlockTableRecord OpenActiveModelSpaceForWrite(Transaction trans)
{
return (BlockTableRecord)trans.GetObject(GetActiveModelSpaceId(), OpenMode.ForWrite);
}

private ObjectId GetActiveModelSpaceId ()
{
using (Transaction trans = StartActiveDatabaseTransaction())
{
BlockTable bt = (BlockTable)trans.GetObject(HostApplicationServices.WorkingDatabase.BlockTableId, OpenMode.ForRead);

return (ObjectId) bt[BlockTableRecord.ModelSpace];
}
}



//Page 16
//Adding non graphic objects
//Variations of the six steps
public static ObjectId CreateLayer(string layerName, Database targetDatabase)
{
//Step one - Start a transaction
using (Transaction trans =targetDatabase.TransactionManager.StartTransaction())
{
ObjectId layerTableId = targetDatabase.LayerTableId;

//Step three - Open the symbol table
//This table has only been opened for reading
LayerTable layers = (LayerTable)trans.GetObject(layerTableId, OpenMode.ForRead);

if (layers.Has(layerName))
{
return layers[layerName];
}
else
{
//Step two - Create the new object
LayerTableRecord newLayer = new LayerTableRecord();
newLayer.Name = layerName;

//Step three - Open the symbol table for writing
layers.UpgradeOpen();

//Step four - Append the object to the symbol table
layers.Add(newLayer);

//Step five - Inform the transactionmanager of the new object
trans.TransactionManager.AddNewlyCreatedDBObject(newLayer, true);

//Step six - Commit the transaction
trans.Commit();

return newLayer.ObjectId;
}
}
}

[CommandMethod("CreateLayer")]
public void CreateLayer()
{
string newLayerName = "AU2005";
CreateLayer(newLayerName, HostApplicationServices.WorkingDatabase);
}
}
}

Bobby C. Jones

TR

  • Guest
Re: AU 2005 code - Part 7 "Digging into the Database"
« Reply #1 on: December 29, 2005, 11:42:31 AM »
Bobby:
I have found that in order for the insert block command to work on multiple drawings in a session you need to close the file in this function. At least this is the case for me in AutoCAD 2005.
Code: [Select]
public Database GetDatabaseFromFile(string fileName)
{
Database databaseFromFile = new Database(false, true);
databaseFromFile.ReadDwgFile(fileName, System.IO.FileShare.None, false, null);
databaseFromFile.CloseInput(true);
return databaseFromFile;
}

Thanks for all the awesome examples and keep em coming. :)

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: AU 2005 code - Part 7 "Digging into the Database"
« Reply #2 on: December 29, 2005, 12:12:15 PM »
Bobby:
I have found that in order for the insert block command to work on multiple drawings in a session you need to close the file in this function. At least this is the case for me in AutoCAD 2005.

Thanks for the heads up Tim!
Bobby C. Jones

TR

  • Guest
Re: AU 2005 code - Part 7 "Digging into the Database"
« Reply #3 on: December 29, 2005, 01:15:16 PM »
No problem. Just out of curiosity, does your code work with multiple drawings in a single session in 2006? For example running InsertBlock on Drawing1.dwg, creating a new drawing and then running InsertBlock on Drawing2.dwg.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AU 2005 code - Part 7 "Digging into the Database"
« Reply #4 on: January 10, 2006, 03:16:51 PM »
Missed this Tim

command handlers run in the application context when they are registered with "CommandFlags.Session"

so you'd need this sort of thing to register the command ;

[CommandMethod("MySuperDuperCommand",CommandFlags.Session)]
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.