void DrawHelper::ConfigDraw( const CString& geType, const CString& drawName ) { MineGEDraw* pDraw = MineGEDrawSystem::GetInstance()->getGEDraw( geType, drawName ); if( pDraw == 0 ) return; // 该绘制效果不存在 pDraw->configExtraParams(); // 配置附加参数 AcDbObjectIdArray objIds; ArxDataTool::GetEntsByType( geType, objIds, false ); if( objIds.isEmpty() ) return; // dwg图形中没有任何geType类型图元 AcTransaction* pTrans = actrTransactionManager->startTransaction(); if( pTrans == 0 ) return; int len = objIds.length(); for( int i = 0; i < len; i++ ) { AcDbObject* pObj; if( Acad::eOk != pTrans->getObject( pObj, objIds.at( i ), AcDb::kForWrite ) ) continue; MineGE* pGE = MineGE::cast( pObj ); if( pGE == 0 ) continue; pGE->configDraw( pDraw->isA()->name() ); // 更新extra param pGE->recordGraphicsModified( true ); // 更新图形 } actrTransactionManager->endTransaction(); AcRxClass* pClass = AcRxClass::cast( acrxClassDictionary->at( geType ) ); if( pClass != 0 && pClass->isDerivedFrom( LinkedGE::desc() ) ) { UpdateLinkedGE( objIds ); } }
void DrawCmd::DrawChimney( void ) { acutPrintf( _T( "\n绘制风筒测试..." ) ); AcDbObjectId objId = ArxUtilHelper::SelectObject( _T( "请选择一个掘进工作面:" ) ); if( objId.isNull() ) return; if( !ArxUtilHelper::IsEqualType( _T( "TTunnel" ), objId ) ) return; AcDbObjectIdArray objIds; DrawHelper::GetTagGEById2( objId, _T( "Chimney" ), objIds ); if( !objIds.isEmpty() ) { AfxMessageBox( _T( "该掘进工作面已设置了风筒!" ) ); return; } AcGePoint3dArray pts; PolyLineJig jig; if( !jig.doJig( pts ) ) return; int len = pts.length(); acutPrintf( _T( "\n点个数:%d" ), len ); if( len < 2 ) return; Chimney* pChimney = new Chimney(); pChimney->setRelatedGE( objId ); // 关联的图元必须是掘进工作面 for( int i = 0; i < len; i++ ) pChimney->addControlPoint( pts[i] ); // 初始化并提交到数据库 if( !ArxUtilHelper::PostToModelSpace( pChimney ) ) delete pChimney; }
void DrawHelper::SwitchDraw( const CString& geType, const CString& drawName ) { // 设置当前可视化效果 if( !SetCurDraw( geType, drawName ) ) return; // 更新所有指定类型的图元 AcDbObjectIdArray objIds; ArxDataTool::GetEntsByType( geType, objIds, false ); if( objIds.isEmpty() ) return; // dwg图形中没有任何MineGE类型图元 // 将所有geType类型图元的绘制效果更新 AcTransaction* pTrans = actrTransactionManager->startTransaction(); if( pTrans == 0 ) return; int len = objIds.length(); for( int i = 0; i < len; i++ ) { AcDbObject* pObj; if( Acad::eOk != pTrans->getObject( pObj, objIds.at( i ), AcDb::kForWrite ) ) continue; MineGE* pGE = MineGE::cast( pObj ); if( pGE == 0 ) continue; pGE->updateDraw(); // 更细可视化效果指针 //pGE->recordGraphicsModified(true); // 更新图形 } actrTransactionManager->endTransaction(); AcRxClass* pClass = AcRxClass::cast( acrxClassDictionary->at( geType ) ); if( pClass != 0 && pClass->isDerivedFrom( LinkedGE::desc() ) ) { UpdateLinkedGE( objIds ); } }
bool ArxEntityHelper::SelectEntities( const AcDbObjectIdArray& objIds ) { //acedSSSetFirst(NULL, NULL); if( objIds.isEmpty() ) return false; ads_name ss; //创建一个空的选择集 if(RTNORM != acedSSAdd( NULL, NULL, ss )) return false; bool ret = true; for(int i=0;i<objIds.length();i++) { ads_name ename; if( Acad::eOk != acdbGetAdsName( ename, objIds[i] ) ) { ret = false;; break; } if( RTNORM != acedSSAdd( ename, ss, ss ) ) // 添加到选择集 { ret = false;; break; } } if(ret) { acedSSSetFirst( ss, NULL ); // 高亮选中 } acedSSFree( ss ); // 释放选择集 return ret; }
// 从图元的扩展词典中查找数据对象 static void GetDataObjectFromExtDict( AcDbObjectIdArray& dbObjIds ) { AcDbObjectIdArray allObjIds; ArxDataTool::GetEntsByType( _T( "MineGE" ), allObjIds, true ); // 判断是否数据对象DataObject // 且类型名称==type if( allObjIds.isEmpty() ) return; AcTransaction* pTrans = actrTransactionManager->startTransaction(); if( pTrans == 0 ) return; int len = allObjIds.length(); for( int i = 0; i < len; i++ ) { AcDbObject* pObj; if( Acad::eOk != pTrans->getObject( pObj, allObjIds[i], AcDb::kForRead ) ) continue; MineGE* pGE = MineGE::cast( pObj ); if( pGE == 0 ) continue; AcDbObjectId dbObjId = pGE->getDataObject(); if( !dbObjId.isNull() ) { dbObjIds.append( dbObjId ); } } actrTransactionManager->endTransaction(); }
void DrawCmd::DrawLocalFan() { AcDbObjectId objId = ArxUtilHelper::SelectObject( _T( "请选择一个掘进工作面:" ) ); if( objId.isNull() ) return; if( !ArxUtilHelper::IsEqualType( _T( "TTunnel" ), objId ) ) return; AcDbObjectIdArray objIds; DrawHelper::GetTagGEById2( objId, _T( "LocalFan" ), objIds ); if( !objIds.isEmpty() ) { AfxMessageBox( _T( "该掘进工作面已设置了局部通风机!" ) ); return; } AcGePoint3d pt; if( !ArxUtilHelper::PromptPt( _T( "\n请指定局扇的插入点坐标:" ), pt ) ) return; Fan* pFan = new LocalFan( pt, 0 ); // 目前假设局扇的角度为0(实际绘图中局扇是没有方向的) if( pFan == 0 ) return; pFan->setRelatedGE( objId ); // 关联巷道 // 初始化并提交到数据库 if( !ArxUtilHelper::PostToModelSpace( pFan ) ) delete pFan; }
void DrawHelper::GetTagGEById2( const AcDbObjectId& objId, const CString& geType, AcDbObjectIdArray& objIds ) { // 查找图元ObjId关联的所有标签 AcDbObjectIdArray allObjIds; DrawHelper::GetAllTagGEById( objId, allObjIds ); if( allObjIds.isEmpty() ) return; // 筛选出类型为geType的tag GetTagGEById2_Helper( geType, allObjIds, objIds ); }
void ArxEntityHelper::EraseObjects2( const AcDbObjectIdArray& objIds, Adesk::Boolean erasing ) { if( objIds.isEmpty() ) return; int len = objIds.length(); for( int i = 0; i < len; i++ ) { EraseObject2( objIds[i], erasing ); } }
void DrawCmd::DrawEffectRanGE() { AcDbObjectIdArray ttunels; DrawHelper::FindMineGEs(_T("TTunnel"),ttunels); int len = ttunels.length(); if(ttunels.isEmpty()) return; for (int i = 0; i < len; i++) { EffectRanDrawed(ttunels[i]); } }
void DrawCmd::DrawQTagGE() { AcDbObjectIdArray chims; DrawHelper::FindMineGEs(_T("Chimney"),chims); int len = chims.length(); //acutPrintf(_T("\n风筒数:%d"),len); if(chims.isEmpty()) return; for (int i = 0; i < len; i++) { QTagGEDrawed(chims[i]); } }
static AcDbObjectId GetContourInfoOnLayer( const CString& layer ) { AcDbObjectIdArray allObjIds; LayerHelper::GetAllEntitiesOnLayer( layer, allObjIds ); AcDbObjectIdArray objIds; ArxDataTool::FilterEntsByType( _T( "ContourInfo" ), allObjIds, objIds ); if( objIds.isEmpty() ) return AcDbObjectId::kNull; else return objIds[0]; }
static void EffectRanDrawed(AcDbObjectId ttunel) { AcTransaction *pTrans = actrTransactionManager->startTransaction(); if ( 0 == pTrans ) return; AcDbObject *pObj; if (Acad::eOk != pTrans->getObject(pObj,ttunel,AcDb::kForRead)) return; TTunnel *pTTunnel = TTunnel::cast(pObj); if ( 0 == pTTunnel) { actrTransactionManager->abortTransaction(); return; } AcGePoint3d spt,ept; pTTunnel->getSEPoint(spt,ept); double angle = pTTunnel->getAngle(); actrTransactionManager->endTransaction(); AcDbObjectIdArray eTags; DrawHelper::GetTagGEById2( ttunel, _T( "EffectRanTagGE" ), eTags ); if (!eTags.isEmpty()) { ArxEntityHelper::EraseObjects( eTags, true ); } AcGeVector3d v = ept - spt; double diatance = v.length(); CString area,way; if(!DataHelper::GetPropertyData(ttunel,_T("断面面积"),area)) return; if(!DataHelper::GetPropertyData(ttunel,_T("通风方法"),way)) return; double minDistan,maxDistan; if(way.IsEmpty()) return; if(area.IsEmpty()) return; if (_T("压入式") == way || _T("长压短抽") == way) { minDistan = 4*sqrtf(_tstof(area)); maxDistan = 5*sqrtf(_tstof(area)); } else { minDistan = 0; maxDistan = 1.5*sqrtf(_tstof(area)); } EffectRanTagGE *pTag = new EffectRanTagGE(ept,angle,minDistan,maxDistan,diatance*0.1); if (0 == pTag) return; pTag->setRelatedGE(ttunel); if( !ArxUtilHelper::PostToModelSpace( pTag ) ) delete pTag; }
void DrawCmd::UpdateAllWindStationData() { // 查找所有的测风站 // 将所在宿主上的面积、风速、风量数据读取到测风站中 AcDbObjectIdArray objIds; DrawHelper::FindMineGEs( _T( "WindStation" ), objIds ); if( objIds.isEmpty() ) return; AcTransaction* pTrans = actrTransactionManager->startTransaction(); if( pTrans == 0 ) return; AcDbObjectIdArray geObjIds; int len = objIds.length(); bool ret = true; for( int i = 0; i < len; i++ ) { AcDbObject* pObj; if( Acad::eOk != pTrans->getObject( pObj, objIds[i], AcDb::kForRead ) ) { ret = false; break; } TagGE* pTag = TagGE::cast( pObj ); if( pTag == 0 ) { ret = false; break; } geObjIds.append( pTag->getRelatedGE() ); } actrTransactionManager->endTransaction(); if( !ret ) { geObjIds.removeAll(); } else { //assert(objIds.length() == geObjIds.length()); int len = objIds.length(); for( int i = 0; i < len; i++ ) { ReadWriteData( geObjIds[i], _T( "断面面积" ), objIds[i], _T( "测试断面面积" ) ); ReadWriteData( geObjIds[i], _T( "风速" ), objIds[i], _T( "测试风速" ) ); ReadWriteData( geObjIds[i], _T( "风量" ), objIds[i], _T( "测试风量" ) ); } } }
void ArxEntityHelper::TransformEntities2( const AcDbObjectIdArray& objIds, const AcGeMatrix3d& xform ) { if( objIds.isEmpty() ) return; int len = objIds.length(); for( int i = 0; i < len; i++ ) { AcDbEntity* pEnt; if( Acad::eOk == acdbOpenAcDbEntity( pEnt, objIds[i], AcDb::kForWrite ) ) { pEnt->transformBy( xform ); pEnt->close(); } } }
bool FieldHelper::AddField( const CString& type, const CString& field ) { if( IsEmptyString( type ) || IsEmptyString( field ) ) return false; bool ret = AddField_Helper( PROPERTY_DATA_FIELD_DICT, type, field ); if( ret ) { AcDbObjectIdArray objIds; GetDataObjectsByType( type, objIds ); if( !objIds.isEmpty() ) { AddFieldToDataObject( objIds ); } } return ret; }
void ArxEntityHelper::EraseObjects( const AcDbObjectIdArray& objIds, Adesk::Boolean erasing ) { if( objIds.isEmpty() ) return; AcTransaction* pTrans = actrTransactionManager->startTransaction(); if( pTrans == 0 ) return; int len = objIds.length(); for( int i = 0; i < len; i++ ) { AcDbObject* pObj; if( Acad::eOk != pTrans->getObject( pObj, objIds[i], AcDb::kForWrite, !erasing ) ) continue; pObj->erase( erasing ); // (反)删除图元 } actrTransactionManager->endTransaction(); }
bool FieldHelper::RemoveField( const CString& type, const CString& field ) { if( IsEmptyString( type ) || IsEmptyString( field ) ) return false; int index = RemoveField_Helper( PROPERTY_DATA_FIELD_DICT, type, field ); bool ret = ( INVALID_ENTRY != index ); if( ret ) { // 删除图元中的字段 AcDbObjectIdArray objIds; GetDataObjectsByType( type, objIds ); if( !objIds.isEmpty() ) { RemoveFieldFromDataObject( objIds, index ); } } return ret; }
void DrawCmd::AutoDirection() { AcDbObjectIdArray objIds; DrawHelper::FindMineGEs( _T( "LinkedGE" ), objIds ); if( objIds.isEmpty() ) return; // 删除所有的风流方向 EraseAllDirections(); AcGePoint3dArray spts, epts; GetSEPts( objIds, spts, epts ); int len = objIds.length(); for( int i = 0; i < len; i++ ) { // 添加风流方向 AddDirection( objIds[i], spts[i], epts[i] ); } }
void ArxEntityHelper::TransformEntities( const AcDbObjectIdArray& objIds, const AcGeMatrix3d& xform ) { if( objIds.isEmpty() ) return; AcTransaction* pTrans = actrTransactionManager->startTransaction(); if( pTrans == 0 ) return; int len = objIds.length(); for( int i = 0; i < len; i++ ) { AcDbObject* pObj; if( Acad::eOk != pTrans->getObject( pObj, objIds[i], AcDb::kForWrite ) ) continue; AcDbEntity* pEnt = AcDbEntity::cast( pObj ); if( pEnt == 0 ) continue; pEnt->transformBy( xform ); } actrTransactionManager->endTransaction(); }
void WindStationDockBarChildDlg::readPropertyData( const AcDbObjectId& objId ) { int pos = m_objIds.find( objId ); if( pos < 0 ) return; AcDbObjectIdArray stations; DrawHelper::GetTagGEById2( m_hosts[pos], _T( "WindStation" ), stations ); if( stations.isEmpty() ) { m_hasStation = FALSE; } else { m_hasStation = TRUE; DataHelper::GetPropertyData( stations[0], _T( "名称" ), m_name ); DataHelper::GetPropertyData( stations[0], _T( "测试断面面积" ), m_area ); DataHelper::GetPropertyData( stations[0], _T( "测试风速" ), m_v ); DataHelper::GetPropertyData( stations[0], _T( "测试风量" ), m_q ); } UpdateData( FALSE ); }
void DrawHelper::ShowAllTagGE( const AcDbObjectId& objId, unsigned short colorIndex ) { AcDbObjectIdArray objIds; DrawHelper::GetAllTagGEById( objId, objIds ); PrintMsg( objIds.length() ); if( objIds.isEmpty() ) return; // 记录原来的颜色 AcArray<Adesk::UInt16> colors; if( !ArxEntityHelper::GetEntitiesColor( objIds, colors ) ) return; // 用黄色高亮显示标签图元 ArxEntityHelper::SetEntitiesColor( objIds, colorIndex ); // 中断 ArxUtilHelper::Pause(); // 恢复原有颜色 ArxEntityHelper::SetEntitiesColor2( objIds, colors ); }
static void FanTagGEDrawed(AcDbObjectId fanId) { AcTransaction *pTrans = actrTransactionManager->startTransaction(); if ( 0 == pTrans ) return; AcDbObject *pObj; if (Acad::eOk != pTrans->getObject(pObj,fanId,AcDb::kForRead)) return; LocalFan *pFan = LocalFan::cast(pObj); if ( 0 == pFan) { actrTransactionManager->abortTransaction(); return; } AcGePoint3d insertPt = pFan->getInsertPt(); actrTransactionManager->endTransaction(); AcDbObjectIdArray fanTags; DrawHelper::GetTagGEById2( fanId, _T( "FanTagGE" ), fanTags ); if (!fanTags.isEmpty()) { ArxEntityHelper::EraseObjects( fanTags, true ); } CString name,qStr,hStr,way; DataHelper::GetPropertyData(fanId,_T("风机型号"),name); DataHelper::GetPropertyData(fanId,_T("工作风量(m3/s)"),qStr); DataHelper::GetPropertyData(fanId,_T("工作风压(Pa)"),hStr); DataHelper::GetPropertyData(fanId,_T("工作方式"),way); FanTagGE *pFanTag = new FanTagGE(insertPt,name,way,_tstof(qStr),_tstof(hStr)); if( pFanTag == 0 ) return; //acutPrintf(_T("\ninsertPt:(%lf,%lf),angle:%lf"),insertPt.x,insertPt.y,angle); pFanTag->setRelatedGE( fanId ); // 关联局扇 // 初始化并提交到数据库 if( !ArxUtilHelper::PostToModelSpace( pFanTag ) ) delete pFanTag; }
void WindStationDockBarChildDlg::writePropertyData( const AcDbObjectId& objId ) { UpdateData( TRUE ); int pos = m_objIds.find( objId ); if( pos < 0 ) return; AcDbObjectIdArray stations; DrawHelper::GetTagGEById2( m_hosts[pos], _T( "WindStation" ), stations ); if( stations.isEmpty() ) return; if( m_hasStation ) { CString v1; v1.Format( _T( "%d" ), 1 ); // 默认都是按照规定测风 DataHelper::SetPropertyData( stations[0], _T( "是否按规定测风" ), v1 ); DataHelper::SetPropertyData( stations[0], _T( "名称" ), m_name ); DataHelper::SetPropertyData( stations[0], _T( "测试断面面积" ), m_area ); DataHelper::SetPropertyData( stations[0], _T( "测试风速" ), m_v ); DataHelper::SetPropertyData( stations[0], _T( "测试风量" ), m_q ); } }
static void GetModelGEById_Helper( const AcDbObjectId& objId, const AcDbObjectIdArray& modelObjIds, AcDbObjectIdArray& objIds ) { if( modelObjIds.isEmpty() ) return; AcTransaction* pTrans = actrTransactionManager->startTransaction(); if( pTrans == 0 ) return; int len = modelObjIds.length(); for( int i = 0; i < len; i++ ) { AcDbObject* pObj; if( Acad::eOk != pTrans->getObject( pObj, modelObjIds[i], AcDb::kForRead ) ) continue; ModelGE* pModel = ModelGE::cast( pObj ); if( pModel == 0 ) continue; if( pModel->getDataObject() == objId ) { objIds.append( modelObjIds[i] ); } } actrTransactionManager->endTransaction(); }
static void GetAllTagGEById_Helper( const AcDbObjectId& objId, const AcDbObjectIdArray& tagObjIds, AcDbObjectIdArray& objIds ) { if( tagObjIds.isEmpty() ) return; //acutPrintf(_T("\n找到%d个图元,进行比较判断..."), tagObjIds.length()); AcTransaction* pTrans = actrTransactionManager->startTransaction(); if( pTrans == 0 ) return; int len = tagObjIds.length(); for( int i = 0; i < len; i++ ) { AcDbObject* pObj; if( Acad::eOk != pTrans->getObject( pObj, tagObjIds[i], AcDb::kForRead ) ) continue; TagGE* pTag = TagGE::cast( pObj ); if( pTag == 0 ) continue; if( pTag->getRelatedGE() == objId ) { objIds.append( tagObjIds[i] ); } } actrTransactionManager->endTransaction(); }
Acad::ErrorStatus CZhfPalette::Wblock(AcDbDatabase*& pDbFrom, AcDbDatabase*& pDbTo, /*const AcGePoint3d& pt_3d_base,*/ const AcGeMatrix3d & xform) { Acad::ErrorStatus es ; AcDbObjectIdArray objIdsOut; AcDbBlockTable* pBT = NULL ; pDbFrom->getBlockTable(pBT, AcDb::kForRead); AcDbBlockTableRecord* pBTR = NULL; es = pBT->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForRead); pBT->close(); AcDbBlockTableRecordIterator* pIT; es = pBTR->newIterator(pIT) ; for (; !pIT->done(); pIT->step()) { AcDbEntity* pEnt = NULL ; if (Acad::eOk==pIT->getEntity(pEnt, AcDb::kForRead)) { // if (!pEnt->isKindOf(AcDbAttributeDefinition::desc())) // { AcDbObjectId objId; if (Acad::eOk == pIT->getEntityId(objId)) { objIdsOut.append(objId); } // } pEnt->close() ; } } delete pIT; pBTR->close(); if (!objIdsOut.isEmpty()) { for (int i=0; i<objIdsOut.length(); i++) { AcDbObjectId objId = objIdsOut.at(i); AcDbEntity *pEnt = NULL ; if(Acad::eOk==acdbOpenAcDbEntity(pEnt,objId, AcDb::kForRead)) { AcDbObjectId objIdDic ; if ((objIdDic = pEnt->extensionDictionary())!= AcDbObjectId::kNull) { AcDbDictionary *pDict = NULL; if (Acad::eOk==acdbOpenObject(pDict, objIdDic, AcDb::kForWrite)) { pDict->setTreatElementsAsHard(Adesk::kTrue); pDict->close(); } } pEnt->close() ; } } AcDbDatabase *pTempDb ; es = pDbFrom->wblock( pTempDb, objIdsOut, AcGePoint3d::kOrigin ) ; if (Acad::eOk != es ) { acedAlert( _T("wblock failed!") ); return es ; } es = pDbTo->insert( xform, pTempDb ) ; if (Acad::eOk != es) acedAlert( _T("insert failed!" )); if (pTempDb) { delete pTempDb; pTempDb = NULL ; } } else { acutPrintf(_T("\nNo entities found in model space of DWG")); } return es ; }
Acad::ErrorStatus ArxDbgDbEntity::deepClone(AcDbObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { // You should always pass back pClonedObject == NULL // if, for any reason, you do not actually clone it // during this call. The caller should pass it in // as NULL, but to be safe, we set it here as well. pClonedObject = NULL; if (ArxDbgOptions::m_instance.m_showDeepCloneDetails) { CString titleStr, tmpStr; titleStr.Format(_T("Beginning -- deepClone: %s"), ArxDbgUtils::objToClassAndHandleStr(const_cast<ArxDbgDbEntity*>(this), tmpStr)); ArxDbgUiTdmIdMap dbox(&idMap, acedGetAcadDwgView(), titleStr); dbox.DoModal(); } AcDb::DeepCloneType type = idMap.deepCloneContext(); // if we know everything will be cloned for us, just let // the base class do everything for us. if ((type == AcDb::kDcInsert) || (type == AcDb::kDcInsertCopy) || (type == AcDb::kDcExplode)) return AcDbEntity::deepClone(pOwner, pClonedObject, idMap, isPrimary); // following case happens when doing a AcDbDatabase::deepCloneObjects() // and the owner happens to be the same... then its really like a // kDcCopy, otherwise deepCloneObjects() is like a kDcBlock if (type == AcDb::kDcObjects) { if (ownerId() == pOwner->objectId()) type = AcDb::kDcCopy; else type = AcDb::kDcBlock; } // now ask derived classes what references they want cloned for them AcDbObjectIdArray refEntIds; AcDbIntArray refTypes; getCloneReferences(type, refEntIds, refTypes); ASSERT(refEntIds.length() == refTypes.length()); // if derived class doesn't have any references to take care of, then // we will just let the AcDbEntity::deepClone() take care of things. if (refEntIds.isEmpty()) return AcDbEntity::deepClone(pOwner, pClonedObject, idMap, isPrimary); // If this object is in the idMap and is already // cloned, then return. bool tmpIsPrimary = isPrimary ? true : false; // get around compiler performance warning AcDbIdPair idPair(objectId(), AcDbObjectId::kNull, false, tmpIsPrimary); if (idMap.compute(idPair) && (idPair.value() != NULL)) return Acad::eOk; // STEP 1: // Create the clone // AcDbObject *pClone = (AcDbObject*)isA()->create(); if (pClone != NULL) pClonedObject = pClone; // set the return value else return Acad::eOutOfMemory; // STEP 2: // Append the clone to its new owner. In this example, // we know that we are derived from AcDbEntity, so we // can expect our owner to be an AcDbBlockTableRecord, // unless we have set up an ownership relationship with // another of our objects. In that case, we need to // establish how we connect to that owner in our own // way. This sample shows a generic method using // setOwnerId(). // AcDbBlockTableRecord *pBTR = AcDbBlockTableRecord::cast(pOwner); if (pBTR != NULL) { AcDbEntity* ent = AcDbEntity::cast(pClone); pBTR->appendAcDbEntity(ent); } else { if (isPrimary) return Acad::eInvalidOwnerObject; // Some form of this code is only necessary if // anyone has set up an ownership for our object // other than with an AcDbBlockTableRecord. // pOwner->database()->addAcDbObject(pClone); pClone->setOwnerId(pOwner->objectId()); } // STEP 3: // Now we copy our contents to the clone. This is done // using an AcDbDeepCloneFiler. This filer keeps a // list of all AcDbHardOwnershipIds and // AcDbSoftOwnershipIds we, and any classes we derive // from, have. This list is then used to know what // additional, "owned" objects need to be cloned below. // AcDbDeepCloneFiler filer; dwgOut(&filer); // STEP 4: // Rewind the filer and read the data into the clone. // filer.seek(0L, AcDb::kSeekFromStart); pClone->dwgIn(&filer); // STEP 5: // This must be called for all newly created objects // in deepClone. It is turned off by endDeepClone() // after it has translated the references to their // new values. // pClone->setAcDbObjectIdsInFlux(); // STEP 6: // Add the new information to the idMap. We can use // the idPair started above. // idPair.setValue(pClonedObject->objectId()); idPair.setIsCloned(Adesk::kTrue); idMap.assign(idPair); // STEP 7: // Using the filer list created above, find and clone // any owned objects. // AcDbObject *pSubObject; AcDbObject *pClonedSubObject; AcDbObjectId id; Acad::ErrorStatus es; while (filer.getNextOwnedObject(id)) { // Open the object and clone it. Note that we now // set "isPrimary" to kFalse here because the object // is being cloned, not as part of the primary set, // but because it is owned by something in the // primary set. es = acdbOpenAcDbObject(pSubObject, id, AcDb::kForRead); if (es != Acad::eOk) continue; // could have been NULL or erased pClonedSubObject = NULL; pSubObject->deepClone(pClonedObject, pClonedSubObject, idMap, Adesk::kFalse); // If this is a kDcInsert context, the objects // may be "cheapCloned". In this case, they are // "moved" instead of cloned. The result is that // pSubObject and pClonedSubObject will point to // the same object. So, we only want to close // pSubObject if it really is a different object // than its clone. if (pSubObject != pClonedSubObject) pSubObject->close(); // The pSubObject may either already have been // cloned, or for some reason has chosen not to be // cloned. In that case, the returned pointer will // be NULL. Otherwise, since we have no immediate // use for it now, we can close the clone. if (pClonedSubObject != NULL) pClonedSubObject->close(); } // clone the referenced entities AcDbObject* ent; int len = refEntIds.length(); for (int i=0; i<len; i++) { if (refTypes[i] == kClone) { es = acdbOpenAcDbObject(ent, refEntIds[i], AcDb::kForRead); if (es == Acad::eOk) { pClonedSubObject = NULL; es = ent->deepClone(pOwner, pClonedSubObject, idMap, Adesk::kTrue); if (es == Acad::eOk) { // see comment above about cheap clone if (ent != pClonedSubObject) ent->close(); if (pClonedSubObject != NULL) pClonedSubObject->close(); } } } // this case is needed for RefEdit so we can pass its validation // test when editing a blockReference. We don't actually clone it // but we add it to the map so it thinks it got cloned and is therefore // a valid "Closed Set" of objects. else if (refTypes[i] == kFakeClone) { AcDbIdPair idPair(refEntIds[i], refEntIds[i], false, false, true); idMap.assign(idPair); } } if (ArxDbgOptions::m_instance.m_showDeepCloneDetails) { CString titleStr, tmpStr; titleStr.Format(_T("End -- deepClone: %s"), ArxDbgUtils::objToClassAndHandleStr(const_cast<ArxDbgDbEntity*>(this), tmpStr)); ArxDbgUiTdmIdMap dbox(&idMap, acedGetAcadDwgView(), titleStr); dbox.DoModal(); } // Leave pClonedObject open for the caller return Acad::eOk; }
static void QTagGEDrawed(const AcDbObjectId& chimId) { AcTransaction *pTrans = actrTransactionManager->startTransaction(); if ( 0 == pTrans ) return; AcDbObject *pObj; if (Acad::eOk != pTrans->getObject(pObj,chimId,AcDb::kForRead)) return; Chimney *pChim = Chimney::cast(pObj); if ( 0 == pChim) { actrTransactionManager->abortTransaction(); return; } AcGePoint3dArray ctlPts = pChim->getControlPoint(); AcDbObjectId fanId; if(!DrawHelper::GetHostGE(chimId,fanId)) return; if (Acad::eOk != pTrans->getObject(pObj,fanId,AcDb::kForRead)) return; LocalFan *pFan = LocalFan::cast(pObj); if ( 0 == pFan) { actrTransactionManager->abortTransaction(); return; } AcGePoint3d insertPt = pFan->getInsertPt(); actrTransactionManager->endTransaction(); AcDbObjectIdArray QTags; DrawHelper::GetTagGEById2( chimId, _T( "QTagGE" ), QTags ); if (!QTags.isEmpty()) { ArxEntityHelper::EraseObjects( QTags, true ); } CString inQStr,outQStr; DataHelper::GetPropertyData(chimId,_T("入口风量(m3/s)"),inQStr); DataHelper::GetPropertyData(chimId,_T("出口风量(m3/s)"),outQStr); CString way; DataHelper::GetPropertyData(fanId,_T("工作方式"),way); if(way.IsEmpty() || inQStr.IsEmpty() || outQStr.IsEmpty()) return; QTagGE *pInQTag,*pOutQTag; if( _T("压入式") == way ) { pInQTag = new QTagGE(ctlPts[0],_tstof(inQStr)); if( pInQTag == 0 ) return; pOutQTag = new QTagGE(ctlPts[ctlPts.length()-1],_tstof(outQStr)); if( pOutQTag == 0 ) return; } if( _T("抽出式") == way ) { pOutQTag = new QTagGE(ctlPts[0],_tstof(outQStr)); if( pOutQTag == 0 ) return; pInQTag = new QTagGE(ctlPts[ctlPts.length()-1],_tstof(inQStr)); if( pInQTag == 0 ) return; } pOutQTag->setRelatedGE( chimId ); // 关联风筒 pInQTag->setRelatedGE( chimId ); // 关联风筒 // 初始化并提交到数据库 if( !ArxUtilHelper::PostToModelSpace( pOutQTag ) ) delete pOutQTag; if( !ArxUtilHelper::PostToModelSpace( pInQTag ) ) delete pInQTag; }
void ArxDbgAppEditorReactor::beginDeepCloneXlation( AcDbIdMapping& idMap, Acad::ErrorStatus* es) { m_didTheseDicts.setLogicalLength(0); // reset the dictionaries we have processed AcDbDatabase* origDb; AcDbDatabase* destDb; idMap.origDb(origDb); idMap.destDb(destDb); AcDbObject* clonedObj; AcDbObject* objToClone; // we catch this event so that we can wblock objects that are not entities. // This happens from the class ArxDbgUiTdcWblockClone where you are allowed // to pick non-entities to wblock to a new/existing drawing. AcDbDatabase::wblock() // only allows entities to be in the set of objects passed to it, but you // can manually wblockClone them yourself here. if (idMap.deepCloneContext() == AcDb::kDcWblock) { // see what non-entity objects we have to clone by hand. AcDbObjectIdArray handCloneObjects; m_cloneSet.getObjectsForDatabase(origDb, handCloneObjects); if (handCloneObjects.isEmpty()) return; // walk through the clone set and try to clone // everything. If something is already cloned, // its ok, it won't be cloned again or return an // error, it will just set clonedObj to NULL. CString str; int len = handCloneObjects.length(); for (int i=0; i<len; i++) { clonedObj = NULL; if (acdbOpenAcDbObject(objToClone, handCloneObjects[i], AcDb::kForRead) == Acad::eOk) { objToClone->wblockClone(destDb, clonedObj, idMap, Adesk::kFalse); if (clonedObj != NULL) { acutPrintf(_T("\nArxDbgAppEditorReactor: cloned additional object [%s, %s]"), ArxDbgUtils::objToClassStr(clonedObj), ArxDbgUtils::objToHandleStr(objToClone, str)); clonedObj->close(); } objToClone->close(); } } } // catching this event allows us to correctly bring in our Dictionary Records. // If we don't do this, then they will be orphaned. AutoCAD will not hook up // the cloned dictionary records automatically. else if ((ArxDbgOptions::m_instance.m_doDictRecordInsertByHand) && ((idMap.deepCloneContext() == AcDb::kDcInsert) || (idMap.deepCloneContext() == AcDb::kDcInsertCopy))) { // have to manually find all things we are interested in inserting. // So, look for all ArxDbgDictRecords, if its a dict record, // make sure owner dict is cloned in new database AcDbObjectIdArray objIds; collectAllDictRecords(origDb, objIds); int len = objIds.length(); for (int i=0; i<len; i++) { // find out if object is a dict record Acad::ErrorStatus es; es = acdbOpenObject(objToClone, objIds[i], AcDb::kForRead); if (es == Acad::eOk) { acutPrintf("\nArxDbgAppEditorReactor: hand inserting [%s]", ArxDbgUtils::objToClassStr(objToClone)); // clone the owner dictionary if one of our dictionary records if (objToClone->isKindOf(ArxDbgDbDictRecord::desc())) insertCloneOwnerDict(objToClone->ownerId(), destDb, idMap); objToClone->close(); } } } }
static bool HasStation( const AcDbObjectId& objId ) { AcDbObjectIdArray stations; DrawHelper::GetTagGEById2( objId, _T( "WindStation" ), stations ); return !( stations.isEmpty() ); }