AcLyLayerFilterManager 图层过滤器 图层分组
Creating and accessing layer filter information
By Balaji Ramamoorthy
Here is a ObjectARX and .Net sample code to create and access the layer filters. A simple trick to know the layer filter expression that will suit your needs, is to create a layer filter in AutoCAD and use this code to find the filter expression for it. This can then be used in your code to create a new layer filter.
Using ObjectARX :
Acad::ErrorStatus es = Acad::eOk;
AcDbDatabase *pDb =
acdbHostApplicationServices()->workingDatabase();
AcLyLayerFilterManager *pLayerFilterManager =
aclyGetLayerFilterManager(pDb);
AcLyLayerFilter *pRoot = NULL;
AcLyLayerFilter *pCurrent = NULL;
es = pLayerFilterManager->getFilters(pRoot, pCurrent);
if(es != Acad::eOk)
return;
if(pRoot != NULL)
{
AcArray<AcLyLayerFilter *> filters;
filters = pRoot->getNestedFilters();
// Lets find out about the root filter
acutPrintf
(
ACRX_T("\n(Root) Name : %s Expr : %s"),
pRoot->name(),
pRoot->filterExpression()
);
// Lets find out about all the filters
for(int i=0; i < filters.length();i++)
{
acutPrintf
(
ACRX_T("\nName : %s Expr : %s"),
filters.at(i)->name(),
filters.at(i)->filterExpression()
);
}
// Lets find out about the current filter
if(pCurrent != NULL)
{
acutPrintf
(
ACRX_T("\n(Current) Name : %s Expr : %s"),
pCurrent->name(),
pCurrent->filterExpression()
);
}
// Create and add a new layer filter
AcLyLayerFilter *pMyLyFilter = new AcLyLayerFilter();
pMyLyFilter->setName(ACRX_T("MyLyFilter"));
pMyLyFilter->setFilterExpression(ACRX_T("NAME == \"*Test*\""));
es = pRoot->addNested(pMyLyFilter);
es = pLayerFilterManager->setFilters(pRoot, pMyLyFilter);
delete pRoot;
}
Using AutoCAD .Net API :
using Autodesk.AutoCAD.LayerManager;
[CommandMethod("CreateLayerFilter")]
public void CreateLayerFilter()
{
Document doc
= Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
LayerFilterTree filterTree = db.LayerFilters;
LayerFilterCollection filters
= filterTree.Root.NestedFilters;
// Lets find out about the root filter
ed.WriteMessage
(
String.Format("\n(Root) Name : {0} Expr : {1}",
db.LayerFilters.Root.Name,
db.LayerFilters.Root.FilterExpression)
);
// Lets find out about all the filters
foreach(LayerFilter f in filters)
{
ed.WriteMessage
(
String.Format("\nName : {0} Expr : {1}",
f.Name,
f.FilterExpression)
);
}
// Lets find out about the current filter
if(db.LayerFilters.Current != null)
{
ed.WriteMessage
(
String.Format("\n(Current) Name : {0} Expr : {1}",
db.LayerFilters.Current.Name,
db.LayerFilters.Current.FilterExpression)
);
}
// Create and add a new layer filter
LayerFilter layerFilter = new LayerFilter();
layerFilter.Name = "MyLyFilter";
layerFilter.FilterExpression = "NAME == \"*Test*\"";
filters.Add(layerFilter);
// Set the changed layer filters tree to the database
db.LayerFilters = filterTree;
}
Posted at 07:26 AM in .NET, AutoCAD, Balaji Ramamoorthy, ObjectARX | Permalink
Delete layer filters using ObjectARX
by Fenton Webb
Issue
I have a customer who uses many dwgs with many filters on the layer. How can I delete the filters using a program?
Solution
Layer filters exist as AcDbXRecord entries in two dictionaries (with name "ACAD_LAYERFILTERS" and "ACLYDICTIONARY") contained in the extension dictionary of Layer Table. To delete the layer filters, you need to iterate through the "ACAD_LAYERFILTERS" and "ACLYDICTIONARY" dictionaries and delete all AcDbXRecords.
The code below opens a dummy drawing and deletes all layer filters inside of the drawing:
static void ASDKLayerFilterDelete_DeleteLayerFilters(void)
{
// Set constructor parameter to kFalse so that the
// database will be constructed empty. This way only
// what is read in will be in the database.
AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);
// The AcDbDatabase::readDwgFile() function
// automatically appends a DWG extension if it is not
// specified in the filename parameter.
pDb->readDwgFile(_T("c:\\drawing1.dwg"));
// ensure the whole dwg is read
pDb->closeInput(true);
// Get the Layer Table
AcDbLayerTablePointer pLyrTbl(pDb->layerTableId(), AcDb::kForRead);
if (pLyrTbl.openStatus() == Acad::eOk)
{
// Get Extention dictionary
AcDbObjectId pExtDicId = pLyrTbl->extensionDictionary();
if(pExtDicId.isValid())
{
AcDbDictionaryPointer pDict(pExtDicId,AcDb::kForRead);
if(Acad::eOk == pDict.openStatus())
{
// Get Layer Filter Dictionary from extension dictionary
AcDbObjectId pObjId;
pDict->getAt(_T("ACAD_LAYERFILTERS"),pObjId);
if(pObjId.isValid())
{
AcDbDictionaryPointer pFiltDict(pObjId,AcDb::kForRead);
if(Acad::eOk == pFiltDict.openStatus())
{
// Get objects in layer filter dictionary
AcDbObjectId filtObjId;
AcDbDictionaryIterator *pItr = pFiltDict->newIterator();
if (NULL != pItr)
{
for(;!pItr->done();pItr->next())
{
AcDbObjectPointer<AcDbXrecord> pLyrFltr(pItr->objectId(),AcDb::kForWrite);
if(Acad::eOk == pLyrFltr.openStatus())
{
pLyrFltr->erase();
}
}
delete pItr;
}
}
}
pDict->getAt(_T("ACLYDICTIONARY"),pObjId);
if(pObjId.isValid())
{
AcDbDictionaryPointer pFiltDict(pObjId,AcDb::kForRead);
if(Acad::eOk == pFiltDict.openStatus())
{
// Get objects in layer filter dictionary
AcDbObjectId filtObjId;
AcDbDictionaryIterator *pItr = pFiltDict->newIterator();
if(NULL != pItr)
{
for(;!pItr->done();pItr->next())
{
AcDbObjectPointer<AcDbXrecord> pLyrFltr(pItr->objectId(),AcDb::kForWrite);
if(Acad::eOk == pLyrFltr.openStatus())
{
pLyrFltr->erase();
}
}
delete pItr;
}
}
}
}
}
}
Acad::ErrorStatus es = pDb->saveAs(_T("c:\\drawing1.dwg"));
delete pDb;
}
Posted at 02:10 PM in 2010, 2011, 2012, 2013, AutoCAD, Fenton Webb, ObjectARX | Permalink