Author Topic: AU 2005 code - Part 9 "Gettin' Jiggy With It"  (Read 10322 times)

0 Members and 1 Guest are viewing this topic.

LE

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #15 on: December 07, 2006, 01:28:51 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.

Welcome to TheSwamp Roland;

I think this is a way to do it:

Code: [Select]
        [CommandMethod("DeepClone")]
        public void deepclone()
        {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            IdMapping mapping = new IdMapping();
            ObjectIdCollection identifiers = new ObjectIdCollection();
            db.DeepCloneObjects(identifiers, db.CurrentSpaceId, mapping, true);
            foreach (ObjectId id in identifiers)
            {
                //...
            }
        }

HTH

LE

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #16 on: December 07, 2006, 02:37:24 PM »
Ignore my previous post, it was the first tryout, see if this one helps you, I used a selection set, but it will be easier to adapt it for your needs.

Code: [Select]
        [CommandMethod("DeepClone")]
        public void deepclone()
        {
        Document doc = acadApp.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;
        Database db = doc.Database;
        IdMapping mapping = new IdMapping();
        ObjectIdCollection identifiers = new ObjectIdCollection();

        PromptSelectionOptions prOpts = new PromptSelectionOptions();
        prOpts.MessageForAdding = "\nSelect objects: ";
        PromptSelectionResult res = ed.GetSelection(prOpts);
        if (res.Status != PromptStatus.OK) return;

        ObjectId[] ids = res.Value.GetObjectIds();
        foreach (ObjectId id in ids)
            identifiers.Add(id);

        db.DeepCloneObjects(identifiers, db.CurrentSpaceId, mapping, false);
        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            foreach (IdPair id in mapping)
            {
                DBObject obj = (DBObject)tr.GetObject(id.Value, OpenMode.ForWrite, false);
                Entity ent = obj as Entity;
            }
            tr.Commit();
        }
        }

HTH

Roland Feletic

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #17 on: February 12, 2007, 11:29:15 AM »
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?

Code: [Select]
#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();
            }
        }


    }
}

Roland Feletic

  • Guest
Re: AU 2005 code - Part 9 "Gettin' Jiggy With It"
« Reply #18 on: February 27, 2007, 08:17:53 AM »
If someone had the same problem, here is the working code. Many thanks to Kean Walmsley from the ADN-Team.
Code: [Select]
#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.TransformSelectionSet(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 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 = trans.GetObject(pair.Value, OpenMode.ForRead) as Entity;
                    if (clonedEntity != null)
                    {
                        Type et = clonedEntity.GetType();
                        if (typeof(SequenceEnd) != et && typeof(AttributeReference) != et)
                        {
                            clonedEntity.UpgradeOpen();
                            clonedEntity.TransformBy(transMatrix);
                            clonedEntity.DowngradeOpen();
                        }
                    }
                }
                trans.Commit();
            }
        }
    }
}