VTK(2) - 듀얼 뷰, 작업 표시 및 연결

22471 단어 VTK
선언: 새로운 수요를 받다
window 단일 창 프로그램, 더블view, 표시 및 연결 작업은 두 가지 방식으로 이루어졌고 코드 사고방식과 원본 코드는 다음과 같다.

(1) 코드 사고방식


1. 누가 움직였는지 판정?
방법 1: 현재 이벤트의 창 위치를 창 크기 중심축과 비교
방법2: 이동한 카메라의 위치와 두 뷰의 카메라 위치를 비교한다
방법3: 현재renderer를 가져와 두 개의rendererer와 비교합니다
 
2. 사건을 어떻게 포획합니까?방법1: vtkCommand에서 리셋 Step1: 리셋 함수를 정의하고, vtkCommand Step2에서 리셋 함수를 설정합니다. Step3: 두 개의view 카메라에 관찰자를 추가합니다.AddObserver(vtkCommand: Modified Event,callback)를 통해 (그 중에서 Modified Event는 임의로 발생하는 이벤트를 수신할 수 있으며, 이벤트가 발생할 때interactor 밑에 Modified Event 이벤트가 호출되고,callback은 step1의 사용자 정의 리셋 함수임)
방법2: vtkInteractorStyleTrackballCamera 응답 이벤트 다시 쓰기 Step1: 사용자 정의 상호작용 형식, vtkInteractorStyleTrackballCamera Step2: OnMouseMove 다시 쓰기 () 등 방법
 
3. 어떻게 하나의view 변화에 따라 다른view를 설정합니까?방법1: 설정할 뷰의 카메라 상태를 변경된 카메라 상태로 설정합니다(vtk에서 이미지 변화는 기본적으로 카메라 이동 방식을 사용하기 때문에 여기서 actor 변화 방식을 논의하지 않습니다)(주: vtk의 카메라는 주로 세 가지 요소에 의해 결정됩니다. 1. 초점2. 카메라 위치3. 위로 방향)(또는 카메라를 직접 가져와서 변경하고 싶은 카메라 상태를 설정할 수도 있다) Step1: 변경할 카메라의 상태를 가져오고, GetPosition(), GetFocalPoint(), GetViewUp()를 통해 Step2: 변경할 카메라의 상태를 설정하고, SetPosition(), SetFocalPoint(), ViewUp()를 통해 설정합니다.
Step3: vtk Rendererer의 Reset Camera Clipping Range () 방법으로 그림의 법방향량을 초기화합니다 Step4: 신호가 동기화되지 않으면 vtk RenderWindow의 Render () 방법을 수동으로 호출해야 합니다.
방법2: 카메라 대상을 만들고 좌우 두 rendererer에 같은 카메라 대상을 추가합니다
방법3: 현재 카메라를 가져와서 두 개의renderer 카메라를 현재 카메라로 설정합니다
 
4. 같은 유형의 문제에 대한 사고?
하나view에서 두 개의actor는 마우스의 지향에 따라 다른 물체를 옮길 수 있다.(이것은 실현하기에 상대적으로 간단하다. vtk는 이미 만들어진 함수가 있다)
방법: vtkInteractorStyleTrackballActor의 상호작용 모드를 사용하면 실현할 수 있다

(2) 데모 원본 코드


 

첫 번째 구현 방법:


방법 설명:

  • 실현 방식: vtkCommand에서 리셋 리셋
  • 계승
  • 카메라 설정: 두 개의 Rendererer가 한 개의 카메라를 공용한다(주: 하나의camera를 사용하지 않고 두 개의 Renderererer를 설정할 때viewsation이 대칭적이지 않으면 상호작용이 나타날 수 있다. 처음에 두 카메라가 물체와 상대적인 위치를 동기화한다)
  • 연동함수: 현재 카메라와 좌우 두 카메라의 비교를 통해 어느 쪽이 움직였는지 판단하는 두 가지 판단방법
  • 포함
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    
    class myCallbackFunc:public vtkCommand
    {
    public:
        static  myCallbackFunc *New()
        {
            return new myCallbackFunc;
        }
        
        void SetLeftRender(vtkRenderer *leftRender)
        {
            this->m_leftRender = leftRender;
        }
        void SetRightRender(vtkRenderer *rightRender)
        {
            this->m_rightRender = rightRender;
        }
        
      
        virtual void Execute(vtkObject *caller, unsigned long eventId, void* callData)
        {
            vtkCamera *camera = reinterpret_cast(caller);
            vtkCamera *leftCamera = m_leftRender->GetActiveCamera();
            vtkCamera *rightCamera = m_rightRender->GetActiveCamera();
     
            double *act_position     = camera->GetPosition();
            double *act_FocalPoint   = camera->GetFocalPoint();
            double *act_ViewUp       = camera->GetViewUp();
          
            //   :    
            if (leftCamera == camera)
            {
                if (rightCamera->GetPosition() != act_position)
                {
                    rightCamera->SetPosition(act_position);
                }
                if (rightCamera->GetViewUp() != act_ViewUp)
                {
                    rightCamera->SetFocalPoint(act_FocalPoint);
                }
                if (rightCamera->GetViewUp() != act_ViewUp)
                {
                    rightCamera->SetViewUp(act_ViewUp);
                }
            }
            else if (rightCamera == camera)
            {
                if (leftCamera->GetPosition() != act_position)
                {
                    leftCamera->SetPosition(act_position);
                }
                if (leftCamera->GetViewUp() != act_ViewUp)
                {
                    leftCamera->SetFocalPoint(act_FocalPoint);
                }
                if (leftCamera->GetViewUp() != act_ViewUp)
                {
                    leftCamera->SetViewUp(act_ViewUp);
                }
            }
            
            //   :camera      
            
    //        if (    (isSame(act_position, leftCamera->GetPosition()))
    //              &&(isSame(act_FocalPoint, leftCamera->GetFocalPoint()))
    //              &&(isSame(act_ViewUp,leftCamera->GetViewUp())))
    //        {
    //            rightCamera->SetPosition(act_position);
    //            rightCamera->SetFocalPoint(act_FocalPoint);
    //            rightCamera->SetViewUp(act_ViewUp);
    //            this->m_rightRender->ResetCameraClippingRange();
    //        }
    //        else
    //        {
    //            leftCamera->SetPosition(act_position);
    //            leftCamera->SetFocalPoint(act_FocalPoint);
    //            leftCamera->SetViewUp(act_ViewUp);
    //            this->m_leftRender->ResetCameraClippingRange();
    //        }
                                   
        }
        
    //private:
        
    //    //           leftRender rightRender   
    //    static bool isSame(double *value0, double *value1) {
    //        bool result = true;
    //        for (int idx = 0; idx != 3; ++idx) {
    //            result = result && qFuzzyCompare(value0[idx], value1[idx]);
    //        }
    //        return result;
    //    }
        
    private:
        //    view,   view,     ,          
        vtkRenderer     *m_leftRender;
        vtkRenderer     *m_rightRender;
        
    };
    
    
    int main(int, char *[])
    {
    
        vtkSmartPointer                      cube        = vtkSmartPointer::New();
        vtkSmartPointer                  mapper      = vtkSmartPointer::New();
        vtkSmartPointer                           actor1      = vtkSmartPointer::New();
        vtkSmartPointer                           actor2      = vtkSmartPointer::New();
        vtkSmartPointer                        leftRender  = vtkSmartPointer::New();
        vtkSmartPointer                        rightRender = vtkSmartPointer::New();
        vtkSmartPointer                    renwindow   = vtkSmartPointer::New();
        vtkSmartPointer                          camera      = vtkSmartPointer::New();
        vtkSmartPointer          interactor  = vtkSmartPointer::New();
        vtkSmartPointer                     callback    = vtkSmartPointer::New();
        vtkSmartPointer  style       = vtkSmartPointer::New();
        
        
        cube->SetCenter(1, 1, 1);
        cube->Update();
    
        mapper->SetInputConnection(cube->GetOutputPort());
        
        actor1->SetMapper(mapper);
        actor1->GetProperty()->SetColor(.2, .3, .4);
        actor2->SetMapper(mapper);
        actor2->GetProperty()->SetColor(.4, .5, .6);
    
        double leftViewStation[4] = {0.0, 0.0, 0.4, 1.0};
        double rightViewStation[4] = {0.4, 0.0, 1.0, 1.0};
        
        leftRender->AddActor(actor1);
        leftRender->SetBackground(.6, .5, .4);
        leftRender->SetViewport(leftViewStation);
    
        rightRender->AddActor(actor2);
        rightRender->SetBackground(.2, .4, .6);
        rightRender->SetViewport(rightViewStation);
        
        camera->SetPosition(4, 4, 4);
        rightRender->SetActiveCamera(camera);
        leftRender->SetActiveCamera(camera);
        
        renwindow->AddRenderer(leftRender);
        renwindow->AddRenderer(rightRender);
        renwindow->SetSize(600, 300);
        renwindow->Render();
        
        callback->SetLeftRender(leftRender);
        callback->SetRightRender(rightRender);
    
        leftRender->GetActiveCamera()->AddObserver(vtkCommand::ModifiedEvent,callback);
        rightRender->GetActiveCamera()->AddObserver(vtkCommand::ModifiedEvent,callback);
        
        interactor->SetInteractorStyle(style);//             、  、     。 
        
        renwindow->SetInteractor(interactor);
        
        interactor->Initialize();
        interactor->Start();
        
        
        return EXIT_SUCCESS;
    }
    
    

    (스택 오버플로우 문제 해결됨)


     

    두 번째 구현 방법:


    방법 설명:

  • 실현 방식: vtkInteractorStyleTrackballCamera에서 계승, 로테이트 다시 불러오기()
  • 카메라 설정: 두 개의 Rendererer가 한 개의 카메라를 공용한다(주: 하나의camera를 사용하지 않고 두 개의 Renderererer를 설정할 때viewsation이 대칭적이지 않으면 상호작용이 나타날 수 있다. 처음에 두 카메라가 물체와 상대적인 위치를 동기화한다)
  • 연동 함수: 두 가지 방법이 포함되어 있다 ① 이벤트가 있는 창의 위치를 통해 어떤render가 움직이는지 판단한다 ② 현재 카메라를 가져오고 두 카메라를 이 카메라의 상태로 리셋한다
  • #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    class myInteractorStyle:public vtkInteractorStyleTrackballCamera
    {
    public:
    
        static myInteractorStyle* New()
        {
            return new myInteractorStyle;
        }
        
        void    SetLeftRender(vtkRenderer *render)
        {
            this->m_leftRender = render;
        }
        
        void    SetRightRender(vtkRenderer *render)
        {
            this->m_rightRender = render;
        }
    
        void Rotate()
        {
            vtkInteractorStyleTrackballCamera::Rotate();
            this->CameraSynchronous();
        }
    
    //****************       :                render     ************//
        void    CameraSynchronous()
        {
            vtkCamera *leftCamera = m_leftRender->GetActiveCamera();
            vtkCamera *rightCamera = m_rightRender->GetActiveCamera();
            
            //      
            int *winSize = this->GetInteractor()->GetRenderWindow()->GetSize();
            
            //        
            int eventStation[3];
            this->GetInteractor()->GetEventPosition(eventStation);
            
            if (eventStation[0] < winSize[0]/2)
            {
                rightCamera->SetPosition(leftCamera->GetPosition());
                rightCamera->SetFocalPoint(leftCamera->GetFocalPoint());
                rightCamera->SetViewUp(leftCamera->GetViewUp());
                m_rightRender->ResetCameraClippingRange();
            
            }
            else
            {
                leftCamera->SetPosition(rightCamera->GetPosition());
                leftCamera->SetViewUp(rightCamera->GetViewUp());
                leftCamera->SetFocalPoint(rightCamera->GetFocalPoint());
                m_leftRender->ResetCameraClippingRange();
                           
            }
            
            
            this->GetInteractor()->GetRenderWindow()->Render();
        }
        
        //****************       :       ,                  ************//
        //    void    CameraSynchronous()
        //    {
        //        vtkCamera *camera = this->GetCurrentRenderer()->GetActiveCamera();
        //        this->m_leftRender->SetActiveCamera(camera);
        //        this->m_rightRender->SetActiveCamera(camera);
        //    }
        
    private:
        vtkRenderer     *m_leftRender;
        vtkRenderer     *m_rightRender;
    
    
    
    };
    
    
    int main(int, char *[])
    {
    
        vtkSmartPointer              cube        = vtkSmartPointer::New();
        vtkSmartPointer          mapper      = vtkSmartPointer::New();
        vtkSmartPointer                   actor1      = vtkSmartPointer::New();
        vtkSmartPointer                   actor2      = vtkSmartPointer::New();
        vtkSmartPointer                leftRender  = vtkSmartPointer::New();
        vtkSmartPointer                rightRender = vtkSmartPointer::New();
        vtkSmartPointer                  camera      = vtkSmartPointer::New();
        vtkSmartPointer            renwindow   = vtkSmartPointer::New();
        vtkSmartPointer  interactor  = vtkSmartPointer::New();
        vtkSmartPointer          style       = vtkSmartPointer::New();
        
        cube->SetXLength(1);
        cube->SetYLength(1);
        cube->SetZLength(1);
        cube->Update();
        
        
        mapper->SetInputConnection(cube->GetOutputPort());
        
        
        actor1->SetMapper(mapper);
        actor1->GetProperty()->SetColor(.2, .3, .4);
        
        actor2->SetMapper(mapper);
        actor2->GetProperty()->SetColor(.4, .5, .6);
    
        double leftViewStation[4] = {0.0, 0.0, 0.4, 1.0};
        double rightViewStation[4] = {0.4, 0.0, 1.0, 1.0};
        
        leftRender->AddActor(actor1);
        leftRender->SetBackground(.6, .5, .4);
        leftRender->SetViewport(leftViewStation);
    
        rightRender->AddActor(actor2);
        rightRender->SetBackground(.2, .4, .6);
        rightRender->SetViewport(rightViewStation);
    
        
        camera->SetPosition(4, 4, 4);
        rightRender->SetActiveCamera(camera);
        leftRender->SetActiveCamera(camera);
        
        
        renwindow->AddRenderer(leftRender);
        renwindow->AddRenderer(rightRender);
        renwindow->SetSize(600, 300);
        renwindow->Render();
        
        style->SetLeftRender(leftRender);
        style->SetRightRender(rightRender);
        
        interactor->SetInteractorStyle(style);
        
        renwindow->SetInteractor(interactor);
        
        interactor->Initialize();
        interactor->Start();
        
        
        return EXIT_SUCCESS;
    }
    

     


    (3) 전체 원본(공정에서 사용)


     

    기능 설명:


    1. 하나의 창에 4개의view가 있어 두 개의 연결을 실현한다
    2. vtkInteractor Style Trackball Camera에서 계승하여 Rotate () 방법을 다시 썼습니다
    3. 인터페이스로서 연동 증가, 연동 삭제 기능 제공
    4. 주: 아래 두 개의 비연동은 삭제 방법을 통해 연동을 삭제한 것이다
    소스 코드는 다음과 같습니다.
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    
    
    #define vSP vtkSmartPointer
    
    typedef QMap, vSP> RenderMap;
    
    class myInteractorStyle:public vtkInteractorStyleTrackballCamera
    {
    public:
        static myInteractorStyle* New()
        {
            return new myInteractorStyle;
        }
        
        void    SetRenderPair(vSP render1, vSP render2)
        {
            do
            {
                if (render1 == nullptr)
                {
                    break;
                }
                if (render2 == nullptr)
                {
                    break;
                }
                
                this->m_renderMap[render1] = render2;
                this->m_renderMap[render2] = render1;
       
            }while(false);
            
        }
        void    RemoveRenderPair(vSP render1, vSP render2)
        {
            do
            {
                if (!this->m_renderMap.contains(render1))
                {
                    break;
                }
                if (!this->m_renderMap.contains(render2))
                {
                    break;
                }
                if (render1 != this->m_renderMap.value(render2, nullptr))
                {
                    break;
                }
                if (render1 == nullptr)
                {
                    break;
                }
                if (render2 == nullptr)
                {
                    break;
                }
                
                this->m_renderMap.remove(render1);
                this->m_renderMap.remove(render2);
                
            }while(false);
            
        }
        
    
        void Rotate()
        {
            vtkInteractorStyleTrackballCamera::Rotate();
            this->CameraSynchronous();
        }
            
    public:
        void    CameraSynchronous()
        {
            vSP curRender    = this->GetCurrentRenderer();
            vSP   curCamera    = curRender->GetActiveCamera();
            
            if (this->m_renderMap.contains(curRender))
            {
                vSP linkRender = this->m_renderMap.value(curRender, nullptr);
                if (linkRender != nullptr)
                {
                    linkRender->SetActiveCamera(curCamera);
                }
                
            }
        }
                
    private:
        RenderMap         m_renderMap;
    
    };
    
    class Client
    {
    public:
        Client()
        {
            this->Init();
            this->setCube();
            this->setMapper();
            this->setActor();
            this->setRender();
            this->setRenderWindow();
            this->setStyle();
            this->setInteractor();
            this->start();
        }
        
        void    Init()
        {
            this->m_cube            = vtkSmartPointer::New();
            this->m_mapper          = vtkSmartPointer::New();
            this->m_actor1          = vtkSmartPointer::New();
            this->m_actor2          = vtkSmartPointer::New();
            this->m_leftRender      = vtkSmartPointer::New();
            this->m_rightRender     = vtkSmartPointer::New();
            this->m_leftRender2     = vtkSmartPointer::New();
            this->m_rightRender2    = vtkSmartPointer::New();
            this->m_renwindow       = vtkSmartPointer::New();
            this->m_interactor      = vtkSmartPointer::New();
            this->m_style           = vtkSmartPointer::New();
        }
        
        void    setCube()
        {
            m_cube->SetXLength(1);
            m_cube->SetYLength(1);
            m_cube->SetZLength(1);
            m_cube->Update();
        }
        void    setMapper()
        {
            m_mapper->SetInputConnection(m_cube->GetOutputPort());
        }
        void    setActor()
        {
            m_actor1->SetMapper(m_mapper);
            m_actor1->GetProperty()->SetColor(.2, .3, .4);
            m_actor2->SetMapper(m_mapper);
            m_actor2->GetProperty()->SetColor(.4, .5, .6);
        }
        void    setRender()
        {
            m_leftRender->AddActor(m_actor1);
            m_leftRender->SetBackground(.6, .5, .4);
            m_leftRender->SetViewport(0.0, 0.5, 0.5, 1.0);
            
            m_leftRender2->AddActor(m_actor1);
            m_leftRender2->SetBackground(.6, .5, .4);
            m_leftRender2->SetViewport(0.0, 0.0, 0.5, 0.5);
            
            m_rightRender->AddActor(m_actor2);
            m_rightRender->SetBackground(.2, .4, .6);
            m_rightRender->SetViewport(0.5, 0.5, 1.0, 1.0);
            
            m_rightRender2->AddActor(m_actor2);
            m_rightRender2->SetBackground(.2, .4, .6);
            m_rightRender2->SetViewport(0.5, 0.0, 1.0, 0.5);
        }
        void    setRenderWindow()
        {       
            m_renwindow->AddRenderer(m_leftRender);
            m_renwindow->AddRenderer(m_rightRender);
            
            m_renwindow->AddRenderer(m_leftRender2);
            m_renwindow->AddRenderer(m_rightRender2);
            
            m_renwindow->SetSize(600, 600);
            m_renwindow->Render();
        }
        void    setStyle()
        {
            m_style->SetRenderPair(m_leftRender, m_rightRender);
            m_style->SetRenderPair(m_leftRender2, m_rightRender2);
            m_style->RemoveRenderPair(m_leftRender2, m_rightRender2);
        }
        void    setInteractor()
        {
            m_interactor->SetInteractorStyle(m_style);
        }
        void    start()
        {
            m_renwindow->SetInteractor(m_interactor);
            m_interactor->Initialize();
            m_interactor->Start();
        }
        
        
    private:
        vtkSmartPointer              m_cube;
        vtkSmartPointer          m_mapper;
        vtkSmartPointer                   m_actor1;
        vtkSmartPointer                   m_actor2;
        vtkSmartPointer                m_leftRender;
        vtkSmartPointer                m_rightRender;
        vtkSmartPointer                m_leftRender2;
        vtkSmartPointer                m_rightRender2;
        vtkSmartPointer            m_renwindow;
        vtkSmartPointer  m_interactor;
        vtkSmartPointer          m_style;
        
    };
    
    
    int main(int, char *[])
    {
        Client client;
        client.start();
    
        
        return EXIT_SUCCESS;
    }
    

    (기타 실현 방법과 사고방식은 보충을 환영한다)

    좋은 웹페이지 즐겨찾기