TheSwamp

Code Red => .NET => Topic started by: MGorecki on March 09, 2011, 10:17:51 AM

Title: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: MGorecki on March 09, 2011, 10:17:51 AM
Hello,
I've looked all over for information on how to insert a DXF file into an existing drawing, but cannot find anything that works.
Does someone have a way to insert a DXF file into an existing drawing using VB.Net?  I've updated my references to include the AuoDesk.AutoCAD.Interop and Interop.Common, but still cannot work out a way to insert a DXF file.

Thanks in advance for any help or at least pointing me in the right direction.
Mark
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Jeff H on March 09, 2011, 01:21:25 PM
Have you looked at Database.DxfIn()
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Jeff H on March 09, 2011, 01:37:05 PM
Sorry, Mixed up forget the DxfIN
 seems I have done it with Regular Insert
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Jeff H on March 09, 2011, 01:40:13 PM
I remember now, post at Autodesk fourms

This code is from Kerry Brown at http://www.theswamp.org/index.php?topic=34982.0 with a litle a change so thank him.

 
[CommandMethod("ImportDXF")]
          public void ImportDXF()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;       
            AcadDocument comDoc = (Autodesk.AutoCAD.Interop.AcadDocument)doc.AcadDocument;
            double myScale = 1;
            Point3d p1 = Point3d.Origin;
            double[] ptArray = p1.ToArray();
            comDoc.Import(@"C:\Users\Jeff\My Documents\XrefTest.dxf", (object)ptArray, myScale);
        }
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 10, 2011, 11:00:58 AM
This code is from Kerry Brown at http://www.theswamp.org/index.php?topic=34982.0 with a litle a change so thank him.

Is it just me or can't the insertion point be set? (Scale factor works fine btw.)

Code: [Select]
        let ppr = ed.GetPoint "Insertion point"
        if ppr.Status = PromptStatus.OK then
            let pdr = ed.GetDouble "Scale factor"
            if pdr.Status = PromptStatus.OK then
                let objs = new ResizeArray<_>()
                (
                    use objectAppended =
                        db.ObjectAppended
                        |> Observable.subscribe
                            (fun e -> objs.Add e.DBObject.ObjectId)
                    doc.AcadDocument?Import(dialog.FileName, ppr.Value.ToArray(), pdr.Value)
                )
                objs |> Array.ofSeq |> ed.SetImpliedSelection

Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Jeff H on March 10, 2011, 05:13:38 PM
Is it just me or can't the insertion point be set? (Scale factor works fine btw.)

Was keeping it simple
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 11, 2011, 04:26:09 AM
Was keeping it simple

Kerry (thx) kept it simple too. Me wants complicated.

What exactly needs to be passed to the Import method to influence the insertion point? (System.Double[] likely doesn't cut it)
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 11, 2011, 09:01:54 AM
kaefer ,

I'm unsure of the f# syntax, and how much goes on behind the scenes regarding typing, but

I think you will need to cast the array of doubles to an object.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 11, 2011, 04:45:20 PM
I'm unsure of the f# syntax, and how much goes on behind the scenes regarding typing, but
Oh, sorry. I think its the same as in C#, autoboxing when assigning to object[].

Quote
I think you will need to cast the array of doubles to an object.

My problem doesn't seem to be the missing cast, but an unintuative interpretation of "insertion point" by the Import method. The following C# code exhibits the same weird behaviour: treating the insertion point as 0,0,0 when the scale factor is 1.0, else do something, but not what I'd expect.

Code: [Select]
   public class MyDxfInCmdClass
    {
        IList<ObjectId> objs;

        [CommandMethod("MyDxfIn")]
        public void MyDxfInCmd()
        {
            objs = new List<ObjectId>();
            Document doc = AcApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            var dialog = new System.Windows.Forms.OpenFileDialog{
                    CheckFileExists = true,
                    CheckPathExists = true,
                    DefaultExt = "dxf",
                    DereferenceLinks = true,
                    Filter = "DXF Files (*.dxf)|*.dxf|All files (*.*)|*.*" ,
                    Title = "Select dxf file" };
            if(dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                return;
            var ppr = ed.GetPoint("Insertion point");
            if(ppr.Status != PromptStatus.OK)
                return;
            var pdr = ed.GetDouble("Scale factor");
            if(pdr.Status != PromptStatus.OK)
                return;
            db.ObjectAppended += new ObjectEventHandler(ObjectAppended);
            try
            {
                object[] args = new object[] {
                    dialog.FileName, ppr.Value.ToArray(), pdr.Value
                };
                Invoke(doc.AcadDocument, "Import", args);
            }
       finally
       {
       db.ObjectAppended -= new ObjectEventHandler(ObjectAppended);
       }
            ObjectId[] ids = new ObjectId[objs.Count];
            objs.CopyTo(ids, 0);
            ed.SetImpliedSelection(ids);
        }
        void ObjectAppended(object sender, ObjectEventArgs e)
        {
            objs.Add(e.DBObject.ObjectId);
        }
        static object Invoke(object o, string name, params object[] args)
        {
            return o.GetType().InvokeMember(name, System.Reflection.BindingFlags.InvokeMethod, null, o, args);
        }
    }
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 11, 2011, 09:58:11 PM
The attached piccy shows my testing routine.

There seems to be a bug in the  Autodesk.AutoCAD.Interop.Import()
Code: [Select]
comDoc.Import(fn, (object)ptArray, insScale);If I insert at 100,200,0 with a scale of 1 the dxf comes in at 0,0,0 at 1:1

If I insert at 100,200,0 with a scale of 2 the dxf comes in at -100,-200,0 at 2:1

If I insert at 100,200,0 with a scale of 3 the dxf comes in at -200,-400,0 at 3:1

I'm sure you see the progression :)

I'll do some more testing and report it to the ADN.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 11, 2011, 10:23:44 PM
One workaround may be :

Identify the last entity in the DataBase.

Collect the FileName, Location, Scale.

Import at 0,0,0 @ scale.

Build a collection of entitys in the Database after the previously identified last entity.

Move the collection from 0,0,0 to Location(factored).
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 12, 2011, 03:23:00 AM
Thinking about this while I was out ...
Another workaround may be :

Identify and save UCS information ; either Name or Coordinates.

Collect the FileName, Location, Scale.

Change the UCS Origin

Import at 0,0,0 @ scale.

Restore the Previous UCS

Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 12, 2011, 04:57:34 AM
Lots of "thank you!" for confirming my suspicions.

Change the UCS Origin

Won't do, because Import lives in world coordinates.

Collect the FileName, Location, Scale.

Import at 0,0,0 @ scale.

Build a collection of entitys in the Database after the previously identified last entity.

Move the collection from 0,0,0 to Location(factored).

This is the way to go, then. The ObjectAppended event may be helpful to collect the entities and a transformation matrix build of displacement and rotation (extra bonus) does the work.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 12, 2011, 05:38:25 AM

I've reported the anomolie.

I'll have a play tomorrow if I can make time ... unless 'someone' posts a solution in the meantime :)

I have code in Lisp for doing what is needed so I know the idea works.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Glenn R on March 12, 2011, 05:23:50 PM
Has anybody tried:

1. New 'side database'
2. DxfIn method on new 'side database' to insert dxf file into new pristine database
3. insert the new 'side database' with dxf info into current drawing

???
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 12, 2011, 08:12:36 PM
yes, I woke up at 0250 thinking about just that.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Glenn R on March 13, 2011, 06:05:49 AM
Hate that.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 13, 2011, 06:55:01 AM
Has anybody tried:

1. New 'side database'
2. DxfIn method on new 'side database' to insert dxf file into new pristine database
3. insert the new 'side database' with dxf info into current drawing

Hey, that's not fair. It's the .NET way, it has kind of diagnostics; worst of all I don't need my dyn op implementation anymore.

Anyway, here's the workaround for the Import method outlined before, as complete F#.
Code: [Select]
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.Runtime
type acApp = Autodesk.AutoCAD.ApplicationServices.Application

open System.Reflection
open Microsoft.FSharp.Reflection

let (?) (o: obj) name : 'R =
    if FSharpType.IsFunction(typeof<'R>) then
        let (argType, resType) = FSharpType.GetFunctionElements(typeof<'R>)
        let toArray args =
            if argType = typeof<unit> then [| |]
            elif not(FSharpType.IsTuple argType) then [| args |]
            else FSharpValue.GetTupleFields args
        let checkUnit = if resType = typeof<unit> then fun _ -> box() else id
        FSharpValue.MakeFunction(typeof<'R>, fun args ->
            o.GetType().InvokeMember(
                name, BindingFlags.InvokeMethod ||| BindingFlags.GetProperty, null, o, toArray args)
            |> checkUnit )
    else
        o.GetType().InvokeMember(name, BindingFlags.InvokeMethod ||| BindingFlags.GetProperty, null, o, null)
    |> unbox<'R>

[<CommandMethod "MYDXFIN">]
let myDxfIn() =
    let doc = acApp.DocumentManager.MdiActiveDocument
    let db = doc.Database
    let ed = doc.Editor
    let dialog =   
        new System.Windows.Forms.OpenFileDialog(
            CheckFileExists = true,
            CheckPathExists = true,
            DefaultExt = "dxf",
            DereferenceLinks = true,
            Filter = "DXF Files (*.dxf)|*.dxf|All files (*.*)|*.*" ,
            Title = "Select dxf file" )
    if dialog.ShowDialog()  = System.Windows.Forms.DialogResult.OK then
        let ppr = ed.GetPoint "Insertion point"
        if ppr.Status = PromptStatus.OK then
            let par =
                new PromptAngleOptions(
                    "Rotation",
                    BasePoint = ppr.Value,
                    UseAngleBase = true )
                |> ed.GetAngle
            if par.Status = PromptStatus.OK then
                let pdr = ed.GetDouble "Scale factor"
                if pdr.Status = PromptStatus.OK then
                    let objs = new ResizeArray<_>()
                    (
                        use objectAppended =
                            db.ObjectAppended
                            |> Observable.subscribe
                                (fun e -> objs.Add e.DBObject.ObjectId)
                        doc.AcadDocument?Import(dialog.FileName, Point3d.Origin.ToArray(), 1.)
                    )
                    let mat =
                        Matrix3d.Scaling(pdr.Value, Point3d.Origin) *
                        Matrix3d.Rotation(par.Value, Vector3d.ZAxis, Point3d.Origin) *
                        Matrix3d.Displacement(ppr.Value - Point3d.Origin)
                    use tr = db.TransactionManager.StartTransaction()
                    for oid in objs do
                        (tr.GetObject(oid, OpenMode.ForWrite) :?> Entity).TransformBy mat
                    tr.Commit()
                    objs |> Array.ofSeq |> ed.SetImpliedSelection
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 13, 2011, 09:22:58 AM


This is what I've been playing with.
It seems fairly stable
The code could be optimised a little, but I left it as was 'cause it was easier to test that way :)
Code: [Select]

// CodeHimBelonga kdub@theSwamp 20100922
// Updated 20110312
// Updated 20110313 workaround for Import bug
//
using System;
using System.IO;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
//
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using AcUtils = Autodesk.AutoCAD.Internal.Utils;

[assembly: CommandClass(typeof(Ducks.MyCommands))]

namespace Ducks
{
    public class MyCommands
    {
        [CommandMethod("ImportDXF", (CommandFlags.Modal & CommandFlags.Session))]
        public void DucksIn_4()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            //------------------------------------------------------------------
            OpenFileDialog dialog = new OpenFileDialog {
                CheckFileExists = true,
                CheckPathExists = true,
                DefaultExt = "dxf",
                DereferenceLinks = true,
                Filter = "DXF Files (*.dxf)|*.dxf|All files (*.*)|*.*",
                Title = "Select dxf file"
            };
            if(dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                return;
            //------------------------------------------------------------------
            PromptPointResult ppr = ed.GetPoint("Insertion point");
            if(ppr.Status != PromptStatus.OK)
                return;
            //------------------------------------------------------------------
            PromptDoubleOptions pdo = new PromptDoubleOptions("Scale factor");
            pdo.AllowZero = false;
            pdo.AllowNone = false;
            pdo.DefaultValue = 1;
            PromptDoubleResult pdr = ed.GetDouble(pdo);
            if(pdr.Status != PromptStatus.OK)
                return;
            //------------------------------------------------------------------
            string fn = dialog.FileName;
            Point3d toPoint = ppr.Value;           
            double insScale = pdr.Value;

            ObjectId lastEnt = AcUtils.EntLast();

            double[] baseArray = Point3d.Origin.ToArray();
            AcadDocument comDoc = (Autodesk.AutoCAD.Interop.AcadDocument) doc.AcadDocument;
            comDoc.Import(fn, (object)baseArray, insScale);
            //------------------------------------------------------------------

            ObjectIdCollection idColl = new ObjectIdCollection();

            using (Transaction tr = doc.TransactionManager.StartTransaction())
                {
                // if the db is empty lastent will be null               
                    if(lastEnt == ObjectId.Null) {
                        lastEnt = AcUtils.EntFirst();
                        idColl.Add(lastEnt);
                    }
                    ObjectId nextent = AcUtils.EntNext(lastEnt);
                    while(nextent != ObjectId.Null)
                    {
                        idColl.Add(nextent);
                        nextent = AcUtils.EntNext(nextent);
                    }
                    Vector3d vector = (Vector3d)(toPoint - Point3d.Origin);
                    Matrix3d transform = Matrix3d.Displacement(vector);
                    foreach(ObjectId id in idColl)
                    {
                        ((Entity)tr.GetObject(id, OpenMode.ForWrite, true)).TransformBy(transform);
                    }
                    tr.Commit();
                }
        }
    }
}

Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 13, 2011, 09:38:53 AM
Rather amusing.
I just finished posting the code and looked at it in the forum code pane

... realised it will go spacoid if the UCS is other than world ... so need to run a UCS2WCS translation on the Selected Point.

Something to play with tomorrow :)


added :
kaefer,
Just tried to read your code ... realised I shall need to spend some time learning to read F# :)
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 13, 2011, 11:48:24 AM
Rather amusing.
I just finished posting the code and looked at it in the forum code pane

... realised it will go spacoid if the UCS is other than world ... so need to run a UCS2WCS translation on the Selected Point.

The benign case is always to simply ignore the UCS settings. Let the user figure out the damn transformation.

Quote
... realised I shall need to spend some time learning to read F#

Shan't. My humble C# version (equally UCS unaware) is here. BTW, what do y'all think about object initializers?
Code: [Select]
    public class MyDxfInCmdClass
    {
        IList<ObjectId> objs;

        [CommandMethod("MyDxfIn")]
        public void MyDxfInCmd()
        {
            objs = new List<ObjectId>();
            Document doc = AcApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            var dialog = new System.Windows.Forms.OpenFileDialog
            {
                CheckFileExists = true,
                CheckPathExists = true,
                DefaultExt = "dxf",
                DereferenceLinks = true,
                Filter = "DXF Files (*.dxf)|*.dxf|All files (*.*)|*.*" ,
                Title = "Select dxf file"
            };
            if(dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                return;
            var ppr = ed.GetPoint("Insertion point");
            if(ppr.Status != PromptStatus.OK)
                return;
            var pda = new PromptAngleOptions("Rotation")
            {
                BasePoint = ppr.Value,
                DefaultValue = 0.0,
                UseAngleBase = true
            };
            var par = ed.GetAngle(pda);
            if(par.Status != PromptStatus.OK)
                return;
            var pdo = new PromptDoubleOptions("Scale factor")
            {
                AllowZero = false,
                AllowNone = false,
                DefaultValue = 1.0
            };
            var pdr = ed.GetDouble(pdo);
            if(pdr.Status != PromptStatus.OK)
                return;
            db.ObjectAppended += new ObjectEventHandler(ObjectAppended);
            try
            {
                Invoke(doc.AcadDocument, "Import", dialog.FileName, ppr.Value.ToArray(), pdr.Value);
            }
            finally
            {
                db.ObjectAppended -= new ObjectEventHandler(ObjectAppended);
            }
            var mat = Matrix3d.Scaling(pdr.Value, Point3d.Origin) *
                Matrix3d.Rotation(par.Value, Vector3d.ZAxis, Point3d.Origin) *
                Matrix3d.Displacement(ppr.Value - Point3d.Origin);
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                foreach (ObjectId oid in objs)
                    ((Entity)tr.GetObject(oid, OpenMode.ForWrite)).TransformBy(mat);
                tr.Commit();
            }
            ObjectId[] ids = new ObjectId[objs.Count];
            objs.CopyTo(ids, 0);
            ed.SetImpliedSelection(ids);
        }
        void ObjectAppended(object sender, ObjectEventArgs e)
        {
            objs.Add(e.DBObject.ObjectId);
        }
        static object Invoke(object o, string name, params object[] args)
        {
            return o.GetType().InvokeMember(name, System.Reflection.BindingFlags.InvokeMethod, null, o, args);
        }
    }
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 14, 2011, 04:08:50 AM
Something to play with :

Accounts Co-ordinate System other than WCS for insertion Point.

Code: [Select]

// CodeHimBelonga kdub@theSwamp 20100922
// Updated 20110312
// Updated 20110313 workaround for Import bug
// Updated 20110314 translate UCS to WCS for move.
//
using System;
using System.IO;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
//
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using AcUtils = Autodesk.AutoCAD.Internal.Utils;

[assembly: CommandClass(typeof(Ducks.MyCommands))]

namespace Ducks
{
    public class MyCommands
    {
        [CommandMethod("ImportDXF", CommandFlags.Session)]
        public void DucksIn_5()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            //------------------------------------------------------------------
            OpenFileDialog dialog = new OpenFileDialog {
                CheckFileExists = true,
                CheckPathExists = true,
                DefaultExt = "dxf",
                DereferenceLinks = true,
                Filter = "DXF Files (*.dxf)|*.dxf|All files (*.*)|*.*",
                Title = "Select dxf file"
            };
            if(dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                return;
            //------------------------------------------------------------------
            PromptPointResult ppr = ed.GetPoint("Insertion point");
            if(ppr.Status != PromptStatus.OK)
                return;
            //------------------------------------------------------------------
            PromptDoubleOptions pdo = new PromptDoubleOptions("Scale factor");
            pdo.AllowZero = false;
            pdo.AllowNone = false;
            pdo.DefaultValue = 1;
            PromptDoubleResult pdr = ed.GetDouble(pdo);
            if(pdr.Status != PromptStatus.OK)
                return;
            //------------------------------------------------------------------
            string fn = dialog.FileName;
            double insScale = pdr.Value;

            ObjectId lastEnt = AcUtils.EntLast();

            double[] baseArray = Point3d.Origin.ToArray();

            AcadDocument comDoc = (Autodesk.AutoCAD.Interop.AcadDocument)doc.AcadDocument;
            comDoc.Import(fn, (object)baseArray, insScale);
            //------------------------------------------------------------------
            ObjectIdCollection idColl = new ObjectIdCollection();

            using(Transaction tr = doc.TransactionManager.StartTransaction()) {
                // if the db is empty lastent will be null                
                if(lastEnt == ObjectId.Null) {
                    lastEnt = AcUtils.EntFirst();
                    idColl.Add(lastEnt);
                }
                ObjectId nextent = AcUtils.EntNext(lastEnt);
                while(nextent != ObjectId.Null) {
                    idColl.Add(nextent);
                    nextent = AcUtils.EntNext(nextent);
                }

                Matrix3d transform = Matrix3d.Displacement(ppr.Value.UcsToWcs().GetAsVector());
                foreach(ObjectId id in idColl) {
                    ((Entity)tr.GetObject(id, OpenMode.ForWrite, true)).TransformBy(transform);
                }
                tr.Commit();
            }
        }
    }
    public static partial class Stuff
    {
        // CodeHimBelongaKwb ©  Feb 2008
        // transposed from MgdDbg by JIM AWE.
        //------------------------------------------------------------------
        // predefined values for common Points and Vectors
        public static readonly Point3d kOrigin = new Point3d(0.0, 0.0, 0.0);
        public static readonly Vector3d kXAxis = new Vector3d(1.0, 0.0, 0.0);
        public static readonly Vector3d kYAxis = new Vector3d(0.0, 1.0, 0.0);
        public static readonly Vector3d kZAxis = new Vector3d(0.0, 0.0, 1.0);
        //------------------------------------------------------------------
        /// <summary>
        /// shortcut for getting the current DWG's database
        /// </summary>
        /// <returns>Database for the current drawing</returns>
        public static Database  GetCurDwg()
        {
            Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
            return db;
        }
        //------------------------------------------------------------------
        /// <summary>
        /// Get a transformed copy of a point from UCS to WCS
        /// </summary>
        /// <param name="pt">Point to transform</param>
        /// <returns>Transformed copy of point</returns>
        
        public static Point3d   UcsToWcs(this Point3d pt)
        {
            Matrix3d m = GetUcsMatrix(GetCurDwg());
            
            return pt.TransformBy(m);
        }            
        //------------------------------------------------------------------
/// <summary>
/// Is Paper Space active in the given database?
/// </summary>
/// <param name="db">Specific database to use</param>
/// <returns></returns>
public static bool IsPaperSpace(this Database db)
{
   System.Diagnostics.Debug.Assert(db != null);    
   if (db.TileMode)
       return false;
   
   Editor ed =  Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            if (db.PaperSpaceVportId == ed.CurrentViewportObjectId)
       return true;
       
   return false;
}
        //------------------------------------------------------------------
        /// <summary>
        /// Figure out the current UCS matrix for the given database.  If
        /// PaperSpace is active, it will return the UCS for PaperSpace.
        /// Otherwise, it will return the UCS for the current viewport in
        /// ModelSpace.
        /// </summary>
        /// <param name="db">Specific database to use</param>
        /// <returns>UCS Matrix for the specified database</returns>

        public static Matrix3d  GetUcsMatrix(Database db)
        {
            System.Diagnostics.Debug.Assert(db != null);

            Point3d origin;
            Vector3d xAxis, yAxis, zAxis;

            if(db.IsPaperSpace()) {
                origin = db.Pucsorg;
                xAxis = db.Pucsxdir;
                yAxis = db.Pucsydir;
            } else {
                origin = db.Ucsorg;
                xAxis = db.Ucsxdir;
                yAxis = db.Ucsydir;
            }
            zAxis = xAxis.CrossProduct(yAxis);
            return Matrix3d.AlignCoordinateSystem(kOrigin, kXAxis, kYAxis, kZAxis, origin, xAxis, yAxis, zAxis);
        }
        //------------------------------------------------------------------

    }
}
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 14, 2011, 08:34:08 AM
Has anybody tried:

1. New 'side database'
2. DxfIn method on new 'side database' to insert dxf file into new pristine database
3. insert the new 'side database' with dxf info into current drawing

Yep, that works too. Incoming dialog.FileName, ppr.Value, par.Value, pdr.Value and then...
Code: [Select]
                    let mat =
                        Matrix3d.Scaling(pdr.Value, Point3d.Origin) *
                        Matrix3d.Rotation(par.Value, Vector3d.ZAxis, Point3d.Origin) *
                        Matrix3d.Displacement(ppr.Value - Point3d.Origin)
                   
                    use srcDb = new Database(false, true)
                    let tmpFileName = System.IO.Path.GetTempFileName()
                    srcDb.DxfIn(dialog.FileName, tmpFileName)
                    let srcMSpaceId = SymbolUtilityServices.GetBlockModelSpaceId srcDb

                    // Build ObjectIdCollection from objects to clone in source model space
                    use str = srcDb.TransactionManager.StartTransaction()
                    let sbtr = str.GetObject(srcMSpaceId, OpenMode.ForRead) :?> BlockTableRecord
                    let objIdColl = new ObjectIdCollection(sbtr |> Seq.cast |> Array.ofSeq)
                    str.Commit()

                    let map = new IdMapping()
                    db.WblockCloneObjects(objIdColl, db.CurrentSpaceId, map, DuplicateRecordCloning.Ignore, false)
               
                    // Sequence of ObjectIds in target database
                    let targetIds =
                         map
                         |> Seq.cast<IdPair>
                         |> Seq.choose
                            (fun pair ->
                                if pair.IsPrimary && pair.IsCloned then Some pair.Value else None
                            )
                   
                    // Transform objects in target current space
                    use tr = db.TransactionManager.StartTransaction()
                    for oid in targetIds do
                        (tr.GetObject(oid, OpenMode.ForWrite) :?> Entity).TransformBy mat
                    tr.Commit()

                    targetIds |> Array.ofSeq |> ed.SetImpliedSelection

Alas, the second DxfIn parameter logFilename is of little use, and it seems to stay open as long as the drawing session lasts.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Glenn R on March 14, 2011, 09:58:08 AM
Isn't there a Database.Insert method that will accept your newly created dbase, rather than going through the whole cloning exercise? That's if I'm deciphering F#; wouldn't surprise me if I'm not as I don't do F#....
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 14, 2011, 10:53:25 AM
Isn't there a Databse.Insert method that will accept your newly created dbase,

Oh, my... of course there is!  The only trick that seems to be required is that the target model space should be opened for write.

Code: [Select]
                    ...
                    let mat =
                        Matrix3d.Scaling(pdr.Value, Point3d.Origin) *
                        Matrix3d.Rotation(par.Value, Vector3d.ZAxis, Point3d.Origin) *
                        Matrix3d.Displacement(ppr.Value - Point3d.Origin)
                   
                    use srcDb = new Database(false, false)
                    let tmpFileName = System.IO.Path.GetTempFileName()
                    srcDb.DxfIn(dialog.FileName, tmpFileName)
                    use tr = db.TransactionManager.StartTransaction()
                    tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId db, OpenMode.ForWrite) |> ignore
                    db.Insert(mat, srcDb, false) |> ignore
                    tr.Commit()

Quote
rather than going through the whole cloning exercise? That's if I'm deciphering F#; wouldn't surprise me if I'm not as I don't do F#....

That was exactly what I was trying accomplish. Doing OOP in F# is almost like C# without the nipple braces.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Jeff H on March 14, 2011, 11:09:02 PM
That was exactly what I was trying accomplish. Doing OOP in F# is almost like C# without the nipple braces.
:lmao: :lmao:
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 15, 2011, 07:54:56 AM
Something to play with :

Accounts Co-ordinate System other than WCS for insertion Point.

Thanks, Kerry.

May I borrow the GetUcsMatrix method as an extension property of Database?

Trying to wrap the whole thing up:

1. I think I'll stick with the WblockCloneObjects approach since it obviates collecting the objects manually, and it allows dumping them into current space.
2. It seems to be possible passing null as second parameter to Database.DxfIn. DXF import errors will cause exceptions, that's enough for error handling.
3. Just multiplicating the db.GetUcsMatrix return value with the transform generated out of insertion point, rotation and scaling arguments brings me UCS awareness.

For reference, the final F# code is appended.

Big thanks to all, Thorsten



Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 15, 2011, 08:50:45 AM
< .. >
May I borrow the GetUcsMatrix method as an extension property of Database?

< .. >

sure

MgdDbg originally by Jim Awe from AutoDesk

This is the 2010 Version
http://through-the-interface.typepad.com/through_the_interface/2010/02/the-stephen-and-fenton-show-adn-devcast-episode-1.html
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 16, 2011, 08:21:00 PM

Just to clarify the usage of GetUcsMatrix() as an extension method.
( for those following and in answer to PM mail)

If the GetUcsMatrix() is modified as follows by adding the this qualifier to the parameter list
( note that the fromOrigin, fromXAxis, fromYAxis, fromZAxis,  have also been modified to use a local definition
rather than  the public static readonly vars used previously, for the sake of simplicity.)

Code: [Select]
        //------------------------------------------------------------------
        /// <summary>
        /// Figure out the current UCS matrix for the given database.  If
        /// PaperSpace is active, it will return the UCS for PaperSpace.
        /// Otherwise, it will return the UCS for the current viewport in
        /// ModelSpace.
        /// </summary>
        /// <param name="db">Specific database to use</param>
        /// <returns>UCS Matrix for the specified database</returns>

        public static Matrix3d  GetUcsMatrix(this Database db)
        {
            System.Diagnostics.Debug.Assert(db != null);

            Point3d toOrigin;
            Vector3d toXAxis, toYAxis, toZAxis;

            if(db.IsPaperSpace()) {
                toOrigin = db.Pucsorg;
                toXAxis = db.Pucsxdir;
                toYAxis = db.Pucsydir;
            } else {
                toOrigin = db.Ucsorg;
                toXAxis = db.Ucsxdir;
                toYAxis = db.Ucsydir;
            }
            toZAxis = toXAxis.CrossProduct(toYAxis);
            return Matrix3d.AlignCoordinateSystem(
                Point3d.Origin,
                Vector3d.XAxis,
                Vector3d.YAxis,
                Vector3d.ZAxis,
                toOrigin, toXAxis, toYAxis, toZAxis);
        }
        //------------------------------------------------------------------


The method can then be called by either :
Code: [Select]
Matrix3d m = GetUcsMatrix(GetCurDwg() );

Matrix3d m = GetUcsMatrix(db);

Matrix3d m = (GetCurDwg().GetUcsMatrix() );

Matrix3d m = (db.GetUcsMatrix() );
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 16, 2011, 08:25:29 PM
< .. >
I'll do some more testing and report it to the ADN.


The Issue has a change request number allocated but don't expect any action soon unless someone can
Quote
provide a strong business case in order to increase the priority of a fix.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 17, 2011, 10:08:54 AM
Database.DxfIn
I'm blind as well as stupid !!
Thanks Philippe at ADN.

Code: [Select]

        [CommandMethod("netInsertDxf")]

        static public void netInsertDxf()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            Database TmpDb = new Database(false, true);

            TmpDb.DxfIn("K:\\ToTest\\Squircle.dxf", "K:\\ToTest\\Squircle.log");

            Matrix3d Transform = Matrix3d.Identity;
            db.Insert(Transform, TmpDb, true);
        }

and I just noticed that kaefer was using it in Post Reply #24
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Glenn R on March 17, 2011, 12:14:08 PM
...at my suggestion from post reply #14
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 17, 2011, 02:49:58 PM
...at my suggestion from post reply #14

Glenn,
At the time I read that as  “AcadDocument.Import” method on the DXF file into a side db. ... which I know does work.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Glenn R on March 17, 2011, 04:45:48 PM
Apologies Kerry - I just re-read what I posted and it might have come across as a bit...terse - not my intention. Also, I wouldn't suggest the use of that...nasty COM stuff :evil:, unless absolutely necessary  :-D
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 17, 2011, 05:07:15 PM


No pain for me ... except that I completely missed the reference ... that's just embarrassing  :oops:
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 22, 2011, 05:40:01 AM
I have tried some things with importing dxf files but I cannot continue. There is not many information about this subject to find.

This is the code till now (thanks to Kerry):

Code: [Select]
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry

Public Class clsImportDXF

  <CommandMethod("InsertDxf")> _
  Public Sub InsertDxf()
    Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
    Dim db As Database = doc.Database
    Dim ed As Editor = doc.Editor
    Dim TmpDb As Database = New Database(False, True)
    TmpDb.DxfIn("G:\\test.dxf", "G:\\test.log")
    Dim pnt1 As New Point3d(0, 0, 0)
    Dim pnt2 As New Point3d(1000, 1000, 0)

    Dim Transform As Matrix3d = Matrix3d.Displacement(pnt1.GetVectorTo(pnt2))

    db.Insert(Transform, TmpDb, True)
  End Sub

End Class

This code does insert a dxf and moves it to a new location. But I also want to scale all entities. How can I add a scale in this code? Can I extend Transform with a Scale?

Further I want to select all entities from the dxf and place them on another layer. How do I select all entities?
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 22, 2011, 05:58:03 AM
If I combine Matrix3D options, then they are ignored:

Code: [Select]
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry

Public Class clsImportDXF

  <CommandMethod("InsertDxf")> _
  Public Sub InsertDxf()
    Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
    Dim db As Database = doc.Database
    Dim ed As Editor = doc.Editor
    Dim TmpDb As Database = New Database(False, True)
    TmpDb.DxfIn("G:\\test.dxf", "G:\\test.log")
    Dim pnt1 As New Point3d(0, 0, 0)
    Dim pnt2 As New Point3d(1000, 1000, 0)
    Dim scale As Double = 10

    Dim Transform As New Matrix3d
    Transform = Matrix3d.Scaling(scale, pnt1)
    Transform = Matrix3d.Displacement(pnt1.GetVectorTo(pnt2))

    db.Insert(Transform, TmpDb, True)
  End Sub

End Class
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 22, 2011, 06:26:00 AM
I think you will need to Multiply the matrix's together ...

WAG

               Dim Transform As New Matrix3d
                Transform = Matrix3d.Scaling(scale, pnt1) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2))

added :
This works in C# anyway :)
Code: [Select]
            Matrix3d Transform = Matrix3d.Identity;
            Transform = Transform * Matrix3d.Scaling(5.0, Point3d.Origin);
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 22, 2011, 06:39:48 AM
Cool! I didn't know that this was possible :-) How is this method called?

I have now:

Code: [Select]
    Dim Transform As New Matrix3d
    Transform = Matrix3d.Scaling(scale, pnt2) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2))

I had to use the displacement point as scale location (pnt2) instead of the origin.



Btw, how do I get all placed entities so I can change the objects layer? Or should I iterate all objects in the TmpDB first?
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 22, 2011, 06:53:51 AM
Btw, how do I get all placed entities so I can change the objects layer? Or should I iterate all objects in the TmpDB first?

You could read further upthread:
ObjectAppended event approach http://www.theswamp.org/index.php?topic=37409.msg424558#msg424558 (http://www.theswamp.org/index.php?topic=37409.msg424558#msg424558)
EntLast()/EntNext() approach http://www.theswamp.org/index.php?topic=37409.msg424652#msg424652 (http://www.theswamp.org/index.php?topic=37409.msg424652#msg424652)
WblockCloneObjects approach http://www.theswamp.org/index.php?topic=37409.msg424709#msg424709 (http://www.theswamp.org/index.php?topic=37409.msg424709#msg424709)

Have fun
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 22, 2011, 07:34:25 AM
Btw, how do I get all placed entities so I can change the objects layer? Or should I iterate all objects in the TmpDB first?

You could read further upthread:
ObjectAppended event approach http://www.theswamp.org/index.php?topic=37409.msg424558#msg424558 (http://www.theswamp.org/index.php?topic=37409.msg424558#msg424558)
EntLast()/EntNext() approach http://www.theswamp.org/index.php?topic=37409.msg424652#msg424652 (http://www.theswamp.org/index.php?topic=37409.msg424652#msg424652)
WblockCloneObjects approach http://www.theswamp.org/index.php?topic=37409.msg424709#msg424709 (http://www.theswamp.org/index.php?topic=37409.msg424709#msg424709)

Have fun


Thanks! How did I overlook this... :-)

Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 27, 2011, 06:35:00 AM
Uhmm, weird... I have the following code:

Code: [Select]
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports AcUtils = Autodesk.AutoCAD.Internal.Utils

Public Class clsImportDXF

  <CommandMethod("InsertDxf")> _
  Public Sub InsertDxf()
    Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
    Dim db As Database = doc.Database
    Dim ed As Editor = doc.Editor
    Dim TmpDb As Database = New Database(False, True)
    TmpDb.DxfIn("G:\\test.dxf", IO.Path.GetTempFileName)

    Dim pnt1 As New Point3d(0, 0, 0)
    Dim pnt2 As New Point3d(1000, 1000, 0)
    Dim scale As Double = 10
    Dim vector As New Vector3d(0, 0, 0)

    Dim Transform As New Matrix3d
    Transform = Matrix3d.Scaling(scale, pnt2) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2))

    db.Insert(Transform, TmpDb, True)


' Change object color -----------------------------
    Dim lastEnt As ObjectId = AcUtils.EntLast()
    Dim idColl As New ObjectIdCollection()

    Using tr As Transaction = doc.TransactionManager.StartTransaction()
      If lastEnt = ObjectId.Null Then
        lastEnt = AcUtils.EntFirst()
        idColl.Add(lastEnt)
      End If
      Dim nextent As ObjectId = AcUtils.EntNext(lastEnt)
      While nextent <> ObjectId.Null
        idColl.Add(nextent)
        nextent = AcUtils.EntNext(nextent)
      End While
      For Each id As ObjectId In idColl
        Dim acEntity As Entity = TryCast(tr.GetObject(id, OpenMode.ForWrite), Entity)
        acEntity.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1)
      Next
      tr.Commit()
    End Using

  End Sub

After inserting the dxf I try to change the color of the objects. While debugging it loops through all the inserted elements but it does not change the color. I get this error while debugging:

"Cannot evaluate expression because we are stopped in a place where garbage collection is impossible, possibly because the code of the current method may be optimized."

 :?
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 27, 2011, 09:39:41 AM
Code: [Select]
    db.Insert(Transform, TmpDb, True)


' Change object color -----------------------------
    Dim lastEnt As ObjectId = AcUtils.EntLast()

After inserting the dxf I try to change the color of the objects. While debugging it loops through all the inserted elements but it does not change the color. I get this error while debugging:
Can't help you there, but aren't you supposed to to get the last entity before the insert operation? That is, switch the order of the two statements quoted.

Another optimization may be using the ColorIndex method...
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 27, 2011, 02:15:42 PM
..
Can't help you there, but aren't you supposed to to get the last entity before the insert operation? That is, switch the order of the two statements quoted.

Another optimization may be using the ColorIndex method...

I assume the last entity is what I'v just inserted. While debugging it loops through all the inserted objects but I can't change color or layer or any other property. So getting the inserted items as last entity is correct, but why can't I access them?
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Jeff H on March 27, 2011, 03:47:50 PM
Hey Huiz, I tested your code real quik and here is what I noticed

Using a new drawing(empty drawing)

This would get the last entity added from 'DxfInsert' called
Code: [Select]
            ' Change object color -----------------------------
            Dim lastEnt As ObjectId = AcUtils.EntLast()


Then this would make it null
Code: [Select]
Dim nextent As ObjectId = AcUtils.EntNext(lastEnt)
so this is never called
Code: [Select]
                    Dim acEntity As Entity = TryCast(tr.GetObject(id, OpenMode.ForWrite), Entity)
                    acEntity.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1)

To get it to work

Using a new drawing(empty drawing) and removing the if statement
Code: [Select]
                If lastEnt = ObjectId.Null Then
                    lastEnt = AcUtils.EntFirst()
                    idColl.Add(lastEnt)
                End If
changed to
Code: [Select]
                lastEnt = AcUtils.EntFirst()
                idColl.Add(lastEnt)

Now lastEnt  is the ObjectId of the first entity added from calling 'DxfInset' of course with a empty drawing
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Jeff H on March 27, 2011, 03:57:22 PM
Or better yet to work on empty and non-empty drawings

Leave the if statement  and move
Code: [Select]
       Dim lastEnt As ObjectId = AcUtils.EntLast()
up to the top of your code
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Jeff H on March 27, 2011, 04:50:49 PM
I was also making a assumption in last post about EntFirst()

I am not fimilar with Lisp and do not know if EntFirst() acts just like Lisp version, but

does EntFirst() get first entity added to Database in the current Session?
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 28, 2011, 03:08:55 AM
I was also making a assumption in last post about EntFirst()

I am not fimilar with Lisp and do not know if EntFirst() acts just like Lisp version, but

does EntFirst() get first entity added to Database in the current Session?


I think so because while debugging it loops through all the new inserted objects.

Thanks Jeff for your answers, I'll have a test this evening when I'm home.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 28, 2011, 05:04:22 AM
A couple of options to play with ...
"InsDXF7"  Collect the  imported entitys then itterate the collection to change Color
"InsDXF8"  Change Color While iterating the imported entitys .. no collection
"InsDXF9"  Change Color in the temporary Side DataBase
Code: [Select]

        [CommandMethod("InsDXF7")]
        public void InsDXF7()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            Database tmpDb = new Database(false, true);

            tmpDb.DxfIn("K:\\ToTest\\Squircle.dxf", "K:\\ToTest\\Squircle.log");
            Point3d pnt1 = new Point3d(0, 0, 0);
            Point3d pnt2 = new Point3d(1000, 1000, 0);
            double scale = 10.0;
            Vector3d vector = new Vector3d(0, 0, 0);

            Matrix3d transform = Matrix3d.Scaling(scale, pnt2) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2));
            ObjectId lastEnt = AcUtils.EntLast();
            Autodesk.AutoCAD.Colors.Color newColor = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1);
            //
            db.Insert(transform, tmpDb, true);
            //
            using( Transaction tr = doc.TransactionManager.StartTransaction() ) {
                // if the db was empty lastent will be null        
                try {
                    if( lastEnt == ObjectId.Null ) {
                        lastEnt = AcUtils.EntFirst();
                        idColl.Add(lastEnt);
                    }
                    ObjectId nextent = AcUtils.EntNext(lastEnt);
                    while( nextent != ObjectId.Null ) {
                        idColl.Add(nextent);
                        nextent = AcUtils.EntNext(nextent);
                    }

                    foreach( ObjectId id in idColl ) {
                        Entity acEntity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                        acEntity.Color = newColor;
                    }
                } catch( Autodesk.AutoCAD.Runtime.Exception exx ) {
                    ed.WriteMessage("\n" + exx.ToString());
                }
                tr.Commit();
            }
        }

Code: [Select]

        [CommandMethod("InsDXF8")]
        public void InsDXF8()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            Database tmpDb = new Database(false, true);

            tmpDb.DxfIn("K:\\ToTest\\Squircle.dxf", "K:\\ToTest\\Squircle.log");
            Point3d pnt1 = new Point3d(0, 0, 0);
            Point3d pnt2 = new Point3d(1000, 1000, 0);
            double scale = 10.0;
            Vector3d vector = new Vector3d(0, 0, 0);

            Matrix3d transform = Matrix3d.Scaling(scale, pnt2) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2));
            ObjectIdCollection idColl = new ObjectIdCollection();
            ObjectId lastEnt = AcUtils.EntLast();
            Entity acEntity;
            Autodesk.AutoCAD.Colors.Color newColor = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1);
            //
            db.Insert(transform, tmpDb, true);
            //
            using( Transaction tr = doc.TransactionManager.StartTransaction() ) {
                // if the db was empty lastent will be null  
                try {
                    if( lastEnt == ObjectId.Null ) {
                        lastEnt = AcUtils.EntFirst();
                        acEntity = (Entity)tr.GetObject(lastEnt, OpenMode.ForWrite);
                        acEntity.Color = newColor;
                    }
                    ObjectId nextent = AcUtils.EntNext(lastEnt);

                    while( nextent != ObjectId.Null ) {
                        acEntity = (Entity)tr.GetObject(nextent, OpenMode.ForWrite);
                        acEntity.Color = newColor;
                        nextent = AcUtils.EntNext(nextent);
                    }
                } catch( Autodesk.AutoCAD.Runtime.Exception exx ) {
                    ed.WriteMessage("\n" + exx.ToString());
                }
                tr.Commit();
            }
        }

Code: [Select]

        [CommandMethod("InsDXF9")]
        public void InsDXF9()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            Database tmpDb = new Database(false, true);

            tmpDb.DxfIn("K:\\ToTest\\Squircle.dxf", "K:\\ToTest\\Squircle.log");
            Point3d pnt1 = new Point3d(0, 0, 0);
            Point3d pnt2 = new Point3d(1000, 1000, 0);
            double scale = 10.0;
            Vector3d vector = new Vector3d(0, 0, 0);

            Matrix3d transform = Matrix3d.Scaling(scale, pnt2) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2));
            ObjectIdCollection idColl = new ObjectIdCollection();
            Entity acEntity;
            Autodesk.AutoCAD.Colors.Color newColor = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1);
            //
            using( Transaction tr = tmpDb.TransactionManager.StartTransaction() ) {
                try {
                    BlockTable tmpDbBlockTable = (BlockTable)
                     tr.GetObject(tmpDb.BlockTableId, OpenMode.ForRead);
                    BlockTableRecord tmpDbModelSpace = (BlockTableRecord)
                            tr.GetObject(tmpDbBlockTable[ BlockTableRecord.ModelSpace ], OpenMode.ForWrite);

                    foreach( ObjectId id in tmpDbModelSpace ) {
                        acEntity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                        acEntity.Color = newColor;
                    }
                    tr.Commit();
                } catch( Autodesk.AutoCAD.Runtime.Exception exx ) {
                    ed.WriteMessage("\n" + exx.ToString());
                }
            }
            //
            db.Insert(transform, tmpDb, true);

        }
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 28, 2011, 02:32:32 PM
Thanks Kerry for your code!  :-)  I've tried all three and I only have success if I change the objects in the temporary database, before inserting in the current drawing. I'm not sure what is wrong with the other examples, I've read the instructions of Jeff but the code does not do anything. I don't get errors, there are no exceptions, and while debugging it seems the objects are there, but not available.

But the last example does work very well and the options are endless now to alter the objects before inserting! Thanks!!!  :-)
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 28, 2011, 03:07:47 PM

huiz,

I probably don't need to say this, but .. the 3 examples work for me in c# from vs2010Pro into AC2011.

I'd guess that your translation may be skewey.

Can you post the VB.net code you used for each or post he solution zipped so I can test it here.
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 29, 2011, 02:29:24 AM
I thought they did work in C# but unfortunately not in vb. Here are the examples in vb:

Code: [Select]
<CommandMethod("InsDXF7")> _
Public Sub InsDXF7()
Dim doc As Document = AcadApp.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Dim tmpDb As New Database(False, True)

tmpDb.DxfIn("K:\ToTest\Squircle.dxf", "K:\ToTest\Squircle.log")
Dim pnt1 As New Point3d(0, 0, 0)
Dim pnt2 As New Point3d(1000, 1000, 0)
Dim scale As Double = 10.0
Dim vector As New Vector3d(0, 0, 0)

Dim transform As Matrix3d = Matrix3d.Scaling(scale, pnt2) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2))
Dim lastEnt As ObjectId = AcUtils.EntLast()
Dim newColor As Autodesk.AutoCAD.Colors.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1)

db.Insert(transform, tmpDb, True)

Using tr As Transaction = doc.TransactionManager.StartTransaction()
' if the db was empty lastent will be null       
Try
If lastEnt = ObjectId.Null Then
lastEnt = AcUtils.EntFirst()
idColl.Add(lastEnt)
End If
Dim nextent As ObjectId = AcUtils.EntNext(lastEnt)
While nextent <> ObjectId.Null
idColl.Add(nextent)
nextent = AcUtils.EntNext(nextent)
End While

For Each id As ObjectId In idColl
Dim acEntity As Entity = DirectCast(tr.GetObject(id, OpenMode.ForWrite), Entity)
acEntity.Color = newColor
Next
Catch exx As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & exx.ToString())
End Try
tr.Commit()
End Using
End Sub

Code: [Select]
<CommandMethod("InsDXF8")> _
Public Sub InsDXF8()
Dim doc As Document = AcadApp.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Dim tmpDb As New Database(False, True)

tmpDb.DxfIn("K:\ToTest\Squircle.dxf", "K:\ToTest\Squircle.log")
Dim pnt1 As New Point3d(0, 0, 0)
Dim pnt2 As New Point3d(1000, 1000, 0)
Dim scale As Double = 10.0
Dim vector As New Vector3d(0, 0, 0)

Dim transform As Matrix3d = Matrix3d.Scaling(scale, pnt2) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2))
Dim idColl As New ObjectIdCollection()
Dim lastEnt As ObjectId = AcUtils.EntLast()
Dim acEntity As Entity
Dim newColor As Autodesk.AutoCAD.Colors.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1)

db.Insert(transform, tmpDb, True)

Using tr As Transaction = doc.TransactionManager.StartTransaction()
' if the db was empty lastent will be null   
Try
If lastEnt = ObjectId.Null Then
lastEnt = AcUtils.EntFirst()
acEntity = DirectCast(tr.GetObject(lastEnt, OpenMode.ForWrite), Entity)
acEntity.Color = newColor
End If
Dim nextent As ObjectId = AcUtils.EntNext(lastEnt)

While nextent <> ObjectId.Null
acEntity = DirectCast(tr.GetObject(nextent, OpenMode.ForWrite), Entity)
acEntity.Color = newColor
nextent = AcUtils.EntNext(nextent)
End While
Catch exx As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & exx.ToString())
End Try
tr.Commit()
End Using
End Sub

Code: [Select]
<CommandMethod("InsDXF9")> _
Public Sub InsDXF9()
Dim doc As Document = AcadApp.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Dim tmpDb As New Database(False, True)

tmpDb.DxfIn("K:\ToTest\Squircle.dxf", "K:\ToTest\Squircle.log")
Dim pnt1 As New Point3d(0, 0, 0)
Dim pnt2 As New Point3d(1000, 1000, 0)
Dim scale As Double = 10.0
Dim vector As New Vector3d(0, 0, 0)

Dim transform As Matrix3d = Matrix3d.Scaling(scale, pnt2) * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2))
Dim idColl As New ObjectIdCollection()
Dim acEntity As Entity
Dim newColor As Autodesk.AutoCAD.Colors.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 1)

Using tr As Transaction = tmpDb.TransactionManager.StartTransaction()
Try
Dim tmpDbBlockTable As BlockTable = DirectCast(tr.GetObject(tmpDb.BlockTableId, OpenMode.ForRead), BlockTable)
Dim tmpDbModelSpace As BlockTableRecord = DirectCast(tr.GetObject(tmpDbBlockTable(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)

For Each id As ObjectId In tmpDbModelSpace
acEntity = DirectCast(tr.GetObject(id, OpenMode.ForWrite), Entity)
acEntity.Color = newColor
Next
tr.Commit()
Catch exx As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & exx.ToString())
End Try
End Using

db.Insert(transform, tmpDb, True)

End Sub
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 29, 2011, 03:35:49 AM
Give these a run ...
(Code solution .ZIP attached)



Code: [Select]

Option Explicit On
Option Strict On

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput

Imports Autodesk.AutoCAD.Colors
Imports Utils = Autodesk.AutoCAD.Internal.Utils

<Assembly: CommandClass(GetType(InsertDXF.MyCommands))>

Namespace InsertDXF

    Public Class MyCommands


   '' < snip >

    End Class

End Namespace

Code: [Select]

        <CommandMethod("InsDXF7")> _
        Public Sub InsDXF7()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            Dim tmpDb As New Database(False, True)
            tmpDb.DxfIn("K:\\ToTest\\Squircle.dxf", "K:\ToTest\\Squircle.log")
            Dim pnt1 As New Point3d(0, 0, 0)
            Dim pnt2 As New Point3d(1000, 1000, 0)
            Dim scale As Double = 10
            Dim vector As New Vector3d(0, 0, 0)
            Dim transform As Matrix3d = (Matrix3d.Scaling(scale, pnt2) _
                                         * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2)))
            Dim idColl As New ObjectIdCollection
            Dim lastEnt As ObjectId = Utils.EntLast
            Dim newColor As Color = Color.FromColorIndex(ColorMethod.ByAci, 1)
            db.Insert(transform, tmpDb, True)
            Using tr As Transaction = doc.TransactionManager.StartTransaction
                Try
                    If (lastEnt = ObjectId.Null) Then
                        lastEnt = Utils.EntFirst
                        idColl.Add(lastEnt)
                    End If

                    Dim nextent As ObjectId = Utils.EntNext(lastEnt)
                    Do While (nextent <> ObjectId.Null)
                        idColl.Add(nextent)
                        nextent = Utils.EntNext(nextent)
                    Loop

                    Dim id As ObjectId
                    For Each id In idColl
                        Dim acEntity As Entity = DirectCast(tr.GetObject( _
                                id, OpenMode.ForWrite), Entity)
                        acEntity.Color = newColor
                    Next

                Catch exx As Autodesk.AutoCAD.Runtime.Exception
                    ed.WriteMessage((ChrW(10) & exx.ToString))
                End Try
                tr.Commit()
            End Using
        End Sub


Code: [Select]

        <CommandMethod("InsDXF8")> _
        Public Sub InsDXF8()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            Dim tmpDb As New Database(False, True)
            tmpDb.DxfIn("K:\\ToTest\\Squircle.dxf", "K:\\ToTest\\Squircle.log")
            Dim pnt1 As New Point3d(0, 0, 0)
            Dim pnt2 As New Point3d(1000, 1000, 0)
            Dim scale As Double = 10
            Dim vector As New Vector3d(0, 0, 0)
            Dim transform As Matrix3d = (Matrix3d.Scaling(scale, pnt2) _
                                         * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2)))
            Dim idColl As New ObjectIdCollection
            Dim lastEnt As ObjectId = Utils.EntLast
            Dim newColor As Color = Color.FromColorIndex(ColorMethod.ByAci, 1)
            db.Insert(transform, tmpDb, True)
            Using tr As Transaction = doc.TransactionManager.StartTransaction
                Try
                    Dim acEntity As Entity
                    If (lastEnt = ObjectId.Null) Then
                        lastEnt = Utils.EntFirst
                        acEntity = DirectCast(tr.GetObject( _
                                lastEnt, OpenMode.ForWrite), Entity)
                        acEntity.Color = newColor
                    End If

                    Dim nextent As ObjectId = Utils.EntNext(lastEnt)
                    Do While (nextent <> ObjectId.Null)
                        acEntity = DirectCast(tr.GetObject( _
                                nextent, OpenMode.ForWrite), Entity)
                        acEntity.Color = newColor
                        nextent = Utils.EntNext(nextent)
                    Loop
                Catch exx As Autodesk.AutoCAD.Runtime.Exception
                    ed.WriteMessage((ChrW(10) & exx.ToString))
                End Try
                tr.Commit()
            End Using
        End Sub

Code: [Select]

       <CommandMethod("InsDXF9")> _
        Public Sub InsDXF9()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            Dim tmpDb As New Database(False, True)
            tmpDb.DxfIn("K:\\ToTest\\Squircle.dxf", "K:\\ToTest\Squircle.log")
            Dim pnt1 As New Point3d(0, 0, 0)
            Dim pnt2 As New Point3d(1000, 1000, 0)
            Dim scale As Double = 10
            Dim vector As New Vector3d(0, 0, 0)
            Dim transform As Matrix3d = (Matrix3d.Scaling(scale, pnt2) _
                                         * Matrix3d.Displacement(pnt1.GetVectorTo(pnt2)))
            Dim newColor As Color = Color.FromColorIndex(ColorMethod.ByAci, 1)
            Dim tr As Transaction = tmpDb.TransactionManager.StartTransaction
            Try
                Dim tmpDbBlockTable As BlockTable = DirectCast(tr.GetObject( _
                        tmpDb.BlockTableId, OpenMode.ForRead), BlockTable)
                Dim tmpDbModelSpace As BlockTableRecord = DirectCast(tr.GetObject( _
                        tmpDbBlockTable.Item(BlockTableRecord.ModelSpace), _
                        OpenMode.ForWrite), BlockTableRecord)

                Dim id As ObjectId
                For Each id In tmpDbModelSpace
                    Dim acEntity As Entity = DirectCast(tr.GetObject( _
                            id, OpenMode.ForWrite), Entity)
                    acEntity.Color = newColor
                Next

                tr.Commit()
            Catch exx As Autodesk.AutoCAD.Runtime.Exception
                ed.WriteMessage((ChrW(10) & exx.ToString))
            Finally
                If (Not tr Is Nothing) Then
                    tr.Dispose()
                End If
            End Try
            db.Insert(transform, tmpDb, True)
        End Sub
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: kaefer on March 29, 2011, 04:18:43 AM
Code: [Select]
Option Explicit On
Option Strict On

Does the culprit sit right here? 

Cheers, Thorsten (missing bargepole, won't do VB)
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: Kerry on March 29, 2011, 04:23:53 AM
Code: [Select]
Option Explicit On
Option Strict On

Does the culprit sit right here? 

Cheers, Thorsten (missing bargepole, won't do VB)

Don't know Thorsten, but it didn't seen correct to me to code with them off .... but that's probably just me :)

I've decided I need to at least be able to read VB and write a little ... as much as I hate the Dim word  :-P
Title: Re: Using VB.Net to Import/Insert a DXF File in Existing Drawing
Post by: huiz on March 29, 2011, 02:53:37 PM
[..]
I've decided I need to at least be able to read VB and write a little ... as much as I hate the Dim word  :-P

All three procedures do work now Kerry. I'll have a closer look what made the difference, as curious as I am. Btw, I've checked the time they need and changing the objects in the temp database is much faster. About half of the time the others need. So I stick with the last piece of code :-)

Btw, I am able to read C# but can't write it, though I don't have trouble with PHP.  Thanks again for your help :-)