<commit_before>#include "shaderApp.h"

//--------------------------------------------------------------
void shaderApp::onVideoEnd(ofxOMXPlayerListenerEventData& e)
{
	ofLogVerbose(__func__) << " RECEIVED";
	bVideoPlaying=false;
}

//--------------------------------------------------------------
void shaderApp::setup()
{
	//ofSetLogLevel(OF_LOG_VERBOSE);
	ofSetLogLevel("ofThread", OF_LOG_SILENT);
	ofSetVerticalSync(false);
	ofEnableAlphaBlending();
	ofSetFullscreen(true);

	doDrawInfo = false;

	OMXCameraSettings omxCameraSettings;
	omxCameraSettings.width = 640;
	omxCameraSettings.height = 480;
	omxCameraSettings.framerate = 30;
	omxCameraSettings.isUsingTexture = true;

	videoGrabber.setup(omxCameraSettings);

	shader.load("shaderExample");

	ofLogNotice() << "Allocating FBOs";
	camFbo.allocate(omxCameraSettings.width, omxCameraSettings.height);
	camFbo.begin();
		ofClear(0, 0, 0, 0);
	camFbo.end();

	overlayFbo.allocate(omxCameraSettings.width, omxCameraSettings.height);
	overlayFbo.begin();
		ofClear(0, 0, 0, 0);
	overlayFbo.end();

	cout << "listening for osc messages on port " << PORT << "\n";
	receiver.setup(PORT);

	ofLogNotice() << "Loading fonts";
	font[0].loadFont("verdana.ttf", 120);
	font[1].loadFont("verdana.ttf", 48);

	ofLogNotice() << "Listing filters";
	for(map<string, OMX_IMAGEFILTERTYPE>::iterator it = OMX_Maps::getInstance().imageFilters.begin();
				it!=OMX_Maps::getInstance().imageFilters.end(); ++it) {
        	ofLogNotice() << (*it).first;
   	}

	ofLogNotice() << "Listing videos";
	ofDirectory dir;
	dir.listDir("videos/");
	for(int i = 0; i < (int)dir.size(); i++){
		string path = dir.getName(i);
		ofLogNotice() << path;
	}

	bVideoPlaying = false;
}

//--------------------------------------------------------------
void shaderApp::update()
{
	bool textChanged = false;

	// check for waiting messages
	while(receiver.hasWaitingMessages()){
		// get the next message
		ofxOscMessage m;
		receiver.getNextMessage(&m);

		if(m.getAddress() == "/text"){
			lineOne = ofToString(m.getArgAsInt32(0));
			lineTwo = m.getArgAsString(1);
			textChanged = true;
		}

		if(m.getAddress() == "/filter") {
			string filterToUse = m.getArgAsString(0);
			for(map<string, OMX_IMAGEFILTERTYPE>::iterator it = OMX_Maps::getInstance().imageFilters.begin();
				it!=OMX_Maps::getInstance().imageFilters.end(); ++it)
			{
				string name = (*it).first;
				OMX_IMAGEFILTERTYPE filter = (*it).second;

				if (ofToLower(name) == ofToLower(filterToUse))  {
					currentFilter = filterToUse;
					videoGrabber.applyImageFilter(filter);
				}
			}
		}

		if(m.getAddress() == "/info") {
			int i = m.getArgAsInt32(0);
			doDrawInfo = i;
		}

		if(m.getAddress() == "/video") {
			string videoToPlay = m.getArgAsString(0);
			ofDirectory dir;
			dir.listDir("videos/");

			for(int i = 0; i < (int)dir.size(); i++){
				string name = dir.getName(i);
				if(name==videoToPlay) {
					ofLogNotice("!!!") << "playing " << name;

					string videoPath = ofToDataPath(dir.getPath(i), true);

					ofxOMXPlayerSettings settings;
					settings.videoPath = videoPath;
					settings.useHDMIForAudio = true;	//default true
					settings.enableTexture = true;		//default true
					settings.enableLooping = false;		//default true
					settings.enableAudio = true;		//default true, save resources by disabling
					settings.listener = this;
					//settings.doFlipTexture = true;		//default false

					//so either pass in the settings
					omxPlayer.setup(settings);

					currentVideo = name;
					bVideoPlaying = true;
				}
			}
		}

		if(m.getAddress() == "/tumblr") {
		}
	}

	if (videoGrabber.isFrameNew() && !bVideoPlaying)
	{
		camFbo.begin();
		ofClear(0, 0, 0, 0);
		shader.begin();
			shader.setUniformTexture("tex0", videoGrabber.getTextureReference(), videoGrabber.getTextureID());
			shader.setUniform1f("time", ofGetElapsedTimef());
			shader.setUniform2f("resolution", videoGrabber.getWidth(), videoGrabber.getHeight());
			videoGrabber.draw();
		shader.end();
		camFbo.end();
	}

	if(textChanged)
	{
		overlayFbo.begin();
			ofClear(0, 0, 0, 0);
			ofRectangle box;
			int x;
			int y = font[0].getLineHeight()+50;

			box = font[0].getStringBoundingBox(lineOne, 0, 0);
			x = (overlayFbo.getWidth()/2.0) - (box.width/2.0);
			font[0].drawString(lineOne, x, y);

			y += font[1].getLineHeight()+50;
			box = font[1].getStringBoundingBox(lineTwo, 0, 0);
			x = (overlayFbo.getWidth()/2.0) - (box.width/2.0);
			font[1].drawString(lineTwo, x, y);
		overlayFbo.end();
	}

}

//--------------------------------------------------------------
void shaderApp::draw(){

	if(bVideoPlaying) {
		omxPlayer.draw(0, 0, ofGetWidth(), ofGetHeight());

	} else {
		camFbo.draw(0, 0, ofGetWidth(), ofGetHeight());
	}

	overlayFbo.draw(0, 0, ofGetWidth(), ofGetHeight());

	stringstream info;
	info << "APP FPS: " << ofGetFrameRate() << "\n";
	info << "Camera Resolution: " << videoGrabber.getWidth() << "x" << videoGrabber.getHeight()	<< " @ "<< videoGrabber.getFrameRate() <<"FPS"<< "\n";
	info << "CURRENT FILTER: " << currentFilter << "\n";
	info << "CURRENT VIDEO: " << currentVideo << " ";
	info << "(" << omxPlayer.getCurrentFrame() << "/" << omxPlayer.getTotalNumFrames() << ")" << endl;

	if (doDrawInfo)
	{
		ofDrawBitmapStringHighlight(info.str(), 100, 100, ofColor::black, ofColor::yellow);
	}
}
<commit_msg>added new fonts to app<commit_after>#include "shaderApp.h"

//--------------------------------------------------------------
void shaderApp::onVideoEnd(ofxOMXPlayerListenerEventData& e)
{
	ofLogVerbose(__func__) << " RECEIVED";
	bVideoPlaying=false;
}

//--------------------------------------------------------------
void shaderApp::setup()
{
	//ofSetLogLevel(OF_LOG_VERBOSE);
	ofSetLogLevel("ofThread", OF_LOG_SILENT);
	ofSetVerticalSync(false);
	ofEnableAlphaBlending();
	ofSetFullscreen(true);

	doDrawInfo = false;

	OMXCameraSettings omxCameraSettings;
	omxCameraSettings.width = 640;
	omxCameraSettings.height = 480;
	omxCameraSettings.framerate = 30;
	omxCameraSettings.isUsingTexture = true;

	videoGrabber.setup(omxCameraSettings);

	shader.load("shaderExample");

	ofLogNotice() << "Allocating FBOs";
	camFbo.allocate(omxCameraSettings.width, omxCameraSettings.height);
	camFbo.begin();
		ofClear(0, 0, 0, 0);
	camFbo.end();

	overlayFbo.allocate(omxCameraSettings.width, omxCameraSettings.height);
	overlayFbo.begin();
		ofClear(0, 0, 0, 0);
	overlayFbo.end();

	cout << "listening for osc messages on port " << PORT << "\n";
	receiver.setup(PORT);

	ofLogNotice() << "Loading fonts";
	font[0].loadFont("fonts/Lubalin Graph Bold.ttf", 120);
	font[1].loadFont("fonts/Lubalin Graph Demi Regular.ttf", 32);

	ofLogNotice() << "Listing filters";
	for(map<string, OMX_IMAGEFILTERTYPE>::iterator it = OMX_Maps::getInstance().imageFilters.begin();
				it!=OMX_Maps::getInstance().imageFilters.end(); ++it) {
        	ofLogNotice() << (*it).first;
   	}

	ofLogNotice() << "Listing videos";
	ofDirectory dir;
	dir.listDir("videos/");
	for(int i = 0; i < (int)dir.size(); i++){
		string path = dir.getName(i);
		ofLogNotice() << path;
	}

	bVideoPlaying = false;
}

//--------------------------------------------------------------
void shaderApp::update()
{
	bool textChanged = false;

	// check for waiting messages
	while(receiver.hasWaitingMessages()){
		// get the next message
		ofxOscMessage m;
		receiver.getNextMessage(&m);

		if(m.getAddress() == "/text"){
			lineOne = ofToString(m.getArgAsInt32(0));
			lineTwo = m.getArgAsString(1);
			textChanged = true;
		}

		if(m.getAddress() == "/filter") {
			string filterToUse = m.getArgAsString(0);
			for(map<string, OMX_IMAGEFILTERTYPE>::iterator it = OMX_Maps::getInstance().imageFilters.begin();
				it!=OMX_Maps::getInstance().imageFilters.end(); ++it)
			{
				string name = (*it).first;
				OMX_IMAGEFILTERTYPE filter = (*it).second;

				if (ofToLower(name) == ofToLower(filterToUse))  {
					currentFilter = filterToUse;
					videoGrabber.applyImageFilter(filter);
				}
			}
		}

		if(m.getAddress() == "/info") {
			int i = m.getArgAsInt32(0);
			doDrawInfo = i;
		}

		if(m.getAddress() == "/video") {
			string videoToPlay = m.getArgAsString(0);
			ofDirectory dir;
			dir.listDir("videos/");

			for(int i = 0; i < (int)dir.size(); i++){
				string name = dir.getName(i);
				if(name==videoToPlay) {
					ofLogNotice("!!!") << "playing " << name;

					string videoPath = ofToDataPath(dir.getPath(i), true);

					ofxOMXPlayerSettings settings;
					settings.videoPath = videoPath;
					settings.useHDMIForAudio = true;	//default true
					settings.enableTexture = true;		//default true
					settings.enableLooping = false;		//default true
					settings.enableAudio = true;		//default true, save resources by disabling
					settings.listener = this;
					//settings.doFlipTexture = true;		//default false

					//so either pass in the settings
					omxPlayer.setup(settings);

					currentVideo = name;
					bVideoPlaying = true;
				}
			}
		}

		if(m.getAddress() == "/gif") {
		}
	}

	if (videoGrabber.isFrameNew() && !bVideoPlaying)
	{
		camFbo.begin();
		ofClear(0, 0, 0, 0);
		shader.begin();
			shader.setUniformTexture("tex0", videoGrabber.getTextureReference(), videoGrabber.getTextureID());
			shader.setUniform1f("time", ofGetElapsedTimef());
			shader.setUniform2f("resolution", videoGrabber.getWidth(), videoGrabber.getHeight());
			videoGrabber.draw();
		shader.end();
		camFbo.end();
	}

	if(textChanged)
	{
		overlayFbo.begin();
			ofClear(0, 0, 0, 0);
			ofRectangle box;
			int x;
			int y = font[0].getLineHeight()+50;

			box = font[0].getStringBoundingBox(lineOne, 0, 0);
			x = (overlayFbo.getWidth()/2.0) - (box.width/2.0);
			ofSetColor(ofColor::black);
			font[0].drawString(lineOne, x+2, y+2);
			ofSetColor(ofColor::white);
			font[0].drawString(lineOne, x, y);

			y += font[1].getLineHeight()+50;
			box = font[1].getStringBoundingBox(lineTwo, 0, 0);
			x = (overlayFbo.getWidth()/2.0) - (box.width/2.0);

			ofSetColor(ofColor::black);
			font[1].drawString(lineTwo, x+2, y+2);
			ofSetColor(ofColor::white);
			font[1].drawString(lineTwo, x, y);

		overlayFbo.end();
	}

}

//--------------------------------------------------------------
void shaderApp::draw(){

	if(bVideoPlaying) {
		omxPlayer.draw(0, 0, ofGetWidth(), ofGetHeight());

	} else {
		camFbo.draw(0, 0, ofGetWidth(), ofGetHeight());
	}

	overlayFbo.draw(0, 0, ofGetWidth(), ofGetHeight());

	stringstream info;
	info << "APP FPS: " << ofGetFrameRate() << "\n";
	info << "Camera Resolution: " << videoGrabber.getWidth() << "x" << videoGrabber.getHeight()	<< " @ "<< videoGrabber.getFrameRate() <<"FPS"<< "\n";
	info << "CURRENT FILTER: " << currentFilter << "\n";
	info << "CURRENT VIDEO: " << currentVideo << " ";
	info << "(" << omxPlayer.getCurrentFrame() << "/" << omxPlayer.getTotalNumFrames() << ")" << endl;

	if (doDrawInfo)
	{
		ofDrawBitmapStringHighlight(info.str(), 100, 100, ofColor::black, ofColor::yellow);
	}
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef __itkCudaImage_hxx
#define __itkCudaImage_hxx

#include "itkCudaImage.h"

namespace itk
{
//
// Constructor
//
template <class TPixel, unsigned int VImageDimension>
CudaImage< TPixel, VImageDimension >::CudaImage()
{
  m_DataManager = CudaImageDataManager< CudaImage< TPixel, VImageDimension > >::New();
  m_DataManager->SetTimeStamp(this->GetTimeStamp());
}

template <class TPixel, unsigned int VImageDimension>
CudaImage< TPixel, VImageDimension >::~CudaImage()
{
}

template <class TPixel, unsigned int VImageDimension>
#if ITK_VERSION_MAJOR < 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR < 6)
  void CudaImage< TPixel, VImageDimension >::Allocate()
#else
  void CudaImage< TPixel, VImageDimension >::Allocate(bool initializePixels)
#endif
{
  // allocate CPU memory - calling Allocate() in superclass
#if ITK_VERSION_MAJOR < 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR < 6)
  Superclass::Allocate();
#else
  Superclass::Allocate(initializePixels);
#endif

  // allocate Cuda memory
  this->ComputeOffsetTable();
  unsigned long numPixel = this->GetOffsetTable()[VImageDimension];
  m_DataManager->SetBufferSize(sizeof(TPixel)*numPixel);
  m_DataManager->SetImagePointer(this);
  m_DataManager->SetCPUBufferPointer(Superclass::GetBufferPointer());

  // When we allocate both buffers are dirty as the image data can provided
  // by GPU filters without going through the CPU memory first
  m_DataManager->SetGPUBufferDirty();
  m_DataManager->SetCPUDirtyFlag(true);

// If initialize pixel is set then we set the CPU dirty flag to false
#if ITK_VERSION_MAJOR > 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR > 5)
  if(initializePixels)
    {
    m_DataManager->SetCPUDirtyFlag(false);
    }
#endif

  // prevent unnecessary copy from CPU to Cuda at the beginning
  m_DataManager->SetTimeStamp(this->GetTimeStamp());
}

template< class TPixel, unsigned int VImageDimension >
void CudaImage< TPixel, VImageDimension >::Initialize()
{
  // CPU image initialize
  Superclass::Initialize();

  m_DataManager = CudaImageDataManager< CudaImage< TPixel, VImageDimension > >::New();
  m_DataManager->SetTimeStamp(this->GetTimeStamp());

  /*
  // Cuda image initialize
  m_DataManager->Initialize();
  this->ComputeOffsetTable();
  unsigned long numPixel = this->GetOffsetTable()[VImageDimension];
  m_DataManager->SetBufferSize(sizeof(TPixel)*numPixel);
  m_DataManager->SetImagePointer(this);
  m_DataManager->SetCPUBufferPointer(Superclass::GetBufferPointer());
  m_DataManager->SetGPUBufferDirty();

  // prevent unnecessary copy from CPU to Cuda at the beginning
  m_DataManager->SetTimeStamp(this->GetTimeStamp());*/
}

/** If the class is modified we marke the GPUBuffer has dirty */
template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::Modified() const
{
  Superclass::Modified();
  //m_DataManager->SetCPUDirtyFlag(false); // prevent the GPU to copy to the CPU
  //m_DataManager->SetGPUBufferDirty();
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::SetBufferedRegion(const RegionType & region)
{
  // If the regions are the same we don't change
  const RegionType currentRegion = this->GetBufferedRegion();
  bool sameRegions = true;
  for(unsigned int i=0;i<VImageDimension;i++)
    {
    if(region.GetSize()[i] != currentRegion.GetSize()[i]
       || region.GetIndex()[i] != currentRegion.GetIndex()[i])
      {
      sameRegions = false;
      break;
      }
    }

  if(sameRegions)
    {
    return;
    }

  Superclass::SetBufferedRegion(region);
  unsigned long numPixel = this->GetOffsetTable()[VImageDimension];
  m_DataManager->SetBufferSize(sizeof(TPixel)*numPixel);
  m_DataManager->SetCPUDirtyFlag(false); // prevent the GPU to copy to the CPU
  m_DataManager->SetGPUBufferDirty();
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::FillBuffer(const TPixel & value)
{
  m_DataManager->SetGPUBufferDirty();
  Superclass::FillBuffer(value);
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::SetPixel(const IndexType & index, const TPixel & value)
{
  m_DataManager->SetGPUBufferDirty();
  Superclass::SetPixel(index, value);
}

template <class TPixel, unsigned int VImageDimension>
const TPixel & CudaImage< TPixel, VImageDimension >::GetPixel(const IndexType & index) const
{
  m_DataManager->UpdateCPUBuffer();
  return Superclass::GetPixel(index);
}

template <class TPixel, unsigned int VImageDimension>
TPixel & CudaImage< TPixel, VImageDimension >::GetPixel(const IndexType & index)
{
  m_DataManager->UpdateCPUBuffer();
  return Superclass::GetPixel(index);
}

template <class TPixel, unsigned int VImageDimension>
TPixel & CudaImage< TPixel, VImageDimension >::operator[] (const IndexType &index)
{
  m_DataManager->UpdateCPUBuffer();
  return Superclass::operator[] (index);
}

template <class TPixel, unsigned int VImageDimension>
const TPixel & CudaImage< TPixel, VImageDimension >::operator[] (const IndexType &index) const
{
  m_DataManager->UpdateCPUBuffer();
  return Superclass::operator[] (index);
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::SetPixelContainer(PixelContainer *container)
{
  Superclass::SetPixelContainer(container);
  m_DataManager->SetCPUDirtyFlag(false);
  m_DataManager->SetGPUDirtyFlag(true);
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::UpdateBuffers()
{
  m_DataManager->UpdateCPUBuffer();
  m_DataManager->UpdateGPUBuffer();
}

template <class TPixel, unsigned int VImageDimension>
TPixel* CudaImage< TPixel, VImageDimension >::GetBufferPointer()
{
  /* less conservative version - if you modify pixel value using
   * this pointer then you must set the image as modified manually!!! */
  m_DataManager->UpdateCPUBuffer();
  m_DataManager->SetGPUDirtyFlag(true);
  return Superclass::GetBufferPointer();
}

template <class TPixel, unsigned int VImageDimension>
const TPixel * CudaImage< TPixel, VImageDimension >::GetBufferPointer() const
{
  // const does not change buffer, but if CPU is dirty then make it up-to-date
  m_DataManager->UpdateCPUBuffer();
  m_DataManager->SetGPUDirtyFlag(true); // THIS IS NEEDED BECAUSE NON-CONST ITERATORS USE THIS FUNCTION
  return Superclass::GetBufferPointer();
}

template <class TPixel, unsigned int VImageDimension>
CudaDataManager::Pointer
CudaImage< TPixel, VImageDimension >::GetCudaDataManager() const
{
  typedef typename CudaImageDataManager< CudaImage >::Superclass CudaImageDataSuperclass;
  typedef typename CudaImageDataSuperclass::Pointer             CudaImageDataSuperclassPointer;

  return static_cast< CudaImageDataSuperclassPointer >(m_DataManager.GetPointer());
}

template <class TPixel, unsigned int VImageDimension>
void
CudaImage< TPixel, VImageDimension >::Graft(const DataObject *data)
{
  typedef CudaImageDataManager< CudaImage >             CudaImageDataManagerType;
  typedef typename CudaImageDataManagerType::Superclass CudaImageDataSuperclass;
  typedef typename CudaImageDataSuperclass::Pointer     CudaImageDataSuperclassPointer;

  // call the superclass' implementation
  Superclass::Graft(data);

  //std::cout << this << " graft from " << data << std::endl;
  m_DataManager = dynamic_cast<CudaImageDataManagerType*>((((CudaImage*)data)->GetCudaDataManager()).GetPointer());

  return;

  // Pass regular pointer to Graft() instead of smart pointer due to type
  // casting problem
  CudaImageDataManagerType* ptr = dynamic_cast<CudaImageDataManagerType*>(
      (((CudaImage*)data)->GetCudaDataManager()).GetPointer());

  // call Cuda data graft function
  m_DataManager->SetImagePointer(this); // hu! not necessary ?!
  m_DataManager->Graft(ptr);

  // Synchronize timestamp of CudaImage and CudaDataManager
  m_DataManager->SetTimeStamp(this->GetTimeStamp());
}

} // namespace itk

#endif
<commit_msg>ENH: Only sets the GPU flag has dirty when Allocating. This avoids doing an unnecessary memory transfer from  GPU -> CPU<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef __itkCudaImage_hxx
#define __itkCudaImage_hxx

#include "itkCudaImage.h"

namespace itk
{
//
// Constructor
//
template <class TPixel, unsigned int VImageDimension>
CudaImage< TPixel, VImageDimension >::CudaImage()
{
  m_DataManager = CudaImageDataManager< CudaImage< TPixel, VImageDimension > >::New();
  m_DataManager->SetTimeStamp(this->GetTimeStamp());
}

template <class TPixel, unsigned int VImageDimension>
CudaImage< TPixel, VImageDimension >::~CudaImage()
{
}

template <class TPixel, unsigned int VImageDimension>
#if ITK_VERSION_MAJOR < 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR < 6)
  void CudaImage< TPixel, VImageDimension >::Allocate()
#else
  void CudaImage< TPixel, VImageDimension >::Allocate(bool initializePixels)
#endif
{
  // allocate CPU memory - calling Allocate() in superclass
#if ITK_VERSION_MAJOR < 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR < 6)
  Superclass::Allocate();
#else
  Superclass::Allocate(initializePixels);
#endif

  // allocate Cuda memory
  this->ComputeOffsetTable();
  unsigned long numPixel = this->GetOffsetTable()[VImageDimension];
  m_DataManager->SetBufferSize(sizeof(TPixel)*numPixel);
  m_DataManager->SetImagePointer(this);
  m_DataManager->SetCPUBufferPointer(Superclass::GetBufferPointer());

  // When we allocate both buffers are dirty as the image data can provided
  // by GPU filters without going through the CPU memory first
  // Setting only the flag so that no memory transfer is done as Allocate
  // is called everytime the filter updates
  //m_DataManager->SetGPUBufferDirty();
  m_DataManager->SetGPUDirtyFlag(true);
  m_DataManager->SetCPUDirtyFlag(true);

// If initialize pixel is set then we set the CPU dirty flag to false
#if ITK_VERSION_MAJOR > 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR > 5)
  if(initializePixels)
    {
    m_DataManager->SetCPUDirtyFlag(false);
    }
#endif

  // prevent unnecessary copy from CPU to Cuda at the beginning
  m_DataManager->SetTimeStamp(this->GetTimeStamp());
}

template< class TPixel, unsigned int VImageDimension >
void CudaImage< TPixel, VImageDimension >::Initialize()
{
  // CPU image initialize
  Superclass::Initialize();

  m_DataManager = CudaImageDataManager< CudaImage< TPixel, VImageDimension > >::New();
  m_DataManager->SetTimeStamp(this->GetTimeStamp());

  /*
  // Cuda image initialize
  m_DataManager->Initialize();
  this->ComputeOffsetTable();
  unsigned long numPixel = this->GetOffsetTable()[VImageDimension];
  m_DataManager->SetBufferSize(sizeof(TPixel)*numPixel);
  m_DataManager->SetImagePointer(this);
  m_DataManager->SetCPUBufferPointer(Superclass::GetBufferPointer());
  m_DataManager->SetGPUBufferDirty();

  // prevent unnecessary copy from CPU to Cuda at the beginning
  m_DataManager->SetTimeStamp(this->GetTimeStamp());*/
}

/** If the class is modified we marke the GPUBuffer has dirty */
template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::Modified() const
{
  Superclass::Modified();
  //m_DataManager->SetCPUDirtyFlag(false); // prevent the GPU to copy to the CPU
  //m_DataManager->SetGPUBufferDirty();
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::SetBufferedRegion(const RegionType & region)
{
  // If the regions are the same we don't change
  const RegionType currentRegion = this->GetBufferedRegion();
  bool sameRegions = true;
  for(unsigned int i=0;i<VImageDimension;i++)
    {
    if(region.GetSize()[i] != currentRegion.GetSize()[i]
       || region.GetIndex()[i] != currentRegion.GetIndex()[i])
      {
      sameRegions = false;
      break;
      }
    }

  if(sameRegions)
    {
    return;
    }

  Superclass::SetBufferedRegion(region);
  unsigned long numPixel = this->GetOffsetTable()[VImageDimension];
  m_DataManager->SetBufferSize(sizeof(TPixel)*numPixel);
  m_DataManager->SetCPUDirtyFlag(false); // prevent the GPU to copy to the CPU
  m_DataManager->SetGPUBufferDirty();
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::FillBuffer(const TPixel & value)
{
  m_DataManager->SetGPUBufferDirty();
  Superclass::FillBuffer(value);
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::SetPixel(const IndexType & index, const TPixel & value)
{
  m_DataManager->SetGPUBufferDirty();
  Superclass::SetPixel(index, value);
}

template <class TPixel, unsigned int VImageDimension>
const TPixel & CudaImage< TPixel, VImageDimension >::GetPixel(const IndexType & index) const
{
  m_DataManager->UpdateCPUBuffer();
  return Superclass::GetPixel(index);
}

template <class TPixel, unsigned int VImageDimension>
TPixel & CudaImage< TPixel, VImageDimension >::GetPixel(const IndexType & index)
{
  m_DataManager->UpdateCPUBuffer();
  return Superclass::GetPixel(index);
}

template <class TPixel, unsigned int VImageDimension>
TPixel & CudaImage< TPixel, VImageDimension >::operator[] (const IndexType &index)
{
  m_DataManager->UpdateCPUBuffer();
  return Superclass::operator[] (index);
}

template <class TPixel, unsigned int VImageDimension>
const TPixel & CudaImage< TPixel, VImageDimension >::operator[] (const IndexType &index) const
{
  m_DataManager->UpdateCPUBuffer();
  return Superclass::operator[] (index);
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::SetPixelContainer(PixelContainer *container)
{
  Superclass::SetPixelContainer(container);
  m_DataManager->SetCPUDirtyFlag(false);
  m_DataManager->SetGPUDirtyFlag(true);
}

template <class TPixel, unsigned int VImageDimension>
void CudaImage< TPixel, VImageDimension >::UpdateBuffers()
{
  m_DataManager->UpdateCPUBuffer();
  m_DataManager->UpdateGPUBuffer();
}

template <class TPixel, unsigned int VImageDimension>
TPixel* CudaImage< TPixel, VImageDimension >::GetBufferPointer()
{
  /* less conservative version - if you modify pixel value using
   * this pointer then you must set the image as modified manually!!! */
  m_DataManager->UpdateCPUBuffer();
  m_DataManager->SetGPUDirtyFlag(true);
  return Superclass::GetBufferPointer();
}

template <class TPixel, unsigned int VImageDimension>
const TPixel * CudaImage< TPixel, VImageDimension >::GetBufferPointer() const
{
  // const does not change buffer, but if CPU is dirty then make it up-to-date
  m_DataManager->UpdateCPUBuffer();
  m_DataManager->SetGPUDirtyFlag(true); // THIS IS NEEDED BECAUSE NON-CONST ITERATORS USE THIS FUNCTION
  return Superclass::GetBufferPointer();
}

template <class TPixel, unsigned int VImageDimension>
CudaDataManager::Pointer
CudaImage< TPixel, VImageDimension >::GetCudaDataManager() const
{
  typedef typename CudaImageDataManager< CudaImage >::Superclass CudaImageDataSuperclass;
  typedef typename CudaImageDataSuperclass::Pointer             CudaImageDataSuperclassPointer;

  return static_cast< CudaImageDataSuperclassPointer >(m_DataManager.GetPointer());
}

template <class TPixel, unsigned int VImageDimension>
void
CudaImage< TPixel, VImageDimension >::Graft(const DataObject *data)
{
  typedef CudaImageDataManager< CudaImage >             CudaImageDataManagerType;
  typedef typename CudaImageDataManagerType::Superclass CudaImageDataSuperclass;
  typedef typename CudaImageDataSuperclass::Pointer     CudaImageDataSuperclassPointer;

  // call the superclass' implementation
  Superclass::Graft(data);

  //std::cout << this << " graft from " << data << std::endl;
  m_DataManager = dynamic_cast<CudaImageDataManagerType*>((((CudaImage*)data)->GetCudaDataManager()).GetPointer());

  return;

  // Pass regular pointer to Graft() instead of smart pointer due to type
  // casting problem
  CudaImageDataManagerType* ptr = dynamic_cast<CudaImageDataManagerType*>(
      (((CudaImage*)data)->GetCudaDataManager()).GetPointer());

  // call Cuda data graft function
  m_DataManager->SetImagePointer(this); // hu! not necessary ?!
  m_DataManager->Graft(ptr);

  // Synchronize timestamp of CudaImage and CudaDataManager
  m_DataManager->SetTimeStamp(this->GetTimeStamp());
}

} // namespace itk

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_UNIT_TEST
#define MFEM_UNIT_TEST

#include "catch.hpp"

/// MFEM_Approx can be used to compare floating point values within an absolute
/// tolerance of `margin` (default value 1e-12).
inline Approx MFEM_Approx(double val, double margin = 1e-12)
{
   return Approx(val).margin(margin);
}

#endif
<commit_msg>Update MFEM_Approx() function used in the unit tests to explicitly set a relative tolerance with a default of 1e-12. Currently, the function is using the default relative tolerance (aka epsilon) as defined by Catch2's Approx class and that is too big:    std::numeric_limits<float>::epsilon()*100 which is 1.192092895507812500e-05.<commit_after>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_UNIT_TEST
#define MFEM_UNIT_TEST

#include "catch.hpp"

/** @brief MFEM_Approx can be used to compare floating point values within an
    absolute tolerance of @a abs_tol (default value 1e-12) and relative
    tolerance of @a rel_tol (default value 1e-12). */
inline Approx MFEM_Approx(double val,
                          double abs_tol = 1e-12,
                          double rel_tol = 1e-12)
{
   return Approx(val).margin(abs_tol).epsilon(rel_tol);
}

#endif
<|endoftext|>


<commit_before>/*******************************************************************/
/*                               XDMF                              */
/*                   eXtensible Data Model and Format              */
/*                                                                 */
/*  Id : Id  */
/*  Date : $Date$ */
/*  Version : $Revision$ */
/*                                                                 */
/*  Author:                                                        */
/*     Jerry A. Clarke                                             */
/*     clarke@arl.army.mil                                         */
/*     US Army Research Laboratory                                 */
/*     Aberdeen Proving Ground, MD                                 */
/*                                                                 */
/*     Copyright @ 2002 US Army Research Laboratory                */
/*     All Rights Reserved                                         */
/*     See Copyright.txt or http://www.arl.hpc.mil/ice for details */
/*                                                                 */
/*     This software is distributed WITHOUT ANY WARRANTY; without  */
/*     even the implied warranty of MERCHANTABILITY or FITNESS     */
/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice   */
/*     for more information.                                       */
/*                                                                 */
/*******************************************************************/
#include <vtkXdmfDataArray.h>

#include <vtkObjectFactory.h>
#include <vtkCommand.h>

#include <vtkUnsignedCharArray.h>
#include <vtkCharArray.h>
#include <vtkIntArray.h>
#include <vtkLongArray.h>
#include <vtkFloatArray.h>
#include <vtkDoubleArray.h>
#include <vtkUnsignedIntArray.h>
#include "vtkShortArray.h"
#include "vtkUnsignedShortArray.h"

#include <XdmfArray.h>

//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkXdmfDataArray);

//----------------------------------------------------------------------------
vtkXdmfDataArray::vtkXdmfDataArray()
{
  this->Array = NULL;
  this->vtkArray = NULL;
}

//----------------------------------------------------------------------------
vtkDataArray *vtkXdmfDataArray::FromXdmfArray( char *ArrayName, int CopyShape,
  int rank, int Components, int MakeCopy ){
  XdmfArray *array = this->Array;
    XdmfInt64 components = 1;
    XdmfInt64 tuples = 0;
  if ( ArrayName != NULL ) {
    array = TagNameToArray( ArrayName );
  }
  if( array == NULL ){
    XdmfErrorMessage("Array is NULL");
    return(NULL);
  }
  if ( this->vtkArray )
    {
    this->vtkArray->Delete();
    this->vtkArray = 0;
    }
  switch( array->GetNumberType() ){
  case XDMF_INT8_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkCharArray::New();
    }
    break;
  case XDMF_UINT8_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkUnsignedCharArray::New();
    }
    break;
  case XDMF_INT16_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkShortArray::New();
    }
    break;
  case XDMF_UINT16_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkUnsignedShortArray::New();
    }
    break;
  case XDMF_UINT32_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkUnsignedIntArray::New();
    }
    break;
  case XDMF_INT32_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkIntArray::New();
    }
    break;
  case XDMF_INT64_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkLongArray::New();
    }
    break;
  case XDMF_FLOAT32_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkFloatArray::New();
    }
    break;
  case XDMF_FLOAT64_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkDoubleArray::New();
    }
    break;
  default:
    vtkErrorMacro("Cannot create VTK data array: " << array->GetNumberType());
    return 0;
  }
  if ( CopyShape )
    {
    if  ( array->GetRank() > rank + 1 )
      {
      this->vtkArray->Delete();
      this->vtkArray = 0;
      vtkErrorMacro("Rank of Xdmf array is more than 1 + rank of dataset");
      return 0;
      }
    if ( array->GetRank() > rank )
      {
      components = array->GetDimension( rank );
      }
    tuples = array->GetNumberOfElements() / components;
    /// this breaks
    components = Components;
    tuples = array->GetNumberOfElements() / components;
    // cout << "Tuples: " << tuples << " components: " << components << endl;
    // cout << "Rank: " << rank << endl;
    this->vtkArray->SetNumberOfComponents( components );
    if(MakeCopy) this->vtkArray->SetNumberOfTuples( tuples );
    }
  else
    {
    this->vtkArray->SetNumberOfComponents( 1 );
    if(MakeCopy) this->vtkArray->SetNumberOfTuples( array->GetNumberOfElements() );
    }
  //cout << "Number type: " << array->GetNumberType() << endl;
  if(MakeCopy){
  switch( array->GetNumberType() ){
  case XDMF_INT8_TYPE :
    array->GetValues( 0,
      ( XDMF_8_INT*)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_UINT8_TYPE :
    array->GetValues( 0,
      ( XDMF_8_U_INT*)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_INT16_TYPE :
    array->GetValues( 0,
      ( XDMF_16_INT*)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_UINT16_TYPE :
    array->GetValues( 0,
      ( XDMF_16_U_INT*)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_INT32_TYPE :
    array->GetValues( 0,
      (XDMF_32_INT *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_UINT32_TYPE :
    array->GetValues( 0,
      (XDMF_32_U_INT *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_INT64_TYPE :
    array->GetValues( 0,
      (XDMF_64_INT *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_FLOAT32_TYPE :
    array->GetValues( 0,
      ( float *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_FLOAT64_TYPE :
    array->GetValues( 0,
      ( double *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  default :
    if ( array->GetNumberOfElements() > 0 )
      {
      //cout << "Manual idx" << endl;
      //cout << "Tuples: " << vtkArray->GetNumberOfTuples() << endl;
      //cout << "Components: " << vtkArray->GetNumberOfComponents() << endl;
      //cout << "Elements: " << array->GetNumberOfElements() << endl;
      vtkIdType jj, kk;
      vtkIdType idx = 0;
      for ( jj = 0; jj < vtkArray->GetNumberOfTuples(); jj ++ )
        {
        for ( kk = 0; kk < vtkArray->GetNumberOfComponents(); kk ++ )
          {
          double val = array->GetValueAsFloat64(idx);
          //cout << "Value: " << val << endl;
          vtkArray->SetComponent(jj, kk, val);
          idx ++;
          }
        }
      }
    break;
  }
  }else{
  switch( array->GetNumberType() ){
  case XDMF_INT8_TYPE :
    vtkCharArray *chara = vtkCharArray::SafeDownCast(this->vtkArray);
    if(!chara){
        XdmfErrorMessage("Cannot downcast data array");
        return(0);
    }
    chara->SetArray((char *)array->GetDataPointer(), components * tuples, 0);
    break;
  case XDMF_UINT8_TYPE :
    vtkUnsignedCharArray *uchara = vtkUnsignedCharArray::SafeDownCast(this->vtkArray);
    if(!uchara){
        XdmfErrorMessage("Cannot downcast ucharata array");
        return(0);
    }
    uchara->SetArray((unsigned char *)array->GetDataPointer(), components * tuples, 0);
    break;
  case XDMF_INT16_TYPE :
    vtkShortArray *shorta = vtkShortArray::SafeDownCast(this->vtkArray);
    if(!shorta){
        XdmfErrorMessage("Cannot downcast data array");
        return(0);
    }
    shorta->SetArray((short *)array->GetDataPointer(), tuples, 0);
    break;
  case XDMF_UINT16_TYPE :
    vtkUnsignedShortArray *ushorta = vtkUnsignedShortArray::SafeDownCast(this->vtkArray);
    if(!ushorta){
        XdmfErrorMessage("Cannot downcast ushortata array");
        return(0);
    }
    ushorta->SetArray((unsigned short *)array->GetDataPointer(), components * tuples, 0);
    break;
  case XDMF_INT32_TYPE :
    vtkIntArray *inta = vtkIntArray::SafeDownCast(this->vtkArray);
    if(!inta){
        XdmfErrorMessage("Cannot downcast intata array");
        return(0);
    }
    inta->SetArray((int *)array->GetDataPointer(), components * tuples, 0);
    break;
  case XDMF_UINT32_TYPE :
    vtkUnsignedIntArray *uinta = vtkUnsignedIntArray::SafeDownCast(this->vtkArray);
    if(!uinta){
        XdmfErrorMessage("Cannot downcast uintata array");
        return(0);
    }
    uinta->SetArray((unsigned int *)array->GetDataPointer(), components * tuples, 0);
    break;
  case XDMF_FLOAT32_TYPE :
    vtkFloatArray *floata = vtkFloatArray::SafeDownCast(this->vtkArray);
    if(!floata){
        XdmfErrorMessage("Cannot downcast floatata array");
        return(0);
    }
    floata->SetArray((float *)array->GetDataPointer(), components * tuples, 0);
    break;
  case XDMF_FLOAT64_TYPE :
    vtkDoubleArray *doublea = vtkDoubleArray::SafeDownCast(this->vtkArray);
    if(!doublea){
        XdmfErrorMessage("Cannot downcast doubleata array");
        return(0);
    }
    doublea->SetArray((double *)array->GetDataPointer(), components * tuples, 0);
    break;
  default :
    XdmfErrorMessage("Can't handle number type");
    return(0);
    break;
  }
  array->Reset();
  }
  return( this->vtkArray );
}

//----------------------------------------------------------------------------
char *vtkXdmfDataArray::ToXdmfArray( vtkDataArray *DataArray, int CopyShape ){
  XdmfArray *array;
  if ( DataArray  == NULL )  {
    DataArray = this->vtkArray;
  }
  if ( DataArray  == NULL )  {
    vtkDebugMacro(<< "Array is NULL");
    return(NULL);
  }
  if ( this->Array == NULL ){
    this->Array = new XdmfArray();
    switch( DataArray->GetDataType() ){
    case VTK_CHAR :
    case VTK_UNSIGNED_CHAR :
      this->Array->SetNumberType( XDMF_INT8_TYPE );
      break;
    case VTK_SHORT :
    case VTK_UNSIGNED_SHORT :
    case VTK_INT :
    case VTK_UNSIGNED_INT :
    case VTK_LONG :
    case VTK_UNSIGNED_LONG :
      this->Array->SetNumberType( XDMF_INT32_TYPE );
      break;
    case VTK_FLOAT :
      this->Array->SetNumberType( XDMF_FLOAT32_TYPE );
      break;
    case VTK_DOUBLE :
      this->Array->SetNumberType( XDMF_FLOAT64_TYPE );
      break;
    default :
      XdmfErrorMessage("Can't handle Data Type");
      return( NULL );
    }
  }
  array = this->Array;
  if( CopyShape ) {
    XdmfInt64 Shape[3];

    Shape[0] = DataArray->GetNumberOfTuples();
    Shape[1] = DataArray->GetNumberOfComponents();
    if( Shape[1] == 1 ) {
      array->SetShape( 1, Shape );
    } else {
      array->SetShape( 2, Shape );
    }

  }
  switch( array->GetNumberType() ){
  case XDMF_INT8_TYPE :
    array->SetValues( 0,
      ( unsigned char  *)DataArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_INT32_TYPE :
  case XDMF_INT64_TYPE :
    array->SetValues( 0,
      ( int *)DataArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_FLOAT32_TYPE :
    array->SetValues( 0,
      ( float *)DataArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  default :
    array->SetValues( 0,
      ( double *)DataArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  }
  return( array->GetTagName() );
}
<commit_msg>fixed error<commit_after>/*******************************************************************/
/*                               XDMF                              */
/*                   eXtensible Data Model and Format              */
/*                                                                 */
/*  Id : Id  */
/*  Date : $Date$ */
/*  Version : $Revision$ */
/*                                                                 */
/*  Author:                                                        */
/*     Jerry A. Clarke                                             */
/*     clarke@arl.army.mil                                         */
/*     US Army Research Laboratory                                 */
/*     Aberdeen Proving Ground, MD                                 */
/*                                                                 */
/*     Copyright @ 2002 US Army Research Laboratory                */
/*     All Rights Reserved                                         */
/*     See Copyright.txt or http://www.arl.hpc.mil/ice for details */
/*                                                                 */
/*     This software is distributed WITHOUT ANY WARRANTY; without  */
/*     even the implied warranty of MERCHANTABILITY or FITNESS     */
/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice   */
/*     for more information.                                       */
/*                                                                 */
/*******************************************************************/
#include <vtkXdmfDataArray.h>

#include <vtkObjectFactory.h>
#include <vtkCommand.h>

#include <vtkUnsignedCharArray.h>
#include <vtkCharArray.h>
#include <vtkIntArray.h>
#include <vtkLongArray.h>
#include <vtkFloatArray.h>
#include <vtkDoubleArray.h>
#include <vtkUnsignedIntArray.h>
#include "vtkShortArray.h"
#include "vtkUnsignedShortArray.h"

#include <XdmfArray.h>

//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkXdmfDataArray);

//----------------------------------------------------------------------------
vtkXdmfDataArray::vtkXdmfDataArray()
{
  this->Array = NULL;
  this->vtkArray = NULL;
}

//----------------------------------------------------------------------------
vtkDataArray *vtkXdmfDataArray::FromXdmfArray( char *ArrayName, int CopyShape,
  int rank, int Components, int MakeCopy ){
  XdmfArray *array = this->Array;
    XdmfInt64 components = 1;
    XdmfInt64 tuples = 0;
  if ( ArrayName != NULL ) {
    array = TagNameToArray( ArrayName );
  }
  if( array == NULL ){
    XdmfErrorMessage("Array is NULL");
    return(NULL);
  }
  if ( this->vtkArray )
    {
    this->vtkArray->Delete();
    this->vtkArray = 0;
    }
  switch( array->GetNumberType() ){
  case XDMF_INT8_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkCharArray::New();
    }
    break;
  case XDMF_UINT8_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkUnsignedCharArray::New();
    }
    break;
  case XDMF_INT16_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkShortArray::New();
    }
    break;
  case XDMF_UINT16_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkUnsignedShortArray::New();
    }
    break;
  case XDMF_UINT32_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkUnsignedIntArray::New();
    }
    break;
  case XDMF_INT32_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkIntArray::New();
    }
    break;
  case XDMF_INT64_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkLongArray::New();
    }
    break;
  case XDMF_FLOAT32_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkFloatArray::New();
    }
    break;
  case XDMF_FLOAT64_TYPE :
    if( this->vtkArray == NULL ) {
      this->vtkArray = vtkDoubleArray::New();
    }
    break;
  default:
    vtkErrorMacro("Cannot create VTK data array: " << array->GetNumberType());
    return 0;
  }
  if ( CopyShape )
    {
    if  ( array->GetRank() > rank + 1 )
      {
      this->vtkArray->Delete();
      this->vtkArray = 0;
      vtkErrorMacro("Rank of Xdmf array is more than 1 + rank of dataset");
      return 0;
      }
    if ( array->GetRank() > rank )
      {
      components = array->GetDimension( rank );
      }
    tuples = array->GetNumberOfElements() / components;
    /// this breaks
    components = Components;
    tuples = array->GetNumberOfElements() / components;
    // cout << "Tuples: " << tuples << " components: " << components << endl;
    // cout << "Rank: " << rank << endl;
    this->vtkArray->SetNumberOfComponents( components );
    if(MakeCopy) this->vtkArray->SetNumberOfTuples( tuples );
    }
  else
    {
    this->vtkArray->SetNumberOfComponents( 1 );
    if(MakeCopy) this->vtkArray->SetNumberOfTuples( array->GetNumberOfElements() );
    }
  //cout << "Number type: " << array->GetNumberType() << endl;
  if(MakeCopy){
  switch( array->GetNumberType() ){
  case XDMF_INT8_TYPE :
    array->GetValues( 0,
      ( XDMF_8_INT*)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_UINT8_TYPE :
    array->GetValues( 0,
      ( XDMF_8_U_INT*)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_INT16_TYPE :
    array->GetValues( 0,
      ( XDMF_16_INT*)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_UINT16_TYPE :
    array->GetValues( 0,
      ( XDMF_16_U_INT*)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_INT32_TYPE :
    array->GetValues( 0,
      (XDMF_32_INT *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_UINT32_TYPE :
    array->GetValues( 0,
      (XDMF_32_U_INT *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_INT64_TYPE :
    array->GetValues( 0,
      (XDMF_64_INT *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_FLOAT32_TYPE :
    array->GetValues( 0,
      ( float *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_FLOAT64_TYPE :
    array->GetValues( 0,
      ( double *)this->vtkArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  default :
    if ( array->GetNumberOfElements() > 0 )
      {
      //cout << "Manual idx" << endl;
      //cout << "Tuples: " << vtkArray->GetNumberOfTuples() << endl;
      //cout << "Components: " << vtkArray->GetNumberOfComponents() << endl;
      //cout << "Elements: " << array->GetNumberOfElements() << endl;
      vtkIdType jj, kk;
      vtkIdType idx = 0;
      for ( jj = 0; jj < vtkArray->GetNumberOfTuples(); jj ++ )
        {
        for ( kk = 0; kk < vtkArray->GetNumberOfComponents(); kk ++ )
          {
          double val = array->GetValueAsFloat64(idx);
          //cout << "Value: " << val << endl;
          vtkArray->SetComponent(jj, kk, val);
          idx ++;
          }
        }
      }
    break;
  }
  }else{
  switch( array->GetNumberType() ){
  case XDMF_INT8_TYPE :
    {
    vtkCharArray *chara = vtkCharArray::SafeDownCast(this->vtkArray);
    if(!chara){
        XdmfErrorMessage("Cannot downcast data array");
        return(0);
    }
    chara->SetArray((char *)array->GetDataPointer(), components * tuples, 0);
    }
    break;
  case XDMF_UINT8_TYPE :
    {
    vtkUnsignedCharArray *uchara = vtkUnsignedCharArray::SafeDownCast(this->vtkArray);
    if(!uchara){
        XdmfErrorMessage("Cannot downcast ucharata array");
        return(0);
    }
    uchara->SetArray((unsigned char *)array->GetDataPointer(), components * tuples, 0);
    }
    break;
  case XDMF_INT16_TYPE :
    {
    vtkShortArray *shorta = vtkShortArray::SafeDownCast(this->vtkArray);
    if(!shorta){
        XdmfErrorMessage("Cannot downcast data array");
        return(0);
    }
    shorta->SetArray((short *)array->GetDataPointer(), tuples, 0);
    }
    break;
  case XDMF_UINT16_TYPE :
    {
    vtkUnsignedShortArray *ushorta = vtkUnsignedShortArray::SafeDownCast(this->vtkArray);
    if(!ushorta){
        XdmfErrorMessage("Cannot downcast ushortata array");
        return(0);
    }
    ushorta->SetArray((unsigned short *)array->GetDataPointer(), components * tuples, 0);
    }
    break;
  case XDMF_INT32_TYPE :
    {
    vtkIntArray *inta = vtkIntArray::SafeDownCast(this->vtkArray);
    if(!inta){
        XdmfErrorMessage("Cannot downcast intata array");
        return(0);
    }
    inta->SetArray((int *)array->GetDataPointer(), components * tuples, 0);
    }
    break;
  case XDMF_UINT32_TYPE :
    {
    vtkUnsignedIntArray *uinta = vtkUnsignedIntArray::SafeDownCast(this->vtkArray);
    if(!uinta){
        XdmfErrorMessage("Cannot downcast uintata array");
        return(0);
    }
    uinta->SetArray((unsigned int *)array->GetDataPointer(), components * tuples, 0);
    }
    break;
  case XDMF_FLOAT32_TYPE :
    {
    vtkFloatArray *floata = vtkFloatArray::SafeDownCast(this->vtkArray);
    if(!floata){
        XdmfErrorMessage("Cannot downcast floatata array");
        return(0);
    }
    floata->SetArray((float *)array->GetDataPointer(), components * tuples, 0);
    }
    break;
  case XDMF_FLOAT64_TYPE :
    {
    vtkDoubleArray *doublea = vtkDoubleArray::SafeDownCast(this->vtkArray);
    if(!doublea){
        XdmfErrorMessage("Cannot downcast doubleata array");
        return(0);
    }
    doublea->SetArray((double *)array->GetDataPointer(), components * tuples, 0);
    }
    break;
  default :
    XdmfErrorMessage("Can't handle number type");
    return(0);
    break;
  }
  array->Reset();
  }
  return( this->vtkArray );
}

//----------------------------------------------------------------------------
char *vtkXdmfDataArray::ToXdmfArray( vtkDataArray *DataArray, int CopyShape ){
  XdmfArray *array;
  if ( DataArray  == NULL )  {
    DataArray = this->vtkArray;
  }
  if ( DataArray  == NULL )  {
    vtkDebugMacro(<< "Array is NULL");
    return(NULL);
  }
  if ( this->Array == NULL ){
    this->Array = new XdmfArray();
    switch( DataArray->GetDataType() ){
    case VTK_CHAR :
    case VTK_UNSIGNED_CHAR :
      this->Array->SetNumberType( XDMF_INT8_TYPE );
      break;
    case VTK_SHORT :
    case VTK_UNSIGNED_SHORT :
    case VTK_INT :
    case VTK_UNSIGNED_INT :
    case VTK_LONG :
    case VTK_UNSIGNED_LONG :
      this->Array->SetNumberType( XDMF_INT32_TYPE );
      break;
    case VTK_FLOAT :
      this->Array->SetNumberType( XDMF_FLOAT32_TYPE );
      break;
    case VTK_DOUBLE :
      this->Array->SetNumberType( XDMF_FLOAT64_TYPE );
      break;
    default :
      XdmfErrorMessage("Can't handle Data Type");
      return( NULL );
    }
  }
  array = this->Array;
  if( CopyShape ) {
    XdmfInt64 Shape[3];

    Shape[0] = DataArray->GetNumberOfTuples();
    Shape[1] = DataArray->GetNumberOfComponents();
    if( Shape[1] == 1 ) {
      array->SetShape( 1, Shape );
    } else {
      array->SetShape( 2, Shape );
    }

  }
  switch( array->GetNumberType() ){
  case XDMF_INT8_TYPE :
    array->SetValues( 0,
      ( unsigned char  *)DataArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_INT32_TYPE :
  case XDMF_INT64_TYPE :
    array->SetValues( 0,
      ( int *)DataArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  case XDMF_FLOAT32_TYPE :
    array->SetValues( 0,
      ( float *)DataArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  default :
    array->SetValues( 0,
      ( double *)DataArray->GetVoidPointer( 0 ),
      array->GetNumberOfElements() );
    break;
  }
  return( array->GetTagName() );
}
<|endoftext|>


<commit_before>#include <blocxx/Logger.hpp>
#include <blocxx/AppenderLogger.hpp>
#include <blocxx/CerrLogger.hpp>
#include <blocxx/CerrAppender.hpp>
#include <blocxx/String.hpp>
#include <blocxx/PerlRegEx.hpp>
#include <limal/Logger.hpp>
#include <limal/PathInfo.hpp>
#include <limal/ca-mgm/CA.hpp>
#include <limal/Exception.hpp>

#include <iostream>
#include <fstream>
#include <unistd.h>

using namespace blocxx;
using namespace limal;
using namespace limal::ca_mgm;
using namespace std;

int main()
{
    try
    {
        cout << "START" << endl;

        blocxx::StringArray cat;
        cat.push_back("FATAL");
        cat.push_back("ERROR");
        cat.push_back("INFO");
        //cat.push_back("DEBUG");

        // Logging
        LoggerRef l = limal::Logger::createCerrLogger(
                                                      "UpdateDBTest",
                                                      LogAppender::ALL_COMPONENTS,
                                                      cat,
                                                      "%-5p %c - %m"
                                                      );
        limal::Logger::setDefaultLogger(l);

        cout << "=================== start Update DB ======================" << endl;
        {
            CA ca("Test_CA1", "system", "./TestRepos/");

            ca.updateDB();

            cout << "UpdateDB successfully executed" << endl;
        }

        cout << "=================== test wrong password ==================" << endl;

        try
        {
            CA ca2("Test_CA1", "tralla", "./TestRepos/");

            ca2.updateDB();
        }
        catch(RuntimeException &re)
        {
            cout << "Got RuntimeException. This is ok!" << endl;
        }
        cout << "=================== end Update DB ========================" << endl;

        cout << "DONE" << endl;
    }
    catch(Exception& e)
    {
        cerr << e << endl;
    }

    return 0;
}

/* vim: set ts=8 sts=8 sw=8 ai noet: */
<commit_msg>catch other exception<commit_after>#include <blocxx/Logger.hpp>
#include <blocxx/AppenderLogger.hpp>
#include <blocxx/CerrLogger.hpp>
#include <blocxx/CerrAppender.hpp>
#include <blocxx/String.hpp>
#include <blocxx/PerlRegEx.hpp>
#include <limal/Logger.hpp>
#include <limal/PathInfo.hpp>
#include <limal/ca-mgm/CA.hpp>
#include <limal/Exception.hpp>

#include <iostream>
#include <fstream>
#include <unistd.h>

using namespace blocxx;
using namespace limal;
using namespace limal::ca_mgm;
using namespace std;

int main()
{
    try
    {
        cout << "START" << endl;

        blocxx::StringArray cat;
        cat.push_back("FATAL");
        cat.push_back("ERROR");
        cat.push_back("INFO");
        //cat.push_back("DEBUG");

        // Logging
        LoggerRef l = limal::Logger::createCerrLogger(
                                                      "UpdateDBTest",
                                                      LogAppender::ALL_COMPONENTS,
                                                      cat,
                                                      "%-5p %c - %m"
                                                      );
        limal::Logger::setDefaultLogger(l);

        cout << "=================== start Update DB ======================" << endl;
        {
            CA ca("Test_CA1", "system", "./TestRepos/");

            ca.updateDB();

            cout << "UpdateDB successfully executed" << endl;
        }

        cout << "=================== test wrong password ==================" << endl;

        try
        {
            CA ca2("Test_CA1", "tralla", "./TestRepos/");

            ca2.updateDB();
        }
        catch(ValueException &re)
        {
            cout << "Got ValueException. This is ok!" << endl;
        }
        cout << "=================== end Update DB ========================" << endl;

        cout << "DONE" << endl;
    }
    catch(Exception& e)
    {
        cerr << e << endl;
    }

    return 0;
}

/* vim: set ts=8 sts=8 sw=8 ai noet: */
<|endoftext|>


<commit_before>/*
  oscarcontact.cpp  -  Oscar Protocol Plugin

  Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
  Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

  *************************************************************************
  *                                                                       *
  * This program is free software; you can redistribute it and/or modify  *
  * it under the terms of the GNU General Public License as published by  *
  * the Free Software Foundation; either version 2 of the License, or     *
  * (at your option) any later version.                                   *
  *                                                                       *
  *************************************************************************
*/

#include "oscarcontact.h"

#include <time.h>

#include <qapplication.h>

#include <kaction.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>

#include <kdeversion.h>

#include "kopeteaccount.h"
#include "kopetemessagemanagerfactory.h"
#include "kopetemetacontact.h"
#include "kopetecontactlist.h"
#include "kopetegroup.h"
#include "kopeteuiglobal.h"
#include <kopeteglobal.h>

#include "oscaraccount.h"
#include "client.h"
#include "ssimanager.h"
#include "oscarutils.h"

#include <assert.h>

OscarContact::OscarContact( Kopete::Account* account, const QString& name,
                            Kopete::MetaContact* parent, const QString& icon, const SSI& ssiItem )
: Kopete::Contact( account, name, parent, icon )
{
	mAccount = static_cast<OscarAccount*>(account);
	mName = name;
	mMsgManager = 0L;
	m_ssiItem = ssiItem;
	connect( this, SIGNAL( updatedSSI() ), this, SLOT( updateSSIItem() ) );
}

OscarContact::~OscarContact()
{
}

void OscarContact::serialize(QMap<QString, QString> &serializedData,
                             QMap<QString, QString> &/*addressBookData*/)
{
	serializedData["ssi_name"] = m_ssiItem.name();
	serializedData["ssi_type"] = QString::number( m_ssiItem.type() );
	serializedData["ssi_gid"] = QString::number( m_ssiItem.gid() );
	serializedData["ssi_bid"] = QString::number( m_ssiItem.bid() );
	serializedData["ssi_alias"] = m_ssiItem.alias();
	serializedData["ssi_waitingAuth"] = m_ssiItem.waitingAuth() ? QString::fromLatin1( "true" ) : QString::fromLatin1( "false" );
}

bool OscarContact::isOnServer() const
{
	return ( m_ssiItem.type() != 0xFFFF );
}

void OscarContact::setSSIItem( const Oscar::SSI& ssiItem )
{
	m_ssiItem = ssiItem;
	emit updatedSSI();
}

Oscar::SSI OscarContact::ssiItem() const
{
	return m_ssiItem;
}

Kopete::ChatSession* OscarContact::manager( CanCreateFlags canCreate )
{
	if ( !mMsgManager && canCreate )
	{
		/*kdDebug(14190) << k_funcinfo <<
			"Creating new ChatSession for contact '" << displayName() << "'" << endl;*/

		QPtrList<Kopete::Contact> theContact;
		theContact.append(this);

		mMsgManager = Kopete::ChatSessionManager::self()->create(account()->myself(), theContact, protocol());

		// This is for when the user types a message and presses send
		connect(mMsgManager, SIGNAL( messageSent( Kopete::Message&, Kopete::ChatSession * ) ),
		        this, SLOT( slotSendMsg( Kopete::Message&, Kopete::ChatSession * ) ) );

		// For when the message manager is destroyed
		connect(mMsgManager, SIGNAL( destroyed() ),
		        this, SLOT( chatSessionDestroyed() ) );

		connect(mMsgManager, SIGNAL( myselfTyping( bool ) ),
		        this, SLOT( slotTyping( bool ) ) );
	}
	return mMsgManager;
}

void OscarContact::deleteContact()
{
	mAccount->engine()->removeContact( contactId() );
	deleteLater();
}

void OscarContact::chatSessionDestroyed()
{
	mMsgManager = 0L;
}

// Called when the metacontact owning this contact has changed groups
void OscarContact::sync(unsigned int flags)
{
	/*
	 * If the contact is waiting for auth, we do nothing
	 * If the contact has changed groups, then we update the server
	 *   adding the group if it doesn't exist, changing the ssi item
	 *   contained in the client and updating the contact's ssi item
	 * Otherwise, we don't do much
	 */
	if ( flags & Kopete::Contact::MovedBetweenGroup == Kopete::Contact::MovedBetweenGroup )
	{

		if ( m_ssiItem.waitingAuth() )
		{
			kdDebug(OSCAR_GEN_DEBUG) << k_funcinfo << "Contact still requires auth. Doing nothing" << endl;
			return;
		}

		kdDebug(OSCAR_GEN_DEBUG) << k_funcinfo << "Moving a contact between groups" << endl;
		SSIManager* ssiManager = mAccount->engine()->ssiManager();
		SSI oldGroup = ssiManager->findGroup( m_ssiItem.gid() );
		Kopete::Group* newGroup = metaContact()->groups().first();
		if ( newGroup->displayName() == oldGroup.name() )
			return; //we didn't really move

		if ( !ssiManager->findGroup( newGroup->displayName() ) )
		{ //we don't have the group on the server
			kdDebug(OSCAR_GEN_DEBUG) << k_funcinfo << "the group '" << newGroup->displayName() << "' is not on the server"
				<< "adding it" << endl;
			mAccount->engine()->addGroup( newGroup->displayName() );
		}

		SSI newSSIGroup = ssiManager->findGroup( newGroup->displayName() );
		if ( !newSSIGroup )
		{
			kdWarning(OSCAR_GEN_DEBUG) << k_funcinfo << newSSIGroup.name() << " not found on SSI list after addition!" << endl;
			return;
		}

		mAccount->engine()->changeContactGroup( contactId(), newGroup->displayName() );
		SSI newItem( m_ssiItem.name(), newSSIGroup.gid(), m_ssiItem.bid(), m_ssiItem.type(),
		             m_ssiItem.tlvList(), m_ssiItem.tlvListLength() );
		setSSIItem( newItem );
	}
	return;
}

void OscarContact::userInfoUpdated( const QString& contact, const UserDetails& details  )
{
	Q_UNUSED( contact );
	setIdleTime( details.idleTime() );
	m_warningLevel = details.warningLevel();
}

void OscarContact::slotSendMsg( Kopete::Message& msg, Kopete::ChatSession* session)
{
	//Why is this unused?
	Q_UNUSED( session );
	Oscar::Message message;

	message.setText( msg.plainBody() );

	message.setTimestamp( msg.timestamp() );
	message.setSender( mAccount->accountId() );
	message.setReceiver( mName );
	message.setType( 0x01 );

	//TODO add support for type 2 messages
	/*if ( msg.type() == Kopete::Message::PlainText )
		message.setType( 0x01 );
	else
		message.setType( 0x02 );*/
	//TODO: we need to check for channel 0x04 messages too;

	// isAuto defaults to false
	mAccount->engine()->sendMessage( message );
	manager(Kopete::Contact::CanCreate)->appendMessage(msg);
	manager(Kopete::Contact::CanCreate)->messageSucceeded();
}

void OscarContact::startedTyping()
{
	if ( mMsgManager )
		mMsgManager->receivedTypingMsg( this, true );
}

void OscarContact::stoppedTyping()
{
	if ( mMsgManager )
		mMsgManager->receivedTypingMsg( this, false );
}

void OscarContact::slotTyping( bool typing )
{
	if ( this != account()->myself() )
		account()->engine()->sendTyping( contactId(), typing );
}

#include "oscarcontact.moc"
//kate: tab-width 4; indent-mode csands;
<commit_msg>send escaped HTML to oscar, not raw html. BUG:99569<commit_after>/*
  oscarcontact.cpp  -  Oscar Protocol Plugin

  Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
  Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

  *************************************************************************
  *                                                                       *
  * This program is free software; you can redistribute it and/or modify  *
  * it under the terms of the GNU General Public License as published by  *
  * the Free Software Foundation; either version 2 of the License, or     *
  * (at your option) any later version.                                   *
  *                                                                       *
  *************************************************************************
*/

#include "oscarcontact.h"

#include <time.h>

#include <qapplication.h>

#include <kaction.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>

#include <kdeversion.h>

#include "kopeteaccount.h"
#include "kopetemessagemanagerfactory.h"
#include "kopetemetacontact.h"
#include "kopetecontactlist.h"
#include "kopetegroup.h"
#include "kopeteuiglobal.h"
#include <kopeteglobal.h>

#include "oscaraccount.h"
#include "client.h"
#include "ssimanager.h"
#include "oscarutils.h"

#include <assert.h>

OscarContact::OscarContact( Kopete::Account* account, const QString& name,
                            Kopete::MetaContact* parent, const QString& icon, const SSI& ssiItem )
: Kopete::Contact( account, name, parent, icon )
{
	mAccount = static_cast<OscarAccount*>(account);
	mName = name;
	mMsgManager = 0L;
	m_ssiItem = ssiItem;
	connect( this, SIGNAL( updatedSSI() ), this, SLOT( updateSSIItem() ) );
}

OscarContact::~OscarContact()
{
}

void OscarContact::serialize(QMap<QString, QString> &serializedData,
                             QMap<QString, QString> &/*addressBookData*/)
{
	serializedData["ssi_name"] = m_ssiItem.name();
	serializedData["ssi_type"] = QString::number( m_ssiItem.type() );
	serializedData["ssi_gid"] = QString::number( m_ssiItem.gid() );
	serializedData["ssi_bid"] = QString::number( m_ssiItem.bid() );
	serializedData["ssi_alias"] = m_ssiItem.alias();
	serializedData["ssi_waitingAuth"] = m_ssiItem.waitingAuth() ? QString::fromLatin1( "true" ) : QString::fromLatin1( "false" );
}

bool OscarContact::isOnServer() const
{
	return ( m_ssiItem.type() != 0xFFFF );
}

void OscarContact::setSSIItem( const Oscar::SSI& ssiItem )
{
	m_ssiItem = ssiItem;
	emit updatedSSI();
}

Oscar::SSI OscarContact::ssiItem() const
{
	return m_ssiItem;
}

Kopete::ChatSession* OscarContact::manager( CanCreateFlags canCreate )
{
	if ( !mMsgManager && canCreate )
	{
		/*kdDebug(14190) << k_funcinfo <<
			"Creating new ChatSession for contact '" << displayName() << "'" << endl;*/

		QPtrList<Kopete::Contact> theContact;
		theContact.append(this);

		mMsgManager = Kopete::ChatSessionManager::self()->create(account()->myself(), theContact, protocol());

		// This is for when the user types a message and presses send
		connect(mMsgManager, SIGNAL( messageSent( Kopete::Message&, Kopete::ChatSession * ) ),
		        this, SLOT( slotSendMsg( Kopete::Message&, Kopete::ChatSession * ) ) );

		// For when the message manager is destroyed
		connect(mMsgManager, SIGNAL( destroyed() ),
		        this, SLOT( chatSessionDestroyed() ) );

		connect(mMsgManager, SIGNAL( myselfTyping( bool ) ),
		        this, SLOT( slotTyping( bool ) ) );
	}
	return mMsgManager;
}

void OscarContact::deleteContact()
{
	mAccount->engine()->removeContact( contactId() );
	deleteLater();
}

void OscarContact::chatSessionDestroyed()
{
	mMsgManager = 0L;
}

// Called when the metacontact owning this contact has changed groups
void OscarContact::sync(unsigned int flags)
{
	/*
	 * If the contact is waiting for auth, we do nothing
	 * If the contact has changed groups, then we update the server
	 *   adding the group if it doesn't exist, changing the ssi item
	 *   contained in the client and updating the contact's ssi item
	 * Otherwise, we don't do much
	 */
	if ( flags & Kopete::Contact::MovedBetweenGroup == Kopete::Contact::MovedBetweenGroup )
	{

		if ( m_ssiItem.waitingAuth() )
		{
			kdDebug(OSCAR_GEN_DEBUG) << k_funcinfo << "Contact still requires auth. Doing nothing" << endl;
			return;
		}

		kdDebug(OSCAR_GEN_DEBUG) << k_funcinfo << "Moving a contact between groups" << endl;
		SSIManager* ssiManager = mAccount->engine()->ssiManager();
		SSI oldGroup = ssiManager->findGroup( m_ssiItem.gid() );
		Kopete::Group* newGroup = metaContact()->groups().first();
		if ( newGroup->displayName() == oldGroup.name() )
			return; //we didn't really move

		if ( !ssiManager->findGroup( newGroup->displayName() ) )
		{ //we don't have the group on the server
			kdDebug(OSCAR_GEN_DEBUG) << k_funcinfo << "the group '" << newGroup->displayName() << "' is not on the server"
				<< "adding it" << endl;
			mAccount->engine()->addGroup( newGroup->displayName() );
		}

		SSI newSSIGroup = ssiManager->findGroup( newGroup->displayName() );
		if ( !newSSIGroup )
		{
			kdWarning(OSCAR_GEN_DEBUG) << k_funcinfo << newSSIGroup.name() << " not found on SSI list after addition!" << endl;
			return;
		}

		mAccount->engine()->changeContactGroup( contactId(), newGroup->displayName() );
		SSI newItem( m_ssiItem.name(), newSSIGroup.gid(), m_ssiItem.bid(), m_ssiItem.type(),
		             m_ssiItem.tlvList(), m_ssiItem.tlvListLength() );
		setSSIItem( newItem );
	}
	return;
}

void OscarContact::userInfoUpdated( const QString& contact, const UserDetails& details  )
{
	Q_UNUSED( contact );
	setIdleTime( details.idleTime() );
	m_warningLevel = details.warningLevel();
}

void OscarContact::slotSendMsg( Kopete::Message& msg, Kopete::ChatSession* session)
{
	//Why is this unused?
	Q_UNUSED( session );
	Oscar::Message message;

	if ( account()->engine()->isIcq() )
		message.setText( msg.plainBody() );
	else
		message.setText( msg.escapedBody() );

	message.setTimestamp( msg.timestamp() );
	message.setSender( mAccount->accountId() );
	message.setReceiver( mName );
	message.setType( 0x01 );

	//TODO add support for type 2 messages
	/*if ( msg.type() == Kopete::Message::PlainText )
		message.setType( 0x01 );
	else
		message.setType( 0x02 );*/
	//TODO: we need to check for channel 0x04 messages too;

	// isAuto defaults to false
	mAccount->engine()->sendMessage( message );
	manager(Kopete::Contact::CanCreate)->appendMessage(msg);
	manager(Kopete::Contact::CanCreate)->messageSucceeded();
}

void OscarContact::startedTyping()
{
	if ( mMsgManager )
		mMsgManager->receivedTypingMsg( this, true );
}

void OscarContact::stoppedTyping()
{
	if ( mMsgManager )
		mMsgManager->receivedTypingMsg( this, false );
}

void OscarContact::slotTyping( bool typing )
{
	if ( this != account()->myself() )
		account()->engine()->sendTyping( contactId(), typing );
}

#include "oscarcontact.moc"
//kate: tab-width 4; indent-mode csands;
<|endoftext|>


<commit_before>/**
 * C S O U N D   V S T
 *
 * A VST plugin version of Csound, with Python scripting.
 *
 * L I C E N S E
 *
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#if defined(_MSC_VER) && !defined(__GNUC__)
#pragma warning (disable:4786)
#endif
#include "Composition.hpp"
#include "System.hpp"

namespace csound
{
  Composition::Composition() :
    tonesPerOctave(12.0),
    conformPitches(false),
    cppSound(&cppSound_)
  {
  }

  Composition::~Composition()
  {
  }

  void Composition::render()
  {
    generate();
    createCsoundScore();
    perform();
  }

  void Composition::createCsoundScore(std::string addToScore, double extendSeconds)
  {
    System::inform("addToScore.length(): %d\n", addToScore.length());
    if (addToScore.length() > 2) {
      cppSound->removeScore();
      cppSound->addScoreLine(addToScore);
    }
    cppSound->addScoreLine(score.getCsoundScore(tonesPerOctave, conformPitches));
    char buffer[0x100];
    std::sprintf(buffer, "\ne %9.3f", extendSeconds);
    cppSound->addScoreLine(buffer);
    cppSound->exportForPerformance();
  }

  void Composition::perform()
  {
    cppSound->perform();
  }

  void Composition::generate()
  {
  }

  void Composition::clear()
  {
    score.clear();
    cppSound->removeScore();
  }

  Score &Composition::getScore()
  {
    return score;
  }

  void Composition::setCppSound(CppSound *cppSound)
  {
    if(!cppSound)
      {
        this->cppSound = &cppSound_;
      }
    else
      {
        this->cppSound = cppSound;
      }
  }

  CppSound *Composition::getCppSound()
  {
    return cppSound;
  }

  void Composition::write(const char *text)
  {
    System::message(text);
  }

  void Composition::setTonesPerOctave(double tonesPerOctave)
  {
    this->tonesPerOctave = tonesPerOctave;
  }

  double Composition::getTonesPerOctave() const
  {
    return tonesPerOctave;
  }

  void Composition::setConformPitches(bool conformPitches)
  {
    this->conformPitches = conformPitches;
  }

  bool Composition::getConformPitches() const
  {
    return conformPitches;
  }
}
<commit_msg>no message<commit_after>/**
 * C S O U N D   V S T
 *
 * A VST plugin version of Csound, with Python scripting.
 *
 * L I C E N S E
 *
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#if defined(_MSC_VER) && !defined(__GNUC__)
#pragma warning (disable:4786)
#endif
#include "Composition.hpp"
#include "System.hpp"

namespace csound
{
  Composition::Composition() :
    tonesPerOctave(12.0),
    conformPitches(false),
    cppSound(&cppSound_)
  {
  }

  Composition::~Composition()
  {
  }

  void Composition::render()
  {
    generate();
    createCsoundScore();
    perform();
  }

  void Composition::createCsoundScore(std::string addToScore, double extendSeconds)
  {
    System::inform("addToScore.length(): %d\n", addToScore.length());
    if (addToScore.length() > 2) {
      cppSound->removeScore();
      cppSound->addScoreLine(addToScore);
    }
    cppSound->addScoreLine(score.getCsoundScore(tonesPerOctave, conformPitches));
    char buffer[0x100];
    std::sprintf(buffer, "\ns %9.3f", extendSeconds);
    cppSound->addScoreLine(buffer);
    std::sprintf(buffer, "\ne %9.3f", 5.0);
    cppSound->addScoreLine(buffer);
    cppSound->exportForPerformance();
  }

  void Composition::perform()
  {
    cppSound->perform();
  }

  void Composition::generate()
  {
  }

  void Composition::clear()
  {
    score.clear();
    cppSound->removeScore();
  }

  Score &Composition::getScore()
  {
    return score;
  }

  void Composition::setCppSound(CppSound *cppSound)
  {
    if(!cppSound)
      {
        this->cppSound = &cppSound_;
      }
    else
      {
        this->cppSound = cppSound;
      }
  }

  CppSound *Composition::getCppSound()
  {
    return cppSound;
  }

  void Composition::write(const char *text)
  {
    System::message(text);
  }

  void Composition::setTonesPerOctave(double tonesPerOctave)
  {
    this->tonesPerOctave = tonesPerOctave;
  }

  double Composition::getTonesPerOctave() const
  {
    return tonesPerOctave;
  }

  void Composition::setConformPitches(bool conformPitches)
  {
    this->conformPitches = conformPitches;
  }

  bool Composition::getConformPitches() const
  {
    return conformPitches;
  }
}
<|endoftext|>


<commit_before>#pragma once

#include <Core/Math/Math.hpp>
#include <Core/Types.hpp>
#include <Core/Utils/Observable.hpp>
namespace Ra {
namespace Core {
namespace Asset {

/// \brief Camera class storing the Camera frame and the projection properties
/// The view direction is -z in camera space.
/// \note Both orthonormal and non-orthonormal frames are supported. However, in the current
/// implementation suspect a bug in fitZRange which does not behave as expected for non-orthogonal
/// frames..
class RA_CORE_API Camera
{
  public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW

    /// Define the projection type.
    enum class ProjType { ORTHOGRAPHIC, PERSPECTIVE };

    Camera( Scalar height = 1_ra, Scalar width = 1_ra );

    ~Camera() = default;

    Camera& operator=( const Camera& rhs );

    /// Return the frame of the camera.
    /// Where Y is the up vector and -Z is the direction vector.
    inline Core::Transform getFrame() const;

    /// Set the frame of the camera to 'frame'
    inline void setFrame( const Core::Transform& frame );

    /// Return the position.
    inline Core::Vector3 getPosition() const;

    /// Set the position of the camera to 'position'.
    inline void setPosition( const Core::Vector3& position );

    /// Return the direction the camera is looking at.
    inline Core::Vector3 getDirection() const;

    /// Set the direction of the camera to 'direction'.
    /// The other vectors will be rotated accordingly.
    void setDirection( const Core::Vector3& direction );

    /// Return the up vector.
    inline Core::Vector3 getUpVector() const;

    /// Set the up vector of the camera to 'upVector'.
    /// The other vectors will be rotated accordingly.
    inline void setUpVector( const Core::Vector3& upVector );

    inline Core::Vector3 getRightVector() const;

    //
    // Utility functions
    //

    // Note : in all screen pixels coordinates function, Y is taken to be in standard UI-libs style
    // coordinates, i.e. Y=0 is the top line and Y=height is the bottom line.

    /// Return a ray emanating from the camera, passing by the point given by
    /// screen coordinates x and y.
    Core::Ray getRayFromScreen( const Core::Vector2& pix ) const;

    /// Return the screen coordinates + depth of the given point p (in world coordinates).
    Core::Vector3 projectToScreen( const Core::Vector3& p ) const;

    /// return NDC cordinate in the view NDC cube [-1,1]^3
    Core::Vector3 projectToNDC( const Core::Vector3& p ) const;

    /// Return the point on the screen plane (near plane) represented by screen coordinates pix.
    /// use z = 0 (near plane)
    Core::Vector3 unProjectFromScreen( const Core::Vector2& pix ) const;
    /// Return the 3D point in world space corresponding to screen pixels pix.x(), pix.y(), at depth
    /// pix.z()
    /// x and y are in pixel coordinates (from (0,0) to width,height, z is in 0, 1 (0 near, 1 far
    /// plane)
    Core::Vector3 unProjectFromScreen( const Core::Vector3& pix ) const;
    Core::Vector3 unProjectFromNDC( const Core::Vector3& pix ) const;

    //
    // Getters and setters for projection matrix parameters.
    //

    /// Return the projection type.
    inline ProjType getType() const;

    /// Set the projection type to 'projectionType'.
    inline void setType( const ProjType& projectionType );

    /// Return the zoom factor.
    inline Scalar getZoomFactor() const;

    /// Set the zoom factor to 'zoomFactor'.
    inline void setZoomFactor( const Scalar& zoomFactor );

    /// Return the horizontal Field Of View.
    /// \note Meaningless for orthogonal projection.
    inline Scalar getFOV() const;

    /// Set the Field Of View to 'fov' in the x (horizontal) direction.
    /// \note Meaningless for orthogonal projection.
    /// \warning Trigger a rebuild of the projection matrix.
    inline void setFOV( Scalar fov );

    inline Scalar getMinZNear() const;
    inline Scalar getMinZRange() const;

    /// Return the projection matrix.
    inline Core::Matrix4 getProjMatrix() const;
    inline Core::Matrix4 getViewMatrix() const;

    /// Update the projection matrix according to the current parameters.
    void updateProjMatrix();

    inline void setProjMatrix( Core::Matrix4 projMatrix );

    /// Return the Z Near plane distance from the camera.
    inline Scalar getZNear() const;

    /// Set the Z Near plane distance to 'zNear'.
    inline void setZNear( Scalar zNear );

    /// Return the Z Far plane distance from the camera.
    inline Scalar getZFar() const;

    /// Set the Z Far plane distance to 'zFar'.
    inline void setZFar( Scalar zFar );

    /// Return the width of the viewport.
    inline Scalar getWidth() const;

    /// Return the height of the viewport.
    inline Scalar getHeight() const;

    /// Return the aspect ratio of the viewport.
    inline Scalar getAspect() const;

    /// Set xmag and ymag for orthographic camera
    inline void setXYmag( Scalar xmag, Scalar ymag );

    /// Get xmag and ymag for orthographic camera
    inline std::pair<Scalar, Scalar> getXYmag() const;

    /// Change the viewport size. Also compute aspectRatio.
    void setViewport( Scalar width, Scalar height );

    void applyTransform( const Core::Transform& T );

    /// Fit the Z-range of the camera to the scene's aabb. This will maximize z-buffer precision
    void fitZRange( const Core::Aabb& aabb );

    const Scalar m_minZNear {0.01_ra};
    const Scalar m_minZRange {0.01_ra};

    /// Compute a project projection matrix as describe here
    /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
    /// adapted to horizontal fov
    /// equivalent to scale = tan(m_fov*.5)*m_zNear
    /// frustum(-n*tan(f/2), n*tan(f/2), -n*tan(f/2)/aspect, n*tan(f/2)/aspect, n, f);
    /// \param a : aspect ratio as width/height, i.e. getAspect()
    /// \param y : fov in the horizontal direction, i.e. getFOV()
    /// \param n : z near, i.e. getZNear()
    /// \param f : z far, i.e. getZFar()
    static Core::Matrix4 perspective( Scalar a, Scalar y, Scalar n, Scalar f );

    /// \brief Build a projection matrix from the parameters of the view volume
    /// \see perspective()
    /// Implements the algorithm described here
    /// https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix
    /// https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml
    /// \param l : left
    /// \param r : right
    /// \param b : bottom
    /// \param t : top
    /// \param n : z near
    /// \param f : z far
    static Core::Matrix4 frustum( Scalar l, Scalar r, Scalar b, Scalar t, Scalar n, Scalar f );

    /// \brief Build a projection matrix from the parameters of the view volume
    /// Implements the algorithm described here
    /// https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/orthographic-projection-matrix
    /// https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml
    /// \param l : left
    /// \param r : right
    /// \param b : bottom
    /// \param t : top
    /// \param n : z near
    /// \param f : z far
    static Core::Matrix4 ortho( Scalar l, Scalar r, Scalar b, Scalar t, Scalar n, Scalar f );

  private:
    Core::Transform m_frame {
        Core::Transform::Identity()}; ///< Camera frame (inverse of the view matrix)

    Core::Matrix4 m_projMatrix {Core::Matrix4::Identity()}; ///< Projection matrix

    Scalar m_width {1_ra};  ///< Viewport width (in pixels)
    Scalar m_height {1_ra}; ///< Viewport height (in pixels)
    Scalar m_aspect {1_ra}; ///< Aspect ratio, i.e. width/height. Precomputed for updateProjMatrix.

    ProjType m_projType {ProjType::PERSPECTIVE}; ///< Projection type
    Scalar m_zoomFactor {1_ra};                  ///< Zoom factor (modifies the field of view)
    Scalar m_zNear {0.1_ra};                     ///< Z Near plane distance
    Scalar m_zFar {1000_ra};                     ///< Z Far plane distance

    /// \name Perspective projection parameters
    ///@{
    Scalar m_fov {Core::Math::PiDiv4}; ///< Horizontal Field Of View
    ///@}

    /// \name Orthographic projection parameters
    ///@{
    Scalar m_xmag {1_ra};
    Scalar m_ymag {1_ra};
    ///@}
};
} // namespace Asset
} // namespace Core
} // namespace Ra

#include <Core/Asset/Camera.inl>
<commit_msg>[core] camera comments.<commit_after>#pragma once

#include <Core/Math/Math.hpp>
#include <Core/Types.hpp>
#include <Core/Utils/Observable.hpp>
namespace Ra {
namespace Core {
namespace Asset {

/// \brief Camera class storing the Camera frame and the projection properties
/// The view direction is -z in camera space.
/// \note Both orthonormal and non-orthonormal frames are supported. However, in the current
/// implementation suspect a bug in fitZRange which does not behave as expected for non-orthogonal
/// frames..
class RA_CORE_API Camera
{
  public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW

    /// Define the projection type.
    enum class ProjType { ORTHOGRAPHIC, PERSPECTIVE };

    Camera( Scalar height = 1_ra, Scalar width = 1_ra );

    ~Camera() = default;

    Camera& operator=( const Camera& rhs );

    /// Return the frame of the camera.
    /// Where Y is the up vector and -Z is the direction vector.
    inline Core::Transform getFrame() const;

    /// Set the frame of the camera to 'frame'
    inline void setFrame( const Core::Transform& frame );

    /// Return the position.
    inline Core::Vector3 getPosition() const;

    /// Set the position of the camera to 'position'.
    inline void setPosition( const Core::Vector3& position );

    /// Return the direction the camera is looking at.
    inline Core::Vector3 getDirection() const;

    /// Set the direction of the camera to 'direction'.
    /// The other vectors will be rotated accordingly.
    void setDirection( const Core::Vector3& direction );

    /// Return the up vector.
    inline Core::Vector3 getUpVector() const;

    /// Set the up vector of the camera to 'upVector'.
    /// The other vectors will be rotated accordingly.
    inline void setUpVector( const Core::Vector3& upVector );

    inline Core::Vector3 getRightVector() const;

    //
    // Utility functions
    //

    // Note : in all screen pixels coordinates function, Y is taken to be in standard UI-libs style
    // coordinates, i.e. Y=0 is the top line and Y=height is the bottom line.

    /// Return a ray emanating from the camera, passing by the point given by
    /// screen coordinates x and y.
    Core::Ray getRayFromScreen( const Core::Vector2& pix ) const;

    /// Return the screen coordinates + depth of the given point p (in world coordinates).
    Core::Vector3 projectToScreen( const Core::Vector3& p ) const;

    /// return NDC cordinate in the view NDC cube [-1,1]^3
    Core::Vector3 projectToNDC( const Core::Vector3& p ) const;

    /// Return the point on the screen plane (near plane) represented by screen coordinates pix.
    /// use z = 0 (near plane)
    Core::Vector3 unProjectFromScreen( const Core::Vector2& pix ) const;
    /// Return the 3D point in world space corresponding to screen pixels pix.x(), pix.y(), at depth
    /// pix.z()
    /// x and y are in pixel coordinates (from (0,0) to width,height, z is in 0, 1 (0 near, 1 far
    /// plane)
    Core::Vector3 unProjectFromScreen( const Core::Vector3& pix ) const;
    Core::Vector3 unProjectFromNDC( const Core::Vector3& pix ) const;

    //
    // Getters and setters for projection matrix parameters.
    //

    /// Return the projection type.
    inline ProjType getType() const;

    /// Set the projection type to 'projectionType'.
    inline void setType( const ProjType& projectionType );

    /// Return the zoom factor.
    inline Scalar getZoomFactor() const;

    /// Set the zoom factor to 'zoomFactor'.
    inline void setZoomFactor( const Scalar& zoomFactor );

    /// Return the horizontal Field Of View.
    /// \note Meaningless for orthogonal projection.
    inline Scalar getFOV() const;

    /// Set the Field Of View to 'fov' in the x (horizontal) direction.
    /// If you have an vertical field of view, you can convert it to horizontal as
    /// Scalar fovx = 2_ra*std::atan( radiumCam->getAspect() * std::tan( cam.yfov / 2_ra ) );
    //        if ( fovxDiv2 < 0_ra ) { fovxDiv2 = Ra::Core::Math::PiDiv2; }
    /// \note Meaningless for orthogonal projection.
    /// \warning Trigger a rebuild of the projection matrix.
    inline void setFOV( Scalar fov );

    inline Scalar getMinZNear() const;
    inline Scalar getMinZRange() const;

    /// Return the projection matrix.
    inline Core::Matrix4 getProjMatrix() const;
    inline Core::Matrix4 getViewMatrix() const;

    /// Update the projection matrix according to the current parameters.
    void updateProjMatrix();

    inline void setProjMatrix( Core::Matrix4 projMatrix );

    /// Return the Z Near plane distance from the camera.
    inline Scalar getZNear() const;

    /// Set the Z Near plane distance to 'zNear'.
    inline void setZNear( Scalar zNear );

    /// Return the Z Far plane distance from the camera.
    inline Scalar getZFar() const;

    /// Set the Z Far plane distance to 'zFar'.
    inline void setZFar( Scalar zFar );

    /// Return the width of the viewport.
    inline Scalar getWidth() const;

    /// Return the height of the viewport.
    inline Scalar getHeight() const;

    /// Return the aspect ratio of the viewport.
    inline Scalar getAspect() const;

    /// Set xmag and ymag for orthographic camera
    inline void setXYmag( Scalar xmag, Scalar ymag );

    /// Get xmag and ymag for orthographic camera
    inline std::pair<Scalar, Scalar> getXYmag() const;

    /// Change the viewport size. Also compute aspectRatio.
    void setViewport( Scalar width, Scalar height );

    void applyTransform( const Core::Transform& T );

    /// Fit the Z-range of the camera to the scene's aabb. This will maximize z-buffer precision
    void fitZRange( const Core::Aabb& aabb );

    const Scalar m_minZNear {0.01_ra};
    const Scalar m_minZRange {0.01_ra};

    /// Compute a project projection matrix as describe here
    /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
    /// adapted to horizontal fov
    /// equivalent to scale = tan(m_fov*.5)*m_zNear
    /// frustum(-n*tan(f/2), n*tan(f/2), -n*tan(f/2)/aspect, n*tan(f/2)/aspect, n, f);
    /// \param a : aspect ratio as width/height, i.e. getAspect()
    /// \param y : fov in the horizontal direction, i.e. getFOV()
    /// \param n : z near, i.e. getZNear()
    /// \param f : z far, i.e. getZFar()
    static Core::Matrix4 perspective( Scalar a, Scalar y, Scalar n, Scalar f );

    /// \brief Build a projection matrix from the parameters of the view volume
    /// \see perspective()
    /// Implements the algorithm described here
    /// https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix
    /// https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml
    /// \param l : left
    /// \param r : right
    /// \param b : bottom
    /// \param t : top
    /// \param n : z near
    /// \param f : z far
    static Core::Matrix4 frustum( Scalar l, Scalar r, Scalar b, Scalar t, Scalar n, Scalar f );

    /// \brief Build a projection matrix from the parameters of the view volume
    /// Implements the algorithm described here
    /// https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/orthographic-projection-matrix
    /// https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml
    /// \param l : left
    /// \param r : right
    /// \param b : bottom
    /// \param t : top
    /// \param n : z near
    /// \param f : z far
    static Core::Matrix4 ortho( Scalar l, Scalar r, Scalar b, Scalar t, Scalar n, Scalar f );

  private:
    /// Camera frame (inverse of the view matrix).
    /// This represent the transformation from view space to world space.
    Core::Transform m_frame {Core::Transform::Identity()};

    Core::Matrix4 m_projMatrix {Core::Matrix4::Identity()}; ///< Projection matrix

    Scalar m_width {1_ra};  ///< Viewport width (in pixels)
    Scalar m_height {1_ra}; ///< Viewport height (in pixels)
    Scalar m_aspect {1_ra}; ///< Aspect ratio, i.e. width/height. Precomputed for updateProjMatrix.

    ProjType m_projType {ProjType::PERSPECTIVE}; ///< Projection type
    Scalar m_zoomFactor {1_ra};                  ///< Zoom factor (modifies the field of view)
    Scalar m_zNear {0.1_ra};                     ///< Z Near plane distance
    Scalar m_zFar {1000_ra};                     ///< Z Far plane distance

    /// \name Perspective projection parameters
    ///@{
    Scalar m_fov {Core::Math::PiDiv4}; ///< Horizontal Field Of View
    ///@}

    /// \name Orthographic projection parameters
    ///@{
    Scalar m_xmag {1_ra};
    Scalar m_ymag {1_ra};
    ///@}
};
} // namespace Asset
} // namespace Core
} // namespace Ra

#include <Core/Asset/Camera.inl>
<|endoftext|>