기본 콘텐츠로 건너뛰기

라벨이 MSTN J인 게시물 표시

MSTN VBA - Lession7(폴더 선택하기)

폴더를 선택하는 예제입니다. Dim MyBl As BrowseInfo Dim FList As Long Dim DirName As String Dim SelFolder As String DirName = Space(255) MyBl.sTitle = "Select Root Folder" MyBl.sDisplayName = Space(255) MyBl.ulFlags = Bif_ReturnOnlyFSDirs FList = SHBrowseForFolder(MyBl) SelFolder = SHGetPathFromIDList(FList, DirName) DirName = Left(DirName, InStr(1, DirName, Chr(0)) - 1) If DirName <> "" Then TextBoxFolder.Text = DirName Else TextBoxFolder.Text = "" End If

요소의 잘못된 Range 수정하기

특정 요소의 Range가 잘못된 경우가 발생할 수 있습니다. 특히 3rd party 프로그램에서 생성된 파일일 경우.. 이때 Range를 수정하는 명령이 있습니다. mdl load fixrange filedesign 특정 폴더 안의 도면에 대해서 위 명령을 수행하는 매크로를 만들어 보겠습니다. Sub main() Dim S$ Dim One_File_List as String MbeSendCommand "mdl load fixrange" One_File_List = Dir$("C:\Temp" + "\*.*") Do While One_File_List <> "" MbeSendCommand "newfile " + One_File_List$ MbeSendCommand "filedesign" One_File_List = Dir$ Loop Close 'up to here End Sub

graphic element들의 색상(gray color) 변경

색상을 변경하는 예제입니다. ULong elemAddr[50], eofPos, filePos; int scanWords, numChanged=0, status, i, numAddr; Scanlist scanList; int grayColor = 32; MSElementUnion el; mdlScan_initScanlist (&scanList); mdlScan_noRangeCheck (&scanList); scanList.extendedType = FILEPOS; mdlScan_initialize (0, &scanList); do { scanWords = sizeof(elemAddr)/sizeof(short); status = mdlScan_file (elemAddr, &scanWords, sizeof(elemAddr), &filePos); numAddr = scanWords / sizeof(short); for (i=0; i<numAddr; i++) { mdlElement_read(&el, 0, elemAddr[i] ); mdlElement_setSymbology(&el , &grayColor , NULL , NULL); mdlElement_rewrite(&el , NULL , elemAddr[i]); } } while (status == BUFF_FULL);

Dimension 환경 설정하기

고객사로부터 아래와 같이 Dimension을 표기해 달라는 요청이 들어왔습니다. Dimension을 Dual로 표기해 달라는 것인데, 상단에는 ft-inch로 하단에는 metric으로 표기해 달라는 것이었습니다. 이렇게 표기 가능하도록 MSTN J7의 Dimension 환경 설정을 해보도록 하겠습니다. [Dimension Settings --> Units] Format을 AEC로 선택합니다. Primary Dimension 설정: -> Units을 Feet로 설정합니다. Secondary Dimension 설정: -> Show Secondary Units를 체크합니다. 이렇게 해야만 하단에 Dimension이 표기가 됩니다. -> Units을 Millimeters로 설정합니다. -> Label : 하단에 표기될 단위를 입력합니다. 입력하지 않으면 MM로 표기됩니다. 이렇게 설정하고 나서도 상단의 Dimension 단위 표기가 우리가 원하던 것과 다를 수 있습니다. 상단의 Dimension 단위 설정은 "Setting-->Design File-->Working Units"에서 하실 수 있습니다. Unit Names의 Master Units,Sub Units에서 원하는 단위를 입력하면 됩니다. 이렇게 하면 거의 원하는 Dimension 형식대로 표기할 수 있습니다. 마지막으로 하단의 Dimension을 감싸는 []표기 입니다. 이것을 Dimension Prefix,Suffix라고 하는데 이것은 "Dimension Settings-->Custom Symbols"에서 설정할 수 있습니다. 이렇게 해서 원하는 형식대로 Dimension을 표기할 수 있습니다. 주의) 결과 이미지를 보시면 하단의 Dimension Text가 []사이의 가운데에...

SWEEP SURFACE V7 / MSTN/MDL/VBA

중국에서 Back Drawing을 만들때 Elbow 형상이 빠져서 나오지 않는다고 메일이 왔습니다. 대부분의 Elbow 형상은 회전 Surface(Surface of revolution)이었기 때문에 회전 Surface만을 처리해 왔었는데, 모델을 받아 보니 회전 Surface가 아니라 Sweep Surface였습니다. 이런 식으로도 Elbow 모델링을 하는구나 싶었습니다. 그런데 왜 이런 식으로 하는지 자세한 이유는 모르겠습니다. Ellipse두개를 Line 4개로 연결한 형상(SWEEP SURFACE)

Element 기준으로 View를 Fit하기

아래 예제 코드를 참고 하시기 바랍니다. ret = mdlElement_read (&mseFeat, MASTERFILE, filePosP); if (SUCCESS == ret) { if (SUCCESS == mdlElement_extractRange (&dvVec, &mseFeat)) { memset (&options, 0, sizeof (FitViewOptions)); if (SUCCESS == mdlView_fitViewToRange (&dvVec.org, &dvVec.end, &options, 0)) {

V7 Compiler Error

오늘 아주 흥미로운 현상을 발견했습니다. 소스의 맨 첫째 줄에 주석을 넣으니 V7 컴파일러가 에러를 뱉어 내었습니다. 아래와 같이 첫번째 줄에 주석을 넣으니 말이죠... #include <mdl.h> // comment in first line #include <cexpr.h> #include <rscdefs.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <cmdlist.h> #include <dlogitem.h> #include <system.h> #include <global.h> #include <userfnc.h> #include <mselems.h> #include <refernce.h> #include <tcb.h> #include <scanner.h> #include <mdldim.h> #include <dlogman.fdf> #include <msdim.fdf> #include <mdlerrs.h> #include <clipdscr.h> #include <msfile.fdf>

mdlLinkage_appendUsingDescr 오류

mdlLinkage_appendUsingDescr 호출 실패 때문에 미치겠습니다. 다른 프로젝트와 똑 같이 했는데 왜 실패하는지? mdlCell_create(&groupCell, pToken1->buf[2], NULL, FALSE); mdlElmdscr_new(&chainDscrP,NULL,&groupCell); addUserData(&chainDscrP , filePos); //! mdlLinkage_appendUsingDescr 호출 filePos = mdlElmdscr_add(chainDscrP); Private int addUserData( MSElementDescr **elP , ULong filePos ) { int status; char cMsg[100]; char linkString[MAXFILELENGTH]; LinkageHeader linkHdr; memset(&linkHdr, '\0' , sizeof(LinkageHeader)); linkHdr.info =0; linkHdr.remote =0; linkHdr.modified =0; linkHdr.user =1; linkHdr.class =0; linkHdr.words; linkHdr.primaryID = 901; memset(&linkInfo , '\0' , sizeof(LinkInfo)); strcpy(linkInfo.tag_Name1 , "hello"); status = mdlLinkage_appendUsingDescr( elP, &linkHdr, &linkInfo, RSCID_DataDef_Link, NULL, FALSE); if (status == ...

Radio Button 동기화

이번에 라디오 버튼 동기화에 대해서 알아보도록 하겠습니다. 아래 그림과 같이 두 개의 라디오 버튼을 생성한 후에 라디오 버튼을 그룹으로 묶어 준다면 List Id를 동일하게 주어야 합니다. 그리고 각각 그 값들을 0에서 부터 설정해 주면 됩니다. 두 개의 라디오 버튼의 List Id는 동일하게 설정했구요, Value는 다르게 설정했습니다. 아래의 Arg 값이 뭘 의미하는지는 잘 모르겠어요^^

Dgn writer for MSTN J

간단한 dgn writer module 을 공개합니다. 첨부한 pdf 파일 형식으로 작성한 텍스트 파일을 읽어 들여 dgn 파일에 쓰는 모듈입니다. 간단한 MSTN element 정도는 지원하고요 property들도 지정이 가능합니다. 예제 텍스트 파일 을 첨부합니다. 관심있으신 분들은 한번 사용해 보시고요 버그나 추가 하고픈 element가 있으면 연락주세요. 사용법은 아래 이미지를 보시면 알수가 있습니다.

Create DONUT like AutoCAD's donut

AutoCAD에서의 Donut과 유사하게 MSTN J에서 Donut을 만드는 함수입니다. 함수 분석은 그리 어렵지 않구요. 간단히 설명하자면 두개의 Ellipse를 생성한 다음에 큰 Ellipse에서 작은 Ellipse을 뺀 나머지 부분을 생성한 후 저장하면 됩니다. //! get difference pattern between two patterns mdlElmdscr_differenceShapes(&patternEdPP, NULL, OutpatternEdPP, InpatternEdPP , 0); 자 그럼 코드를 볼까요... /** @brief create donut @author HumKyung.Baek @date ????.??.?? @return boolean */ Private boolean Draw_Donut(floatfInsideDia, floatfOutsideDia, Dpoint3d *ptCenter, intnColor, intnLayer) { MSElementUnion newElement, newInElement, newOutElement; inti, stat; intnFillmode = 1; intnWeight, nStyle; MSElementDescr *OutpatternEdPP = NULL, *InpatternEdPP = NULL, *patternEdPP = NULL; doubleunitVal = tcb->uorpersub; ptCenter->x = ptCenter->x * unitVal; ptCenter->y = ptCenter->y * unitVal; ptCenter->z = ptCenter->z * unitVal; stat = mdlEllipse_create(&newOutElement, NULL, ptCenter, fOutsideDia*unitVal, fOutsideDia*unitVal, NULL, nFillmode); ...

Fill이 보이지 않을때

분명히 Shape같은 element를 Fill했는데 화면에 보이지 않을 경우에 View Attribute를 살펴보세요

which one we should select as model reference origin while converting 3D to 2D

제목을 쓰다 보니 길어졌는데요, 간단히 말하자면 3D에서 2D로 변환시킬 때 3D의 기준 좌표로 어디를 선택하느냐는 것입니다. 지금 수행중인 도면 자동화 프로그램에서(PDS용) ISO 뷰에 대한 도면 작업을 하는 부분이 있습니다. 그래서 일반 뷰(TOP,BOTTOM,LEFT,RIGHT,FRONT,BACK)에서 처럼 3D 좌표를 2D로 좌표로 변환시키는 작업을 했습니다. 그런데 원하는 결과가 나타나지 않고 그 위치가 조금 어긋나 있는 것이었습니다. 반나절을 헤멘 결과 그 원인을 찾았는데, View Reference 좌표는 PDS Hidden Drawing에서 얻었고, Model Reference 는 좌표는 PDS Database에서 뷰의 모델 min,max에서 center를 구해서 model reference로 삼았습니다. 결과적으로 model reference에서 문제가 발생했습니다. 사실 PDS Hidden Drawing에도 reference origin이라는 항목이 있는데 이 값이 일반 뷰에서는 PDS Database에서 계산한 값과 일치했습니다. 그런데 ISO 뷰에서는 그 값이 일치하지 않더군요. 결론적으로 model reference 좌표는 PDS Hidden Drawing에서 구하는게 맞습니다.

extract cell name from cell library

#include #include #include #include "w2Dgn.h" #include #include externvoidloadCellLibraryIfNeeded(char*libToLoad); /*----------------------------------------------------------------------+ | | | name GetCellNameFromCellLib | | | | author HumKyung.Baek | | | +----------------------------------------------------------------------*/ Public intGetCellNameFromCellLib(char* pOutputTextFilePath , char* pstrCellLib) { ULong elemAddr[250], eofPos, filePos, actualPos, readPos; intscanWords, status, i,j=0, numAddr, fileNum=CELL_LIB, offset; charcellName[10], cellDescription[30], msg[132]; Scanlist scanList; MSElement cellElm; /*cell element descriptor */ FILE* fp = NULL; if(fp = mdlTextFile_open(pOutputTextFilePath , TEXTFILE_WRITE)) { loadCellLibraryIfNeeded(pstrCellLib); mdlScan_initScanlist (&scanList); mdlScan_noRangeCheck (&scanList); scanList.scantype = ELEMTYPE | NESTCELL; ...

microstation J view direction

아래 이미지를 참조하세요. 그림에 제가 번호를 매겨 놓았습니다.

memory allocation의 비용

메모리 할당/해제에 당연히 어느 정도의 비용이 든다고는 알고 있었지만, V7에서의 눈에 띄는 성능 저하는 메모리 할당/해제의 문제라 생각하지 못할 정도였다. 몇 백개의 line,text들을 생성하는데 생성하는 것을 눈으로 확인할수 있을 정도로 속도가 느렸습니다. 메모리 할당/해제 대신에 배열을 사용하니, 정말 눈깜짝할 정도의 시간에 모든 line,text의 생성이 완료가 되었습니다. 아마도 mdl compiler의 메모리 할당/해제에 문제가 있는게 아닌가 합니다.

mdlText_createWide 함수

mdlText_create대신 mdlText_createWide를 사용하는 가장 큰 이유는 텍스트의 기울기를 줄수 있기 때문이다. int mdlText_createWide ( MSElementUnion *out, /* template element */ MSWideChar *wString, /* => wide character string */ Dpoint3d *userOrigin, /* => origin (or NULL) */ RotMatrix *rMatrix, /* => rotation matrix (or NULL) */ TextSizeParam *textSize, /* => size (or NULL) */ TextParamWide *txtParamWide, /* => parameters (or NULL) */ TextEDParam *edParam /* => enter data info (or NULL) */ ); mbstowcs 함수를 통하여 char*를 MSWideChar*로 변환시킬 수 있습니다. 여기서 한가지 주의해야 할 것은 txtParamWide의 flag들의 속성을 제대로 설정해주어야 한다는 것이다. 예를 들어 txtParamWide.flags.vertical을 FALSE로 하지 않으면 텍스트들이 Vertical 방향으로 쓰여지게 된다. txtParamWide.flags.vertical을 FALSE로 두고 텍스트의 회전은 rMatrix에서 설정을 하면 된다. 이번 프로젝트에서 이 문제로 인해 며칠동안 고민을 했었습니다.

Microstation J와 file size 32MB

Microstation J까지의 버전에서 DGN file이 32MB가 넘어가면 문제가 발생한다고 합니다. 주의하세요!!! mdlSystem_compressDgnFile 함수를 호출하면 Undo같은 기능을 위해 저장하고 있는 내용을 지워 파일 크기를 줄일 수가 있습니다. J가 워낙 오래된 프로그램이라 파일 크기 제한은 현재 상황과 맞지 않습니다. PDS 사용자들은 어쩔수 없이 사용할수 밖에 없구요.

Element Descriptors

이 부분은 본래 MDL Programming하기 전에 반드시 알아야만 하는 부분입니다.(뒷늦게 올리게 되었네요) 프로그래밍에서 주로 하는 일은 Element들을 다루는 일일 것입니다. 따라서 이 Element들이 어떻게 저장되어 있는지를 꼭 알아야만 합니다. (ARX를 시작하기 전에 AutoCAD Element들이 어떻게 저장되어 있는지 알아야만 하는 것 처럼..) 아래는 msElementDescr구조체의 구조와 샘플 이미지 입니다. structmsElementDescr /* defined in mselems.h*/ { struct { structMSElementDescr*next; /* ptrto first entry in list */ structMSElementDescr*previous; /* ptrto last entry in list */ structMSElementDescr*myHeader; /* ptrto my hdr*/ structMSElementDescr*firstElem; /* ptrto first elemif header*/ DgnModelRefP *dgnModelRef; /* valid only if from cache */ ElementRef *elementRef; /* valid only if from cache */ Int32 isHeader; /* is this a complex header */ Int32 isValid; /* INTERNAL USE ONLY */ Int32 userData1; /* available for user */ Int32 ...