기본 콘텐츠로 건너뛰기

2010의 게시물 표시

선분과 직선과의 거리

선분(S-E)와 점 P와의 거리를 구해보도록 합시다. 우선 두개의 벡터를 구할수 있습니다. $$ \begin{aligned} V_1 &= \overrightarrow{P-S} \\ V_2 &= \overrightarrow{E-S} \\ \vec{V_1}\cdot\vec{V_2} &= |\vec{V_2}||\vec{V_1}|cos(\theta) =|\vec{V_2}||\vec{V_2}|U \\ U &= \frac{\vec{V_1}\cdot\vec{V_2}}{|\vec{V_2}||\vec{V_2}|} \end{aligned} $$ 위 식을 통해서 U값을 구할수 있습니다. 일단 U를 구했으면, U를 통하여 $V_2$와 수직을 이루는 벡터 $\overrightarrow{P-C}$의 C 값을 구할 수 있습니다. $$ C = S + U*\overrightarrow{E-S} $$ 마지막으로 C를 구했으니 $C-P$간의 거리가 선분과 점의 거리가 됩니다. double CIsLine2d::DistanceTo(const CIsPoint2d &pt) const { const double mag = Length(); if(0.f != mag) { double u = ((pt.x() - m_start.x())*(m_end.x() - m_start.x()) + (pt.y() - m_start.y())*(m_end.y() - m_start.y())) / (mag*mag); double xp= m_start.x() + u*(m_end.x() - m_start.x()); double yp= m_start.y() + u*(m_end.y() - m_start.y()); const double dx = xp - pt.x(); const double dy = yp - pt.y(); return sqr

How to pick object?

앞에서는 영역을 잡아서 object를 선택하는 것에 대해서 알아 봤는데, 이번에는 click하여 object를 선택하는 것에 대해서 알아보겠습니다. 아래와 같이 Select함수를 사용하게 되는데요 1 Standard_EXPORT AIS_StatusOfPick Select( const  Standard_Boolean updateviewer  =  Standard_True) ; cs 인자로 click한 좌표를 넘겨주지 않습니다. 그럼 어떻게 object를 선택할까요?(좌표없이 말이죠...) 이 함수는 highlight된 object를 선택하는 함수입니다. 따라서 이 Select 함수를 호출하기 전에 선택할 object가 highlight되어있어야 합니다. highlight는 마우스가 움직일때 MoveTo 함수를 통해서 쉽게 할수가 있습니다. 그림을 보시면 마우스 커서 밑의 원이 highlight된것을 볼수가 있습니다. 형상들을 선택한 후 color dialog에서 변경할 색상을 선택한 후에 선택한 형상의 색상을 변경합니다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 Quantity_Color CSFColor ; COLORREF MSColor ;        m_hAISContext - > Select(); m_hAISContext - > InitSelected(); if  (m_hAISContext - > MoreSelected()) {     m_hAISContext - > InitCurrent();     Handle_AIS_InteractiveObject Current  =  m_hAISContext - > Current() ;      if  ( Current - > HasColor () )     {        CSFC

선택한 형상의 색상 변경하기

영역으로 형상을 선택하고 선택한 형상의 색상을 변경하는 방법을 알아보도록 하겠습니다. 간단히 그림과 코드로 살펴보겠습니다. 형상들을 선택한 후 color dialog에서 변경할 색상을 선택한 후에 선택한 형상의 색상을 변경합니다. void CLibMesh2dTestCaseDoc :: InputEvent ( const Standard_Integer cXmin , const Standard_Integer cYmin , const Standard_Integer cXmax , const Standard_Integer cYmax , const Handle ( V3d_View ) & aView ) { Quantity_Color CSFColor ; COLORREF MSColor ; m_hAISContext - > Select ( cXmin , cYmin , cXmax , cYmax , aView ) ; m_hAISContext - > InitSelected ( ) ; if ( m_hAISContext - > MoreSelected ( ) ) { m_hAISContext - > InitCurrent ( ) ; Handle_AIS_InteractiveObject Current = m_hAISContext - > Current ( ) ; if ( Current - > HasColor ( ) ) { CSFColor = m_hAISContext - > Color ( Current ) ; MSColor = RGB ( CSFColor . Red ( ) * 255 . , CSFColor . Green ( ) * 255 . , CSFColor . Blue ( ) * 255 . ) ; } else { MSColor

Radio Button 동기화

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

Colorbar 표현하기

일반적으로 contour를 표현하는 프로그램을 보면 오른쪽 상단에 레벨별로 색상을 표현한 colorbar를 볼수가 있습니다. 이를 한번 구현해 보았습니다. 일단 Layer를 하나 만들고 그 위에 colorbar를 표기하도록 하였습니다. 신경쓰였던 부분은 윈도우의 크기가 변경될때 어떻게 colorbar의 크기를 일정하게 유지하는냐 하는 것이었습니다. 이렇게 해서 제가 원하는 colorbar를 표현하는데 성공했습니다.!!! 코드는 아래에... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 glPushAttrib (GL_LIST_BIT);  charbuf[ 20 ]  =  { '\0' ,};  Quantity_Color color( 1. 0 ,  1. 0 ,  0. 0 , Quantity_TOC_RGB);  aToppestLayer - > SetColor(color);    //! pixel 단위의 colorbar의 min,max를 구한다. double  minx  =  right  -  (right  -  left) * 70 / w;  double  maxx  =  right  -  (right  -  left) * 50 / w;  double  maxy  =  top  -  (top  -  bottom) * 20 / h;  double  miny  =  top  -  (top  -  bottom) * 300 / h;    const  doubledStep  =  (maxy  -  miny)  /   7. 0 ;  for (inti  =   0 ;i  <   7 ; + + i)  {      glBegin( GL_QUADS );      glNormal3f(  0. f,  0. f,  1. f);      glColor3f(          ( float )(( 255 -  i *

Gradient Background 표현하기

OpenCASCADE 6.5.0이상에서는 단 한줄의 코드로 Gradient Background color를 설정할 수 있습니다. 관련 링크 --------------------------------------------------------------------------------- 원문은 아래에서 확인하실 수 있습니다. http://sondra.egloos.com/5446008 MFC를 사용한다면 OnSize Mehtod에 원문의 코드를 넣으면 됩니다. 원문에 있는 코드를 사용해보니 윈도우의 크기가 변경될 때마다 gradient 색상이 조금씩 차이가 나는걸 발견하였습니다. 그 이유를 수소문해보니(?) 윈도우의 크기에 따라 opengl의 직교 좌표계의 범위를 OCC가 계산하여 설정하는 것을 알았습니다. 즉 우리가 layer에서 SetOrtho 함수를 사용하여 좌표계의 범위를 주어도 OCC에서 그댈 사용하지 않고 다시 계산하여 최종적으로 그 값을 사용하는 것입니다. 다행히 OCC에서 소스를 제공하니 소스에서 좌표계를 계산하는 루틴을 알수가 있습니다. 그 값을 적용하여 gradient를 그려주면 윈도우의 크기가 변경될때 마다 색상 차이가 나는 것을 방지할 수 있습니다.  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 if (aBackgroundLayer.IsNull())  {      Standard_Boolean aSizeDependant  =  Standard_True;  //each window to have particular mapped layer?     aBackgroundLayer  =  newVisual3d_Layer(m_hView - > Viewer() - > Viewer(),      Aspect_TOL_UNDERLAY, aSi

주요 배치파일 작성 명령어

dusttin's Notes | dusttin http://dusttin.blog.me/10715315 배치파일 작성 명령어 9인방 배 치 파일은 파일 안에 기록되어 있는 명령의 순서대로 실행됩니다.가장 대표적인 것이 부팅에 이용되며, 컴퓨터의 루트 디렉토리에 위치하고 있는 Autoexec.bat 파일입니다. 그런데 만약 배치 파일의 실행의 순서를 순차적이 아닌멀티부팅용 Autoexec.bat 처럼 사용자 마음대로 정하고 싶다면 배치파일에 제공되는배치명령어의 용도를 알고 있어야 합니다. 1. CALL 현재 실행중인 배치 파일을 종료하지 않고 필요한 다른 배치파일을 호출하여 실행한 다음 원래의 배치파일로 다시 돌아오려고 할 때 사용됩니다. ◇ 사용법 : Call [drive:]\[경로]\<배치파일명>[.BAT] ◇ 예 : Call c:\bats\sample.bat 어떤 배치 파일을 실행하는 도중에 경로 C:\bats 에 있는 sample.bat 파일을 실행한 다음 다시 원래의 배치파일로 돌아옵니다. 2. CHOICE 배치 프로그램 내에서 사용자의 선택을 묻기 위해 사용됩니다. 배치 파일 제작자가 설정한 물음을 출력하면서 지정된 키 입력을 기다립니다. 이 명령은 배치파일 내에서만 사용 가능합니다. ◇ 사용법 :choice [/C[:]문자열][/N][/S][/T[:]기본키,대기시간][메세지] ◇ 옵션 - /C[:]문자열 : 사용자가 선택할 수 있는 키목록을 [] 괄호 내에 ', ' 로 구분하여 출력하고 /C 스위치를 사용하지 않으면 기본적으로 YN이 사용됩니다. - /N : 프롬프트를 출력하지 않도록 합니다. - /S : 사용자의 입력에서 소문자, 대문자를 구분하도록 합니다. - /T[:]기

3D 평면 상의 점들을 2D로 변환

3D 평면상의 점들을 2D로 변환하는 방법에 대해서 알아보도록 하자. 지금 개발하고 있는 2D상의 점들을 삼각화 시키는 루틴이 있는데 이 루틴을 3D 평면상의 점들에 대해서 적용시키기 위해서 3D 평면상의 점들을 2D로 변환시키는 방법이 필요하다. 고찰 1) 3D 평면을 X-Y 평면으로 맞추는 것이다. 3D 평면의 법선 벡터(n)를 Z축과 일치시키기 위해서 X,Y 축 방향으로 회전시키는 방법이다. 이 방법에 대해서는 이전 글 을 참조 하면 될것 같다. 고찰 2) 이 글에서 주로 생각해 볼것은 실제로 평면을 회전시키지 않고 2D 상으로 변환시키는 방법이다. 앞서 이야기 했듯이 이미 평면의 법선 벡터(n)를 알고 있으므로, 평면상의 임의의 점(P)을 하나 선택하고 그리고 다른 또 하나의 점을 선택한다. 그럼 하나의 벡터(u)를 구할 수 있고 이 벡터와 평면의 법선 벡터와의 외적을 통해 구한 벡터와 평면상에서 수직인 또 다른 벡터(v)를 구할 수 있다. 여기서 구한 평면상의 두 벡터(u,v)를 축으로 하여 평면상의 모든 점들을 u,v축에 대한 값으로 표현할 수 있다. 이렇게 해서 $t_2$의 값을 구할 수 있고, 마찬가지로 $t_1$의 값을 구할 수 있다. 결론적으로 모든 점들에 대하여 u,v 축에 대한 값을 구할수 있으므로 2D로 변환한 것이 된다. 고찰 2)가 고찰 1)보다 나은 점은 고찰 1)에서는 실제적으로 몇 단계의 계산을 거쳐 2D 상의 점으로 변환시킨다는 것이다. 이때 아무래도 시간과 floating point연산으로 인한 데이터 변형이 일어날수 있다는 것이다. 이에 비해 고찰 2)는 변화 루틴이 간단하다.

entity 색상 설정하기

gp_Circ gpCircle ; gpCircle . SetLocation ( center ) ; gpCircle . SetRadius ( dRadius ) ; Handle ( Geom_Circle ) aCircle = :: new Geom_Circle ( gpCircle ) ; Handle ( AIS_Circle ) hCircle = :: new AIS_Circle ( aCircle ) ; //! set red color7 Quantity_Color color(1.0, 0.0, 0.0, Quantity_TOC_RGB); m_pAISContext - > SetColor ( hCircle , color ) ; m_pAISContext - > Display ( hCircle , true ) ; 2011.08.25; m_pAISContext->Display 함수를 호출하면 화면이 바로 갱신되는 문제(?)가 있습니다. 이 문제를 피하고 싶으면 AIS 객체의 색상의 설정해 주면 됩니다. Handle ( AIS_Circle ) hCircle = :: new AIS_Circle ( aCircle ) ; Quantity_Color aColor ( 1.0 , 0.0 , 0.0 , Quantity_TOC_RGB ) ; hCircle - > SetColor ( aColor ) ;

Circle 그리기

gp_Circ gpCircle ; gpCircle . SetLocation ( center ) ; gpCircle . SetRadius ( dRadius ) ; Handle ( Geom_Circle ) aCircle = new Geom_Circle ( gpCircle ) ; Handle ( AIS_Circle ) hCircle = new AIS_Circle ( aCircle ) ; m_pAISContext - > Display ( hCircle , true ) ; Handle(Geom_Circle) aCircle = new Geom_Circle(gpCircle); 로 생성했는데 이를 해제하지 않아서 영~~ 찝찝하네요... 2011.08.25; 메모리 관리는 OCC에서 하는 것으로 보입니다.

Constants

4.2.3 Constants Constants can also be used in the InstallDirattribute. Note that some of the new constants will not work on every OS. For example, \$CDBURN_AREA will only work on Windows XP and above. If it's used on Windows 98, it'll be empty. Unless mentioned otherwise, a constant should be available on every OS. \$PROGRAMFILES , \$PROGRAMFILES32 , \$PROGRAMFILES64 The program files directory (usually C:\Program Filesbut detected at runtime). On Windows x64, \$PROGRAMFILES and \$PROGRAMFILES32 point to C:\Program Files (x86) while \$PROGRAMFILES64 points to C:\Program Files. Use \$PROGRAMFILES64 when installing x64 applications. \$COMMONFILES, \$COMMONFILES32, \$COMMONFILES64 The common files directory. This is a directory for components that are shared across applications (usually C:\Program Files\Common Filesbut detected at runtime). On Windows x64, \$COMMONFILES and \$COMMONFILES32 point to C:\Program Files (x86)\Common Files while \$COMMONFILES64 points t

UserType.dat 사용하기

OpenCasCade 배포판에서 UserType.dat 파일도 함께 배포하고 있습니다. (배포판 설치 폴더의 Tools 폴더 안에 보면 UserType.dat 파일이 있습니다.) 다들 아시다시피 이것을 사용하면 사용자 정의 Type도 highlighting할수 있습니다. 이 UserType.dat 파일을 예를 들면 C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE 폴더에 복사해 두면 OCC관련 Type들이 highlighting됩니다. 1 2 3 4 5 6 7 8 9 10 void  C3DWnd::DisplayAxis() {     CLibMesh2dTestCaseView *  pView  =  (CLibMesh2dTestCaseView * )GetParent();     CLibMesh2dTestCaseDoc *  pDoc  =  (CLibMesh2dTestCaseDoc * )pView - > GetDocument();       Handle(AIS_Trihedron) aTrihedron;     Handle(Geom_Axis2Placement) anAxis  =   new  Geom_Axis2Placement(gp::XOY());     aTrihedron  =   new  AIS_Trihedron(anAxis);     pDoc - > m_pAISContext - > Display(aTrihedron); } Colored by Color Scripter cs

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에서 구하는게 맞습니다.

DLL calling convention

오늘 조금 희한한 경우를 발견했습니다. 다름이 아니라 VC++ 아래와 같이 정의한 함수를 1 2 3 4 5 extern   "C"  DLL_EXPORT void  DGN2NSQ( const   char *  pExportFilePath, const   char *  pImportFilePath ,  const   char *  pIniFilePath ) { ... 생략 } Colored by Color Scripter cs VB에서 아래와 같이 선언한 뒤 VB CODE를 컴파일해도 아무런 에러를 발생시키지 않고 컴파일이 성공되었습니다. 매개 변수 하나를 선언하지 않았는데도 말이죠. 1 2 Declare  Sub  DGN2NSQ Lib  "IEManager.dll"  _ ( ByVal  ExportFilePath  As   String ,  ByVal  ImportFilePath  As   String ) cs VC++의 함수에서 디버깅을 해보면 제일 마지막의 값은 쓰레기 값이 넘어오는 것을 확인할 수 있었습니다. DLL함수 호출 규약을 __stdcall으로 바꾸어 테스트를 한번 해 보아야 겠습니다. - 결론 : VB는 똑똑하게(?) 인자 갯수를 다르게 선언하고 또 사용하고 해도 컴파일때 에러를 내지 않습니다. 뭐 이런게 다 있을까요?

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;