#include #include #include #include "ProjectionModel.h" #include "Channel.h" #include "RSync.h" #include "GUIControler.h" #include "Exporter.h" using namespace projection; /** * Constructor. * * @param pModel Projection model. */ Exporter::Exporter(ProjectionModel* pModel) { m_pModel = pModel; m_bSoftEdge = true; m_blendEdgeWidth = 16; m_blendEdgeExponent = 1.0f; m_exportWidth = 512; m_exportHeight = 512; m_distortMapFileNamePattern = "distort_%CHANNELNAME%.bmp"; m_blendMapFileNamePattern = "blend_%CHANNELNAME%.bmp"; m_viewMatrixFileNamePattern = "view_%CHANNELNAME%.cfg"; m_texCoordColorTexIndex = 0; m_texCoordColorRTexIndex = 0; m_blendAreaTexIndex = 0; } /** * Destructor. */ Exporter::~Exporter() { if (glIsTexture(m_texCoordColorTexIndex)) glDeleteTextures(1, &m_texCoordColorTexIndex); if (glIsTexture(m_blendAreaTexIndex)) glDeleteTextures(1, &m_blendAreaTexIndex); } /** * Enable or disable soft edge blending. * * @param bSoftEdge True if soft edge blending is enabled. */ void Exporter::setSoftEdge(bool bSoftEdge) { if (m_bSoftEdge != bSoftEdge) { m_bSoftEdge = bSoftEdge; if (glIsTexture(m_blendAreaTexIndex)) glDeleteTextures(1, &m_blendAreaTexIndex); m_blendAreaTexIndex = 0; if (m_pModel->getRSync()->isServer()) { QDomDocument doc; doc.appendChild(domElement("Exporter", doc)); m_pModel->getRSync()->sendChanges(RSYNC_COMMAND_EXPORT, doc.toString(0)); } if (m_pModel->getDesignMode() == DESIGN_MODE_BLENDMAP) m_pModel->updateViews(); } } /** * Set width of the soft edge blending. * * @param blendWidth Width of the soft edge blending. */ void Exporter::setBlendEdgeWidth(int blendEdgeWidth) { if (m_blendEdgeWidth != blendEdgeWidth) { m_blendEdgeWidth = blendEdgeWidth; if (glIsTexture(m_blendAreaTexIndex)) glDeleteTextures(1, &m_blendAreaTexIndex); m_blendAreaTexIndex = 0; if (m_pModel->getRSync()->isServer()) { QDomDocument doc; doc.appendChild(domElement("Exporter", doc)); m_pModel->getRSync()->sendChanges(RSYNC_COMMAND_EXPORT, doc.toString(0)); } if (m_pModel->getDesignMode() == DESIGN_MODE_BLENDMAP) m_pModel->updateViews(); } } /** * Set gamma curve of blend map edge. * * @param gamma Curve exponent of blend map edge. */ void Exporter::setBlendEdgeExponent(float blendEdgeExponent) { if (m_blendEdgeExponent != blendEdgeExponent) { m_blendEdgeExponent = blendEdgeExponent; if (glIsTexture(m_blendAreaTexIndex)) glDeleteTextures(1, &m_blendAreaTexIndex); m_blendAreaTexIndex = 0; if (m_pModel->getRSync()->isServer()) { QDomDocument doc; doc.appendChild(domElement("Exporter", doc)); m_pModel->getRSync()->sendChanges(RSYNC_COMMAND_EXPORT, doc.toString(0)); } if (m_pModel->getDesignMode() == DESIGN_MODE_BLENDMAP) m_pModel->updateViews(); } } /** * Set width of distortion map to export. * * @param width Width of distortion map to export. */ void Exporter::setExportWidth(int exportWidth) { if (m_exportWidth != exportWidth) { m_exportWidth = exportWidth; if (m_pModel->getRSync()->isServer()) { QDomDocument doc; doc.appendChild(domElement("Exporter", doc)); m_pModel->getRSync()->sendChanges(RSYNC_COMMAND_EXPORT, doc.toString(0)); } } } /** * Set height of distortion map to export. * * @param height Height of distortion map to export. */ void Exporter::setExportHeight(int exportHeight) { if (m_exportHeight != exportHeight) { m_exportHeight = exportHeight; if (m_pModel->getRSync()->isServer()) { QDomDocument doc; doc.appendChild(domElement("Exporter", doc)); m_pModel->getRSync()->sendChanges(RSYNC_COMMAND_EXPORT, doc.toString(0)); } } } /** * Create a color encoded coordinate texture and retrieve its texture object index. * * @return Texture object index of the encoded coordinate texture. */ unsigned int Exporter::getTexCoordColorTexture() { if (m_texCoordColorTexIndex == 0) { unsigned char *data; data = new unsigned char[256*256*4]; int count = 0; for (unsigned int y=0; y<256; ++y) { for (unsigned int x=0; x<256; ++x) { data[x*4+y*256*4+0] = x; data[x*4+y*256*4+1] = y; data[x*4+y*256*4+2] = 0; data[x*4+y*256*4+3] = 255; count++; } } QImage image((uchar *)data, 256, 256, QImage::Format_RGB32); m_texCoordColorTexIndex = m_pModel->getGUI()->getGLWidget()->bindTexture(image); delete [] data; } return m_texCoordColorTexIndex; } /** * Create a color encoded coordinate texture (red channel) and retrieve its texture object index. * * @return Texture object index of the encoded coordinate texture (red channel). */ unsigned int Exporter::getTexCoordColorRTexture() { if (m_texCoordColorRTexIndex == 0) { unsigned char* data; data = new unsigned char[16*16*4]; int count = 0; for (unsigned int y=0; y<16; ++y) { for (unsigned int x=0; x<16; ++x) { data[x*4+y*16*4+0] = 0; data[x*4+y*16*4+1] = 0; data[x*4+y*16*4+2] = x+y*16; data[x*4+y*16*4+3] = 255; count++; } } QImage image((uchar *)data, 16, 16, QImage::Format_RGB32); m_texCoordColorRTexIndex = m_pModel->getGUI()->getGLWidget()->bindTexture(image); delete [] data; } return m_texCoordColorRTexIndex; } /** * Create an edge blending texture and retrieve its texture object index. * * @return Texture object index of the edge blending texture. */ unsigned int Exporter::getBlendingAreaTexture() { if (m_blendAreaTexIndex == 0) { int blendBaseValue = 255; QPixmap pixmap(128, 128); pixmap.fill(QColor(blendBaseValue, blendBaseValue, blendBaseValue)); if (m_bSoftEdge) { QPainter painter(&pixmap); QPen pen; for (int w=0; wgetGUI()->getGLWidget()->bindTexture(pixmap); } return m_blendAreaTexIndex; } /** * Export projection settings to file. * * @param fileName File name of the projection settings. * @return True if successfully exported. */ bool Exporter::exportDataset(const QString& fileName) { for (unsigned int i=0; igetNumChannels(); ++i) m_pModel->getChannel(i)->exportDataset(fileName); if (m_pModel->getRSync()->isServer()) m_pModel->getRSync()->sendChanges(RSYNC_COMMAND_EXPORTFILE, fileName); return true; } /** * Restore the export settings from XML data. * * @param element Parent XML element of the export settings data. */ bool Exporter::initFromDOMElement(const QDomElement& element) { if (!element.isNull()) { setSoftEdge(element.attribute("softEdge")=="true"); setBlendEdgeWidth(element.attribute("blendEdgeWidth").toInt()); setBlendEdgeExponent(element.attribute("blendEdgeExponent").toFloat()); m_exportWidth = element.attribute("exportWidth").toInt(); m_exportHeight = element.attribute("exportHeight").toInt(); m_distortMapFileNamePattern = element.attribute("distortMapFileNamePattern"); m_blendMapFileNamePattern = element.attribute("blendMapFileNamePattern"); m_viewMatrixFileNamePattern = element.attribute("viewMatrixFileNamePattern"); if (m_distortMapFileNamePattern.isEmpty()) m_distortMapFileNamePattern = "distort_%CHANNELNAME%.bmp"; if (m_blendMapFileNamePattern.isEmpty()) m_blendMapFileNamePattern = "blend_%CHANNELNAME%.bmp"; if (m_viewMatrixFileNamePattern.isEmpty()) m_viewMatrixFileNamePattern = "view_%CHANNELNAME%.cfg"; } return true; // todo: secure this function and return false on any critical error } /** * Store the current export settings as XML data. * * @param name XML node name of the data. * @param doc XML document to store the data. * @return Current export settings data as XML data. */ QDomElement Exporter::domElement(const QString& name, QDomDocument& doc) const { QDomElement de = doc.createElement(name); de.setAttribute("softEdge", m_bSoftEdge?"true":"false"); de.setAttribute("blendEdgeWidth", QString::number(m_blendEdgeWidth)); de.setAttribute("blendEdgeExponent", QString::number(m_blendEdgeExponent)); de.setAttribute("exportWidth", QString::number(m_exportWidth)); de.setAttribute("exportHeight", QString::number(m_exportHeight)); de.setAttribute("distortMapFileNamePattern", m_distortMapFileNamePattern); de.setAttribute("blendMapFileNamePattern", m_blendMapFileNamePattern); de.setAttribute("viewMatrixFileNamePattern", m_viewMatrixFileNamePattern); return de; }