LINQ provides an easy way to find the number of entities in modelspace without having to iterate on our own. The IEnumerator exposed by BlockTableRecord can be cast as IEnumerable<ObjectId> to find the count. Here is a code snippet :
ObjectARX 2004 SDK had this nice C++ sample on adding tray items to the status bar and displaying balloon notification in one of those tray items. I have migrated this sample project to work on AutoCAD 2015 and you can download it here :
When implementing an AutoCAD plugin, its quite easy to retrieve entity properties without having to directly deal with the entity's COM wrapper. But when implementing a RealDWG host application, this can become necessary to retrieve some of the entity properties.
If you are using .Net languages, using reflection can come very handy. Here is a blog post that can help :
If you are using C++, here are the changes to the DumpDwg sample from the RealDWG SDK. In this code snippet, our objective is to retrieve properties of a custom entity using the IDispatch interface of its COM wrapper. For example, a drawing that includes a "AsdkPoly" entity from "ObjectARX 2015\samples\entity\polysampPolySamp".
// Info on each IDispatch member item
// DispId map to retrieve properties
static stringdispid* m_pMap;
// Helper method to convert VARIANT to ads_point
static HRESULT get_PointFromVariant(
if (V_VT(&variant) != VT_EMPTY)
if (V_VT(&variant) == (VT_ARRAY | VT_R8))
SAFEARRAY *psa = variant.parray;
long lStartIndex = 0;
long lEndIndex = 0;
SafeArrayGetLBound(psa, 1, &lStartIndex);
SafeArrayGetUBound(psa, 1, &lEndIndex);
if (lEndIndex == 2)
pt[X] = tmpPt[X];
pt[Y] = tmpPt[Y];
pt[Z] = tmpPt[Z];
if (lEndIndex == 1)
pt[X] = tmpPt[X];
pt[Y] = tmpPt[Y];
pt[Z] = 0.0;
// Helper method to get the COM wrapper for an entity
The long waited enhancement is rolled out , I’m personally very happy that our API package is available on Nuget .
So what is big deal about Nuget ?
NuGet is the package manager for the Microsoft development platform including .NET. The NuGet client tools provide the ability to produce and consume packages. The NuGet Gallery is the central package repository used by all package authors and consumers.Nuget
How it is going to help us ?
Very simply ,now you need not download sdk and manually add references to your project ,after installing package from nuget search available with in Visual Studio IDE ,it copies the library files to your solution and automatically updates your project (add references, change config files, etc.). If you remove a package, NuGet reverses whatever changes it made so that no clutter is left.
How should I install a package from Nuget ?
Go to Tools\Library Package Manager \ Manage Nuget Packages
As you may already know, the BlockView .Net sample demonstrates the use of Graphics system to preview a drawing in a Windows form. The migrated sample that works with AutoCAD 2015 is available here.
To get the preview displayed inside a WPF user control hosted in an AutoCAD palette, poses a small problem. In that sample, as the "GraphicsManager.CreateAutoCADDevice" requires a Window handle to display the graphics, there is no direct way to get the display in a WPF user control. In a WPF window, the controls are managed by the top level window and there are no individual handles assigned separately for the controls. Because of this difference, the only way to get this working in WPF is to host the Windows user control that displays the preview in a WindowsFormsHost.
The attached sample is a modified version of the BlockView .Net sample that demonstrates this.
Download Modified BlockView.NET
To try it, netload the dll and run the "bviewpal" command. To preview a drawing, click on the button in the palette and browse to a drawing.
Here is a screenshot of the WPF palette previewing a drawing :
If you have a collection of subDMesh and wish to create a Solid from it, first convert each of those mesh to a surface. If the sufaces all put together form a closed volume, then a sculpted solid can be created from these surfaces. Here is a sample code snippet :
// For SubDMesh
// Select the meshes to create the solid from
ret = acedEntSel(L"Select a mesh : " ,
if (RTNORM != ret)
AcDbObjectId objId = AcDbObjectId::kNull;
if ( Acad::eOk != acdbGetObjectId(objId, entName))
if (objId.objectClass() == AcDbSubDMesh::desc())
}while (ret == RTNORM);
// Convert the meshes to surfaces
AcDbSurface *pSurface = NULL;
for (int mesh = 0; mesh < meshIdArray.length(); mesh++)
AcDbEntity *pEntity = NULL;
if (acdbOpenAcDbEntity(pEntity, meshIdArray[mesh],
I recently received a case query where customer is getting this compilation error C2440: 'type cast' : cannot convert from 'AcDbHandle' to 'long' ,which is working fine VS 90.0 compiler but failing in VS 100.0\110.0 , after investigating it is found that the default implementation of
AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key)
is changed in one of the atlmfc includes Afxtempl.h, the new definition is not allowing the type conversion, so we have two options either to understand new definition ,which I didn’t get completely so expecting some expert opinion or to override HashKey template to suit to our need.
Here I’m going with the second option ,to override HashKey template.
You can incorporate the following definition in your DLLMain file to avoid type conversion error.