Jump to content

loading linetype to drawing


btraemoore

Recommended Posts

I'm trying to load a linetype into the active document so i can set a layers linetype to the one i'm trying to load. Now the problem is when i try to load it, autocad is giving me an exception of: eWasOpenForRead. so i tried to send it via the command line and it worked, BUT the application that im writing just ended... does anybody have any idea as to why this is happening?

 

code:

       private void defaultLayerFix() {

       // Open a transaction for fixing layers that have the correct name
       // but not the correct color or linetype.
       using(curTrans = db.TransactionManager.StartOpenCloseTransaction()) {

           // Open the layerTable and lineType table for read.
           dwgLyrTbl = curTrans.GetObject(
               db.LayerTableId,OpenMode.ForRead) as LayerTable;
           acLinTbl = curTrans.GetObject(
               db.LinetypeTableId,OpenMode.ForRead) as LinetypeTable;

           // Check each layer against the standard layers DataSet.
           foreach (ObjectId layID in dwgLyrTbl) {
               LayerTableRecord curLayer = curTrans.GetObject(
                   layID,OpenMode.ForRead) as LayerTableRecord;

               var layerFound = _LayerDataTable.Rows.Find(curLayer.Name.ToUpper());
               if(layerFound != null){

                   // Upgrade the layerTable and LayerRecord for write.
                   dwgLyrTbl.UpgradeOpen();
                   curLayer.UpgradeOpen();


                   // modify the color of the layer
                   curLayer.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(
                       Autodesk.AutoCAD.Colors.ColorMethod.ByAci, (short)layerFound[2]);

                   // I tried to put it in its own transaction in hopes that it would help.. but it didnt
                   using(Transaction tempTrans = db.TransactionManager.StartOpenCloseTransaction()){

                       // if the layer is not loaded in the current dwg
                       if(!acLinTbl.Has((string)layerFound[3])) 
                           try {
                               db.LoadLineTypeFile((string)layerFound[3], "acad.lin");
                           } catch (Autodesk.AutoCAD.Runtime.Exception e) {
                               Editor ed = acDoc.Editor;
                               ed.WriteMessage(e.Message);
                           }

                   tempTrans.Commit();
                   }

                   // Change current layer linetype to...
                   curLayer.LinetypeObjectId = acLinTbl[(string)layerFound[3]];

                   // Downgrade the layerTable, lineTable and the LayerRecord for read.
                   curLayer.DowngradeOpen();
                   dwgLyrTbl.DowngradeOpen();

                   // Remove the layer from the standards list
                   // so we do not attempt to have redundant layers.
                   for(int i = _LayerDataTable.Rows.Count-1; i >= 0; i--) {
                       System.Data.DataRow dr = _LayerDataTable.Rows[i];
                       if (dr["NAME"] == layerFound[0]){
                           dr.Delete();
                           break;
                       }
                   }
               } else {

                   // if the layer is not in within standard add it to a data set
                   // to fix manually.
                   if(curLayer.Name == "0")
                       continue;
                   var newRow = LayersToFix.NewRow();
                   newRow["NAME"] = curLayer.Name;
                   // TODO get color name..
                   newRow["COLOR"] = curLayer.Color.ColorName;
                   newRow["COLOR_ID"] = 0;
                   LinetypeTableRecord Ltype = (LinetypeTableRecord)curTrans.GetObject(
                       curLayer.LinetypeObjectId,OpenMode.ForRead
                   );
                   newRow["LINETYPE"] = Ltype.Name;
                   LayersToFix.Rows.Add(newRow);
               }
           }
           // accept the changes made in this transaction
           curTrans.Commit();
       }
   }

Link to comment
Share on other sites

On the quick glance if you've deleted row from datatable

you have to end this action with AcceptChanges method right after that,

also why StartOpenCloseTransaction? better yet to use StartTransaction I think

I will be look at your code closely tomorrow,

Cheers :)

Link to comment
Share on other sites

I think i may have found something here, but im not sure. From what i think he is saying, you have to set a commandflag.session to be able to load/reload a layer synchronously. Im not really clear, forgive me.

Link to comment
Share on other sites

I think i may have found something here, but im not sure. From what i think he is saying, you have to set a commandflag.session to be able to load/reload a layer synchronously. Im not really clear, forgive me.

 

Perhaps I'm overlooking something... Why the need to invoke Command synchronously when there's an API available to load linetype?

Link to comment
Share on other sites

Here is an excerpt from my form

Pay attention how you could to use color and linetype,

all within top transaction, no temporary transaction is needed

 

 
private void btnUsed_Click(object sender, EventArgs e)
{
List<string> used = GetUsedLayers();
this.listBox1.DataSource = used;// populate listBox to show used layers
}

public List<string> GetUsedLayers()
{
List<string> used = new List<string>();
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable lt = tr.GetObject( db.LayerTableId, OpenMode.ForRead ) as LayerTable;
lt.GenerateUsageData();
foreach (ObjectId oid in lt)
{
LayerTableRecord ltr = tr.GetObject (oid, OpenMode.ForRead ) as LayerTableRecord;
if (ltr.IsUsed == true)
{
used.Add(ltr.Name);
}
}
return used;
}
}
 
public void CreateLayer(string layerName, string ltpname, params short[] color)
{
ObjectId layerId;
ObjectId ltrid = ObjectId.Null;
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
if (lt.Has(layerName))
{
layerId = lt[layerName];
}
else
{
LayerTableRecord ltr = new LayerTableRecord();
ltr.Name = layerName;

if (color.Length == 1)
{
ltr.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(ColorMethod.ByAci, color[0]);
// return;
}
else
{
if (color.Length == 3)
{
byte red = Convert.ToByte(color[0]); byte green = Convert.ToByte(color[1]); byte blue = Convert.ToByte(color[2]);
ltr.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(red, green, blue);

}
else return;
}
LinetypeTable ltt = tr.GetObject(db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable;
if (ltt.Has(ltpname))
{
ltrid = ltt[ltpname];
ltt.UpgradeOpen();
ltr.LinetypeObjectId = ltrid;
}
else
{
LoadLineType(ltpname);
LinetypeTableRecord lttr = tr.GetObject(ltt[ltpname], OpenMode.ForRead, false) as LinetypeTableRecord;
ltr.LinetypeObjectId = ltt[ltpname];
}
lt.UpgradeOpen();
layerId = lt.Add(ltr);
tr.AddNewlyCreatedDBObject(ltr, true);
db.Clayer = layerId;// set layer current, optional, may remove this line
}
tr.Commit();
}
}
// without check MEASUREINIT system variable //
public void LoadLineType(string ltname)
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
LinetypeTable tbl = (LinetypeTable)tr.GetObject(db.LinetypeTableId, OpenMode.ForRead);
if (!tbl.Has(ltname))
{
db.LoadLineTypeFile(ltname, "acad.lin");// imperic
}
tr.Commit();
}
}

 
privatevoid btnCreate_Click(object sender, EventArgs e)
{
string layerName = this.txtGrid.Text;// text box for input layer name
// this.Hide();
CreateLayer(layerName+"1", "Phantom2", 64,128,64);
CreateLayer(layerName+"2", "Center", 107, 62, 132);// arguments are 3 digits fo RGB or single one for colorindex
CreateLayer(layerName+"3", "Hidden", 1);
// this.Show();
}

Link to comment
Share on other sites

@BlackBox you were not overlooking anything, i know there is a perfectly good API for this i just couldn't figure out why it was not working... My assumption was because of the transaction placement. I still don't know exactly why it was not working but, i did get it functioning after some rewriting..

 

@Fixo thank you for your implementation of this, I do however want several sub-transactions so that it can be undone in steps. (if im even correct on my assumption that the undo feature ties in with transactions) if not, then i will consider changing it for simplicity sake. I've only been writing in C# for about a week, I still have a lot to learn.

 

 

code:

 

             private void defaultLayerFix (){
		using(var DLFTrans = db.TransactionManager.StartTransaction()){
			// Open the layerTable table for read.
			dwgLyrTbl = DLFTrans.GetObject(
				db.LayerTableId,OpenMode.ForRead) as LayerTable;
			
			// Foreach layer in current DWG
			foreach (ObjectId layID in dwgLyrTbl) {
				var curLayer = DLFTrans.GetObject(
					layID,OpenMode.ForRead) as LayerTableRecord;
				
				FixLayer(curLayer);
			}
			DLFTrans.Commit();
		}
	}
	
	private void FixLayer(LayerTableRecord curLayer){
		
		// Open a transaction for fixing layers that have the correct name
		// but not the correct color or linetype.
		using(curTrans = db.TransactionManager.StartTransaction()) {
			
			// Check Standard layer data table for current layer
			var layerFound = _LayerDataTable.Rows.Find(curLayer.Name.ToUpper());
			
			// If found
			if(layerFound != null) {
				
				// Open the Line Type table for read
				acLinTbl = curTrans.GetObject(
					db.LinetypeTableId,OpenMode.ForRead) as LinetypeTable;
				
				// Send to load.
				LoadLinetype((string)layerFound[3]);
				
				// If linetype table has the needed linetype.
				if (acLinTbl.Has((string)layerFound[3])){
					
					// Upgrade the current layer for Write.
					curLayer.UpgradeOpen();
					
					// Change the layers Linetype.
					curLayer.LinetypeObjectId = acLinTbl[(string)layerFound[3]];
					
					// Change the layers color.
					curLayer.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(
						Autodesk.AutoCAD.Colors.ColorMethod.ByAci, (short)layerFound[2]);
					
					// Downgrade the layer from write to read.
					curLayer.DowngradeOpen();
					
					// Remove the layer from the Standard Layers Dataset within current dwg.
					for(int i = _LayerDataTable.Rows.Count-1; i >= 0; i--) {
						var dr = _LayerDataTable.Rows[i];
						if (dr["NAME"] == layerFound[0]){
							dr.Delete();
							break;
						}
					}
				} else {
					MessageBox.Show("awe ****, still not working");
				}
			} else {
				
				// If the layer is not in within standard add it to a data set
				// to fix manually.
				if(curLayer.Name != "0") {
					
					// Create a new row in dataset
					var newRow = LayersToFix.NewRow();
					newRow["NAME"] = curLayer.Name;
					// TODO get color name..
					newRow["COLOR"] = curLayer.Color.ColorName;
					newRow["COLOR_ID"] = 0;
					var Ltype = (LinetypeTableRecord)curTrans.GetObject(
						curLayer.LinetypeObjectId,OpenMode.ForRead
					);
					newRow["LINETYPE"] = Ltype.Name;
					
					// Add the new row to the dataset.
					LayersToFix.Rows.Add(newRow);
				}
			}
			
			// Accept changes and dispose of the transacton
			curTrans.Commit();
		}
	}
	
	
	private void LoadLinetype(string ltName)
	{
		// Start a transaction
		using (var acTrans = db.TransactionManager.StartTransaction())
		{
			// Open the Linetype table for read
			var acLineTypTbl = acTrans.GetObject(db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable;
			
			// If the linetype does not exist
			if (!acLineTypTbl.Has(ltName))
			{
				// Load the Center Linetype
				db.LoadLineTypeFile(ltName, "acad.lin");
			}
			
			// Save the changes and dispose of the transaction
			acTrans.Commit();
		}
	}

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...