void AnimationForm::slot_setColorFromPicker(QRgb rgba)
{
	CObjectModel *pModel = m_pEditData->getObjectModel() ;
	QModelIndex index = m_pEditData->getSelIndex() ;
	if ( !pModel->isLayer(index) ) { return ; }

	int frame = m_pEditData->getSelectFrame() ;
	ObjectItem *pItem = pModel->getItemFromIndex(index) ;
	FrameData *pData = pItem->getFrameDataPtr(frame) ;
	if ( !pData ) {
		pData = pModel->getFrameDataFromPrevFrame(index, frame, true) ;
		if ( !pData ) { return ; }
		FrameData *pNext = pModel->getFrameDataFromNextFrame(index, frame) ;
		FrameData data = pData->getInterpolation(pNext, frame) ;
		data.rgba[0] = qRed(rgba) ;
		data.rgba[1] = qGreen(rgba) ;
		data.rgba[2] = qBlue(rgba) ;
		slot_addNewFrameData(index, frame, data);
	}
	else {
		pData->rgba[0] = qRed(rgba) ;
		pData->rgba[1] = qGreen(rgba) ;
		pData->rgba[2] = qBlue(rgba) ;

		addCommandEdit(*pData);
	}
}
Beispiel #2
0
 void update( const FrameData& frameData )
 {
     initTransferFunction( frameData.getRenderSettings().getTransferFunction( ));
     _nSamplesPerRay = frameData.getVRParameters().getSamplesPerRay();
     _computedSamplesPerRay = _nSamplesPerRay;
     _nSamplesPerPixel = frameData.getVRParameters().getSamplesPerPixel();
 }
void makeFromEditDataArea(ObjectItem *pObj, QVector4D *pqv4AreaMin, QVector4D *pqv4AreaMax, bool isRecursive)
{
    QMatrix4x4 mat = pObj->getDisplayMatrix(0);
    FrameData frameData = pObj->getDisplayFrameData(0);
    QVector3D v[4];
    frameData.getVertexApplyMatrix(v, mat);
    for (int i = 0; i < 4; i++)
    {
        if (pqv4AreaMin->x() > v[i].x())
            pqv4AreaMin->setX(v[i].x());
        if (pqv4AreaMin->y() > v[i].y())
            pqv4AreaMin->setY(v[i].y());
        if (pqv4AreaMin->z() > v[i].z())
            pqv4AreaMin->setZ(v[i].z());
        if (pqv4AreaMax->x() < v[i].x())
            pqv4AreaMax->setX(v[i].x());
        if (pqv4AreaMax->y() < v[i].y())
            pqv4AreaMax->setY(v[i].y());
        if (pqv4AreaMax->z() < v[i].z())
            pqv4AreaMax->setZ(v[i].z());
    }

    if (isRecursive == false)
        return;

    if (pObj->childCount())
    {
        for (int i = 0; i < pObj->childCount(); i++)
        {
            ObjectItem *pChild = pObj->child(i);
            makeFromEditDataArea(pChild, pqv4AreaMin, pqv4AreaMax, isRecursive);
        }
    }
}
Beispiel #4
0
void CompositeViewer::advance( const uint32_t frameNumber,
        const FrameData& frameData )
{
    _frameStamp->setFrameNumber( frameNumber );
    // reference time has to use osg::Timer because other OSG internals that
    // attempt to compute relative time based on the frame stamp also use it
    // (e.g. IncrementalCompileOperation)
    _frameStamp->setReferenceTime( osg::Timer::instance( )->delta_s( _startTick,
        osg::Timer::instance( )->tick( )));
    _frameStamp->setSimulationTime( frameData.getSimulationTime( ));
    const time_t calendar = frameData.getCalendarTime( );
    struct tm now;
    if( NULL != gmtime_r( &calendar, &now ))
        _frameStamp->setCalendarTime( now );

#if OSG_VERSION_GREATER_OR_EQUAL( 3, 0, 0 )
    for( RefViews::iterator vitr = _views.begin( );
            vitr != _views.end( ); ++vitr )
    {
        osgViewer::View *view = vitr->get( );
        view->getEventQueue( )->frame( _frameStamp->getReferenceTime( ));
    }
#endif

    if( osg::Referenced::getDeleteHandler( ))
    {
        osg::Referenced::getDeleteHandler( )->flush( );
        osg::Referenced::getDeleteHandler( )->setFrameNumber( frameNumber );
    }
}
QMatrix4x4 ObjectItem::getDisplayMatrix(int frame, bool *bValid)
{
    QMatrix4x4 parent, mat;
    if (m_pParent)
    {
        parent = m_pParent->getDisplayMatrix(frame);
    }

    bool valid;
    FrameData d = getDisplayFrameData(frame, &valid);
    if (valid)
    {
        mat = parent * d.getMatrix();

        if (bValid)
        {
            *bValid = true;
        }
    }
    else
    {
        if (bValid)
        {
            *bValid = false;
        }
    }
    return mat;
}
void ofxBvh::parseMotion(const string& data)
{
	vector<string> lines = ofSplitString(data, "\n", true, true);
	
	int index = 0;
	
	while (index < lines.size())
	{
		string line = lines[index];
		
		if (line.empty())
		{
			index++;
			continue;
		}
		
		if (line.find("MOTION") != string::npos) {}
		else if (line.find("Frames:") != string::npos)
		{
			num_frames = ofToInt(ofSplitString(line, ":")[1]);
		}
		else if (line.find("Frame Time:") != string::npos)
		{
			frame_time = ofToFloat(ofSplitString(line, ":")[1]);
		}
		else break;
		
		index++;
	}
	
	while (index < lines.size())
	{
		string line = lines[index];
		vector<string> channels = ofSplitString(line, " ");

		if (channels.size() != total_channels)
		{
			ofLogError("ofxBvh", "channel size mismatch");
			return;
		}
		
		char buf[64];
		FrameData data;
		for (int i = 0; i < channels.size(); i++)
		{
			float v;
			sscanf(channels[i].c_str(), "%f", &v);
			data.push_back(v);
		}
		
		frames.push_back(data);
		
		index++;
	}
	
	if (num_frames != frames.size())
		ofLogWarning("ofxBvh", "frame size mismatch");
}
// 選択中レイヤのUV変更
void AnimationForm::slot_changeSelectLayerUV( QRectF rect )
{
	addNowSelectLayerAndFrame();
	FrameData *p = getNowSelectFrameData() ;
	if ( !p ) {
		return ;
	}
	p->setRect(rect) ;
	addCommandEdit(*p) ;

	slot_setUI(*p);
}
Beispiel #8
0
bool getFramePointCloud(int frameID, pcl::PointCloud<pcl::PointXYZRGB> &pointCloud)
{
	FrameData frameData;
	if (!frameData.loadImageRGBD(frameID)) {
		pointCloud.points.clear();
		return false;
	}

	// allocate the point cloud buffer
	pointCloud.width = NBPIXELS_WIDTH;
	pointCloud.height = NBPIXELS_HEIGHT;
	pointCloud.points.clear();
	pointCloud.points.reserve(NBPIXELS_WIDTH*NBPIXELS_HEIGHT);	// memory preallocation
	//pointCloud.points.resize(NBPIXELS_WIDTH*NBPIXELS_HEIGHT);

	//printf("Generating point cloud frame %d\n", frameID);

	float focalInv = 0.001 / Config::_FocalLength;
	unsigned int rgb;
	int depth_index = 0;
	IplImage *img = frameData.getImage();
	for (int ind_y =0; ind_y < NBPIXELS_HEIGHT; ind_y++)
	{
		for (int ind_x=0; ind_x < NBPIXELS_WIDTH; ind_x++, depth_index++)
		{
			//pcl::PointXYZRGB& pt = pointCloud(ind_x,ind_y);
			TDepthPixel depth = frameData.getDepthData()[depth_index];
			if (depth != 0)
			{
				pcl::PointXYZRGB pt;

				// locate point in meters
				pt.z = (ind_x - NBPIXELS_X_HALF) * depth * focalInv;
				pt.y = (NBPIXELS_Y_HALF - ind_y) * depth * focalInv;
				pt.x = depth * 0.001 ; // depth values are given in mm

				// reinterpret color bytes
				unsigned char b = ((uchar *)(img->imageData + ind_y*img->widthStep))[ind_x*img->nChannels + 0];
				unsigned char g = ((uchar *)(img->imageData + ind_y*img->widthStep))[ind_x*img->nChannels + 1];
				unsigned char r = ((uchar *)(img->imageData + ind_y*img->widthStep))[ind_x*img->nChannels + 2];
				rgb = (((unsigned int)r)<<16) | (((unsigned int)g)<<8) | ((unsigned int)b);
				pt.rgb = *reinterpret_cast<float*>(&rgb);
				pointCloud.push_back(pt);
			}
		}
	}

	return true;
}
FrameData ObjectItem::getDisplayFrameData(int frame, bool *bValid)
{
	FrameData d ;
	FrameData *pPrev = getFrameDataFromPrevFrame(frame+1) ;
	if ( pPrev ) {
		FrameData *pNext = getFrameDataFromNextFrame(frame) ;
		d = pPrev->getInterpolation(pNext, frame) ;
		d.frame = frame ;
		if ( bValid ) { *bValid = true ; }
	}
	else {
		if ( bValid ) { *bValid = false ; }
	}
	return d ;
}
// uv bottom 変更
void AnimationForm::slot_changeUvBottom( double val )
{
	if ( m_pGlWidget->getDragMode() != AnimeGLWidget::kDragMode_None ) { return ; }
	if ( m_bDontSetData ) { return ; }

	addNowSelectLayerAndFrame();
	FrameData *p = getNowSelectFrameData() ;
	if ( !p ) { return ; }

	p->bottom = val ;
	addCommandEdit(*p) ;

	QRectF rect = p->getRect() ;
	m_pEditData->setCatchRect(rect);
	emit sig_imageRepaint() ;
}
void CompoundUpdateOutputVisitor::_updateZoom(const Compound* compound,
                                              Frame* frame)
{
    Zoom zoom = frame->getNativeZoom();
    Zoom zoom_1;

    if (!zoom.isValid()) // if zoom is not set, auto-calculate from parent
    {
        zoom_1 = compound->getInheritZoom();
        LBASSERT(zoom_1.isValid());
        zoom.x() = 1.0f / zoom_1.x();
        zoom.y() = 1.0f / zoom_1.y();
    }
    else
    {
        zoom_1.x() = 1.0f / zoom.x();
        zoom_1.y() = 1.0f / zoom.y();
    }

    if (frame->getType() == Frame::TYPE_TEXTURE)
    {
        FrameData* frameData = frame->getMasterData();
        frameData->setZoom(zoom_1); // textures are zoomed by input frame
        frame->setZoom(Zoom::NONE);
    }
    else
    {
        Zoom inputZoom;
        /* Output frames downscale pixel data during readback, and upscale it on
         * the input frame by setting the input frame's inherit zoom. */
        if (zoom.x() > 1.0f)
        {
            inputZoom.x() = zoom_1.x();
            zoom.x() = 1.f;
        }
        if (zoom.y() > 1.0f)
        {
            inputZoom.y() = zoom_1.y();
            zoom.y() = 1.f;
        }

        FrameData* frameData = frame->getMasterData();
        frameData->setZoom(inputZoom);
        frame->setZoom(zoom);
    }
}
Beispiel #12
0
void CAnm2D::renderOpenGL_FrameData(const FrameData &data, QMatrix4x4 mat)
{
	QRectF rect ;
	QRect uv = data.getRect() ;
	QRectF uvF ;

	AnmImage *pImage = getImage(data.nImage) ;
	if ( !pImage ) { return ; }

	const GLTexture *pTex = gEditData.getTexture(pImage->path) ;
	if ( !pTex ) { return ; }

	glPushMatrix() ;
	{
		double m[16] ;
		convMat(m, mat) ;
		m[14] /= 4096.0 ;
		glMultMatrixd(m) ;

		Vertex v = data.getVertex() ;
		rect.setLeft(v.x0);
		rect.setRight(v.x1) ;
		rect.setTop(v.y0);
		rect.setBottom(v.y1);

		int w = pTex->imgSize.width() ;
		int h = pTex->imgSize.height() ;
		uvF.setLeft((float)uv.left()/w) ;
		uvF.setRight((float)uv.right()/w) ;
		uvF.setTop(1.0f-(float)uv.top()/h) ;
		uvF.setBottom(1.0f-(float)uv.bottom()/h) ;

		glBindTexture(GL_TEXTURE_2D, pTex->nTexObj) ;

		QColor col ;
		col.setRed(data.rgba[0]);
		col.setGreen(data.rgba[1]);
		col.setBlue(data.rgba[2]);
		col.setAlpha(data.rgba[3]);

		drawRect(rect, uvF, 0, col) ;
	}
	glPopMatrix() ;
}
// UI数値セット
void AnimationForm::slot_setUI(FrameData data)
{
	m_bDontSetData = true ;
	if ( data.pos_x != ui->doubleSpinBox_pos_x->value() ) { ui->doubleSpinBox_pos_x->setValue(data.pos_x); }
	if ( data.pos_y != ui->doubleSpinBox_pos_y->value() ) { ui->doubleSpinBox_pos_y->setValue(data.pos_y); }
	if ( data.pos_z != ui->doubleSpinBox_pos_z->value() ) { ui->doubleSpinBox_pos_z->setValue(data.pos_z); }
	if ( data.rot_x != ui->doubleSpinBox_rot_x->value() ) { ui->doubleSpinBox_rot_x->setValue(data.rot_x); }
	if ( data.rot_y != ui->doubleSpinBox_rot_y->value() ) { ui->doubleSpinBox_rot_y->setValue(data.rot_y); }
	if ( data.rot_z != ui->doubleSpinBox_rot_z->value() ) { ui->doubleSpinBox_rot_z->setValue(data.rot_z); }
	if ( data.fScaleX != (float)ui->doubleSpinBox_scale_x->value() ) { ui->doubleSpinBox_scale_x->setValue(data.fScaleX) ; }
	if ( data.fScaleY != (float)ui->doubleSpinBox_scale_y->value() ) { ui->doubleSpinBox_scale_y->setValue(data.fScaleY) ; }

	if ( data.left   != ui->doubleSpinBox_uv_left->value() ) { ui->doubleSpinBox_uv_left->setValue(data.left); }
	if ( data.right  != ui->doubleSpinBox_uv_right->value() ) { ui->doubleSpinBox_uv_right->setValue(data.right); }
	if ( data.top    != ui->doubleSpinBox_uv_top->value() ) { ui->doubleSpinBox_uv_top->setValue(data.top); }
	if ( data.bottom != ui->doubleSpinBox_uv_bottom->value() ) { ui->doubleSpinBox_uv_bottom->setValue(data.bottom); }

	if ( data.center_x != ui->doubleSpinBox_center_x->value() ) { ui->doubleSpinBox_center_x->setValue(data.center_x); }
	if ( data.center_y != ui->doubleSpinBox_center_y->value() ) { ui->doubleSpinBox_center_y->setValue(data.center_y); }
	if ( data.nImage != ui->comboBox_image_no->currentText().toInt() ) {
		for ( int i = 0 ; i < ui->comboBox_image_no->count() ; i ++ ) {
			if ( ui->comboBox_image_no->itemText(i).toInt() == data.nImage ) {
				ui->comboBox_image_no->setCurrentIndex(i);
				break ;
			}
		}
		emit sig_imageChangeTab(data.nImage) ;
	}
	if ( data.bUVAnime != ui->checkBox_uv_anime->isChecked() ) { ui->checkBox_uv_anime->setChecked(data.bUVAnime); }
	if ( data.rgba[0] != ui->spinBox_r->value() ) { ui->spinBox_r->setValue(data.rgba[0]); }
	if ( data.rgba[1] != ui->spinBox_g->value() ) { ui->spinBox_g->setValue(data.rgba[1]); }
	if ( data.rgba[2] != ui->spinBox_b->value() ) { ui->spinBox_b->setValue(data.rgba[2]); }
	if ( data.rgba[3] != ui->spinBox_a->value() ) { ui->spinBox_a->setValue(data.rgba[3]); }
	m_bDontSetData = false ;

	if ( data.getRect() != m_pEditData->getCatchRect() ) {
		QRectF rect = data.getRect() ;
		m_pEditData->setCatchRect(rect);
		emit sig_imageChangeRect(rect) ;
		emit sig_imageRepaint() ;
	}
}
// 選択レイヤの選択フレームにフレームデータを追加
void AnimationForm::addNowSelectLayerAndFrame( void )
{
	CObjectModel *pModel = m_pEditData->getObjectModel() ;
	QModelIndex index = m_pEditData->getSelIndex() ;

	if ( !pModel->isLayer(index) ) { return ; }

	ObjectItem *pItem = pModel->getItemFromIndex(index) ;
	if ( !pItem ) { return ; }

	int frame = m_pEditData->getSelectFrame() ;
	if ( pItem->getFrameDataPtr(frame) ) { return ; }

	FrameData *pPrev = pModel->getFrameDataFromPrevFrame(index, frame, true) ;
	if ( !pPrev ) { return ; }
	FrameData *pNext = pModel->getFrameDataFromNextFrame(index, frame) ;
	FrameData data = pPrev->getInterpolation(pNext, frame) ;

	slot_addNewFrameData(index, frame, data) ;	// フレームデータ追加
}
Beispiel #15
0
void CAnm2D::setRect(AnmLayer *pLayer)
{
	bool valid0, valid1 ;
	FrameData data = pLayer->getDisplayFrameData(0, &valid0) ;
	QMatrix4x4 mat = pLayer->getDisplayMatrix(0, &valid1) ;
	if ( valid0 && valid1 ) {
		QVector3D v[4] ;
		data.getVertexApplyMatrix(v, mat) ;

		for ( int i = 0 ; i < 4 ; i ++ ) {
			if ( m_rect.left() > v[i].x() ) { m_rect.setLeft(v[i].x()) ; }
			if ( m_rect.right() < v[i].x() ) { m_rect.setRight(v[i].x()) ; }
			if ( m_rect.top() > v[i].y() ) { m_rect.setTop(v[i].y()) ; }
			if ( m_rect.bottom() < v[i].y() ) { m_rect.setBottom(v[i].y()) ; }
		}
	}

	for ( int i = 0 ; i < pLayer->childPtrs.size() ; i ++ ) {
		setRect(pLayer->childPtrs[i]) ;
	}
}
Beispiel #16
0
void Frame::cycleData(const uint32_t frameNumber, const Compound* compound)
{
    _masterFrameData = 0;
    for (unsigned i = 0; i < NUM_EYES; ++i)
    {
        _inputFrames[i].clear();

        const Eye eye = Eye(1 << i);
        if (!compound->isInheritActive(eye)) // eye pass not used
        {
            _frameData[i] = 0;
            continue;
        }

        // reuse unused frame data
        FrameData* data = _datas.empty() ? 0 : _datas.back();
        const uint32_t latency = getAutoObsolete();
        const uint32_t dataAge = data ? data->getFrameNumber() : 0;

        if (data && dataAge < frameNumber - latency && frameNumber > latency)
            // not used anymore
            _datas.pop_back();
        else // still used - allocate new data
        {
            data = new FrameData;

            getLocalNode()->registerObject(data);
            data->setAutoObsolete(1); // current + in use by render nodes
        }

        data->setFrameNumber(frameNumber);

        _datas.push_front(data);
        _frameData[i] = data;
        _getInputNodes(i).clear();
        _getInputNetNodes(i).clear();
        if (!_masterFrameData)
            _masterFrameData = data;
    }
}
void ObjectItem::applyFrameDataFromParent()
{
	QList<FrameData> datas ;
	for ( int i = 0 ; i < m_frameDatas.size() ; i ++ ) {
		FrameData data = m_frameDatas[i] ;

		bool valid ;
		QMatrix4x4 mat = getDisplayMatrix(data.frame, &valid) ;
		if ( !valid ) { continue ; }

		data.applyMatrix(mat) ;
		datas.append(data) ;
	}

	FrameData old ;
	int frame = getParentFrameMax() ;
	for ( int i = 0 ; i < frame ; i ++ ) {
		if ( getFrameDataPtr(i) ) {
			old = *getFrameDataPtr(i) ;
			continue ;
		}

		FrameData *parent = getParentFrameDataPtr(i) ;
		if ( !parent ) { continue ; }

		bool valid ;
		FrameData data ;
		data = getDisplayFrameData(i, &valid) ;
		if ( !valid ) { continue ; }

		QMatrix4x4 mat = getDisplayMatrix(i, &valid) ;
		if ( !valid ) { continue ; }

		data.applyMatrix(mat) ;
		if ( !(old.frame&0x8000) ) {
			if ( old.rot_z != data.rot_z ) {
				for ( int j = old.frame + 1 ; j < data.frame ; j ++ ) {
					bool b ;
					FrameData tmp = getDisplayFrameData(j, &b) ;
					if ( !b ) { continue ; }
					QMatrix4x4 mat = getDisplayMatrix(j, &b) ;
					if ( !b ) { continue ; }
					tmp.applyMatrix(mat);
					datas.append(tmp) ;
				}
			}
		}
		old = data ;
		datas.append(data);
	}

	m_frameDatas = datas ;
}
bool ObjectItem::isContain(FrameData &displayData, QPoint &pos, const QMatrix4x4 &matDisp)
{
    QVector3D v[4];
    displayData.getVertexApplyMatrix(v, matDisp);
    QVector3D tri[2][3] = {
        {
            v[0],
            v[2],
            v[1],
        },
        {
            v[2],
            v[1],
            v[3],
        }
    };
    for (int i = 0; i < 3; i++)
    {
        tri[0][i].setZ(0);
        tri[1][i].setZ(0);
    }

    QVector3D p = QVector3D(pos.x(), pos.y(), 0);
    for (int i = 0; i < 2; i++)
    {
        QVector3D p0 = tri[i][0] - p;
        QVector3D p1 = tri[i][1] - p;
        QVector3D p2 = tri[i][2] - p;
        QVector3D c0 = QVector3D::crossProduct(p0, p1);
        QVector3D c1 = QVector3D::crossProduct(p1, p2);
        QVector3D c2 = QVector3D::crossProduct(p2, p0);
        if (QVector3D::dotProduct(c0, c1) > 0 && QVector3D::dotProduct(c1, c2) > 0 && QVector3D::dotProduct(c2, c0) > 0)
        {
            return true;
        }
    }

    return false;
}
// ドロップ時のスロット
// レイヤ追加
void AnimationForm::slot_dropedImage( QRectF rect, QPoint pos, int imageIndex )
{
	CObjectModel *pModel = m_pEditData->getObjectModel() ;
	int frameNum  = ui->label_frame->value() ;
	QModelIndex index = ui->treeView->currentIndex() ;

	if ( !index.isValid() ) {
		qWarning() << "slot_dropedImage current index invalid 0" ;
		return ;
	}

	ObjectItem *pObjItem = pModel->getObject(index) ;
	if ( !pObjItem ) {
		qWarning() << "slot_dropedImage current obj 0" ;
		return ;
	}

	if ( !m_pSetting->getLayerHierarchy() ) {
		index = pObjItem->getIndex() ;
	}

	pos -= QPoint((m_pSetting->getAnmWindowW()/2), (m_pSetting->getAnmWindowH()/2)) ;	// GLWidgetのローカルポスに変換

	ObjectItem *pItem = pModel->getItemFromIndex(index) ;
	bool valid ;
	QMatrix4x4 mat = pItem->getDisplayMatrix(frameNum, &valid) ;
	if ( valid ) {
		QMatrix4x4 inv = mat.inverted(&valid) ;
		if ( valid ) {
			pos = inv.map(pos) ;
		}
	}

	index = m_pEditData->cmd_addItem(QString("Layer %1").arg(pObjItem->childCount()), index) ;
	ui->treeView->setCurrentIndex(index) ;
//	m_pEditData->setSelIndex(index) ;

	// ツリービューに追加
    FrameData frameData ;
	frameData.pos_x = pos.x() ;
	frameData.pos_y = pos.y() ;
	frameData.pos_z = 0 ;
	frameData.rot_x =
	frameData.rot_y =
	frameData.rot_z = 0 ;
	frameData.center_x = (rect.width()) / 2 ;
	frameData.center_y = (rect.height()) / 2 ;
	frameData.frame = frameNum ;
	frameData.fScaleX = frameData.fScaleY = 1.0f ;
	frameData.setRect(rect);
	frameData.nImage = imageIndex ;
	frameData.bUVAnime = false ;
	frameData.rgba[0] =
	frameData.rgba[1] =
	frameData.rgba[2] =
	frameData.rgba[3] = 255 ;

	QList<QWidget *> updateWidget ;
	updateWidget << m_pGlWidget ;
	updateWidget << m_pDataMarker ;

	m_pEditData->cmd_addFrameData(index, frameData, updateWidget) ;
}
AlgorithmWidget::AlgorithmWidget(FrameData& framedata, QWidget *parent) :
	QWidget(parent), framedata(framedata)
{
	setWindowTitle("Algorithm");

	algo_chooser = new QComboBox;
	QStringList list;
	framedata.for_each_algorithm(append_name(list));
	algo_chooser->addItems(list);
	connect(algo_chooser, SIGNAL(currentIndexChanged(int)), //
			this, SLOT(choose(int)));

	int_manager = new QtIntPropertyManager(this);
	bool_manager = new QtBoolPropertyManager(this);
	double_manager = new QtDoublePropertyManager(this);
	enum_manager = new QtEnumPropertyManager(this);
	color_manager = new QtColorPropertyManager(this);
	filepath_manager = new FilePathManager(this);
	vector2d_manager = new QVector2DPropertyManager(this);
	vector3d_manager = new QVector3DPropertyManager(this);
	vector4d_manager = new QVector4DPropertyManager(this);

	connect(int_manager, SIGNAL(valueChanged(QtProperty*, int)), this,
			SLOT(value_changed(QtProperty*, int)));
	connect(bool_manager, SIGNAL(valueChanged(QtProperty*, bool)), this,
			SLOT(value_changed(QtProperty*, bool)));
	connect(double_manager, SIGNAL(valueChanged(QtProperty*, double)), this,
			SLOT(value_changed(QtProperty*, double)));
	connect(enum_manager, SIGNAL(valueChanged(QtProperty*, int)), this,
			SLOT(value_changed(QtProperty*, int)));
	connect(color_manager, SIGNAL(valueChanged(QtProperty*, QColor)), this,
			SLOT(value_changed(QtProperty*, QColor)));
	connect(filepath_manager, SIGNAL(valueChanged(QtProperty*, QString)), this,
			SLOT(value_changed(QtProperty*, QString)));
	connect(vector2d_manager, SIGNAL(valueChanged(QtProperty*, Vec2)), this,
			SLOT(value_changed(QtProperty*, Vec2)));
	connect(vector3d_manager, SIGNAL(valueChanged(QtProperty*, Vec3)), this,
			SLOT(value_changed(QtProperty*, Vec3)));
	connect(vector4d_manager, SIGNAL(valueChanged(QtProperty*, Vec4)), this,
			SLOT(value_changed(QtProperty*, Vec4)));

	QtDoubleSpinBoxFactory* double_factory = new QtDoubleSpinBoxFactory(this);
	QtCheckBoxFactory* bool_factory = new QtCheckBoxFactory(this);
	QtSpinBoxFactory* int_factory = new QtSpinBoxFactory(this);
	QtEnumEditorFactory* enum_factory = new QtEnumEditorFactory(this);
	QtColorEditorFactory* color_factory = new QtColorEditorFactory(this);
	FileEditFactory* filepath_factory = new FileEditFactory(this);

	property_browser = new QtTreePropertyBrowser;
	property_browser->setFactoryForManager(int_manager, int_factory);
	property_browser->setFactoryForManager(bool_manager, bool_factory);
	property_browser->setFactoryForManager(double_manager, double_factory);
	property_browser->setFactoryForManager(enum_manager, enum_factory);
	property_browser->setFactoryForManager(color_manager, color_factory);
	property_browser->setFactoryForManager(
			color_manager->subIntPropertyManager(), int_factory);
	property_browser->setFactoryForManager(filepath_manager, filepath_factory);
	property_browser->setFactoryForManager(
			vector2d_manager->subDoublePropertyManager(), double_factory);
	property_browser->setFactoryForManager(
			vector3d_manager->subDoublePropertyManager(), double_factory);
	property_browser->setFactoryForManager(
			vector4d_manager->subDoublePropertyManager(), double_factory);

	QVBoxLayout* layout = new QVBoxLayout;

	if (framedata.num_algorithms() > 1)
		layout->addWidget(algo_chooser);

	layout->addWidget(property_browser);

	setLayout(layout);
	choose(0);
}
void CompoundUpdateOutputVisitor::_updateFrames(Compound* compound)
{
    const Frames& outputFrames = compound->getOutputFrames();
    if (outputFrames.empty())
        compound->unsetInheritTask(fabric::TASK_READBACK);

    const Channel* channel = compound->getChannel();
    if (!compound->testInheritTask(fabric::TASK_READBACK) || !channel)
        return;

    for (FramesCIter i = outputFrames.begin(); i != outputFrames.end(); ++i)
    {
        //----- Check uniqueness of output frame name
        Frame* frame = *i;
        const std::string& name = frame->getName();

        if (_outputFrames.find(name) != _outputFrames.end())
        {
            LBWARN << "Multiple output frames of the same name are unsupported"
                   << ", ignoring output frame " << name << std::endl;
            frame->unsetData();
            continue;
        }

        //----- compute readback area
        const Viewport& frameVP = frame->getViewport();
        const PixelViewport& inheritPVP = compound->getInheritPixelViewport();
        PixelViewport framePVP(inheritPVP);
        framePVP.apply(frameVP);

        if (!framePVP.hasArea()) // output frame has no pixels
        {
            LBINFO << "Skipping output frame " << name << ", no pixels"
                   << std::endl;
            frame->unsetData();
            continue;
        }

        //----- Create new frame datas
        // * one frame data used for each eye pass
        // * data is set only on master frame data (will copy to all others)
        frame->cycleData(_frameNumber, compound);
        FrameData* frameData = frame->getMasterData();
        LBASSERT(frameData);

        LBLOG(LOG_ASSEMBLY)
            << lunchbox::disableFlush << "Output frame \"" << name << "\" id "
            << frame->getID() << " v" << frame->getVersion() + 1 << " data id "
            << frameData->getID() << " v" << frameData->getVersion() + 1
            << " on channel \"" << channel->getName() << "\" tile pos "
            << framePVP.x << ", " << framePVP.y;

        //----- Set frame data parameters:
        // 1) offset is position wrt destination view, used only by input frames
        const bool tiled = !compound->getInputTileQueues().empty();
        frameData->setOffset(tiled ? Vector2i(0, 0)
                                   : Vector2i(framePVP.x, framePVP.y));

        // 2) pvp is area within channel
        framePVP.x = static_cast<int32_t>(frameVP.x * inheritPVP.w);
        framePVP.y = static_cast<int32_t>(frameVP.y * inheritPVP.h);
        frameData->setPixelViewport(framePVP);

        // 3) image buffers and storage type
        const Frame::Buffer buffers = frame->getBuffers();

        frameData->setType(frame->getType());
        frameData->setBuffers(buffers == Frame::Buffer::undefined
                                  ? compound->getInheritBuffers()
                                  : buffers);

        // 4) (source) render context
        frameData->setContext(compound->setupRenderContext(EYE_CYCLOP));

        //----- Set frame parameters:
        // 1) offset is position wrt window, i.e., the channel position
        if (compound->getInheritChannel() == channel)
            frame->setOffset(Vector2i(inheritPVP.x, inheritPVP.y));
        else
        {
            const PixelViewport& nativePVP = channel->getPixelViewport();
            frame->setOffset(Vector2i(nativePVP.x, nativePVP.y));
        }

        // 2) zoom
        _updateZoom(compound, frame);

        //----- Commit
        frame->commitData();

        _outputFrames[name] = frame;
        LBLOG(LOG_ASSEMBLY)
            << " buffers " << frameData->getBuffers() << " read area "
            << framePVP << " readback " << frame->getZoom() << " assemble "
            << frameData->getZoom() << lunchbox::enableFlush << std::endl;
    }
}