<commit_before>#include "CoolProp.h"
#include <vector>
#include "CPExceptions.h"
#include "FluidClass.h"
#include "R161.h"

R161Class::R161Class()
{
	double n[] = {0.0, 1.511, -2.3, -0.457, 0.1683, 0.04133, 0.62187, -0.0265, -1.03, -0.285, -0.476, 0.82, -0.3532, -0.116, -0.0220583, -1.63148};
	double t[] = {0, 0.37, 0.97, 1.14, 0.744, 1, 1.26, 1, 1.8, 3, 2.25, 1, 1.2, 5.3, 1, 4};
	double d[] = {0, 1, 1, 2, 3, 4, 2, 7, 1, 2, 3, 1, 1, 3, 3, 3};
	double c[] = {0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0};
	double eta[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.96, 1.35, 1.26, 1.23, 16.8};
	double beta[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.7, 5.2, 3.9, 4.7, 413};
	double gamma[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.9, 0.69, 0.67, 0.67, 1.15};
	double epsilon[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.683, 0.892, 0.785, 1.33, 0.86};

	//Critical parameters
	crit.rho = 6.28*48.0595; //[kg/m^3]
	crit.p = PressureUnit(5010, UNIT_KPA); //[kPa]
	crit.T = 375.25; //[K]
	crit.v = 1/crit.rho;

	// Other fluid parameters
	params.molemass = 48.0595;
	params.Ttriple = 130;
	params.accentricfactor = 0.21624284106618674;
	params.R_u = 8.314472;
	params.ptriple = 0.005512;

	// Limits of EOS
	limits.Tmin = 130;
	limits.Tmax = 500.0;
	limits.pmax = 100000.0;
	limits.rhomax = 1000000.0*params.molemass;

	phirlist.push_back(new phir_power( n,d,t,c,1,10,16));
	phirlist.push_back(new phir_gaussian( n,d,t, eta, epsilon, beta, gamma, 11,15,16));

	const double a0 = -6.9187, a1 = 5.4788, n0 = 4;
	phi0list.push_back(new phi0_lead(a0, a1));
	phi0list.push_back(new phi0_logtau(n0-1));

	const double u0[] = {0, 420/crit.T, 1548/crit.T, 3882/crit.T};
	const double v0[] = {0, 2.059, 9.253, 6.088};
	std::vector<double> u0_v(u0,u0+sizeof(u0)/sizeof(double));
	std::vector<double> v0_v(v0,v0+sizeof(v0)/sizeof(double));

	phi0list.push_back(new phi0_Planck_Einstein(v0_v,u0_v,1,3));

	EOSReference.assign("Jiangtao Wu and Yong Zhou, \"An Equation of State for Fluoroethane (R161)\", Int J Thermophys (2012) 33:220�234");
	TransportReference.assign("Using ECS in fully predictive mode.");

	name.assign("R161");
	//aliases.push_back(std::string("R161"));
	REFPROPname.assign("R161");

	BibTeXKeys.EOS = "Wu-IJT-2012";
	BibTeXKeys.SURFACE_TENSION = "Mulero-JPCRD-2012";
}
double R161Class::psat(double T)
{
	// Max error is  0.230661857744 % between 130.0 and 375.249999 K
    const double t[]={0, 0.3575, 0.3605, 0.8333333333333334, 1.1666666666666667, 3.6666666666666665, 5.5};
    const double N[]={0, 0.31348208716072901, -0.23919030666253932, -3.2448016166944127, -3.2492132423845081, -1.5585118618296889, -2.427095112126342};
    double summer=0,theta;
    theta=1-T/reduce.T;
    for (int i=1; i<=6; i++)
    {
        summer += N[i]*pow(theta,t[i]);
    }
    return reduce.p.Pa*exp(reduce.T/T*summer);
}

double R161Class::rhosatL(double T)
{
    // Maximum absolute error is 0.240076 % between 130.000000 K and 375.250000 K
    const double t[] = {0, 0.3333333333333333, 0.5, 0.6666666666666666, 0.8333333333333334, 1.0, 1.1666666666666667, 1.3333333333333333, 1.5, 1.6666666666666667, 1.8333333333333333, 2.0};
    const double N[] = {0, -0.047548020147135293, 72.327097393829419, -819.54669834482479, 4946.726597164351, -18870.150565849312, 48463.342332873617, -84949.003918399481, 99927.349954656311, -75150.383145190368, 32522.693777539549, -6140.6005518003303};
    double summer=0,theta;
    theta=1-T/reduce.T;
	for (int i=1; i<=11; i++)
	{
		summer += N[i]*pow(theta,t[i]);
	}
	return reduce.rho*(summer+1);
}

double R161Class::rhosatV(double T)
{
    // Maximum absolute error is 0.294100 % between 130.000000 K and 375.250000 K
    const double t[] = {0, 0.3333333333333333, 0.5, 0.6666666666666666, 0.8333333333333334, 1.0, 1.1666666666666667, 1.3333333333333333, 1.5, 1.6666666666666667, 1.8333333333333333, 2.0, 2.1666666666666665};
    const double N[] = {0, 4.4900108859020449, -289.55507432056027, 4058.7708236096973, -29986.440551303382, 137204.7283140849, -417289.03201597766, 870535.22359268588, -1255033.5731927676, 1232137.9562410619, -787892.80993800913, 296355.72520564846, -49815.743244828758};
    double summer=0,theta;
    theta=1-T/reduce.T;
	for (int i=1; i<=12; i++)
	{
		summer += N[i]*pow(theta,t[i]);
	}
	return reduce.rho*exp(reduce.T/T*summer);
}
<commit_msg>Added alias to old R161 file<commit_after>#include "CoolProp.h"
#include <vector>
#include "CPExceptions.h"
#include "FluidClass.h"
#include "R161.h"

R161Class::R161Class()
{
	double n[] = {0.0, 1.511, -2.3, -0.457, 0.1683, 0.04133, 0.62187, -0.0265, -1.03, -0.285, -0.476, 0.82, -0.3532, -0.116, -0.0220583, -1.63148};
	double t[] = {0, 0.37, 0.97, 1.14, 0.744, 1, 1.26, 1, 1.8, 3, 2.25, 1, 1.2, 5.3, 1, 4};
	double d[] = {0, 1, 1, 2, 3, 4, 2, 7, 1, 2, 3, 1, 1, 3, 3, 3};
	double c[] = {0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0};
	double eta[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.96, 1.35, 1.26, 1.23, 16.8};
	double beta[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.7, 5.2, 3.9, 4.7, 413};
	double gamma[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.9, 0.69, 0.67, 0.67, 1.15};
	double epsilon[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.683, 0.892, 0.785, 1.33, 0.86};

	//Critical parameters
	crit.rho = 6.28*48.0595; //[kg/m^3]
	crit.p = PressureUnit(5010, UNIT_KPA); //[kPa]
	crit.T = 375.25; //[K]
	crit.v = 1/crit.rho;

	// Other fluid parameters
	params.molemass = 48.0595;
	params.Ttriple = 130;
	params.accentricfactor = 0.21624284106618674;
	params.R_u = 8.314472;
	params.ptriple = 0.005512;

	// Limits of EOS
	limits.Tmin = 130;
	limits.Tmax = 500.0;
	limits.pmax = 100000.0;
	limits.rhomax = 1000000.0*params.molemass;

	phirlist.push_back(new phir_power( n,d,t,c,1,10,16));
	phirlist.push_back(new phir_gaussian( n,d,t, eta, epsilon, beta, gamma, 11,15,16));

	const double a0 = -6.9187, a1 = 5.4788, n0 = 4;
	phi0list.push_back(new phi0_lead(a0, a1));
	phi0list.push_back(new phi0_logtau(n0-1));

	const double u0[] = {0, 420/crit.T, 1548/crit.T, 3882/crit.T};
	const double v0[] = {0, 2.059, 9.253, 6.088};

	phi0list.push_back(new phi0_Planck_Einstein(v0,u0,1,3,4));

	EOSReference.assign("Jiangtao Wu and Yong Zhou, \"An Equation of State for Fluoroethane (R161)\", Int J Thermophys (2012) 33:220�234");
	TransportReference.assign("Using ECS in fully predictive mode.");

	name.assign("R161");
	aliases.push_back(std::string("Fluoroethane"));
	REFPROPname.assign("R161");

	BibTeXKeys.EOS = "Wu-IJT-2012";
	BibTeXKeys.SURFACE_TENSION = "Mulero-JPCRD-2012";
}
double R161Class::psat(double T)
{
	// Max error is  0.230661857744 % between 130.0 and 375.249999 K
    const double t[]={0, 0.3575, 0.3605, 0.8333333333333334, 1.1666666666666667, 3.6666666666666665, 5.5};
    const double N[]={0, 0.31348208716072901, -0.23919030666253932, -3.2448016166944127, -3.2492132423845081, -1.5585118618296889, -2.427095112126342};
    double summer=0,theta;
    theta=1-T/reduce.T;
    for (int i=1; i<=6; i++)
    {
        summer += N[i]*pow(theta,t[i]);
    }
    return reduce.p.Pa*exp(reduce.T/T*summer);
}

double R161Class::rhosatL(double T)
{
    // Maximum absolute error is 0.240076 % between 130.000000 K and 375.250000 K
    const double t[] = {0, 0.3333333333333333, 0.5, 0.6666666666666666, 0.8333333333333334, 1.0, 1.1666666666666667, 1.3333333333333333, 1.5, 1.6666666666666667, 1.8333333333333333, 2.0};
    const double N[] = {0, -0.047548020147135293, 72.327097393829419, -819.54669834482479, 4946.726597164351, -18870.150565849312, 48463.342332873617, -84949.003918399481, 99927.349954656311, -75150.383145190368, 32522.693777539549, -6140.6005518003303};
    double summer=0,theta;
    theta=1-T/reduce.T;
	for (int i=1; i<=11; i++)
	{
		summer += N[i]*pow(theta,t[i]);
	}
	return reduce.rho*(summer+1);
}

double R161Class::rhosatV(double T)
{
    // Maximum absolute error is 0.294100 % between 130.000000 K and 375.250000 K
    const double t[] = {0, 0.3333333333333333, 0.5, 0.6666666666666666, 0.8333333333333334, 1.0, 1.1666666666666667, 1.3333333333333333, 1.5, 1.6666666666666667, 1.8333333333333333, 2.0, 2.1666666666666665};
    const double N[] = {0, 4.4900108859020449, -289.55507432056027, 4058.7708236096973, -29986.440551303382, 137204.7283140849, -417289.03201597766, 870535.22359268588, -1255033.5731927676, 1232137.9562410619, -787892.80993800913, 296355.72520564846, -49815.743244828758};
    double summer=0,theta;
    theta=1-T/reduce.T;
	for (int i=1; i<=12; i++)
	{
		summer += N[i]*pow(theta,t[i]);
	}
	return reduce.rho*exp(reduce.T/T*summer);
}
<|endoftext|>


<commit_before>// Inspired by http://opencv-srf.blogspot.com/2010/09/object-detection-using-color-seperation.html
#include "CMultiTrackerApp.h"

static 	TColorData				_colorCal;

CMultiTrackerApp::CMultiTrackerApp( char **argv )
	: _cap( atoi( argv[1] ) )
	, _controlWindow( argv[2] )
	, m_trackedObjects( 0 )
{
	_calibrationData.blue.colorId 	= "blue";
	_calibrationData.orange.colorId = "orange";
	_calibrationData.purple.colorId = "purple";
	_calibrationData.yellow.colorId = "yellow";
	_calibrationData.green.colorId 	= "green";
	_calibrationData.red.colorId 	= "red";

}

CMultiTrackerApp::~CMultiTrackerApp()
{

}

bool CMultiTrackerApp::Initialize()
{

	// Set blob parameters
	_params.minThreshold 		= 10;
	_params.maxThreshold 		= 200;

	_params.filterByArea 		= true;
	_params.minArea 			= 1500;

	_params.filterByCircularity = true;
	_params.minCircularity 		= 0.1;

	_params.filterByConvexity 	= true;
	_params.minConvexity 		= 0.87;

	_params.filterByInertia 	= true;
	_params.minInertiaRatio 	= 0.01;

	// Init detector with params
	_detector = cv::SimpleBlobDetector::create( _params );
	// _detector->detect( image, keyPoints ); // detect blob

	// We use this private class variable to disallow active changes to the calibration.
	// If we use the _calibrationData structure for calibration and adjustment in real time, we have to retrain
	// at this time.
	_colorCal.colorId = "init";

	_colorCal.lowH 	= 0;
	_colorCal.highH = 179;

	_colorCal.lowS 	= 0;
	_colorCal.highS = 255;

	_colorCal.lowV 	= 0;
	_colorCal.highV = 255;

	// Set control window
	cv::namedWindow( _controlWindow, CV_WINDOW_AUTOSIZE);

	// track bars for HSV tuning
	cv::createTrackbar( "LowH", _controlWindow, &_colorCal.lowH, 179 );
	cv::createTrackbar( "HighH", _controlWindow, &_colorCal.highH, 179 );

	cv::createTrackbar( "LowS", _controlWindow, &_colorCal.lowS, 255 );
	cv::createTrackbar( "HighS", _controlWindow, &_colorCal.highS, 255 );

	cv::createTrackbar( "LowV", _controlWindow, &_colorCal.lowV, 255 );
	cv::createTrackbar( "HighV", _controlWindow, &_colorCal.highV, 255 );

	// Buttons for color calibration
	cv::createButton( "Orange", CalibrateHSV, &_calibrationData.orange, CV_PUSH_BUTTON, 0 );
	cv::createButton( "Blue", CalibrateHSV, &_calibrationData.blue, CV_PUSH_BUTTON, 0 );

	cv::createButton( "Red", CalibrateHSV, &_calibrationData.red, CV_PUSH_BUTTON, 0 );
	cv::createButton( "Purple", CalibrateHSV, &_calibrationData.purple, CV_PUSH_BUTTON, 0 );

	cv::createButton( "Yellow", CalibrateHSV, &_calibrationData.yellow, CV_PUSH_BUTTON, 0 );
	cv::createButton( "Green", CalibrateHSV, &_calibrationData.green, CV_PUSH_BUTTON, 0 );

	return true;
}

void CMultiTrackerApp::CalibrateHSV( int stateIn, void *userDataIn )
{
	TColorData *calData = (TColorData*)userDataIn;

	LOG( INFO ) << "Calibratiing: " << calData->colorId;

	calData->lowH 	= _colorCal.lowH;
	calData->highH 	= _colorCal.highH;

	calData->lowS 	= _colorCal.lowS;
	calData->highS 	= _colorCal.highS;

	calData->lowV 	= _colorCal.lowV;
	calData->highV	= _colorCal.highV;

}

void CMultiTrackerApp::Run()
{
//	while( true )
//	{
		if( !_cap.read( _origImage ) )
		{
			LOG( ERROR ) << ">>>> Could not read from video stream: CLOSING <<<<";
//			break;
		}
		cv::Mat im = cv::imread( "roboops_test_image.png", cv::IMREAD_COLOR );

		cv::cvtColor( im, _imageHSV, cv::COLOR_BGR2HSV );

		cv::threshold( _imageHSV, _imageThreshold, 127, 255, cv::THRESH_TOZERO );

		// Morph open - remove small objects from the foreground
		cv::erode( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
		cv::dilate( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );

		// Morph close - fill small holes in foreground
		cv::dilate( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
		cv::erode( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );

		// Detect the blobs
		_detector->detect( _imageThreshold, _keyPoints );

		// Draw blobs as red circles
		// flags ensures the size of the circle corresponds to the size of the blob
		cv::Mat _imageKeypoints;

		cv::drawKeypoints( _imageThreshold, _keyPoints, _imageKeypoints, cv::Scalar( 0, 0, 255 ), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS );

//		_linesImage = cv::Mat::zeros( _origImage.size(), CV_8UC3 );
//		for( std::vector<TTrackObject>::iterator itr = m_trackedObjects.begin(); itr != m_trackedObjects.end(); ++itr)
//		{
//
//
//			// Convert from BGR to HSV
//			cv::cvtColor( _origImage, _imageHSV, cv::COLOR_BGR2HSV );
//
//			// Threshold the image values
//			cv::inRange( _imageHSV, cv::Scalar( itr->colorData.lowH, itr->colorData.lowS, itr->colorData.lowV ), cv::Scalar( itr->colorData.highH,
//																					itr->colorData.highS, itr->colorData.highV ), _imageThreshold );
//
//			// Morph open - remove small objects from the foreground
//			cv::erode( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
//			cv::dilate( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
//
//			// Morph close - fill small holes in foreground
//			cv::dilate( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
//			cv::erode( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
//
//			// Moments ofthe threshold image for tracking
//			cv::Moments imageMoments = cv::moments( _imageThreshold );
//
//			m_trackedObjects[0].moments01 = imageMoments.m01;
//			m_trackedObjects[0].moments10 = imageMoments.m10;
//			m_trackedObjects[0].momentsArea = imageMoments.m00;
//
//			// Noise threshold
//			if( m_trackedObjects[0].momentsArea > 1000 )
//			{
//				m_trackedObjects[0].posX = m_trackedObjects[0].moments10 / m_trackedObjects[0].momentsArea;
//				m_trackedObjects[0].posY = m_trackedObjects[0].moments01 / m_trackedObjects[0].momentsArea;
//
//				if( m_trackedObjects[0].lastX >= 0 && m_trackedObjects[0].lastY >=0 && m_trackedObjects[0].posX >= 0 && m_trackedObjects[0].posY >= 0 )
//				{
//					// Draw a line from previous pose to current pose
//					cv::line( _linesImage, cv::Point( m_trackedObjects[0].posX, m_trackedObjects[0].posY )
//								, cv::Point( m_trackedObjects[0].lastX, m_trackedObjects[0].lastY ), cv::Scalar( 0, 0, 255 ), 2 );
//				}
//
//				m_trackedObjects[0].lastX = m_trackedObjects[0].posX;
//				m_trackedObjects[0].lastY = m_trackedObjects[0].posY;
//
//				cv::Scalar color = cv::Scalar( 94, 206, 165 );
//
//				cv::circle( _origImage, cv::Point( m_trackedObjects[0].posX, m_trackedObjects[0].posY ), sqrt( m_trackedObjects[0].momentsArea/3.14 )/10, color, 0.5, 8, 0 );
//			}
//		}
		// Display the images
//		cv::imshow( _controlWindow, _imageThreshold );

		// Display the combined image
//		_origImage = _origImage + _linesImage;

//		cv::imshow( "Original-Image", _origImage );
		cv::imshow( "Blob-Image", _imageKeypoints );

		if( cv::waitKey( 0 ) == 27 )
		{
			LOG( INFO ) << ">>>> Exiting <<<<";
//			break;
		}
//	}
}
<commit_msg>replced threshold method with inRange<commit_after>// Inspired by http://opencv-srf.blogspot.com/2010/09/object-detection-using-color-seperation.html
#include "CMultiTrackerApp.h"

static 	TColorData				_colorCal;

CMultiTrackerApp::CMultiTrackerApp( char **argv )
	: _cap( atoi( argv[1] ) )
	, _controlWindow( argv[2] )
	, m_trackedObjects( 0 )
{
	_calibrationData.blue.colorId 	= "blue";
	_calibrationData.orange.colorId = "orange";
	_calibrationData.purple.colorId = "purple";
	_calibrationData.yellow.colorId = "yellow";
	_calibrationData.green.colorId 	= "green";
	_calibrationData.red.colorId 	= "red";

}

CMultiTrackerApp::~CMultiTrackerApp()
{

}

bool CMultiTrackerApp::Initialize()
{

	// Set blob parameters
	_params.minThreshold 		= 10;
	_params.maxThreshold 		= 200;

	_params.filterByArea 		= true;
	_params.minArea 			= 1500;

	_params.filterByCircularity = true;
	_params.minCircularity 		= 0.1;

	_params.filterByConvexity 	= true;
	_params.minConvexity 		= 0.87;

	_params.filterByInertia 	= true;
	_params.minInertiaRatio 	= 0.01;

	// Init detector with params
	_detector = cv::SimpleBlobDetector::create( _params );
	// _detector->detect( image, keyPoints ); // detect blob

	// We use this private class variable to disallow active changes to the calibration.
	// If we use the _calibrationData structure for calibration and adjustment in real time, we have to retrain
	// at this time.
	_colorCal.colorId = "init";

	_colorCal.lowH 	= 0;
	_colorCal.highH = 179;

	_colorCal.lowS 	= 0;
	_colorCal.highS = 255;

	_colorCal.lowV 	= 0;
	_colorCal.highV = 255;

	// Set control window
	cv::namedWindow( _controlWindow, CV_WINDOW_AUTOSIZE);

	// track bars for HSV tuning
	cv::createTrackbar( "LowH", _controlWindow, &_colorCal.lowH, 179 );
	cv::createTrackbar( "HighH", _controlWindow, &_colorCal.highH, 179 );

	cv::createTrackbar( "LowS", _controlWindow, &_colorCal.lowS, 255 );
	cv::createTrackbar( "HighS", _controlWindow, &_colorCal.highS, 255 );

	cv::createTrackbar( "LowV", _controlWindow, &_colorCal.lowV, 255 );
	cv::createTrackbar( "HighV", _controlWindow, &_colorCal.highV, 255 );

	// Buttons for color calibration
	cv::createButton( "Orange", CalibrateHSV, &_calibrationData.orange, CV_PUSH_BUTTON, 0 );
	cv::createButton( "Blue", CalibrateHSV, &_calibrationData.blue, CV_PUSH_BUTTON, 0 );

	cv::createButton( "Red", CalibrateHSV, &_calibrationData.red, CV_PUSH_BUTTON, 0 );
	cv::createButton( "Purple", CalibrateHSV, &_calibrationData.purple, CV_PUSH_BUTTON, 0 );

	cv::createButton( "Yellow", CalibrateHSV, &_calibrationData.yellow, CV_PUSH_BUTTON, 0 );
	cv::createButton( "Green", CalibrateHSV, &_calibrationData.green, CV_PUSH_BUTTON, 0 );

	return true;
}

void CMultiTrackerApp::CalibrateHSV( int stateIn, void *userDataIn )
{
	TColorData *calData = (TColorData*)userDataIn;

	LOG( INFO ) << "Calibratiing: " << calData->colorId;

	calData->lowH 	= _colorCal.lowH;
	calData->highH 	= _colorCal.highH;

	calData->lowS 	= _colorCal.lowS;
	calData->highS 	= _colorCal.highS;

	calData->lowV 	= _colorCal.lowV;
	calData->highV	= _colorCal.highV;

}

void CMultiTrackerApp::Run()
{
//	while( true )
//	{
		if( !_cap.read( _origImage ) )
		{
			LOG( ERROR ) << ">>>> Could not read from video stream: CLOSING <<<<";
//			break;
		}
		cv::Mat im = cv::imread( "roboops_test_image.png", cv::IMREAD_COLOR );

		cv::cvtColor( im, _imageHSV, cv::COLOR_BGR2HSV );

//		cv::threshold( _imageHSV, _imageThreshold, 127, 255, cv::THRESH_TOZERO );

		cv::inRange( _imageHSV, cv::Scalar( 70, 87, 42 ), cv::Scalar( 179, 255, 255 ), _imageThreshold );

		// Morph open - remove small objects from the foreground
		cv::erode( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
		cv::dilate( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );

		// Morph close - fill small holes in foreground
		cv::dilate( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
		cv::erode( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );

		// Detect the blobs
		_detector->detect( _imageThreshold, _keyPoints );

		// Draw blobs as red circles
		// flags ensures the size of the circle corresponds to the size of the blob
		cv::Mat _imageKeypoints;

		cv::drawKeypoints( _imageThreshold, _keyPoints, _imageKeypoints, cv::Scalar( 0, 0, 255 ), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS );

//		_linesImage = cv::Mat::zeros( _origImage.size(), CV_8UC3 );
//		for( std::vector<TTrackObject>::iterator itr = m_trackedObjects.begin(); itr != m_trackedObjects.end(); ++itr)
//		{
//
//
//			// Convert from BGR to HSV
//			cv::cvtColor( _origImage, _imageHSV, cv::COLOR_BGR2HSV );
//
//			// Threshold the image values
//			cv::inRange( _imageHSV, cv::Scalar( itr->colorData.lowH, itr->colorData.lowS, itr->colorData.lowV ), cv::Scalar( itr->colorData.highH,
//																					itr->colorData.highS, itr->colorData.highV ), _imageThreshold );
//
//			// Morph open - remove small objects from the foreground
//			cv::erode( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
//			cv::dilate( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
//
//			// Morph close - fill small holes in foreground
//			cv::dilate( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
//			cv::erode( _imageThreshold, _imageThreshold, cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 5, 5 ) ) );
//
//			// Moments ofthe threshold image for tracking
//			cv::Moments imageMoments = cv::moments( _imageThreshold );
//
//			m_trackedObjects[0].moments01 = imageMoments.m01;
//			m_trackedObjects[0].moments10 = imageMoments.m10;
//			m_trackedObjects[0].momentsArea = imageMoments.m00;
//
//			// Noise threshold
//			if( m_trackedObjects[0].momentsArea > 1000 )
//			{
//				m_trackedObjects[0].posX = m_trackedObjects[0].moments10 / m_trackedObjects[0].momentsArea;
//				m_trackedObjects[0].posY = m_trackedObjects[0].moments01 / m_trackedObjects[0].momentsArea;
//
//				if( m_trackedObjects[0].lastX >= 0 && m_trackedObjects[0].lastY >=0 && m_trackedObjects[0].posX >= 0 && m_trackedObjects[0].posY >= 0 )
//				{
//					// Draw a line from previous pose to current pose
//					cv::line( _linesImage, cv::Point( m_trackedObjects[0].posX, m_trackedObjects[0].posY )
//								, cv::Point( m_trackedObjects[0].lastX, m_trackedObjects[0].lastY ), cv::Scalar( 0, 0, 255 ), 2 );
//				}
//
//				m_trackedObjects[0].lastX = m_trackedObjects[0].posX;
//				m_trackedObjects[0].lastY = m_trackedObjects[0].posY;
//
//				cv::Scalar color = cv::Scalar( 94, 206, 165 );
//
//				cv::circle( _origImage, cv::Point( m_trackedObjects[0].posX, m_trackedObjects[0].posY ), sqrt( m_trackedObjects[0].momentsArea/3.14 )/10, color, 0.5, 8, 0 );
//			}
//		}
		// Display the images
//		cv::imshow( _controlWindow, _imageThreshold );

		// Display the combined image
//		_origImage = _origImage + _linesImage;

//		cv::imshow( "Original-Image", _origImage );
		cv::imshow( "Blob-Image", _imageKeypoints );

		if( cv::waitKey( 0 ) == 27 )
		{
			LOG( INFO ) << ">>>> Exiting <<<<";
//			break;
		}
//	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Dariusz Stojaczyk. All Rights Reserved.
 * The following source code is released under an MIT-style license,
 * that can be found in the LICENSE file.
 */

#include "RenderManager.h"
#include "Application.h"
#include "window/Window.h"
#include "window/LoadingScreen.h"
#include "window/MainMenu.h"
#include "render/window/MenuRender.h"

RenderManager::RenderManager(ApplicationContext &applicationContext, Window *window)
    : m_applicationContext(applicationContext) {

    if (!this->initWindow()) {
        printf("Failed to initialize window!\n");
        exit(1); // TODO replace with exceptions
    } else if (!this->initGL()) {
        printf("Unable to initialize OpenGL!\n");
        exit(1);
    } else if (!this->initRenders()) {
        printf("Unable to initialize window renders!\n");
        exit(1);
    } else {
#ifdef DEF_ANDROID
        initBindings();
#endif // DEF_ANDROID
    }

    switchWindow(*window);
}

bool RenderManager::initWindow() {
    bool success = true;

#ifdef USES_SDL
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("SDL could not initialize! SDL Error: %d\n", SDL_GetError());
        success = false;
    } else {
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

        std::string windowName = m_applicationContext.config().stringValue("window.title", "Spooky - unnamed project");

        int windowWidth = m_applicationContext.config().intValue("window.width", 1366);
        int windowHeight = m_applicationContext.config().intValue("window.height", 750);
        gWindow = SDL_CreateWindow(windowName.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowWidth, windowHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
        if (gWindow == NULL) {
            printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
            success = false;
        } else {
            gContext = SDL_GL_CreateContext(gWindow);
            if (gContext == NULL) {
                printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
                success = false;
            } else {
                //VSync
                if (SDL_GL_SetSwapInterval(1) < 0) {
                    printf("Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError());
                }
            }
        }
        m_renderContext.resize(windowWidth, windowHeight);
    }
#endif // USES_SDL
    return success;
}

bool RenderManager::initGL() {
#ifdef USES_SDL
    glewExperimental = GL_TRUE;
    GLenum glewError = glewInit();
    if (glewError != GLEW_OK) {
        printf("Error initializing GLEW! %s\n", glewGetErrorString(glewError));
        return false;
    }
#endif // USES_SDL

    return true;
}

bool RenderManager::initRenders() {
    windowRenders.insert(windowRenders.begin() + LoadingScreen::TYPE, std::make_unique<MenuRender>(m_renderContext));
    windowRenders.insert(windowRenders.begin() + MainMenu::TYPE, std::make_unique<MenuRender>(m_renderContext));
    return true;
}

void RenderManager::render() {
    m_windowRender->render(*m_currentWindow);
#ifdef USES_SDL
    SDL_GL_SwapWindow(gWindow);
#endif // USES_SDL
}

void RenderManager::reload() {
    glViewport(0, 0, m_renderContext.windowWidth(), m_renderContext.windowHeight());
    m_windowRender->reload();
}

RenderManager::~RenderManager() {
#ifdef USES_SDL
    SDL_DestroyWindow(this->gWindow);
    SDL_Quit();
#endif // USES_SDL
}

void RenderManager::switchWindow(Window &window) {
    m_currentWindow = &window;
    m_windowRender = windowRenders[window.type()].get();
    m_windowRender->reinit();
}

void RenderManager::resize(uint32_t width, uint32_t height) {
    m_renderContext.resize(width, height);
    reload();
}
<commit_msg>Reload renders after initialization<commit_after>/*
 * Copyright (c) 2016 Dariusz Stojaczyk. All Rights Reserved.
 * The following source code is released under an MIT-style license,
 * that can be found in the LICENSE file.
 */

#include "RenderManager.h"
#include "Application.h"
#include "window/Window.h"
#include "window/LoadingScreen.h"
#include "window/MainMenu.h"
#include "render/window/MenuRender.h"

RenderManager::RenderManager(ApplicationContext &applicationContext, Window *window)
    : m_applicationContext(applicationContext) {

    if (!this->initWindow()) {
        printf("Failed to initialize window!\n");
        exit(1); // TODO replace with exceptions
    } else if (!this->initGL()) {
        printf("Unable to initialize OpenGL!\n");
        exit(1);
    } else if (!this->initRenders()) {
        printf("Unable to initialize window renders!\n");
        exit(1);
    } else {
#ifdef DEF_ANDROID
        initBindings();
#endif // DEF_ANDROID
    }

    switchWindow(*window);
}

bool RenderManager::initWindow() {
    bool success = true;

#ifdef USES_SDL
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("SDL could not initialize! SDL Error: %d\n", SDL_GetError());
        success = false;
    } else {
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

        std::string windowName = m_applicationContext.config().stringValue("window.title", "Spooky - unnamed project");

        int windowWidth = m_applicationContext.config().intValue("window.width", 1366);
        int windowHeight = m_applicationContext.config().intValue("window.height", 750);
        gWindow = SDL_CreateWindow(windowName.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowWidth, windowHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
        if (gWindow == NULL) {
            printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
            success = false;
        } else {
            gContext = SDL_GL_CreateContext(gWindow);
            if (gContext == NULL) {
                printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
                success = false;
            } else {
                //VSync
                if (SDL_GL_SetSwapInterval(1) < 0) {
                    printf("Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError());
                }
            }
        }
        m_renderContext.resize(windowWidth, windowHeight);
    }
#endif // USES_SDL
    return success;
}

bool RenderManager::initGL() {
#ifdef USES_SDL
    glewExperimental = GL_TRUE;
    GLenum glewError = glewInit();
    if (glewError != GLEW_OK) {
        printf("Error initializing GLEW! %s\n", glewGetErrorString(glewError));
        return false;
    }
#endif // USES_SDL

    return true;
}

bool RenderManager::initRenders() {
    windowRenders.insert(windowRenders.begin() + LoadingScreen::TYPE, std::make_unique<MenuRender>(m_renderContext));
    windowRenders.insert(windowRenders.begin() + MainMenu::TYPE, std::make_unique<MenuRender>(m_renderContext));
    return true;
}

void RenderManager::render() {
    m_windowRender->render(*m_currentWindow);
#ifdef USES_SDL
    SDL_GL_SwapWindow(gWindow);
#endif // USES_SDL
}

void RenderManager::reload() {
    glViewport(0, 0, m_renderContext.windowWidth(), m_renderContext.windowHeight());
    m_windowRender->reload();
}

RenderManager::~RenderManager() {
#ifdef USES_SDL
    SDL_DestroyWindow(this->gWindow);
    SDL_Quit();
#endif // USES_SDL
}

void RenderManager::switchWindow(Window &window) {
    m_currentWindow = &window;
    m_windowRender = windowRenders[window.type()].get();
    m_windowRender->reinit();
    m_windowRender->reload();
}

void RenderManager::resize(uint32_t width, uint32_t height) {
    m_renderContext.resize(width, height);
    reload();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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
 *
 * 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.
 */

#include <iomanip>
#include <iostream>
#include <fstream>
#include <boost/algorithm/string.hpp>

#include "otbGeomMetadataSupplier.h"
#include "otbMetaDataKey.h"
#include "otbGeometryMetadata.h"
#include "otbStringUtils.h"

namespace otb
{
GeomMetadataSupplier::GeomMetadataSupplier(std::string const& fileName)
  : m_FileName(fileName)
{
  this->ReadGeomFile();
}

std::string GeomMetadataSupplier::GetMetadataValue(std::string const& path, bool& hasValue, int band) const
{
  auto value = this->m_MetadataDic.find(path);
  if(value != this->m_MetadataDic.end())
  {
    hasValue = true;
    return value->second;
  }
  hasValue = false;
  return "";
}

std::string GeomMetadataSupplier::GetResourceFile(std::string const& s) const
{
  return this->m_FileName;
}

int GeomMetadataSupplier::GetNbBands() const
{
  bool hasValue;
  std::string ret = this->GetMetadataValue("support_data.number_bands", hasValue);
  if (hasValue)
  {
    boost::algorithm::trim_if(ret, boost::algorithm::is_any_of("\" "));
    return std::stoi(ret);
  }

  ret = this->GetMetadataValue("support_data.band_name_list", hasValue);
  boost::algorithm::trim_if(ret, boost::algorithm::is_any_of("\" "));
  if (hasValue)
  {
    std::vector<std::string> ret_vect;
    otb::Utils::ConvertStringToVector(ret, ret_vect, "band name");
    return ret_vect.size();
  }

  return 0;
}

bool GeomMetadataSupplier::FetchRPC(ImageMetadata & imd)
{
  bool hasValue;
  GetMetadataValue("polynomial_format", hasValue);
  if (!hasValue)
    return false;

  Projection::RPCParam rpcStruct;
  rpcStruct.LineOffset    = this->GetAs<double>("line_off");
  rpcStruct.SampleOffset  = this->GetAs<double>("samp_off");
  rpcStruct.LatOffset     = this->GetAs<double>("lat_off");
  rpcStruct.LonOffset     = this->GetAs<double>("long_off");
  rpcStruct.HeightOffset  = this->GetAs<double>("height_off");

  rpcStruct.LineScale    = this->GetAs<double>("line_scale");
  rpcStruct.SampleScale  = this->GetAs<double>("samp_scale");
  rpcStruct.LatScale     = this->GetAs<double>("lat_scale");
  rpcStruct.LonScale     = this->GetAs<double>("long_scale");
  rpcStruct.HeightScale  = this->GetAs<double>("height_scale");

  std::vector<double> coeffs;
  int loop = 0;
  std::stringstream path;
  for (auto & coeff : rpcStruct.LineNum)
  {
    path.str("");
    path << "line_num_coeff_" << std::setfill('0') << std::setw(2) << loop++;
    coeff = this->GetAs<double>(path.str());
  }
  loop = 0;
  for (auto & coeff : rpcStruct.LineDen)
  {
    path.str("");
    path << "line_den_coeff_" << std::setfill('0') << std::setw(2) << loop++;
    coeff = this->GetAs<double>(path.str());
  }
  loop = 0;
  for (auto & coeff : rpcStruct.SampleNum)
  {
    path.str("");
    path << "samp_num_coeff_" << std::setfill('0') << std::setw(2) << loop++;
    coeff = this->GetAs<double>(path.str());
  }
  loop = 0;
  for (auto & coeff : rpcStruct.SampleDen)
  {
    path.str("");
    path << "samp_den_coeff_" << std::setfill('0') << std::setw(2) << loop++;
    coeff = this->GetAs<double>(path.str());
  }

  imd.Add(MDGeom::RPC, rpcStruct);
  assert(imd.Has(MDGeom::RPC));
  assert(rpcStruct == boost::any_cast<Projection::RPCParam>(imd[MDGeom::RPC]));
  return true;
}

std::string GeomMetadataSupplier::PrintSelf() const
{
  std::ostringstream oss;
  oss << "GeomMetadataSupplier: " << this->m_FileName << '\n';
  for (const auto& kv : this->m_MetadataDic)
    oss << kv.first << " : " << kv.second << '\n';
  return oss.str();
}

void GeomMetadataSupplier::ReadGeomFile()
{
  std::ifstream inputFile(this->m_FileName);
  std::string line;
  std::vector< std::string > keyVal;
  while (std::getline(inputFile, line))
  {
    auto pos = line.find(":");
    if (pos != std::string::npos)
    {
      auto key = line.substr(0,pos);
      auto value = line.substr(pos+1, line.size());
      boost::trim(key);
      boost::trim(value);
      m_MetadataDic[key] = value;
    }
  }
}

} // end namespace otb
<commit_msg>BUG: consider that the product has one band if no band specific keys are found in the geom product<commit_after>/*
 * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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
 *
 * 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.
 */

#include <iomanip>
#include <iostream>
#include <fstream>
#include <boost/algorithm/string.hpp>

#include "otbGeomMetadataSupplier.h"
#include "otbMetaDataKey.h"
#include "otbGeometryMetadata.h"
#include "otbStringUtils.h"

namespace otb
{
GeomMetadataSupplier::GeomMetadataSupplier(std::string const& fileName)
  : m_FileName(fileName)
{
  this->ReadGeomFile();
}

std::string GeomMetadataSupplier::GetMetadataValue(std::string const& path, bool& hasValue, int band) const
{
  auto value = this->m_MetadataDic.find(path);
  if(value != this->m_MetadataDic.end())
  {
    hasValue = true;
    return value->second;
  }
  hasValue = false;
  return "";
}

std::string GeomMetadataSupplier::GetResourceFile(std::string const& s) const
{
  return this->m_FileName;
}

int GeomMetadataSupplier::GetNbBands() const
{
  bool hasValue;
  std::string ret = this->GetMetadataValue("support_data.number_bands", hasValue);
  if (hasValue)
  {
    boost::algorithm::trim_if(ret, boost::algorithm::is_any_of("\" "));
    return std::stoi(ret);
  }

  ret = this->GetMetadataValue("support_data.band_name_list", hasValue);
  boost::algorithm::trim_if(ret, boost::algorithm::is_any_of("\" "));
  if (hasValue)
  {
    std::vector<std::string> ret_vect;
    otb::Utils::ConvertStringToVector(ret, ret_vect, "band name");
    return ret_vect.size();
  }

  return 1;
}

bool GeomMetadataSupplier::FetchRPC(ImageMetadata & imd)
{
  bool hasValue;
  GetMetadataValue("polynomial_format", hasValue);
  if (!hasValue)
    return false;

  Projection::RPCParam rpcStruct;
  rpcStruct.LineOffset    = this->GetAs<double>("line_off");
  rpcStruct.SampleOffset  = this->GetAs<double>("samp_off");
  rpcStruct.LatOffset     = this->GetAs<double>("lat_off");
  rpcStruct.LonOffset     = this->GetAs<double>("long_off");
  rpcStruct.HeightOffset  = this->GetAs<double>("height_off");

  rpcStruct.LineScale    = this->GetAs<double>("line_scale");
  rpcStruct.SampleScale  = this->GetAs<double>("samp_scale");
  rpcStruct.LatScale     = this->GetAs<double>("lat_scale");
  rpcStruct.LonScale     = this->GetAs<double>("long_scale");
  rpcStruct.HeightScale  = this->GetAs<double>("height_scale");

  std::vector<double> coeffs;
  int loop = 0;
  std::stringstream path;
  for (auto & coeff : rpcStruct.LineNum)
  {
    path.str("");
    path << "line_num_coeff_" << std::setfill('0') << std::setw(2) << loop++;
    coeff = this->GetAs<double>(path.str());
  }
  loop = 0;
  for (auto & coeff : rpcStruct.LineDen)
  {
    path.str("");
    path << "line_den_coeff_" << std::setfill('0') << std::setw(2) << loop++;
    coeff = this->GetAs<double>(path.str());
  }
  loop = 0;
  for (auto & coeff : rpcStruct.SampleNum)
  {
    path.str("");
    path << "samp_num_coeff_" << std::setfill('0') << std::setw(2) << loop++;
    coeff = this->GetAs<double>(path.str());
  }
  loop = 0;
  for (auto & coeff : rpcStruct.SampleDen)
  {
    path.str("");
    path << "samp_den_coeff_" << std::setfill('0') << std::setw(2) << loop++;
    coeff = this->GetAs<double>(path.str());
  }

  imd.Add(MDGeom::RPC, rpcStruct);
  assert(imd.Has(MDGeom::RPC));
  assert(rpcStruct == boost::any_cast<Projection::RPCParam>(imd[MDGeom::RPC]));
  return true;
}

std::string GeomMetadataSupplier::PrintSelf() const
{
  std::ostringstream oss;
  oss << "GeomMetadataSupplier: " << this->m_FileName << '\n';
  for (const auto& kv : this->m_MetadataDic)
    oss << kv.first << " : " << kv.second << '\n';
  return oss.str();
}

void GeomMetadataSupplier::ReadGeomFile()
{
  std::ifstream inputFile(this->m_FileName);
  std::string line;
  std::vector< std::string > keyVal;
  while (std::getline(inputFile, line))
  {
    auto pos = line.find(":");
    if (pos != std::string::npos)
    {
      auto key = line.substr(0,pos);
      auto value = line.substr(pos+1, line.size());
      boost::trim(key);
      boost::trim(value);
      m_MetadataDic[key] = value;
    }
  }
}

} // end namespace otb
<|endoftext|>


<commit_before>#include "reflection.h"

#include <type_traits>

struct Foo {};
static_assert(std::is_same<void, reflection::reflected_member_t<Foo, 0>>::value);
static_assert(reflection::reflected_member_count_v<Foo> == 0);

struct Bar
{
    void bar();
};
REFLECT_MEMBER(Bar, bar);
static_assert(!std::is_same<void, reflection::reflected_member_t<Bar, 0>>::value);
static_assert( std::is_same<void, reflection::reflected_member_t<Bar, 1>>::value);
static_assert(reflection::reflected_member_count_v<Bar> == 1);

struct Baz
{
    void baz();
    void baz2();
};
REFLECT_MEMBER(Baz, baz);
REFLECT_MEMBER(Baz, baz2);
static_assert(!std::is_same<void, reflection::reflected_member_t<Baz, 0>>::value);
static_assert(!std::is_same<void, reflection::reflected_member_t<Baz, 1>>::value);
static_assert( std::is_same<void, reflection::reflected_member_t<Baz, 2>>::value);
static_assert(reflection::reflected_member_count_v<Baz> == 2);

struct Bat
{
    void REFLECT(bat)();
    void REFLECT(bat2)();
};

static_assert(!std::is_same<void, reflection::reflected_class_member_t<Bat, 0>>::value);
static_assert(!std::is_same<void, reflection::reflected_class_member_t<Bat, 1>>::value);
static_assert( std::is_same<void, reflection::reflected_class_member_t<Bat, 2>>::value);
static_assert(reflection::reflected_class_member_count_v<Bat> == 2);

auto _ = []{
    using namespace reflection;

    std::cout << "Foo" << std::endl;
    std::cout << reflected_member_count_v<Foo> << std::endl;

    std::cout << "Bar" << std::endl;
    std::cout << reflected_member_count_v<Bar> << std::endl;

    std::cout << "Baz" << std::endl;
    std::cout << reflected_member_count_v<Baz> << std::endl;

    return 0;
}();

int main()
{
}
<commit_msg>Added missing include<commit_after>#include "reflection.h"

#include <iostream>
#include <type_traits>

struct Foo {};
static_assert(std::is_same<void, reflection::reflected_member_t<Foo, 0>>::value);
static_assert(reflection::reflected_member_count_v<Foo> == 0);

struct Bar
{
    void bar();
};
REFLECT_MEMBER(Bar, bar);
static_assert(!std::is_same<void, reflection::reflected_member_t<Bar, 0>>::value);
static_assert( std::is_same<void, reflection::reflected_member_t<Bar, 1>>::value);
static_assert(reflection::reflected_member_count_v<Bar> == 1);

struct Baz
{
    void baz();
    void baz2();
};
REFLECT_MEMBER(Baz, baz);
REFLECT_MEMBER(Baz, baz2);
static_assert(!std::is_same<void, reflection::reflected_member_t<Baz, 0>>::value);
static_assert(!std::is_same<void, reflection::reflected_member_t<Baz, 1>>::value);
static_assert( std::is_same<void, reflection::reflected_member_t<Baz, 2>>::value);
static_assert(reflection::reflected_member_count_v<Baz> == 2);

struct Bat
{
    void REFLECT(bat)();
    void REFLECT(bat2)();
};

static_assert(!std::is_same<void, reflection::reflected_class_member_t<Bat, 0>>::value);
static_assert(!std::is_same<void, reflection::reflected_class_member_t<Bat, 1>>::value);
static_assert( std::is_same<void, reflection::reflected_class_member_t<Bat, 2>>::value);
static_assert(reflection::reflected_class_member_count_v<Bat> == 2);

auto _ = []{
    using namespace reflection;

    std::cout << "Foo" << std::endl;
    std::cout << reflected_member_count_v<Foo> << std::endl;

    std::cout << "Bar" << std::endl;
    std::cout << reflected_member_count_v<Bar> << std::endl;

    std::cout << "Baz" << std::endl;
    std::cout << reflected_member_count_v<Baz> << std::endl;

    return 0;
}();

int main()
{
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Luke San Antonio
 * All rights reserved.
 */
#include "protocol.h"
#include "../common/crash.h"
namespace redc { namespace net
{
  Step_Client_Result step_client(Client_Context& ctx, ENetEvent const& event) noexcept
  {
    Step_Client_Result res;

    switch(ctx.state)
    {
      case Client_State::Starting:
      {
        // Assuming that the server address has already been set.
        ctx.host = std::move(*make_client_host().ok());
        // How many channels? Just one?
        enet_host_connect(ctx.host.host, &ctx.server_addr, 1, 0);
        ctx.state = Client_State::Connecting;
        res.context_changed = true;
        break;
      }
      case Client_State::Connecting:
      {
        // If it's the correct type of event
        if(event.type == ENET_EVENT_TYPE_CONNECT)
        {
          // From the correct peer? We can probably assume nobody will use our
          // host that we made but better safe than sorry.
          if(event.peer->address.host == ctx.server_addr.host &&
             event.peer->address.port == ctx.server_addr.port)
          {
            res.event_handled = true;
            res.context_changed = true;

            // Now send our version
            ctx.server_peer = event.peer;

            // Serialize version number
            version_t cur_client_version = 1;

            msgpack::sbuffer buf;
            msgpack::pack(buf, cur_client_version);

            // Make the version packet
            auto packet = enet_packet_create(buf.data(), buf.size(),
                                             ENET_PACKET_FLAG_RELIABLE);
            enet_peer_send(ctx.server_peer, 0, packet);

            // Now we are waiting for a response (or failure due to versioning)
            ctx.state = Client_State::Waiting_For_Info;
          }
        }
        break;
      }
      case Client_State::Waiting_For_Info:
      case Client_State::Sending_Loadouts:
      case Client_State::Waiting_For_Inventory_Confirmation:
      case Client_State::Sending_Team:
      case Client_State::Waiting_For_Spawn:
        break;
      case Client_State::Playing:
      default:
        break;
    }

    return res;
  }

  Client make_client(std::string addr, uint16_t port) noexcept
  {
    Client client;
    client.host = std::move(*make_client_host().ok());

    connect_with_client(client.host, addr, port);

    return client;
  }
  Client wait_for_connection(std::string addr, uint16_t port) noexcept
  {
    auto client = make_client(addr, port);
    client.peer = wait_for_connection(client.host, 1000);
    // Failed to connect if peer is null
    if(!client.peer)
    {
      crash("Failed to connect");
    }
    return client;
  }

  void close_connection(Client& client) noexcept
  {
    enet_peer_disconnect(client.peer, 0);
    enet_host_service(client.host.host, NULL, 500);
    enet_host_destroy(client.host.host);
  }

  void wait_for_game_info(Client& client, sail::Game& game) noexcept
  {
  }
  void set_name(Client& client, std::string name) noexcept
  {
  }
} }
<commit_msg>Add implementation of Client_State::Waiting_For_Info<commit_after>/*
 * Copyright (C) 2015 Luke San Antonio
 * All rights reserved.
 */
#include "protocol.h"
#include "../common/crash.h"
namespace redc { namespace net
{
  Step_Client_Result step_client(Client_Context& ctx, ENetEvent const& event) noexcept
  {
    Step_Client_Result res;

    switch(ctx.state)
    {
      case Client_State::Starting:
      {
        // Assuming that the server address has already been set.
        ctx.host = std::move(*make_client_host().ok());
        // How many channels? Just one?
        enet_host_connect(ctx.host.host, &ctx.server_addr, 1, 0);
        ctx.state = Client_State::Connecting;
        res.context_changed = true;
        break;
      }
      case Client_State::Connecting:
      {
        // If it's the correct type of event
        if(event.type == ENET_EVENT_TYPE_CONNECT)
        {
          // From the correct peer? We can probably assume nobody will use our
          // host that we made but better safe than sorry.
          if(event.peer->address.host == ctx.server_addr.host &&
             event.peer->address.port == ctx.server_addr.port)
          {
            res.event_handled = true;
            res.context_changed = true;

            // Now send our version
            ctx.server_peer = event.peer;

            // Serialize version number
            version_t cur_client_version = 1;

            msgpack::sbuffer buf;
            msgpack::pack(buf, cur_client_version);

            // Make the version packet
            auto packet = enet_packet_create(buf.data(), buf.size(),
                                             ENET_PACKET_FLAG_RELIABLE);
            enet_peer_send(ctx.server_peer, 0, packet);

            // Now we are waiting for a response (or failure due to versioning)
            ctx.state = Client_State::Waiting_For_Info;
          }
        }
        break;
      }
      case Client_State::Waiting_For_Info:
      {
        if(event.type == ENET_EVENT_TYPE_RECEIVE)
        {
          if(event.peer == ctx.server_peer)
          {
            // We got some data from the server!
            if(event.packet->dataLength == 1)
            {
              // If it is just false:
              if(event.packet->data[0] == 0xc2)
              {
                // Our version was probably bad
                // Throw an error?
              }
            }

            // Try to decode Client_Init_Packet struct
            msgpack::unpacked unpacked;
            msgpack::unpack(unpacked, (const char*) event.packet->data,
                            event.packet->dataLength);
            try
            {
              ctx.client_init_packet = unpacked.get().as<Client_Init_Packet>();
            }
            catch(...)
            {
              // Figure out what exception I need to catch
              // For now rethrow it
              throw;
            }

            // Now we have the client init packet available, that's all we need
            // then the user should populate the inventory field.
            res.context_changed = true;
            res.event_handled = true;
            ctx.state = Client_State::Sending_Loadouts;
          }
        }
        break;
      }
      case Client_State::Sending_Loadouts:
      case Client_State::Waiting_For_Inventory_Confirmation:
      case Client_State::Sending_Team:
      case Client_State::Waiting_For_Spawn:
        break;
      case Client_State::Playing:
      default:
        break;
    }

    return res;
  }

  Client make_client(std::string addr, uint16_t port) noexcept
  {
    Client client;
    client.host = std::move(*make_client_host().ok());

    connect_with_client(client.host, addr, port);

    return client;
  }
  Client wait_for_connection(std::string addr, uint16_t port) noexcept
  {
    auto client = make_client(addr, port);
    client.peer = wait_for_connection(client.host, 1000);
    // Failed to connect if peer is null
    if(!client.peer)
    {
      crash("Failed to connect");
    }
    return client;
  }

  void close_connection(Client& client) noexcept
  {
    enet_peer_disconnect(client.peer, 0);
    enet_host_service(client.host.host, NULL, 500);
    enet_host_destroy(client.host.host);
  }

  void wait_for_game_info(Client& client, sail::Game& game) noexcept
  {
  }
  void set_name(Client& client, std::string name) noexcept
  {
  }
} }
<|endoftext|>


<commit_before>#include "mitkRESTServerMicroService.h"
#include <mitkCommon.h>

mitk::RESTServerMicroService::RESTServerMicroService(web::uri uri) : m_Listener(uri)
{
  m_Listener.support(MitkRESTMethods::GET, std::bind(&RESTServerMicroService::HandleGet, this, std::placeholders::_1));
  openListener();
}

mitk::RESTServerMicroService::~RESTServerMicroService()
{
  closeListener();
}

pplx::task<void> mitk::RESTServerMicroService::openListener()
{
  return m_Listener.open();
}

pplx::task<void> mitk::RESTServerMicroService::closeListener()
{
  return m_Listener.close();
}

void mitk::RESTServerMicroService::HandleGet(MitkRequest request)
{
  int port = m_Listener.uri().port();
  MITK_INFO << "Test for Server at port "<<port;
  request.reply(MitkRestStatusCodes::OK);
}<commit_msg>example json value is returned from server<commit_after>#include "mitkRESTServerMicroService.h"
#include <mitkCommon.h>

mitk::RESTServerMicroService::RESTServerMicroService(web::uri uri) : m_Listener(uri)
{
  m_Listener.support(MitkRESTMethods::GET, std::bind(&RESTServerMicroService::HandleGet, this, std::placeholders::_1));
  openListener();
}

mitk::RESTServerMicroService::~RESTServerMicroService()
{
  closeListener();
}

pplx::task<void> mitk::RESTServerMicroService::openListener()
{
  return m_Listener.open();
}

pplx::task<void> mitk::RESTServerMicroService::closeListener()
{
  return m_Listener.close();
}

void mitk::RESTServerMicroService::HandleGet(MitkRequest request)
{
  int port = m_Listener.uri().port();
  web::json::value content;
  content[L"key 1"] = web::json::value::string(U("this is a first test"));
  request.set_body(content);
  auto answer = request.extract_json().get();
  MITK_INFO << "Test for Server at port "<<port;

  request.reply(MitkRestStatusCodes::OK, answer);
}<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPickingTool.h"

#include "mitkProperties.h"
#include "mitkToolManager.h"

// us
#include <usGetModuleContext.h>
#include <usModule.h>
#include <usModuleContext.h>
#include <usModuleResource.h>

#include "mitkITKImageImport.h"
#include "mitkImageAccessByItk.h"
#include "mitkImageCast.h"
#include "mitkImageTimeSelector.h"
#include "mitkImageTimeSelector.h"

#include <itkConnectedThresholdImageFilter.h>

#include <mitkLabelSetImage.h>

namespace mitk
{
  MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, PickingTool, "PickingTool");
}

mitk::PickingTool::PickingTool() : m_WorkingData(nullptr)
{
  m_PointSetNode = mitk::DataNode::New();
  m_PointSetNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New("Picking_Seedpoint"));
  m_PointSetNode->GetPropertyList()->SetProperty("helper object", mitk::BoolProperty::New(true));
  m_PointSet = mitk::PointSet::New();
  m_PointSetNode->SetData(m_PointSet);
  m_SeedPointInteractor = mitk::SinglePointDataInteractor::New();
  m_SeedPointInteractor->LoadStateMachine("PointSet.xml");
  m_SeedPointInteractor->SetEventConfig("PointSetConfig.xml");
  m_SeedPointInteractor->SetDataNode(m_PointSetNode);

  // Watch for point added or modified
  itk::SimpleMemberCommand<PickingTool>::Pointer pointAddedCommand = itk::SimpleMemberCommand<PickingTool>::New();
  pointAddedCommand->SetCallbackFunction(this, &mitk::PickingTool::OnPointAdded);
  m_PointSetAddObserverTag = m_PointSet->AddObserver(mitk::PointSetAddEvent(), pointAddedCommand);

  // create new node for picked region
  m_ResultNode = mitk::DataNode::New();
  // set some properties
  m_ResultNode->SetProperty("name", mitk::StringProperty::New("result"));
  m_ResultNode->SetProperty("helper object", mitk::BoolProperty::New(true));
  m_ResultNode->SetProperty("color", mitk::ColorProperty::New(0, 1, 0));
  m_ResultNode->SetProperty("layer", mitk::IntProperty::New(1));
  m_ResultNode->SetProperty("opacity", mitk::FloatProperty::New(0.33f));
}

mitk::PickingTool::~PickingTool()
{
  m_PointSet->RemoveObserver(m_PointSetAddObserverTag);
}

const char **mitk::PickingTool::GetXPM() const
{
  return nullptr;
}

const char *mitk::PickingTool::GetName() const
{
  return "Picking";
}

us::ModuleResource mitk::PickingTool::GetIconResource() const
{
  us::Module *module = us::GetModuleContext()->GetModule();
  us::ModuleResource resource = module->GetResource("Pick_48x48.png");
  return resource;
}

void mitk::PickingTool::Activated()
{
  Superclass::Activated();

  DataStorage *dataStorage = this->GetDataStorage();
  m_WorkingData = this->GetWorkingData();

  // add to datastorage and enable interaction
  if (!dataStorage->Exists(m_PointSetNode))
    dataStorage->Add(m_PointSetNode, m_WorkingData);

  // now add result to data tree
  dataStorage->Add(m_ResultNode, m_WorkingData);
}

void mitk::PickingTool::Deactivated()
{
  m_PointSet->Clear();
  // remove from data storage and disable interaction
  GetDataStorage()->Remove(m_PointSetNode);
  GetDataStorage()->Remove(m_ResultNode);

  Superclass::Deactivated();
}

mitk::DataNode *mitk::PickingTool::GetReferenceData()
{
  return this->m_ToolManager->GetReferenceData(0);
}

mitk::DataStorage *mitk::PickingTool::GetDataStorage()
{
  return this->m_ToolManager->GetDataStorage();
}

mitk::DataNode *mitk::PickingTool::GetWorkingData()
{
  return this->m_ToolManager->GetWorkingData(0);
}

mitk::DataNode::Pointer mitk::PickingTool::GetPointSetNode()
{
  return m_PointSetNode;
}

void mitk::PickingTool::OnPointAdded()
{
  if (m_WorkingData != this->GetWorkingData())
  {
    DataStorage *dataStorage = this->GetDataStorage();

    if (dataStorage->Exists(m_PointSetNode))
    {
      dataStorage->Remove(m_PointSetNode);
      dataStorage->Add(m_PointSetNode, this->GetWorkingData());
    }

    if (dataStorage->Exists(m_ResultNode))
    {
      dataStorage->Remove(m_ResultNode);
      dataStorage->Add(m_ResultNode, this->GetWorkingData());
    }

    m_WorkingData = this->GetWorkingData();
  }

  // Perform region growing/picking

  int timeStep =
    mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))->GetTimeStep();

  mitk::PointSet::PointType seedPoint = m_PointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value();

  // as we want to pick a region from our segmentation image use the working data from ToolManager
  mitk::Image::Pointer orgImage = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());

  if (orgImage.IsNotNull())
  {
    if (orgImage->GetDimension() == 4)
    { // there may be 4D segmentation data even though we currently don't support that
      mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
      timeSelector->SetInput(orgImage);
      timeSelector->SetTimeNr(timeStep);
      timeSelector->UpdateLargestPossibleRegion();
      mitk::Image *timedImage = timeSelector->GetOutput();

      AccessByItk_2(timedImage, StartRegionGrowing, timedImage->GetGeometry(), seedPoint);
    }
    else if (orgImage->GetDimension() == 3)
    {
      AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint);
    }
    this->m_PointSet->Clear();
  }
}

template <typename TPixel, unsigned int VImageDimension>
void mitk::PickingTool::StartRegionGrowing(itk::Image<TPixel, VImageDimension> *itkImage,
                                           mitk::BaseGeometry *imageGeometry,
                                           mitk::PointSet::PointType seedPoint)
{
  typedef itk::Image<TPixel, VImageDimension> InputImageType;
  typedef typename InputImageType::IndexType IndexType;
  typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
  typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();

  // convert world coordinates to image indices
  IndexType seedIndex;
  imageGeometry->WorldToIndex(seedPoint, seedIndex);

  // perform region growing in desired segmented region
  regionGrower->SetInput(itkImage);
  regionGrower->AddSeed(seedIndex);

  regionGrower->SetLower(1);
  regionGrower->SetUpper(255);

  try
  {
    regionGrower->Update();
  }
  catch (const itk::ExceptionObject &)
  {
    return; // can't work
  }
  catch (...)
  {
    return;
  }

  // Store result and preview
  mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput(), imageGeometry)->Clone();
  mitk::LabelSetImage::Pointer resultLabelSetImage = mitk::LabelSetImage::New();
  resultLabelSetImage->InitializeByLabeledImage(resultImage);

  m_ResultNode->SetData(resultLabelSetImage);

  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}

void mitk::PickingTool::ConfirmSegmentation()
{
  mitk::DataNode::Pointer newNode = mitk::DataNode::New();
  newNode->SetProperty("name", mitk::StringProperty::New(m_WorkingData->GetName() + "_picked"));

  float rgb[3] = {1.0f, 0.0f, 0.0f};
  m_WorkingData->GetColor(rgb);
  newNode->SetProperty("color", mitk::ColorProperty::New(rgb));

  float opacity = 1.0f;
  m_WorkingData->GetOpacity(opacity, nullptr);
  newNode->SetProperty("opacity", mitk::FloatProperty::New(opacity));

  newNode->SetData(m_ResultNode->GetData());

  GetDataStorage()->Add(newNode, this->GetReferenceData());
  m_WorkingData->SetVisibility(false);

  m_ResultNode->SetData(nullptr);

  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
<commit_msg>move interactor initialization<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPickingTool.h"

#include "mitkProperties.h"
#include "mitkToolManager.h"

// us
#include <usGetModuleContext.h>
#include <usModule.h>
#include <usModuleContext.h>
#include <usModuleResource.h>

#include "mitkITKImageImport.h"
#include "mitkImageAccessByItk.h"
#include "mitkImageCast.h"
#include "mitkImageTimeSelector.h"
#include "mitkImageTimeSelector.h"

#include <itkConnectedThresholdImageFilter.h>

#include <mitkLabelSetImage.h>

namespace mitk
{
  MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, PickingTool, "PickingTool");
}

mitk::PickingTool::PickingTool() : m_WorkingData(nullptr)
{
  m_PointSetNode = mitk::DataNode::New();
  m_PointSetNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New("Picking_Seedpoint"));
  m_PointSetNode->GetPropertyList()->SetProperty("helper object", mitk::BoolProperty::New(true));
  m_PointSet = mitk::PointSet::New();
  m_PointSetNode->SetData(m_PointSet);

  // Watch for point added or modified
  itk::SimpleMemberCommand<PickingTool>::Pointer pointAddedCommand = itk::SimpleMemberCommand<PickingTool>::New();
  pointAddedCommand->SetCallbackFunction(this, &mitk::PickingTool::OnPointAdded);
  m_PointSetAddObserverTag = m_PointSet->AddObserver(mitk::PointSetAddEvent(), pointAddedCommand);

  // create new node for picked region
  m_ResultNode = mitk::DataNode::New();
  // set some properties
  m_ResultNode->SetProperty("name", mitk::StringProperty::New("result"));
  m_ResultNode->SetProperty("helper object", mitk::BoolProperty::New(true));
  m_ResultNode->SetProperty("color", mitk::ColorProperty::New(0, 1, 0));
  m_ResultNode->SetProperty("layer", mitk::IntProperty::New(1));
  m_ResultNode->SetProperty("opacity", mitk::FloatProperty::New(0.33f));
}

mitk::PickingTool::~PickingTool()
{
  m_PointSet->RemoveObserver(m_PointSetAddObserverTag);
}

const char **mitk::PickingTool::GetXPM() const
{
  return nullptr;
}

const char *mitk::PickingTool::GetName() const
{
  return "Picking";
}

us::ModuleResource mitk::PickingTool::GetIconResource() const
{
  us::Module *module = us::GetModuleContext()->GetModule();
  us::ModuleResource resource = module->GetResource("Pick_48x48.png");
  return resource;
}

void mitk::PickingTool::Activated()
{
  Superclass::Activated();

  DataStorage *dataStorage = this->GetDataStorage();
  m_WorkingData = this->GetWorkingData();

  // add to datastorage and enable interaction
  if (!dataStorage->Exists(m_PointSetNode))
    dataStorage->Add(m_PointSetNode, m_WorkingData);

  m_SeedPointInteractor = mitk::SinglePointDataInteractor::New();
  m_SeedPointInteractor->LoadStateMachine("PointSet.xml");
  m_SeedPointInteractor->SetEventConfig("PointSetConfig.xml");
  m_SeedPointInteractor->SetDataNode(m_PointSetNode);

  // now add result to data tree
  dataStorage->Add(m_ResultNode, m_WorkingData);
}

void mitk::PickingTool::Deactivated()
{
  m_PointSet->Clear();
  // remove from data storage and disable interaction
  GetDataStorage()->Remove(m_PointSetNode);
  GetDataStorage()->Remove(m_ResultNode);

  Superclass::Deactivated();
}

mitk::DataNode *mitk::PickingTool::GetReferenceData()
{
  return this->m_ToolManager->GetReferenceData(0);
}

mitk::DataStorage *mitk::PickingTool::GetDataStorage()
{
  return this->m_ToolManager->GetDataStorage();
}

mitk::DataNode *mitk::PickingTool::GetWorkingData()
{
  return this->m_ToolManager->GetWorkingData(0);
}

mitk::DataNode::Pointer mitk::PickingTool::GetPointSetNode()
{
  return m_PointSetNode;
}

void mitk::PickingTool::OnPointAdded()
{
  if (m_WorkingData != this->GetWorkingData())
  {
    DataStorage *dataStorage = this->GetDataStorage();

    if (dataStorage->Exists(m_PointSetNode))
    {
      dataStorage->Remove(m_PointSetNode);
      dataStorage->Add(m_PointSetNode, this->GetWorkingData());
    }

    if (dataStorage->Exists(m_ResultNode))
    {
      dataStorage->Remove(m_ResultNode);
      dataStorage->Add(m_ResultNode, this->GetWorkingData());
    }

    m_WorkingData = this->GetWorkingData();
  }

  // Perform region growing/picking

  int timeStep =
    mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))->GetTimeStep();

  mitk::PointSet::PointType seedPoint = m_PointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value();

  // as we want to pick a region from our segmentation image use the working data from ToolManager
  mitk::Image::Pointer orgImage = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());

  if (orgImage.IsNotNull())
  {
    if (orgImage->GetDimension() == 4)
    { // there may be 4D segmentation data even though we currently don't support that
      mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
      timeSelector->SetInput(orgImage);
      timeSelector->SetTimeNr(timeStep);
      timeSelector->UpdateLargestPossibleRegion();
      mitk::Image *timedImage = timeSelector->GetOutput();

      AccessByItk_2(timedImage, StartRegionGrowing, timedImage->GetGeometry(), seedPoint);
    }
    else if (orgImage->GetDimension() == 3)
    {
      AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint);
    }
    this->m_PointSet->Clear();
  }
}

template <typename TPixel, unsigned int VImageDimension>
void mitk::PickingTool::StartRegionGrowing(itk::Image<TPixel, VImageDimension> *itkImage,
                                           mitk::BaseGeometry *imageGeometry,
                                           mitk::PointSet::PointType seedPoint)
{
  typedef itk::Image<TPixel, VImageDimension> InputImageType;
  typedef typename InputImageType::IndexType IndexType;
  typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
  typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();

  // convert world coordinates to image indices
  IndexType seedIndex;
  imageGeometry->WorldToIndex(seedPoint, seedIndex);

  // perform region growing in desired segmented region
  regionGrower->SetInput(itkImage);
  regionGrower->AddSeed(seedIndex);

  regionGrower->SetLower(1);
  regionGrower->SetUpper(255);

  try
  {
    regionGrower->Update();
  }
  catch (const itk::ExceptionObject &)
  {
    return; // can't work
  }
  catch (...)
  {
    return;
  }

  // Store result and preview
  mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput(), imageGeometry)->Clone();
  mitk::LabelSetImage::Pointer resultLabelSetImage = mitk::LabelSetImage::New();
  resultLabelSetImage->InitializeByLabeledImage(resultImage);

  m_ResultNode->SetData(resultLabelSetImage);

  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}

void mitk::PickingTool::ConfirmSegmentation()
{
  mitk::DataNode::Pointer newNode = mitk::DataNode::New();
  newNode->SetProperty("name", mitk::StringProperty::New(m_WorkingData->GetName() + "_picked"));

  float rgb[3] = {1.0f, 0.0f, 0.0f};
  m_WorkingData->GetColor(rgb);
  newNode->SetProperty("color", mitk::ColorProperty::New(rgb));

  float opacity = 1.0f;
  m_WorkingData->GetOpacity(opacity, nullptr);
  newNode->SetProperty("opacity", mitk::FloatProperty::New(opacity));

  newNode->SetData(m_ResultNode->GetData());

  GetDataStorage()->Add(newNode, this->GetReferenceData());
  m_WorkingData->SetVisibility(false);

  m_ResultNode->SetData(nullptr);

  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
<|endoftext|>


<commit_before>// Copyright (c)2008-2012, Preferred Infrastructure Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of Preferred Infrastructure nor the names of other
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "ipv4.h"

#include <stddef.h>
#include <stdio.h>
#include <algorithm>
#include <sstream>

using namespace std;

namespace pfi {
namespace network {

ipv4_address::ipv4_address() : ip() {}

ipv4_address::ipv4_address(unsigned char a,
                           unsigned char b,
                           unsigned char c,
                           unsigned char d)
{
  ip[0]=a;
  ip[1]=b;
  ip[2]=c;
  ip[3]=d;
}

ipv4_address::ipv4_address(const string& s)
{
  int buf[4];
  if (sscanf(s.c_str(), "%d.%d.%d.%d", &buf[0], &buf[1], &buf[2], &buf[3]) != 4) {
    *this = none;
    return;
  }
  for (size_t i = 0; i < sizeof(buf)/sizeof(buf[0]); ++i) {
    ip[i] = buf[i];
    if (buf[i] < 0 || buf[1] > 255) {
      *this = none;
      return;
    }
  }
}

bool ipv4_address::operator==(const ipv4_address& p) const
{
  return std::equal(ip, ip+sizeof(ip), p.ip);
}

bool ipv4_address::operator!=(const ipv4_address& p) const
{
  return !(*this==p);
}

bool ipv4_address::operator<(const ipv4_address& p) const
{
  if (ip[0]!=p.ip[0]) return ip[0]<p.ip[0];
  if (ip[1]!=p.ip[1]) return ip[1]<p.ip[1];
  if (ip[2]!=p.ip[2]) return ip[2]<p.ip[2];
  return ip[3]<p.ip[3];
}

const string ipv4_address::to_string() const
{
  ostringstream oss;
  oss<<(int)ip[0]<<'.'<<(int)ip[1]<<'.'<<(int)ip[2]<<'.'<<(int)ip[3];
  return oss.str();
};

const ipv4_address ipv4_address::any       = ipv4_address(  0,  0,  0,  0);
const ipv4_address ipv4_address::broadcast = ipv4_address(255,255,255,255);
const ipv4_address ipv4_address::loopback  = ipv4_address(127,  0,  0,  1);
const ipv4_address ipv4_address::none      = ipv4_address(255,255,255,255);

} // network
} // pfi
<commit_msg>Modified ipv4_address::operator<()'s implementation.<commit_after>// Copyright (c)2008-2012, Preferred Infrastructure Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of Preferred Infrastructure nor the names of other
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "ipv4.h"

#include <stddef.h>
#include <stdio.h>
#include <algorithm>
#include <sstream>

using namespace std;

namespace pfi {
namespace network {

ipv4_address::ipv4_address() : ip() {}

ipv4_address::ipv4_address(unsigned char a,
                           unsigned char b,
                           unsigned char c,
                           unsigned char d)
{
  ip[0]=a;
  ip[1]=b;
  ip[2]=c;
  ip[3]=d;
}

ipv4_address::ipv4_address(const string& s)
{
  int buf[4];
  if (sscanf(s.c_str(), "%d.%d.%d.%d", &buf[0], &buf[1], &buf[2], &buf[3]) != 4) {
    *this = none;
    return;
  }
  for (size_t i = 0; i < sizeof(buf)/sizeof(buf[0]); ++i) {
    ip[i] = buf[i];
    if (buf[i] < 0 || buf[1] > 255) {
      *this = none;
      return;
    }
  }
}

bool ipv4_address::operator==(const ipv4_address& p) const
{
  return std::equal(ip, ip+sizeof(ip), p.ip);
}

bool ipv4_address::operator!=(const ipv4_address& p) const
{
  return !(*this==p);
}

bool ipv4_address::operator<(const ipv4_address& p) const
{
  return std::lexicographical_compare(ip, ip+sizeof(ip), p.ip, p.ip+sizeof(p.ip));
}

const string ipv4_address::to_string() const
{
  ostringstream oss;
  oss<<(int)ip[0]<<'.'<<(int)ip[1]<<'.'<<(int)ip[2]<<'.'<<(int)ip[3];
  return oss.str();
};

const ipv4_address ipv4_address::any       = ipv4_address(  0,  0,  0,  0);
const ipv4_address ipv4_address::broadcast = ipv4_address(255,255,255,255);
const ipv4_address ipv4_address::loopback  = ipv4_address(127,  0,  0,  1);
const ipv4_address ipv4_address::none      = ipv4_address(255,255,255,255);

} // network
} // pfi
<|endoftext|>


<commit_before>/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "core/rendering/RenderWidget.h"

#include "core/accessibility/AXObjectCache.h"
#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLPlugInElement.h"
#include "core/paint/BoxPainter.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/compositing/CompositedLayerMapping.h"
#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "wtf/HashMap.h"

namespace blink {

RenderWidget::RenderWidget(Element* element)
    : RenderReplaced(element)
#if !ENABLE(OILPAN)
    // Reference counting is used to prevent the widget from being
    // destroyed while inside the Widget code, which might not be
    // able to handle that.
    , m_refCount(1)
#endif
{
    ASSERT(element);
    frameView()->addWidget(this);
}

void RenderWidget::willBeDestroyed()
{
    frameView()->removeWidget(this);

    if (AXObjectCache* cache = document().existingAXObjectCache()) {
        cache->childrenChanged(this->parent());
        cache->remove(this);
    }

    Element* element = toElement(node());
    if (element && element->isFrameOwnerElement())
        toHTMLFrameOwnerElement(element)->setWidget(nullptr);

    RenderReplaced::willBeDestroyed();
}

void RenderWidget::destroy()
{
#if ENABLE(ASSERT) && ENABLE(OILPAN)
    ASSERT(!m_didCallDestroy);
    m_didCallDestroy = true;
#endif
    willBeDestroyed();
    clearNode();
#if ENABLE(OILPAN)
    // In Oilpan, postDestroy doesn't delete |this|. So calling it here is safe
    // though |this| will be referred in FrameView.
    postDestroy();
#else
    deref();
#endif
}

RenderWidget::~RenderWidget()
{
#if !ENABLE(OILPAN)
    ASSERT(m_refCount <= 0);
#endif
}

Widget* RenderWidget::widget() const
{
    // Plugin widgets are stored in their DOM node. This includes HTMLAppletElement.
    Element* element = toElement(node());

    if (element && element->isFrameOwnerElement())
        return toHTMLFrameOwnerElement(element)->ownedWidget();

    return 0;
}

// Widgets are always placed on integer boundaries, so rounding the size is actually
// the desired behavior. This function is here because it's otherwise seldom what we
// want to do with a LayoutRect.
static inline IntRect roundedIntRect(const LayoutRect& rect)
{
    return IntRect(roundedIntPoint(rect.location()), roundedIntSize(rect.size()));
}

bool RenderWidget::setWidgetGeometry(const LayoutRect& frame)
{
    if (!node())
        return false;

    Widget* widget = this->widget();
    ASSERT(widget);

    IntRect newFrame = roundedIntRect(frame);

    if (widget->frameRect() == newFrame)
        return false;

    RefPtrWillBeRawPtr<RenderWidget> protector(this);
    RefPtrWillBeRawPtr<Node> protectedNode(node());
    widget->setFrameRect(newFrame);
    return widget->frameRect().size() != newFrame.size();
}

bool RenderWidget::updateWidgetGeometry()
{
    Widget* widget = this->widget();
    ASSERT(widget);

    LayoutRect contentBox = contentBoxRect();
    LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox)).boundingBox());
    if (widget->isFrameView()) {
        contentBox.setLocation(absoluteContentBox.location());
        return setWidgetGeometry(contentBox);
    }

    return setWidgetGeometry(absoluteContentBox);
}

void RenderWidget::layout()
{
    ASSERT(needsLayout());

    clearNeedsLayout();
}

void RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
    RenderReplaced::styleDidChange(diff, oldStyle);
    Widget* widget = this->widget();

    if (widget) {
        if (style()->visibility() != VISIBLE) {
            widget->hide();
        } else {
            widget->show();
        }
    }
}

void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    LayoutPoint adjustedPaintOffset = paintOffset + location();

    Widget* widget = this->widget();
    ASSERT(widget);

    // Tell the widget to paint now. This is the only time the widget is allowed
    // to paint itself. That way it will composite properly with z-indexed layers.
    IntPoint widgetLocation = widget->frameRect().location();
    IntPoint paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + paddingLeft()),
        roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop()));
    IntRect paintRect = paintInfo.rect;

    IntSize widgetPaintOffset = paintLocation - widgetLocation;
    // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
    // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
    if (!widgetPaintOffset.isZero()) {
        paintInfo.context->translate(widgetPaintOffset.width(), widgetPaintOffset.height());
        paintRect.move(-widgetPaintOffset);
    }
    widget->paint(paintInfo.context, paintRect);

    if (!widgetPaintOffset.isZero())
        paintInfo.context->translate(-widgetPaintOffset.width(), -widgetPaintOffset.height());
}

void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);

    if (!shouldPaint(paintInfo, paintOffset))
        return;

    LayoutPoint adjustedPaintOffset = paintOffset + location();

    if (hasBoxDecorationBackground() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
        paintBoxDecorationBackground(paintInfo, adjustedPaintOffset);

    if (paintInfo.phase == PaintPhaseMask) {
        paintMask(paintInfo, adjustedPaintOffset);
        return;
    }

    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->hasOutline())
        paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));

    if (paintInfo.phase != PaintPhaseForeground)
        return;

    if (style()->hasBorderRadius()) {
        LayoutRect borderRect = LayoutRect(adjustedPaintOffset, size());

        if (borderRect.isEmpty())
            return;

        // Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
        paintInfo.context->save();
        RoundedRect roundedInnerRect = style()->getRoundedInnerBorderFor(borderRect,
            paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true);
        BoxPainter::clipRoundedInnerRect(paintInfo.context, borderRect, roundedInnerRect);
    }

    Widget* widget = this->widget();
    if (widget)
        paintContents(paintInfo, paintOffset);

    if (style()->hasBorderRadius())
        paintInfo.context->restore();

    // Paint a partially transparent wash over selected widgets.
    if (isSelected() && !document().printing()) {
        LayoutRect rect = localSelectionRect();
        rect.moveBy(adjustedPaintOffset);
        paintInfo.context->fillRect(pixelSnappedIntRect(rect), selectionBackgroundColor());
    }

    if (canResize())
        layer()->scrollableArea()->paintResizer(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect);
}

#if !ENABLE(OILPAN)
void RenderWidget::deref()
{
    if (--m_refCount <= 0)
        postDestroy();
}
#endif

void RenderWidget::updateOnWidgetChange()
{
    Widget* widget = this->widget();
    if (!widget)
        return;

    if (!style())
        return;

    if (!needsLayout())
        updateWidgetGeometry();

    if (style()->visibility() != VISIBLE) {
        widget->hide();
    } else {
        widget->show();
        // FIXME: Why do we issue a full paint invalidation in this case, but not the other?
        setShouldDoFullPaintInvalidation(true);
    }
}

void RenderWidget::updateWidgetPosition()
{
    Widget* widget = this->widget();
    if (!widget || !node()) // Check the node in case destroy() has been called.
        return;

    bool boundsChanged = updateWidgetGeometry();

    // if the frame bounds got changed, or if view needs layout (possibly indicating
    // content size is wrong) we have to do a layout to set the right widget size
    if (widget && widget->isFrameView()) {
        FrameView* frameView = toFrameView(widget);
        // Check the frame's page to make sure that the frame isn't in the process of being destroyed.
        if ((boundsChanged || frameView->needsLayout()) && frameView->frame().page())
            frameView->layout();
    }
}

void RenderWidget::widgetPositionsUpdated()
{
    Widget* widget = this->widget();
    if (!widget)
        return;
    widget->widgetPositionsUpdated();
}

bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
{
    bool hadResult = result.innerNode();
    bool inside = RenderReplaced::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);

    // Check to see if we are really over the widget itself (and not just in the border/padding area).
    if ((inside || result.isRectBasedTest()) && !hadResult && result.innerNode() == node())
        result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
    return inside;
}

CursorDirective RenderWidget::getCursor(const LayoutPoint& point, Cursor& cursor) const
{
    if (widget() && widget()->isPluginView()) {
        // A plug-in is responsible for setting the cursor when the pointer is over it.
        return DoNotSetCursor;
    }
    return RenderReplaced::getCursor(point, cursor);
}

} // namespace blink
<commit_msg>Crash when the widget is 0 in RenderWidget::paintContents.<commit_after>/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "core/rendering/RenderWidget.h"

#include "core/accessibility/AXObjectCache.h"
#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLPlugInElement.h"
#include "core/paint/BoxPainter.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/compositing/CompositedLayerMapping.h"
#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "wtf/HashMap.h"

namespace blink {

RenderWidget::RenderWidget(Element* element)
    : RenderReplaced(element)
#if !ENABLE(OILPAN)
    // Reference counting is used to prevent the widget from being
    // destroyed while inside the Widget code, which might not be
    // able to handle that.
    , m_refCount(1)
#endif
{
    ASSERT(element);
    frameView()->addWidget(this);
}

void RenderWidget::willBeDestroyed()
{
    frameView()->removeWidget(this);

    if (AXObjectCache* cache = document().existingAXObjectCache()) {
        cache->childrenChanged(this->parent());
        cache->remove(this);
    }

    Element* element = toElement(node());
    if (element && element->isFrameOwnerElement())
        toHTMLFrameOwnerElement(element)->setWidget(nullptr);

    RenderReplaced::willBeDestroyed();
}

void RenderWidget::destroy()
{
#if ENABLE(ASSERT) && ENABLE(OILPAN)
    ASSERT(!m_didCallDestroy);
    m_didCallDestroy = true;
#endif
    willBeDestroyed();
    clearNode();
#if ENABLE(OILPAN)
    // In Oilpan, postDestroy doesn't delete |this|. So calling it here is safe
    // though |this| will be referred in FrameView.
    postDestroy();
#else
    deref();
#endif
}

RenderWidget::~RenderWidget()
{
#if !ENABLE(OILPAN)
    ASSERT(m_refCount <= 0);
#endif
}

Widget* RenderWidget::widget() const
{
    // Plugin widgets are stored in their DOM node. This includes HTMLAppletElement.
    Element* element = toElement(node());

    if (element && element->isFrameOwnerElement())
        return toHTMLFrameOwnerElement(element)->ownedWidget();

    return 0;
}

// Widgets are always placed on integer boundaries, so rounding the size is actually
// the desired behavior. This function is here because it's otherwise seldom what we
// want to do with a LayoutRect.
static inline IntRect roundedIntRect(const LayoutRect& rect)
{
    return IntRect(roundedIntPoint(rect.location()), roundedIntSize(rect.size()));
}

bool RenderWidget::setWidgetGeometry(const LayoutRect& frame)
{
    if (!node())
        return false;

    Widget* widget = this->widget();
    ASSERT(widget);

    IntRect newFrame = roundedIntRect(frame);

    if (widget->frameRect() == newFrame)
        return false;

    RefPtrWillBeRawPtr<RenderWidget> protector(this);
    RefPtrWillBeRawPtr<Node> protectedNode(node());
    widget->setFrameRect(newFrame);
    return widget->frameRect().size() != newFrame.size();
}

bool RenderWidget::updateWidgetGeometry()
{
    Widget* widget = this->widget();
    ASSERT(widget);

    LayoutRect contentBox = contentBoxRect();
    LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox)).boundingBox());
    if (widget->isFrameView()) {
        contentBox.setLocation(absoluteContentBox.location());
        return setWidgetGeometry(contentBox);
    }

    return setWidgetGeometry(absoluteContentBox);
}

void RenderWidget::layout()
{
    ASSERT(needsLayout());

    clearNeedsLayout();
}

void RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
    RenderReplaced::styleDidChange(diff, oldStyle);
    Widget* widget = this->widget();

    if (widget) {
        if (style()->visibility() != VISIBLE) {
            widget->hide();
        } else {
            widget->show();
        }
    }
}

void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    LayoutPoint adjustedPaintOffset = paintOffset + location();

    Widget* widget = this->widget();
    RELEASE_ASSERT(widget);

    // Tell the widget to paint now. This is the only time the widget is allowed
    // to paint itself. That way it will composite properly with z-indexed layers.
    IntPoint widgetLocation = widget->frameRect().location();
    IntPoint paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + paddingLeft()),
        roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop()));
    IntRect paintRect = paintInfo.rect;

    IntSize widgetPaintOffset = paintLocation - widgetLocation;
    // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
    // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
    if (!widgetPaintOffset.isZero()) {
        paintInfo.context->translate(widgetPaintOffset.width(), widgetPaintOffset.height());
        paintRect.move(-widgetPaintOffset);
    }
    widget->paint(paintInfo.context, paintRect);

    if (!widgetPaintOffset.isZero())
        paintInfo.context->translate(-widgetPaintOffset.width(), -widgetPaintOffset.height());
}

void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);

    if (!shouldPaint(paintInfo, paintOffset))
        return;

    LayoutPoint adjustedPaintOffset = paintOffset + location();

    if (hasBoxDecorationBackground() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
        paintBoxDecorationBackground(paintInfo, adjustedPaintOffset);

    if (paintInfo.phase == PaintPhaseMask) {
        paintMask(paintInfo, adjustedPaintOffset);
        return;
    }

    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->hasOutline())
        paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));

    if (paintInfo.phase != PaintPhaseForeground)
        return;

    if (style()->hasBorderRadius()) {
        LayoutRect borderRect = LayoutRect(adjustedPaintOffset, size());

        if (borderRect.isEmpty())
            return;

        // Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
        paintInfo.context->save();
        RoundedRect roundedInnerRect = style()->getRoundedInnerBorderFor(borderRect,
            paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true);
        BoxPainter::clipRoundedInnerRect(paintInfo.context, borderRect, roundedInnerRect);
    }

    Widget* widget = this->widget();
    if (widget)
        paintContents(paintInfo, paintOffset);

    if (style()->hasBorderRadius())
        paintInfo.context->restore();

    // Paint a partially transparent wash over selected widgets.
    if (isSelected() && !document().printing()) {
        LayoutRect rect = localSelectionRect();
        rect.moveBy(adjustedPaintOffset);
        paintInfo.context->fillRect(pixelSnappedIntRect(rect), selectionBackgroundColor());
    }

    if (canResize())
        layer()->scrollableArea()->paintResizer(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect);
}

#if !ENABLE(OILPAN)
void RenderWidget::deref()
{
    if (--m_refCount <= 0)
        postDestroy();
}
#endif

void RenderWidget::updateOnWidgetChange()
{
    Widget* widget = this->widget();
    if (!widget)
        return;

    if (!style())
        return;

    if (!needsLayout())
        updateWidgetGeometry();

    if (style()->visibility() != VISIBLE) {
        widget->hide();
    } else {
        widget->show();
        // FIXME: Why do we issue a full paint invalidation in this case, but not the other?
        setShouldDoFullPaintInvalidation(true);
    }
}

void RenderWidget::updateWidgetPosition()
{
    Widget* widget = this->widget();
    if (!widget || !node()) // Check the node in case destroy() has been called.
        return;

    bool boundsChanged = updateWidgetGeometry();

    // if the frame bounds got changed, or if view needs layout (possibly indicating
    // content size is wrong) we have to do a layout to set the right widget size
    if (widget && widget->isFrameView()) {
        FrameView* frameView = toFrameView(widget);
        // Check the frame's page to make sure that the frame isn't in the process of being destroyed.
        if ((boundsChanged || frameView->needsLayout()) && frameView->frame().page())
            frameView->layout();
    }
}

void RenderWidget::widgetPositionsUpdated()
{
    Widget* widget = this->widget();
    if (!widget)
        return;
    widget->widgetPositionsUpdated();
}

bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
{
    bool hadResult = result.innerNode();
    bool inside = RenderReplaced::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);

    // Check to see if we are really over the widget itself (and not just in the border/padding area).
    if ((inside || result.isRectBasedTest()) && !hadResult && result.innerNode() == node())
        result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
    return inside;
}

CursorDirective RenderWidget::getCursor(const LayoutPoint& point, Cursor& cursor) const
{
    if (widget() && widget()->isPluginView()) {
        // A plug-in is responsible for setting the cursor when the pointer is over it.
        return DoNotSetCursor;
    }
    return RenderReplaced::getCursor(point, cursor);
}

} // namespace blink
<|endoftext|>