在acad中建立一个层过滤器

作者: admin 分类: C++,CAD,ObjectARX 发布时间: 2021-02-10 17:13

转载:https://blog.csdn.net/TXH0001/article/details/6675893

添加下面代码向acad中添加一个层过滤器

int CreateLayerFilter(LPTSTR filterName,LPTSTR layerNames)
{
    AcDbSymbolTablePointer<AcDbLayerTable> bp(acdbCurDwg(),AcDb::kForWrite);
    bp->createExtensionDictionary();
    AcDbObjectId  ExDic_ID=bp->extensionDictionary();  //为层表创建扩展字典
    AcDbObject * p_Obj=NULL;
 
 if (Acad::eOk == acdbOpenAcDbObject(p_Obj,ExDic_ID,AcDb::kForWrite))
 {
  AcDbDictionary * p_Dic=NULL;
  
  p_Dic=AcDbDictionary::cast(p_Obj);
  
  AcDbDictionary * p_LfDic=NULL;
  AcDbObjectId lfDic_ID;
  
  if (p_Dic->has(_T("ACAD_LAYERFILTERS"))){  //如果已有层过滤器定义就获取
   p_Dic->getAt(_T("ACAD_LAYERFILTERS"),lfDic_ID);
  }
  else{
   p_LfDic=new AcDbDictionary;  //如果没有就添加一个
   p_Dic->setAt(_T("ACAD_LAYERFILTERS"),p_LfDic,lfDic_ID);
   p_LfDic->close();
  }
  p_Dic->close();

  
  acdbOpenAcDbObject(p_Obj,lfDic_ID,AcDb::kForWrite);
  
  p_LfDic=AcDbDictionary::cast(p_Obj);
  
  AcDbXrecord *p_NewXrec=NULL;
  AcDbObjectId xrecID;
   
  if (p_LfDic->has(filterName))  //如果已有同名过滤器就获取
  { 
       p_LfDic->getAt(filterName,xrecID);
    acdbOpenAcDbObject(p_Obj,xrecID,AcDb::kForWrite);
    p_NewXrec=AcDbXrecord::cast(p_Obj);
  }else{  //如果没有就添加一个
      p_NewXrec=new AcDbXrecord;
     p_LfDic->setAt(filterName,p_NewXrec,xrecID);
  }
      p_LfDic->close();

   resbuf *pRb; 
    pRb = acutBuildList(
    AcDb::kDxfText,filterName,   //过滤器设定名
    AcDb::kDxfText,layerNames,   //过滤图层名,用逗号分隔
    AcDb::kDxfText,_T("*"),
    AcDb::kDxfText,_T("*"),
    AcDb::kDxfInt16 ,0,
    AcDb::kDxfText,_T("*"),
    AcDb::kDxfText,_T("*"),
    RTNONE);

   p_NewXrec->setFromRbChain(*pRb);  //按构建的dxf编码组设置AcdbXrecrod的内容
   acutRelRb(pRb);
   p_NewXrec->close();
   
 }
   return RTNORM;
}

执行代码如: CreateLayerFilter(_T("test"),_T("图层1,图层2"));

结果如下:

0_1312961066UvJF.gif

AcDbDictionary中存的内容很杂,可以先用AcDbDictionaryIterator将其遍历一遍,搞清楚里面存的东西的类型和name,

这个很重要,最好是先有一个已经建好的结构,比如上面的层过滤器,先用acad建一个,然后分析就方便了

  AcDbDictionaryIterator * it;
   it=p_LfDic->newIterator(); 
     
    AcDbXrecord *p_Xrec;
    while (!it->done())
    { 
       CString itemName=it->name();    //存储内容的关键字AcDbDictionary的setAt就靠它了,当然也可用acdbobjectid
        resbuf *pRb;
       it->getObject(p_Obj,AcDb::kForWrite); //获取存储的内容,一般都是AcDbXrecord
        p_Xrec=AcDbXrecord::cast(p_Obj);
       p_Xrec->rbChain(&pRb);
       CString str_value= pRb->resval.rstring;  //随便找个值读一下,根据dxf的类型自己分,在层过滤器中其acdbxrecord的dxf编码第一个是string类型,就是过滤器的名字
      acutPrintf(_T("%s"),str_value);
       p_Xrec->close();
       acutRelRb(pRb);
        it->next();

    }
    delete it;

说name重要是因为AcDbDictionary在setAt的时候,要和acutBuildList中用同样的filterName命名

p_LfDic->setAt(filterName,p_NewXrec,xrecID); //一定要用filterName,否则就悲剧,一点图层过滤器按钮就崩溃,折腾了好久才发现。

避免这个问题的最好办法就是前面说的,先用acad建一个图层过滤器,用迭代器看清楚了再动手添加。

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

标签云