튜토리얼 6: 서비스 및 객체를 사용한 V2 인터페이스 작업 방법

튜토리얼 6: 서비스 및 객체를 사용한 V2 인터페이스 작업 방법 동영상에서는 VR에서 카메라, 뷰포인트 및 장면 플레이트를 사용하는 예제를 다룹니다.

예제 스크립트 다운로드

스크립트 예제로 이동

튜토리얼의 PDF 다운로드

동영상 캡션: 안녕하세요. VRED Pro를 위한 새로운 Python 튜토리얼에 오신 것을 환영합니다. 저는 크리스토퍼라고 하며 오늘은 새 API 버전 2에 대해 소개하고, 작업 방식이 다른 이유 및 사용 방법에 대해 이야기하겠습니다.

오토데스크는 API 버전 2를 출시하면서 VRED에서 Python 인터페이스 작업을 더욱 쉽게 수행할 수 있도록 위해 새로운 객체 모델을 도입했습니다. 이제 서비스 클래스라고 불리는 중요한 기능으로 전환하여 더 많은 객체 지향 데이터 유형을 제공합니다. 새 버전이 좋은 이유를 이해하려면 먼저 이전 API의 단점부터 알아보아야 합니다.

다음 예제를 살펴보겠습니다. 버전 1 API는 일반적으로 별도의 값을 매개변수로 사용합니다. 예를 들어 단일 벡터의 X, Y, Z 값을 작업하는 경우에 적합합니다. 그러나 함수에 여러 개의 벡터 또는 벡터 구성요소가 있을 경우에는 매우 혼란스러울 수 있습니다. 더 좋은 방법은 이러한 매개변수를 벡터와 같이 필요한 것을 명확히 정의하는 객체로 캡슐화하는 것입니다. 반환 값의 경우도 마찬가지입니다.

API 버전 1에서는 반환 값이 벡터의 구성요소인 경우 단일 값 또는 값 목록을 반환하는 함수가 표시됩니다. 개발자는 이 반환 값 목록이 무엇인지 알기 위해 함수의 반환 유형을 알아야 합니다. 함수가 벡터처럼 단일 객체를 반환하는 경우 바로 인식 가능합니다.

API 버전 1의 또 다른 단점은 Python 2.7을 기반으로 한다는 점입니다. Python 2.7이 잘못된 릴리스는 아니지만 Python 3을 사용하면 완전히 정적으로 형식화된 API를 훨씬 쉽게 제공할 수 있습니다. 동적 유형이 필요한 때가 있기는 하지만 정적 유형으로 일관된 API를 작성하는 것이 더 쉽습니다.

제가 보기에 API 버전 2는 많은 부분을 개선해 줍니다. 먼저, VRED와 상호 작용하기 위한 기본 게이트웨이 역할을 하는 몇 가지 특수 서비스 클래스가 도입되었습니다. vrNodeService 또는 vrSessionService 같은 서비스에는 해당 특정 주제에 대한 모든 기능이 결합되어 있습니다. 예를 들어 세션 서비스에는 공동 작업 세션을 관리하는 함수가 포함됩니다. 카메라 서비스를 사용하면 카메라와 뷰포인트를 관리할 수 있습니다. 이 경우 적절한 함수를 훨씬 더 쉽게 찾을 수 있습니다. 예를 들어 모든 카메라 관련 기능은 이제 vrCameraService와 새 카메라 유형인 vrdCameraNodevrdCameraBaseNode에 위치하고 있기 때문입니다.

새 API에서는 데이터 조각의 기능을 캡슐화하는 다양한 데이터 유형이 도입되었습니다. 이러한 새 유형에는 모두 "vrd"라는 접두사가 붙습니다. 예를 들어 방금 설명한 것처럼 vrdCameraNode에는 장면의 카메라에 대한 모든 정보가 들어 있습니다. 마찬가지로, vrdSessionUser 유형의 객체는 공동 작업 세션에서 특정 사용자에 대한 모든 정보를 보유합니다.

각각의 새 유형에는 객체의 데이터를 추가하거나 변경할 수 있는 함수가 포함됩니다. 따라서 초점 길이와 같은 카메라의 설정을 변경하려면 먼저 vrCameraService에서 vrdCameraNode 유형의 객체를 가져온 다음 setFocalLength 함수를 사용하여 설정을 변경해야 합니다. VRED에는 모든 종류의 데이터에 대해 여러 가지 새로운 유형이 있는데 여기서 모두 설명할 수는 없습니다. 예를 들면 장면에서 포인트 라이트 소스를 조작하는 데 필요한 기능을 정확하게 제공하는 vrdPointLightNode가 있습니다.

또 다른 장점은 새 API 버전 2와 함께 제공되는 다른 지원 데이터 유형의 범위입니다. 벡터 데이터 유형에 대해서는 이미 언급했습니다. 이 유형은 이제 벡터로 명확하게 레이블이 지정된 별도의 숫자를 결합합니다. 따라서 코드를 훨씬 더 쉽게 읽고 이해할 수 있습니다. 각 개발자는 이 함수가 벡터 입력을 기대하고 다른 함수는 벡터를 반환한다는 것을 즉시 인식할 수 있습니다. 또 다른 장점은 이러한 새 데이터 유형을 수학 연산에 사용하여 직관적으로 작업할 수 있다는 점입니다. 몇 가지 예제를 살펴보겠습니다.

먼저, 새로운 서비스의 기본적인 사용법을 살펴보겠습니다. 사용하는 데 어려운 점이 전혀 없습니다. 이 예제에서는 vrCameraService를 사용한 카메라 작업 방법에 대해 살펴봅니다. 먼저 장면에 새 카메라를 생성해 보겠습니다. vrCameraServicecreateCamera 함수를 사용하고 이름을 지정합니다. 이 함수의 반환 값은 변수에 할당한 vrdCameraNode입니다.

이제 이 카메라 노드 객체를 사용하여 새 카메라 트랙을 생성할 수 있습니다. 이 작업은 vrCameraServicecreateCameraTrack 함수로 수행합니다. 이번에는 반환 값이 vrdCameraTrack 객체이며 역시 변수에 저장됩니다.

이 값을 더 회전하고 이 카메라 트랙에 새 뷰포인트를 생성할 수 있습니다. “camera service”에서 createViewpoint 함수를 사용하고 카메라 트랙 객체를 입력 매개변수로 사용하기만 하면 됩니다. 카메라 편집기를 보면 생성한 모든 객체를 확인할 수 있습니다.

다음 예제에서는 장면에 라이트 소스를 몇 개 생성하려고 합니다. 다시 vrLightService와 해당 함수 createLight를 사용합니다. 이번에는 이름과 라이트 유형을 입력 매개변수로 제공해야 합니다.

API 버전 2에는 일종의 정렬 유형이 포함된 클래스도 포함되어 있습니다. 이 경우 vrLightType 포인트 라이트가 필요합니다. 이러한 유형을 이 동영상 앞부분에서 설명한 데이터 유형과 혼동하지 마십시오. 새 API에서 "type"으로 끝나는 모든 클래스는 고유한 항목 또는 유형 집합을 정의합니다. 예를 들어 라이트는 포인트 라이트, 스포트 라이트, 디렉셔널 라이트 유형이 될 수 있습니다. 이 유형을 사용하여 라이트 서비스에서 어떤 종류의 라이트를 생성할지 지정할 수 있습니다.

카메라 예제에서 우리는 이미 몇 가지 새로운 "vrd 객체"를 확인했습니다. 이 예제로 돌아오면 카메라 서비스를 사용하여 새 객체를 생성할 수 있을 뿐 아니라 생성한 카메라, 카메라 트랙 및 뷰포인트를 변경할 수도 있습니다.

먼저 카메라의 위치를 변경하려고 합니다. 이 작업은 카메라가 있어야 하는 위치, 카메라가 바라보는 지점, 장면에서 "위쪽"의 위치를 알려 주는 방향을 정의하여 수행할 수 있습니다. 정의한 벡터를 제공하는 fromAtUp 데이터 유형을 사용하여 이러한 값을 설정합니다. 이렇게 하면 카메라가 장면의 중심에 배치됩니다. 그런 다음 카메라를 활성화하여 결과를 즉시 확인할 수 있습니다.

물론 다른 객체도 유사한 방식으로 변경할 수 있습니다. 예를 들어 createPreview() 함수를 사용하여 뷰포인트의 미리보기를 업데이트할 수 있습니다. 그러면 현재 장면에서 뷰포인트의 새 미리 보기가 만들어집니다.

마지막 예제에서 새 데이터 유형으로 작업을 더 쉽게 수행할 수 있는 방법을 알려드리겠습니다. 앞으로 나올 동영상에서 보다 상세한 튜토리얼을 제공할 것이므로 지금 너무 깊게 다루지는 않겠습니다. 새로운 벡터 유형을 사용하여 어떻게 벡터 구성요소를 캡슐화하고 전체 스크립트를 보다 읽기 쉽고 간략하게 만들 수 있는지만 살펴보겠습니다.

오른쪽에서 몇 가지 형상을 생성하고 3D 공간에서 형상의 위치를 설정합니다. 왼쪽에는 API 버전 1의 함수로 스크립팅된 동일한 예제가 있습니다. 제가 보기에는 훨씬 더 읽기 쉽고 이해하기 쉽습니다. 벡터 유형에서 제공하는 수학 연산을 사용하여 스크립트를 더 짧게 만들 수도 있습니다.

설명서의 마지막 참고 사항입니다. 설명서에서 버전 2로 대체된 버전 1의 모든 함수를 확인할 수 있습니다. 이러한 함수는 "더 이상 사용되지 않는 함수(deprecated)"로 분류됩니다. 즉, 기본적으로 이러한 함수를 계속 사용할 수는 있지만 이후에 제거하거나 대체할 수 있음을 의미합니다.

예를 들어 버전 2에서는 vrCamera에 포함된 거의 모든 함수가 현재 vrCameraService, vrdCameraNode 또는 vrdCameraBaseNode에 포함된 함수로 대체되었습니다. 새 스크립트를 작성할 때는 더 이상 사용되지 않는 함수를 사용하지 마십시오. 작동하기는 하지만 새로운 API를 사용하는 편이 안전합니다. 페이지 상단을 보면, 이 기능이 포함된 버전 2의 클래스를 가리키는 링크도 있습니다.

오토데스크는 API 버전 2를 통해 VRED의 Python 인터페이스에 새롭고 흥미로운 변경 사항을 도입했습니다. 스크립트 작성에 익숙하다면 새로운 클래스 및 데이터 유형을 사용하는 데 아무런 문제가 없습니다. 이제 막 시작하는 단계라면 시작하는 데 도움이 되었으면 합니다. 오늘은 이것으로 마치겠습니다. 이 동영상이 도움이 되셨기를 바랍니다. 다음에 또 뵙겠습니다.


샘플 Python 코드

튜토리얼 6: 서비스 및 객체를 사용한 V2 인터페이스 작업 방법 동영상과 함께 제공되는 예제 Python 스크립트입니다.

팁:

이러한 파일을 압축하여 다운로드하려면 여기를 클릭하십시오.

camera.py

import math

# Example 1.0
# Get active camera with vrCameraService
camera = vrCameraService.getActiveCamera()

# Set Focal Length
camera.setFocalLength(35)


# Example 2.0
# Creating a camera using API v1 and settings its fov to 35
vrCamera.selectCamera("Perspective")
camera_v1 = vrCamera.getActiveCameraNode()

# read field of view mode (0 := vertical, 1 := horizontal)
fov_mode = camera_v1.fields().getUInt32("fovMode")
sensor_size = camera_v1.fields().getVec("sensorSize", 2)

# calculate fov based on sensor size
fov = vrOSGWidget.getFov()
focal_length = 35

if fov_mode is 0:
    fov = 2 * math.degrees(math.atan((sensor_size[1] / 2) / focal_length))
else:
    fov = 2 * math.degrees(math.atan((sensor_size[0] / 2) / focal_length))

vrOSGWidget.setFov(fov)


# Example 3.0
# Creating a camera using API v2 and calculating the fov manually
camera_v2_1 = vrCameraService.createCamera("Camera v2_1")

# read field of view mode (vertical or horizontal)
fov_mode = camera_v2_1.getFovMode()

# read sensor size as QtVector2D
sensor_size = camera_v2_1.getSensorSize()

# calculate fov based on sensor size
fov = camera_v2_1.getFov()
focal_length = 50

if fov_mode is vrCameraTypes.FovMode.Vertical:
    fov = 2 * math.degrees(math.atan((sensor_size.y() / 2) / focal_length))
else:
    fov = 2 * math.degrees(math.atan((sensor_size.x() / 2) / focal_length))

camera_v2_1.setFov(fov)

light.py

# Example 1

# Get vrdPointLightNode with the vrLightService
myPointLight = vrLightService.findLight("MyPointLight")

# Set the ground shadow intensity
myPointLight.setGroundShadowIntensity(0.5)

service.py

#Example 1

# Get the active camera from the camera service
camera = vrCameraService.createCamera("My New Camera")

# Create a new camera track on the camera object
cameraTrack = vrCameraService.createCameraTrack("My New Camera Track", camera)

# Create a new viewpoint on the camera track
viewpoint = vrCameraService.createViewpoint("My New Viewpoint", cameraTrack)


#Example 2

# Create a new pointlight with the vrLightService
newPointLight = vrLightService.createLight(
                    "My New PointLight",
                    vrLightTypes.LightType.Point
                )

# Set the translation of this pointlight                               
newPointLight.setTranslation(QVector3D(0,0,1000))


#Example 3

# Create a new camera with the vrCameraService
camera = vrCameraService.createCamera("New Camera")

# Create vectors that define the location and look-at point of the camera
cameraFrom = QVector3D(5000, 8000, 3000)
cameraAt = QVector3D(0, 0, 0)
cameraUp = QVector3D(0, 0, 1)

# Set the camera parameters
fromAtUp = vrCameraFromAtUp(cameraFrom, cameraAt, cameraUp)
camera.setFromAtUp(fromAtUp)

# Activate the camera
camera.activate()


# Create a new camera track on the camera object
cameraTrack = vrCameraService.createCameraTrack("My New Camera Track", camera)

# Create a new viewpoint on the camera track
viewpoint = vrCameraService.createViewpoint("My New Viewpoint", cameraTrack)

viewpoint.createPreview(True)