void LHENode<ImageSigT>::lheProcess(const Matrix<float>& img, Matrix<float>& result) { if (m_img_update_time < getInputPort()->getMTime()) { buildPDFGrid(img); lheBuildCDFGrid(); m_img_update_time = getInputPort()->getMTime(); } sliceCDFGrid(img,result); }
TFx *TExternalProgramFx::clone(bool recursive) const { TExternalProgramFx *fx = dynamic_cast<TExternalProgramFx *>(TExternFx::create(m_externFxName)); assert(fx); // new TExternalProgramFx(); // fx->setExecutable(m_executablePath, m_args); // copia della time region fx->setActiveTimeRegion(getActiveTimeRegion()); // fx->m_imp->m_activeTimeRegion = m_imp->m_activeTimeRegion; fx->getParams()->copy(getParams()); assert(getInputPortCount() == fx->getInputPortCount()); // std::map<std::string, Port>::const_iterator j; // for(j=m_ports.begin(); j!=m_ports.end(); ++j) // fx->addPort(j->first, j->second.m_ext, j->second.m_port != 0); // copia ricorsiva sulle porte if (recursive) { for (int i = 0; i < getInputPortCount(); ++i) { TFxPort *port = getInputPort(i); if (port->getFx()) fx->connect(getInputPortName(i), port->getFx()->clone(true)); } } // std::map<std::string, TParamP>::const_iterator j; // for(j=m_params.begin(); j!=m_params.end(); ++j) // fx->addParam(j->first, j->second->clone()); return fx; }
bool FilterTypeInfoHelper::isMode(const QString &id, InputPortMode mode) const { const PortInfo& info = getInputPort(id); if(info.isValid()) return info.mode == mode; return false; }
string TMacroFx::getAlias(double frame, const TRenderSettings &info) const { string alias = getFxType(); alias += "["; // alias degli effetti connessi alle porte di input separati da virgole // una porta non connessa da luogo a un alias vuoto (stringa vuota) int i; for (i = 0; i < getInputPortCount(); i++) { TFxPort *port = getInputPort(i); if (port->isConnected()) { TRasterFxP ifx = port->getFx(); assert(ifx); alias += ifx->getAlias(frame, info); } alias += ","; } // alias dei valori dei parametri dell'effetto al frame dato for (int j = 0; j < (int)m_fxs.size(); j++) { alias += (j == 0) ? "(" : ",("; for (i = 0; i < m_fxs[j]->getParams()->getParamCount(); i++) { if (i > 0) alias += ","; TParam *param = m_fxs[j]->getParams()->getParam(i); alias += param->getName() + "=" + param->getValueAlias(frame, 2); } alias += ")"; } alias += "]"; return alias; }
bool ImageWriteNode<ImgSigT>::selfcheck() { if (m_file_path == "") { EAGLEEYE_ERROR("file path couldn't be empty\n"); return false; } core::FileManager::FileHandle file_handle = core::FileManager::FileFactory(m_file_path.c_str()); if (!file_handle.get()) { EAGLEEYE_ERROR("sorry,I couldn't support this file type ()\n"); return false; } //judge whether input image signal is correct ImgSigT* input_img_signal = dynamic_cast<ImgSigT*>(getInputPort(0)); if (!input_img_signal) { EAGLEEYE_ERROR("sorry, image type isn't consistent.please be careful...\n"); return false; } return true; }
std::string Iwa_TiledParticlesFx::getAlias(double frame, const TRenderSettings &info) const { std::string alias = getFxType(); alias += "["; // alias degli effetti connessi alle porte di input separati da virgole // una porta non connessa da luogo a un alias vuoto (stringa vuota) for (int i = 0; i < getInputPortCount(); ++i) { TFxPort *port = getInputPort(i); if (port->isConnected()) { TRasterFxP ifx = port->getFx(); assert(ifx); alias += ifx->getAlias(frame, info); } alias += ","; } std::string paramalias(""); for (int i = 0; i < getParams()->getParamCount(); ++i) { TParam *param = getParams()->getParam(i); paramalias += param->getName() + "=" + param->getValueAlias(frame, 3); } return alias + toString(frame) + "," + toString(getIdentifier()) + paramalias + "]"; }
std::string TGeometryFx::getAlias(double frame, const TRenderSettings &info) const { TGeometryFx *tthis = const_cast<TGeometryFx *>(this); TAffine affine = tthis->getPlacement(frame); std::string alias = getFxType(); alias += "["; // alias degli effetti connessi alle porte di input separati da virgole // una porta non connessa da luogo a un alias vuoto (stringa vuota) for (int i = 0; i < getInputPortCount(); ++i) { TFxPort *port = getInputPort(i); if (port->isConnected()) { TRasterFxP ifx = port->getFx(); assert(ifx); alias += ifx->getAlias(frame, info); } alias += ","; } return alias + (areAlmostEqual(affine.a11, 0) ? "0" : ::to_string(affine.a11, 5)) + "," + (areAlmostEqual(affine.a12, 0) ? "0" : ::to_string(affine.a12, 5)) + "," + (areAlmostEqual(affine.a13, 0) ? "0" : ::to_string(affine.a13, 5)) + "," + (areAlmostEqual(affine.a21, 0) ? "0" : ::to_string(affine.a21, 5)) + "," + (areAlmostEqual(affine.a22, 0) ? "0" : ::to_string(affine.a22, 5)) + "," + (areAlmostEqual(affine.a23, 0) ? "0" : ::to_string(affine.a23, 5)) + "]"; }
void TRasterFx::compute(TFlash &flash, int frame) { for (int i = getInputPortCount() - 1; i >= 0; i--) { TFxPort *port = getInputPort(i); if (port->isConnected() && !port->isaControlPort()) { flash.pushMatrix(); ((TRasterFxP)(port->getFx()))->compute(flash, frame); flash.popMatrix(); } } }
int FilterTypeInfoHelper::portType(const QString &id) const { const PortInfo& input = getInputPort(id); if(input.isValid()) return input.type; const PortInfo& output = getOutputPort(id); if(output.isValid()) return output.type; return -1; }
bool AirSpring::init(void) { mPositionPort = getInputPort(0)->toRealPortHandle(); if (!mPositionPort.isConnected()) { Log(Model, Error) << "Initialization of AirSpring model \"" << getName() << "\" failed: Input port \"" << getInputPortName(0) << "\" is not connected!" << endl; return false; } mVelocityPort = getInputPort(1)->toRealPortHandle(); if (!mVelocityPort.isConnected()) { Log(Model, Error) << "Initialization of AirSpring model \"" << getName() << "\" failed: Input port \"" << getInputPortName(1) << "\" is not connected!" << endl; return false; } return Model::init(); }
bool DeadBand::init(void) { mInputPort = getInputPort(0)->toRealPortHandle(); if (!mInputPort.isConnected()) { Log(Model, Error) << "Initialization of DeadBand model \"" << getName() << "\" failed: Input port \"" << getInputPortName(0) << "\" is not connected!" << endl; return false; } return Model::init(); }
void LineRenderer::draw() { boost::lock_guard<boost::mutex> lock(mMutex); // For all input data boost::unordered_map<uint, LineSet::pointer>::iterator it; for(it = mLineSetsToRender.begin(); it != mLineSetsToRender.end(); it++) { LineSet::pointer points = it->second; LineSetAccess::pointer access = points->getAccess(ACCESS_READ); AffineTransformation::pointer transform = SceneGraph::getAffineTransformationFromData(points); glPushMatrix(); glMultMatrixf(transform->data()); ProcessObjectPort port = getInputPort(it->first); if(mInputWidths.count(port) > 0) { glLineWidth(mInputWidths[port]); } else { glLineWidth(mDefaultLineWidth); } if(mInputColors.count(port) > 0) { Color c = mInputColors[port]; glColor3f(c.getRedValue(), c.getGreenValue(), c.getBlueValue()); } else { Color c = mDefaultColor; glColor3f(c.getRedValue(), c.getGreenValue(), c.getBlueValue()); } bool drawOnTop; if(mInputDrawOnTop.count(port) > 0) { drawOnTop = mInputDrawOnTop[port]; } else { drawOnTop = mDefaultDrawOnTop; } if(drawOnTop) glDisable(GL_DEPTH_TEST); glBegin(GL_LINES); for(uint i = 0; i < access->getNrOfLines(); i++) { Vector2ui line = access->getLine(i); Vector3f a = access->getPoint(line.x()); Vector3f b = access->getPoint(line.y()); glVertex3f(a.x(), a.y(), a.z()); glVertex3f(b.x(), b.y(), b.z()); } glEnd(); if(drawOnTop) glEnable(GL_DEPTH_TEST); glPopMatrix(); } glColor3f(1.0f, 1.0f, 1.0f); // Reset color }
void TGeometryFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) { TRasterFxPort *input = dynamic_cast<TRasterFxPort *>(getInputPort(0)); assert(input); if (!input->isConnected()) return; if (!getActiveTimeRegion().contains(frame)) { TRasterFxP(input->getFx())->compute(tile, frame, ri); return; } if (!TRaster32P(tile.getRaster()) && !TRaster64P(tile.getRaster())) throw TException("AffineFx unsupported pixel type"); TAffine aff1 = getPlacement(frame); TRenderSettings ri2(ri); ri2.m_affine = ri2.m_affine * aff1; TRasterFxP src = getInputPort("source")->getFx(); src->compute(tile, frame, ri2); return; }
bool Launchbar::init(void) { mState = Unmounted; mAngleCommand = mUpAngle; mTryMountPort = getInputPort(0)->toRealPortHandle(); if (!mTryMountPort.isConnected()) { Log(Model, Error) << "Initialization of Launchbar model \"" << getName() << "\" failed: Input port \"" << getInputPortName(0) << "\" is not connected!" << std::endl; return false; } mLaunchCommandPort = getInputPort(1)->toRealPortHandle(); if (!mLaunchCommandPort.isConnected()) { Log(Model, Error) << "Initialization of Launchbar model \"" << getName() << "\" failed: Input port \"" << getInputPortName(1) << "\" is not connected!" << std::endl; return false; } return ExternalForce::init(); }
bool DenseDescriptorDictionaryTrainer::selfcheck() { if (!m_descriptor) { EAGLEEYE_ERROR("sorry, please descriptor extractor"); return false; } if (!TO_INFO_SIGNAL(std::string,getInputPort(0))) { EAGLEEYE_ERROR("sorry,there isn't correct input port"); return false; } return true; }
bool TGeometryFx::doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info) { TRasterFxPort *input = dynamic_cast<TRasterFxPort *>(getInputPort(0)); assert(input); if (input->isConnected()) { TRasterFxP fx = input->getFx(); assert(fx); bool ret = fx->doGetBBox(frame, bBox, info); if (getActiveTimeRegion().contains(frame)) bBox = getPlacement(frame) * bBox; return ret; } else { bBox = TRectD(); return false; } return true; };
void Iwa_TiledParticlesFx::doDryCompute(TRectD &rect, double frame, const TRenderSettings &info) { Iwa_ParticlesManager *pc = Iwa_ParticlesManager::instance(); unsigned long fxId = getIdentifier(); int inputPortCount = getInputPortCount(); int i, j, curr_frame = frame, /*- 現在のフレーム -*/ startframe = startpos_val->getValue(); /*- Particesの開始フレーム -*/ TRenderSettings infoOnInput(info); infoOnInput.m_affine = TAffine(); // Using the standard reference - indep. from cameras. infoOnInput.m_bpp = 64; // Control ports rendered at 32 bit - since not visible. for (i = startframe - 1; i <= curr_frame; ++i) { double frame = tmax(0, i); for (j = 0; j < inputPortCount; ++j) { TFxPort *port = getInputPort(j); std::string tmpName = getInputPortName(j); if (port->isConnected()) { TRasterFxP fx = port->getFx(); // Now, consider that source ports work different than control ones QString portName = QString::fromStdString(tmpName); if (portName.startsWith("C")) { // Control ports are calculated from start to current frame, since // particle mechanics at current frame is influenced by previous ones // (and therefore by all previous control images). TRectD bbox; fx->getBBox(frame, bbox, infoOnInput); if (bbox == TConsts::infiniteRectD) bbox = info.m_affine.inv() * rect; fx->dryCompute(bbox, frame, infoOnInput); } else if (portName.startsWith("T")) { // Particles handle source ports caching procedures on its own. } } } } }
bool FilterTypeInfoHelper::canConnect(const QString &portId, const PortInfo& info, QString &warning) const { warning.clear(); const PortInfo& port = getInputPort(portId); if(!port.isValid()) return false; if(!port.isArray && info.isArray) warning = tr("Connecting list port to single port: only the first element of the list will be used\n"); if(port.isArray && !info.isArray) warning = tr("Connecting single port to list port: value will be converted into a one-element list\n"); if(port.type == info.type) return true; if(port.compatibleTypes.contains(info.type)) return true; if(port.partlyCompatibleTypes.contains(info.type)) { warning += port.partlyCompatibleTypes[info.type]; return true; } warning.clear(); return false; }
bool Bias::init(void) { // Invalidate outputs mOutput.resize(0, 0); mInputPort = getInputPort(0)->toMatrixPortHandle(); if (!mInputPort.isConnected()) { Log(Model, Error) << "Initialization of Bias model \"" << getName() << "\" failed: Input port \"" << getInputPortName(0) << "\" is not connected!" << endl; return false; } // Size compatibility check if (size(mInputPort.getMatrixValue()) != size(mBias)) { Log(Model, Error) << "Input port of \"" << getName() << "\", does not " << "match the size of the bias property" << endl; return false; } mOutput.resize(mInputPort.getMatrixValue()); return Model::init(); }
void MeshRenderer::draw2D( cl::BufferGL PBO, uint width, uint height, Eigen::Transform<float, 3, Eigen::Affine> pixelToViewportTransform, float PBOspacing, Vector2f translation ) { boost::lock_guard<boost::mutex> lock(mMutex); OpenCLDevice::pointer device = getMainDevice(); cl::CommandQueue queue = device->getCommandQueue(); std::vector<cl::Memory> v; v.push_back(PBO); queue.enqueueAcquireGLObjects(&v); // Map would probably be better here, but doesn't work on NVIDIA, segfault surprise! //float* pixels = (float*)queue.enqueueMapBuffer(PBO, CL_TRUE, CL_MAP_WRITE, 0, width*height*sizeof(float)*4); boost::shared_array<float> pixels(new float[width*height*sizeof(float)*4]); queue.enqueueReadBuffer(PBO, CL_TRUE, 0, width*height*4*sizeof(float), pixels.get()); boost::unordered_map<uint, Mesh::pointer>::iterator it; for(it = mMeshToRender.begin(); it != mMeshToRender.end(); it++) { Mesh::pointer mesh = it->second; if(mesh->getDimensions() != 2) // Mesh must be 2D continue; Color color = mDefaultColor; ProcessObjectPort port = getInputPort(it->first); if(mInputColors.count(port) > 0) { color = mInputColors[port]; } MeshAccess::pointer access = mesh->getMeshAccess(ACCESS_READ); std::vector<VectorXui> lines = access->getLines(); std::vector<MeshVertex> vertices = access->getVertices(); // Draw each line for(int i = 0; i < lines.size(); ++i) { Vector2ui line = lines[i]; Vector2f a = vertices[line.x()].getPosition(); Vector2f b = vertices[line.y()].getPosition(); Vector2f direction = b - a; float lengthInPixels = ceil(direction.norm() / PBOspacing); // Draw the line for(int j = 0; j <= lengthInPixels; ++j) { Vector2f positionInMM = a + direction*((float)j/lengthInPixels); Vector2f positionInPixels = positionInMM / PBOspacing; int x = round(positionInPixels.x()); int y = round(positionInPixels.y()); y = height - 1 - y; if(x < 0 || y < 0 || x >= width || y >= height) continue; pixels[4*(x + y*width)] = color.getRedValue(); pixels[4*(x + y*width) + 1] = color.getGreenValue(); pixels[4*(x + y*width) + 2] = color.getBlueValue(); } } } //queue.enqueueUnmapMemObject(PBO, pixels); queue.enqueueWriteBuffer(PBO, CL_TRUE, 0, width*height*4*sizeof(float), pixels.get()); queue.enqueueReleaseGLObjects(&v); }
void MeshRenderer::draw() { boost::lock_guard<boost::mutex> lock(mMutex); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); glEnable(GL_LIGHTING); boost::unordered_map<uint, Mesh::pointer>::iterator it; for(it = mMeshToRender.begin(); it != mMeshToRender.end(); it++) { Mesh::pointer surfaceToRender = it->second; if(surfaceToRender->getDimensions() != 3) continue; // Draw the triangles in the VBO AffineTransformation::pointer transform = SceneGraph::getAffineTransformationFromData(surfaceToRender); glPushMatrix(); glMultMatrixf(transform->data()); float opacity = mDefaultOpacity; Color color = mDefaultColor; ProcessObjectPort port = getInputPort(it->first); if(mInputOpacities.count(port) > 0) { opacity = mInputOpacities[port]; } if(mInputColors.count(port) > 0) { color = mInputColors[port]; } // Set material properties if(opacity < 1) { // Enable transparency glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } GLfloat GLcolor[] = { color.getRedValue(), color.getGreenValue(), color.getBlueValue(), opacity }; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GLcolor); GLfloat specReflection[] = { mDefaultSpecularReflection, mDefaultSpecularReflection, mDefaultSpecularReflection, 1.0f }; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specReflection); GLfloat shininess[] = { 16.0f }; glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess); VertexBufferObjectAccess::pointer access = surfaceToRender->getVertexBufferObjectAccess(ACCESS_READ, getMainDevice()); GLuint* VBO_ID = access->get(); // Normal Buffer glBindBuffer(GL_ARRAY_BUFFER, *VBO_ID); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3, GL_FLOAT, 24, 0); glNormalPointer(GL_FLOAT, 24, (float*)(sizeof(GLfloat)*3)); glDrawArrays(GL_TRIANGLES, 0, surfaceToRender->getNrOfTriangles()*3); // Release buffer glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); if(opacity < 1) { // Disable transparency glDisable(GL_BLEND); } glPopMatrix(); } glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); glColor3f(1.0f, 1.0f, 1.0f); // Reset color }
void ImageWriteNode<ImgSigT>::executeNodeInfo() { core::FileManager::FileHandle file_handle = core::FileManager::FileFactory(m_file_path.c_str()); if (!file_handle.get()) { EAGLEEYE_ERROR("sorry, I couldn't write image\n"); return; } ImgSigT* input_img_signal = dynamic_cast<ImgSigT*>(getInputPort(INPUT_PORT_IMAGE_DATA)); Matrix<PixelType> input_img = input_img_signal->img; input_img.clone(); //write image file switch(AtomicTypeTrait<PixelType>::pixel_type) { case EAGLEEYE_CHAR: { file_handle->saveImageData((void*)input_img.dataptr(), input_img.rows(), input_img.cols(), core::CORE_CHAR); break; } case EAGLEEYE_UCHAR: { file_handle->saveImageData((void*)input_img.dataptr(), input_img.rows(), input_img.cols(), core::CORE_UCHAR); break; } case EAGLEEYE_SHORT: { file_handle->saveImageData((void*)input_img.dataptr(), input_img.rows(), input_img.cols(), core::CORE_SHORT); break; } case EAGLEEYE_USHORT: { file_handle->saveImageData((void*)input_img.dataptr(), input_img.rows(), input_img.cols(), core::CORE_USHORT); break; } case EAGLEEYE_INT: { file_handle->saveImageData((void*)input_img.dataptr(), input_img.rows(), input_img.cols(), core::CORE_INT); break; } case EAGLEEYE_UINT: { file_handle->saveImageData((void*)input_img.dataptr(), input_img.rows(), input_img.cols(), core::CORE_UINT); break; } case EAGLEEYE_FLOAT: { file_handle->saveImageData((void*)input_img.dataptr(), input_img.rows(), input_img.cols(), core::CORE_FLOAT); break; } case EAGLEEYE_RGB: { //switch channels order Matrix<ERGB> swith_img = input_img.transform<ERGB>(); //switch pixel channel switchPixelChannels(swith_img); file_handle->saveImageData((void*)swith_img.dataptr(), swith_img.rows(), swith_img.cols(), core::CORE_RGB_UCHAR); break; } case EAGLEEYE_RGBA: { //switch channels order Matrix<ERGBA> swith_img = input_img.transform<ERGBA>(); //switch pixel channel switchPixelChannels(swith_img); file_handle->saveImageData((void*)swith_img.dataptr(), swith_img.rows(), swith_img.cols(), core::CORE_RGBA_UCHAR); break; } default: { EAGLEEYE_ERROR("couldn't write image\n"); break; } } }
bool FilterTypeInfoHelper::hasInputPort(const QString &id) const { return getInputPort(id).isValid(); }
void SemanticBagOfWordsTrainer::train() { //get samples file std::string training_samples_file = TO_INFO(std::string,getInputPort(INPUT_PORT_SAMPLES_INFO)); Matrix<float> samples_label,samples_representation; { Matrix<float> training_samples; EagleeyeIO::read(training_samples,m_trainer_folder + training_samples_file + m_ext_name,READ_BINARY_MODE); int samples_num = training_samples.rows(); samples_label = training_samples(Range(0,samples_num),Range(0,1)); samples_label.clone(); samples_representation = training_samples(Range(0,samples_num),Range(1,training_samples.cols())); samples_representation.clone(); } EagleeyeIO semantic_models_o; semantic_models_o.createWriteHandle(m_trainer_folder + m_trainer_name + m_ext_name,false,WRITE_BINARY_MODE); //write class number semantic_models_o.write(m_class_num); for (int class_index = 0; class_index < 2; ++class_index) { EAGLEEYE_INFO("process model %d\n",class_index); Matrix<float> resampling_label = samples_label; resampling_label.clone(); int samples_num = resampling_label.rows(); //reassign positive and negative samples for (int i = 0; i < samples_num; ++i) { if (int(resampling_label(i)) == class_index) resampling_label(i) = 0.0f; else resampling_label(i) = 1.0f; } Matrix<float> resampling_samples = samples_representation; resampling_samples.clone(); resampling(resampling_samples,resampling_label); int resamples_num = resampling_label.rows(); //reconstruct sample feature Matrix<float> words_frequency = resampling_samples(Range(0,resamples_num),Range(0,m_words_num)); Matrix<float> words_pair_dis = resampling_samples(Range(0,resamples_num),Range(m_words_num,m_words_num + m_clique_num)); Matrix<float> words_pair_angle = resampling_samples(Range(0,resamples_num),Range(m_words_num + m_clique_num,m_words_num + 2 * m_clique_num)); Matrix<int> target_states(resamples_num,m_words_num); for (int sample_index = 0; sample_index < resamples_num; ++sample_index) { if (int(resampling_label(sample_index)) == 0) { //positive samples for (int w_index = 0; w_index < m_words_num; ++w_index) { if (words_frequency(sample_index,w_index) > 0.0001f) target_states(sample_index,w_index) = 1; else target_states(sample_index,w_index) = 0; } } else { //negative samples for (int w_index = 0; w_index < m_words_num; ++w_index) { if (words_frequency(sample_index,w_index) > 0.0001f) target_states(sample_index,w_index) = 2; else target_states(sample_index,w_index) = 0; } } } /* putToMatlab(target_states,"target");*/ //start training SemanticBagOfWords* semantic_model = new SemanticBagOfWords(m_words_num,3); semantic_model->semanticLearn(target_states,words_frequency,words_pair_dis,words_pair_angle); Matrix<float> unary_coe,clique_coe; semantic_model->getModelParam(unary_coe,clique_coe); semantic_models_o.write(unary_coe); semantic_models_o.write(clique_coe); delete semantic_model; } semantic_models_o.destroyHandle(); //write classifier model info InfoSignal<std::string>* output_signal_calssifier_info = TO_INFO_SIGNAL(std::string,getOutputPort(OUTPUT_PORT_CLASSIFIER_INFO)); m_trainer_info = m_trainer_name; output_signal_calssifier_info->info = &m_trainer_info; //evaluate performance }
bool Tank::init(void) { mInputPort = getInputPort(0)->toRealPortHandle(); return Mass::init(); }
TFxPort *getXsheetPort() const override { return getInputPort(1); }