TheSwamp
Code Red => .NET => Topic started by: Kerry on December 14, 2007, 11:16:53 PM
-
From my Saturday reading ..
public sealed class SymbolUtilityServices
Name: Autodesk.AutoCAD.DatabaseServices.SymbolUtilityServices
Assembly: acdbmgd, Version=17.1.0.0
has a Method
public static ObjectId GetBlockModelSpaceId(Database databasePointer);
In the past , to open Modelspace for Write, I've used something like the following, in one of several variations
ObjectId objId = new ObjectId();
Database Db = HostApplicationServices.WorkingDatabase;
AcDb.TransactionManager Tm = Db.TransactionManager;
using (Transaction tr = Tm.StartTransaction())
{
BlockTable tb = (BlockTable)Tm.GetObject
(Db.BlockTableId, OpenMode.ForRead, false);
objId = ((BlockTableRecord)Tm.GetObject
(tb[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false)).AppendEntity(ent);
Tm.AddNewlyCreatedDBObject(entToWriteToDataBase, true);
tr.Commit();
}
however, using SymbolUtilityServices.GetBlockModelSpaceId seems a little easier ..
ObjectId objId = new ObjectId();
Database Db = HostApplicationServices.WorkingDatabase;
AcDb.TransactionManager Tm = Db.TransactionManager;
using (Transaction tr = Tm.StartTransaction())
{
objId = ((BlockTableRecord)Tm.GetObject(AcDb.SymbolUtilityServices.GetBlockModelSpaceId(Db),
OpenMode.ForWrite, false)).AppendEntity(ent);
Tm.AddNewlyCreatedDBObject(ent, true);
tr.Commit();
}
edit for fatFingerSpelling
-
So, an Entity extension Class ( similar to previously posted by Daniel M )
// CodeHimBelongaKwb © Dec 2007
// D:\Development\Visual Studio 2008\CAD Projects\Sat1215\Sat1215\EntityExtensions.cs
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
namespace Sat1215
{
public static partial class EntityExtensions
{
internal static ObjectId AddToModelSpace(this Entity ent)
{
ObjectId objId = new ObjectId();
Database Db = HostApplicationServices.WorkingDatabase;
AcDb.TransactionManager Tm = Db.TransactionManager;
using (Transaction tr = Tm.StartTransaction())
{
objId = ((BlockTableRecord)Tm.GetObject(AcDb.SymbolUtilityServices.GetBlockModelSpaceId(Db),
OpenMode.ForWrite, false)).AppendEntity(ent);
Tm.AddNewlyCreatedDBObject(ent, true);
tr.Commit();
}
return objId;
}
internal static ObjectId AddToModelSpace(this Entity ent , Database Db)
{
ObjectId objId = new ObjectId();
AcDb.TransactionManager Tm = Db.TransactionManager;
using (Transaction tr = Tm.StartTransaction())
{
objId = ((BlockTableRecord)Tm.GetObject( AcDb.SymbolUtilityServices.GetBlockModelSpaceId(Db),
OpenMode.ForWrite, false)).AppendEntity(ent);
Tm.AddNewlyCreatedDBObject(ent, true);
tr.Commit();
}
return objId;
}
}
}
and to Test it ....
// CodeHimBelongaKwb © Dec 2007
// D:\Development\Visual Studio 2008\CAD Projects\Sat1215\Sat1215\Commands.cs
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
[assembly: CommandClass(typeof(Sat1215.Commands))]
namespace Sat1215
{
class Commands
{
[CommandMethod("test")]
static public void cmdtest()
{
Line ln = new Line(new Point3d(0, 0, 0), new Point3d(100, 100, 0));
ln.AddToModelSpace();
Database Db = HostApplicationServices.WorkingDatabase;
ln = new Line(new Point3d(100, 100, 0), new Point3d(100, 200, 0));
ln.AddToModelSpace(Db);
}
}
}
The partial classes are irrelevant to the use of the Method, I'm just playing with them here..
-
I'll be getting back into C# down the road, so I'm thanking you, Daniel ... in advance, for surely this stuff will be useful to me.
-
and a piccy of some of the OTHER Methods and Properties available
-
Though, thinking of extension classes ...
This is pretty efficient AND cool ..
internal static ObjectId ModelSpaceId(this Database Db)
{
return SymbolUtilityServices.GetBlockModelSpaceId(Db);
}
Piccy Added ..
-
This is what I ended up with ..
just need to add XML comments so that the Intellisense displays the comments.
internal static ObjectId ModelSpaceId(this Database db)
{
return SymbolUtilityServices.GetBlockModelSpaceId(db);
}
//
internal static ObjectId AddToModelSpace(this Entity ent)
{
return ent.AddToModelSpace(HostApplicationServices.WorkingDatabase);
}
//
internal static ObjectId AddToModelSpace(this Entity ent, Database db)
{
ObjectId objId = new ObjectId();
Acdb.TransactionManager tm = db.TransactionManager;
using (Transaction tr = tm.StartTransaction())
{
objId = ((BlockTableRecord)tm.GetObject(db.ModelSpaceId(),
OpenMode.ForWrite, false)).AppendEntity(ent);
tm.AddNewlyCreatedDBObject(ent, true);
tr.Commit();
}
return objId;
}
-
Great stuff Kerry! FYI in the 2006 API the GetBlockModelSpaceId() & GetBlockPaperSpaceId()
methods are not static, so people using this API will need to create a new instance of the class.
It might be wise to use the other method to get the Space id for compatibility.
-
Thanks for the heads-up about the 2006 API.
.. the old backward compatibility issue ... yuk !
I'm developing for AC2007, 2008, 2009 so I think I'll ignore 2006 issues.
-
This is the Paperspace stuff using SymbolUtilityServices
/// <summary>
/// Gets and return the PaperSpace ObjectId.
/// </summary>
/// <param name="db">Database to use</param>
/// <returns>The PaperSpace ObjectId of the Database parameter</returns>
internal static ObjectId PaperSpaceId(this Database db)
{
return SymbolUtilityServices.GetBlockPaperSpaceId(db);
}
//
internal static ObjectId AddToPaperSpace(this Entity ent)
{
return ent.AddToPaperSpace(HostApplicationServices.WorkingDatabase);
}
//
internal static ObjectId AddToPaperSpace(this Entity ent, Database db)
{
ObjectId objId;
Acdb.TransactionManager tm = db.TransactionManager;
using (Transaction tr = tm.StartTransaction())
{
objId = ((BlockTableRecord)tm.GetObject(db.PaperSpaceId(),
OpenMode.ForWrite, false)).AppendEntity(ent);
tm.AddNewlyCreatedDBObject(ent, true);
tr.Commit();
}
return objId;
}
-
.. and this is the associated Intellisence comments from the compiled XML comment. ( for anyone who hasn't made use of the feature :-) )
-
The Database object already has a CurrentSpaceId getter, so when Writing to the Current Space we don't need to concoct our own.
internal static ObjectId AddToCurrentSpace(this Entity ent)
{
return ent.AddToCurrentSpace(HostApplicationServices.WorkingDatabase);
}
//
internal static ObjectId AddToCurrentSpace(this Entity ent, Database db)
{
ObjectId objId;
Acdb.TransactionManager tm = db.TransactionManager;
using (Transaction tr = tm.StartTransaction())
{
objId = ((BlockTableRecord) tm.GetObject(db.CurrentSpaceId,
OpenMode.ForWrite, false)).AppendEntity(ent);
tm.AddNewlyCreatedDBObject(ent, true);
tr.Commit();
}
return objId;
}
-
public sealed class SymbolUtilityServices
How did I miss this class!?! <shakes head> Nice find Kerry...you just keep on reading ;)
Cheers,
Glenn.
-
>>>>. ..you just keep on reading ;)
Cheers,
Glenn.
I certainly will :)