#include "stdafx.h" #include #include "AecDbCurveBase.h" #include "AcGiViewDraw.h" #include "AcGiExplodeDraw.h" #include "simpleproperty.h" #include "dbobjptr.h" #include "AecDbObjXDataMap.h" #include "AecDbEntityBase.h" #include "dbgrip.h" #include "AecGripCback.h" #include "GrPolyhedronGeometry.h" using namespace GrPolyhedronGeometry; static const Adesk::UInt16 kRed = 1; BOOL ReadModelXData(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap, AcDbDatabase* pDb); BOOL WriteModelXData(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap, AcDbDatabase* pDb); extern CString IDCreate(); const Adesk::UInt16 kColorByLayer = 256; #ifndef _ttof #define _ttof(pszVal) _tcstod((pszVal), NULL) #endif ACRX_NO_CONS_DEFINE_MEMBERS(AecDbCurveBase, AcDbCurve); namespace { void FreeBuffer(int n, AcDbVoidPtrArray& arEntPtrs) { AcDbEntity* pEnt = NULL; while (arEntPtrs.length() > n) { pEnt = (AcDbEntity*)arEntPtrs.last(); pEnt->erase(); pEnt->close(); DELETE_PTR(pEnt); arEntPtrs.removeLast(); } } } AecDbCurveBase::AecDbCurveBase(void) { m_eExplodeOrDrawType = kWroldDraw; m_nDrawDimCur = -1; } AecDbCurveBase::~AecDbCurveBase(void) { FreeBuffer(0, m_ar2DDrableBufPtrs_); FreeBuffer(0, m_ar3DDrableBufPtrs_); } static void ReleaseEntSet(AcDbVoidPtrArray &entSet) { while(!entSet.isEmpty()) { AcDbEntity *pEnt = AcDbEntity::cast((AcDbEntity *)entSet[0]); if (pEnt != NULL) { DELETE_PTR(pEnt); } entSet.removeAt(0); } } Adesk::UInt32 AecDbCurveBase::subViewportDrawLogicalFlags(AcGiViewportDraw * vd) { Adesk::UInt32 nRet = AcDbCurve::subViewportDrawLogicalFlags(vd); Adesk::UInt32 nFlagNew = nRet; int nDrawMode = GetDrawMode(); DrawModeType nDrawType = k2Dand3D; int nDraw = GetDrawDimOnType(nDrawMode, nDrawType); if (nDraw != 3) { nFlagNew |= AcGiDrawable::kDrawableViewIndependentViewportDraw; } else { nFlagNew |= kDrawableRegenDraw;//256 } return nFlagNew; } Adesk::UInt32 AecDbCurveBase::subSetAttributes(AcGiDrawableTraits * traits) { Adesk::UInt32 nRet = AcDbCurve::subSetAttributes(traits); int nDrawMode = GetDrawMode(); DrawModeType nDrawType = k2Dand3D; int nDraw = GetDrawDimOnType(nDrawMode, nDrawType); Adesk::UInt32 nFlagNew = nRet; nFlagNew |= AcGiDrawable::kDrawableViewIndependentViewportDraw; return nFlagNew; } Adesk::Boolean AecDbCurveBase::subWorldDraw(AcGiWorldDraw *pWd) { assertReadEnabled(); m_eExplodeOrDrawType = kWroldDraw; AcGiViewDraw dc(pWd, NULL); dc.SetDrawRaw(this); //1.如果是保存代理图形 AcGiRegenType nRegenType = pWd->regenType(); if (nRegenType == kAcGiSaveWorldDrawForProxy) { ads_point pt; struct resbuf rb; acedGetVar(_T("VIEWDIR"),&rb); ads_point_set(rb.resval.rpoint,pt); ads_point viewDir; acdbUcs2Wcs(pt,viewDir,false); if (fabs(viewDir[X]) > 1.0e-6 || fabs(viewDir[Y]) > 1.0e-6) { Draw3d(dc); m_nDrawDimCur = 3; } else { Draw2d(dc); m_nDrawDimCur = 2; } return Adesk::kTrue; } //设属性 dc.SetLayer(_T("0")); dc.SetColor(256); //如果图层关闭 AcDbLayerTableRecordPointer pLayer; if ( Acad::eOk == pLayer.open(layerId(), AcDb::kForRead) ) { if ( pLayer->isOff() ) { return Adesk::kTrue; } } int nDrawMode = GetDrawMode(); DrawModeType nDrawType = k2Dand3D; int nDraw = GetDrawDimOnType(nDrawMode, nDrawType); if (nRegenType == kAcGiSaveWorldDrawForProxy || nRegenType == kAcGiSaveWorldDrawForR12) { if (!!ownerId()) { pWd->subEntityTraits().setSelectionMarker(0); dc.SetColor(colorIndex()); dc.SetLayer(layerId()); } if ((nDrawMode & DRAW_2D) && (nDrawType != k3DOnly)) { Draw2d(dc); m_nDrawDimCur = 2; } else if ((nDrawMode & DRAW_3D) && (nDrawType != k2DOnly)) { Draw3d(dc); m_nDrawDimCur = 3; } return Adesk::kTrue; } return Adesk::kFalse; } void AecDbCurveBase::subViewportDraw(AcGiViewportDraw* pMode) { assertReadEnabled(); m_eExplodeOrDrawType = kViewportDraw; AcGiRegenType nRegenType = pMode->regenType(); AcGiViewport &vp = pMode->viewport(); AcGePoint3d ptCamera, ptTarget; vp.getCameraTarget(ptTarget); vp.getCameraLocation(ptCamera); AcGeVector3d vtViewDrt = ptCamera-ptTarget; AcGeVector3d vtViewDir1 = vp.viewDir(); AcGeVector3d vtCamera; vp.getCameraUpVector(vtCamera); vtViewDrt.normalize(); AcGiViewDraw dc(NULL, pMode); dc.SetDrawRaw(this); // 设属性 dc.SetLayer(_T("0")); dc.SetColor(256); //如果图层关闭 AcDbLayerTableRecordPointer pLayer; if ( Acad::eOk == pLayer.open(layerId(), AcDb::kForRead) ) { if ( pLayer->isOff() ) { return ; } } if (!!ownerId()) { pMode->subEntityTraits().setSelectionMarker(0); dc.SetColor(colorIndex()); dc.SetLayer(layerId()); } int nDrawMode = GetDrawMode(); DrawModeType nDrawType = k2Dand3D; int nDraw = GetDrawDimOnType(nDrawMode, nDrawType); if (nDraw == 3) { if ( nRegenType == kAcGiRenderCommand || nRegenType == kAcGiHideOrShadeCommand || vp.isPerspective() || vtViewDrt != AcGeVector3d(0,0,1)) { Draw3d(dc); m_nDrawDimCur = 3; } else { Draw2d(dc); m_nDrawDimCur = 2; } } else if (nDraw == 1) { Draw2d(dc); m_nDrawDimCur = 2; } else if (nDraw == 2) { Draw3d(dc); m_nDrawDimCur = 3; } } //保存代理实体图元 void AecDbCurveBase::saveAs(AcGiWorldDraw *pWd,AcDb::SaveType saveType) { AecDbObjXDataMap xDataMap; ReadModelXData(EW_EARTHWORMINIT, xDataMap, NULL); int nSaveToProxy(0); xDataMap.GetAt(_T("SaveToProxy"), nSaveToProxy); if (nSaveToProxy == 0) // 不保存代理图形 return; AcGiRegenType rtype = pWd->regenType(); if (rtype == kAcGiSaveWorldDrawForProxy) { subWorldDraw(pWd); } else { AcDbCurve::saveAs(pWd, saveType); } } Acad::ErrorStatus AecDbCurveBase::subExplode(AcDbVoidPtrArray& entitySet) const { ExplodeOrDrawType& eExplodeType = (ExplodeOrDrawType&)m_eExplodeOrDrawType; eExplodeType = kExplode; int expMode = GetExplodeMode(); if (expMode == 1) { GetDraw2dables(0,entitySet); } else if (expMode == 2) { GetDraw3dables(entitySet); } return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subGetGeomExtents(AcDbExtents& extents) const { AcGePoint3d ptLow, ptUp; AcDbVoidPtrArray entSet; int expMode = GetExplodeMode(); if (expMode == 1) { entSet.append(Get2DBuffer()); } else if (expMode == 2) { entSet.append(Get3DBuffer()); } BOOL bInit = TRUE; AcGePoint3d ptMax,ptMin; AcDbExtents ext,extT; int len = entSet.length(); for (int i = 0; i < len; i++) { AcDbEntity *pEnt = (AcDbEntity *)entSet[i]; if (pEnt->getGeomExtents(extT) == Acad::eOk) { ext.addExt(extT); } } ptLow = ext.minPoint(); ptUp = ext.maxPoint(); extents.set(ptLow, ptUp); return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subGet3dGeomExtents(AcDbExtents &extents) const { AcDbVoidPtrArray entSet; if (!Has3DBuffer()) { AcGiViewDraw dc(NULL, NULL); Draw3d(dc); } entSet.append(Get3DBuffer()); if (entSet.isEmpty()) return Acad::eNullExtents; BOOL bInit = TRUE; AcGePoint3d ptMax, ptMin; AcDbExtents ext, extT; int len = entSet.length(); for (int i = 0; i < len; i++) { AcDbEntity *pEnt = (AcDbEntity *)entSet[i]; if (pEnt->getGeomExtents(extT) == Acad::eOk) { ext.addExt(extT); } } AcGePoint3d ptLow, ptUp; ptLow = ext.minPoint(); ptUp = ext.maxPoint(); extents.set(ptLow, ptUp); return Acad::eOk; } void AecDbCurveBase::subList() const { AcDbCurve::subList(); } Acad::ErrorStatus AecDbCurveBase::setColorIndex(Adesk::UInt16 color,Adesk::Boolean doSubents/* = true*/) { assertWriteEnabled(); AecDbObjXDataMap* pMap = GetSpecialtyData(); if (pMap != NULL) { int nCr = 0; if (pMap->GetAt(_T("COLOR"),nCr)) { pMap->SetAt(_T("COLOR"),color); } } return AcDbCurve::setColorIndex(color,doSubents); } Acad::ErrorStatus AecDbCurveBase::subIntersectWith(const AcDbEntity* ent, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { assertReadEnabled(); Acad::ErrorStatus es; AcDbCurve* pNaCrv = GetNativeCurve(); if (pNaCrv != NULL) { //放开后很慢 es = pNaCrv->intersectWith(ent,intType,points,thisGsMarker,otherGsMarker); } //EXTEND 仅仅需要 m_pBaseCurve 求交 struct resbuf rb; acedGetVar(_T("CMDNAMES"),&rb); if (_tcscmp(rb.resval.rstring,_T("EXTEND")) != 0) { int expMode = GetExplodeMode(); if (expMode == 2) { return Acad::eNotImplementedYet; } const AcDbVoidPtrArray& entSet = Get2DBuffer(); es = Acad::eNotApplicable; int len = entSet.length(); for(int i = 0; i < len; i++) { AcDbEntity *pEnt = (AcDbEntity *)entSet[i]; if (pEnt != NULL && Acad::eOk == pEnt->intersectWith(ent, intType, points, 0, otherGsMarker) ) { es = Acad::eOk; } } } return es; } Acad::ErrorStatus AecDbCurveBase::subIntersectWith(const AcDbEntity* ent, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { assertReadEnabled(); Acad::ErrorStatus es; AcDbCurve* pNaCrv = GetNativeCurve(); if (pNaCrv != NULL) { //放开后很慢 es = pNaCrv->intersectWith(ent,intType,points,thisGsMarker,otherGsMarker); } int expMode = GetExplodeMode(); if (expMode == 2) { return Acad::eNotImplementedYet; } //EXTEND 仅仅需要 m_pBaseCurve 求交 struct resbuf rb; acedGetVar(_T("CMDNAMES"),&rb); if (_tcscmp(rb.resval.rstring,_T("EXTEND")) != 0) { const AcDbVoidPtrArray& entSet = Get2DBuffer(); es = Acad::eNotApplicable; int len = entSet.length(); for (int i = 0; i < len; i++) { AcDbEntity *pEnt = (AcDbEntity *)entSet[i]; if (pEnt != NULL && Acad::eOk == pEnt->intersectWith(ent, intType, projPlane, points, 0, otherGsMarker) ) { es = Acad::eOk; } } } return es; } Acad::ErrorStatus AecDbCurveBase::subSetPropertiesFrom( const AcDbEntity* pEntity, Adesk::Boolean doSubents/* = Adesk::kTrue*/) { assertWriteEnabled(); Acad::ErrorStatus es = AcDbCurve::setPropertiesFrom(pEntity, doSubents); // 颜色 { setColorIndex(pEntity->colorIndex()); } //图层 if (database() == NULL || database() == pEntity->database()) { { setLayer(layerId()); } // 线型 { setLinetype(pEntity->linetypeId()); } #if ARX > 16 // 材质 { setMaterial(pEntity->materialId()); } #endif } // 线型比例 { setLinetypeScale(pEntity->linetypeScale()); } // 可见性. 总是被复制 setVisibility(pEntity->visibility()); return es; } #if (ARX > 15) Acad::ErrorStatus AecDbCurveBase::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& ptPick, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { assertReadEnabled(); AcDbVoidPtrArray entSet; int expMode = GetExplodeMode(); if (expMode == 1) { entSet.append(Get2DBuffer()); } else if (expMode == 2) { entSet.append(Get3DBuffer()); } Acad::ErrorStatus es = Acad::eOk; if (es == Acad::eOk) { int len = entSet.length(); for (int i = 0; i < len; i++) { AcDbEntity *pEnt=(AcDbEntity *)entSet[i]; if (pEnt->isKindOf(AcDbText::desc())) { if (osnapMode == AcDb::kOsModeIns) { snapPoints.append(AcDbText::cast(pEnt)->position()); } else { continue; } } es = pEnt->getOsnapPoints(osnapMode, 0, ptPick, lastPoint, viewXform, snapPoints, geomIds); } es = Acad::eOk; } return es; } Acad::ErrorStatus AecDbCurveBase::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& ptPick, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds, const AcGeMatrix3d& insersionMat) const { assertReadEnabled(); return getOsnapPoints(osnapMode,gsSelectionMark,ptPick,lastPoint,viewXform,snapPoints,geomIds); } #endif #if ARX>15 void AecDbCurveBase::subGripStatus(const AcDb::GripStat status) { } Acad::ErrorStatus AecDbCurveBase::subGetGripPoints ( AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const { return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subMoveGripPointsAt(const AcDbVoidPtrArray& appData,const AcGeVector3d& offset,const int bitflags) { return Acad::eOk; } #endif Acad::ErrorStatus AecDbCurveBase::subGetGripPoints (AcGePoint3dArray& gripPoints,AcDbIntArray& osnapModes,AcDbIntArray& geomIds) const { assertReadEnabled(); return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subMoveGripPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset) { assertWriteEnabled(); return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const { assertReadEnabled(); return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subMoveStretchPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset) { assertWriteEnabled(); return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subGetTransformedCopy(const AcGeMatrix3d& xform,AcDbEntity*& pEnt) const { assertReadEnabled(); AcDbEntity *pCloned = (AcDbEntity *)clone(); pCloned->setLayer(layerId());// ((AecDbCurveBase*)pCloned)->m_nDrawDimCur = m_nDrawDimCur; Acad::ErrorStatus es = pCloned->transformBy(xform); if(es == Acad::eOk) pEnt = pCloned; else DELETE_PTR(pCloned); return es; } Acad::ErrorStatus AecDbCurveBase::subDeepClone( 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 this object is in the idMap and is already // cloned, then return. // bool isPrim = false; if (isPrimary) isPrim = true; AcDbIdPair idPair(objectId(), (AcDbObjectId)NULL, false, isPrim); if (idMap.compute(idPair) && (idPair.value() != NULL)) return Acad::eOk; // Create the clone // AecDbCurveBase *pClone = (AecDbCurveBase*)isA()->create(); if (pClone != NULL) pClonedObject = pClone; // set the return value else return Acad::eOutOfMemory; AcDbDeepCloneFiler filer; dwgOut(&filer); filer.seek(0L, AcDb::kSeekFromStart); pClone->dwgIn(&filer); pClone->NewGUID(); pClone->setLayer(layerId()); bool bOwnerXlated = false; if (isPrimary) { AcDbBlockTableRecord *pBTR = AcDbBlockTableRecord::cast(pOwner); if (pBTR != NULL) { pBTR->appendAcDbEntity(pClone); bOwnerXlated = true; } else { pOwner->database()->addAcDbObject(pClone); } } else { pOwner->database()->addAcDbObject(pClone); pClone->setOwnerId(pOwner->objectId()); bOwnerXlated = true; } // 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(); pClone->disableUndoRecording(true); // Add the new information to the idMap. We can use // the idPair started above. // idPair.setValue(pClonedObject->objectId()); idPair.setIsCloned(Adesk::kTrue); idPair.setIsOwnerXlated(bOwnerXlated); idMap.assign(idPair); // Using the filer list created above, find and clone // any owned objects. // AcDbObjectId id; while (filer.getNextOwnedObject(id)) { AcDbObject *pSubObject; AcDbObject *pClonedSubObject; // Some object's references may be set to NULL, // so don't try to clone them. // if (id == NULL) continue; // 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. // acdbOpenAcDbObject(pSubObject, id, AcDb::kForRead); 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(); } //xdataMap 复制 //到mep中找建立新的关系 AecDbObjXDataMap* pXDataMapCloned = pClone->GetSpecialtyData(); AecDbObjXDataMap* pXDataMap = (AecDbObjXDataMap*)GetSpecialtyData(); if (pXDataMapCloned != NULL) pXDataMapCloned->CopyFrom(pXDataMap); if (pXDataMap != NULL && pXDataMapCloned != NULL) { //发送提资需要相同的ID Adesk::Int16 nVal = acdbCurDwg()->useri4(); if (nVal != KEY_NOPROTECT) { int nVt = 0; CString sID = IDCreate(); if (pXDataMapCloned->HasKey(KEY_NO, nVt)) { pXDataMapCloned->SetAt(KEY_NO, sID); } } AecDbObjXDataMap::It it = pXDataMap->Begin(); AecDbObjXDataMap::It end = pXDataMap->End(); CString sKey; CStringArray arHandKeys; AecXData cVal; memset(&cVal,0,sizeof(AecXData)); AcDbObjectId idSrc,idCloned; for (; it != end; ) { if (!pXDataMap->GetNext(it, sKey, cVal)) break; if (cVal.nVt == VT_UI4 || cVal.nVt == VT_UI8)//soft,hard { idSrc.setFromOldId(cVal.nVal); AcDbObject *pSubObject; AcDbObject *pClonedSubObject; // Some object's references may be set to NULL, // so don't try to clone them. // if (idSrc == NULL) continue; AcDbIdPair idPair2(idSrc, (AcDbObjectId)NULL, false, isPrim); if (idMap.compute(idPair2) && (idPair2.value() != NULL)) { if (pXDataMapCloned != NULL) { pXDataMapCloned->RemoveAt(sKey); pXDataMapCloned->SetAt(sKey,idPair2.value(),cVal.nVt == VT_UI4 ? TRUE : FALSE); } continue; } // 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. // pSubObject = NULL; acdbOpenAcDbObject(pSubObject, idSrc, AcDb::kForRead); pClonedSubObject = NULL; if (pSubObject != NULL) { //只考虑上华AEC的实体 LPCTSTR pszDxf = pSubObject->isA()->dxfName(); if (_tcsstr(pszDxf,_T("AEC_'")) != NULL) { pSubObject->deepClone(pClonedObject, pClonedSubObject, idMap, Adesk::kFalse); } else { pSubObject->close(); pSubObject = NULL; } } // 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) idCloned = pClonedSubObject->objectId(); if (pClonedSubObject != NULL) pClonedSubObject->close(); if (pXDataMapCloned != NULL) { if (idCloned.isValid()) { pXDataMapCloned->RemoveAt(sKey); pXDataMapCloned->SetAt(sKey, idCloned, cVal.nVt == VT_UI4 ? TRUE : FALSE); } else { } } } else if (sKey.Find(_T("$H")) != -1 && cVal.nVt == VT_BSTR)//可能的实体句柄 { arHandKeys.Add(sKey); } } //2022-05-04 需要测试 CString sHand; AcDbHandle hd; for(int n = 0;n < arHandKeys.GetSize();n++) { sKey = arHandKeys.GetAt(n); sHand = sKey; sHand.TrimRight(_T("$H")); AcDbHandle handle(sHand); AcDbObjectId idSrc; if ( Acad::eOk == acdbCurDwg()->getAcDbObjectId(idSrc,false,handle) ) { AcDbObject *pSubObject; AcDbObject *pClonedSubObject; // Some object's references may be set to NULL, // so don't try to clone them. // if (idSrc == NULL) continue; AcDbIdPair idPair2(idSrc, (AcDbObjectId)NULL, false, isPrim); if (idMap.compute(idPair2) && (idPair2.value() != NULL)) { CString sKeyNew; //sKey.Format(_T("%s$H"),szHand); if (pXDataMapCloned != NULL) { TCHAR szHand[19]; memset(szHand,0,sizeof(szHand) ); idPair2.value().handle().getIntoAsciiBuffer(szHand); sKeyNew.Format(_T("%s$H"),szHand); pXDataMapCloned->RemoveAt(sKey); pXDataMapCloned->SetAt(sKeyNew,szHand); } continue; } // 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. // pSubObject = NULL; acdbOpenAcDbObject(pSubObject, idSrc, AcDb::kForRead); pClonedSubObject = NULL; if (pSubObject != NULL) { //只考虑上华AEC的实体 LPCTSTR pszDxf = pSubObject->isA()->dxfName(); if (_tcsstr(pszDxf,_T("AEC_'")) != NULL) { pSubObject->deepClone(pClonedObject, pClonedSubObject, idMap, Adesk::kFalse); } else { pSubObject->close(); pSubObject = NULL; } } // 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) idCloned = pClonedSubObject->objectId(); if (pClonedSubObject != NULL) pClonedSubObject->close(); if (pXDataMapCloned != NULL) { CString sKeyNew; TCHAR szHand[19]; memset(szHand,0,sizeof(szHand) ); idCloned.handle().getIntoAsciiBuffer(szHand); sKeyNew.Format(_T("%s$H"),szHand); pXDataMapCloned->RemoveAt(sKey); pXDataMapCloned->SetAt(sKeyNew,szHand); } } } } // Leave pClonedObject open for the caller return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::subWblockClone(AcRxObject* 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 this is a fast wblock operation then no cloning // should take place, so we simply call the base class's // wblockClone() and return whatever it returns. // // For fast wblock, the source and destination databases // are the same, so we can use that as the test to see // if a fast wblock is in progress. // AcDbDatabase *pDest, *pOrig; idMap.destDb(pDest); idMap.origDb(pOrig); if (pDest == pOrig) return AcDbCurve::subWblockClone(pOwner, pClonedObject, idMap, isPrimary); // If this is an Xref bind operation and this AsdkPoly // entity is in Paper Space, then we don't want to // clone because Xref bind doesn't support cloning // entities in Paper Space. So we simply return // Acad::eOk // AcDbObjectId pspace; AcDbBlockTable *pTable; database()->getSymbolTable(pTable, AcDb::kForRead); pTable->getAt(ACDB_PAPER_SPACE, pspace); pTable->close(); if ( idMap.deepCloneContext() == AcDb::kDcXrefBind && ownerId() == pspace) return Acad::eOk; // If this object is in the idMap and is already // cloned, then return. // bool isPrim = false; if (isPrimary) isPrim = true; AcDbIdPair idPair(objectId(), (AcDbObjectId)NULL, false, isPrim); if (idMap.compute(idPair) && (idPair.value() != NULL)) return Acad::eOk; // The owner object can be either an AcDbObject, or an // AcDbDatabase. AcDbDatabase is used if the caller is // not the owner of the object being cloned (because it // is being cloned as part of an AcDbHardPointerId // reference). In this case, the correct ownership // will be set during reference translation. So, if // the owner is an AcDbDatabase, then pOwn will be left // NULL here, and is used as a "flag" later. // AcDbObject *pOwn = AcDbObject::cast(pOwner); AcDbDatabase *pDb = AcDbDatabase::cast(pOwner); if (pDb == NULL) pDb = pOwn->database(); // STEP 1: // Create the clone // AecDbCurveBase *pClone = (AecDbCurveBase*)isA()->create(); if (pClone != NULL) pClonedObject = pClone; // set the return value else return Acad::eOutOfMemory; // STEP 2: // If the owner is an AcDbBlockTableRecord, go ahead // and append the clone. If not, but we know who the // owner is, set the clone's ownerId to it. Otherwise, // we set the clone's ownerId to our own ownerId (in // other words, the original owner Id). This Id will // then be used later, in reference translation, as // a key to finding who the new owner should be. This // means that the original owner must also be cloned at // some point during the wblock operation. // EndDeepClone's reference translation aborts if the // owner is not found in the idMap. // // The most common situation where this happens is // AcDbEntity references to Symbol Table Records, such // as the Layer an Entity is on. This is when you will // have to pass in the destination database as the owner // of the Layer Table Record. Since all Symbol Tables // are always cloned in Wblock, you do not need to make // sure that Symbol Table Record owners are cloned. // // However, if the owner is one of your own classes, // then it is up to you to make sure that it gets // cloned. This is probably easiest to do at the end // of this function. Otherwise you may have problems // with recursion when the owner, in turn, attempts // to clone this object as one of its subObjects. // AcDbBlockTableRecord *pBTR = NULL; if (pOwn != NULL) pBTR = AcDbBlockTableRecord::cast(pOwn); if (pBTR != NULL && isPrimary) { pBTR->appendAcDbEntity(pClone); } else { pDb->addAcDbObject(pClonedObject); } // STEP 3: // The AcDbWblockCloneFiler makes a list of // AcDbHardOwnershipIds and AcDbHardPointerIds. These // are the references which must be cloned during a // Wblock operation. // AcDbWblockCloneFiler filer; dwgOut(&filer); // STEP 4: // Rewind the filer and read the data into the clone. // filer.seek(0L, AcDb::kSeekFromStart); pClone->dwgIn(&filer); pClone->NewGUID(); idMap.assign(AcDbIdPair(objectId(), pClonedObject->objectId(), Adesk::kTrue, isPrim, (Adesk::Boolean)(pOwn != NULL) )); pClonedObject->setOwnerId((pOwn != NULL) ? pOwn->objectId() : ownerId()); // STEP 5: // This must be called for all newly created objects // in wblockClone. 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. We must also let the // idMap entry know whether the clone's owner is // correct, or needs to be translated later. // // STEP 7: // Using the filer list created above, find and clone // any hard references. // AcDbObjectId id; while (filer.getNextHardObject(id)) { AcDbObject *pSubObject; AcDbObject *pClonedSubObject; // Some object's references may be set to NULL, // so don't try to clone them. // if (id == NULL) continue; // If the referenced object is from a different // database, such as an xref, do not clone it. // acdbOpenAcDbObject(pSubObject, id, AcDb::kForRead); if (pSubObject->database() != database()) { pSubObject->close(); continue; } // We can find out if this is an AcDbHardPointerId // verses an AcDbHardOwnershipId, by seeing if we // are the owner of the pSubObject. If we are not, // then we cannot pass our clone in as the owner // for the pSubObject's clone. In that case, we // pass in our clone's database (the destination // database). // // 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. // pClonedSubObject = NULL; if (pSubObject->ownerId() == objectId()) { pSubObject->wblockClone(pClone, pClonedSubObject, idMap, Adesk::kFalse); } else { pSubObject->wblockClone(pClone->database(), pClonedSubObject, idMap, Adesk::kFalse); } 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(); } //xdataMap 复制 //到mep中找建立新的关系 AecDbObjXDataMap* pXDataMapCloned = pClone->GetSpecialtyData(); AecDbObjXDataMap* pXDataMap = (AecDbObjXDataMap*)GetSpecialtyData(); if (pXDataMap != NULL && pXDataMapCloned != NULL) { //发送提资需要相同的ID Adesk::Int16 nVal = acdbCurDwg()->useri4(); if (nVal != KEY_NOPROTECT) { int nVt = 0; CString sID = IDCreate(); if (pXDataMapCloned->HasKey(KEY_NO, nVt)) { pXDataMapCloned->SetAt(KEY_NO, sID); } } AecDbObjXDataMap::It it = pXDataMap->Begin(); AecDbObjXDataMap::It end = pXDataMap->End(); CString sKey; CStringArray arHandKeys; AecXData cVal; memset(&cVal,0,sizeof(AecXData)); AcDbObjectId idSrc,idCloned; for (; it != end;) { if (!pXDataMap->GetNext(it, sKey, cVal)) break; if (cVal.nVt == VT_UI4 || cVal.nVt == VT_UI8)//soft,hard { idSrc.setFromOldId(cVal.nVal); AcDbObject *pSubObject; AcDbObject *pClonedSubObject; // Some object's references may be set to NULL, // so don't try to clone them. // if (idSrc == NULL) continue; AcDbIdPair idPair2(idSrc, (AcDbObjectId)NULL, false, isPrim); if (idMap.compute(idPair2) && (idPair2.value() != NULL)) { if (pXDataMapCloned != NULL) { pXDataMapCloned->SetAt(sKey,idPair2.value(),cVal.nVt == VT_UI4 ? TRUE : FALSE); } continue; } // 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. // acdbOpenAcDbObject(pSubObject, idSrc, AcDb::kForRead); pClonedSubObject = NULL; if (pSubObject->ownerId() == objectId()) { pSubObject->wblockClone(pClone, pClonedSubObject, idMap, Adesk::kFalse); } else { pSubObject->wblockClone(pClone->database(), 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. // idCloned = pClonedSubObject->objectId(); if (pClonedSubObject != NULL) pClonedSubObject->close(); if (pXDataMapCloned != NULL) { pXDataMapCloned->RemoveAt(sKey); pXDataMapCloned->SetAt(sKey,idCloned,cVal.nVt == VT_UI4 ? TRUE : FALSE); } } else if (sKey.Find(_T("$H")) != -1 && cVal.nVt == VT_BSTR)//可能的实体句柄 { arHandKeys.Add(sKey); } } } return Acad::eOk; } Adesk::Boolean AecDbCurveBase::isClosed() const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Adesk::Boolean bRet = pCurve->isClosed(); return bRet; } else { return AcDbCurve::isClosed(); } } Adesk::Boolean AecDbCurveBase::isPeriodic() const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Adesk::Boolean bRet = pCurve->isPeriodic(); return bRet; } else { return AcDbCurve::isPeriodic(); } } Acad::ErrorStatus AecDbCurveBase::getStartParam(double&pa) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getStartParam(pa); return bRet; } else { return AcDbCurve::getStartParam(pa); } } Acad::ErrorStatus AecDbCurveBase::getEndParam (double&pa) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getEndParam(pa); return bRet; } else { return AcDbCurve::getEndParam(pa); } } Acad::ErrorStatus AecDbCurveBase::getStartPoint(AcGePoint3d&pt) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getStartPoint(pt); return bRet; } else { return AcDbCurve::getStartPoint(pt); } } Acad::ErrorStatus AecDbCurveBase::getEndPoint (AcGePoint3d&pt) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getEndPoint(pt); return bRet; } else { return AcDbCurve::getEndPoint(pt); } } Acad::ErrorStatus AecDbCurveBase::getPointAtParam(double pa, AcGePoint3d&pt) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getPointAtParam(pa,pt); return bRet; } else { return AcDbCurve::getPointAtParam(pa,pt); } } Acad::ErrorStatus AecDbCurveBase::getParamAtPoint(const AcGePoint3d& pt, double&pa)const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getParamAtPoint(pt,pa); return bRet; } else { return AcDbCurve::getParamAtPoint(pt,pa); } } Acad::ErrorStatus AecDbCurveBase::getDistAtParam (double param, double& dist) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getDistAtParam(param,dist); return bRet; } else { return AcDbCurve::getDistAtParam(param,dist); } } Acad::ErrorStatus AecDbCurveBase::getParamAtDist (double dist, double& param) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getParamAtDist(dist,param); return bRet; } else { return AcDbCurve::getParamAtDist(dist,param); } } Acad::ErrorStatus AecDbCurveBase::getDistAtPoint (const AcGePoint3d&pt, double&dist)const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getDistAtPoint(pt,dist); return bRet; } else { return AcDbCurve::getDistAtPoint(pt,dist); } } Acad::ErrorStatus AecDbCurveBase::getPointAtDist (double dist, AcGePoint3d&pt) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getPointAtDist(dist,pt); return bRet; } else { return AcDbCurve::getPointAtDist(dist,pt); } } Acad::ErrorStatus AecDbCurveBase::getFirstDeriv (double param,AcGeVector3d& firstDeriv) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getFirstDeriv(param,firstDeriv); return bRet; } else { return AcDbCurve::getFirstDeriv(param,firstDeriv); } } Acad::ErrorStatus AecDbCurveBase::getFirstDeriv (const AcGePoint3d&pt,AcGeVector3d& firstDeriv) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getFirstDeriv(pt,firstDeriv); return bRet; } else { return AcDbCurve::getFirstDeriv(pt,firstDeriv); } } Acad::ErrorStatus AecDbCurveBase::getSecondDeriv (double param,AcGeVector3d& secDeriv) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getSecondDeriv(param,secDeriv); return bRet; } else { return AcDbCurve::getSecondDeriv(param,secDeriv); } } Acad::ErrorStatus AecDbCurveBase::getSecondDeriv (const AcGePoint3d&pt,AcGeVector3d& secDeriv) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getSecondDeriv(pt,secDeriv); return bRet; } else { return AcDbCurve::getSecondDeriv(pt,secDeriv); } } Acad::ErrorStatus AecDbCurveBase::getClosestPointTo(const AcGePoint3d& givenPnt, AcGePoint3d& pointOnCurve, Adesk::Boolean extend) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getClosestPointTo(givenPnt,pointOnCurve,extend); return bRet; } else { return AcDbCurve::getClosestPointTo(givenPnt,pointOnCurve,extend); } } Acad::ErrorStatus AecDbCurveBase::getClosestPointTo(const AcGePoint3d& givenPnt, const AcGeVector3d& direction, AcGePoint3d& pointOnCurve, Adesk::Boolean extend) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getClosestPointTo(givenPnt,direction,pointOnCurve,extend); return bRet; } else { return AcDbCurve::getClosestPointTo(givenPnt,direction,pointOnCurve,extend); } } Acad::ErrorStatus AecDbCurveBase::getOrthoProjectedCurve(const AcGePlane& plane, AcDbCurve*& projCrv) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { AcDbCurve* pCurve1 = NULL; Acad::ErrorStatus bRet = pCurve->getOrthoProjectedCurve(plane,pCurve1); if (bRet == Acad::eOk) { AecDbCurveBase* pCurveEnt = (AecDbCurveBase*)clone(); bRet = pCurveEnt->SetBaseCurve(pCurve1); projCrv = pCurveEnt; DELETE_PTR(pCurve1); } return bRet; } else { return AcDbCurve::getOrthoProjectedCurve(plane,projCrv); } } Acad::ErrorStatus AecDbCurveBase::getProjectedCurve(const AcGePlane& plane, const AcGeVector3d& projDir, AcDbCurve*& projCrv) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { AcDbCurve* pCurve1 = NULL; Acad::ErrorStatus bRet = pCurve->getProjectedCurve(plane,projDir,pCurve1); if (bRet == Acad::eOk) { AecDbCurveBase* pCurveEnt = (AecDbCurveBase*)clone(); bRet = pCurveEnt->SetBaseCurve(pCurve1); projCrv = pCurveEnt; DELETE_PTR(pCurve1); } return bRet; } else { return AcDbCurve::getProjectedCurve(plane,projDir,projCrv); } } Acad::ErrorStatus AecDbCurveBase::getOffsetCurves(double offsetDist, AcDbVoidPtrArray& offsetCurves) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { AcDbVoidPtrArray offsetCurves0; Acad::ErrorStatus bRet = pCurve->getOffsetCurves(offsetDist,offsetCurves0); if (bRet == Acad::eOk) { for (long i = 0; i < offsetCurves0.length(); i++) { AecDbCurveBase*pCurveEnt = (AecDbCurveBase*)clone(); pCurveEnt->SetBaseCurve((AcDbCurve*)offsetCurves0[i]); offsetCurves.append(pCurveEnt); } ReleaseEntSet(offsetCurves0); } return bRet; } else { return AcDbCurve::getOffsetCurves(offsetDist,offsetCurves); } } Acad::ErrorStatus AecDbCurveBase::getOffsetCurvesGivenPlaneNormal( const AcGeVector3d& normal, double offsetDist, AcDbVoidPtrArray& offsetCurves) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { AcDbVoidPtrArray offsetCurves0; Acad::ErrorStatus bRet = pCurve->getOffsetCurvesGivenPlaneNormal(normal,offsetDist,offsetCurves0); if (bRet == Acad::eOk) { for (long i = 0; i < offsetCurves0.length(); i++) { AecDbCurveBase*pCurveEnt = (AecDbCurveBase*)clone(); pCurveEnt->SetBaseCurve((AcDbCurve*)offsetCurves0[i]); offsetCurves.append(pCurveEnt); } ReleaseEntSet(offsetCurves0); } return bRet; } else return AcDbCurve::getOffsetCurvesGivenPlaneNormal(normal,offsetDist,offsetCurves); } Acad::ErrorStatus AecDbCurveBase::getSpline(AcDbSpline*& spline) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getSpline(spline); return bRet; } else { return AcDbCurve::getSpline(spline); } } Acad::ErrorStatus AecDbCurveBase::getSplitCurves (const AcGeDoubleArray& params, AcDbVoidPtrArray& curveSegments) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { AcDbVoidPtrArray curveSegments0; Acad::ErrorStatus bRet = pCurve->getSplitCurves(params,curveSegments0); if (bRet == Acad::eOk) { for (long i = 0; i < curveSegments0.length(); i++) { AecDbCurveBase*pCurveEnt = (AecDbCurveBase*)clone(); AecDbObjXDataMap* pXDataMap = pCurveEnt->GetSpecialtyData(); if (pXDataMap != NULL) { CString sNo; if (pXDataMap->GetAt(KEY_NO,sNo)) { sNo = IDCreate(); pXDataMap->SetAt(KEY_NO,sNo); } } pCurveEnt->SetBaseCurve((AcDbCurve*)curveSegments0[i]); curveSegments.append(pCurveEnt); } ReleaseEntSet(curveSegments0); } return bRet; } else { return AcDbCurve::getSplitCurves(params,curveSegments); } } Acad::ErrorStatus AecDbCurveBase::getSplitCurves (const AcGePoint3dArray& points, AcDbVoidPtrArray& curveSegments) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { AcDbVoidPtrArray curveSegments0; Acad::ErrorStatus bRet = pCurve->getSplitCurves(points,curveSegments0); if (bRet == Acad::eOk) { for (long i = 0; i < curveSegments0.length(); i++) { AecDbCurveBase*pCurveEnt = (AecDbCurveBase*)clone(); AecDbObjXDataMap* pXDataMap = pCurveEnt->GetSpecialtyData(); if (pXDataMap != NULL) { CString sNo; if (pXDataMap->GetAt(KEY_NO,sNo)) { sNo = IDCreate(); pXDataMap->SetAt(KEY_NO,sNo); } } pCurveEnt->SetBaseCurve((AcDbCurve*)curveSegments0[i]); curveSegments.append(pCurveEnt); } ReleaseEntSet(curveSegments0); } return bRet; } else { return AcDbCurve::getSplitCurves(points,curveSegments); } } Acad::ErrorStatus AecDbCurveBase::extend(double newParam) { AssertWriteEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->extend(newParam); if (bRet == Acad::eOk) { //bRet = SetBaseCurve(pCurve); } return bRet; } else { return AcDbCurve::extend(newParam); } } static AcDbArc* FormatArc(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2,const AcGePoint3d& ptGe3) { AcDbArc* pArcThis = NULL; AcGeCircArc3d cirArc3d; cirArc3d.set(ptGe1,ptGe2,ptGe3);//可能逆弧 AcGeVector3d vtNorm = cirArc3d.normal(); if (vtNorm.isParallelTo(AcGeVector3d::kZAxis)) { if (!vtNorm.isCodirectionalTo(AcGeVector3d::kZAxis)) { vtNorm.negate();//相反 } } AcDbCircle cir; cir.setCenter(cirArc3d.center()); cir.setRadius(cirArc3d.radius()); cir.setNormal(vtNorm); AcGePoint3dArray arPts; arPts.append(ptGe1); arPts.append(ptGe3); AcDbVoidPtrArray arCurPtrs; cir.getSplitCurves(arPts,arCurPtrs); double dPara = 0.0; AcDbCurve* pCurve = NULL; for (int j = 0;j < arCurPtrs.length();j++) { pCurve = (AcDbCurve*)arCurPtrs.at(j); if (pCurve != NULL) { if (Acad::eOk == pCurve->getParamAtPoint(ptGe2,dPara))//中点在圆弧上 { AcDbArc* pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { pArcThis = pArc; arCurPtrs.removeAt(j); break; } } } } FreeBuffer(0,arCurPtrs); return pArcThis; } static AcGePoint3d GetArcMidPoint(AcDbArc* pArc) { double dSta = 0.0,dEnd = 0.0; pArc->getStartParam(dSta); pArc->getEndParam(dEnd); AcGePoint3d ptMid; pArc->getPointAtParam((dSta + dEnd) / 2.0,ptMid); return ptMid; } Acad::ErrorStatus AecDbCurveBase::extend(Adesk::Boolean extendStart, const AcGePoint3d& toPoint) { AssertWriteEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { AcGePoint3d ptS,ptE; pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); if (toPoint.distanceTo(ptS) < toPoint.distanceTo(ptE)) extendStart = Adesk::kTrue; else extendStart = Adesk::kFalse; Acad::ErrorStatus bRet = pCurve->extend(extendStart,toPoint); if (bRet == Acad::eOk) { //延长到外部一点 //GetNativeCurve //bRet = SetBaseCurve(pCurve); } else { //内部,缩短到内部一点 AcDbLine* pLn = AcDbLine::cast(pCurve); if (pLn != NULL) { if (extendStart) { pLn->setStartPoint(toPoint); } else { pLn->setEndPoint(toPoint); } bRet = Acad::eOk; } AcDbArc* pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { if (extendStart)//开始缩短 { AcGePoint3d ptE,ptM; pArc->getEndPoint(ptE); ptM = GetArcMidPoint(pArc); AcDbArc* pArc2 = FormatArc(toPoint,ptM,ptE); if (pArc2 != NULL) { pArc->setStartAngle(pArc2->startAngle()); pArc->setEndAngle(pArc2->endAngle()); delete pArc2; } } else//末尾缩短 { AcGePoint3d ptE,ptM; pArc->getStartPoint(ptE); ptM = GetArcMidPoint(pArc); AcDbArc* pArc2 = FormatArc(ptE,ptM,toPoint); if (pArc2 != NULL) { pArc->setStartAngle(pArc2->startAngle()); pArc->setEndAngle(pArc2->endAngle()); delete pArc2; } } bRet = Acad::eOk; } } return bRet; } else { return AcDbCurve::extend(extendStart,toPoint); } } Acad::ErrorStatus AecDbCurveBase::getArea(double&area) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getArea(area); return bRet; } else { return AcDbCurve::getArea(area); } } Adesk::Boolean AecDbCurveBase::isPlanar() const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Adesk::Boolean bRet = pCurve->isPlanar(); return bRet; } else { return AcDbCurve::isPlanar(); } } Acad::ErrorStatus AecDbCurveBase::getPlane(AcGePlane&plane, AcDb::Planarity&pr) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { Acad::ErrorStatus bRet = pCurve->getPlane(plane,pr); return bRet; } else { return AcDbCurve::getPlane(plane,pr); } } void AecDbCurveBase::getEcs(AcGeMatrix3d& retVal) const { assertReadEnabled(); AcDbCurve* pCurve = GetNativeCurve(); if (pCurve != NULL) { pCurve->getEcs(retVal); } else { AcDbCurve::getEcs(retVal); } } Acad::ErrorStatus AecDbCurveBase::SetBaseCurve(const AcDbCurve* pDbCurve) { return Acad::eNotImplementedYet; } AcDbCurve* AecDbCurveBase::GetBaseCurve(bool bOrthoProjectToXY) const { return NULL; } AcDbCurve* AecDbCurveBase::GetNativeCurve() const { return NULL; } //AEC派生 int AecDbCurveBase::GetDrawMode() { int nDrawMode = 3; //从命名字典中取,默认3 return nDrawMode; } void AecDbCurveBase::SetDrawMode(int nMode) { //写入命名字典 } //某些实体只有2D int AecDbCurveBase::GetDrawDimOnType(int nDrawMode, int nDrawType) const { int nDraw = 0; //0--NONE; 1--2D; 2--3D; 3--2D&3D; if (nDrawMode == DRAW_2D && (nDrawType == k2DOnly || nDrawType == k2Dand3D)) { nDraw = 1; } else if (nDrawMode == DRAW_3D && (nDrawType == k3DOnly || nDrawType == k2Dand3D)) { nDraw = 2; } else if (nDrawMode == (DRAW_2D | DRAW_3D) && nDrawType == k2Dand3D) { nDraw = 3;//转到viewportdraw } else if (nDrawMode == (DRAW_2D | DRAW_3D) && nDrawType == k2DOnly) { nDraw = 1; } else if (nDrawMode == (DRAW_2D | DRAW_3D) && nDrawType == k3DOnly) { nDraw = 2; } return nDraw; } void AecDbCurveBase::BackupColorIndex(AcDbEntity* pEnt) { if (pEnt != NULL) { struct resbuf* pXData = NULL; pXData = pEnt->xData(_T("COLOR_BK")); if (pXData == NULL) { struct resbuf* pTemp = acutNewRb(AcDb::kDxfRegAppName); acutNewString(_T("COLOR_BK"),pTemp->resval.rstring); pXData = pTemp; struct resbuf* pTempNext = NULL; pTempNext = acutNewRb(AcDb::kDxfXdInteger32); pTempNext->resval.rlong = pEnt->colorIndex(); pTemp->rbnext = pTempNext; pTempNext->rbnext = NULL; acdbRegApp(_T("COLOR_BK")); pEnt->setXData(pXData); acutRelRb(pXData); } } } int AecDbCurveBase::SetBackupColorIndex(AcDbEntity* pEnt) { int nColor = kColorByLayer; if (pEnt != NULL) { resbuf* pXData = NULL; pXData = pEnt->xData(_T("COLOR_BK")); if (pXData != NULL) { struct resbuf* pTempNext = pXData->rbnext; if (pTempNext != NULL) { if (pTempNext->restype == AcDb::kDxfXdInteger32) { nColor = pTempNext->resval.rint; pEnt->setColorIndex(nColor); // 存在清空 struct resbuf* pTmp = acutNewRb(AcDb::kDxfRegAppName); pEnt->setXData(pTmp); acutRelRb(pXData); acutRelRb(pTmp); } } } } return nColor; } int AecDbCurveBase::GetExplodeMode() const { int nDrawMode = GetDrawMode(); DrawModeType nDrawType = k2Dand3D; int nDraw = GetDrawDimOnType(nDrawMode, nDrawType); if (nDraw == 1) { nDraw = DRAW_2D; } else if (nDraw == 2) { nDraw = DRAW_3D; } else if (nDraw == 3) { ads_point pt; struct resbuf rb; acedGetVar(_T("VIEWDIR"),&rb); ads_point_set(rb.resval.rpoint,pt); ads_point viewDir; acdbUcs2Wcs(pt,viewDir,false); if (fabs(viewDir[X]) > 1.0e-6 || fabs(viewDir[Y]) > 1.0e-6) { nDraw = DRAW_3D; } else { nDraw = DRAW_2D; } } return nDraw; } Acad::ErrorStatus AecDbCurveBase::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled () ; //----- Read parent class information first. Acad::ErrorStatus es = AcDbCurve::dwgInFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; return (pFiler->filerStatus ()) ; } Acad::ErrorStatus AecDbCurveBase::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled () ; //----- Save parent class information first. Acad::ErrorStatus es = AcDbCurve::dwgOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; return (pFiler->filerStatus ()) ; } Acad::ErrorStatus AecDbCurveBase::dxfInFields (AcDbDxfFiler* pFiler) { assertWriteEnabled () ; //----- Read parent class information first. Acad::ErrorStatus es = AcDbCurve::dxfInFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; return (pFiler->filerStatus ()) ; } Acad::ErrorStatus AecDbCurveBase::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled () ; //----- Save parent class information first. Acad::ErrorStatus es = AcDbCurve::dxfOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; return (pFiler->filerStatus ()) ; } Acad::ErrorStatus AecDbCurveBase::Draw2d(AcGiDraw &dc) const { return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::Draw3d(AcGiDraw &dc) const { return Acad::eOk; } void AecDbCurveBase::AssertWriteEnabled(Adesk::Boolean autoUndo /*= true*/, Adesk::Boolean recordModified /*= true*/) { FreeBuffer(0, m_ar2DDrableBufPtrs_); FreeBuffer(0, m_ar3DDrableBufPtrs_); m_ar3DDrableBufPtrs_.removeAll(); m_ar2DDrableBufPtrs_.removeAll(); assertWriteEnabled(autoUndo,recordModified); } bool AecDbCurveBase::GetPositionGrip(int nIndex, AecGripData *&pGrip) const { return NULL; } extern double PixelToWcs(int nPixel); bool AecDbCurveBase::SubAddHitEditGrip(AcDbGripDataPtrArray &grips) const { assertReadEnabled(); AecGripData *pGrip = NULL; GetPositionGrip(grips.length() - 1, pGrip); if (pGrip != NULL) { AcGePoint3d ptHit = pGrip->ptGrip; ptHit += AcGeVector3d::kXAxis * PixelToWcs(30); AecGripData *pGrip2 = new AecGripData; memset(pGrip2, 0, sizeof(AecGripData)); pGrip2->nIndex = grips.length(); pGrip2->ePos = eHitEdit; pGrip2->nColor = kRed; pGrip2->ptGrip = ptHit; _tcscpy(pGrip2->szTip, _T("点击修改")); _tcscpy(pGrip2->szID, _T("HITEDIT_2023")); pGrip2->pOwner = (AcDbEntity *)this; pGrip2->idHost = this->objectId(); AcDbGripData* pGripData = new AcDbGripData; pGripData->setGripPoint(ptHit); pGripData->setAppData((void *)pGrip2); pGripData->setWorldDraw(AecGripCback::WorldDrawfunc); pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc); grips.append(pGripData); return true; } return false; } //不得导出,需要数据,增加特定的获取函数 extern AecDbObjXDataMap g_mapGlobalData; bool AecDbCurveBase::HitOnGripEdit(const AcDbVoidPtrArray &gripAppData) { AecGripData *pAppData = NULL; AcDbIntArray arIndex; if (gripAppData.isEmpty()) { return Acad::eOk; } pAppData = (AecGripData *)gripAppData.first(); if (pAppData->ePos == eHitEdit) { //命令名 DBL_DXFNAME TCHAR szCmd[65]; _tcscpy(szCmd, _T("DBL_")); _tcscat(szCmd, this->isA()->dxfName()); //判断命令是否存在 AcEdCommand *pCmd = acedRegCmds->lookupLocalCmd(szCmd); if (pCmd != NULL) { //发送ID 到 USERI; AcDbObjectId id = pAppData->idHost; g_mapGlobalData.SetAt(szCmd, id); acedPostCommand(_T("\x03")); _tcscat(szCmd, _T(" ")); acedPostCommand(szCmd); } else { acutPrintf(_T("\nLocalCmd %s does not exist!"), szCmd); } return true; } return false; } bool AecDbCurveBase::Draw3DBuffers(AcGiDraw &dc)const { if (m_ar3DDrableBufPtrs_.isEmpty()) return false; AcDbEntity *pEnt = NULL; for (int i = 0; i < m_ar3DDrableBufPtrs_.length(); ++i) { pEnt = (AcDbEntity *)m_ar3DDrableBufPtrs_[i]; dc.DrawEntity(*pEnt); } return true; } bool AecDbCurveBase::Draw2DBuffers(AcGiDraw &dc)const { if (m_ar2DDrableBufPtrs_.isEmpty()) { return false; } AcDbEntity *pEnt = NULL; for (int i = 0; i < m_ar2DDrableBufPtrs_.length(); ++i) { pEnt = (AcDbEntity *)m_ar2DDrableBufPtrs_[i]; pEnt->setLayer(dc.GetLayerId()); pEnt->setColorIndex(colorIndex()); dc.DrawEntity(*pEnt); } return true; } const AcDbVoidPtrArray& AecDbCurveBase::Get3DBuffer() const { //剖切隐藏 BoolSubtractHide(); return m_ar3DDrableBufPtrs_; } const AcDbVoidPtrArray& AecDbCurveBase::Get2DBuffer() const { return m_ar2DDrableBufPtrs_; } bool AecDbCurveBase::Has3DBuffer() const { return !m_ar3DDrableBufPtrs_.isEmpty(); } bool AecDbCurveBase::Has2DBuffer() const { return !m_ar2DDrableBufPtrs_.isEmpty(); } void AecDbCurveBase::Add3DBuffer(AcDbEntity *pEnt) const { if (pEnt) m_ar3DDrableBufPtrs_.append(pEnt); } void AecDbCurveBase::Add3DBuffer(const AcDbVoidPtrArray &arr) const { m_ar3DDrableBufPtrs_.append(arr); } void AecDbCurveBase::Add2DBuffer(AcDbEntity *pEnt) const { if (pEnt) m_ar2DDrableBufPtrs_.append(pEnt); } void AecDbCurveBase::Add2DBuffer(const AcDbVoidPtrArray &arr) const { m_ar2DDrableBufPtrs_.append(arr); } bool AecDbCurveBase::IsIn2DBuffer(AcDbEntity* pEnt) const { assertReadEnabled(); if (-1 == m_ar2DDrableBufPtrs_.find(pEnt)) return false; return true; } bool AecDbCurveBase::IsIn3DBuffer(AcDbEntity* pEnt) const { assertReadEnabled(); if (-1 == m_ar3DDrableBufPtrs_.find(pEnt)) return false; return true; } void AecDbCurveBase::Clean3DBuffer() const { FreeBuffer(0, m_ar3DDrableBufPtrs_); m_ar3DDrableBufPtrs_.removeAll(); } void AecDbCurveBase::Clean2DBuffer() const { FreeBuffer(0, m_ar2DDrableBufPtrs_); m_ar2DDrableBufPtrs_.removeAll(); } void AecDbCurveBase::Clean3DBufferNoDel() const { m_ar3DDrableBufPtrs_.removeAll(); } void AecDbCurveBase::Clean2DBufferNoDel() const { m_ar2DDrableBufPtrs_.removeAll(); } int AecDbCurveBase::GetDrawDimCur() const { return m_nDrawDimCur; } //获取二维视图显示的图形 int AecDbCurveBase::GetDraw2dables(Adesk::UInt16 nDrawStyle, AcDbVoidPtrArray& arEntPtrs) const { assertReadEnabled(); AcDbEntity* pEnt = NULL,*pEntT = NULL; const AcDbVoidPtrArray &ar2D = Get2DBuffer(); for (int i = 0;i < ar2D.length();i++) { pEnt = (AcDbEntity*)ar2D.at(i); pEntT = (AcDbEntity*)pEnt->clone(); pEntT->setLayer(layerId()); arEntPtrs.append(pEntT); } return arEntPtrs.length(); } //获取三维显示图形 int AecDbCurveBase::GetDraw3dables(AcDbVoidPtrArray& arEntPtrs,bool bWriteBimInfo) const { assertReadEnabled(); const AecDbObjXDataMap* pXDataMap = GetSpecialtyData(); if (pXDataMap != NULL) { AcDbEntity* pEnt = NULL,*pEntClone = NULL; if (!Has3DBuffer()) { AcGiViewDraw dc(NULL, NULL); Draw3d(dc); } const AcDbVoidPtrArray &ar3D = Get3DBuffer(); for (int i = 0;i < ar3D.length();i++) { pEnt = (AcDbEntity*)ar3D.at(i); pEntClone = (AcDbEntity*)pEnt->clone(); int nColor = 0; if ( pXDataMap->GetAt(_T("COLOR"),nColor) ) { pEntClone->setColorIndex(nColor); } else { pEntClone->setColorIndex(colorIndex()); } pEntClone->setLayer(layerId()); if (bWriteBimInfo) { pXDataMap->Write(pEntClone,_T("BIMDATA")); } arEntPtrs.append(pEntClone); } } return arEntPtrs.length(); } void AecDbCurveBase::UpdateDrableSpecData(LPCTSTR pszApp,LPCTSTR pszKey,CString& sVal) { assertWriteEnabled(); AecDbObjXDataMap xDataMap; AcDbEntity* pEnt = NULL,*pEntT = NULL; const AcDbVoidPtrArray &ar2D = Get2DBuffer(); for (int i = 0;i < ar2D.length();i++) { pEnt = (AcDbEntity*)ar2D.at(i); if (xDataMap.Read(pEnt,pszApp)) { xDataMap.RemoveAt(pszKey); xDataMap.SetAt(pszKey,sVal); xDataMap.Write(pEnt,pszApp); } } const AcDbVoidPtrArray &ar3D = Get3DBuffer(); for (int i = 0;i < ar3D.length();i++) { pEnt = (AcDbEntity*)ar3D.at(i); if (xDataMap.Read(pEnt,pszApp)) { xDataMap.RemoveAt(pszKey); xDataMap.SetAt(pszKey,sVal); xDataMap.Write(pEnt,pszApp); } } } bool AecDbCurveBase::GetBimInfoTip(CString& sInfoTip) const { return false; } bool AecDbCurveBase::GetProperties(SimpleProperty::PropertySetByIndex &porpertys) const { assertReadEnabled(); CString sLayer(_T("0")); TCHAR *pLayer = layer(); if (pLayer) { sLayer = pLayer; acutDelString(pLayer); } SimpleProperty::makeAndInsert(porpertys, _T("图层"), sLayer, false); const AecDbObjXDataMap *pData = GetSpecialtyData(); CString sys; if (pData->GetAt(PIPE_SYS, sys)) SimpleProperty::makeAndInsert(porpertys, _T("分系统"), sys, false); return TRUE; } bool AecDbCurveBase::SetProperties(SimpleProperty::PropertySetByName &properties) { AssertWriteEnabled(); using namespace SimpleProperty; CString sVal(_T("")); if (properties.findAndSet(_T("图层"), sVal)) { setLayer(sVal); } if (properties.findAndSet(_T("分系统"), sVal)) { AecDbObjXDataMap *pData = GetSpecialtyData(AcDb::kForWrite); if (pData) pData->SetAt(PIPE_SYS, sVal); } return true; } bool AecDbCurveBase::SendUserData(struct resbuf *pRb) { return false; } Acad::ErrorStatus AecDbCurveBase::ReCreateDraw2d() { assertWriteEnabled(); Clean2DBuffer(); return Acad::eOk; } Acad::ErrorStatus AecDbCurveBase::ReCreateDraw3d() { assertWriteEnabled(); Clean3DBuffer(); return Acad::eOk; } int AecDbCurveBase::GetSectionDraw(const AcGePoint3d& ptFr,const AcGePoint3d& ptTo,const AcGeVector3d& vtViewDir,const AcGeVector3d& vtTo, AcDbVoidPtrArray& arRegionPtrs) const { return 0; } bool AecDbCurveBase::GetSectionHatchPattern(CString& sPattern) const { assertReadEnabled(); CString sMat; if (GetSpecialtyData()->GetAt(KEY_SECTION_HATCH, sMat)) { sPattern = sMat; if (sMat == HATCH_NO_NEED) return false; if (sMat != HATCH_DEFAULT) return true; } if ( GetSpecialtyData()->GetAt(KEY_MATERIAL,sMat)) { //以后从外部配置文件中获取 //钢筋混凝土 //石材 //砖墙 //填充墙体 //轻质隔墙 //玻璃幕墙 sPattern = _T("AR-CONC"); if (sMat.CompareNoCase(_T("钢筋混凝土")) == 0) { sPattern = _T("钢筋混凝土"); } else if(sMat.CompareNoCase(_T("石材")) == 0) { sPattern = _T("天然石材"); } else if(sMat.CompareNoCase(_T("砖墙")) == 0) { sPattern = _T("普通砖"); } else if(sMat.CompareNoCase(_T("填充墙体")) == 0) { sPattern = _T("钢筋混凝土"); } else if(sMat.CompareNoCase(_T("轻质隔墙")) == 0) { sPattern = _T("混凝土"); } else if(sMat.CompareNoCase(_T("玻璃幕墙")) == 0) { sPattern = _T("玻璃砖墙"); } } return true; } double AecDbCurveBase::GetVolume(bool bIsBody/* = false*/) const { assertReadEnabled(); if (!Has3DBuffer()) { AcGiViewDraw dc(NULL,NULL); Draw3d(dc); } double dVol = 0.0,dVolAll = 0.0,momInertia[3],prodInertia[3],prinMoments[3],radiiGyration[3]; AcGePoint3d ptCen; AcGeVector3d prinAxes[3]; AcDbExtents extents; AcDbVoidPtrArray arEntPtrs; GetDraw3dables(arEntPtrs); AcDbEntity* pEnt = NULL; for (int i = 0;i < arEntPtrs.length();i++) { pEnt = (AcDbEntity*)arEntPtrs.at(i); AcDb3dSolid* pSolid = AcDb3dSolid::cast(pEnt); if (pSolid != NULL) { pSolid->getMassProp(dVol,ptCen,momInertia,prodInertia,prinMoments,prinAxes,radiiGyration,extents); dVolAll += dVol; } } return dVolAll; } int AecDbCurveBase::ComparedTo(AecDbCurveBase* pCurOther) const { return -1;//不做比较 } double AecDbCurveBase::GetArea() const { assertReadEnabled(); if (!Has3DBuffer()) { AcGiViewDraw dc(NULL,NULL); Draw3d(dc); } double dArea = 0.0,dAreaAll = 0.0; AcDbVoidPtrArray arEntPtrs; GetDraw3dables(arEntPtrs); AcDbEntity* pEnt = NULL; for (int i = 0;i < arEntPtrs.length();i++) { pEnt = (AcDbEntity*)arEntPtrs.at(i); AcDb3dSolid* pSolid = AcDb3dSolid::cast(pEnt); if (pSolid != NULL) { pSolid->getArea(dArea); dAreaAll += fabs(dArea); } AcDbRegion* pReg = AcDbRegion::cast(pEnt); if (pReg != NULL) { pReg->getArea(dArea); dAreaAll += fabs(dArea); } } return dAreaAll; } void AecDbCurveBase::Add3DBoolSubtract(AcDb3dSolid* pSolidBlackHole) { assertWriteEnabled(); const AcDbVoidPtrArray& ar3D_ = Get3DBuffer(); AcDbVoidPtrArray ar3D; ar3D.append(ar3D_); AcDbEntity* pEnt = NULL; AcDb3dSolid* pSolid = NULL; AcDb3dSolid* pSolidCln = NULL; AcDb3dSolid* pSolidNotGet = NULL; Acad::ErrorStatus es; Adesk::Boolean bSlidInterface = Adesk::kFalse; double dArea1 = 0.0,dArea2 = 0.0; for (int i = 0;i < ar3D.length();i++) { pEnt = (AcDbEntity*)ar3D.at(i); pSolid = AcDb3dSolid::cast(pEnt); if (pSolid != NULL) { pSolidCln = (AcDb3dSolid*)pSolidBlackHole->clone(); //有交集才处理 if ( Acad::eOk == pSolid->checkInterference( pSolidCln,Adesk::kFalse,bSlidInterface,pSolidNotGet)) { pSolid->getArea(dArea1); es = pSolid->booleanOper(AcDb::kBoolSubtract,pSolidCln); pSolid->getArea(dArea2); if ( es == Acad::eOk) { pSolid->recordGraphicsModified(Adesk::kTrue); if ( fabs(dArea1 - dArea2) < 1.e-3)//没有变化,被包含 { ar3D.removeAt(i); i -= 1; m_ar3DDrableBufPtrs_.removeAt(i); } } else if ( es == Acad::eGeneralModelingFailure ) { ar3D.removeAt(i); i -= 1; m_ar3DDrableBufPtrs_.removeAt(i); } //delete pSolidCln; } } } } void AecDbCurveBase::Remove3DBoolSubtract() { assertWriteEnabled(); //清除3D,重建 Clean3DBuffer(); } void AecDbCurveBase::AddBlackHole(AcDbObjectId& idHole) { AssertWriteEnabled(); AecDbObjXDataMap* pXdataMap = GetSpecialtyData(AcDb::kForWrite); if (pXdataMap != NULL) { TCHAR szHand[19]; memset(szHand,0,sizeof(szHand) ); idHole.handle().getIntoAsciiBuffer(szHand); CString sKey; sKey.Format(_T("%s_%s"),KEY_HOLE,szHand); pXdataMap->SetAt(sKey,idHole.handle()); } } void AecDbCurveBase::RemoveBlackHole(AcDbObjectId& idHole) { AssertWriteEnabled(); AecDbObjXDataMap* pXdataMap = GetSpecialtyData(AcDb::kForWrite); if (pXdataMap != NULL) { TCHAR szHand[19]; memset(szHand,0,sizeof(szHand) ); idHole.handle().getIntoAsciiBuffer(szHand); CString sKey; sKey.Format(_T("%s_%s"),KEY_HOLE,szHand); pXdataMap->RemoveAt(sKey); } } void AecDbCurveBase::DrawBlackHole(AcDbEntity* pSolidEnt) const { AcDb3dSolid* pSolidAll = AcDb3dSolid::cast(pSolidEnt); if (pSolidAll == NULL) return; const AecDbObjXDataMap* pCXDataMap = GetSpecialtyData(); if (pCXDataMap != NULL) { AecDbObjXDataMap* pXDataMap = (AecDbObjXDataMap*)pCXDataMap; AecDbObjXDataMap::It it = pXDataMap->Begin(); AecDbObjXDataMap::It end = pXDataMap->End(); CString sKey; AecXData cVal; memset(&cVal,0,sizeof(AecXData)); AcDbEntity* pEnt = NULL; AcDbHandle hd; AcDbObjectId idHole; for (; it != end; ) { if (!pXDataMap->GetNext(it, sKey, cVal)) break; if (sKey.Find(KEY_HOLE) != -1) { pXDataMap->GetAt(sKey,hd); if ( Acad::eOk == acdbCurDwg()->getAcDbObjectId(idHole,false,hd) ) { if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idHole,AcDb::kForRead)) { AecDbEntityBase* pBlackHole = AecDbEntityBase::cast(pEnt); if (pBlackHole != NULL) { AcDb3dSolid* pSolidBlackHold = pBlackHole->GetBlackHole(); if (pSolidBlackHold != NULL) { pSolidAll->booleanOper(AcDb::kBoolSubtract,pSolidBlackHold); } } pEnt->close(); } } } } } } AcDb3dSolid* AecDbCurveBase::GetBlackHole() const { return NULL; } void AecDbCurveBase::SplitStrintToArray(LPCTSTR pszDescr, CStringArray & arInfo, TCHAR tcSpace) { if (pszDescr == NULL) return; CString sDescr = pszDescr; int nLen = sDescr.GetLength(); int i = 0; CString sText = _T(""); TCHAR tchar = _T('\0'); for (i = 0; i < nLen; i++) { tchar = sDescr.GetAt(i); if (tchar == tcSpace) { if (!sText.IsEmpty()) arInfo.Add(sText); sText = _T(""); } else { sText += tchar; } if (i == nLen - 1 && !sText.IsEmpty()) { arInfo.Add(sText); } } } AcDbPolyline * AecDbCurveBase::StringToPolyline(LPCTSTR pszPoint2ds) { CString sPlane,sTemp; CString sAll = pszPoint2ds; int nPos = sAll.Find(_T("plane=")); if (nPos != -1) { sPlane = sAll.Mid(nPos); sTemp = sAll.Mid(0,nPos); sAll = sTemp; } CStringArray arXYs; SplitStrintToArray(sAll, arXYs, _T(',')); double dEl = 0.0; AcGeVector3d vtNorm = AcGeVector3d::kZAxis; CString sLast; if (arXYs.GetSize() > 0) { sLast = arXYs.GetAt(arXYs.GetSize() - 1); if (sLast.Find(_T('[')) != -1) { sLast.TrimLeft(_T('[')); sLast.TrimRight(_T(']')); } CStringArray arVals; SplitStrintToArray(sLast, arVals, _T(';')); if (arVals.GetSize() >= 4) { dEl = _ttof(arVals.GetAt(0)); vtNorm.set(_ttof(arVals.GetAt(1)), _ttof(arVals.GetAt(2)), _ttof(arVals.GetAt(3))); } } CString sX, sYB, sBulge, sY; double dBulge = 0.0; int nFind = -1; AcGePoint2d pt; AcDbPolyline pl; AcDbPolyline* pPl = new AcDbPolyline; if (!sPlane.IsEmpty()) { sPlane.TrimLeft(_T("plane=")); sPlane.TrimLeft(_T('(')); sPlane.TrimRight(_T(')')); CStringArray arVals; SplitStrintToArray(sPlane,arVals,_T(',')); if (arVals.GetSize() >= 4) { vtNorm.set(_ttof(arVals.GetAt(0)),_ttof(arVals.GetAt(1)),_ttof(arVals.GetAt(2))); dEl = _ttof(arVals.GetAt(3)); pPl->setNormal(vtNorm); pPl->setElevation(dEl); } } else { pPl->setNormal(vtNorm); pPl->setElevation(dEl); } for (int i = 0; i < arXYs.GetSize() / 2; i++) { sX = arXYs.GetAt(2 * i); sYB = arXYs.GetAt(2 * i + 1); sY = sYB; dBulge = 0.0; nFind = sYB.Find(_T('@')); if (nFind != -1) { sBulge = sYB.Mid(nFind + 1); dBulge = _ttof(sBulge); sY = sYB.Mid(0, nFind); } pt.set(_ttof(sX), _ttof(sY)); pPl->addVertexAt(i, pt, dBulge); } return pPl; } static AcGePoint3d MidPoint(AcGePoint3d& pt1, AcGePoint3d& pt2) { return AcGePoint3d((pt1.x + pt2.x) / 2.0, (pt1.y + pt2.y) / 2.0, (pt1.z + pt2.z) / 2.0); } //剖切隐藏 void AecDbCurveBase::BoolSubtractHide() const { if (m_ar3DDrableBufPtrs_.isEmpty()) return; const AecDbObjXDataMap* pXDataMap = GetSpecialtyData(); if (pXDataMap != NULL) { CString sPl; double dBomEl = 0.0,dH = 0.0; if ( pXDataMap->GetAt(KEY_BOOLSPL,sPl) && pXDataMap->GetAt(KEY_BOOLBOM,dBomEl) && pXDataMap->GetAt(KEY_BOOLH,dH) ) { AcDbPolyline* pPl = StringToPolyline(sPl); if (pPl != NULL) { AcGePoint3d ptFr,ptTo; pPl->getPointAt(0,ptFr); //简单取内一心 if (pPl->numVerts() > 2) { AcGePoint3d pt2; pPl->getPointAt(2,pt2); ptFr = MidPoint(ptFr,pt2); } AcDbLine ln; ptFr.z = dBomEl; ptTo = ptFr; ptTo.z = dH; ln.setStartPoint(ptFr); ln.setEndPoint(ptTo); AcDbRegion* pRegion = NULL; AcDbVoidPtrArray arCur,arReg; arCur.append(pPl); Acad::ErrorStatus es; if (Acad::eOk == ( es = AcDbRegion::createFromCurves(arCur,arReg) ) ) { if (!arReg.isEmpty()) { pRegion = (AcDbRegion*)arReg.first(); AcDb3dSolid* pSoldSub = new AcDb3dSolid; if ( Acad::eOk == (es = pSoldSub->extrudeAlongPath(pRegion,&ln) ) ) { AcDb3dSolid* pSolid = NULL; AcDbEntity* pEnt = NULL; for (int i = 0;i < m_ar3DDrableBufPtrs_.length();i++) { pEnt = (AcDbEntity*)m_ar3DDrableBufPtrs_.at(i); pSolid = AcDb3dSolid::cast(pEnt); if (pSolid != NULL) { AcDb3dSolid* pSolidSubCln = (AcDb3dSolid*)pSoldSub->clone(); CopyObject(*pSoldSub,*pSolidSubCln); if ( Acad::eOk != (es = pSolid->booleanOper(AcDb::kBoolSubtract,pSolidSubCln) ) ) { delete pSolidSubCln; } } } } delete pSoldSub; delete pRegion; } } delete pPl; } } } } typedef AcArray AcDbEntityArray; void AecDbCurveBase::PreprocessForHlr(const AcGePoint3d &ptPlnO , const AcGeVector3d &vtPlnN , AcArray &ar) const { assertReadEnabled(); return; } void AecDbCurveBase::ProcessHlrResult(const AcDbEntityArray &ar , const std::map &preAr , AcDbEntityArray &output) const { assertReadEnabled(); AcDbObjectId idLy(layerId()), idLt(linetypeId()); int clr(colorIndex()); const AecDbObjXDataMap *pXData = GetSpecialtyData(); for (int i(0); i < ar.length(); ++i) { AcDbEntity *pEnt((AcDbEntity *)ar[i]->clone()); if (pEnt) { if (pXData) pXData->Write(pEnt, BIMDATA_APP); pEnt->setLayer(idLy); pEnt->setLinetype(idLt); pEnt->setColorIndex(clr); output.append(pEnt); } } } SHJson::WValue& AecDbCurveBase::ToJson(bool bExprotGeo) const { using namespace SHJson; assertReadEnabled(); WValue &v(m_json); v.SetObject(); addMember(v, _T("__class__"), isA()->name()); addMember(v, _T("__self__"), objectId().asOldId()); addMember(v, _T("__owner__"), 0); const AecDbObjXDataMap *pXMap = GetSpecialtyData(); if (pXMap) { addMember(v, _T("__xdata__"), pXMap->ToJson()); } CString sVertices, sIndices; __int64 dwRgb = 0; struct resbuf rb; acedGetVar(_T("useri5"), &rb); if (rb.resval.rint == 30)//3D导出 { WValue node; node.SetObject(); WValue body; body.SetArray(); AcDbEntity *pE = NULL; for (int i = 0; i < Get3DBuffer().length(); i++) { node.SetNull(); pE = (AcDbEntity *)Get3DBuffer().at(i); AcDb3dSolid *p3d = AcDb3dSolid::cast(pE); if (p3d != NULL) { dwRgb = RGB(p3d->color().red(), p3d->color().green(), p3d->color().blue()); if (PolyhedronGeometry(p3d, sVertices, sIndices)) { addMember(node, _T("RGB"), dwRgb); addMember(node, _T("vertices"), sVertices); addMember(node, _T("indices"), sIndices); pushBack(body, node); } } AcDbSubDMesh *pSubMesh = AcDbSubDMesh::cast(pE); if (pSubMesh != NULL) { dwRgb = RGB(pSubMesh->color().red(), pSubMesh->color().green(), pSubMesh->color().blue()); if (PolyhedronGeometry(pSubMesh, sVertices, sIndices)) { addMember(node, _T("RGB"), dwRgb); addMember(node, _T("vertices"), sVertices); addMember(node, _T("indices"), sIndices); pushBack(body, node); } } } if (!body.Empty()) addMember(v, _T("__body__"), body); } return v; } bool AecDbCurveBase::ByJson(const SHJson::WValue &v) { using namespace SHJson; AssertWriteEnabled(); AecDbObjXDataMap *pXMap = GetSpecialtyData(AcDb::kForWrite); if (pXMap) { MCIt it = v.FindMember(_T("__xdata__")); if (it != v.MemberEnd()) return pXMap->ByJson(it->value); } return true; } Acad::ErrorStatus AecDbCurveBase::setTransparency(const AcCmTransparency &trans, Adesk::Boolean doSubents) { AssertWriteEnabled(); return AcDbEntity::setTransparency(trans, doSubents); } CString AecDbCurveBase::getUniqueName() const { return _T(""); }