示例#1
0
void readDatabase()
{
	// Use kFalse to create an empty database.
    AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);

    // Use readDwgFile to load the DWG file.
	acutPrintf(_T("\nRead file \"d:\\temp\\testfile.dwg\"."));
    if(Acad::eOk != pDb->readDwgFile(_T("d:\\temp\\testfile.dwg")))
        return;

    // Get the BlockTable.
    AcDbBlockTable *pBTable = NULL;
    pDb->getSymbolTable(pBTable, AcDb::kForRead);

	// Get the ModelSpace.
    AcDbBlockTableRecord *pRecord = NULL;
    pBTable->getAt(ACDB_MODEL_SPACE, pRecord, AcDb::kForRead);
    pBTable->close();

	// Get new iterator.
    AcDbBlockTableRecordIterator *pItr = NULL;
    pRecord->newIterator(pItr);

    AcDbEntity *pEnt = NULL;
    for (pItr->start(); !pItr->done(); pItr->step())
    {
        pItr->getEntity(pEnt, AcDb::kForRead);
        acutPrintf(_T("\nclassname: %s"), (pEnt->isA())->name());
        pEnt->close();
    }
    pRecord->close();
    delete pItr;
    delete pDb;
}
void frgExtractTopologicalEntsFromLinesAlgm::_extract_from_seg(Vertex2dsOnSegment2d &stru)
{
	// - 获取相关的线段(相交、重合)
	AcDbObjectIdArray ids;
	_search_related_segs(ids, stru.seg);

	// - 分为两类进行处理:相交和重叠
	// -- 增加起点和终点
	rlVertex2d *v = NULL;
	stru.vertex2ds.insert(std::make_pair(0.0, v));
	stru.vertex2ds.insert(std::make_pair(1.0, v));

	// -- 处理每一个线段
	AcDbEntity *entity = NULL;
	for (int i = 0; i < ids.length(); i++)
	{
		acdbOpenAcDbEntity(entity, ids[i], AcDb::kForRead);
		if (entity == NULL)
			continue;

		if (entity->isA() != AcDbLine::desc())
		{
			entity->close();
			continue;
		}
		AcDbLine *_line = (AcDbLine *)entity;

		AcGeLineSeg2d _seg(AcGePoint2d(_line->startPoint().x, _line->startPoint().y),
			AcGePoint2d(_line->endPoint().x, _line->endPoint().y));
		_line->close();

		_extract_vertices(stru, _seg);
	}
}
void frgExtractTopologicalEntsFromLinesAlgm::_extract_vertices_from_lines(std::vector<Vertex2dsOnSegment2d> &seg_pnts_pairs,
	const AcDbObjectIdArray &ids)
{
	AcDbEntity *entity = NULL;
	acedSetStatusBarProgressMeter(_T("正在提取每根线段上的节点..."), 0, ids.length());
	for (int i = 0; i < ids.length(); i++)
	{
		acdbOpenAcDbEntity(entity, ids[i], AcDb::kForRead);
		if (entity == NULL)
			continue;

		if (entity->isA() != AcDbLine::desc())
		{
			entity->close();
			continue;
		}
		AcDbLine *line = (AcDbLine *)entity;

		Vertex2dsOnSegment2d stru;
		stru.seg.set(AcGePoint2d(line->startPoint().x, line->startPoint().y),
			AcGePoint2d(line->endPoint().x, line->endPoint().y));
		entity->close();

		_extract_from_seg(stru);
		seg_pnts_pairs.push_back(stru);
		acedSetStatusBarProgressMeterPos(i);
	}
	acedRestoreStatusBar();
}
示例#4
0
BOOL CDetailShow::OnInitDialog()
{
	CAcUiDialog::OnInitDialog();

	// TODO:  在此添加额外的初始化
	long len = m_objIds.length();
	//取得选择集的长度
	//遍历选择集中的实体,将其打开并修改其颜色为红色
	for (int i =0;i<len;i++)
	{
		ads_name entres;
		AcDbObjectId objId;
		AcDbEntity *obj;
		Acad::ErrorStatus es;
		es = acdbOpenAcDbEntity(obj, m_objIds[i], AcDb::kForRead, true);
		if (es == Acad::eOk) {
			LPCTSTR str;
			str = obj->isA()->name();
			m_listBox.AddString(str);
			obj->close();
		}
		
	}
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}
示例#5
0
    // ----- AsdkSelectionFilterUI.SubentSel command (do not rename)
    static void AsdkSelectionFilterUI_SubentSel(void)
    {
        // we have to allow duplicates; otherwise, the xref would be selectable
        // only once (because the main entity is the one that counts).

        setAllowDuplicateSelection(curDoc(), true);
        ads_name sset, eName;
        AcDbObjectId id;

        // "_:n" gives us nested entities
        //
        if (RTNORM == acedSSGet("_:n", NULL, NULL, NULL, sset))
        {
            acutPrintf("\n");
            long len = 0;
            acedSSLength(sset, &len);
            for (long i = 0; i < len; i++)// For each entity in sset
            {

                resbuf *rb = NULL;
                // We use ssnamex() here, because the regular ssname()
                // would give only the main entity (the xref)
                //
                if (RTNORM == acedSSNameX(&rb, sset, i))//Get the sub entity
                {
                    resbuf *rbWalk = rb;
                    while (NULL != rbWalk)
                    {
                        if (RTENAME == rbWalk->restype)
                        {
                            eName[0] = rbWalk->resval.rlname[0];
                            eName[1] = rbWalk->resval.rlname[1];
                            if(Acad::eOk == acdbGetObjectId(id, eName))
                            {
                                acutPrintf("Entity %d: <%x>", i, id.asOldId());
                                AcDbEntity *pEnt;
                                if (Acad::eOk == acdbOpenObject(pEnt, id, AcDb::kForRead))
                                {
                                    acutPrintf("(%s)\n", pEnt->isA()->name());
                                    pEnt->close();
                                }
                                else
                                    acutPrintf("\nCouldn't open object");
                            }
                            rbWalk = NULL; //force quit out of loop
                        }
                        else
                            rbWalk = rbWalk->rbnext;
                    }
                    acutRelRb(rb);
                }
            }
            acedSSFree(sset);
        }

        setAllowDuplicateSelection(curDoc(), false);
    }
示例#6
0
void ZcEntityReactor::modified(const AcDbObject* dbObj)
{
	if (!dbObj->isKindOf(AcDbEntity::desc()))
	{
		acutPrintf(_T("\nObject is not a valid Entity!"));
		return;
	}

	AcDbEntity* pEnt = AcDbEntity::cast(dbObj);
	CString strLayer;
	strLayer.Format(_T("\nEntity:%s has been modified.The layerName:%s.\n"), pEnt->isA()->name(), pEnt->layer());
	acutPrintf(strLayer);
}
示例#7
0
void ZcEntityReactor::openedForModify(const AcDbObject* dbObj)
{
	if (!dbObj->isKindOf(AcDbEntity::desc()))
	{
		acutPrintf(_T("\nObject is not a valid Entity!"));
		return;
	}

	AcDbEntity* pEnt = AcDbEntity::cast(dbObj);
	CString strLayer;
	strLayer.Format(_T("\nCurrent Entity:%s .The layerName:%s ."), pEnt->isA()->name(), pEnt->layer());
	acutPrintf(strLayer);
}
void

readDwg()

{

    // Set constructor parameter to kFalse so that the

    // database will be constructed empty.  This way only

    // what is read in will be in the database.

    //

    AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);



    // The AcDbDatabase::readDwgFile() function

    // automatically appends a DWG extension if it is not

    // specified in the filename parameter.

    //

    if(Acad::eOk != pDb->readDwgFile(_T("./test1.dwg")))

        return;



    // Open the model space block table record.

    //

    AcDbBlockTable *pBlkTbl;

    pDb->getSymbolTable(pBlkTbl, AcDb::kForRead);



    AcDbBlockTableRecord *pBlkTblRcd;

    pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd,

        AcDb::kForRead);

    pBlkTbl->close();



    AcDbBlockTableRecordIterator *pBlkTblRcdItr;

    pBlkTblRcd->newIterator(pBlkTblRcdItr);



    AcDbEntity *pEnt;

    for (pBlkTblRcdItr->start(); !pBlkTblRcdItr->done();

        pBlkTblRcdItr->step())

    {

        pBlkTblRcdItr->getEntity(pEnt,

            AcDb::kForRead);

        acutPrintf(_T("classname: %s\n"),

            (pEnt->isA())->name());

        pEnt->close();

    }

    pBlkTblRcd->close();

    delete pBlkTblRcdItr;

    delete pDb;

}
示例#9
0
void setInsertLayer()
{
	// Iterate through Model Space to find every instance of the EMPLOYEE block
	// When found, change its layer to "USER"
	
	Acad::ErrorStatus es;
	AcDbBlockTable* pBlockTbl;
	AcDbBlockTableRecord* pMS;

	if ((es = acdbCurDwg()->getBlockTable(pBlockTbl, AcDb::kForRead)) == Acad::eOk)
	{
	//Get the Model Space record and open it for read.
        if ((es = pBlockTbl->getAt(ACDB_MODEL_SPACE, pMS, AcDb::kForWrite)) != Acad::eOk)
		{
			acrx_abort("\nCouldn't get Model Space! Drawing corrupt.\n");
		}
	    pBlockTbl->close();
    }

	// declare the appropriate iterator
	// get the iterator from the object to be iterated through

	// in this case, the Model Space block table record will provide the iterator
	// start at the beginning of the record and skip deleted entities

	AcDbBlockTableRecordIterator* pBtrIter;
	if ((es = pMS->newIterator(pBtrIter)) != Acad::eOk)
	{
		acutPrintf("\nCouldn't create Model Space iterator: %s", acadErrorStatusText(es));
		return;
	}

	char* blockName;  
	AcDbEntity* pEnt;
	AcDbBlockTableRecord* pCurEntBlock;
	AcDbObjectId blockId;

	for (pBtrIter->start(); !pBtrIter->done(); pBtrIter->step())
	{
		// first open each entity for read, just to check its class
		// if it's what we want, we can upgrade open later
		// Don't bother with erased entities
		if ((es = pBtrIter->getEntity(pEnt, AcDb::kForRead)) != Acad::eOk)
		{
			acutPrintf("\nCouldn't open entity:  %s", acadErrorStatusText(es));
			continue;
		}

		// check isf the entity is an instance of type AcDbBlockReference
		if (pEnt->isA() != AcDbBlockReference::desc())
		{
			pEnt->close();
			continue;
		}
		
		// get the insert's block table record and compare its name
		// to make sure we've got the right block.  If so, set the layer
		blockId = (AcDbBlockReference::cast(pEnt))->blockTableRecord();
		if (acdbOpenObject((AcDbObject*&)pCurEntBlock, blockId, AcDb::kForRead) == Acad::eOk)
		{
			pCurEntBlock->getName(blockName);
			if (strcmp(blockName, "EMPLOYEE") == 0)
			{
				if (pEnt->upgradeOpen() == Acad::eOk)
					// setLayer also has an overload that takes a layer ID
					// but to avoid global variables we specify the layer name
					pEnt->setLayer("USER");
			}
			pCurEntBlock->close();
			acdbFree ( blockName );
		}
		pEnt->close();
	}

	// delete, rather than close, the iterator object
	delete pBtrIter;
    pMS->close();
	return;

}
Adesk::Boolean
AecUiPrEntitySet::verifyPickfirstSet(Adesk::Boolean singleSelect)
{
    if (m_disallowPickfirstSet) {
        cleanPickfirstSet();
        return Adesk::kFalse;
    }

    // if the set is already selected, verify that it has
    // the right stuff in it.
    AecBaseEditorReactor* edReact = AecUiBaseServices::getEditorReactor();
    if (edReact == NULL) {
        AEC_ASSERT(0);
        cleanPickfirstSet();
        return Adesk::kFalse;
    }

    m_selSet.setLogicalLength(0);   // reset to null set

    AcDbEntity* ent;
    Acad::ErrorStatus es;
    int filteredBecauseOfClass = 0;
    int filteredBecauseOfLockedLayer = 0;

    const AcDbObjectIdArray& pickSet = edReact->pickfirstSet();
    int len = pickSet.length();

    // if only allowing single select, bail if more than 1 item
    // in the pickfirst set.
    if (singleSelect && (len > 1)) {
        ads_printf(_DNT(_T("\n"))); // make sure we get to a new line
        AecRmCString tmpStr(GetAecUiBaseAppName(), AECU_STR_VERIFYPICKFIRSTSET_AECUIPRENTITYSET_TOO_MANY_OBJECTS, TRUE);
        ads_printf(tmpStr);        //~  "Too many objects in the pickfirst set, please select again.\n"
        cleanPickfirstSet();
        return Adesk::kFalse;
    }

    for (int i=0; i<len; i++) {
        es = acdbOpenAcDbEntity(ent, pickSet[i], AcDb::kForRead);
        if (es == Acad::eOk) {
            if (isCorrectClassType(ent->isA()) == Adesk::kFalse) {
                filteredBecauseOfClass++;
                ent->close();
                continue;
            }
            if (m_filterLockedLayers && m_lockedLayerCache.contains(ent->layerId())) {
                filteredBecauseOfLockedLayer++;
                ent->close();
                continue;
            }

            ent->close();
            m_selSet.append(pickSet[i]);
        }
        else {
            Aec::ads_printf(GetAecUiBaseAppName(), AECU_STR_VERIFYPICKFIRSTSET_AECUIPRENTITYSET_COULD_NOT_OPEN_ENTITY_FOR_READ, Aec::rxErrorStr(es)); //~ "\nCould not open entity for read: %s"
        }
    }

    ads_printf(_DNT(_T("\n"))); // make sure we get to a new line

    if (filteredBecauseOfClass == 1) {
        AecRmCString tmpStr(GetAecUiBaseAppName(), AECU_STR_VERIFYPICKFIRSTSET_AECUIPRENTITYSET_OBJECT_WAS, TRUE);
        ads_printf(tmpStr);    // NOTE: leave \n's at end so you can see message before dialog comes up (jma)        //~  "1 object was of the wrong type.\n"
    }
    else if (filteredBecauseOfClass > 1) {
        Aec::ads_printf(GetAecUiBaseAppName(), AECU_STR_VERIFYPICKFIRSTSET_AECUIPRENTITYSET_OBJECTS_WERE_OF_THE_WRONG_TYPE, filteredBecauseOfClass); //~ "%ld objects were of the wrong type.\n"
    }

    if (filteredBecauseOfLockedLayer == 1) {
        AecRmCString tmpStr(GetAecUiBaseAppName(), AECU_STR_VERIFYPICKFIRSTSET_AECUIPRENTITYSET_OBJECT_WAS_0, TRUE);
        ads_printf(tmpStr);        //~  "1 object was on a locked layer.\n"
    }
    else if (filteredBecauseOfLockedLayer > 1) {
        Aec::ads_printf(GetAecUiBaseAppName(), AECU_STR_VERIFYPICKFIRSTSET_AECUIPRENTITYSET_OBJECTS_WERE_ON_LOCKED_LAYER, filteredBecauseOfLockedLayer); //~"%ld objects were on a locked layer.\n"
    }

    if ((len > 0) && m_selSet.isEmpty()) {
        AecRmCString tmpStr(GetAecUiBaseAppName(), AECU_STR_VERIFYPICKFIRSTSET_AECUIPRENTITYSET_ALL_OBJECTS_IN, TRUE);
        ads_printf(tmpStr);        //~  "All objects in the pickfirst set were filtered out, please select again.\n"
    }

    cleanPickfirstSet();

    return !m_selSet.isEmpty();
}
void extractVertexCoords(const AcDbObjectId& objID, std::map<std::wstring, AcGePoint3d>& m_3dPoints)
{
	AcDbEntity* pEnt = nullptr;
	acdbOpenObject(pEnt, objID, AcDb::kForRead);

	             /*****Pline****/
	if (pEnt->isA() == AcDbPolyline::desc())
	{
		AcDbPolyline* pLine = static_cast<AcDbPolyline*>(pEnt);
		pEnt->close();
		acdbOpenObject(pLine, objID, AcDb::kForRead);
		AcGePoint3d vertex;
		for (LONGLONG i = 0; i < pLine->numVerts(); i++)
		{
			pLine->getPointAt(i, vertex);
			std::wstring w_nrPunct = std::to_wstring(i + 1);
			m_3dPoints.insert(std::pair<std::wstring, AcGePoint3d>(w_nrPunct, vertex));
		}

		pLine->close();	
	}

	            /******P2dLine****/
	else if (pEnt->isA() == AcDb2dPolyline::desc())
	{
		AcGePoint3d point;
		AcDbObjectId vertexID;
		AcDb3dPolylineVertex* pVertex = nullptr;

		AcDb2dPolyline* p2dline = static_cast<AcDb2dPolyline*>(pEnt);
		pEnt->close();

		acdbOpenObject(p2dline, objID, AcDb::kForRead);
		AcDbObjectIterator* pIterator = p2dline->vertexIterator();
		for (pIterator->start(); !pIterator->done(); pIterator->step())
		{
			LONGLONG contor = 1;
			vertexID = pIterator->objectId();
			acdbOpenObject(pVertex, vertexID, AcDb::kForRead);
			point = pVertex->position();

			std::wstring w_nrPunct = std::to_wstring(contor);
			contor++;
			m_3dPoints.insert(std::pair<std::wstring, AcGePoint3d>(w_nrPunct, point));

			pVertex->close();
		}
		delete pIterator;
		p2dline->close();
	}

	         /***********P3dLine**************/
	else if (pEnt->isA() == AcDb3dPolyline::desc())
	{
		AcGePoint3d point;
		AcDbObjectId vertexID;
		AcDb3dPolylineVertex* pVertex = nullptr;

		AcDb3dPolyline* p3dline = static_cast<AcDb3dPolyline*>(pEnt);
		pEnt->close();

		acdbOpenObject(p3dline, objID, AcDb::kForRead);
		AcDbObjectIterator* pIterator = p3dline->vertexIterator();

		for (pIterator->start(); !pIterator->done(); pIterator->step())
		{
			LONGLONG contor = 1;
			vertexID = pIterator->objectId();
			acdbOpenObject(pVertex, vertexID, AcDb::kForRead);
			point = pVertex->position();

			std::wstring w_nrPunct = std::to_wstring(contor);

			m_3dPoints.insert(std::pair<std::wstring, AcGePoint3d>(w_nrPunct, point));
			pVertex->close();
		}
		delete pIterator;
		p3dline->close();
	}
	else
	{
		pEnt->close();
		acutPrintf(_T("\nObiectul selectat nu este o polilinie"));
	}

}
示例#12
0
void
printAll()
{
    int rc;
    char blkName[50];
    rc = acedGetString(Adesk::kTrue,
        "Enter Block Name <CR for current space>: ",
        blkName);

    if (rc != RTNORM)
        return;

    if (blkName[0] == '\0') {
        if (acdbHostApplicationServices()->workingDatabase()->tilemode() 
            == Adesk::kFalse) {
            struct resbuf rb;
            acedGetVar("cvport", &rb);
            if (rb.resval.rint == 1) {
                strcpy(blkName, ACDB_PAPER_SPACE);
            } else {
                strcpy(blkName, ACDB_MODEL_SPACE);
            }
        } else {
            strcpy(blkName, ACDB_MODEL_SPACE);
        }
    }
    AcDbBlockTable *pBlockTable;
    acdbHostApplicationServices()->workingDatabase()
        ->getSymbolTable(pBlockTable, AcDb::kForRead);

    AcDbBlockTableRecord *pBlockTableRecord;
    pBlockTable->getAt(blkName, pBlockTableRecord,
        AcDb::kForRead);
    pBlockTable->close();

    AcDbBlockTableRecordIterator *pBlockIterator;
    pBlockTableRecord->newIterator(pBlockIterator);

    for (; !pBlockIterator->done();
        pBlockIterator->step())
    {
        AcDbEntity *pEntity;
        pBlockIterator->getEntity(pEntity, AcDb::kForRead);

        AcDbHandle objHandle;
        pEntity->getAcDbHandle(objHandle);

        char handleStr[20];
        objHandle.getIntoAsciiBuffer(handleStr);
        const char *pCname = pEntity->isA()->name();

        acutPrintf("Object Id %lx, handle %s, class %s.\n",
            pEntity->objectId(), handleStr, pCname);

        pEntity->close();
    }
    delete pBlockIterator;
    pBlockTableRecord->close();

    acutPrintf("\n");
}
示例#13
0
//
// This is where we take advantage of quite a bit of information
// provide by this big function to display multiline tooltip
// (new feature in Acad 2002) under the cursor aperture.
//
// It gets even more interesting when you mix it with OSNAP info.
//
// Have fun!
//
Acad::ErrorStatus 
CSampleIPM::monitorInputPoint(
	 bool& bAppendToTooltipStr,
     char*& pAdditionalTooltipString,
     AcGiViewportDraw* pDrawContext,
     AcApDocument* pDocument,
     bool pointComputed,
     int history,
     const AcGePoint3d& lastPoint,
     const AcGePoint3d& rawPoint,
     const AcGePoint3d& grippedPoint,
     const AcGePoint3d& cartesianSnappedPoint,
     const AcGePoint3d& osnappedPoint,
     AcDb::OsnapMask osnapMask,
     const AcArray<AcDbCustomOsnapMode*>& customOsnapModes,
     AcDb::OsnapMask osnapOverrides,
     const AcArray<AcDbCustomOsnapMode*>& customOsnapOverrides,
     const AcArray<AcDbObjectId>& apertureEntities,
     const AcArray< AcDbObjectIdArray,
     AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedApertureEntities,
     const AcArray<int>& gsSelectionMark,
     const AcArray<AcDbObjectId>& keyPointEntities,
     const AcArray< AcDbObjectIdArray,
     AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedKeyPointEntities,
     const AcArray<int>& keyPointGsSelectionMark,
     const AcArray<AcGeCurve3d*>& alignmentPaths,
     const AcGePoint3d& computedPoint,
     const char* pTooltipString)
{
	char mtooltipStr[1024],
		 tempStr[100];
	mtooltipStr[0] = '\0';

	Acad::ErrorStatus es;
	AcDbEntity* pEnt;
	AcDbObjectId highlightId = AcDbObjectId::kNull;

	if (pointComputed)
	{
		//
		// Analyze the aperture entities.
		//
		if (apertureEntities.length() > 0)
		{
			if(strlen(mtooltipStr) > 0)
				strcpy(mtooltipStr, "\nEntities under the cursor aperture:");
			else
				strcpy(mtooltipStr, "Entities under the cursor aperture:");

			for (int i = 0; i < apertureEntities.length(); ++i)
			{
				if (Acad::eOk != (es = acdbOpenAcDbEntity(pEnt, apertureEntities[i], AcDb::kForRead)))
					continue;

					sprintf(tempStr, "\n  %s%s%d%s", pEnt->isA()->name(), " <Object ID: ", pEnt->objectId(), ">");
					strcat(mtooltipStr, tempStr);
					pEnt->close();

					// Analyze the nested aperture entities.
					AcDbObjectIdArray nestedIds = nestedApertureEntities[i];
					int length = nestedIds.length();
					if (length > 1)
					{
						// There is a nested entitiy: get it.
						AcDbEntity* pEnt2;
						if (Acad::eOk == (es = acdbOpenAcDbEntity(pEnt2, nestedIds[length - 1], AcDb::kForRead))) {
							sprintf(tempStr, "\n  nested: %s", pEnt2->isA()->name());
							strcat(mtooltipStr, tempStr);
							pEnt2->close();
						}
					}
			}
			highlightId = apertureEntities[0];
		}

		//
		// Analyze OSNAP.
		//

		if (history && Acad::eOsnapped)
		{
			char osnapInfo[500];
			osnapInfo[0] = '\0';

			switch (osnapMask)
			{
			case AcDb::kOsMaskEnd:
				strcpy(osnapInfo, "\nOsnap:\n  end");
				break;
			case AcDb::kOsMaskMid:
				strcpy(osnapInfo, "\nOsnap:\n  mid");
				break;
			case AcDb::kOsMaskCen:
				strcpy(osnapInfo, "\nOsnap:\n  center");
				break;
			case AcDb::kOsMaskNode:
				strcpy(osnapInfo, "\nOsnap:\n  node");
				break;
			case AcDb::kOsMaskQuad:
				strcpy(osnapInfo, "\nOsnap:\n  quadrant");
				break;
			case AcDb::kOsMaskInt:
				strcpy(osnapInfo, "\nOsnap:\n  intersection");
				break;
			case AcDb::kOsMaskIns:
				strcpy(osnapInfo, "\nOsnap:\n  insert");
				break;
			case AcDb::kOsMaskPerp:
				strcpy(osnapInfo, "\nOsnap:\n  perpendicular");
				break;
			case AcDb::kOsMaskTan:
				strcpy(osnapInfo, "\nOsnap:\n  tangent");
				break;
			case AcDb::kOsMaskNear:
				strcpy(osnapInfo, "\nOsnap:\n  near");
				break;
			case AcDb::kOsMaskQuick:
				strcpy(osnapInfo, "\nOsnap:\n  quick");
				break;
			case AcDb::kOsMaskApint:
				strcpy(osnapInfo, "\nOsnap:\n  apint");
				break;
			case AcDb::kOsMaskImmediate:
				strcpy(osnapInfo, "\nOsnap:\n  immediate");
				break;

			case AcDb::kOsMaskAllowTan:
				strcpy(osnapInfo, "\nOsnap:\n  allowTan");
				break;
			case AcDb::kOsMaskDisablePerp:
				strcpy(osnapInfo, "\nOsnap:\n  DisablePerp");
				break;
			case AcDb::kOsMaskRelCartesian:
				strcpy(osnapInfo, "\nOsnap:\n  RelCartesian");
				break;
			case AcDb::kOsMaskRelPolar:
				strcpy(osnapInfo, "\nOsnap:\n  RelPolar");
				break;
			}
			if (strlen(osnapInfo))
			{
				if (keyPointEntities.length())
				{
					strcat(osnapInfo, "\nKey entities:");
					for (int i=0; i<keyPointEntities.length(); ++i)
					{
						if (Acad::eOk != (es = acdbOpenAcDbEntity(pEnt, keyPointEntities[i], AcDb::kForRead)))
							continue;

						sprintf(tempStr, "\n    %s", pEnt->isA()->name());
						strcat(osnapInfo, tempStr);
						pEnt->close();
					}
				}
			}
			strcat(mtooltipStr, osnapInfo);
		}
	}

	//
	// Do highlighting, only the top level entity is highlighted.
	//
	static AcDbObjectId oldHighlightId = AcDbObjectId::kNull;
	if(highlightId != oldHighlightId)
	{
		if (AcDbObjectId::kNull != oldHighlightId)
		{
			es = acdbOpenAcDbEntity(pEnt, oldHighlightId, AcDb::kForRead);
			if (es == Acad::eOk)
			{
				es = pEnt->unhighlight();
				pEnt->close();
				oldHighlightId = AcDbObjectId::kNull;
			}
		}
		es = acdbOpenAcDbEntity(pEnt, highlightId, AcDb::kForRead);
		if (es == Acad::eOk)
		{
			es = pEnt->highlight();
			pEnt->close();
			oldHighlightId = highlightId;
		}
	}

	// Turn on additional tooltip.
	bAppendToTooltipStr = true;
	pAdditionalTooltipString = mtooltipStr;
	return Acad::eOk;
}