AutoCAD 데이터베이스 기초


 



































AutoCAD 데이터베이스 개요
 
 

AutoCAD 도면은 데이터베이스에 저장된 객체의 집합체입니다. 기본 데이터베이스 객체는 엔티티, 기호 테이블, 딕셔너리 등입니다. 엔티티는 AutoCAD 도면안에서 그래픽으로 표시되는 데이터베이스의 특정한 종류입니다. 선, 원, 호, 문자, 스플라인 및 타원 등은 엔티티의 예입니다. 사용자는 화면상에서 엔티티를 볼 수 있고 다룰 수 있습니다.

기호 테이블과 딕셔너리는 데이터베이스 객체를 저장하기 위해 사용되는 컨테이너(그릇)입니다. 두 컨테이너 객체는 데이터베이스 객체를 기호이름(문자열)로 인식합니다. AutoCAD 데이터베이스는 기호 테이블 레코드의 특정 클래스의 인스턴스를 포함하는 각각의 기호 테이블의 고정된 세트를 가지고 있습니다. 기호 테이블의 예로는 도면층 테이블(AcDbLayerTable)과 블록 테이블(AcDbBlockTable)을 들수 있습니다. 모든 AutoCAD 엔티티는 블록 테이블 레코드에 의해 소유됩니다.

딕셔너리는 기호 테이블보다 객체 저장에 있어서 더 많은 일반적인 컨테이너를 제공합니다. 딕셔너리는 AcDbObject 유형의 어떤 객체 또는 하위 클래스에 대한 것도 포함할 수 있습니다. AutoCAD 데이터베이스는 새로운 도면을 생성할 때 명명된 객체 딕셔너리라 불리우는 딕셔너리를 자동적으로 생성합니다. 명명된 객체 딕셔너리는 데이터베이스와 조합된 모든 딕셔너리에 대한 “컨텐츠들의 테이블”의 주인으로서 보여질 수 있습니다. 사용자는 명명된 객체 딕셔너리내에 새로운 딕셔너리들을 만들 수 있으며, 그것들에 새로운 데이터베이스 객체들을 추가할 수 있습니다.

아래의 그림은 AutoCAD 데이터베이스의 핵심 구성요소를 표현한 것입니다.

          
 
 

AutoCAD 편집 세션동안 아래와 같은 전역 함수를 호출함으로써 현재 도면에 대한 데이터베이스를 얻을 수 있습니다.

        acdbHostApplicationServices()->workingDatabase()

단일 AutoCAD 세션에서 다중 데이터베이스가 로드될 수 있습니다. 세션에서 각각의 객체는 핸들과 객체 ID를 가집니다. 핸들은 특정 데이터베이스 범위내에서만 유일하게 식별할 수 있습니다. 이에 비해 객체 ID는 한 번에 로드된 모든 데이터베이스에서 유일하게 식별할 수 있습니다. 객체 ID는 편집 세션동안에만 영향을 받고, 핸들은 저장된 도면에서 얻습니다.

객체 ID를 가지고서 객체의 조작을 수행할 수 있도록 하기 위한 실제 데이터베이스 객체의 포인터를 얻을 수 있습니다. 아래와 같은 방법들로 객체 ID를 얻을 수 있습니다.

       객체를 생성하고 그것을 데이터베이스에 추가합니다. 그러면 데이터베이스에 객체 ID가 주어지고       그것을 리턴하게 됩니다.
       데이터베이스가 생성될 때 기호 테이블과 명명된 객체 딕셔너리의 고정된 세트와 같은 자동적으       로 생성되는 객체의 ID를 얻기 위해서는 데이터베이스 프로토콜을 사용합니다.
       객체 ID를 얻기 위해서는 클래스 특정 프로토콜을 사용합니다. 기호 테이블과 딕셔너리와 같은 어       떤 클래스는 다른 객체를 소유한 객체를 정의합니다. 이 클래스는 소유된 객체의 객체 ID를 얻기       위한 프로토콜을 제공합니다.
       객체의 목록 또는 세트에서 모든 객체를 얻기 위해서는 반복자를 사용합니다. AcDb 라이브러리는       컨테이너 객체의 여러가지 종류의 모든 객체(AcDbDictionaryIterator, AcDbObjectIterator)를 얻       기위해 사용될 수 있는 반복자를 제공합니다.
       선택 세트 질의를 사용합니다. 사용자가 객체를 선택한 후에 선택된 객체들의 엔티티 이름의 목록       에 대한 선택 세트를 요구할 수 있고, 이름으로부터 객체 ID를 변환합니다.


 























필수 데이터베이스 객체
 
 

AutoCAD에서 생성된 객체는 데이터베이스의 적절한 컨테이너 객체에 추가됩니다. 엔티티는 블록 테이블의 레코드에 추가됩니다. 기호 테이블 레코드는 적절한 기호 테이블에 추가됩니다. 다른 모든 객체는 명명된 객체 딕셔너리나 다른 객체에 의해 소유된 객체(결국은 명명된 객체 딕셔너리에 추가됨) 또는 확장 딕셔너리에 추가됩니다.

데이터베이스가 사용 가능하게 되려면 최소한 다음 객체 세트를 가지고 있어야 합니다.

       블록 테이블, 도면층 테이블 및 선종류 테이블을 포함하는 9 개의 기호 테이블 세트. 블록 테이블       은 초기에 *MODEL_SPACE라 불리우는 레코드와 *PAPER_SPACE와 *PAPER_SPACE0이라고       불리우는 두 개의 종이 공간 레코드의 3개 레코드를 가집니다. 이 블록 테이블 레코드는 모형 공간       과 미리 정의된 두 개의 종이 공간 배치도를 의미합니다. 도면층 테이블은 초기에 도면층 0이라는       하나의 레코드를 가집니다. 선종류 테이블은 초기에 CONTINUOUS 선종류를 가집니다.
       명명된 객체 딕셔너리. 명명된 객체 딕셔너리 데이터베이스가 생성될 때 그룹 딕셔너리, 다중선       유형 딕셔너리, 배치도 딕셔너리 및 플롯 유형 딕셔너리의 네 개 딕셔너리가 자동적으로 만들어집       니다. 다중선 유형 딕셔너리에는 STANDARD 유형이 항상 존재합니다.
 
 

이러한 객체들은 데이터베이스 생성자의 buildDefaultDrawing 파라미터 변수를 kTrue로 설정하여 새로운 데이터베이스에 자동적으로 생성할 수 있습니다. kFalse로 설정하면 로드될 수 있는 DWG 또는 DXF 파일내에 빈 데이터베이스가 생성됩니다.

        AcDbDatabase(Adesk::Boolean buildDefaultDrawing = Adesk::kTrue);


 







































AutoCAD에서 객체 생성하기
 
 

여기서는 AutoCAD에서 선, 원, 도면층 및 그룹을 생성하는 것을 설명하고 AutoCAD가 객체를 어떻게 데이터베이스에 저장하는지를 설명합니다. 먼저 다음 명령으로 모형공간에서 선을 작성합니다.

        line 4,2 10,7

AutoCAD는 데이터베이스에서 AcDbLine 클래스의 인스턴스를 생성하고 다음 그림에서 보는 바와 같이 모형공간 테이블 레코드 안에 그것을 저장합니다.

          
 
 

AutoCAD가 처음 시작되고 데이터베이스가 디폴트 상태일 때, 엔티티들은 모형의 기하학적 외형이나 그래픽들을 위해 사용되는 AutoCAD의 주 공간인 모형 공간에 추가됩니다. 종이 공간은 도면의 외곽선, 표제란, 주석문 같은 도형과 그래픽의 “문서화”를 지원하기 위해 고안되었습니다. AutoCAD에서 LINE의 경우 엔티티 생성 명령은 모형 공간 블럭뿐만 아니라 현재 데이터베이스에도 추가됩니다.

다음과 같은 명령으로 원을 생성한다고 가정합니다.

        circle 9,3 2

다시 AutoCAD는 여기서 적절한 엔티티의 인스턴스(AcDbCircle)를 생성하고, 그것을 모형공간 블록 테이블 레코드에 추가합니다.

          
 
 

다음과 같은 명령으로 도면층을 생성합니다.

        layer _make mylayer

AutoCAD는 도면층을 저장하기 위하여 새로운 도면층 테이블 레코드를 생성하고, 이것을 도면층 테이블에 추가합니다.

          
 
 

마지막으로 모든 엔티티들을 그룹으로 만듭니다.

        group 3,2 9,3

AutoCAD는 새로운 그룹 객체를 만들고 이것을 명명된 객체 딕셔너리에 들어있는 그룹 딕셔너리에 추가합니다. 새로운 그룹에는 그룹을 구성하고 있는 객체들의 객체 ID 목록이 들어있습니다.

          


 


 


ObjectARX에서 객체 생성하기


 












엔티티 만들기
 
 

아래의 ObjectARX 코드는 선을 생성하고 모형공간 블록 테이블에 이것을 추가합니다.

        AcDbObjectId
        createLine()
        {
            AcGePoint3d startPt(4.0, 2.0, 0.0);
            AcGePoint3d endPt(10.0, 7.0, 0.0);
            AcDbLine *pLine = new AcDbLine(startPt, endPt);
            AcDbBlockTable *pBlockTable;
            acdbHostApplicationServices()->workingDatabase()
                    ->getSymbolTable(pBlockTable, AcDb::kForRead);
            AcDbBlockTableRecord *pBlockTableRecord;
            pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
            pBlockTable->close();
            AcDbObjectId lineId;
            pBlockTableRecord->appendAcDbEntity(lineId, pLine);
            pBlockTableRecord->close();
            pLine->close();
            return lineId;
        }

createLine() 함수는 현재 도면에 대한 블록 테이블을 얻습니다. 그리고 모형공간 블록 테이블 레코드를 쓰기 모드로 엽니다. 블록 테이블을 닫은 후에 블록 테이블 레코드에 엔티티를 추가하고 블록 테이블 레코드와 엔티티를 닫습니다.

참 고 : 어떤 ObjectARX 객체를 사용하여 객체를 생성하면 반드시 객체를 명시적으로 닫아야만 합니다.

아래의 createCircle() 루틴은 원을 생성하고 모형공간 블록 테이블에 이것을 추가합니다.

        AcDbObjectId
        createCircle()
        {
            AcGePoint3d center(9.0, 3.0, 0.0);
            AcGeVector3d normal(0.0, 0.0, 1.0);
            AcDbCircle *pCirc = new AcDbCircle(center, normal, 2.0);
            AcDbBlockTable *pBlockTable;
            acdbHostApplicationServices()->workingDatabase()
                    ->getSymbolTable(pBlockTable, AcDb::kForRead);
            AcDbBlockTableRecord *pBlockTableRecord;
            pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
            pBlockTable->close();
            AcDbObjectId circleId;
            pBlockTableRecord->appendAcDbEntity(circleId, pCirc);
            pBlockTableRecord->close();
            pCirc->close();
            return circleId;
        }


 












새로운 도면층 만들기
 
 

다음 코드는 데이터베이스로부터 도면층 기호 테이블을 얻고, 새로운 도면층 테이블 레코드를 생성하며 도면층 이름을 ASDK_MYLAYER로 설정합니다. 도면층 테이블 레코드는 도면층 테이블에 추가됩니다.

        void
        createNewLayer()
        {
            AcDbLayerTable *pLayerTable;
            acdbHostApplicationServices()->workingDatabase()
                    ->getSymbolTable(pLayerTable, AcDb::kForWrite);
            AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord;
            pLayerTableRecord->setName(“ASDK_MYLAYER”);
            // 도면층 특성을 특별히 지정하지 않으면 디폴트 값으로 지정됩니다.
            pLayerTable->add(pLayerTableRecord);
            pLayerTable->close();
            pLayerTableRecord->close();
        }


 












ObjectARX 객체 열기 및 닫기
 
 

이곳의 모든 코드 예제는 데이터베이스에 상주하는 객체로 작업할 때마다 관찰이 필요한 객체를 열거나 닫는 프로토콜을 예를 들어 설명합니다. 이 프로토콜은 객체에 액세스할 필요가 있을 때 메모리안에 물리적으로 존재하는지를 확인할 수 있도록 합니다. 물론 더 이상 필요가 없을 때에는 메모리에서 제거될 수 있습니다. 객체를 수정하기 위해서는 다음과 같이 수정할 객체를 열어야만 합니다.

        acdbOpenObject(pObject, objId, AcDb::kForWrite);

열기 함수는 객체를 읽기, 쓰기 또는 통지 용도로 열것인지를 결정하는 모드 파라미터를 가지고 있습니다. 객체가 쓰기 모드로 열렸을 때 객체를 수정할 수 있습니다. 수정이 끝난 후에는 객체가 어떤 모드로 열렸는지와 관계없이 다음과 같이 명시적으로 객체를 닫아야만 합니다.

        pObject->close();

아래의 코드는 엔티티의 색상을 변경합니다.

        Acad::ErrorStatus
        changeColor(AcDbObjectId entId, Adesk::UInt16 newColor)
        {
            AcDbEntity *pEntity;
            acdbOpenObject(pEntity, entId, AcDb::kForWrite);
            pEntity->setColorIndex(newColor);
            pEntity->close();
            return Acad::eOk;
        }

위의 코드에서 객체의 새로운 인스턴스는 쓰기 모드로 열리도록 고려되었습니다. AcDbBlockTable::getAt() 함수와 같은 일부 함수는 객체 ID를 얻는 동시에 객체를 엽니다. 객체는 데이터베이스에 추가되기 전까지는 닫혀질 수 없습니다. 여러분이 객체를 소유하고 객체가 데이터베이스에 추가되기 전 아무때나 자유롭게 삭제할 수 있습니다.

그렇지만, 객체가 데이터베이스에 추가되면 직접 객체를 삭제할 수 없습니다. AcDbObject::erase() 함수를 호출할 수 있으며 객체는 삭제된 것으로 표시만 됩니다. 삭제 표시된 객체는 데이터베이스가 파괴되기 전까지는 데이터베이스에 그대로 남아있습니다. 단, 도면이 저장될 때 저장되지는 않습니다.

참 고 : 데이터베이스에 추가된 객체를 직접 삭제하는 것은 AutoCAD가 종료되는 원인이 될 수도 있습니            다.


 












GROUP 사전에 그룹 추가하기
 
 

아래의 코드는 createLine()createCircle() 함수에 의해 만들어진 선과 원의 그룹(pGroup)을 만들고, GROUP 사전에 이 그룹을 저장합니다. 선과 원의 객체 ID는 함수에 전달됩니다. GROUP 사전이 쓰기 모드로 열리는지와 수정한 후에는 명시적으로 닫아야 한다는 점에 주의하십시오.

        void
        createGroup(AcDbObjectIdArray& objIds, char* pGroupName)
        {
            AcDbGroup *pGroup = new AcDbGroup(pGroupName);
            for (int i = 0; i < objIds.length(); i++) {
                pGroup->append(objIds[i]);
            }
            // 명명된 객체 사전에 있는 그룹 사전에 그룹을 저장합니다.
            AcDbDictionary *pGroupDict;
            acdbHostApplicationServices()->workingDatabase()
                    ->getGroupDictionary(pGroupDict, AcDb::kForWrite);
            AcDbObjectId pGroupId;
            pGroupDict->setAt(pGroupName, pGroup, pGroupId);
            pGroupDict->close();
            pGroup->close();
        }


 


출처:> http://cadgroup.info



답글 남기기

이메일 주소는 공개되지 않습니다.