AutoCAD 3rdParty

[CAD] 치수 속성창 값을 사용자가 변경한 경우 유지되는 메커니즘

matesoft 2026. 3. 18. 18:55
반응형

개요

치수의 속성창에서 속성값을 변경한 경우 [치수스타일대화상자(dimstyle)]에서 동일한 값을 변경하여도 속성창에서 변경한 값으로 유지되는 메커니즘에 대해 알아보자.

기본적으로, 치수를 생성하면(어떤 치수든) 치수 객체에 다음 2가지에 대한 XData를 생성한다.

  • [1차단위]의 [선형 치수 축척]
  • [맞춤]의 [전체 치수 축척]

 

여기서 XData란 eXtended Data의 약자로 AutoCAD에서 Entity에 16Kbyte 이하의 데이터를 추가로 붙여서 저장할 수 있는 resbuf들의 연결 리스트이다. AutoCAD는 이 정보를 유지 관리하지만 직접 사용하지는 않는다. resbuf 데이터는 1000 ~ 1071 범위의 DXF 그룹 코드를 사용한다. 다음은 XData를 가져오고 설정하는 간단한 활용 코드 예제이다.

void printXdata()
{
    AcDbObject *pObj;
    if ((pObj = selectObject(AcDb::kForRead)) == NULL) {
        return;
    }

    char appname[133];
    if (acedGetString(NULL,
        "\nEnter the desired Xdata application name: ",
        appname) != RTNORM)
    {
        return;
    }
    
    struct resbuf *pRb;
    pRb = pObj->xData(appname);
    if (pRb != NULL) {
        printList(pRb);
        acutRelRb(pRb);
    } else {
        acutPrintf("\nNo xdata for this appname");
    }
    pObj->close();
}

void addXdata() 
{
    AcDbObject* pObj = selectObject(AcDb::kForRead);
    if (!pObj) {
        acutPrintf("Error selecting object\n");
        return;
    }

    char appName[132], resString[200];
    appName[0] = resString[0] = '\0';
    acedGetString(NULL, "Enter application name: ",
        appName);
    acedGetString(NULL, "Enter string to be added: ",
        resString);
    struct  resbuf  *pRb, *pTemp;
    pRb = pObj->xData(appName);
    if (pRb != NULL) {
        for (pTemp = pRb; pTemp->rbnext != NULL;
                pTemp = pTemp->rbnext)
                { ; }
    } else {
        acdbRegApp(appName);
        pRb = acutNewRb(AcDb::kDxfRegAppName);
        pTemp = pRb;
        pTemp->resval.rstring
            = (char*) malloc(strlen(appName) + 1);
        strcpy(pTemp->resval.rstring, appName);
    }

    pTemp->rbnext = acutNewRb(AcDb::kDxfXdAsciiString);
    pTemp = pTemp->rbnext;
    pTemp->resval.rstring
        = (char*) malloc(strlen(resString) + 1);
    strcpy(pTemp->resval.rstring, resString);
    
    pObj->upgradeOpen();
    pObj->setXData(pRb);
    pObj->close();
    acutRelRb(pRb);
}


사용자가 치수 객체를 선택한 후 속성창에서 값을 변경하면 변경한 값을 XData 형태로 기록한다. 저장된 값은  [치수스타일대화상자]의 값이 변경되더라도 유지된다.
그러면 좀 더 자세하게 속성창 값이 유지되는 메커니즘에 대해 설명한다.

설명

치수 객체는 사용자가 속성 값을 변경한 경우 그 값을 유지하기 위하여 객체 자체의 XData 영역에 값을 저장한다. 값을 저장할 때 ResBuf 형태로 저장하고 다음과 같은 그룹 코드를 갖는다.

PrintDimensionOverrides.h 에 정의 되어 있는 DXF DimStyle 그룹 코드

enum DXFDimstyleGroupCodes
{
    DIMPOST		= 3,// DIMPOST
    DIMAPOST	= 4,
    DIMBLK_OBS  = 5,// DIMBLK (obsolete, now object ID)
    DIMBLK1_OBS = 6,// DIMBLK1 (obsolete, now object ID)
    DIMBLK2_OBS = 7,// DIMBLK2 (obsolete, now object ID)
    DIMSCALE	= 40,
    DIMASZ		= 41,
    DIMEXO		= 42,
    DIMDLI		= 43,
    DIMEXE		= 44,
    DIMRND		= 45,
    DIMDLE		= 46,
    DIMTP		= 47,
    DIMTM		= 48,
    DIMTXT		= 140,
    DIMCEN		= 141,
    DIMTSZ		= 142,
    DIMALTF		= 143,
    DIMLFAC		= 144,
    DIMTVP		= 145,
    DIMTFAC		= 146,
    DIMGAP		= 147,
    DIMALTRND	= 148,
    DIMTOL		= 71,
    DIMLIM		= 72,
    DIMTIH		= 73,
    DIMTOH		= 74,
    DIMSE1		= 75,
    DIMSE2		= 76,
    DIMTAD		= 77,
    DIMZIN		= 78,
    DIMAZIN		= 79,
    DIMALT		= 170,
    DIMALTD		= 171,
    DIMTOFL		= 172,
    DIMSAH		= 173,
    DIMTIX		= 174,
    DIMSOXD		= 175,
    DIMCLRD		= 176,
    DIMCLRE		= 177,
    DIMCLRT		= 178,
    DIMADEC		= 179,
    DIMDEC		= 271,
    DIMTDEC		= 272,
    DIMALTU		= 273,
    DIMALTTD	= 274,
    DIMAUNIT	= 275,
    DIMFRAC		= 276,
    DIMLUNIT	= 277,
    DIMDSEP		= 278,
    DIMTMOVE	= 279,
    DIMJUST		= 280,
    DIMSD1		= 281,
    DIMSD2		= 282,
    DIMTOLJ		= 283,
    DIMTZIN		= 284,
    DIMALTZ		= 285,
    DIMALTTZ	= 286,
    DIMUPT		= 288,
    DIMATFIT	= 289,
    DIMTXSTY	= 340,// DimTextStyle(handle of referenced STYLE)
    DIMLDRBLK	= 341,// DIMLDRBLK(handle of referenced BLOCK)
    DIMBLK		= 342,// DIMBLK(handle of referenced BLOCK)
    DIMBLK1		= 343,// DIMBLK1(handle of referenced BLOCK)
    DIMBLK2		= 344,// DIMBLK2(handle of referenced BLOCK)
    DIMLTYPE	= 345,// DIMLTYPE
    DIMLTEX1	= 346,
    DIMLTEX2	= 347,
    DIMLWD		= 371,
    DIMLWE		= 372,
    MaxValue	= DIMLWE,
    MinValue	= DIMPOST
};

 

사용자가 치수 속성 창에서 값을 바꾸면 시스템은 DXF 코드와 값을 Pair로 기록한다.

다음은 속성 창에서 치수선 연장 값을 100으로 변경한 예시 이다. 시스템에서 ACAD라는 RegName을 만들고 중괄호 {} 카테고리를 만든 다음 사용자가 변경한 값들을 XData로 저장 한다.

XData는 항상 Pair로 저장 됨

 

그러면, 왜 치수 스타일 대화 상자에서 값을 변경할 때 속성 창에서 변경한 값은 변경 되지 않을까?

의외로 간단 하다.

if (!isEqualTo(style->dimlfac(), styleClone->dimlfac()))
{
	double dOrglfac = style->dimlfac();
	double dNewlfac = styleClone->dimlfac();
	AcDbObjectIdArray arDim = style->getPersistentReactors();

	unsigned int nSize = arDim.size();
	for (unsigned int i = 0; i < nSize; i++)
	{
		AcDbObject* pObj = arDim[i].safeOpenObject(OdDb::kForWrite);
		if (!pObj->isKindOf(AcDbDimension::desc()))
			continue;
		AcDbDimension* pDim = AcDbDimension::cast(pObj);

		double dimlfac = pDim->dimlfac();

		double dAreaFac, dAreascale;
		if (!GetAreaFactor_Property(pDim, dAreaFac, dAreascale)) return;
		dimlfac = dimlfac * dAreaFac;

		if (isEqualTo(dimlfac, dOrglfac))
		{
			dimlfac = safeDivide(dNewlfac, dAreaFac);
			pDim->setDimlfac(dimlfac);
		}
	}
}

여기서, dimlfac은 선형 축척 비율이다.

 

위 코드는 [치수스타일대화상자]에서 1차 단위의 선형 치수 축척의 변경이 있을 때 호출되는 부분이다. 빨간색 화살표에 기술되어 있는 것처럼 치수 객체의 XData에 저장되어 있는 값(dimlfac)과 치수 스타일 레코드에 저장되어 있는 값(dOrglfac)이 같을 때에만 적용되도록 코딩 되어 있는 것을 알 수 있다.  

따라서, 속성 창에서 치수 스타일 값과 동일하게 값을 변경하면 스타일의 값이 변경될 때 객체의 속성 값도 함께 바꿀 수 있음을 의미 한다.

반응형