VTK 에서 vtkProp 은 화면에 그리고자 하는 사물의 위치와 회전 정보를 갖고 있다.
보통 Prop의 DataSet은 건드리지 않고 공간상의 위치와 회전을 변경하는 방식을 많이 사용하게 된다.
이때 고려해야 할 것들을 정리한다.
1. 1. vtkProp 기본 제어
Prop 의 원점과 위치 제어는 API 명령을 통해 쉽게 할 수 있다. Origin 과 Position 이 다른 것은 Origin은 나중에 Transform을 수행할 때의 Pivot 점으로 사용된다.
prop.SetOrigin(x,y,z);
prop.SetPosition(x,y,z);
회전은 Degree 값을 회전을 하는데 PostMultiply (상대축회전) 로는 RotZ->RotX->RotY 순으로 PreMultiply (절대축회전) 방식으로는 RotY -> RotX -> RotZ 순으로 회전한다.
PostMultiply는 상대축으로 앞에서 회전한 축의 좌표에 영향을 받아서 회전하며, PreMultiply의 경우는 회전 이전의 축을 기준으로 회전을 하는 것이다.
prop.SetOrientation(rotX,rotY,rotZ);
2.UserTransform
UserTransform은 Prop 에 입력한 Origin, Position, Orientation 을 계산하기 이전에 추가할 Transform 정보를 설정하는 것이다. UserTransform이 기본 제어 결과 값에서 추가적으로 UserTransform 값이 적용되는 것이 아님을 주의해야 한다.
만약에 Origin, Position, Orientation 제어를 하지 않는 경우에는 UserTransform 만으로 원하는 계산을 한번에 수행할 수 있다.
3. vtkProp Matrix 파헤치기
추후 업데이트 예정.
4. 구현 예시
4-1. 기본 제어 방법
기본 위치, 회전 제어 명령으로 값을 입력한다.
public void TestPropControl1()
{
vtkCubeSource cube = vtkCubeSource.New();
cube.Update();
vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
mapper.SetInputConnection(cube.GetOutputPort());
vtkActor actor = vtkActor.New();
actor.SetMapper(mapper);
var pos = new double[] { 3, 5, 0 };
var orient = new double[] { 90, 180, -45 };
actor.SetPosition(pos.ToIntPtr());
actor.SetOrientation(orient.ToIntPtr());
actor.GetProperty().SetColor(VtkColorUtils.GetNamedColor3d("Gold").ToIntPtr());
axesLength = 5;
renderer.AddActor(actor);
renderer.ResetCamera();
}
4-2. 기본 제어 방법
기본 제어 값으로 정해진 위치와 회전 값이 있고 그뒤에 추가적인 제어를 하는 방법이다.
외부의 제어에 의해 결정된 Matrix 값을 얻은 뒤에 Transform에서 Concatenate 한 뒤에 actor 의 위치, 회전 값을 갱신한다.
여기에서는 UserTransform 을 사용하는 방식은 맞지 않다.
public void TestPropControl2()
{
vtkCubeSource cube = vtkCubeSource.New();
cube.Update();
vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
mapper.SetInputConnection(cube.GetOutputPort());
vtkActor actor = vtkActor.New();
actor.SetMapper(mapper);
var pos = new double[] { 3, 5, 2 };
var orient = new double[] { 90, 180, -45 };
actor.SetPosition(pos.ToIntPtr());
vtkTransform xfm = vtkTransform.New();
xfm.SetMatrix(actor.GetMatrix());
xfm.RotateZ(orient[2]);
xfm.RotateX(orient[0]);
xfm.RotateY(orient[1]);
actor.SetOrientation(xfm.GetOrientation().ToIntPtr());
actor.GetProperty().SetColor(VtkColorUtils.GetNamedColor3d("SkyBlue").ToIntPtr());
axesLength = 5;
renderer.AddActor(actor);
renderer.ResetCamera();
}
4-3. UserTransformation 제어
Actor에는 아무런 제어 하지 않고 최종 계산된 위치와 회전 값을 UserTransform 값으로 입력한다.
public void TestPropControl3()
{
vtkCubeSource cube = vtkCubeSource.New();
cube.Update();
vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
mapper.SetInputConnection(cube.GetOutputPort());
vtkActor actor = vtkActor.New();
actor.SetMapper(mapper);
var pos = new double[] { 3, 5, 4 };
var orient = new double[] { 90, 180, -45 };
vtkTransform xfm = vtkTransform.New();
xfm.Translate(pos.ToIntPtr());
xfm.RotateZ(orient[2]);
xfm.RotateX(orient[0]);
xfm.RotateY(orient[1]);
actor.SetUserTransform(xfm);
actor.GetProperty().SetColor(VtkColorUtils.GetNamedColor3d("Red").ToIntPtr());
axesLength = 5;
renderer.AddActor(actor);
renderer.ResetCamera();
}