Author Topic: AU 2005 code - Part 9 "Gettin' Jiggy With It"  (Read 10293 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 9 "Gettin' Jiggy With It"
« on: December 28, 2005, 03:39:56 PM »
I debated on whether or not to post this one because it's not quite ready for production.  But then I said to myself, "What the heck, you only live once". :)

This example takes the previous Jig example to the next logical level.  It allows you to pass in an array of ObjectId's and allows you to drag them around the screen and reports back the displacement matrix of the drag operation.  The test driver defines a method that drags them around and creates a copy, "DragCopy". 

**WARNING**
Don't use the test driver on block inserts with attributes.  The EntityDragger class works just fine with them.

**WARNING II**
This code requires the 2.0 version of the .NET framework.  Although with a very small change this can be made compatible with the 1.1 version.  Simply change all instances of the generic List<T> to an ArrayList.

EntityDragger class
Code: [Select]
//Code not in the handout!
using System;
using System.Collections;
using System.Collections.Generic;

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



namespace AU2005.AcadApi
{
   //TODO: Handle the pointer moving out of the Acad window
//TODO: Determine how/if to handle non database resident entities
//TODO: Add UseBasePoint option
public class EntityDragger : DrawJig
{
#region Private member fields

private Point3d m_basePoint;
private Point3d m_previousCursorPosition;
private Point3d m_currentCursorPosition;
private Matrix3d m_displacementMatrix = Matrix3d.Identity;
private List<Entity> m_entitiesToDrag;

#endregion


#region Public members

/// <summary>
/// Drag entities on screen with cursor.
/// </summary>
/// <param name="basePoint">The base point of the drag</param>
/// <param name="entitiesToDrag">ObjectId's to drag.</param>
/// <returns>The PromptResult of the Drag operation</returns>
public virtual PromptResult StartDrag (Point3d basePoint, params ObjectId[] entitiesToDrag)
{
m_basePoint = TransformPointToCurrentUcs(basePoint);

//Prepare for initial transformation
m_previousCursorPosition = m_basePoint;

m_entitiesToDrag = CloneEntitiesToDrag(entitiesToDrag);

//Start dragging loop
return Application.DocumentManager.MdiActiveDocument.Editor.Drag(this);
}

/// <summary>
/// WCS displacement matrix from the basepoint to the final selected point.
/// </summary>
public virtual Matrix3d DisplacementMatrix
{
get
{
Vector3d displacementVector = m_currentCursorPosition.GetVectorTo(m_basePoint);

return Matrix3d.Displacement(TransformVectorToWcs(displacementVector));
}
}
#endregion


#region protected members

protected override SamplerStatus Sampler(JigPrompts prompts)
{
//Track cursor position
PromptPointResult userFeedback = prompts.AcquirePoint();
m_currentCursorPosition = userFeedback.Value;

if (CursorHasMoved())
{
//Get the vector of the move
Vector3d displacementVector = m_currentCursorPosition.GetVectorTo(m_previousCursorPosition);

//Save a displacement matrix for the move
m_displacementMatrix = Matrix3d.Displacement(displacementVector);

//Save the cursor position
m_previousCursorPosition = m_currentCursorPosition;

return SamplerStatus.OK;
}
else
{
return SamplerStatus.NoChange;
}
}


protected override bool WorldDraw(WorldDraw draw)
{
Matrix3d displacementMatrix = m_displacementMatrix;

foreach (Entity draggingEntity in m_entitiesToDrag)
{
draggingEntity.TransformBy(displacementMatrix);
draw.Geometry.Draw(draggingEntity);
}
return true;
}
#endregion


#region private members

private List<Entity> CloneEntitiesToDrag (IList entities)
{
List<Entity> entitiesToDrag = new List<Entity>(entities.Count);

using (Transaction dragTrans = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction())
{
foreach (ObjectId entityId in entities)
{
Entity drawableEntity = (Entity)dragTrans.GetObject(entityId, OpenMode.ForRead);

entitiesToDrag.Add((Entity)drawableEntity.Clone());
}
}
return entitiesToDrag;
}


private bool CursorHasMoved ()
{
return m_currentCursorPosition != m_previousCursorPosition;
}


private Vector3d TransformVectorToWcs (Vector3d vector)
{
return vector.TransformBy(Matrix3d.Identity);
}


private Point3d TransformPointToCurrentUcs (Point3d basePoint)
{
Matrix3d currentUcs = Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;

return basePoint.TransformBy(currentUcs);
}
#endregion

}
}


TestEntityDragger class
Defines the "DragCopy" command
Code: [Select]
using System;

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

using AU2005.AcadApi;

namespace AU2005.AcadApi
{
public class TestEntityDragger
{
[CommandMethod("DragCopy")]
public void DragAndCopyEntities ()
{
Editor currentEditor = Application.DocumentManager.MdiActiveDocument.Editor;

//Create a new selection set options object
PromptSelectionOptions ssOptions = new PromptSelectionOptions();
ssOptions.AllowDuplicates = true;
ssOptions.MessageForAdding = "Select objects to copy: ";

//Get a selection from the user
PromptSelectionResult ssResult = currentEditor.GetSelection(ssOptions);

//Get a point from the user
PromptPointResult pointResult = currentEditor.GetPoint("\nSelect Base Point: ");

bool userPromptsOk = (ssResult.Status == PromptStatus.OK) && (pointResult.Status == PromptStatus.OK);

if (userPromptsOk)
{
EntityDragger dragger = new EntityDragger();
PromptResult dragResult = dragger.StartDrag(pointResult.Value, ssResult.Value.GetObjectIds());

if (dragResult.Status == PromptStatus.OK)
{
CreateTransformedCopy(dragger.DisplacementMatrix, ssResult.Value.GetObjectIds());
}
}
}


/// <summary>
/// Creates a transformed copy of the provided entities in the current space.
/// </summary>
/// <param name="transformationMatrix">The Matrix3d to apply to the entities.</param>
/// <param name="entitiesToCopy">A list of ObjectId's to copy and transform</param>
private void CreateTransformedCopy(Matrix3d transformationMatrix, params ObjectId[] entitiesToCopy)
//TODO: Handle blocks with attributes
{
Editor currentEditor = Application.DocumentManager.MdiActiveDocument.Editor;

using (Transaction trans = currentEditor.Document.TransactionManager.StartTransaction())
{
ObjectIdCollection entityCollection = new ObjectIdCollection(entitiesToCopy);

Database currentDb = currentEditor.Document.Database;

IdMapping idMap = currentDb.DeepCloneObjects(entityCollection, currentDb.CurrentSpaceId, false);

foreach (IdPair pair in idMap)
{
Entity clonedEntity = (Entity)trans.GetObject(pair.Value, OpenMode.ForWrite);
clonedEntity.TransformBy(transformationMatrix);
}

trans.Commit();
}
}
}
}
« Last Edit: December 28, 2005, 04:19:50 PM by Bobby C. Jones »
Bobby C. Jones

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #1 on: December 28, 2005, 06:08:45 PM »
Thanks immensely for posting these 9 Examples Bobby.


I'm sure that they will become an invaluable resource as more people delve into C# and NET generally.


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.

Draftek

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #2 on: December 29, 2005, 08:04:40 AM »
agreed.

Very nice Bobby..

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #3 on: December 29, 2005, 11:00:21 AM »
Thanks immensely for posting these 9 Examples Bobby.


I'm sure that they will become an invaluable resource as more people delve into C# and NET generally.

Thanks guys, and you're welcome.

I don't know about invaluable, but I hope that they are a resource.  And I sure hope that those out there using VB.NET aren't turned off by the C# code.  These examples should easily translate over to VB.  Of course I say that without trying it first  :-)
Bobby C. Jones

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #4 on: August 18, 2006, 06:49:00 PM »
.......
I don't know about invaluable, but I hope that they are a resource.  .......................

I just found this thread copied to another forum, warts and all, including Bobby'd edit note,
Quote
« Last Edit: 2005-12-29, 06:19:50 by Bobby C. Jones »

... so I'd consider it IS a valid resource  :lol:
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.

DBARANAS

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #5 on: August 18, 2006, 10:07:03 PM »
Another piece of the puzzle!

My thanks too!

Roland Feletic

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #6 on: December 07, 2006, 08:20:49 AM »
Hello,
your code helped me a lot. But now i have the problem that i use AutoCAD 2007 and there the following code does not work.
What do i have to do now?
Code: [Select]
IdMapping idMap = currentDb.DeepCloneObjects(entityCollection, currentDb.CurrentSpaceId, false);I get this error: Error   1   No overload for method 'DeepCloneObjects' takes '3' arguments

I need 4 arguments, but i do not know which IdMapping i have to use.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #7 on: December 07, 2006, 08:49:00 AM »
Roland,
Welcome to the Swamp.
I'm not sure of the requirement for the IdMapping Parameter other than whats in the help file.

You may be able to determine it from the clones.CPP and deepclon.CPP in the SDK

regards
kwb
« Last Edit: December 07, 2006, 09:02:37 AM by Kerry Brown »
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.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #8 on: December 07, 2006, 09:03:20 AM »
This may help ..

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.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #9 on: December 07, 2006, 09:12:29 AM »
public DeepCloneType DeepCloneContext { get; }

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.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #10 on: December 07, 2006, 09:15:32 AM »
public Database DestinationDatabase { get; set; }


///--------------------------------------------------

public DuplicateRecordCloning DuplicateRecordCloning { get; }
« Last Edit: December 07, 2006, 09:19:26 AM by Kerry Brown »
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.

Roland Feletic

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #11 on: December 07, 2006, 11:52:41 AM »
I think that i need more time to look at cloning objects, i've never done it before. Thank you for your help. Will see if i understand all this stuff  :lol:

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #12 on: December 07, 2006, 12:12:56 PM »
Hello,
your code helped me a lot. But now i have the problem that i use AutoCAD 2007 and there the following code does not work.
What do i have to do now?
Code: [Select]
IdMapping idMap = currentDb.DeepCloneObjects(entityCollection, currentDb.CurrentSpaceId, false);I get this error: Error   1   No overload for method 'DeepCloneObjects' takes '3' arguments

I need 4 arguments, but i do not know which IdMapping i have to use.

Hey Roland,
If you're using 2007 and are just trying to mimic the code from that post, have a look here http://www.theswamp.org/index.php?topic=11340.0

The examples shown there are the prefered way to drag a selection set in 2007 and a different approach to cloning entities is shown.
Bobby C. Jones

Roland Feletic

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #13 on: December 07, 2006, 12:54:51 PM »
Sorry, but i do not understand it. I tried it now with following code and it also doesn't work.
Code: [Select]
                IdMapping idMap = new IdMapping();

                currentDb.DeepCloneObjects(entityCollection, currentDb.CurrentSpaceId, idMap, false);
OK, i will leave it now because i will be out of office for a few days, will be back on Tuesday.
Will try a little bit more next week.

Roland

Roland Feletic

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #14 on: December 07, 2006, 12:56:46 PM »
Again sorry, Bobby i've seen your post after writing the last one, will have a look at it next week.
Thanks

Roland