Here's a code snippet from a project I'm working on (processing a large number of surfaces from point files in Civil 3D):
// Create and open a new drawing, from the specified template Document doc = AcApplication.DocumentManager.Add(templateFileName); AcApplication.DocumentManager.MdiActiveDocument = doc; Database db = doc.Database; // need to wait for Civil 3D to catch up! MessageBox.Show(surfacename); // Create the surface using (Transaction trans = db.TransactionManager.StartTransaction()) { // get the point file format object, required for import: PointFileFormatCollection ptFileFormats = PointFileFormatCollection.GetPointFileFormats(db); PointFileFormat ptFormat = ptFileFormats[ptFileFormat]; ObjectId styleId = GetStyleId(surfaceStyleName); ObjectId surfaceId = TinSurface.Create(filename, styleId); TinSurface surface = trans.GetObject(surfaceId, OpenMode.ForWrite) as TinSurface;
What's odd, is that this works, pretty much the way I want it to, except for the MessageBox.Show(surfacename); line.
If I remove this line, or replace it with Thread.Sleep(30000); or for (int i=0; i<1000000; i++) {}, the program crashes on the TinSurface.Create(filename, styleId); line with a "Fail to create surface" error. I've tried using TinSurface.Create(db, surfacename); and it still crashes. I've also tried creating all of the drawing files first, then coming back and using DocumentManager.Open(). I can access existing surfaces using this technique, but I can't create them without the MessageBox.Show() statement. When I simply add the surfaces to the active drawing, the program works perfectly, but I want to put the surfaces into separate drawings for performance reasons.
Does anyone know what the MessageBox.Show() statement is doing that could be replicated without actually stopping the program to request input from the user? What part of the process did I miss? Do I need to reset the UI, or something along those lines, and how would I go about doing so?
Solved! Go to Solution.
Solved by Jeff_M. Go to Solution.
Thanks Jeff,
I really appreciate you looking into this. I was under the (possibly mistaken) understanding that the Civil namespaces didn't load unless you open the drawing in the editor and I wasn't able to find an example (except for Kean Walsley's discussion on the topic). I haven't worked with a side database before. I certainly don't need the UI, so I think approach would work.
How would I create the new file from a template, and then open it as a side database?
Document doc = AcApplication.DocumentManager.Add(templateFileName); // <-- Need to change this line
// AcApplication.DocumentManager.MdiActiveDocument = doc; // <-- No longer required
// Create a database and try to load the file
Database db = new Database(false, true); using (db) { try { db.ReadDwgFile( filename, System.IO.FileShare.Read, false, "" ); } catch (System.Exception) { ed.WriteMessage("\nUnable to read drawing file."); return; } // ... do some stuff }
I suppose I could just copy the template file on the server, rename it and open it. Or open the template and do a CloseAndSave.
Is there a better way?
Thanks again, for your feedback.
John, sorry for the delayed response. Was researching some other things and lost track of time. The following code works quite well and fast:
OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "Select PointFiles to import"; ofd.CheckFileExists = true; ofd.Multiselect = true; if (ofd.ShowDialog() != System.Windows.Forms.DialogResult.OK) return; dynamic prefs = Autodesk.AutoCAD.ApplicationServices.Application.Preferences; dynamic files = prefs.Files; string qnew = files.QNewTemplateFile; foreach (string file in ofd.FileNames) { string path = Path.GetDirectoryName(file); string filename = Path.GetFileNameWithoutExtension(file); string newname = path + "\\" + filename + ".dwg"; using (Database db = new Database(false, true)) { db.ReadDwgFile(qnew, FileOpenMode.OpenForReadAndWriteNoShare, false, ""); using (Transaction tr = db.TransactionManager.StartTransaction()) { CivilDocument civdoc = CivilDocument.GetCivilDocument(db); ObjectId styleId = civdoc.Styles.SurfaceStyles["TDG - Border Only"]; ObjectId surfId = TinSurface.Create(db, filename); TinSurface surf = (TinSurface)surfId.GetObject(OpenMode.ForWrite); PointFileFormatCollection ptFileFormats = PointFileFormatCollection.GetPointFileFormats(db); PointFileFormat ptFormat = ptFileFormats["PNEZD (comma delimited)"]; surf.StyleId = styleId; surf.PointFilesDefinition.AddPointFile(file, ptFormat); tr.Commit(); } db.SaveAs(newname, DwgVersion.Current); } }
I have some problems with creating of new surfaces. I tryed with this code, and it works if I type command "create"'
public class Commands
{
[CommandMethod("create")]
public void CreateTinSurfaceTest()
{
Document m_Doc = Application.DocumentManager.MdiActiveDocument;
Database db = m_Doc.Database;
Editor ed = m_Doc.Editor;
CivilDocument civilDoc = CivilApplication.ActiveDocument;
using (Transaction m_Tr = db.TransactionManager.StartTransaction())
{
try
{
//1. Variant: defintion styleproperties- and SurfaceName
m_SurfaceStyleId = civilDoc.Styles.SurfaceStyles["Rutnät och gräns"];
m_SurfaceId = TinSurface.Create("TIN_Surface_From_Contours", m_SurfaceStyleId);
//2. Variant definition SurfaceName
//m_SurfaceId = Autodesk.Civil.DatabaseServices.TinSurface.Create(db, "m_NewSurfaceName");
m_Surface = m_SurfaceId.GetObject(OpenMode.ForWrite) as TinSurface;
ed.WriteMessage("Import succeeded: {0} \n {1}", m_SurfaceId.ToString(), db.Filename);
}
catch (System.Exception e)
{
ed.WriteMessage("Import failed: {0}", e.Message);
}
m_Tr.Commit();
}
}
But if I call metod (CreateTinSurfaceTest()) from annother class like so
Commands cmd = new Commands();
cmd.CreateTinSurfaceTest();
it doesn´t work. Anybody know why?
Is your call to "CreateTinSurfaceTest()"? "create" is an acad command - not the same as the name of the method.
Thanx!
Problem is solved, it hade to do with implemented winformDialog. I could click button_ok and than TinSurface.Create()-metod was running. But the problem was I didn´t get a SurfaceId. The problem was, the dialog was open and so the metod couldn´t work right.
How did you get reference to Autodesk.AutoCAD.ApplicationServices.Application.Preferences ?
When I include a reference to ACMGD.DLL ... although it creates a DLL, ACCORE crashes on NETLOAD : (
Can't find what you're looking for? Ask the community or share your knowledge.