Code Red > .NET

Bricscad: Help with WBlockCloneObjects

(1/1)

Keith Brown:
I have some code that I am trying to port over to Bricscad.  The code is supposed to create a new drawing and then xref the current drawing into it.  It will copy some views from the current drawing into the new drawing and then save and exit the new drawing.  The code that I have is working just fine in AutoCAD but when I run it in Bricscad it gives me the dreaded EInvalidOwnerObject when i use the WBlockCloneObject command.


Here is the stripped down code that I am using.  Any ideas?



--- Code - C#: --- using System;using System.Collections.Generic;using System.IO;    using System.Windows.Forms; #if BricsCAD    using System.Runtime.InteropServices;    using BricscadApp;    using Teigha.Runtime;    using Teigha.DatabaseServices;    using Teigha.GraphicsInterface;    using Teigha.Geometry;    using Bricscad.ApplicationServices;    using Bricscad.EditorInput;    using Bricscad.Runtime;    using CadRx = Teigha.Runtime;    using CadAs = Bricscad.ApplicationServices;    using CadApp = Bricscad.ApplicationServices.Application;    using CadBr = Teigha.BoundaryRepresentation;    using CadDb = Teigha.DatabaseServices;    using CadGe = Teigha.Geometry;    using CadEd = Bricscad.EditorInput;    using CadGi = Teigha.GraphicsInterface;    using CadClr = Teigha.Colors;    using CadWnd = Bricscad.Windows; #elif AutoCAD     using Autodesk.AutoCAD.Runtime;    using Autodesk.AutoCAD.ApplicationServices;    using Autodesk.AutoCAD.DatabaseServices;    using Autodesk.AutoCAD.Geometry;    using Autodesk.AutoCAD.EditorInput;    using Autodesk.AutoCAD.GraphicsInterface;    using Autodesk.AutoCAD.Colors;    using Autodesk.AutoCAD.Windows;    using Autodesk.AutoCAD.Internal;    using CadRx = Autodesk.AutoCAD.Runtime;    using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;    using CadAs = Autodesk.AutoCAD.ApplicationServices;        using CadDb = Autodesk.AutoCAD.DatabaseServices;    using CadGe = Autodesk.AutoCAD.Geometry;    using CadEd = Autodesk.AutoCAD.EditorInput;    using CadGi = Autodesk.AutoCAD.GraphicsInterface;    using CadClr = Autodesk.AutoCAD.Colors;    using CadWnd = Autodesk.AutoCAD.Windows;#endif [assembly: CommandClass(typeof(CsBrxMgd.Commands))][assembly: ExtensionApplication(typeof(CsBrxMgd.Commands))] namespace CsBrxMgd{    /// <summary>    /// Class Commands.    /// </summary>    /// <seealso cref="IExtensionApplication" />    public class Commands : IExtensionApplication    {        #region Public Methods         /// <summary>        /// this is initialized when the application is loaded        /// </summary>        public void Initialize()        {            Document doc = CadApp.DocumentManager.MdiActiveDocument;            Editor ed = doc.Editor;            Database db = doc.Database;            ed.WriteMessage("\nCsBrxMgd sample is loaded...");        }         /// <summary>        /// this is initialized when the application is terminated        /// </summary>        public void Terminate()        {            CadApp.ShowAlertDialog("The commands class is Terminated");        }         [CommandMethod("CopyObjectsBetweenDatabases", CommandFlags.Session)]        public static void CopyObjectsBetweenDatabases()        {            string filePath = @"c:\users\kbrown\desktop\New Drawing.dwg";            Database destDb = new Database(false, true);            Database sourceDb = CadApp.DocumentManager.MdiActiveDocument.Database;            destDb.ReadDwgFile(@"c:\users\kbrown\desktop\CopyViews.dwt", FileOpenMode.OpenForReadAndWriteNoShare, false, null);            destDb.CloseInput(true);            string myFileName = (string)CadApp.GetSystemVariable("DWGNAME");            string myFilePath = (string)CadApp.GetSystemVariable("DWGPREFIX");            string _originalFile = Path.Combine(myFilePath, myFileName);            string blockName = Path.GetFileNameWithoutExtension(_originalFile);            ObjectId xrefId = destDb.AttachXref(_originalFile, blockName);            HostApplicationServices.WorkingDatabase = destDb;            BlockTableRecord destModelSpace;            ObjectIdCollection idCollection = new ObjectIdCollection();            using (Transaction tr = destDb.TransactionManager.StartTransaction())            {                using (BlockReference br = new BlockReference(Point3d.Origin, xrefId))                {                    br.SetDatabaseDefaults();                    br.Layer = "0";                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForWrite);                    string relativePath = MakeRelativePath(filePath, _originalFile);                    btr.PathName = relativePath;                     BlockTable bt = (BlockTable)tr.GetObject(destDb.BlockTableId, OpenMode.ForRead);                    destModelSpace = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);                    destModelSpace.AppendEntity(br);                    tr.AddNewlyCreatedDBObject(br, true);                }                                tr.Commit();            }             HostApplicationServices.WorkingDatabase = sourceDb;             using (Transaction tr = sourceDb.TransactionManager.StartTransaction())            {                ViewTable vt = (ViewTable)tr.GetObject(sourceDb.ViewTableId, OpenMode.ForRead);                foreach (ObjectId id in vt)                {                    idCollection.Add(id);                }                 tr.Commit();            }             using (Transaction tr = destDb.TransactionManager.StartTransaction())            {                try                {                    BlockTable destBt = (BlockTable)tr.GetObject(destDb.BlockTableId, OpenMode.ForRead);                    destModelSpace = (BlockTableRecord)tr.GetObject(destBt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);                    IdMapping mapping = new IdMapping();                    destDb.WblockCloneObjects(idCollection, destModelSpace.ObjectId, mapping, DuplicateRecordCloning.Ignore, false);                }                catch (Exception ex)                {                    MessageBox.Show($"Error in wblockclone:\n{ex.Message}");                }                 tr.Commit();            }             destDb.SaveAs(filePath, DwgVersion.Current);         }         public static string MakeRelativePath(string fromPath, string toPath)        {            string relativePath = toPath;            try            {                Uri fromUri = new Uri(fromPath);                Uri toUri = new Uri(toPath);                if (fromUri.Scheme != toUri.Scheme)                {                    return toPath;                } // path can't be made relative.                 Uri relativeUri = fromUri.MakeRelativeUri(toUri);                relativePath = Uri.UnescapeDataString(relativeUri.ToString());                if (toUri.Scheme.ToUpperInvariant() == "FILE")                {                    relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);                }            }            catch            {                            }             return relativePath;        }         #endregion Public Methods    }} 

Keith Brown:
So the issue with this code is in the WBlockCloneObjects call.  If you notice the source container is the modelspace objectId of the new drawing.   The views being copied into the new drawing should actually be copied into the viewtable and not modelspace.  So passing in the ViewTableId of the new drawing fixed the issue.


As I am porting over all of our apps into Bricscad I am finding that Autocad is very forgiving in its Managed code.  It will allow you to do things that you should not necessarily do.  This is a prime example of that. 


Thank you to Owen Wengerd for pointing me in the right direction and giving me the answer.  I need to pay better attention to the error messages as it told me directly to my face that i had passed in the wrong owner container.  I just refused to believe it.

Atook:
Keith, thanks for the follow up.

I'm hoping to port my apps to Bricscad as well, any information will be helpful in the future.

kdub_nz:

Thanks Keith,

I like that you have prefixed the topic title with ' Bricscad: '
Perhaps we should encourage that ..

Navigation

[0] Message Index

Go to full version