Now i changed the code that it works for my use. The only problem is that it does not work with blocks. Now i changed the TransformSelectionSet to TransformSelectionSet2. There i use DeepCloneObjects and all works good. But if i want to transform blocks i get an error. Every other object works correctly. What do i have to do that i can transform a block?
#region Using directives
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;
using RSNNAcadApp.ExtendedCommands;
#endregion
[assembly: CommandClass(typeof(RSNNAcadApp.ExtendedCommands.Copy))]
namespace RSNNAcadApp.ExtendedCommands
{
class Copy
{
private Matrix3d UcsMatrix;
private Point3d m_basePoint;
private Point3d m_destinationPoint;
private Curve BaseCurve;
private Matrix3d transMat;
private Vector3d xAxisFrom, yAxisFrom, zAxisFrom;
private Vector3d xAxisTo, yAxisTo, zAxisTo;
/// <summary>
/// Moves blockreferences along a Curve with a given distance
/// </summary>
[CommandMethod("KOPIERENENTLANGMITBASIS", CommandFlags.UsePickSet)]
public void CopyAlongCurve()
{
Database db = HostApplicationServices.WorkingDatabase;
//Transaction myT = db.TransactionManager.StartTransaction();
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
try
{
PromptSelectionOptions ssOptions = new PromptSelectionOptions();
ssOptions.MessageForAdding = "\nObjekte wählen: ";
ssOptions.MessageForRemoval = "\nObjekte entfernen: ";
ssOptions.AllowDuplicates = true;
PromptSelectionResult ssResult = ed.GetSelection(ssOptions);
if (ssResult.Status != PromptStatus.OK)
return;
if (ssResult.Value.Count == 0)
return;
PromptEntityOptions entOptions = new PromptEntityOptions("\nBezugslinie wählen, entlang der kopiert werden soll");
entOptions.SetRejectMessage("\nNur Kurven können gewählt werden.");
entOptions.AddAllowedClass(typeof(Curve), false);
PromptEntityResult entResult = ed.GetEntity(entOptions);
if (entResult.Status != PromptStatus.OK)
return;
ObjectId BaseCurveId = entResult.ObjectId;
//Get a base point from the user
PromptPointResult pointResult = ed.GetPoint("\nBasispunkt: ");
if (pointResult.Status != PromptStatus.OK)
return;
UcsMatrix = ed.CurrentUserCoordinateSystem;
m_basePoint = pointResult.Value.TransformBy(UcsMatrix);
do
{
using (Transaction myT = db.TransactionManager.StartTransaction())
{
BaseCurve = (Curve)myT.GetObject(BaseCurveId, OpenMode.ForRead);
if (BaseCurve == null)
return;
Point3d tmpbasePoint = BaseCurve.GetClosestPointTo(m_basePoint, false);
xAxisFrom = BaseCurve.GetFirstDerivative(tmpbasePoint).GetNormal();
yAxisFrom = BaseCurve.GetSecondDerivative(tmpbasePoint).GetNormal();
if (yAxisFrom.IsZeroLength() || !yAxisFrom.IsPerpendicularTo(xAxisFrom))
{
if (BaseCurve.IsPlanar)
yAxisFrom = BaseCurve.GetPlane().Normal.CrossProduct(xAxisFrom.GetNormal()).GetNormal();
else
yAxisFrom = xAxisFrom.GetPerpendicularVector().GetNormal();
}
zAxisFrom = xAxisFrom.CrossProduct(yAxisFrom).GetNormal();
//Initiate the drag callback delegate
DragCallback dragCallbackDelegate = this.FollowCursor;
//Start the drag operation
PromptDragOptions dragOptions = new PromptDragOptions(ssResult.Value, "\nZweiter Punkt angeben oder", dragCallbackDelegate);
string kwDefault = "Beenden";
dragOptions.Keywords.Add(kwDefault);
dragOptions.Keywords.Default = kwDefault;
PromptPointResult destinationPointResult = ed.Drag(dragOptions);
if (destinationPointResult.Status != PromptStatus.OK)
return;
m_destinationPoint = destinationPointResult.Value.TransformBy(UcsMatrix);
//m_destinationPoint = destinationPointResult.Value;
Point3d tmpdestinationPoint = BaseCurve.GetClosestPointTo(m_destinationPoint, false);
xAxisTo = BaseCurve.GetFirstDerivative(tmpdestinationPoint).GetNormal();
yAxisTo = BaseCurve.GetSecondDerivative(tmpdestinationPoint).GetNormal();
if (yAxisTo.IsZeroLength() || !yAxisTo.IsPerpendicularTo(xAxisTo))
{
if (BaseCurve.IsPlanar)
yAxisTo = BaseCurve.GetPlane().Normal.CrossProduct(xAxisTo.GetNormal()).GetNormal();
else
yAxisTo = xAxisTo.GetPerpendicularVector().GetNormal();
}
zAxisTo = xAxisTo.CrossProduct(yAxisTo).GetNormal();
//Determine the final displacement matrix
transMat = Matrix3d.AlignCoordinateSystem(
m_basePoint, xAxisFrom, yAxisFrom, zAxisFrom,
m_destinationPoint, xAxisTo, yAxisTo, zAxisTo);
myT.Commit();
}
//transform the ss to the new location
this.TransformSelectionSet2(ssResult.Value, transMat);
} while (true);
}
finally
{
//myT.Dispose();
}
}
//DragCallback Delegate
public SamplerStatus FollowCursor(Point3d currentPoint, ref Matrix3d transMat)
{
Point3d tmpcurrentPoint = BaseCurve.GetClosestPointTo(currentPoint.TransformBy(UcsMatrix), false);
xAxisTo = BaseCurve.GetFirstDerivative(tmpcurrentPoint).GetNormal();
yAxisTo = BaseCurve.GetSecondDerivative(tmpcurrentPoint).GetNormal();
if (yAxisTo.IsZeroLength() || !yAxisTo.IsPerpendicularTo(xAxisTo))
{
if (BaseCurve.IsPlanar)
yAxisTo = BaseCurve.GetPlane().Normal.CrossProduct(xAxisTo.GetNormal()).GetNormal();
else
yAxisTo = xAxisTo.GetPerpendicularVector().GetNormal();
}
zAxisTo = xAxisTo.CrossProduct(yAxisTo).GetNormal();
//Determine the final displacement matrix
transMat = Matrix3d.AlignCoordinateSystem(
m_basePoint, xAxisFrom, yAxisFrom, zAxisFrom,
currentPoint.TransformBy(UcsMatrix), xAxisTo, yAxisTo, zAxisTo);
return SamplerStatus.OK;
}
private void TransformSelectionSet(SelectionSet ss, Matrix3d transMat)
{
if (ss.Count == 0)
{
return;
}
Database targetDatabase = ss[0].ObjectId.Database;
using (Transaction trans = targetDatabase.TransactionManager.StartTransaction())
{
BlockTableRecord currentSpace = (BlockTableRecord)trans.GetObject(targetDatabase.CurrentSpaceId, OpenMode.ForWrite);
foreach (SelectedObject selectedObj in ss)
{
Entity selectedEntity = (Entity)trans.GetObject(selectedObj.ObjectId, OpenMode.ForRead);
Entity transformedEntity = selectedEntity.GetTransformedCopy(transMat);
currentSpace.AppendEntity(transformedEntity);
trans.AddNewlyCreatedDBObject(transformedEntity, true);
}
trans.Commit();
}
}
private void TransformSelectionSet2(SelectionSet ss, Matrix3d transMatrix)
{
if (ss.Count == 0)
{
return;
}
Database targetDatabase = ss[0].ObjectId.Database;
using (Transaction trans = targetDatabase.TransactionManager.StartTransaction())
{
ObjectIdCollection entityCollection = new ObjectIdCollection(ss.GetObjectIds());
IdMapping idMap = new IdMapping();
targetDatabase.DeepCloneObjects(entityCollection, targetDatabase.CurrentSpaceId, idMap, false);
BlockTableRecord currentSpace = (BlockTableRecord)trans.GetObject(targetDatabase.CurrentSpaceId, OpenMode.ForWrite);
foreach (IdPair pair in idMap)
{
Entity clonedEntity = (Entity)trans.GetObject(pair.Value, OpenMode.ForWrite);
clonedEntity.TransformBy(transMatrix);
}
trans.Commit();
}
}
}
}