.NET

Reply
Active Contributor
davidgarner
Posts: 26
Registered: ‎04-14-2005
Message 1 of 6 (420 Views)

Copy Selection Set

420 Views, 5 Replies
03-17-2006 03:06 PM
I have lisp code that looks like this.

(setq ss (ssget))
(command "COPY" ss "" "@" "@")

This allows the user to make a selection set, then the copy command is called on the selection set.

I need to do the same thing in .Net (C#)

I can get the selection set from the user with:
SelectionSet selection = Application.DocumentManager.MdiActiveDocument.Editor.GetSelection().Value

How can I invoke the copy command on the selection set contained in the "selection" variable?
Valued Contributor
pellacad
Posts: 73
Registered: ‎04-19-2006
Message 2 of 6 (420 Views)

Re: Copy Selection Set

12-15-2009 04:27 PM in reply to: davidgarner
Greetings David,

I'm trying to do the same thing in VB.NET.

We're you ever able to use selection sets with ACAD commands?

I'm searching high and low...

I'll post any developments.

Pete
*Expert Elite*
_gile
Posts: 2,106
Registered: ‎04-29-2006
Message 3 of 6 (420 Views)

Re: Copy Selection Set

12-16-2009 12:16 AM in reply to: davidgarner
Hi,

IMO, using .NET as a script langage (calling native AutoCAD commands) is a nonsense.
Even LISP provides much more than this kinf of statements.

Anyway, you can convert your selection set into an ObjectId array:
selection.GetObjectIds
Then, iterate thru this array, get each objectId as entity and use the Clone() method to create a copy, add this copy to the current space (or another BlockTableRecord.

Here's a little example, the "Test" command prompt for a selection, a base point, a second point and calls the CopyMove method to copy the selection set and move the copied entities.

{code}[CommandMethod("Test")]
public void Test()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Matrix3d ucs = ed.CurrentUserCoordinateSystem;
PromptSelectionResult psr = ed.GetSelection();
if (psr.Status != PromptStatus.OK)
return;
PromptPointResult ppr = ed.GetPoint("\nBase point: ");
if (ppr.Status != PromptStatus.OK)
return;
Point3d basePoint = ppr.Value;
PromptPointOptions ppo = new PromptPointOptions("\nSecond point: ");
ppo.BasePoint = basePoint;
ppo.UseBasePoint = true;
ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
Vector3d disp = basePoint.TransformBy(ucs).GetVectorTo(ppr.Value.TransformBy(ucs));
ObjectId[] ss = psr.Value.GetObjectIds();
try
{
CopyMove(ss, disp);
}
catch (System.Exception ex)
{
ed.WriteMessage("Error: " + ex.Message);
}
}

private void CopyMove(ObjectId[] ss, Vector3d disp)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
foreach (ObjectId id in ss)
{
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite, false);
Entity copiedEnt = (Entity)ent.Clone();
btr.AppendEntity(copiedEnt);
tr.AddNewlyCreatedDBObject(copiedEnt, true);
ent.TransformBy(Matrix3d.Displacement(disp));
}
tr.Commit();
}
}{code}
Gilles Chanteau
*Tony Tanzillo
Message 4 of 6 (420 Views)

Re: Copy Selection Set

12-16-2009 01:11 AM in reply to: davidgarner
Ummmm.... Applications generally don't call Clone() directly to copy
objects.

Clone() creates a *shallow* clone of an object, which means that things like
subentities and other owned objects (like extension dictionaries and their
contents) are not also cloned, as they would be if you used the AutoCAD COPY
command.

For example, if you tried your code on a 'heavy' polyline or a block
reference with attributes, odds are that you would end up with a corrupt
drawing, polylines with no vertices, block insertions with no attributes,
multiply-owned objects, and other unexpected/undesired results.

There is also the matter of object id translation that occurs when multiple
objects are copied, and some of those objects hold a reference other objects
that are also being copied. In that case, a translation applied to all
object id references in the referencing objects, such that clones of those
referencing objects will be modified to reference the clones of the
referenced objects.

For example, if you have object 'a' and object 'b', where 'a' holds a
reference to 'b', and you DeepClone() both of them resulting in 'c' and 'd'
respectively, the clone of 'a' (c) will be modified to reference the clone
of 'b' (d).

The DeepClone() method of the database is generally how we 'copy' objects.
You can use it to copy objects within the same owner, as well as to another
owner. It takes care of all of the aforementioned (and other) gory details.
You can also handle the DeepClone-related events of the Database to operate
on the cloned objects as well, to transform them, or whatever else you need
to do.

An example of using DeepClone-related events can be found in this file:

http://www.caddzone.com/BlockExplodeHelper.cs

--
http://www.caddzone.com

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

http://www.acadxtabs.com

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");

<_gile> wrote in message news:6305533@discussion.autodesk.com...
Hi,

You can convert your selection set into an ObjectId array:
selection.GetObjectIds
Then, iterate thru this array, get each objectId as entity and use the
Clone() method to create a copy, add this copy to the current space (or
another BlockTableRecord.

Here's a little example, the "Test" command prompt for a selection, a base
point, a second point and calls the CopyMove method to copy the selection
set and move the copied entities.
*Expert Elite*
_gile
Posts: 2,106
Registered: ‎04-29-2006
Message 5 of 6 (420 Views)

Re: Copy Selection Set

12-16-2009 03:19 AM in reply to: davidgarner
Thank you Tony (one more time).

I used the statement shown in AutoCAD .NET Developer's Guide > Create and Edit AutoCAD Entities > Edit Named and 2D Objects > Copy Objects > Copy Object.

I made some tests with complex entities (block references with attributes, heavy polylines), with xdictionaries and xdatas too, but have no problem.

Anyway, I'll study what you provide.

So, this way would be safer ?

{code}private void CopyMove(ObjectIdCollection ids, Vector3d disp)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
IdMapping idMap = new IdMapping();
db.DeepCloneObjects(ids, db.CurrentSpaceId, idMap, false);
foreach (IdPair pair in idMap)
{
if (pair.IsPrimary && pair.IsCloned)
{
Entity ent = (Entity)tr.GetObject(pair.Value, OpenMode.ForWrite, false);
ent.TransformBy(Matrix3d.Displacement(disp));
}
}
tr.Commit();
}
}{code}

Edited by: _gile on Dec 16, 2009 7:05 PM
Gilles Chanteau
*Tony Tanzillo
Message 6 of 6 (420 Views)

Re: Copy Selection Set

12-18-2009 10:26 AM in reply to: davidgarner
Ooops..

In case anyone is confused by it, I mistakenly refer to the
DeepCloneObjects() method, as the 'DeepClone()' method, which doesn't exist.

--
http://www.caddzone.com

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

http://www.acadxtabs.com

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");

<_gile> wrote in message news:6305560@discussion.autodesk.com...
Thank you Tony (one more time).
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.