.NET

Reply
Distinguished Contributor
RolandF
Posts: 172
Registered: ‎11-19-2003
Message 1 of 3 (218 Views)

DeepCloneObjects and TransformBy with BlockReferences

218 Views, 2 Replies
02-14-2007 02:41 AM

I have a litte program which copies and rotates a
selectionset along a curve. It works without any problems for every object
except BlockReferences. If i do not transform the objects in
TransformSelectionSet2, also the BlockReferences are working, i just get the
error when i want to transform the BlockReferences. Does anyone know what i have
to do?

 

#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);

foreach (IdPair pair in idMap)

{

Entity clonedEntity = (Entity)trans.GetObject(pair.Value, OpenMode.ForWrite);

clonedEntity.TransformBy(transMatrix);

}

trans.Commit();

}

}

 

}

}

*Tony Tanzillo
Message 2 of 3 (218 Views)

Re: DeepCloneObjects and TransformBy with BlockReferences

02-14-2007 08:58 AM in reply to: RolandF
Autodesk has worked very hard to make it nearly impossible
to post readable code in their discussion forums.

Because of that, its hard for me to look at your code, so I'll
ask you to post it as an attachment (*.cs or in a .zip file).

Also, you don't mention what error message you're getting.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2004/2005/2006/2007
http://www.acadxtabs.com

wrote in message news:5485952@discussion.autodesk.com...
I have a litte program which copies and rotates a selectionset along a curve. It works without any problems for every object except BlockReferences. If i do not transform the objects in TransformSelectionSet2, also the BlockReferences are working, i just get the error when i want to transform the BlockReferences. Does anyone know what i have to do?

#region Using directivesusing 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;/// /// Moves blockreferences along a Curve with a given distance/// [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 userPromptPointResult 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();elseyAxisFrom = xAxisFrom.GetPerpendicularVector().GetNormal();}zAxisFrom = xAxisFrom.CrossProduct(yAxisFrom).GetNormal();//Initiate the drag callback delegateDragCallback dragCallbackDelegate = this.FollowCursor;//Start the drag operationPromptDragOptions 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();elseyAxisTo = xAxisTo.GetPerpendicularVector().GetNormal();}zAxisTo = xAxisTo.CrossProduct(yAxisTo).GetNormal();//Determine the final displacement matrixtransMat = Matrix3d.AlignCoordinateSystem(m_basePoint, xAxisFrom, yAxisFrom, zAxisFrom,m_destinationPoint, xAxisTo, yAxisTo, zAxisTo);myT.Commit();}//transform the ss to the new locationthis.TransformSelectionSet2(ssResult.Value, transMat);} while (true);}finally{//myT.Dispose();}}//DragCallback Delegatepublic 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();elseyAxisTo = xAxisTo.GetPerpendicularVector().GetNormal();}zAxisTo = xAxisTo.CrossProduct(yAxisTo).GetNormal();//Determine the final displacement matrixtransMat = 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);foreach (IdPair pair in idMap){Entity clonedEntity = (Entity)trans.GetObject(pair.Value, OpenMode.ForWrite);clonedEntity.TransformBy(transMatrix);}trans.Commit();}} }}
Distinguished Contributor
RolandF
Posts: 172
Registered: ‎11-19-2003
Message 3 of 3 (218 Views)

Re: DeepCloneObjects and TransformBy with BlockReferences

02-14-2007 11:19 AM in reply to: RolandF
Thank you, Tony.
Attached you can find the code and here is the error message. I get this
message only when i have blocks in my ss.

System.Reflection.TargetInvocationException: Ein Aufrufziel hat einen
Ausnahmefehler verursacht. ---> Autodesk.AutoCAD.Runtime.Exception:
eNotApplicable
bei Autodesk.AutoCAD.DatabaseServices.Entity.TransformBy(Matrix3d
transform)
bei RSNNAcadApp.ExtendedCommands.Copy.TransformSelectionSet2(SelectionSet
ss, Matrix3d transMatrix)
bei RSNNAcadApp.ExtendedCommands.Copy.CopyAlongCurve()
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[]
arguments, SignatureStruct& sig, MethodAttributes methodAttributes,
RuntimeTypeHandle typeOwner)
bei System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[]
arguments, Signature sig, MethodAttributes methodAttributes,
RuntimeTypeHandle typeOwner)
bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean
skipVisibilityChecks)
bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

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