Trying to add elements to modelspace

Trying to add elements to modelspace

m.de.vriesTH5VM
Enthusiast Enthusiast
579 Views
6 Replies
Message 1 of 7

Trying to add elements to modelspace

m.de.vriesTH5VM
Enthusiast
Enthusiast

I am working on an addin for AutoCAD that needs to place a Section and from that create a block with the intersected geometry.

 

The code I am using is based on the sample code from Autodesk. But while it appears that the section is created correctly it does not show up in the drawing.

 

The code I use to create a section is

internal Section CreateSection(string name, Point3dCollection pts, Vector3d verticalDir, Vector3d viewingDir)
{
	if (string.IsNullOrEmpty(name)) return null;
	if (null == pts || pts.Count <= 1return null;
	if (null == verticalDir || null == viewingDir) return null;
 
	Section res = null;
	using (Transaction trans = Db.TransactionManager.StartTransaction())
	{
		try
		{
			ObjectId blockId = CreateBlock(name, trans);
 
			res = new Section(pts, verticalDir, viewingDir);
			res.Name = name;
 
			BlockTable bt = trans.GetObject(Db.BlockTableId, OpenMode.ForRead) as BlockTable;					
			if (trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) is BlockTableRecord mspace)
			{
				ObjectId id = mspace.AppendEntity(res);
				trans.AddNewlyCreatedDBObject(res, true);
 
				if (trans.GetObject(res.Settings, OpenMode.ForWrite) is SectionSettings settings) SetDefaultSectionSettings(settings, blockId);
			}
 
			trans.Commit();
		}
		catch (Exception ex)
		{
			string mssg = ex.Message;
		}
	}
	return res;
}



 Neither the output block nor the section itself appears in the drawing, even though inspecting the data after creation seems to show everything is in order with them (the section does not have an AcadBlock property set, but everything is is filled correctly)

I am unlocking the document at the start of the command (or I could not open anything for Write).

 

Clearly I am missing something obvious, but I cannot think of what, and the documentation does not suggest anything I should do different or additionally.

 

 

0 Likes
Accepted solutions (1)
580 Views
6 Replies
Replies (6)
Message 2 of 7

ActivistInvestor
Mentor
Mentor
I am unlocking the document at the start of the command (or I could not open anything for Write).

I think you need to show more of your code. The problem is possibly outside of the method you posted, possibly related to the locking/unlocking business 

Message 3 of 7

forge5WTUG
Observer
Observer

The createblock code is mostly a placeholder

 

internal ObjectId CreateBlock(string name, Transaction trans)
{
	if (string.IsNullOrEmpty(name)) return ObjectId.Null;
	if (!(trans.GetObject(Db.BlockTableId, OpenMode.ForRead) is BlockTable bt)) return ObjectId.Null;
 
	BlockTableRecord btr = new BlockTableRecord();
	ObjectId res = ObjectId.Null;
	btr.Name = name;
	try
	{
		bt.UpgradeOpen();
		res = bt.Add(btr);
		trans.AddNewlyCreatedDBObject(btr, true);
	}
	catch (Exception ex)
	{
		string mssg = ex.Message;
	}
 
	return res;
}

 

When the OK button on the dialog is pressed this code is called

 

using (DocumentLock mdi = SDSI.SDSIToolManager.Cmd.Acad.LockDocument())
{
	// get the selected 
	List<SectionData> selected = GetCheckedSections();
	if (null == selected || selected.Count <= 0return;
 
	// first create the selected sections (replacing the ones already in the drawing)
	RemoveExistingDwg(selected);
 
	// create the section drawings based on the selected sections
	DBObjectCollection objects = GetAllIntersectableElements();
	foreach (SectionData section in selected)
	{
		GenerateSectionDrawing(section, objects);
	}
 }

GetCheckedSections() gets data from the dialog

RemoveExistingDwg() does not use the AutoCAD api (it just deletes files from a folder)

GetAllIntersectableElements() returns all 3D objects, included nested ones, that match certain criteria for what needs to be visible in the sections

GenerateSectionDrawing() calls CreateSection(), instersects it with the intersectable objects into a block definition and writes the block definition to file. For testing it does not actually does the intersection and saving part yet, as the CreateSection() does not generate a section in the drawing to use for this part of the process.

 

 

 

0 Likes
Message 4 of 7

forge5WTUG
Observer
Observer

I forgot to add the LockDocument function

internal DocumentLock LockDocument()
{
	return Doc.LockDocument();
}

 

Doc is a property that returns the active document that is kept from when the commandmethod was started

 

DocumentCollection docMngr = Application.DocumentManager;
Doc = docMngr.CurrentDocument;

 

0 Likes
Message 5 of 7

ActivistInvestor
Mentor
Mentor
Accepted solution

I didn't look that closely at your code,  but my guess is that the issue might be in SetDefaultSectionSettings(), but another possible problem is that the block you're creating may need to exist when the transaction is started (IOW, created in another top-level transaction first, that is committed before you create the section). Also, are you inserting the block at some point?

 

A few other possible causes:

 

You should use the Document's TransactionManager, rather than the Database's TransactionManager. The former calls the TransactionManager's FlushGraphics() method when it's Commit() method is called.

 

I'm not sure why you're saving the DocumentManager's CurrentDocument. In any case, you should use MdiActiveDocument if the intent is to restore the active document later, but I'm also not sure why you need to switch the active document. Also are you assigning another Document to CurrentDocument at some point? If so, that is very likely the cause.

 

Not calling RecordGraphicsModified() on the Section (or the BlockReference) before committing the transaction.

 

 

0 Likes
Message 6 of 7

m.de.vriesTH5VM
Enthusiast
Enthusiast

I found that the line where I set the SectionSettings output to a blocktablerecord throw an exception, so I removed that line and added the section output geometry to the output block differently.

In addition I followed your suggestion to change from Database.TransactionManger to Document.TransactionManager

 

Together these changes made my code work.

 

(I keep track of the active document mostly for convenience, but also because the tool does not allow the active document to be switched while the tool is running. By keeping track my code can verify that this has not happened)

 

0 Likes
Message 7 of 7

ActivistInvestor
Mentor
Mentor

The comment about CurrentDocument verses MdiActiveDocument, is that they're not exactly the same.

E.g., a Document can be made 'current' without it being the active document. Making a document the

Current document is required if you are modifying objects in that document that affect the graphics

representation. Without making the non-active document current, graphics will not update to reflect

changes to objects in the document.

 

Not sure if you're using it, but if not, the DocumentCollection.DocumentActivationEnabled property

can be set to prevent a document switch, but must be used with care, as it could accidently be left

set to false, which would lock the user in the active document.

 

In releases of AutoCAD since 2015-or-thereabouts, switching the active document while a command

is running will cancel the command.

0 Likes