.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Add selected entities to BlockTableRecord

8 REPLIES 8
Reply
Message 1 of 9
Anonymous
1240 Views, 8 Replies

Add selected entities to BlockTableRecord

I'm following some of Keans methods for adding entities to a BTR.

At runtime, it crashes at the record.ApppendEntity(ent);

The program is creating the block okay, but the block is empty.

I'm selecting enties from the AutoCAD screen using:

PromptSelectionOptions posel = new PromptSelectionOptions();
posel.AllowDuplicates = false;
PromptSelectionResult selres = editor.GetSelection(posel);

I've attached the entire class in a txt file.

This is the part I'm having trouble with.
Do I have to change the entity to a COM object?

{
BlockTableRecord record = new BlockTableRecord();

record.Name = blkName;
record.Origin = new Point3d(0, 0, 0);

ObjectId[] objIds = selres.Value.GetObjectIds();

foreach (ObjectId objId in objIds)
{
DBObject obj = transaction.GetObject(objId, OpenMode.ForRead);
Entity ent = (Entity)obj;
editor.WriteMessage("\nType: " + ent.GetType().ToString());

record.AppendEntity(ent); //***crashes here***.
transaction.AddNewlyCreatedDBObject(ent, true);

//obj.Dispose();

}

table.Add(record);

transaction.AddNewlyCreatedDBObject(record, true);

transaction.Commit();


TIA

Bill
8 REPLIES 8
Message 2 of 9
Anonymous
in reply to: Anonymous


Hi Bill,

The entities that you're trying to add to the new
btr already have an owner.
--
Bobby C. Jones


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
I'm
following some of Keans methods for adding entities to a BTR. At runtime, it
crashes at the record.ApppendEntity(ent); The program is creating the block
okay, but the block is empty. I'm selecting enties from the AutoCAD screen
using: PromptSelectionOptions posel = new PromptSelectionOptions();
posel.AllowDuplicates = false; PromptSelectionResult selres =
editor.GetSelection(posel); I've attached the entire class in a txt file. This
is the part I'm having trouble with. Do I have to change the entity to a COM
object? { BlockTableRecord record = new BlockTableRecord(); record.Name =
blkName; record.Origin = new Point3d(0, 0, 0); ObjectId[] objIds =
selres.Value.GetObjectIds(); foreach (ObjectId objId in objIds) { DBObject obj
= transaction.GetObject(objId, OpenMode.ForRead); Entity ent = (Entity)obj;
editor.WriteMessage("\nType: " + ent.GetType().ToString());
record.AppendEntity(ent); //***crashes here***.
transaction.AddNewlyCreatedDBObject(ent, true); //obj.Dispose(); }
table.Add(record); transaction.AddNewlyCreatedDBObject(record, true);
transaction.Commit(); TIA Bill
Message 3 of 9
Anonymous
in reply to: Anonymous

Thanks Bobby,

>The entities that you're trying to add to the new
>btr already have an owner.

That implied to me that I didn't need to append an entity that's already there.
So AssumeOwnershipOf was the logical thing to look at.
That led me to learn that my btr was not yet in the Database so I added that to the bt first.

Works now, maybe a more elegant way to write but here's the code:

[code]

if (!table.Has(blkName))
{
try
{
BlockTableRecord record = new BlockTableRecord();

record.Name = blkName;
record.Origin = new Point3d(0, 0, 0);

table.Add(record);
transaction.AddNewlyCreatedDBObject(record, true);

ObjectId[] objIds = selres.Value.GetObjectIds();

ObjectIdCollection obid = new ObjectIdCollection();

foreach (ObjectId objId in objIds)
{
obid.Add(objId);
}

record.AssumeOwnershipOf(obid);

transaction.Commit();

blkName = "(command \"_.BlockIcon\" \"\" blockname) ";

CallBlockIcon.BlkIcon(blkName);

editor.WriteMessage("\nBlockRecord : " + record.Name + " Created.\n");
}
catch (System.Exception e)
{
editor.WriteMessage("\nError: " + e.ToString());
}
}
[/code]


Thanks agian for the hint!

Bill
Message 4 of 9
Anonymous
in reply to: Anonymous

If you're writing something that works like the BLOCK command, then
the latter doesn't transfer the selected objects to the block, it just
copies
them (and then erases the originals). You can use DeepCloneObjects()
to do the same thing.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009

http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm


wrote in message news:6162843@discussion.autodesk.com...
Thanks Bobby, >The entities that you're trying to add to the new >btr
already have an owner. That implied to me that I didn't need to append an
entity that's already there. So AssumeOwnershipOf was the logical thing to
look at. That led me to learn that my btr was not yet in the Database so I
added that to the bt first. Works now, maybe a more elegant way to write but
here's the code: [code] if (!table.Has(blkName)) { try { BlockTableRecord
record = new BlockTableRecord(); record.Name = blkName; record.Origin = new
Point3d(0, 0, 0); table.Add(record);
transaction.AddNewlyCreatedDBObject(record, true); ObjectId[] objIds =
selres.Value.GetObjectIds(); ObjectIdCollection obid = new
ObjectIdCollection(); foreach (ObjectId objId in objIds) {
obid.Add(objId); } record.AssumeOwnershipOf(obid); transaction.Commit();
blkName = "(command \"_.BlockIcon\" \"\" blockname) ";
CallBlockIcon.BlkIcon(blkName); editor.WriteMessage("\nBlockRecord : " +
record.Name + " Created.\n"); } catch (System.Exception e) {
editor.WriteMessage("\nError: " + e.ToString()); } } [/code] Thanks agian
for the hint! Bill
Message 5 of 9
Anonymous
in reply to: Anonymous

Thanks Tony.

>If you're writing something that works like the BLOCK command, then
>the latter doesn't transfer the selected objects to the block, it just
>copies them (and then erases the originals).

So that's what happened to the entities.
I didn't like the fact that they disappeared upon completion,
so I changed my program to clone them instead.
I've only used simple objects up to this point so I'll look into the DeepCloneObject method.

Interesting that they get copied then erased when using the AssumeOwnershipOf method.

This made the block and left the originals, but again, haven't tested thoroughly.

[code]
foreach (ObjectId objId in objIds)
{
Entity ent = transaction.GetObject(objId, OpenMode.ForRead) as Entity;
Entity cpe = ent.Clone() as Entity;
record.AppendEntity(cpe);
transaction.AddNewlyCreatedDBObject(cpe, true);

//obid.Add(objId);
}
[/code]

Bill
Message 6 of 9
Anonymous
in reply to: Anonymous

Tony,

The DeepCloneObjects method was a simpler way to do this.

One question, is there an easier way to pass values from an "ObjectId[]" to a "ObjectIdCollection" other than looping with a for or foreach?
Or is this one of the things you live with in C#?

[code]
ObjectId[] objIds = selres.Value.GetObjectIds();

ObjectIdCollection obids = new ObjectIdCollection();

foreach (ObjectId oid in objIds) //seems like you have to do this to add ObjectIds to the collection. 😞
{
obids.Add(oid);
}

database.DeepCloneObjects(obids, database.CurrentSpaceId, false);
record.AssumeOwnershipOf(obids);
[/code]

TIA

Bill

Edited by: BillZndl on Apr 16, 2009 10:06 AM Edited by: BillZndl on Apr 16, 2009 11:02 AM
Message 7 of 9
Anonymous
in reply to: Anonymous

Nevermind that last question.

Thanks for not answering. :~)

[code]

ObjectId[] objIds = selres.Value.GetObjectIds();

ObjectIdCollection obids = new ObjectIdCollection(objIds);

[/code]

Bill
Message 8 of 9
Anonymous
in reply to: Anonymous

AssumeOwnershipOf doesn't copy/erase objects.

It just changes the owner of the entities.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009

http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm


wrote in message news:6163384@discussion.autodesk.com...
Thanks Tony. >If you're writing something that works like the BLOCK command,
then >the latter doesn't transfer the selected objects to the block, it just
>copies them (and then erases the originals). So that's what happened to the
entities. I didn't like the fact that they disappeared upon completion, so I
changed my program to clone them instead. I've only used simple objects up
to this point so I'll look into the DeepCloneObject method. Interesting that
they get copied then erased when using the AssumeOwnershipOf method. This
made the block and left the originals, but again, haven't tested thoroughly.
[code] foreach (ObjectId objId in objIds) { Entity ent =
transaction.GetObject(objId, OpenMode.ForRead) as Entity; Entity cpe =
ent.Clone() as Entity; record.AppendEntity(cpe);
transaction.AddNewlyCreatedDBObject(cpe, true); //obid.Add(objId); } [/code]
Bill
Message 9 of 9
Anonymous
in reply to: Anonymous

Okay, thanks.
I had misunderstood what you said.
(I was thinking "latter" meant the code I had posted).

>If you're writing something that works like the BLOCK command, then
>the latter doesn't transfer the selected objects to the block, it just
>copies
>them (and then erases the originals). You can use DeepCloneObjects()
>to do the same thing.

>AssumeOwnershipOf doesn't copy/erase objects.
>It just changes the owner of the entities.

Bill

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost