반응형

데이터는 없는데 유튜브로 음악은 듣고 싶다면?

데이터는 없는데 봐야 할 영상이 수두룩 하다면?

바로 다운로드 받아서 보는 방법이 있죠. 인터넷에 보면 유튜브 주소를 넣으면 음원 파일이나 영상 파일로 다운로드 해주는 사이트 들이 많이 있습니다. 지저분한 광고로 도배가 되어 있는가 하면 정말 답답하게 느리기도 하고요. 뭔가 상당히 찜찜함을 남기는 UI 나 뭐 거시기 합니다.

그래서 광고 없고, 빠르고, 무료인 깔끔한 프로그램을 직접 만들어 보았습니다.

MUSIC DOWNTOWN

드디어 나왔다 뮤직 다운타운

네 이름 그대로 뮤직 다운타운 입니다. 

설치할 필요 없고요. 압축 풀고 실행파일 (musicdowntown.exe) 실행하시면 됩니다.

압축 파일을 열어 보시면 아래와 같이 3개의 실행 파일이 있을텐데요. 

yt-dlp 는 유튜브영상이나 음악을 다운로드 해주는 정말 놀라운 프로그램이고요, ffmpeg 는 아시는 분은 아시겠지만 영상, 음악 분야의 신의 손 정도로 부를 수 있는 대단한 프로그램 입니다. 물론 둘다 command line 으로 사용해야 하는 프로그램이다 보니 약간 일반 사용자들에게 익숙한 프로그램은 아니죠. 

대충 감 잡으셨을지도 모르겠지만 musicdowntown 은 사실 저 두개의 프로그램을 조금더 사용하기 편리하게 만들어주기 위하여 적당한 명령을 날려주는 역할을 하는 HMI(Human Machine Interface) 정도로 보시면 되겠습니다.

yt-dlp 와 ffmpeg 프로그램을 직접 사용하시기 위한 사용법이나 자세한 내용이 궁금하시면 아래 사이트를 방문해 주세요

https://github.com/yt-dlp/yt-dlp

 

GitHub - yt-dlp/yt-dlp: A youtube-dl fork with additional features and fixes

A youtube-dl fork with additional features and fixes - GitHub - yt-dlp/yt-dlp: A youtube-dl fork with additional features and fixes

github.com

https://ffmpeg.org/

 

FFmpeg

Converting video and audio has never been so easy. $ ffmpeg -i input.mp4 output.avi     News May 31st, 2023, Vulkan decoding A few days ago, Vulkan-powered decoding hardware acceleration code was merged into the codebase. This is the first vendor-generic

ffmpeg.org

 

자 이제 제가 만든 프로그램 설명을 좀 드리겠습니다. 사용법이랑 뭐 그런거요.

참고로 동작은 PC 에서만 가능하며 window10 에서 테스트 하였습니다.

 

주요 기능

  1. 음원 파일 하나 다운로드
  2. 음원 플레이 리스트 다운로드
  3. 여러개로 뭉쳐진 하나의 음원 다운로드 후 자동으로 자르기!
  4. 비디오 파일 다운로드
  5. 비디오 파일 플레이 리스트 다운로드

와우! 놀랍지 않습니까? 여러개의 음악을 하나로 묶어둔 음원 자르는것도 자동으로 됩니다. 마음에 드는 플레이 리스트가 있다면 한번에 모두 다운로드 받으세요.

 

사용방법

먼저 유튜브 주소를 복사합니다. 주소 표시줄의 주소를 그냥 복사 하시면 됩니다. 현재 보고 있는 영상의 주소가 플레이 리스트인데 재생중인 영상만 다운로드 받고 싶다면 영상 아래쪽에 공유 버튼을 이용해서 주소를 복사해도 됩니다. 

복사한 주소를 youtube 옆에 있는 칸에 붙여 넣습니다.
그리고 아래 그림처럼 아래 줄에 음원이나 영상이 저장될 PC 의 경로를 넣어 주세요.

주의사항!

저장될 경로에 한글이 있거나 공백이 있으면 저장이 잘 되지 않습니다. 가능하면 공백 없는 영문으로만 이루어진 경로를 이용해 주세요.

임의로 없는 경로를 넣으면 please write exist save path 라고 스마트하게 알려줌!

자 download 버튼을 누르셨가면 이제 다운로드 되기 시작할텐데요

다운로드 중

처음에는 요렇게 2개의 파일이 생성되는데요. 다운로드가 완료되면 아래와 같이 하나만 남게 됩니다.

다운로드 완료!

 

영상으로 받고 싶으시면 MUSIC 버튼을 누르시면 VIDEO 로 변경이 되며 download 실행 시 영상 파일(mp4)로 다운로드가 됩니다.

현재 듣거나 보고 있는 영상의 주소가 playlist 중의 일부라면 자동으로 플래이 리스트의 모든 파일이 다운로드 됩니다. 아무래도 공식 영상이나 음원에 신경쓴 자료들은 한곡씩 있는 경우가 많죠? 또 어떤 분이 멋진 플레이 리스트를 생성해서 공유한 경우도 있을 테고요. 또 내가 좋아하는곡들만 모아듣고 싶을 때도 있습니다. 이럴때 한번에 받을 수 있는 기능입니다.

위에도 적었지만 만약 그 중 한 파일만 받고 싶으시면 주소 표시줄의 주소가 아닌 영상 하단의 '공유' 버튼을 통해 생성된 링크를 입력하셔야 하나만 다운로드 됩니다.

어쨌든 플레이리스트 주소의 특징은 아래와 같이 생겼습니다.

https://www.youtube.com/watch?v=1w7OgIMMRc4&list=RDEMEvuJWC_U9r60eIeyIb5j_w&start_radio=1&ab_channel=GunsNRosesVEVO

제가 빨간색 표시한 부분이 보이시나요?

저렇게 list 라는 표시가 있으면 해당 주소는 플레이 리스트 주소를 담고 있습니다. 제가 좋아하는 guns n roses 의 음원 모음이네요. (너무 좋음)

다운로드 받은 경로와 주소를 모두 붙여넣은 뒤 download 버튼을 눌러주시면 끝

아래쪽 검은색 칸에 진행상황이 나오고요..

요렇게 자동으로 쭉쭉쭉 다운로드가 됩니다.

플레이리스트 다운로드 받기

 

어떠신가요 ? 마음에 드시나요?? ㅎ

 

뭉터기 음원 자동 자르기

중간에 single/list 라고 되어 있는 버튼을 눌러 주시면 multiple 로 변경이 되는데요, 이때 아래에 있는 download 버튼이 download cutting 으로 변경이 되고요. 그 옆에 name prefix 라는 부분에 이름을 적을 수 있는 칸이 활성화 됩니다.

예를 들어 '옛날노래' 라고 적으시면 아래와 같이 자동으로 음악을 잘라주게 됩니다. ㅋㅋ

 

음원에 따라 dB, duration 을 조정해야 하는 경우도 있긴 하지만 제 경험상 대부분 그냥 사용하시면 잘 동작합니다.

 

마음에 드신다면 개발자 후원하기!

사용해 보시고 괜찮다 싶으시면 커피한잔 사주십쇼~ ㅎ

고급커피는 좌측, 싸구려커피는 우측 QR 코드를 찍어 주세요~

 

 

다운로드 받기

7z 파일 또는 zip 파일을 다운로드 받으셔서 압축만 푸시면 됩니다.

https://drive.google.com/file/d/1B3pwH098BUE1FJUtbQ6iiYRuTJW_sjPX/view?usp=sharing 

 

MusicDownTown.7z

 

drive.google.com

https://drive.google.com/file/d/1oZn1H45jYP52BnRQVMP8hSJlo-bfm_6a/view?usp=sharing 

 

MusicDownTown.zip

 

drive.google.com

 

영상 올리신 분을 생각해서 데이터가 있거나 와이파이 가능하시면 직접 들으시길 추천 드립니다.

그럼 이만~

 

2020.03.09 - [DEV/c#] - 재택근무 필수 유틸 "자리안비움" - 윈도우 꺼짐 방지

 

재택근무 필수 유틸 "자리안비움" - 윈도우 꺼짐 방지

요즘 코로나 바이러스 때문인지 덕분인지 재택근무를 하는 분들이 많은데요. 막상 집에 있다 보면 사무실에 있을 때 처럼 연속해서 자리에 머무르지 못하는 경우가 종종 있습니다. 애들이나 와

diy-dev-design.tistory.com

 

2022.11.10 - [tip] - 유튜브에서 다운 받은 음악 자동으로 자르는 방법

 

유튜브에서 다운 받은 음악 자동으로 자르는 방법

유튜브 영상 또는 음악을 mp3 파일로 다운로드 받을 수 있는 것을 아시나요? 인터넷에 보면 그런 기능을 지원해주는 사이트들이 있습니다. 저도 유튜브에서 주로 음악을 듣는데 데이터 사용량이

diy-dev-design.tistory.com

 

반응형

'DEV' 카테고리의 다른 글

[GIT] diff 한글 깨지는 문제 해결 방법  (2) 2019.07.09
반응형

뻔하디 뻔한 개발 노하누는 가라~

이번에도 쓸만한 내용을 소개해 드릴 까 합니다.

개발을 하다 보면 실제 소스코드 외에도 어떤 텍스트를 resource 에 넣어 두고 소스코드에서 불러와야 하는 경우가 있을 수 있습니다. 저의 경우는 포토샵, 일러스트 등의 프로그램을 연동하여 c# 으로 App 을 만들었을때 실제 수행되는 코드는 jsx 스크립트 파일로 만든 뒤 app 에서 해당 스크립트를 실행하도록 하는데 이때 resource 에 스크립트 파일을 추가해 놓고 실행하는 타이밍에 해당 내용을 불러와 실행하도록 하는 경우가 종종 있습니다.

일단 c# 보다 javascript 로 작성하는게 쉽고 나중에 오류가 생기더라도 app 이 아닌 기능 단위로 만들어진 스크립트만 수정하면 되기 때문인데요.

보통 인터넷에 그런 내용으로 검색해 보면 실행파일이 빌드되는 순간 빌드 폴더에 해당 스크립트 파일이 복사되고 실행 파일 경로를 기준으로 하여 해당 파일을 불러와서 사용하도록 안내하고 있는 예제가 대부분입니다.

해당 스크립트(텍스트)를 굳이 공개하고 싶지 않고 스크립트 코드(텍스트 파일)가 빌드된 실행파일 내에 포함되면서 해당 텍스트를 불러오는 방법을 이번에 소개해 드리겠습니다.

두가지 방법이 있는데요. 두가지 방법을 모두 보시고 본인이 편한 방법을 사용하면 되겠습니다.

 

1. Properties > Resources.resx 내에 추가하는 방법

  1. 개발 디렉토리 내 임의의 폴더를 생성
  2. 생성된 임의의 폴더에 원하는 텍스트 파일 작성
  3. 작성된 텍스트 파일을 Properties > Resources 내에 텍스트 리소스로 추가
  4. 소스코드 내에 리소스를 텍스트(string) 로 가져오는 코드 작성

자 실제 화면을 보면서 설명을 드려보면요

JS 폴더를 생성한 뒤 텍스트 파일을 하나 추가함

위와같이 임의의 폴더를 하나 개발 디렉토리내에 생성한 뒤 필요한 텍스트 파일을 추가 합니다.

저의 경우는 포토샵 스크립트 파일 포멧인 jsx 로 추가하였고요. 좌측 내용을 보면 실행하면 그냥 "hello photoshop" 을 팝업으로 띄워주는 스크립트 입니다. 

그 다음 Properties > Resources.resx 를 더블클릭해서 열어준 뒤 좌측 상단의 리소스 타입을 '파일'로 변경해 줍니다.

리소스 타입을 파일로 변경\

 

그런 다음 리소스 추가 를 누르시고 '기존 파일 추가' 를 선택해 줍니다.

아까 만들어둔 파일을 등록한다

그럼 파일 선택 창이 나타나는데요. 아까 만들어준 JS 폴더 ( 본인이 생성한 폴더) 에 가보시면 생성한 텍스트 파일이 있을 거고요. 해당 파일을 선택해 주시면 됩니다.

01 은 바이너리 라는 뜻

그럼 이렇게 파일이 들어와 있는 것을 보실 수 있는데요. 이 파일이 텍스트 파일이라고 확인을 시켜 주어야 합니다.

우측 아래 속성 텝에 보면 이 파일의 타입이 Binary 로 되어 있는 것을 Text로 변경해 주어야 합니다.

바이너리로 되어 있다
텍스트로 변경

Text 로 변경하고 나면 위와 같이 인코딩을 지정할 수 있으니 나중에 텍스트 오류가 나면 해당 인코딩을 변경해가면서 사용하시면 됩니다.

자 이제 리소스로 추가 하였으니 불러오는 방법을 알아야 겠죠?

리소스로 등록한 텍스트 파일을 문자열로 불러오는 방법

위와 같이 string 문자열을 만들어서 불러오면 됩니다. PSXL_AUTO 는 솔루션 명으로 namespace 에 지정된 이름을 사용하시면 됩니다.

그 뒤로는 Properties 부터 자동완성 되므로 상세한 설명은 생략

MessageBox.Show(myResourceText) 를 이용하여 리소스 텍스트 내용을 불러와보면 

요렇게 잘 불러와 진것을 볼 수 있습니다.

물론 이렇게 하면 자동으로 포함리소스가 되므로 런타임에 별도로 파일을 찾아야 하거나 할 필요가 없습니다. 빌드 폴더에도 역시 별도로 파일이 나오거나 하지 않습니다.

간단하죠?

막상 해보면 간단합니다.

 

2. 그냥 개발 디렉토리 내에 폴더를 생성하고 파일을 추가하는 방법

 

  1. 임의의 폴더를 생성한다
  2. 생성한 폴더에 스크립트 파일을 작성한다
  3. 실행할 때 해당 스크립트를 불러오는 코드를 포함하여 실행한다.

 

요 방법도 제가 자주 사용하는 방법인데요. 별도로 리소스로 등록할 필요가 없어서 스크립트를 만들고 사용하는 과정에서 좀더 간단한 방법이라 할 수 있겠습니다.

물론 실행하는 부분에서 코드가 약간 복잡하기는 하지만 그래도 텍스트를 만들고 또 리소스에 추가하는 과정이 없어 좀더 직관적이라고 할까요? 

임의의 폴더에 스크립트 파일을 추가하였다

이번에도 생성한 폴더에 스크립트 파일을 추가하였습니다.

내용을 구분하기 위하여 hellow 를 bye로 변경하였습니다 ㅎ

속성 텝에서 아래와 같이 포함리소스, 출력디렉토리에 복사 안함 으로 설정해 줍니다.

포함리소스, 복사안함으로 설정 필수

 

자 이제 코드를 불러오는 내용을 작성해야 하는데요. resources 에 추가한 내용을 불러오는 것은 아주 간단했죠?

요건 약간 복잡합니다. 아래 코드를 참고해 주세요.

private string showtextString()
        {
            string myStr = "";
            var assembly = Assembly.GetExecutingAssembly();
            var myScript = "PSXL_Auto.JS.defPSScript.jsx";
            using (Stream stream = assembly.GetManifestResourceStream(myScript))
            {
                using (StreamReader sr = new StreamReader(stream))
                {
                    myStr = sr.ReadToEnd();
                }
            }
            MessageBox.Show(myStr);
            return myStr;
        }

// 또는 

private string showtextString(string txtName)
        {
            string myStr = "";
            var assembly = Assembly.GetExecutingAssembly();
            var myScript = "PSXL_Auto.JS." + txtName;
            using (Stream stream = assembly.GetManifestResourceStream(myScript))
            {
                using (StreamReader sr = new StreamReader(stream))
                {
                    myStr = sr.ReadToEnd();
                }
            }
            MessageBox.Show(myStr);
            return myStr;
        }
        
        
// 실행하는 부분에서
showtextString("defPSScript.jsx");

일단 간단하게 해당 리소스 텍스트를 string 으로 돌려주는 함수처럼 만들었는데요. 코드 내에 "JS" 라는 부분은 사용자가 만든 폴더 명칭이라는 것을 아실 수 있으시죠? 물론 아래와 같이 리소스 파일명을 인자로 받아 해당 텍스트를 리턴해 줄 수 있도록 하면 사용할 때도 간단하게 사용할 수 있을 것입니다.

요렇게 만들어진 함수를 실행해서 메시지 박스로 출력해 보면 

당연히 잘 출력 됩니다.

중간에 bye 로 나오는 것 잘 보이시죠?

당연히 위의 두가지 방법 모두 실행 파일 경로에 해당 텍스트 파일이 따라오지 않고 잘 숨겨져 있게 됩니다.

 

꼭 필요하신 분들께 도움이 되었기를 바라면서 이만 줄입니다~

 

2020.08.11 - [DEV/c#] - [c#] streamreader 를 이용하여 정확한 라인 위치 찾기

 

[c#] streamreader 를 이용하여 정확한 라인 위치 찾기

c# 을 이용하여 streamreader 개체로 텍스트를 읽는 방법은 매우 효율 적이고 손쉽게 작업을 수행하도록 해줍니다. 빠르고 간단하게 개발을 할 수 있어 저도 자주 사용하고는 합니다. 그런데 이번에

diy-dev-design.tistory.com

 

2020.06.03 - [DEV/c#] - C# .net으로 photoshop 연동하기

 

C# .net으로 photoshop 연동하기

저는 회사에서 디자인팀에 있고 전공도 디자인과 출신이며 심지어는 고등학교도 예체능계열 고등학교를 나왔습니다만 지금 회사에서 하는일의 95% 정도는 개발을 하고 있습니다. 실제로 제가

diy-dev-design.tistory.com

 

2020.07.21 - [DEV/c#] - C# 문자열 읽어서 문자열에 해당하는 변수에 값 세팅하기

 

C# 문자열 읽어서 문자열에 해당하는 변수에 값 세팅하기

오늘 소개해드릴 꿀팁은요. 문자열을 읽어 들여서 문자열 내에 들어있는 특정 단어를 이용하여 개발 중인 코드의 변수로 인식하여 해당 변수에 값을 세팅하는 방법을 소개해 드릴까 합니다. 예

diy-dev-design.tistory.com

 

 

반응형
반응형

오늘은 간단한 VBA 코드를 하나 소개해 드릴까 합니다.

프로그래밍을 하다보면 16진수를 10진수로 바꾸거나 10진수를 16진수로 바꾸어야 하는 경우가 종종 있습니다.

읭? 16 진수?

라고 하실수도 있겠지만 막상 개발을 하다 보면 16진수가 쓰이는 경우를 생각보다 자주 만나게 됩니다. 

대표적을 RGB 컬러 값을 HTML 에서 사용하는 #FFEACB 이런 값으로 변경하는 작업이 있겠습니다. 또는 반대로 0 ~ FF 가지 255개의 숫자가 16진수로 구성되어 있는 값을 0~255인 자연수로 변경을 해야 하는 경우가 있을 수도 있고요. 16진수는 1개의 자릿수에서 0~15 까지의 값을 표현할 수 있기 때문에 10진수에 비하여 간단한 텍스트로 더 큰 숫자를 표현할 수 있다는 장점도 있습니다.

자 쓸데 없는 말이 길었네요.

VBA를 이용해서 숫자의 형을 변환하는 여러가지 방법이 있지만 오늘 소개해드릴 방법은 그중에서도 단연 쉽고 간단한 방법입니다.

바로 worksheet의 함수를 이용하는 방법인데요. 엑셀 상단에 수식을 입력할 수 있는 칸이 있자나요? 여기서 사용되는 함수가 바로 worksheet function 입니다. 

worksheet function 중에 DEC2HEX() 와 HEX2DEC()  가 바로 오늘의 주인공 입니다.

함수 명칭만 봐도 딱 감이 오시죠?

사용하는 방법은 아래와 같습니다.

먼저 위와 같이 엑셀에 16진수 값이 들어있는 셀이 있다고 가정을 하고요.

vba 에디터를 열어 아래와 같이 코드를 작성해봅니다.

Sub changeNumber()

    Dim rngA As Range
    Set rngA = [A1]
    
    rngA.Offset(0, 1).Value = WorksheetFunction.Hex2Dec(rngA.Value)
    rngA.Offset(0, 2).Value = WorksheetFunction.Dec2Hex(rngA.Offset(0, 1).Value)

End Sub

자 A1 셀에 있는 값을 바로 우측 옆 칸에 10진수로 바꾸는 함수를 적용하여 값을 넣어 줍니다.

그다음 B1 에 위에서 자동으로 입력된 값을 다시 16진수로 옆칸에 자동으로 입력해주는 코드 입니다.

실행하면요

요렇게 B1 에는 10진수로, 다시 C1 에는 16진수로 값이 변경된 것을 볼 수 있죠?

worksheetFunction 에는 물론 엑셀에서 사용할 수 있는 모든 함수를 지원해 주니까 vba 작성중에도 가져다가 사용할 만한 함수가 많지만 오늘 포스트의 주제에 맞게 숫자의 형 변환 관점에서만 보자면 아래와 같은 여러 함수들이 지원됩니다.

물론 Hex 로 부터 출발 하는 경우에도 마찬가지 입니다.

문장이 조금 길어 보여서 어렵거나 복잡하게 생각될 수도 있기는한데 막상 사용해보면 생각보다 단순 합니다. 사용하는데 따로 알아두어야 할 규칙 같은것도 없어서 코딩하는 시간도 많이 절약되는 방식이라 할 수 있겠습니다.

 

만약 아래와 같이 셀에 html 색상 값이 들어있는 경우 

vba를 이용하여 해당 색상으로 셀의 배경 색상을 자동으로 칠해 줄 수 있습니다.

Sub changeNumber()

    Dim rngA As Range
    Set rngA = [A1]
    
    Dim clrR As Integer
    Dim clrG As Integer
    Dim clrB As Integer
    
    clrR = WorksheetFunction.Hex2Dec(Mid(rngA.Value, 2, 2))
    clrG = WorksheetFunction.Hex2Dec(Mid(rngA.Value, 4, 2))
    clrB = WorksheetFunction.Hex2Dec(Mid(rngA.Value, 6, 2))
    
    rngA.Interior.Color = RGB(clrR, clrG, clrB)
    

End Sub

간단하죠? 위에서 소개해 드린 worksheetFunction을 이용하여 2자리씩 잘라낸 16진수를 10진수로 담은뒤에 셀의 배경 색상으로 지정하는 것이죠.

글자를 잘라내는 건 2019.08.12 - [DEV/VBA] - [VBA] 문자열 가지고 놀기 참고하세요~

스크립트를 실행하면 어떻게 될까요?

 

요렇게 html 형식의 색상 값으로 셀의 색상이 지정 됩니다.

뭐 한두칸이야 얼마든지 수작업으로도 적용할수 있기는 합니다만 이런 값이 수천개가 있는데 모두 엑셀 시트에서 지정된 색상으로 보여지기를 원한다면 vba 가 반드시 필요하겠죠?

 

그럼 이만 오늘의 포스팅을 마칩니다.

2022.06.16 - [DEV/VBA] - [VBA] 선택한 셀의 이미지 파일 이미지 뷰어로 열기

 

[VBA] 선택한 셀의 이미지 파일 이미지 뷰어로 열기

오늘 소개해 드릴 내용은 엑셀 시트에 이미지 파일명과 경로가 있는 상태에서 선택한 이미지만 뷰어로 바로 확인하는 방법 입니다. 이미지가 수백개 들어있는 엑셀 시트에 이미지를 모두 붙여

diy-dev-design.tistory.com

2020.09.04 - [DEV/VBA] - [vba] 엑셀 이미지 리스트로 일괄 다운로드 받기

2020.06.22 - [DEV/VBA] - [vba] 초등학교 연산 자동 문제집 - 곱셈 추가

2019.08.12 - [DEV/VBA] - [VBA] 문자열 가지고 놀기

 

[VBA] 문자열 가지고 놀기

안녕하세요. 이번 글에서는 VBA 에서 문자열을 가지고 무엇인가를 하는 것을 알아보겠습니다. 프로그래밍을 하다 보면 조건을 가지고 어떤 액션을 해야 하는 결우가 무척 많은데요. 그중에 대표

diy-dev-design.tistory.com

2020.01.30 - [분류 전체보기] - [vba] 셀 속성 조정하기 (넓이, 높이, 숨기기, 테두리 등)

 

[vba] 셀 속성 조정하기 (넓이, 높이, 숨기기, 테두리 등)

이번 포스트에서는 vba 를 이용하여 셀의 속성을 조정하는 방법을 설명 드리겠습니다. 엑셀은 단순한 표의 형식을 취하고 있지만 셀의 간격이나 테두리 등의 속성을 자유롭게 조정할 수 있어 다

diy-dev-design.tistory.com

2019.08.30 - [DEV/VBA] - [VBA]RGB 색상 값이 들어있는 셀에 셀 색상 지정하기

 

반응형
반응형

안녕하세요 오랜만에 3DS MAX SCRIPT 포스팅을 합니다.

제가 올리는 글을 누가 보는가 싶은데.. 간혹 스크립트를 잘 봐주시는 방문객들이 계신듯 하여 포스팅을 하게 되었습니다.

오늘은 3DS MAX SCRIPT의 계층 구조에 대한 이야기 입니다. 

왠만한 개발을 해 보신 분들은 사실 약간 상식적으로 알고 계신 내용일 것 같기는 합니만 그래도 역시 누군가에게는 도움이 될 듯 하여 글을 남겨 봅니다.

 

3DS MAX Scritp 에서 어떤 오브젝트는 개발 관점에서 보면 클래스 입니다. 상위 클래스가 있고 또 하위 클래스가 있는데요. 계층 구조라고 말씀 드린것처럼 클래스 안에 또 작은 클래스가 정의 되어 있고 또 그안에 작은 클래스 또는 구조체가 정의 되어 있다고 보시면 됩니다.

 

클래스라고???

개발이 생소하신 분들은 클래스라고 하면 잘 이해가 안되시죠?

우리 인간을 예를 들어 클래스라는 개념을 설명해 보면 다음과 같습니다. (그냥 예 입니다)

각 단계는 상위 클래스의 하위 클래스가 됩니다.

  • 동물 - 호흡을 한다. 심장이 있다. 
    • 포유류 - 4개의 팔 또는 다리를 가지고 있다. 아기를 낳는다. 젖을 먹인다.
      • 영장류 - 지능이 뛰어나다. 두발 또는 네발로 걸을 수 있다. 시각 능력이 좋다
        • 인간 - 특별히 뇌가 발달했다. 다양한 언어를 구사할 수 있다. 손의 움직임이 뛰어나다
    • 조류 ... 
    • 양서류...
    • 파충류...

뭐 이런식으로 어떤 큰 개념을 정의하고 그 하위에 상위의 개념을 포함하지만 조금 세분화된 개념을 담는 그런 방식으로 한단계 한단계 세분화된 그런 개념을 담고 있는 것이 일반적인 클래스의 개념입니다. (위에 설명한 건 그냥 예를 든 것입니다. 시비 노노)

 

예를 들면 익히 잘 알고 있는 Box 는 

요런 순서의 계층 구조를 가지고 있습니다.

우린 레퍼런스 파일을 통해서 Box() 라는 클래스가 가지고 있는 다양한 프라퍼티에 접근을 할 수 있습니다.

2021.03.24 - [DEV/MAX SCRIPT] - 3DS MAX 스크립트 레퍼런스 (헬프파일) 다운 받기

예를 들면 생성된 Box 개체의 width, Height, length 를 다음과 같이 변경할 수 있습니다.

myBox = box()
myBox.width = 25
myBox.Height = 150
myBox.Length = 50

그럼 아래와 같은 모델이 화면에 자동으로 생성되겠죠.

스크립트로 생성한 box

 스크립트에서 설정한 값이 잘 들어가 있는 것을 알 수 있습니다.

 

GeometryClass

그런데 위에 계층 구조를 보면 Box 위에 GeometryClass 라는 상위 클래스가 보이죠? 레퍼런스에서 해당 위치를 클릭해보면 GeometryClass 라는 녀석에 대한 정보가 나오는데요, 

"The mesh operations underlying the Boolean Compound Object in 3ds Max are accessible in MAXScript." 

라는 글이 해당 페이지의 첫줄에 보이고 

  • <node1> + <node2>
  • <node1>-<node2>
  • <node1>*<node2>

요런 수식들이 소개가 되어있습니다. 내용을 읽어 보면 GeometryClass 는 + - * 와 같은 연산자로 boolean 을 수행할 수 있다는 의미가 되겠습니다. Box 는 GeometryClass 이므로 당연히 Box 와 Box 는 위와 같은 boolean 연산이 된다고 볼 수 있겠습니다.

한번 해볼까요? 

myBoxA = box()
myBoxA.width = 50
myBoxA.Height = 50
myBoxA.Length = 50


myBoxB = box()
myBoxB.width = 150
myBoxB.Height = 25
myBoxB.Length = 25

myBoxB.pos.z = 12.5

요렇게 두개의 박스를 만드는 스크립트를 실행하면 

요런 형태의 두개의 박스가 생성이 됩니다.정육면체가 myBoxA, 길다란 육면체가 myBoxB가 되겠습니다.

자 그럼 myBoxA 에서 myBoxB를 빼 보도록 하겠습니다.

myBoxA = box()
myBoxA.width = 50
myBoxA.Height = 50
myBoxA.Length = 50

myBoxB = box()
myBoxB.width = 150
myBoxB.Height = 25
myBoxB.Length = 25
myBoxB.pos.z = 12.5

myBoxA - myBoxB

delete myBoxB

다른부분은 동일하고 마지막에 myBoxA 에서 myBoxB 를 빼는 수식을 추가한 다음 길다란 녀석을 삭제하는 코드를 추가하였습니다.

결과는요?

네. boolean 같은 복잡한 클래스를 사용하지 않아도 이렇게 쉽게 boolean 동작을 수행하는 군요. 

네 그럼 Box 뿐만 아니라 다른 geometryClass 의 모든 대상이 위와 같이 단순한 연산자를 이용하여 boolean 연산을 할 수 있다는 의미로 보시면 됩니다.

GeometryClass 에는 Box 외에도 Sphere 나 Cylinder, Tube 및 친근한 Teapot 같은 개체도 모두 GeometryClass 이므로 모두 동일하게 위와 같은 연산을 사용할 수 있다는 거죠.

GeometryClass 에는 아래와 같은 명령어도 지원합니다.

설명을 보면 

"Returns an array of two integers - the face count and the vertex count of the TriMesh on top of the modifier stack. "

라고 되어 있는데요, Sphere 를 하나 생성한 뒤 위의 코드를 한번 실행해 볼까요?

mySphere = Sphere()
GetTriMeshFaceCount mySphere

요렇게 작성한 뒤 실행해 보면 

$Sphere:Sphere002 @ [0.000000,0.000000,0.000000]
#(224, 114)

요런 결과가 리턴 됩니다. 첫째 줄은 생성된 sphere 에 대한 정보이고요, 두번째가 바로 작성한 코드의 결과물인데요. 위의 설명에 따르면 face 개수와 vertex 개수를 돌려 준다고 합니다. 생성된 sphere 는 224개의 face 와 114개의 vertex 로 이루어져 있다는 것을 알 수 있습니다. 다시 말하자면 우리는 생성한 geometryclass 가 뭐든간에 해당 개체의 폴리곤수를 바로 알 수 있게 되는 겁니다. mesh 나 poly 같은 개체의 geometry 속성 정보를 알기 위하여 class 구분을 하고 getNumfaces 나 polyop.getNumVertexs 를 사용하는 것처럼 개체의 클래스나 구성 방식 등을 검사를 할 필요가 없는거죠.

 

Node

자 그럼 한칸 더 상위로 올라가서 Node 를 볼까요?

Node 는 3DS MAX Script 에서 아주 중요한 개념으로 해당 클래스에서 사용할 수 있는 프라퍼티나 메소드가 아주 많습니다. 스크립팅의 아주 기본적인 부분도 많이 보이네요.

아주 간단한 예를 들면 우리가 scene 에서 보여지는 모든 개체는 node 라는 클래스라고 보면 됩니다. EditableMesh 건 EditablePoly 건 Camera 건 심지어 helper 나 dummy 같은 개체도 모두 node의 하위 클래스 입니다.

즉 Node 라는 개체에 대한 설명이 적혀있는 레퍼런스 페이지에 있는 모든 하위요소를 사용할 수 있습니다.

 제가 아~~주 자주 사용하는 node 의 대표적인 프라퍼티 또는 메소드를 보면 아래와 같습니다.

  • IsValidNode <var>
  • move <node> <point3> -- mapped
  • scale <node> <point3> -- mapped
  • rotate <node> <eulerangles> -- mapped
  • copy <node> -- mapped
  • reference <node> -- mapped
  • instance <node> -- mapped
  • delete <node> -- mapped
  • classOf <node>

딱 봐도 어떤 일을 하는지 아시겠죠? 우리가 알고있는 대부분의 요소는 node 이며 위와 같은 명령어를 이용하여 컨트롤 할 수 있답니다. 복사하고 이동하고, 회전하고 삭제하고, 해당 개체가 어떤 클래스인지 확인하는 그런 것들이죠.

Node Common Methods

 

라는 항목을 보면 Node 에서 사용할 수 있는 더 많은 상세한 레퍼런스들을 확인할 수 있습니다.

Node 클리스의 상세한 레퍼런스 들

이렇게 말이죠.

물론 Node 자신의 subClass 에는 GeometryClass, Shape, Light, Camera, Helper, SpacewarpObject, System 이러한 요소들이 있고 각기 자신에 해당하는 프라펕와 메소드들을 다룰 수 있지만 역시 node 에서 정의하고 있는 모든 프라퍼티와 메소드를 사용할 수 있는 것 입니다.

 

드디어 최상위 클래스 : Value

그럼 최상위 Value 라는 개체로 가 볼까요?

Value 개체는 3DS MAX 에서 정의하고 있는 class 의 최상위 개체입니다. 말하자면 모든 구조체, 클래스 등은 Value 에 속하므로 Value 에서 정의하고 있는 기능을 수행할 수 있는 것이라 할 수 있겠습니다.

최상위인 value 에는 대표적으로 다음과 같은 항목들이 정의되어 있습니다.

  • <value> == <value>
  • <value> != <value>

익히 잘 알고 있는 bool 연산자죠? if 구분 같은 곳에서 대상과 대상이 같은지 다른지 판단할 수 있고요. 

  • print <value>
  • format <format_string>

와 같은 코드를 통해서 해당 정보를 출력해 볼 수 도 있습니다. 

Working with Values

라는 레퍼런스 페이지에 보면 스크립팅을 하는 동안 Value 를 어떻게 다룰 수 있는지 잘 소개가 되어있습니다.

스크립트는 다른 개발 언어와 다르게 빠르게 작성하고 빠르게 컴파일, 실행을 할 수 있기 때문에 이런 구조체를 알면 디버깅도 빠르고 작성도 손쉽게 할 수 있겠습니다.

Value 에는 node 와 같은 scene 내의 개체 뿐만 아니라 Float ,Integer ,String ,BitArray ,Point3 ,Ray ,Quat ,AngAxis ,EulerAngles ,Matrix3 ,Point2 ,Color ,Arrays 와 같은 클래스나 구조체들도 포함되어 있습니다. Ray 에 대해서 지난 포스팅에 소개해 드렸었죠?

2022.05.31 - [DEV/MAX SCRIPT] - [3ds max script] ray 에 대하여 알아보기

 

[3ds max script] ray 에 대하여 알아보기

가끔 아니 어쩌면 자주 3D 공간안에서 물체의 위치를 지정할때 이 물체가 저쪽에 닿는 면에 딱 위치하고 싶은데... 할때가 있죠? 예를 들면 나무나 돌덩이 이런걸 랜덤하게 막 생성한 다음 굴곡진

diy-dev-design.tistory.com

사실 Value 는 정말 아~~주 아주 기본적인 속성들을 다루고 있다고 보시면 되고 해당 정보들 없이는 스크립팅이 불가능한 정말 개념이 없어도 늘 사용하는 그런 애들이라고 보시면 됩니다.

 

 

마치며

자 오늘 포스팅은 사실 개념적인 부분이어서 조금 어려울 수도 있을 것 같습니다.

하지만 스크립팅을 하다보면 저처럼 자연스럽게 알게 되기도 하고요. 또 이런 개념을 이해하고 스크립팅을 하면 훨씬 쉽고 유연하게 코딩을 하실 수 있을 거에요. 

저 처럼 무작정 코딩을 하며 배워가는 경우에도 "아~~~ 이게 이런거였어?!?!?" 이런 적이 셀 수 없이 많았거든요. 

 

자 다시 정리하자면 

  • 상위 클래스에서 정의되어 있는 프라퍼티나 메소드는 하위 클래스에서도 접근 할 수 있다.
  • 즉 name, rotate, move, delete, copy 같은 개념은 하위의 어떤 클래스에서도 사용할 수 있다.
  • 지금 보고 있는 개체의 상위 클래스가 무었인지 확인해 보자.

 

자 다들 화이팅하시고 스크립팅을 통해 에이스의 진면모를 보여주시기를 바라며 오늘의 포스팅을 마칩니다.

 

2021.02.26 - [DEV/MAX SCRIPT] - [3ds max script] vector 에 대하여

 

[3ds max script] vector 에 대하여

안녕하세요. 오늘은 디자이너라면 조금 생소할 수 있는 vector 라는 개념에 대하여 소개해 드릴까 합니다. 혹시 작년 쯤인가요? 슈퍼밴드라는 밴드 오디션 프로그램에서 F=ma 라는 곡으로 아주 인

diy-dev-design.tistory.com

2021.02.24 - [DEV/MAX SCRIPT] - 3da max script 점과 점 사이의 거리 구하기

 

3da max script 점과 점 사이의 거리 구하기

간단하게 포스팅을 남기려고 합니다. 제목 그대로 버텍스 간 거리 구하기 입니다. 아니 정확히는 두개의 point3 사이의 거리를 구하는 방법을 소개해 드릴까 합니다. 그리고 용용 편으로 두 점사

diy-dev-design.tistory.com

 

반응형
반응형

일러스트로 디자인을 하다 보면 뒤에 사진이나 이미지를 앉혀야 하는 경우가 자주 있는데 보통 한번에 컨펌이 나지 않기 때문에 place 시킬때 link 형식으로 앉히게 됩니다.

배경 이미지의 시안이 변경 될 경우 이미지만 변경하면 자동으로 일러스트에서도 변경이 되기 때문이기도 하고 또 작업하는 파일의 용량이 작아 HDD 디스크에 부담도 적기 때문이지요.

그런데!!

 

이걸 이제 인쇄를 넘기려면 링크된 모든 파일을 다 찾는 것도 일이고.. 보냈을때 하나라도 누락이 되었다면 사고가 나는것이죠. 

그래서 embed 형식으로 변경하면 ai 파일 내에 이미지가 포함이 되서 이런 문제가 일어나지 않는데요.

place 된 이미지가 한 두개면 괜찮은데 그 숫자가 좀 많을 때는 여간 귀찮고 번거로운 일이 아닐 수 없습니다.

이렇게나 많다면 말이죠.

link 형식으로 잔뜪 place 된 이미지들

 

또 파일을 보낸 뒤에 누락된 개체는 없는지 확인할 동안 기다려야 되는 문제도 있겠네요.

 

이럴때 스크립트가 출동한다면!!!

스!

크!

립!

트!

 

네. 바로 스크립트라면 간단히 해결을 할 수 있습니다.

바로 스크립트를 볼까요?

var cDoc = app.activeDocument
var pItems = cDoc.pageItems

for (var k = 0; k < pItems.length; k++)
{
	var cItem = pItems[k] 
	if (cItem.typename == "PlacedItem")
	{
		cItem.embed()	
	}
}

 

엥?

엄청 짧죠?

 

네 그런데 이게 됩니다.

위의 내용을 텍스트 에디터에 붙여 넣고 jsx 형식으로 저장합니다.

jsx 형식으로 저장된 스크립트

잘 모르시겠으면 그냥 .txt 파일로 저장한 뒤에 확장자만 jsx 로 바꾸어 주어도 됩니다.

그런 다음 일러스트에서 이 스크립트를 실행 시키면 되는데요.

간단합니다. 두가지 방법이 있는데

 

1. 그냥 스크립트 파일을 일러스트 창 안으로 drag and drop 한다

 

2. File - Script - Other Script --> 만들어 두었던 스크립트 파일 선택

 

간단하죠? 

요렇게 하면 place 된 개체가 어느정도이냐에 따라 다르지만 많아야 많아야 1~2분이면 될거에요.

 

결과를 볼까요 ? Ctrl + Y 를 해서 보면 link 형식으로 place 된 개체는 X 표시가 되는 것을 알수 있는데요.

상당히 많은 link 형식의 placeItem 이 있는 화면

 

요렇게요.

그럼 스크립트를 실행한 ai 파일을 Ctrl + Y 해서 볼까요?

모든 placeItem 이 embed 형식으로 변경된 화면

네. 단하나의 누락 없이 모두 embed 로 변경이 되었습니다.

 

캬!

역시 배워야 합니다.

오늘은 이만 마치도록 하겠습니다.

다시한번 말씀 드리지만 위에 제가 소개해드린 스크립트를 메모장 등으로 옮기신 후 jsx 파일로 저장, 일러스트에서 실행하시면 됩니다.

 

감사합니다.

2020.12.03 - [DEV/Adobe Script] - [illustrator script] 일러스트도 스크립트가 되나요?

 

[illustrator script] 일러스트도 스크립트가 되나요?

네! 당연히 됩니다. 일러스트레이터에서 스크립트를 사용할 수 있게 되면 진정 놀라운 결과들을 만들어 낼 수 있습니다. 사람이 손으로 하기에는 정말 귀찮은 작업들을 가능하게 만들어 줍니다.

diy-dev-design.tistory.com

 

2019.12.13 - [DEV/Adobe Script] - [포토샵스크립트] PSD 모든 레이어 자동 저장, 하위 폴더 포함 (레이어 크기로 이미지 저장)

 

[포토샵스크립트] PSD 모든 레이어 자동 저장, 하위 폴더 포함 (레이어 크기로 이미지 저장)

안녕하세요. 제가 포토샵 스크립트를 이용하여 PSD 파일내의 모든 레이어를 자동으로 하위폴더 구조를 유지하며 저장할 수 있는 스크립트를 만들어서 올렸었는데요. 바로 아래 링크에서요. https:

diy-dev-design.tistory.com

 

반응형
반응형

오늘 소개해 드릴 내용은 엑셀 시트에 이미지 파일명과 경로가 있는 상태에서 선택한 이미지만 뷰어로 바로 확인하는 방법 입니다.

이미지가 수백개 들어있는 엑셀 시트에 이미지를 모두 붙여넣는 기능도 사용할 수 있겠지만 이미지가 매우 크거나 이미지가 수시로 업데이트 될 수도 있겠고요, 또 이미지가 너무 많은 경우 이미지를 모두 붙여 넣으면 엑셀 파일의 용량이 매우 커지겠죠.

그럴 때 사용하면 괜찮은 기능입니다.

바로 어떻게 생긴 이미지인지 궁금한 대상만 선택하여 바로 이미지 뷰어로 보는 것이죠.

 

먼저 이미지 파일명이 쭈~ 욱 들어있는 엑셀 파일을 준비하시고 스크립트를 동작시킬 단추를 하나 추가합니다.

상단을 틀고정 같은걸로 고정해 놓으면 리스트를 내려도 단추가 계속 보일 거에요.

단추를 추가하는 방법을 모르고 계시만 아래 포스트를 참고해 주세요
https://diy-dev-design.tistory.com/59

 

이미지 리스트와 단추가 준비된 엑셀

위 엑셀 리스트는 예전에 제가 폴더 내의 파일 정보를 가져오는 스크립트를 이용하여 만든 리스트 입니다.

제가 원하는 기능은 이미지 파일명을 선택하고 버튼을 누르면 윈도우에서 지정된 이미지 뷰어로 해당 파일을 열어서 보여주는 것입니다.

그럼 선택한 셀 정보를 얻어오는 스크립트가 필요하겠고 윈도우 shell 명령으로 이미지 파일을 연결하면 윈도우에서 지정한 이미지 뷰어가 이미지를 열어주겠죠?

먼저 선택한 셀 정보를 얻는 스크립트가 필요하겠죠? 여기를 참고하세요

선택한 셀에 이미지 파일명을 아래와 같이 shell 명령을 사용하면 이미지가 열리게 됩니다.

Dim wsh As Object
    
Set wsh = VBA.CreateObject("WScript.Shell")
wsh.Run imgName

 

전체 코드를 볼까요?

Sub showImage()

    Dim aSht As Worksheet
    Dim currentSelection As Range
    Dim imgExtName As String
    Dim imgName As String
    Dim curext As String
    Dim wsh As Object
    
    Set wsh = VBA.CreateObject("WScript.Shell")
    
    Set aSht = ActiveSheet
    Set currentSelection = Selection.Cells()
    
    imgExtName = ".png.jpg.jpeg.bmp.gif.webp.pct.ico...."
    
    curext = LCase(Right(currentSelection.Value, 4))
    
    If (InStr(imgExtName, curext)) Then ' 현재 선택한 셀 내용 중 이미지 확장자를 가지고 있으면
        imgName = currentSelection.Offset(0, -1).Value & "\" & currentSelection.Value
        If Dir(imgName) <> "" Then
            wsh.Run imgName
            
        End If
    Else
        MsgBox ("이미지 파일명이 들어있는 셀을 선택해 주세요")
    End If
    
End Sub

 

선택한 셀이 이미지 파일명인지 아닌지는 확장자로 검사를 하도록 했습니다. imgExtName 이라는 문자열에 이미지 확장자들을 쭈욱 넣어둔 뒤에 실제 선택한 셀의 텍스트에서 뒤에서 4글자를 떼어낸 뒤에 위에 말씀드린 문자열 중에 포함되는지를 검사하는 것이죠.

아주 정교한 방식이라고 볼 수는 없지만 간단하게 구현할 수 있는 이미지 검출 방식이라 할 수 있겠습니다.

어쨌든 이렇게 이미지 파일명이 맞는지 확인한 뒤에 앞에있는 경로명과 결합해서 해당 이미지가 실제로 존재하는 이미지 인지 추가로 확인한 뒤에 shell 명령을 통해 이미지를 열어주게 됩니다. 

저는 바로 왼쪽 옆칸에 경로가 있어 offset(0,-1) 과 같은 방법으로 연결하였지만 별도 셀에 이미지 경로가 들어있다면 해당 경로를 따로 지정해 주거나 스크립트 내에 문자열로 넣어 주셔도 되겠습니다.

이렇게 만들어진 매크로를 버튼에 연결하는 방법은

버튼을 최초 생성할때도 보였겠지만 매크로를 연결하는 메뉴가 있습니다. 단추에서 오른쪽 클릭한 다음 "매크로지정" 을 선택하면 매크로 선택창이 나타나게 되는데요, 여기서 지금 만들어준 스크립트를 선택해주면 됩니다.

매크로 지정하는 과정

 

자 이제 어떻게 동작하는지 한번 볼까요?

먼저 이미지 들이 들어있는 폴더가 있을 거고요. 만약 이미지가 아닌 셀을 선택하면 경고창을, 이미지 이름을 선택하면 윈도우 이미지 뷰어로 바로 열리게 됩니다.

선택한 이미지가 열리는 기능이 실제 동작되는 화면

 

자 간단하게 원하는 기능이 구현되었습니다.

필요하신 분들은 소스 복사하셔서 사용하시면 될 것 같고요. 잘 응용하셔서 본인의 엑셀 문서에 딱 맞는 기능으로 추가하시면 되겠습니다..

 

그럼 이만~

반응형
반응형

가끔 아니 어쩌면 자주 3D 공간안에서 물체의 위치를 지정할때 이 물체가 저쪽에 닿는 면에 딱 위치하고 싶은데... 할때가 있죠? 

예를 들면 나무나 돌덩이 이런걸 랜덤하게 막 생성한 다음 굴곡진 지형에 모두 딱 안착시키고 싶다거나요.

또는 어떤 물체를 기준으로 어떤 방향으로 뻗어 나갈때 무엇인가 닿는 물체가 있는지 검사하고 싶을때도 있지요.

이때 사용되는 개체가 바로 Ray 입니다.

실제로 Ray를 알기 전과 알고난 뒤는 정말 다른 세계라고 할수 있겠습니다.

 

자 오늘은 Ray 에 대하여 알아보도록 하겠습니다.

3D 는 정말 놀라울 정도로 기하학적인 수학의 결정체라 할 수 있겠습니다. 이를 구현하기 위하여 정말 얼마만큼의 수학적 노력이 있었는지 상상이 안될 정도 입니다.

오늘은 그 결정체중의 하나인 Ray에 대하여 알아볼텐데요. 3DS MAX 에서 Ray 는 두가지 명령어를 통해 사용됩니다.

intersectRay 와 intersectRayEx, intersectRayScene 이렇게 세가지 입니다. 사용하는 목적에 따라 구분하여 사용하시면 되는데요. 각각은 아래와 같습니다.

  • intersectRay : Ray 와 대상물체를 지정한 뒤 부딧히는 위치를 알아낸다.
  • intersectRayEx : 위와 동일하며 부딪힌 Face 정보와 부딪힌 면의 normal 정보를 돌려준다
  • intersectRayScene : 대상 개체를 지정하지 않고 Scene 내의 어떤 물체든 부딪힌 정보를 돌려준다. (느림)

사용하는 방법은 간단한데요, 먼저 Ray 를 생성해주고 필요하면 Ray의 출발 위치(pos)와 방향(dir)을 변경할 수 있습니다.

myRay = ray [0,0,0] [0,0,-1]

ray 를 생성하는 구문 인데요, [0,0,0] 위치를 출발점으로 하고 [0,0,-1] 을 방향으로 하는 ray 가 만들어 지게 됩니다. [0,0,-1] 이라 하면 z 축을 기준으로 아래쪽을 바라보는 방향이라고 보면 되겠죠? 

 

이렇게 만들어진 Ray를 위의 명령어와 함께 사용해볼까요?

임시로 테스트용 Scene 을 만들어 봄

먼저 위와 같은 Scene 을 만들어서 테스트 해보려 합니다. 노란색 공이 지면에 부딪히는 위치로 이동 시킬거에요. 중간에 네모 박스가 있지만 네모박스는 무시하고 지면에 위치시켜야 한다면 아래와 같이 intersectray 를 이용하여 위치시킬 수 있습니다.

-- ray 를 생성해 준다
myRay = ray [0,0,0] [0,0,-1]

-- 이동시킬 물체를 지정하자
obj = $Sphere001

-- ray 의 출발 위치를 물체의 중심으로 설정해보자
myRay.pos = obj.pos

-- 위치 검출에 사용될 지형을 지정해보자
tern = $terrain_01

-- intersectray 를 이용하여 지형과 부딪히는 위치를 찾아내자
interResult = intersectray tern myRay

-- 어떤 결과가 나왔는지 print 를 이용해서 살펴보자
print(interResult)

-- 부딪힌 위치에 오브젝트를 위치시키자
obj.pos = interResult.pos

요렇게 하면 어떻게 되냐면요

지면에 정확하게 안착함

요렇게 노란 공이 지면에 달라 붙게 됩니다. 코드에 주석을 달아 놓았으니 따로 설명은 안드려도 될 것 같은데요. 한가지만 설명해 드리자면 intersectray의 결과값을 보면 (ray [-1.62331,11.1008,1.22501] [-0.407511,-0.107746,0.906822]) 요런 식으로 ray 의 형식으로 결과가 나옵니다. ray 는 pos 와 dir 의 속성이 있지 않습니까?? 여기서 결과값의 pos 정보가 바로 부딧힌 면의 위치 정보가 됩니다. 그 뒤에 나오는 [-0.407511,-0.107746,0.906822] 는 부딪힌 면의 normal 값으로 만약 공이 부딪힌 다음 튕겨나간다거나 하는 다음 동작이 필요하다면 반드시 필요한 정보이지요.

어쨌든 intersectray 만 보자면 부딪힌 위치와 각도를 ray 의 형태로 돌려준다는 것을 알 수 있었습니다. 특징이라 하면 , 특정 개체를 대상으로 하기 때문에 속도가 매우 빠릅니다. 사실상 성능을 고려하지 않아도 되는 함수죠.

그런데 만약 부딪힌 면이 어디인지 알아야 하고 부딪힌 개체에도 뭔가 추가적인 액션이 필요할 수 있겠습니다. 사람일은 모르는거자나요? 누군가는 저 지형개체에 어떤 face에 물체가 부딪혔는지를 알아야 할수도 있지 않겠습니까? 이 때 intersectrayex 라는 함수를 이용하게 됩니다.

이번에는 intersectray 대신에 intersectrayex 를 사용해 볼 겁니다. 사용방법은 동일하고요. intersectrayEx [node] [ray] 와 같이 사용해 주면 됩니다.

-- intersectray 를 이용하여 지형과 부딪히는 위치를 찾아내자
interResult = intersectrayex tern myRay

-- 어떤 결과가 나왔는지 print 를 이용해서 살펴보자
print(interResult)

-- 결과는? 
#((ray [-1.62331,11.1008,1.22501] [-0.382998,-0.128105,0.914823]), 240, [0.383149,0.282177,0.334673])

아까와는 결과가 조금 다르죠? #(oo,oo,oo) 형태로 나온걸 보면 배열로 결과가 나온걸 알 수 있습니다. 총 3개의 리턴값이 나왔는데요.

  • (ray [-1.62331,11.1008,1.22501] [-0.382998,-0.128105,0.914823])
  • 240
  • [0.383149,0.282177,0.334673]

intersectray 와 마찬가지로 첫번째 결과에는 부딪힌 면의 위치, 방향을 담는 ray 정보가, 두번째에는 어떤 숫자가 나왔고요, 세번째에는 point3 형식으로 좌표가 나왔는데, 딱보니 위에 ray 에 부딪힌 면의 방향이라는 것을 알 수 있겠습니다. 두번째 숫자는 뭐냐고요?

부딪힌 face 의 index 임을 알 수 있다.

바로 부딪힌 mesh 의 face 인덱스 입니다. 240 번이죠? 바로 저부분에 부딪힌 것 입니다. (이번에는 이동은 하지 않았기 때문에..) 만약 동일하게 이동해야 한다면 배열 안의 개체에서 위치 정보를 뽑아내야 하므로 interResult[1].pos 와 같은 방법으로 부딪힌 면의 위치를 가져오면 됩니다.

이런 기능을 이용해서 부딪힌 면의 색상을 바꾸어 준다거나 해당 face를 삭제하는 등의 기능을 넣을 수 있겠지요? 뭐 레이저총에 맞은 face 가 폭파되며 사라지는 등의...  네.. 그럴때 꼭 필요한 훌륭한 명령어 입니다.

참고로 intersectray 나 intersectrayex 는 mesh 오브젝트에서 정확한 정보를 받아 올 수 있습니다. 가끔 기본 primatine 에 modifier 로 edit_poly 같은것을 씌운 경우에는 동작하지 않을 수 있으니 만약 결과값이 undefined 와 같은 값이 나온다면 검출에 사용된 모델링을 mesh 로 변경한 뒤 (convertTomesh obj) 검사를 진행하시면 됩니다.

 

끝으로 intersectRayScene 은 위와는 다르게 Ray 가 어떤 개체에 부딪히는지 알수 없을 때 사용합니다.

모두 동일하고 해당 명령만 intersectRayScene 으로 변경해서 돌려볼까요?

interResult = intersectrayScene myRay

요렇게 말이죠. 이번에는 대상을 특정하지 않기 때문에 함수 뒤에 인자가 ray 개체 하나만 들어갔습니다. 

결과를 볼까요? 

#(#($Editable_Mesh:terrain_01 @ [-4.616531,-2.612816,0.000000], (ray [-1.62331,11.1008,1.22501] [-0.382998,-0.128105,0.914823])), #($Sphere:Sphere001 @ [-1.623309,11.100846,65.260162], (ray [-1.62331,11.1008,61.9389] [0,0,-1])), #($Box:Box001 @ [15.646946,18.567043,19.666662], (ray [-1.62331,11.1008,26.4499] [0,0,1])))

뭔가 무시무시하게 길게 나왔죠?

이녀석도 역시 배열 개체이므로 하나씩 보면 

#($Editable_Mesh:terrain_01 @ [-4.616531,-2.612816,0.000000], (ray [-1.62331,11.1008,1.22501] [-0.382998,-0.128105,0.914823]))
#($Sphere:Sphere001 @ [-1.623309,11.100846,65.260162], (ray [-1.62331,11.1008,61.9389] [0,0,-1]))
#($Box:Box001 @ [15.646946,18.567043,19.666662], (ray [-1.62331,11.1008,26.4499] [0,0,1]))

요렇게 3개의 개체와 부딪혔다는 정보를 돌려준 것을 알 수 있습니다. 심지어는 본인(sphere) 에도 부딪힌 정보를 돌려 받았다는 것을 알 수 있네요 ㄷㄷㄷ. (저걸 원한건 아닌데) 부딪힌 정보를 보면 역시 내부 정보 역시 배열인데요, 첫번째는 부딪힌 대상 개체, 두번째는 부딪힌 위치정보 (ray 속성) 라는걸 알 수 있습니다.

만약 개체에 어떤 특정할만한 속성이 있다면 해당 개체에 물체를 위치 시킬 수 있습니다.

-- ray 를 생성해 준다
myRay = ray [0,0,0] [0,0,-1]

-- 이동시킬 물체를 지정하자
obj = $Sphere001

-- ray 의 출발 위치를 물체의 중심으로 설정해보자
myRay.pos = obj.pos

-- 위치 검출에 사용될 지형을 지정해보자
tern = $terrain_01

-- intersectray 를 이용하여 지형과 부딪히는 위치를 찾아내자
interResult = intersectrayScene myRay

-- 어떤 결과가 나왔는지 print 를 이용해서 살펴보자
print(interResult)

for i = 1 to interResult.count do
(
	testObj = interResult[i][1]
	if (findString testObj.name "Box") != undefined then
	(
		obj.pos = interResult[i][2].pos
	)
)

요렇게요. 

코드에서는 Box 라는 이름을 포함하는 개체를 만나면 해당 개체에 위치하도록 하는 코드 입니다.

이게 사실 한두개일 때는 간단한 이야기 인데 지면에 위치 시켜야 하는 개체가 수십개 ~ 수백개가 되면 일이 커집니다. 그럴때는 스크립트가 필요한 시점인거죠.

예를 들면 이렇게요..

이 많은 공들을 지면에 붙이라고?

 

모두 sphere 라는 이름을 갖고 있기때문에 간단하게 처리할 수 있겠네요. 지면에 닿는 개체는 지면에 닿도록 하고 box 에 닿는 개체는 box 에 위치시키도록 하겠습니다. 

sphere 의 중심을 기준으로 하다보니 약간 파뭍히는 대상이 있었는데요, sphere 의 반지름 만큼 위쪽으로 위치하도록 코드를 짜 보겠습니다.

-- ray 를 생성해 준다
myRay = ray [0,0,0] [0,0,-1]

-- 이름이 sphere 로 시작되는 모든 개체를 변수 objs 에 담자.
objs = execute("$Sphere*")

for obj in objs do
(
	-- 각 sphere 의 중심점으로 ray 의 위치를 지정함
	myRay.pos = obj.pos
	
	-- intersectray 를 이용하여 지형과 부딪히는 위치를 찾아내자
	interResult = intersectrayScene myRay


	for i = 1 to interResult.count do
	(
		testObj = interResult[i][1]
		if (findString testObj.name "Box") != undefined then
		(
			obj.pos = interResult[i][2].pos
			-- 파묻히지 않도록 반지름 만큼 위로 올림
			obj.pos.z += obj.radius
		)
		else if (findString testObj.name "terrain") != undefined then
		(
			--- 부딪힌 정보가 terrain 일때 해당 위치로 이동 시킴 
			obj.pos = interResult[i][2].pos
		-- 파묻히지 않도록 반지름 만큼 위로 올림
			obj.pos.z += obj.radius
		)
	)
)

 

뭐 별거 없죠? 위에서 설명한 것을 반복문만 추가했을 뿐 입니다.

결과는요?

한번에 모두 지면에 안착 성공

요렇게 예쁘게 안착된 것을 확인 할 수 있습니다.

물론 저는 본 기능을 설명 드리기 위해 위와 같은 예제를 들었지만요. 실제 제가 사용하는 함수에는 몇초만에 수천번 이상 위치를 검출하며 ray 가 사용되는 케이스가 허다분 합니다.

저는 주로 자동으로 모델링을 할때 모델링의 위치, 크기, 배치, 부딪힘, 확장 범위 등을 검사할때 사용하는데요, 이런 검사들을 통해 사람이 손을 데지 않고도 아주 정교한 모델링을 할 수 있는 근간이 됩니다.

참고로 intersectRayScene 의 경우 scene 의 모든 개체에 대하여 검사가 이루어지기 때문에 Scene 내에 아주 많은(수만개 이상의) node 들이 자리잡고 있는 경우에는 속도가 매우 느려질 수 있습니다. 그래서 시작 위치를 기준으로 반경내에 들어오는 대상을 먼저 골라낸 다음 속도가 빠른 intersectRay 를 이용하여 각각 부딪힌 위치를 검출하는 방식으로 사용하고 있습니다. 프로그래밍이라는게 그렇자나요. ㅎ 높은 성능과 효율성을 위해 다양하고 창의적인 방법으로 접근해 가는게 바로 프로그래밍의 묘미이지요.

오늘은 이만 마칩니다. 내용이 길어기니 힘드네요 ㅋ

2021.03.24 - [DEV/MAX SCRIPT] - 3DS MAX 스크립트 레퍼런스 (헬프파일) 다운 받기

 

3DS MAX 스크립트 레퍼런스 (헬프파일) 다운 받기

스크립트 초급자든 중급자든 반드시 필요한 것 하나를 꼽으라면 저는 레퍼런스라고 생각합니다. 기존에는 3DS MAX 설치 시에 함께 설치되어 스크립트 작성 창에서 F1 키를 누르면 chm 파일 형식의

diy-dev-design.tistory.com

2021.02.24 - [DEV/MAX SCRIPT] - 3da max script 점과 점 사이의 거리 구하기

 

3da max script 점과 점 사이의 거리 구하기

간단하게 포스팅을 남기려고 합니다. 제목 그대로 버텍스 간 거리 구하기 입니다. 아니 정확히는 두개의 point3 사이의 거리를 구하는 방법을 소개해 드릴까 합니다. 그리고 용용 편으로 두 점사

diy-dev-design.tistory.com

2020.04.29 - [DEV/MAX SCRIPT] - 3DS MAX 스크립트로 개체 선택하기

 

3DS MAX 스크립트로 개체 선택하기

Max Script 를 이용하여 무엇인가를 하려면 필수 요소라고 할 수 있는 것 중의 하나가 개체를 선택하거나 지정하는 방법입니다. 여기서 개체는 3D Scene 안의 오브젝트, 스플라인, 헬퍼 등과 같은 사

diy-dev-design.tistory.com

 

반응형
반응형

키움증권에서는 API 를 제공하여 사용자가 자동매수, 매도를 할 수 있는 프로그램을 직접 개발할 수 있도록 제공하고 있습니다. 

키움증권 API 를 이용하여 시작하는 방법은 여러 포스트에서 이미 다루고 있으므로 별도로 다루지는 않을 예정입니다.

많이 어렵지 않으므로 관련 포스트를 따라서 하시면 손쉽게 시작하실 수 있으며 이미 샘플 c# 코드도 키움증권에서 배포하고 있으므로 일일이 내용을 작성하지는 않을 것이고요. 제가 인터넷에서 쉽게 구하지 못한 코드들을 올려보려 합니다.

오늘은 키움증권 API 가 제공하는 전체 종목코드를 받아오는 코드를 소개해 드릴까 합니다.

 

키움증권 API 가 동작하는 방식

  • 필요한 커맨드를 인자와 함께 전달한다.
  • API 는 서버에서 해당 정보를 내려받는다. (이벤트가 발생하는 경우가 있고 직접 결과를 리턴하는 경우가 있다)
    • 결과를 리턴하는 경우 : 바로 처리
    • 이벤트를 발생시키는 경우 : 이벤트 핸들러를 이용하여 함수로 구현하여 처리

대충 이런식인데요. 전체 종목 코드를 받아오는 것은 결과를 바로 리턴해주는 방식 입니다.

 

키움증권에서 배포하는 open API 가이드를 보면 아래와 같은 커맨드가 있음을 알 수 있습니다.

키움 openAPI 개발 가이드에 있는 커맨드 리스트

바로 14번에 해당하는 GetCodeListByMarket 에 해당하는 커맨드죠.

해당 커맨드의 상세한 항목은 아래와 같이 나와 있습니다.

제어함수 명세서에 나와있는 전체 종목 코드 받기 설명

문자열로 결과가 리턴되는 것을 알 수 있고, sMarket 부분에 필요한 주식시장의 종류를 넣을 수 있게 되어 있네요.

전 "장내"에 해당하는 항목을 알아보려 합니다.

바로 한번 구현을 해볼까요?

private AxKHOpenAPILib.AxKHOpenAPI axKHOpenAPI; // 키움 샘플이라면 이건 적을 필요 없음.

private void getAllCodeList()
{
  string codelistResult = axKHOpenAPI.GetCodeListByMarket("0"); // 0: 장내
  //종목간 구분은 ";" 로 한다고 하였으므로 아래와 같이 각각의 종목을 쪼개 줍니다.
  string[] mylist = codelistResult.Split(';');
  foreach (string s in mylist)
  {
      Console.WriteLine("종목코드 : " + s);
  }
}

간단하죠?

이렇게하고 getAllCodeList 함수를 실행해 보면 아래와 같이 출력창에 종목 코드가 출력됩니다.

종목 코드가 받아진 모습

 

그런데 이렇게 하면 전체 코드는 얻었지만 해당 코드가 어떤 종목인지 알수가 없잖아요?

그래서 몇줄 추가해 보겠습니다. 해당 코드의 종목 명칭과 전일가격을 출력해보도록 하겠습니다.

private void getAllCodeList(ref List<string> rList)
{
  rList.Clear();

  string codelistResult = axKHOpenAPI.GetCodeListByMarket("0");
  string[] mylist = codelistResult.Split(';');
  MessageBox.Show("전체 종목 수는 " + mylist.Length.ToString() + "개 입니다");
  foreach (string s in mylist)
  {   
 	rList.Add(s); // rList 에 종목 코드를 넣어준다. (최종 결과 반환용)
    string stName = axKHOpenAPI.GetMasterCodeName(s);    // 종목 명칭 얻기
    string lastPrice = axKHOpenAPI.GetMasterLastPrice(s);  // 종목 전일가 얻기
    Console.WriteLine("종목코드 : " + s + ", 종목 명:" + stName + ", 전일가 :" + lastPrice);
  }
}

몇 줄 추가를 하였습니다. 먼저 rList 라는 리스트를 참조 인자로 받아서 나중에 사용하려고 합니다. 이전 코드와 달라진점은 메시지 팝업으로 전체 종목수를 알려주는 것과 종목 명칭, 종목의 전일가격을 받는 커맨드를 추가하여 콘솔창에 좀더 직관적으로 가격을 보여주도록 한 것이 달라진 점 입니다.

이렇게 하면 출력창에는 아래와 같이 결과가 출력됩니다.

종목 코드와 종목명, 전일가를 한번에 출력해본 모습

어떠신가요? 좀 더 직관적으로 볼 수 있겠죠?

프로그램을 직접 만드는 만큼 재가 가지고 있는 관심 종목만 살펴보기 보다는 전체 종목들의 추이를 보면서 내가 발견하지 못한 좋은 종목을 컴퓨터에게 분석을 시켜보려고 하는데요. 그러기 위해서는 전체 종목을 자동으로 받아오는 함수가 반드시 필요할 것 같아서 구현해 보았습니다. 

 

다음번에는 이벤트 핸들러를 이용하여 결과값을 처리하는 방법을 소개해 드려 보도록 하겠습니다.

다들 돈 많이 버세요~ ㅋ

 

 

2020.08.11 - [DEV/c#] - [c#] streamreader 를 이용하여 정확한 라인 위치 찾기

 

[c#] streamreader 를 이용하여 정확한 라인 위치 찾기

c# 을 이용하여 streamreader 개체로 텍스트를 읽는 방법은 매우 효율 적이고 손쉽게 작업을 수행하도록 해줍니다. 빠르고 간단하게 개발을 할 수 있어 저도 자주 사용하고는 합니다. 그런데 이번에

diy-dev-design.tistory.com

2020.01.03 - [DEV/c#] - [C#] C# APP 에서 엑셀 연동해보기

 

[C#] C# APP 에서 엑셀 연동해보기

엑셀에서 VBA 로 코드를 짜다 보면 막상 특정 엑셀 파일에만 VBA 가 적용이 가능하기 때문에 막상 다른 엑셀 파일에서 동일한 동작을 하려면 또 코드를 복사해 넣고 실행을 해야 하는 경우가 있습

diy-dev-design.tistory.com

 

반응형
반응형

스크립트 초급자든 중급자든 반드시 필요한 것 하나를 꼽으라면 저는 레퍼런스라고 생각합니다. 기존에는 3DS MAX 설치 시에 함께 설치되어 스크립트 작성 창에서 F1 키를 누르면 chm 파일 형식의 레퍼런스 파일이 나타나 간편하게 사용을 했는데요. 언제부터인가 온라인 레퍼런스 사이트로 연결이 되기 시작했습니다.

내용상 큰 차이가 없더라도 매번 인터넷 페이지 안에서 검색하고 찾는 것보다 로컬에 저장되어 있는 chm 파일에서 찾고 검색하는 것이 훨씬 빠르고 쉽기 때문에 전느 chm 포멧의 레퍼런스를 선호하는 편입니다.

사실 autodesk 사이트에도 chm 파일을 배포하고 있는데 굳이 온라인 페이지로 연결 시켰는지 잘 이해가 가지 않는 부분입니다.

 

아래 경로에가시면 chm 형식으로 제작된 최신 레퍼런스 파일을 받으실 수 있으니 참고하시기 바랍니다.

www.autodesk.com/developer-network/platform-technologies/me-sdk-docs-2021

 

Media and Entertainment SDK Docs 2021 | Autodesk Developer Network

The Autodesk Media and Entertainment SDK page offers access to the latest documentation for the 2021 releases of the Autodesk Media & Entertainment SDKs. Use the links below to view the documentation in your browser, or to download the documentation to you

www.autodesk.com

위 페이지에 가셔서 아래 표시해 놓은 링크를 클릭하시면 로컬에 저장해 놓고 사용하실 수 있습니다.

빨간 박스 부분을 클릭하면 다운로드가 가능하다.

 

혹 해당 링크가 깨지는 경우를 대비하여 압축파일로도 업로드 해놓도록 하겠으니 아래 압축파일을 풀어 사용하시면 되겠습니다. 파일 4개를 모두 내려받으신 후 001 번을 압축해제 하시면 됩니다.

3dsmax-2021.1-maxscript-help-chm.zip.001
9.00MB
3dsmax-2021.1-maxscript-help-chm.zip.002
9.00MB
3dsmax-2021.1-maxscript-help-chm.zip.003
9.00MB
3dsmax-2021.1-maxscript-help-chm.zip.004
1.37MB

 

chm 파일은 파일 하나로 완전한 레퍼런스 북 입니다. 웹페이지에 비하여 색인도 훨씬 잘 되어 있고 로딩 시간도 필요치 않으며 오프라인 환경에서도 완벽하게 동작하는 훌륭한 녀석이라 할 수 있습니다.

스크립트 개발에 도움이 되시길 바랍니다.

 

감사합니다. 그럼 이만~

 

2021.03.03 - [DEV/MAX SCRIPT] - [3DS MAXscript] 스크립트 에디터 한글이 ??? 로 나오는 문제 해결 방법

 

[3DS MAXscript] 스크립트 에디터 한글이 ??? 로 나오는 문제 해결 방법

3DS MAX script 는 정말 훌륭한 개발 언어이지만 아쉬운점이 없는 것은 아닙니다. 대표적인 예가 바로 한글지원 문제인데요. 개발 코드 상에 한글이 지원되는건 바라지도 않습니다. 적어도 주석이라

diy-dev-design.tistory.com

2019.12.16 - [DEV/MAX SCRIPT] - 3DS MAX SCRIPT 강좌?? 무작정 시작하기 - 디자이너 추천

 

3DS MAX SCRIPT 강좌?? 무작정 시작하기 - 디자이너 추천

개발이라 하면 두드러기가 나는 디자이너 들이 있습니다. 아니 대부분 그렇죠. 이글을 읽고 계신 본인도 그러하다면, 그런데 스크립트로 무언가를 하고 싶다면 어쩌겠습니까.. 배워야지요. 그래

diy-dev-design.tistory.com

2019.06.12 - [DEV/Adobe Script] - 포토샵 스크립트 레퍼런스, 도움말 사용하기

 

포토샵 스크립트 레퍼런스, 도움말 사용하기

포토샵 스크립트 역시 다른 개발언어와 마찬가지로 도움말이 있습니다. 레퍼런스라고 해야할까요. 사실 개발자라고 해도 모든 명령어와 프라퍼티, 메소드를 외우고 있을 수는 없기 때문에 잘

diy-dev-design.tistory.com

 

반응형

+ Recent posts