Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

552 lines
15 KiB
C++

#include "stdafx.h"
#include "MaterialRecord.h"
#include "TDbBlockInsert.h"
BOOL GetMaterialsFromBlock(const AcDbObjectId &idBlock, AcDbObjectIdArray &idArray)
{
XDbBlockTableRec rm_sdb("RM_SDB", AcDb::kForRead);
if(!rm_sdb)
return FALSE;
AcDbObjectId idMater = rm_sdb.m_pBlockTableRec->objectId();
rm_sdb.Close();
OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlockRec);
if(pBlockRec){
AcDbBlockTableRecordIterator *pRecIter = NULL;
if(pBlockRec->newIterator(pRecIter)!=Acad::eOk || !pRecIter)
return FALSE;
for(pRecIter->start(); !pRecIter->done(); pRecIter->step()) {
AcDbEntity *pEnt = NULL;
if(pRecIter->getEntity(pEnt, AcDb::kForRead)!=Acad::eOk)
continue;
XDbObject obj(pEnt);
if(pEnt->isA() == AcDbBlockReference::desc()) {
AcDbBlockReference *pRef=(AcDbBlockReference *)pEnt;
if(pRef->blockTableRecord() == idMater){
resbuf *rb=pRef->xData("AVE_MATERIAL");
if(!rb){
continue;
}
RBList rbList(rb);
idArray.append(pEnt->objectId());
}
}
}
delete pRecIter;
}
OPENOBJ_END();
return TRUE;
}
// 由块表记录获得给定名称的材质ID
TARCH_EXP BOOL MaterialName2IdFromBlock(const AcDbObjectId &idBlock, const XStringList &lstNewMat, AcDbObjectIdArray &idArray)
{
XDbBlockTableRec rm_sdb("RM_SDB", AcDb::kForRead);
if(!rm_sdb)
return FALSE;
AcDbObjectId idMater = rm_sdb.m_pBlockTableRec->objectId();
rm_sdb.Close();
OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlockRec);
if(pBlockRec){
AcDbBlockTableRecordIterator *pRecIter = NULL;
if(pBlockRec->newIterator(pRecIter)!=Acad::eOk || !pRecIter)
return FALSE;
for(pRecIter->start(); !pRecIter->done(); pRecIter->step()) {
AcDbEntity *pEnt = NULL;
if(pRecIter->getEntity(pEnt, AcDb::kForRead)!=Acad::eOk)
continue;
XDbObject obj(pEnt);
if(pEnt->isA() == AcDbBlockReference::desc()) {
AcDbBlockReference *pRef=(AcDbBlockReference *)pEnt;
if(pRef->blockTableRecord() == idMater){
resbuf *rb=pRef->xData("AVE_MATERIAL");
if(!rb){
continue;
}
RBList rbList(rb);
Groups *group=rbList.SearchNode(1000);
if(group && ((XStringList &)lstNewMat).Index(group->string, FALSE)>=0) {
idArray.append(pEnt->objectId());
}
}
}
}
delete pRecIter;
}
OPENOBJ_END();
return TRUE;
}
// 由块表记录获得给定名称的材质ID
TARCH_EXP AcDbObjectId MaterialName2IdFromBlock(const AcDbObjectId &idBlock, const char *szMatName)
{
AcDbObjectId idRet;
XDbBlockTableRec rm_sdb("RM_SDB", AcDb::kForRead);
if(!rm_sdb)
return idRet;
AcDbObjectId idMater = rm_sdb.m_pBlockTableRec->objectId();
rm_sdb.Close();
OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlockRec);
if(pBlockRec){
AcDbBlockTableRecordIterator *pRecIter = NULL;
if(pBlockRec->newIterator(pRecIter)!=Acad::eOk || !pRecIter)
return FALSE;
for(pRecIter->start(); !pRecIter->done(); pRecIter->step()) {
AcDbEntity *pEnt = NULL;
if(pRecIter->getEntity(pEnt, AcDb::kForRead)!=Acad::eOk)
continue;
XDbObject obj(pEnt);
if(pEnt->isA() == AcDbBlockReference::desc()) {
AcDbBlockReference *pRef=(AcDbBlockReference *)pEnt;
if(pRef->blockTableRecord() == idMater){
resbuf *rb=pRef->xData("AVE_MATERIAL");
if(!rb){
continue;
}
RBList rbList(rb);
Groups *group=rbList.SearchNode(1000);
if(group && stricmp(group->string, szMatName)==0) {
idRet=pEnt->objectId();
break;
}
}
}
}
delete pRecIter;
}
OPENOBJ_END();
return idRet;
}
BOOL GetBlkRecMatName(AcDbObjectId idBlock, XStringList &lstMatName, XStringList &lstGroupName)
{
XDbBlockTableRec rm_sdb("RM_SDB", AcDb::kForRead);
if(!rm_sdb)
return FALSE;
AcDbObjectId id = rm_sdb.m_pBlockTableRec->objectId();
rm_sdb.Close();
OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlockRec);
if(pBlockRec){
AcDbBlockTableRecordIterator *pRecIter = NULL;
if(pBlockRec->newIterator(pRecIter)!=Acad::eOk || !pRecIter)
return FALSE;
for(pRecIter->start(); !pRecIter->done(); pRecIter->step()) {
AcDbEntity *pEnt = NULL;
if(pRecIter->getEntity(pEnt, AcDb::kForRead)!=Acad::eOk)
continue;
XDbObject obj(pEnt);
if(pEnt->isA() == AcDbBlockReference::desc()) {
AcDbBlockReference *pRef=(AcDbBlockReference *)pEnt;
if(pRef->blockTableRecord() == id){
resbuf *rb=pRef->xData("AVE_MATERIAL");
if(!rb){
delete pRecIter;
return FALSE;
}
RBList rbList(rb);
Groups *group=rbList.SearchNode(1000);
if(group) {
CString csMatName = group->string;
lstMatName.Append(strnew(csMatName));
}
continue;
}
}
resbuf *pxData = pEnt->xData("TCH_GROUPNAME");
CString csName;
if(pxData) {
resbuf *pNext = pxData->rbnext;
if(pNext && pNext->restype == 1000) {
csName = pNext->resval.rstring; //编号
if(lstGroupName.Index(csName) < 0)
lstGroupName.Append(strnew(csName));
}
ads_relrb(pxData);
}
}
delete pRecIter;
}
OPENOBJ_END();
return TRUE;
}
void ListCurMatFromMSpace(XStringList &lstMats)
{
lstMats.Reset();
XDbBlockTableRec rm_sdb("RM_SDB", AcDb::kForRead);
if(!rm_sdb)
return;
AcDbObjectId id = rm_sdb.m_pBlockTableRec->objectId();
rm_sdb.Close();
AcDbBlockTable *pTable = NULL;
AcDbDatabase *dwg = acdbCurDwg();
if (acdbCurDwg()->getBlockTable(pTable, AcDb::kForRead) != Acad::eOk)
return;
if(!pTable)
return;
AcDbBlockTableRecord *pBlockTableRecord = NULL;
VERIFY(pTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForRead)==Acad::eOk);
pTable->close();
if(!pBlockTableRecord)
return;
AcDbBlockTableRecordIterator* pBlockIterator = NULL;
pBlockTableRecord->newIterator(pBlockIterator);
if(!pBlockIterator){
pBlockTableRecord->close();
return;
}
AcRxClass *pClass = AcDbBlockReference::desc();
for(pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) {
AcDbEntity *pEnt = NULL;
pBlockIterator->getEntity(pEnt, AcDb::kForRead);
if(pEnt){
XDbObject obj(pEnt);
if(pEnt->isA() == pClass) {
AcDbBlockReference *pRef=(AcDbBlockReference *)pEnt;
if(pRef->blockTableRecord() == id){ //材质块
resbuf *rb=pRef->xData("AVE_MATERIAL");
if(!rb){
continue;
}
RBList rbList(rb);
Groups *group=rbList.SearchNode(1000);
if(group) {
if(stricmp(group->string, "*全局*") != 0 &&
stricmp(group->string, "*GLOBAL*") != 0)
lstMats.Append(strnew(group->string));
}
}
}
}
}
delete pBlockIterator;
pBlockTableRecord->close();
}
BOOL GetMatByMatName(const char * csMat, CMaterialData &matData)
{
if(!csMat || !csMat[0])
return FALSE;
CAvRmatParam rmatPara;
rmatPara.mode = AvRmatList;
rmatPara.flags = AvRmatName;
rmatPara.name = strdup(csMat);
AvErrorCode retCode = av_rmat(&rmatPara); //其他信息,如贴图文件没有被释放
if(retCode!=AvRetNorm) {
//free(rmatPara.name);
return FALSE;
}
matData.ConvertFrom(rmatPara);
//free(rmatPara.name);
return TRUE;
}
BOOL DeleteMatInBlk(AcDbObjectId idBlock)
{
XDbBlockTableRec rm_sdb("RM_SDB", AcDb::kForRead);
if(!rm_sdb)
return FALSE;
AcDbObjectId id = rm_sdb.m_pBlockTableRec->objectId();
rm_sdb.Close();
OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlockRec);
if(pBlockRec){
AcDbBlockTableRecordIterator *pRecIter = NULL;
if(pBlockRec->newIterator(pRecIter)!=Acad::eOk || !pRecIter)
return FALSE;
for(pRecIter->start(); !pRecIter->done(); pRecIter->step()) {
AcDbEntity *pEnt = NULL;
if(pRecIter->getEntity(pEnt, AcDb::kForWrite)!=Acad::eOk)
continue;
XDbObject obj(pEnt);
if(pEnt->isA() == AcDbBlockReference::desc()) {
AcDbBlockReference *pRef=(AcDbBlockReference *)pEnt;
if(pRef->blockTableRecord() == id){
pRef->erase();
continue;
}
}
}
delete pRecIter;
}
OPENOBJ_END();
return TRUE;
}
// ******************** 把图块的材质移动到模型空间 ******************************
// 1. 如果模型空间已经存在同名材质,则删除图块的材质。并把模型空间材质附到图块部件
// 2. 如果模型空间没有同名材质,则记录图块材质,删除图块材质,然后在模型空间创建材质并附到图块部件
TARCH_IMPEXP BOOL MoveMaterial2MSpace(AcDbObjectId idBlock)
{
if (av_loadlib() != AvRetNorm) {
acdbFail("Library initialization failed.\n");
return 1;
}
av_initialize();
XDbBlockTableRec rm_sdb("RM_SDB", AcDb::kForRead);
if(!rm_sdb)
return FALSE;
AcDbObjectId id = rm_sdb.m_pBlockTableRec->objectId();
rm_sdb.Close(); //这个不关闭,将造成AV命令执行不正常。
XStringList lstMatName, lstMSpaceMat, lstGroup, lstNewMat;
if(!GetBlkRecMatName(idBlock, lstMatName, lstGroup) || lstMatName.Length() < 1)
return FALSE;
ListCurMatFromMSpace(lstMSpaceMat);
for(int i=0;i<lstMatName.Length();i++){
CString csTmp1 = lstMatName[i];
BOOL flag = TRUE;
for(int j=0;j<lstMSpaceMat.Length();j++){
CString csTmp2 = lstMSpaceMat[j];
if(stricmp(csTmp1, csTmp2)==0){
flag = FALSE;
break;
}
}
if(flag)
lstNewMat.Append(strnew(csTmp1)); //模型空间没有,而图块确有的材质的名称
}
AcDbObjectId idMSpace=GetMSpaceId(acdbCurDwg());
#if (ADS>15)
{ //DbMaterial和AvMaterial同步
AvRprefParam pref;
pref.mode = AvRprefSet;
pref.flags = AvRprefToggle;
pref.toggle.AvRprefSyncDatabaseToggle = TRUE;
pref.toggle.flags = AvRprefSyncDatabase;
AvErrorCode retCode = av_rpref(&pref);
if(retCode!=AvRetNorm)
adsout << av_errorstr(retCode);
}
//R16的AV调用不支持,图块材质的访问,因此要把材质移动到模型空间
/*
AcDbObjectIdArray idArray;
MaterialName2IdFromBlock(idBlock, lstNewMat, idArray);
AcDbIdMapping idMap;
Acad::ErrorStatus esOk=acdbCurDwg()->deepCloneObjects(idArray, idMSpace, idMap, false);
*/
// 创建Db的材质,从外部数据库获取
XString sFilePath;
if(lstNewMat.Length() && FindFile("上华标准材质.TML", sFilePath)) {
CMaterialRecord matRec;
if(matRec.Open(sFilePath)) {
for(matRec.MoveFirst(); !matRec.IsEOF(); matRec.MoveNext()) {
if(lstNewMat.Index(matRec.m_sItem, FALSE)>=0) {
matRec.DbCreate();
lstNewMat.Remove();
CAvRmatParam rmat;
if(matRec.ConvertTo(rmat))
rmat.MatModify();
if(!lstNewMat)
break;
}
}
}
}
#else
// 这一段可能导致图中的最后一个物体被删除
for(i=0;i<lstNewMat.Length();i++){
CString csTmp = lstNewMat[i];
CMaterialData pData;
if(!GetMatByMatName(csTmp, pData))
continue;
AvMatlibParam matLibPara;
matLibPara.mode = AvMatlibDelete;
matLibPara.flags = AvMatlibMaterial;
matLibPara.materialName = strdup(csTmp);
AvErrorCode retCode = av_matlib(&matLibPara);
if(retCode!=AvRetNorm) {
adsout << av_errorstr(retCode);
AfxMessageBox(XString("删除材质%s失败!", (const char *)csTmp));
}
free(matLibPara.materialName);
CAvRmatParam rmat;
if(!pData.ConvertTo(rmat))
return FALSE;
rmat.mode=AvRmatNew;
retCode = av_rmat(&rmat);
if(retCode!=AvRetNorm)
adsout << av_errorstr(retCode);
}
#endif
// 为什么要执行这一句?前面AV调用已经删除了材质了
if(!DeleteMatInBlk(idBlock))
return FALSE;
//#if (ADS<16)
OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlockRec);
if(pBlockRec){
AcDbBlockTableRecordIterator *pRecIter = NULL;
if(pBlockRec->newIterator(pRecIter)!=Acad::eOk || !pRecIter)
return FALSE;
for(pRecIter->start(); !pRecIter->done(); pRecIter->step()) {
AcDbEntity *pEnt = NULL;
if(pRecIter->getEntity(pEnt, AcDb::kForWrite)!=Acad::eOk)
continue;
XDbObject obj(pEnt);
resbuf *pxData = pEnt->xData("TCH_GROUPNAME");
CString csName;
if(pxData) {
CString csMatName;
resbuf *pNext = pxData->rbnext;
if(pNext && pNext->restype == 1000) {
csName = pNext->resval.rstring; //编号
pNext = pNext->rbnext;
}
if(pNext && pNext->restype == 1000)
csMatName = pNext->resval.rstring; //材质
ads_relrb(pxData);
RBList xd2=pEnt->xData("AVE_FINISH");
Groups *rb=xd2.SearchNode(1005);
if(rb) {
AcDbObjectId idMat=MaterialName2IdFromBlock(idMSpace, csMatName);
if(idMat.isValid()) {
AcDbHandle hand=idMat.handle();
char szHand[256]="";
hand.getIntoAsciiBuffer(szHand);
free(rb->string);
rb->string=strdup(szHand);
}
pEnt->setXData(xd2);
}
/*
CAvRmatParam rmatPara;
rmatPara.attachment =AvRmatByObject;
rmatPara.name=strdup(csMatName);
rmatPara.mode = AvRmatAttachResbuf;
rmatPara.flags = AvRmatName|AvRmatRb;
if(av_rmat(&rmatPara)==AvRetNorm) {
resbuf *pXData2 = rmatPara.rb;
pEnt->setXData(pXData2);
}*/
}
}
delete pRecIter;
}
OPENOBJ_END();
//#endif
return TRUE;
}
BOOL IsMultiViewBlock(const AcDbBlockTableRecord *pBlock)
{
BOOL bRet=FALSE;
if(pBlock) {
resbuf *pxData = pBlock->xData(TCHXD); // 读扩展数据
if(pxData) {
resbuf *pNext = pxData->rbnext;
if(pNext && pNext->restype == 1005) {
bRet=TRUE;
}
ads_relrb(pxData);
}
}
return bRet;
}
// 从TArch6Beta1版本升级多视图图块,消除图块中的材质
void UpdateMViewBlock()
{
if (av_loadlib() != AvRetNorm) {
acdbFail("AvLibrary initialization failed.\n");
return;
}
av_initialize();
AcDbObjectIdArray idBlockArray;
AcDbBlockTable *pNewBlockTab=NULL;
VERIFY(acdbCurDwg()->getSymbolTable(pNewBlockTab, AcDb::kForRead)==Acad::eOk);
ASSERT(pNewBlockTab);
AcDbBlockTableIterator *pIterator=NULL;
Acad::ErrorStatus es1=pNewBlockTab->newIterator(pIterator);
pNewBlockTab->close();
if(es1==Acad::eOk && pIterator) {
for(pIterator->start(); !pIterator->done(); pIterator->step()) {
AcDbBlockTableRecord *pRec=NULL;
if(pIterator->getRecord(pRec, AcDb::kForWrite)==Acad::eOk && pRec && !pRec->isFromExternalReference()) {
if(IsMultiViewBlock(pRec))
idBlockArray.append(pRec->objectId());
pRec->close();
}
}
delete pIterator;
}
int nCount=idBlockArray.length();
for(int i=0; i<nCount; i++) {
AcDbObjectId id3d=idBlockArray[i];
// 把材质从图块移动到模型空间
MoveMaterial2MSpace(id3d);
}
PickSet ss(SS_FREE);
RBList mask=ads_buildlist(RTDXF0, "AEC_BLOCK_INSERT", NULL);
if(ss.Get("X", NULL, NULL, mask)==RTNORM) {
long len=ss.Length();
for(long idx=0L; idx<len; idx++) {
Entity ent=ss[idx];
AcDbObjectId idEnt;
acdbGetObjectId(idEnt, ent.name);
TDbBlockInsert *pInsert1=NULL;
if(acdbOpenObject(pInsert1, idEnt, AcDb::kForWrite)==Acad::eOk && pInsert1) {
if(pInsert1->IsMultiView()) {
TDbMultiViewInsert *pInsert2=new TDbMultiViewInsert;
pInsert2->setPropertiesFrom(pInsert1);
pInsert2->SetBlockId(TRUE, pInsert1->blockTableRecord());
pInsert2->SetBlockId(FALSE, pInsert1->Get2DBlockId());
XPoint ptLoc=pInsert1->position();
pInsert2->SetLocation(ptLoc);
pInsert2->SetScaleFactors(pInsert1->scaleFactors());
pInsert2->SetRotation(pInsert1->rotation());
Acad::ErrorStatus es=pInsert1->handOverTo(pInsert2);
if(es==Acad::eObjectToBeDeleted) {
pInsert2->close();
delete pInsert1;
} else {
pInsert1->close();
delete pInsert2; // ZJQ add this line on 2003/10/16
}
} else {
pInsert1->close();
}
}
/*
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbBlockInsert, pInsert);
int nFlag=pInsert->GetMaskFlag();
if(nFlag&BIF_T6BETA1) {
nFlag &= ~BIF_T6BETA1;
pInsert->SetMaskFlag(nFlag);
}
OPENOBJ_END();
*/
}
}
}