<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2006 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 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
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de

#include "TrackerConfig.h"
#include "trackerconfigdtd.h"
#include "DeDistort.h"

#include "../base/XMLHelper.h"
#include "../base/Logger.h"
#include "../base/FileHelper.h"
#include "../base/Exception.h"

#include <libxml/parser.h>
#include <libxml/xmlwriter.h>
#include <libxml/xmlstring.h>

#include <cstring>
#include <sstream>

using namespace std;

namespace avg {

    void assureEmptyNode(const char * pNodeName)
    {
        if (strcmp(pNodeName, "text") && strcmp(pNodeName, "comment")) {
            AVG_TRACE(Logger::WARNING, "TrackerConfig: Unexpected node " << pNodeName);
        }
    }

    BlobConfig::BlobConfig(bool bIsTouch)
        : m_bIsTouch(bIsTouch),
          m_Threshold(128),
          m_Similarity(31)
    {
          m_AreaBounds[0] = 80;
          m_AreaBounds[1] = 450;
          m_EccentricityBounds[0] = 1;
          m_EccentricityBounds[1] = 3;
    }

    BlobConfig::~BlobConfig()
    {
    }

    void BlobConfig::load(xmlNodePtr pParentNode, const string& sFilename)
    {
        xmlNodePtr curXmlChild = pParentNode->xmlChildrenNode;
        while (curXmlChild) {
            const char * pNodeName = (const char *)curXmlChild->name;
            if (!strcmp(pNodeName, "threshold")) {
                m_Threshold = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "similarity")) {
                m_Similarity = getRequiredDoubleAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "areabounds")) {
                m_AreaBounds[0] = getRequiredIntAttr(curXmlChild, "min");
                m_AreaBounds[1] = getRequiredIntAttr(curXmlChild, "max");
            } else if (!strcmp(pNodeName, "eccentricitybounds")) {
                m_EccentricityBounds[0] = getRequiredDoubleAttr(curXmlChild, "min");
                m_EccentricityBounds[1] = getRequiredDoubleAttr(curXmlChild, "max");
            } else {
                assureEmptyNode(pNodeName);
            }
            curXmlChild = curXmlChild->next;
        }
    }

    void BlobConfig::save(xmlTextWriterPtr writer)
    {
        int rc;
        if (m_bIsTouch) {
            rc = xmlTextWriterStartElement(writer, BAD_CAST "touch");
        } else {
            rc = xmlTextWriterStartElement(writer, BAD_CAST "track");
        }
        writeSimpleXMLNode(writer, "threshold", m_Threshold);
        writeSimpleXMLNode(writer, "similarity", m_Similarity);
        writeMinMaxXMLNode(writer, "areabounds", m_AreaBounds);
        writeMinMaxXMLNode(writer, "eccentricitybounds", m_EccentricityBounds);
        rc = xmlTextWriterEndElement(writer);
    }

    TrackerConfig::TrackerConfig()
        : m_sPixFmt("MONO8"),
          m_Size(640, 480),
          m_Channel(0),
          m_FPS(30),
          m_Brightness(128),
          m_Exposure(128),
          m_Gamma(1),
          m_Gain(128),
          m_Shutter(128),
          m_Prescale(5),
          m_HistoryUpdateInterval(5),
          m_bBrighterRegions(true),
          m_bEventOnMove(true),
          m_ContourPrecision(50),
          m_bCreateDebugImages(false),
          m_bCreateFingerImage(false),
          m_pTrafo(new DeDistort()),
          m_Doc(0)
    {
    }

    TrackerConfig::TrackerConfig(const TrackerConfig& other)
    {
        *this = other;
        if (m_pTouch) {
            *m_pTouch = *(other.m_pTouch);
        }
        if (m_pTrack) {
            *m_pTrack = *(other.m_pTrack);
        }
        *m_pTrafo = *(other.m_pTrafo);
    }

    TrackerConfig::~TrackerConfig()
    {
        // TODO: free complete m_Doc.
    }

    void TrackerConfig::load(const string& sCustomFilename)
    {
        // TODO: There is duplicated code here and in Player::loadFile which belongs
        // in a lower-level xml handling class.
        registerDTDEntityLoader("trackerconfig.dtd", g_pTrackerConfigDTD);
        string sFilename(sCustomFilename);
        if (sCustomFilename.empty()) {
            sFilename = "/etc/avgtrackerrc";
            if (!fileExists(sFilename)) {
                sFilename = getConfigFilename();
            }
        }
        xmlDtdPtr dtd;
        string sDTDFName = "trackerconfig.dtd";
        dtd = xmlParseDTD(NULL, (const xmlChar*) sDTDFName.c_str());
        if (!dtd) {
            AVG_TRACE(Logger::WARNING,
                    "DTD not found at " << sDTDFName << ". Not validating trackerconfig files.");
        }

        m_Doc = xmlParseFile(sFilename.c_str());
        if (!m_Doc) {
            AVG_TRACE(Logger::ERROR, "Could not open tracker config file "
                    << sFilename << ". Using defaults which will probably not work.");
            return;
        }

        xmlValidCtxtPtr cvp = xmlNewValidCtxt();
        cvp->error = xmlParserValidityError;
        cvp->warning = xmlParserValidityWarning;
        int valid=xmlValidateDtd(cvp, m_Doc, dtd);
        xmlFreeValidCtxt(cvp);
        if (!valid) {
            throw (Exception(AVG_ERR_XML_PARSE,
                    sFilename + " does not validate."));
        }

        m_pRoot = xmlDocGetRootElement(m_Doc);

        xmlFreeDtd(dtd);

        parse(false);
    }

    void TrackerConfig::parse(bool bOnlyDyn)
    {
        xmlNodePtr curXmlChild = m_pRoot->xmlChildrenNode;
        while (curXmlChild) {
            const char * pNodeName = (const char *)curXmlChild->name;
            if (!strcmp(pNodeName, "camera")) {
                loadCamera(curXmlChild, getConfigFilename(), bOnlyDyn);
            } else if (!strcmp(pNodeName, "tracker")) {
                loadTracker(curXmlChild, getConfigFilename());
            } else if (!strcmp(pNodeName, "transform")) {
                m_pTrafo->load(DPoint(m_Size), curXmlChild);
            } else {
                assureEmptyNode(pNodeName);
            }
            curXmlChild = curXmlChild->next;
        }
    }

    xmlXPathObjectPtr TrackerConfig::findConfigNodes(const xmlChar* xpExpr)
    {
        xmlXPathContextPtr xpCtx;
        xmlXPathObjectPtr xpElement;

        xpCtx = xmlXPathNewContext(m_Doc);
        if(!xpCtx) {
            AVG_TRACE(Logger::ERROR, "Unable to create new XPath context");
            return NULL;
        }

        xpElement = xmlXPathEvalExpression(xpExpr, xpCtx);
        if(!xpElement) {
            AVG_TRACE(Logger::ERROR, "Unable to evaluate XPath expression '"
                << xpExpr << "'");
            xmlXPathFreeContext(xpCtx);
            return NULL;
        }

        xmlXPathFreeContext(xpCtx);

        return xpElement;
    }

    void TrackerConfig::setParam(const xmlChar* xpExpr, const xmlChar* Value)
    {
        xmlXPathObjectPtr xpElement = findConfigNodes(xpExpr);
        xmlNodeSetPtr nodes = xpElement->nodesetval;

        if (!nodes || nodes->nodeNr == 0)
            throw (Exception(AVG_ERR_OPTION_UNKNOWN,
                        string("setParam(): cannot find requested element ")+string((char *)xpExpr)));

        for(int i = nodes->nodeNr - 1; i >= 0; i--) {
            assert(nodes->nodeTab[i]);

            xmlNodeSetContent(nodes->nodeTab[i], Value);
            if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL)
                nodes->nodeTab[i] = NULL;
        }

        xmlXPathFreeObject(xpElement);

        parse(true);
    }

    string TrackerConfig::getParam(const xmlChar* xpExpr)
    {
        xmlXPathObjectPtr xpElement = findConfigNodes(xpExpr);
        xmlNodeSetPtr nodes = xpElement->nodesetval;

        if (!nodes || nodes->nodeNr == 0)
            throw (Exception(AVG_ERR_OPTION_UNKNOWN,
                        string("getParam(): cannot find requested element ")+string((char *)xpExpr)));
        else if (nodes->nodeNr > 1)
            AVG_TRACE(Logger::WARNING,
                "getParam(): expression selects more than one node. Returning the first.");

        xmlChar *xsRc = xmlNodeGetContent(nodes->nodeTab[0]);
        string sValue((char *)xsRc);

        xmlFree(xsRc);
        xmlXPathFreeObject(xpElement);

        return sValue;
    }

    void TrackerConfig::dump() const
    {
        cerr << "Tracker config: " << endl;
        cerr << "  Camera: " << endl;
        cerr << "    Source: " << m_sSource << endl;
        cerr << "    Device: " << m_sDevice << endl;
        cerr << "    PixFmt: " << m_sPixFmt << endl;
        cerr << "    Size: " << m_Size << endl;
        cerr << "    Channel: " << m_Channel << endl;
        cerr << "    FPS: " << m_FPS << endl;
        cerr << "    Brightness: " << m_Brightness << endl;
        cerr << "    Exposure: " << m_Exposure << endl;
        cerr << "    Gamma: " << m_Gamma << endl;
        cerr << "    Gain: " << m_Gain << endl;
        cerr << "    Shutter: " << m_Shutter << endl;
        cerr << "  Tracker:" << endl;
        cerr << "    Prescale: " << m_Prescale << endl;
        cerr << "    HistoryUpdateInterval: " << m_HistoryUpdateInterval << endl;
        cerr << "    BrighterRegions: " << m_bBrighterRegions << endl;
        cerr << "    EventOnMove: " << m_bEventOnMove << endl;
        cerr << "    ContourPrecision: " << m_ContourPrecision << endl;
        // TODO: Dump Touch/Track
        m_pTrafo->dump();
    }

    void TrackerConfig::save(const string& sCustomFilename)
    {
        string sFilename(sCustomFilename);
        if (sFilename.empty()) {
            sFilename = getConfigFilename();
        }

        AVG_TRACE(Logger::CONFIG, "Saving tracker configuration to "
                << sFilename << ".");

        if (m_Doc)
            xmlSaveFileEnc(sFilename.c_str(), m_Doc, "utf-8");
        else
            throw (Exception(AVG_ERR_FILEIO,
                        "save(): tracker configuration not initialized"));
    }

    void TrackerConfig::loadCamera(xmlNodePtr pParentNode, const string& sFilename, bool bOnlyDyn)
    {
        xmlNodePtr curXmlChild = pParentNode->xmlChildrenNode;
        while (curXmlChild) {
            bool bManaged = true;
            const char * pNodeName = (const char *)curXmlChild->name;
            if (!bOnlyDyn)
            {
                if (!strcmp(pNodeName, "source")) {
                    m_sSource = getRequiredStringAttr(curXmlChild, "value");
                } else if (!strcmp(pNodeName, "device")) {
                    m_sDevice = getRequiredStringAttr(curXmlChild, "value");
                } else if (!strcmp(pNodeName, "format")) {
                    m_sPixFmt = getRequiredStringAttr(curXmlChild, "value");
                } else if (!strcmp(pNodeName, "size")) {
                    m_Size.x = getRequiredIntAttr(curXmlChild, "x");
                    m_Size.y = getRequiredIntAttr(curXmlChild, "y");
                }
                else bManaged = false;
            }

            if (!strcmp(pNodeName, "channel")) {
                // TODO: V4L2 channel is not updated on-the-fly
                m_Channel = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "fps")) {
                m_FPS = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "brightness")) {
                m_Brightness = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "exposure")) {
                m_Exposure = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "gamma")) {
                m_Gamma = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "gain")) {
                m_Gain = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "shutter")) {
                m_Shutter = getRequiredIntAttr(curXmlChild, "value");
            } else {
                if (!bOnlyDyn && !bManaged) {
                    assureEmptyNode(pNodeName);
                }
            }
            curXmlChild = curXmlChild->next;
        }
    }

    void TrackerConfig::loadTracker(xmlNodePtr pParentNode, const string& sFilename)
    {
        xmlNodePtr curXmlChild = pParentNode->xmlChildrenNode;
        while (curXmlChild) {
            const char * pNodeName = (const char *)curXmlChild->name;
            if (!strcmp(pNodeName, "prescale")) {
                m_Prescale = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "historyupdateinterval")) {
                m_HistoryUpdateInterval = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "brighterregions")) {
                m_bBrighterRegions = getRequiredBoolAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "eventonmove")) {
                m_bEventOnMove = getRequiredBoolAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "contourprecision")) {
                m_ContourPrecision = getRequiredIntAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "touch")) {
                m_pTouch = BlobConfigPtr(new BlobConfig(true));
                m_pTouch->load(curXmlChild, sFilename);
            } else if (!strcmp(pNodeName, "track")) {
                m_pTrack = BlobConfigPtr(new BlobConfig(false));
                m_pTrack->load(curXmlChild, sFilename);
            } else {
                assureEmptyNode(pNodeName);
            }
            curXmlChild = curXmlChild->next;
        }
    }

    std::string TrackerConfig::getConfigFilename()
    {
        char * pHome = getenv("HOME");
        if (pHome) {
            return string(pHome)+"/.avgtrackerrc";
        } else {
            return "";
        }
    }
}
<commit_msg>Indentation fix.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2006 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 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
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de

#include "TrackerConfig.h"
#include "trackerconfigdtd.h"
#include "DeDistort.h"

#include "../base/XMLHelper.h"
#include "../base/Logger.h"
#include "../base/FileHelper.h"
#include "../base/Exception.h"

#include <libxml/parser.h>
#include <libxml/xmlwriter.h>
#include <libxml/xmlstring.h>

#include <cstring>
#include <sstream>

using namespace std;

namespace avg {

void assureEmptyNode(const char * pNodeName)
{
    if (strcmp(pNodeName, "text") && strcmp(pNodeName, "comment")) {
        AVG_TRACE(Logger::WARNING, "TrackerConfig: Unexpected node " << pNodeName);
    }
}

BlobConfig::BlobConfig(bool bIsTouch)
    : m_bIsTouch(bIsTouch),
      m_Threshold(128),
      m_Similarity(31)
{
      m_AreaBounds[0] = 80;
      m_AreaBounds[1] = 450;
      m_EccentricityBounds[0] = 1;
      m_EccentricityBounds[1] = 3;
}

BlobConfig::~BlobConfig()
{
}

void BlobConfig::load(xmlNodePtr pParentNode, const string& sFilename)
{
    xmlNodePtr curXmlChild = pParentNode->xmlChildrenNode;
    while (curXmlChild) {
        const char * pNodeName = (const char *)curXmlChild->name;
        if (!strcmp(pNodeName, "threshold")) {
            m_Threshold = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "similarity")) {
            m_Similarity = getRequiredDoubleAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "areabounds")) {
            m_AreaBounds[0] = getRequiredIntAttr(curXmlChild, "min");
            m_AreaBounds[1] = getRequiredIntAttr(curXmlChild, "max");
        } else if (!strcmp(pNodeName, "eccentricitybounds")) {
            m_EccentricityBounds[0] = getRequiredDoubleAttr(curXmlChild, "min");
            m_EccentricityBounds[1] = getRequiredDoubleAttr(curXmlChild, "max");
        } else {
            assureEmptyNode(pNodeName);
        }
        curXmlChild = curXmlChild->next;
    }
}

void BlobConfig::save(xmlTextWriterPtr writer)
{
    int rc;
    if (m_bIsTouch) {
        rc = xmlTextWriterStartElement(writer, BAD_CAST "touch");
    } else {
        rc = xmlTextWriterStartElement(writer, BAD_CAST "track");
    }
    writeSimpleXMLNode(writer, "threshold", m_Threshold);
    writeSimpleXMLNode(writer, "similarity", m_Similarity);
    writeMinMaxXMLNode(writer, "areabounds", m_AreaBounds);
    writeMinMaxXMLNode(writer, "eccentricitybounds", m_EccentricityBounds);
    rc = xmlTextWriterEndElement(writer);
}

TrackerConfig::TrackerConfig()
    : m_sPixFmt("MONO8"),
      m_Size(640, 480),
      m_Channel(0),
      m_FPS(30),
      m_Brightness(128),
      m_Exposure(128),
      m_Gamma(1),
      m_Gain(128),
      m_Shutter(128),
      m_Prescale(5),
      m_HistoryUpdateInterval(5),
      m_bBrighterRegions(true),
      m_bEventOnMove(true),
      m_ContourPrecision(50),
      m_bCreateDebugImages(false),
      m_bCreateFingerImage(false),
      m_pTrafo(new DeDistort()),
      m_Doc(0)
{
}

TrackerConfig::TrackerConfig(const TrackerConfig& other)
{
    *this = other;
    if (m_pTouch) {
        *m_pTouch = *(other.m_pTouch);
    }
    if (m_pTrack) {
        *m_pTrack = *(other.m_pTrack);
    }
    *m_pTrafo = *(other.m_pTrafo);
}

TrackerConfig::~TrackerConfig()
{
    // TODO: free complete m_Doc.
}

void TrackerConfig::load(const string& sCustomFilename)
{
    // TODO: There is duplicated code here and in Player::loadFile which belongs
    // in a lower-level xml handling class.
    registerDTDEntityLoader("trackerconfig.dtd", g_pTrackerConfigDTD);
    string sFilename(sCustomFilename);
    if (sCustomFilename.empty()) {
        sFilename = "/etc/avgtrackerrc";
        if (!fileExists(sFilename)) {
            sFilename = getConfigFilename();
        }
    }
    xmlDtdPtr dtd;
    string sDTDFName = "trackerconfig.dtd";
    dtd = xmlParseDTD(NULL, (const xmlChar*) sDTDFName.c_str());
    if (!dtd) {
        AVG_TRACE(Logger::WARNING,
                "DTD not found at " << sDTDFName << ". Not validating trackerconfig files.");
    }

    m_Doc = xmlParseFile(sFilename.c_str());
    if (!m_Doc) {
        AVG_TRACE(Logger::ERROR, "Could not open tracker config file "
                << sFilename << ". Using defaults which will probably not work.");
        return;
    }

    xmlValidCtxtPtr cvp = xmlNewValidCtxt();
    cvp->error = xmlParserValidityError;
    cvp->warning = xmlParserValidityWarning;
    int valid=xmlValidateDtd(cvp, m_Doc, dtd);
    xmlFreeValidCtxt(cvp);
    if (!valid) {
        throw (Exception(AVG_ERR_XML_PARSE,
                sFilename + " does not validate."));
    }

    m_pRoot = xmlDocGetRootElement(m_Doc);

    xmlFreeDtd(dtd);

    parse(false);
}

void TrackerConfig::parse(bool bOnlyDyn)
{
    xmlNodePtr curXmlChild = m_pRoot->xmlChildrenNode;
    while (curXmlChild) {
        const char * pNodeName = (const char *)curXmlChild->name;
        if (!strcmp(pNodeName, "camera")) {
            loadCamera(curXmlChild, getConfigFilename(), bOnlyDyn);
        } else if (!strcmp(pNodeName, "tracker")) {
            loadTracker(curXmlChild, getConfigFilename());
        } else if (!strcmp(pNodeName, "transform")) {
            m_pTrafo->load(DPoint(m_Size), curXmlChild);
        } else {
            assureEmptyNode(pNodeName);
        }
        curXmlChild = curXmlChild->next;
    }
}

xmlXPathObjectPtr TrackerConfig::findConfigNodes(const xmlChar* xpExpr)
{
    xmlXPathContextPtr xpCtx;
    xmlXPathObjectPtr xpElement;

    xpCtx = xmlXPathNewContext(m_Doc);
    if(!xpCtx) {
        AVG_TRACE(Logger::ERROR, "Unable to create new XPath context");
        return NULL;
    }

    xpElement = xmlXPathEvalExpression(xpExpr, xpCtx);
    if(!xpElement) {
        AVG_TRACE(Logger::ERROR, "Unable to evaluate XPath expression '"
            << xpExpr << "'");
        xmlXPathFreeContext(xpCtx);
        return NULL;
    }

    xmlXPathFreeContext(xpCtx);

    return xpElement;
}

void TrackerConfig::setParam(const xmlChar* xpExpr, const xmlChar* Value)
{
    xmlXPathObjectPtr xpElement = findConfigNodes(xpExpr);
    xmlNodeSetPtr nodes = xpElement->nodesetval;

    if (!nodes || nodes->nodeNr == 0)
        throw (Exception(AVG_ERR_OPTION_UNKNOWN,
                    string("setParam(): cannot find requested element ")+string((char *)xpExpr)));

    for(int i = nodes->nodeNr - 1; i >= 0; i--) {
        assert(nodes->nodeTab[i]);

        xmlNodeSetContent(nodes->nodeTab[i], Value);
        if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL)
            nodes->nodeTab[i] = NULL;
    }

    xmlXPathFreeObject(xpElement);

    parse(true);
}

string TrackerConfig::getParam(const xmlChar* xpExpr)
{
    xmlXPathObjectPtr xpElement = findConfigNodes(xpExpr);
    xmlNodeSetPtr nodes = xpElement->nodesetval;

    if (!nodes || nodes->nodeNr == 0)
        throw (Exception(AVG_ERR_OPTION_UNKNOWN,
                    string("getParam(): cannot find requested element ")+string((char *)xpExpr)));
    else if (nodes->nodeNr > 1)
        AVG_TRACE(Logger::WARNING,
            "getParam(): expression selects more than one node. Returning the first.");

    xmlChar *xsRc = xmlNodeGetContent(nodes->nodeTab[0]);
    string sValue((char *)xsRc);

    xmlFree(xsRc);
    xmlXPathFreeObject(xpElement);

    return sValue;
}

void TrackerConfig::dump() const
{
    cerr << "Tracker config: " << endl;
    cerr << "  Camera: " << endl;
    cerr << "    Source: " << m_sSource << endl;
    cerr << "    Device: " << m_sDevice << endl;
    cerr << "    PixFmt: " << m_sPixFmt << endl;
    cerr << "    Size: " << m_Size << endl;
    cerr << "    Channel: " << m_Channel << endl;
    cerr << "    FPS: " << m_FPS << endl;
    cerr << "    Brightness: " << m_Brightness << endl;
    cerr << "    Exposure: " << m_Exposure << endl;
    cerr << "    Gamma: " << m_Gamma << endl;
    cerr << "    Gain: " << m_Gain << endl;
    cerr << "    Shutter: " << m_Shutter << endl;
    cerr << "  Tracker:" << endl;
    cerr << "    Prescale: " << m_Prescale << endl;
    cerr << "    HistoryUpdateInterval: " << m_HistoryUpdateInterval << endl;
    cerr << "    BrighterRegions: " << m_bBrighterRegions << endl;
    cerr << "    EventOnMove: " << m_bEventOnMove << endl;
    cerr << "    ContourPrecision: " << m_ContourPrecision << endl;
    // TODO: Dump Touch/Track
    m_pTrafo->dump();
}

void TrackerConfig::save(const string& sCustomFilename)
{
    string sFilename(sCustomFilename);
    if (sFilename.empty()) {
        sFilename = getConfigFilename();
    }

    AVG_TRACE(Logger::CONFIG, "Saving tracker configuration to "
            << sFilename << ".");

    if (m_Doc)
        xmlSaveFileEnc(sFilename.c_str(), m_Doc, "utf-8");
    else
        throw (Exception(AVG_ERR_FILEIO,
                    "save(): tracker configuration not initialized"));
}

void TrackerConfig::loadCamera(xmlNodePtr pParentNode, const string& sFilename, bool bOnlyDyn)
{
    xmlNodePtr curXmlChild = pParentNode->xmlChildrenNode;
    while (curXmlChild) {
        bool bManaged = true;
        const char * pNodeName = (const char *)curXmlChild->name;
        if (!bOnlyDyn)
        {
            if (!strcmp(pNodeName, "source")) {
                m_sSource = getRequiredStringAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "device")) {
                m_sDevice = getRequiredStringAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "format")) {
                m_sPixFmt = getRequiredStringAttr(curXmlChild, "value");
            } else if (!strcmp(pNodeName, "size")) {
                m_Size.x = getRequiredIntAttr(curXmlChild, "x");
                m_Size.y = getRequiredIntAttr(curXmlChild, "y");
            }
            else bManaged = false;
        }

        if (!strcmp(pNodeName, "channel")) {
            // TODO: V4L2 channel is not updated on-the-fly
            m_Channel = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "fps")) {
            m_FPS = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "brightness")) {
            m_Brightness = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "exposure")) {
            m_Exposure = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "gamma")) {
            m_Gamma = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "gain")) {
            m_Gain = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "shutter")) {
            m_Shutter = getRequiredIntAttr(curXmlChild, "value");
        } else {
            if (!bOnlyDyn && !bManaged) {
                assureEmptyNode(pNodeName);
            }
        }
        curXmlChild = curXmlChild->next;
    }
}

void TrackerConfig::loadTracker(xmlNodePtr pParentNode, const string& sFilename)
{
    xmlNodePtr curXmlChild = pParentNode->xmlChildrenNode;
    while (curXmlChild) {
        const char * pNodeName = (const char *)curXmlChild->name;
        if (!strcmp(pNodeName, "prescale")) {
            m_Prescale = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "historyupdateinterval")) {
            m_HistoryUpdateInterval = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "brighterregions")) {
            m_bBrighterRegions = getRequiredBoolAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "eventonmove")) {
            m_bEventOnMove = getRequiredBoolAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "contourprecision")) {
            m_ContourPrecision = getRequiredIntAttr(curXmlChild, "value");
        } else if (!strcmp(pNodeName, "touch")) {
            m_pTouch = BlobConfigPtr(new BlobConfig(true));
            m_pTouch->load(curXmlChild, sFilename);
        } else if (!strcmp(pNodeName, "track")) {
            m_pTrack = BlobConfigPtr(new BlobConfig(false));
            m_pTrack->load(curXmlChild, sFilename);
        } else {
            assureEmptyNode(pNodeName);
        }
        curXmlChild = curXmlChild->next;
    }
}

std::string TrackerConfig::getConfigFilename()
{
    char * pHome = getenv("HOME");
    if (pHome) {
        return string(pHome)+"/.avgtrackerrc";
    } else {
        return "";
    }
}

}
<|endoftext|>


<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "MeshVisualizer.h"

#include <Corrade/Utility/Resource.h>

#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
#include "Magnum/Shader.h"
#include "MagnumExternal/Optional/optional.hpp"

#include "Implementation/CreateCompatibilityShader.h"

namespace Magnum { namespace Shaders {

MeshVisualizer::MeshVisualizer(const Flags flags): flags(flags), transformationProjectionMatrixUniform(0), viewportSizeUniform(1), colorUniform(2), wireframeColorUniform(3), wireframeWidthUniform(4), smoothnessUniform(5) {
    #ifndef MAGNUM_TARGET_GLES2
    if(flags & Flag::Wireframe && !(flags & Flag::NoGeometryShader)) {
        #ifndef MAGNUM_TARGET_GLES
        MAGNUM_ASSERT_VERSION_SUPPORTED(Version::GL320);
        MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::geometry_shader4);
        #elif !defined(MAGNUM_TARGET_WEBGL)
        MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::geometry_shader);
        #endif
    }
    #else
    if(flags & Flag::Wireframe)
        MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::OES::standard_derivatives);
    #endif

    #ifdef MAGNUM_BUILD_STATIC
    /* Import resources on static build, if not already */
    if(!Utility::Resource::hasGroup("MagnumShaders"))
        importShaderResources();
    #endif
    Utility::Resource rs("MagnumShaders");

    #ifndef MAGNUM_TARGET_GLES
    const Version version = Context::current()->supportedVersion({Version::GL320, Version::GL310, Version::GL300, Version::GL210});
    CORRADE_INTERNAL_ASSERT(!flags || flags & Flag::NoGeometryShader || version >= Version::GL320);
    #elif !defined(MAGNUM_TARGET_WEBGL)
    const Version version = Context::current()->supportedVersion({Version::GLES310, Version::GLES300, Version::GLES200});
    CORRADE_INTERNAL_ASSERT(!flags || flags & Flag::NoGeometryShader || version >= Version::GLES310);
    #else
    const Version version = Context::current()->supportedVersion({Version::GLES300, Version::GLES200});
    #endif

    Shader vert = Implementation::createCompatibilityShader(rs, version, Shader::Type::Vertex);
    Shader frag = Implementation::createCompatibilityShader(rs, version, Shader::Type::Fragment);

    vert.addSource(flags & Flag::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
        .addSource(flags & Flag::NoGeometryShader ? "#define NO_GEOMETRY_SHADER\n" : "")
        #ifdef MAGNUM_TARGET_WEBGL
        .addSource("#define SUBSCRIPTING_WORKAROUND\n")
        #elif defined(MAGNUM_TARGET_GLES2)
        .addSource(Context::current()->detectedDriver() & Context::DetectedDriver::ProbablyAngle ?
            "#define SUBSCRIPTING_WORKAROUND\n" : "")
        #endif
        .addSource(rs.get("generic.glsl"))
        .addSource(rs.get("MeshVisualizer.vert"));
    frag.addSource(flags & Flag::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
        .addSource(flags & Flag::NoGeometryShader ? "#define NO_GEOMETRY_SHADER\n" : "")
        .addSource(rs.get("MeshVisualizer.frag"));

    #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
    std::optional<Shader> geom;
    if(flags & Flag::Wireframe && !(flags & Flag::NoGeometryShader)) {
        geom = Implementation::createCompatibilityShader(rs, version, Shader::Type::Geometry);
        geom->addSource(rs.get("MeshVisualizer.geom"));
    }
    #endif

    #ifndef MAGNUM_TARGET_GLES2
    if(geom) CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({vert, *geom, frag}));
    else
    #endif
        CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({vert, frag}));

    attachShaders({vert, frag});
    #ifndef MAGNUM_TARGET_GLES2
    if(geom) attachShader(*geom);
    #endif

    #ifndef MAGNUM_TARGET_GLES
    if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::explicit_attrib_location>(version))
    #else
    if(!Context::current()->isVersionSupported(Version::GLES300))
    #endif
    {
        bindAttributeLocation(Position::Location, "position");

        #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
        #ifndef MAGNUM_TARGET_GLES
        if(!Context::current()->isVersionSupported(Version::GL310))
        #endif
        {
            bindAttributeLocation(VertexIndex::Location, "vertexIndex");
        }
        #endif
    }

    CORRADE_INTERNAL_ASSERT_OUTPUT(link());

    #ifndef MAGNUM_TARGET_GLES
    if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::explicit_uniform_location>(version))
    #endif
    {
        transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
        colorUniform = uniformLocation("color");
        if(flags & Flag::Wireframe) {
            wireframeColorUniform = uniformLocation("wireframeColor");
            wireframeWidthUniform = uniformLocation("wireframeWidth");
            smoothnessUniform = uniformLocation("smoothness");
            if(!(flags & Flag::NoGeometryShader))
                viewportSizeUniform = uniformLocation("viewportSize");
        }
    }

    /* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
    #ifdef MAGNUM_TARGET_GLES
    setColor(Color3(1.0f));
    if(flags & Flag::Wireframe) {
        setWireframeColor(Color3(0.0f));
        setWireframeWidth(1.0f);
        setSmoothness(2.0f);
    }
    #endif
}

}}
<commit_msg>Shaders: one more try.<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013, 2014, 2015
              Vladimír Vondruš <mosra@centrum.cz>

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
*/

#include "MeshVisualizer.h"

#include <Corrade/Utility/Resource.h>

#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
#include "Magnum/Shader.h"
#include "MagnumExternal/Optional/optional.hpp"

#include "Implementation/CreateCompatibilityShader.h"

namespace Magnum { namespace Shaders {

MeshVisualizer::MeshVisualizer(const Flags flags): flags(flags), transformationProjectionMatrixUniform(0), viewportSizeUniform(1), colorUniform(2), wireframeColorUniform(3), wireframeWidthUniform(4), smoothnessUniform(5) {
    #ifndef MAGNUM_TARGET_GLES2
    if(flags & Flag::Wireframe && !(flags & Flag::NoGeometryShader)) {
        #ifndef MAGNUM_TARGET_GLES
        MAGNUM_ASSERT_VERSION_SUPPORTED(Version::GL320);
        MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::geometry_shader4);
        #elif !defined(MAGNUM_TARGET_WEBGL)
        MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::geometry_shader);
        #endif
    }
    #else
    if(flags & Flag::Wireframe)
        MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::OES::standard_derivatives);
    #endif

    #ifdef MAGNUM_BUILD_STATIC
    /* Import resources on static build, if not already */
    if(!Utility::Resource::hasGroup("MagnumShaders"))
        importShaderResources();
    #endif
    Utility::Resource rs("MagnumShaders");

    #ifndef MAGNUM_TARGET_GLES
    const Version version = Context::current()->supportedVersion({Version::GL320, Version::GL310, Version::GL300, Version::GL210});
    CORRADE_INTERNAL_ASSERT(!flags || flags & Flag::NoGeometryShader || version >= Version::GL320);
    #elif !defined(MAGNUM_TARGET_WEBGL)
    const Version version = Context::current()->supportedVersion({Version::GLES310, Version::GLES300, Version::GLES200});
    CORRADE_INTERNAL_ASSERT(!flags || flags & Flag::NoGeometryShader || version >= Version::GLES310);
    #else
    const Version version = Context::current()->supportedVersion({Version::GLES300, Version::GLES200});
    #endif

    Shader vert = Implementation::createCompatibilityShader(rs, version, Shader::Type::Vertex);
    Shader frag = Implementation::createCompatibilityShader(rs, version, Shader::Type::Fragment);

    vert.addSource(flags & Flag::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
        .addSource(flags & Flag::NoGeometryShader ? "#define NO_GEOMETRY_SHADER\n" : "")
        #ifdef MAGNUM_TARGET_WEBGL
        .addSource("#define SUBSCRIPTING_WORKAROUND\n")
        #elif defined(MAGNUM_TARGET_GLES2)
        .addSource(Context::current()->detectedDriver() & Context::DetectedDriver::ProbablyAngle ?
            "#define SUBSCRIPTING_WORKAROUND\n" : "")
        #endif
        .addSource(rs.get("generic.glsl"))
        .addSource(rs.get("MeshVisualizer.vert"));
    frag.addSource(flags & Flag::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
        .addSource(flags & Flag::NoGeometryShader ? "#define NO_GEOMETRY_SHADER\n" : "")
        .addSource(rs.get("MeshVisualizer.frag"));

    #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
    std::optional<Shader> geom;
    if(flags & Flag::Wireframe && !(flags & Flag::NoGeometryShader)) {
        geom = Implementation::createCompatibilityShader(rs, version, Shader::Type::Geometry);
        geom->addSource(rs.get("MeshVisualizer.geom"));
    }
    #endif

    #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
    if(geom) CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({vert, *geom, frag}));
    else
    #endif
        CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({vert, frag}));

    attachShaders({vert, frag});
    #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
    if(geom) attachShader(*geom);
    #endif

    #ifndef MAGNUM_TARGET_GLES
    if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::explicit_attrib_location>(version))
    #else
    if(!Context::current()->isVersionSupported(Version::GLES300))
    #endif
    {
        bindAttributeLocation(Position::Location, "position");

        #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
        #ifndef MAGNUM_TARGET_GLES
        if(!Context::current()->isVersionSupported(Version::GL310))
        #endif
        {
            bindAttributeLocation(VertexIndex::Location, "vertexIndex");
        }
        #endif
    }

    CORRADE_INTERNAL_ASSERT_OUTPUT(link());

    #ifndef MAGNUM_TARGET_GLES
    if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::explicit_uniform_location>(version))
    #endif
    {
        transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
        colorUniform = uniformLocation("color");
        if(flags & Flag::Wireframe) {
            wireframeColorUniform = uniformLocation("wireframeColor");
            wireframeWidthUniform = uniformLocation("wireframeWidth");
            smoothnessUniform = uniformLocation("smoothness");
            if(!(flags & Flag::NoGeometryShader))
                viewportSizeUniform = uniformLocation("viewportSize");
        }
    }

    /* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
    #ifdef MAGNUM_TARGET_GLES
    setColor(Color3(1.0f));
    if(flags & Flag::Wireframe) {
        setWireframeColor(Color3(0.0f));
        setWireframeWidth(1.0f);
        setSmoothness(2.0f);
    }
    #endif
}

}}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   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., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <cmath>
# include <gp_Trsf.hxx>
# include <BRepOffsetAPI_MakeOffset.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <BRepBuilderAPI_Transform.hxx>
# include <BRepOffsetAPI_ThruSections.hxx>
# include <BRepPrimAPI_MakePrism.hxx>
# include <Precision.hxx>
# include <ShapeAnalysis.hxx>
# include <ShapeFix_Wire.hxx>
# include <TopoDS.hxx>
# include <TopExp_Explorer.hxx>
#endif

#include "FeatureExtrusion.h"
#include <Base/Tools.h>
#include <Base/Exception.h>

using namespace Part;

PROPERTY_SOURCE(Part::Extrusion, Part::Feature)

Extrusion::Extrusion()
{
    ADD_PROPERTY(Base,(0));
    ADD_PROPERTY(Dir,(Base::Vector3f(0.0f,0.0f,1.0f)));
    ADD_PROPERTY(Solid,(false));
    ADD_PROPERTY(TaperAngle,(0.0f));
}

short Extrusion::mustExecute() const
{
    if (Base.isTouched() ||
        Dir.isTouched() ||
        Solid.isTouched() ||
        TaperAngle.isTouched())
        return 1;
    return 0;
}

App::DocumentObjectExecReturn *Extrusion::execute(void)
{
    App::DocumentObject* link = Base.getValue();
    if (!link)
        return new App::DocumentObjectExecReturn("No object linked");
    if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return new App::DocumentObjectExecReturn("Linked object is not a Part object");
    Part::Feature *base = static_cast<Part::Feature*>(Base.getValue());

    Base::Vector3f v = Dir.getValue();
    gp_Vec vec(v.x,v.y,v.z);
    float taperAngle = TaperAngle.getValue();
    bool makeSolid = Solid.getValue();

    try {
        if (std::fabs(taperAngle) >= Precision::Confusion()) {
#if defined(__GNUC__) && defined (FC_OS_LINUX)
            Base::SignalException se;
#endif
            double distance = std::tan(Base::toRadians(taperAngle)) * vec.Magnitude();
            const TopoDS_Shape& shape = base->Shape.getValue();
            bool isWire = (shape.ShapeType() == TopAbs_WIRE);
            bool isFace = (shape.ShapeType() == TopAbs_FACE);
            if (!isWire && !isFace)
                return new App::DocumentObjectExecReturn("Only a wire or a face is supported");

            std::list<TopoDS_Wire> wire_list;
            BRepOffsetAPI_MakeOffset mkOffset;
            if (isWire) {
#if 1 //OCC_HEX_VERSION < 0x060502
                // The input wire may have erorrs in its topology
                // and thus may cause a crash in the Perfrom() method
                // See also:
                // http://www.opencascade.org/org/forum/thread_17640/
                // http://www.opencascade.org/org/forum/thread_12012/
                ShapeFix_Wire aFix;
                aFix.Load(TopoDS::Wire(shape));
                aFix.FixReorder();
                aFix.FixConnected();
                aFix.FixClosed();
                mkOffset.AddWire(aFix.Wire());
                wire_list.push_back(aFix.Wire());
#else
                mkOffset.AddWire(TopoDS::Wire(shape));
#endif
            }
            else if (isFace) {
                TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape));
                wire_list.push_back(outerWire);
                mkOffset.AddWire(outerWire);
            }

            mkOffset.Perform(distance);

            gp_Trsf mat;
            mat.SetTranslation(vec);
            BRepBuilderAPI_Transform mkTransform(mkOffset.Shape(),mat);
            wire_list.push_back(TopoDS::Wire(mkTransform.Shape()));

            BRepOffsetAPI_ThruSections mkGenerator(makeSolid ? Standard_True : Standard_False, Standard_False);
            for (std::list<TopoDS_Wire>::const_iterator it = wire_list.begin(); it != wire_list.end(); ++it) {
                const TopoDS_Wire &wire = *it;
                mkGenerator.AddWire(wire);
            }

            mkGenerator.Build();
            this->Shape.setValue(mkGenerator.Shape());
        }
        else {
            // Now, let's get the TopoDS_Shape
            TopoDS_Shape myShape = base->Shape.getValue();
            if (myShape.IsNull())
                Standard_Failure::Raise("Cannot extrude empty shape");
            if (makeSolid && myShape.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeFace mkFace(TopoDS::Wire(myShape));
                myShape = mkFace.Face();
            }
            BRepPrimAPI_MakePrism mkPrism(myShape, vec);
            TopoDS_Shape swept = mkPrism.Shape();
            if (swept.IsNull())
                return new App::DocumentObjectExecReturn("Resulting shape is null");
            this->Shape.setValue(swept);
        }
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
}
<commit_msg>0000910: Circles Extrude Only Surfaces<commit_after>/***************************************************************************
 *   Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   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., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
# include <cmath>
# include <gp_Trsf.hxx>
# include <BRepOffsetAPI_MakeOffset.hxx>
# include <BRepBuilderAPI_Copy.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <BRepBuilderAPI_MakeWire.hxx>
# include <BRepBuilderAPI_Transform.hxx>
# include <BRepOffsetAPI_ThruSections.hxx>
# include <BRepPrimAPI_MakePrism.hxx>
# include <Precision.hxx>
# include <ShapeAnalysis.hxx>
# include <ShapeFix_Wire.hxx>
# include <TopoDS.hxx>
# include <TopExp_Explorer.hxx>
#endif

#include "FeatureExtrusion.h"
#include <Base/Tools.h>
#include <Base/Exception.h>

using namespace Part;

PROPERTY_SOURCE(Part::Extrusion, Part::Feature)

Extrusion::Extrusion()
{
    ADD_PROPERTY(Base,(0));
    ADD_PROPERTY(Dir,(Base::Vector3f(0.0f,0.0f,1.0f)));
    ADD_PROPERTY(Solid,(false));
    ADD_PROPERTY(TaperAngle,(0.0f));
}

short Extrusion::mustExecute() const
{
    if (Base.isTouched() ||
        Dir.isTouched() ||
        Solid.isTouched() ||
        TaperAngle.isTouched())
        return 1;
    return 0;
}

App::DocumentObjectExecReturn *Extrusion::execute(void)
{
    App::DocumentObject* link = Base.getValue();
    if (!link)
        return new App::DocumentObjectExecReturn("No object linked");
    if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
        return new App::DocumentObjectExecReturn("Linked object is not a Part object");
    Part::Feature *base = static_cast<Part::Feature*>(Base.getValue());

    Base::Vector3f v = Dir.getValue();
    gp_Vec vec(v.x,v.y,v.z);
    float taperAngle = TaperAngle.getValue();
    bool makeSolid = Solid.getValue();

    try {
        if (std::fabs(taperAngle) >= Precision::Confusion()) {
#if defined(__GNUC__) && defined (FC_OS_LINUX)
            Base::SignalException se;
#endif
            double distance = std::tan(Base::toRadians(taperAngle)) * vec.Magnitude();
            TopoDS_Shape myShape = base->Shape.getValue();
            if (myShape.IsNull())
                Standard_Failure::Raise("Cannot extrude empty shape");
            // #0000910: Circles Extrude Only Surfaces, thus use BRepBuilderAPI_Copy
            myShape = BRepBuilderAPI_Copy(myShape).Shape();
            bool isWire = (myShape.ShapeType() == TopAbs_WIRE);
            bool isFace = (myShape.ShapeType() == TopAbs_FACE);
            if (!isWire && !isFace)
                return new App::DocumentObjectExecReturn("Only a wire or a face is supported");

            std::list<TopoDS_Wire> wire_list;
            BRepOffsetAPI_MakeOffset mkOffset;
            if (isWire) {
#if 1 //OCC_HEX_VERSION < 0x060502
                // The input wire may have erorrs in its topology
                // and thus may cause a crash in the Perfrom() method
                // See also:
                // http://www.opencascade.org/org/forum/thread_17640/
                // http://www.opencascade.org/org/forum/thread_12012/
                ShapeFix_Wire aFix;
                aFix.Load(TopoDS::Wire(myShape));
                aFix.FixReorder();
                aFix.FixConnected();
                aFix.FixClosed();
                mkOffset.AddWire(aFix.Wire());
                wire_list.push_back(aFix.Wire());
#else
                mkOffset.AddWire(TopoDS::Wire(shape));
#endif
            }
            else if (isFace) {
                TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(TopoDS::Face(myShape));
                wire_list.push_back(outerWire);
                mkOffset.AddWire(outerWire);
            }

            mkOffset.Perform(distance);

            gp_Trsf mat;
            mat.SetTranslation(vec);
            BRepBuilderAPI_Transform mkTransform(mkOffset.Shape(),mat);
            if (mkTransform.Shape().IsNull())
                Standard_Failure::Raise("Tapered shape is empty");
            TopAbs_ShapeEnum type = mkTransform.Shape().ShapeType();
            if (type == TopAbs_WIRE) {
                wire_list.push_back(TopoDS::Wire(mkTransform.Shape()));
            }
            else if (type == TopAbs_EDGE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(mkTransform.Shape()));
                wire_list.push_back(mkWire.Wire());
            }
            else {
                Standard_Failure::Raise("Tapered shape type is not supported");
            }

            BRepOffsetAPI_ThruSections mkGenerator(makeSolid ? Standard_True : Standard_False, Standard_False);
            for (std::list<TopoDS_Wire>::const_iterator it = wire_list.begin(); it != wire_list.end(); ++it) {
                const TopoDS_Wire &wire = *it;
                mkGenerator.AddWire(wire);
            }

            mkGenerator.Build();
            this->Shape.setValue(mkGenerator.Shape());
        }
        else {
            // Now, let's get the TopoDS_Shape
            TopoDS_Shape myShape = base->Shape.getValue();
            if (myShape.IsNull())
                Standard_Failure::Raise("Cannot extrude empty shape");
            // #0000910: Circles Extrude Only Surfaces, thus use BRepBuilderAPI_Copy
            myShape = BRepBuilderAPI_Copy(myShape).Shape();
            if (makeSolid && myShape.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeFace mkFace(TopoDS::Wire(myShape));
                myShape = mkFace.Face();
            }
            BRepPrimAPI_MakePrism mkPrism(myShape, vec);
            TopoDS_Shape swept = mkPrism.Shape();
            if (swept.IsNull())
                return new App::DocumentObjectExecReturn("Resulting shape is null");
            this->Shape.setValue(swept);
        }
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
}
<|endoftext|>


<commit_before>struct State {
    bool begun;
};

{{ GENERATED_CODE }}

void evaluate(Context ctx) {
    if (!isInputDirty<input_DUMP>(ctx))
        return;

    State* state = getState(ctx);
    if (!state->begun) {
        Serial.begin(115200);
        state->begun = true;
    }

    auto line = getValue<input_LINE>(ctx);
    if (line) {
        for (auto it = line->iterate(); it; ++it)
            Serial.write((char)*it);
        Serial.write('\r');
        Serial.write('\n');
        Serial.flush();
    }
}
<commit_msg>fix(stdlib): remove unnecessary check from console-log implementation, make it compile again<commit_after>struct State {
    bool begun;
};

{{ GENERATED_CODE }}

void evaluate(Context ctx) {
    if (!isInputDirty<input_DUMP>(ctx))
        return;

    State* state = getState(ctx);
    if (!state->begun) {
        Serial.begin(115200);
        state->begun = true;
    }

    auto line = getValue<input_LINE>(ctx);

    for (auto it = line->iterate(); it; ++it)
        Serial.write((char)*it);
    Serial.write('\r');
    Serial.write('\n');
    Serial.flush();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: XMLBackgroundImageExport.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: dvo $ $Date: 2002-08-29 17:46:18 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_STYLE_GRAPHICLOCATION_HPP_
#include <com/sun/star/style/GraphicLocation.hpp>
#endif

#include <xmlnmspe.hxx>

#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmltoken.hxx>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#ifndef _XMLBACKGROUNDIMAGEEXPORT_HXX
#include "XMLBackgroundImageExport.hxx"
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;
using namespace ::xmloff::token;

XMLBackgroundImageExport::XMLBackgroundImageExport( SvXMLExport& rExp ) :
    rExport( rExp )
{
}

XMLBackgroundImageExport::~XMLBackgroundImageExport()
{
}

void XMLBackgroundImageExport::exportXML( const Any& rURL,
            const Any *pPos,
            const Any *pFilter,
            const Any *pTransparency,
            sal_uInt16 nPrefix,
            const ::rtl::OUString& rLocalName )
{
    GraphicLocation ePos;
    if( !(pPos && ((*pPos) >>= ePos)) )
        ePos = GraphicLocation_AREA;

    OUString sURL;
    rURL >>= sURL;
    if( sURL.getLength() && GraphicLocation_NONE != ePos )
    {
        OUString sTempURL( GetExport().AddEmbeddedGraphicObject( sURL ) );
        if( sTempURL.getLength() )
        {
            GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sTempURL );
            GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE,
                                      XML_SIMPLE );
            GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE,
                                      XML_ONLOAD );
        }

        OUStringBuffer aOut;
        switch( ePos )
        {
        case GraphicLocation_LEFT_TOP:
        case GraphicLocation_MIDDLE_TOP:
        case GraphicLocation_RIGHT_TOP:
            aOut.append( GetXMLToken(XML_TOP) );
            break;
        case GraphicLocation_LEFT_MIDDLE:
        case GraphicLocation_MIDDLE_MIDDLE:
        case GraphicLocation_RIGHT_MIDDLE:
            aOut.append( GetXMLToken(XML_CENTER) );
            break;
        case GraphicLocation_LEFT_BOTTOM:
        case GraphicLocation_MIDDLE_BOTTOM:
        case GraphicLocation_RIGHT_BOTTOM:
            aOut.append( GetXMLToken(XML_BOTTOM) );
            break;
        }

        if( aOut.getLength() )
        {
            aOut.append( sal_Unicode( ' ' ) );

            switch( ePos )
            {
            case GraphicLocation_LEFT_TOP:
            case GraphicLocation_LEFT_BOTTOM:
            case GraphicLocation_LEFT_MIDDLE:
                aOut.append( GetXMLToken(XML_LEFT) );
                break;
            case GraphicLocation_MIDDLE_TOP:
            case GraphicLocation_MIDDLE_MIDDLE:
            case GraphicLocation_MIDDLE_BOTTOM:
                aOut.append( GetXMLToken(XML_CENTER) );
                break;
            case GraphicLocation_RIGHT_MIDDLE:
            case GraphicLocation_RIGHT_TOP:
            case GraphicLocation_RIGHT_BOTTOM:
                aOut.append( GetXMLToken(XML_RIGHT) );
                break;
            }
        }
        if( aOut.getLength() )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                  XML_POSITION, aOut.makeStringAndClear() );

        if( GraphicLocation_AREA == ePos )
        {
            aOut.append( GetXMLToken(XML_BACKGROUND_STRETCH) );
        }
        else if( GraphicLocation_NONE != ePos && GraphicLocation_TILED != ePos  )
        {
            aOut.append( GetXMLToken(XML_BACKGROUND_NO_REPEAT) );
        }
        if( aOut.getLength() )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_REPEAT,
                          aOut.makeStringAndClear() );

        if( pFilter )
        {
            OUString sFilter;
            (*pFilter) >>= sFilter;
            if( sFilter.getLength() )
                GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FILTER_NAME,
                                          sFilter );
        }

        if( pTransparency )
        {
            sal_Int8 nTransparency;
            if( (*pTransparency) >>= nTransparency )
            {
                OUStringBuffer aOut;
                SvXMLUnitConverter::convertPercent( aOut, nTransparency );
                GetExport().AddAttribute( XML_NAMESPACE_DRAW, XML_TRANSPARENCY,
                                          aOut.makeStringAndClear() );
            }
        }
    }

    {
        SvXMLElementExport aElem( GetExport(), nPrefix, rLocalName, sal_True, sal_True );
        if( sURL.getLength() && GraphicLocation_NONE != ePos )
        {
            // optional office:binary-data
            GetExport().AddEmbeddedGraphicObjectAsBase64( sURL );
        }
    }
}
<commit_msg>INTEGRATION: CWS oasis (1.7.250); FILE MERGED 2004/05/24 09:16:06 mib 1.7.250.1: - #i20153#: replaced transparency with opacity<commit_after>/*************************************************************************
 *
 *  $RCSfile: XMLBackgroundImageExport.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 08:22:15 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_STYLE_GRAPHICLOCATION_HPP_
#include <com/sun/star/style/GraphicLocation.hpp>
#endif

#include <xmlnmspe.hxx>

#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmltoken.hxx>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#ifndef _XMLBACKGROUNDIMAGEEXPORT_HXX
#include "XMLBackgroundImageExport.hxx"
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;
using namespace ::xmloff::token;

XMLBackgroundImageExport::XMLBackgroundImageExport( SvXMLExport& rExp ) :
    rExport( rExp )
{
}

XMLBackgroundImageExport::~XMLBackgroundImageExport()
{
}

void XMLBackgroundImageExport::exportXML( const Any& rURL,
            const Any *pPos,
            const Any *pFilter,
            const Any *pTransparency,
            sal_uInt16 nPrefix,
            const ::rtl::OUString& rLocalName )
{
    GraphicLocation ePos;
    if( !(pPos && ((*pPos) >>= ePos)) )
        ePos = GraphicLocation_AREA;

    OUString sURL;
    rURL >>= sURL;
    if( sURL.getLength() && GraphicLocation_NONE != ePos )
    {
        OUString sTempURL( GetExport().AddEmbeddedGraphicObject( sURL ) );
        if( sTempURL.getLength() )
        {
            GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sTempURL );
            GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE,
                                      XML_SIMPLE );
            GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE,
                                      XML_ONLOAD );
        }

        OUStringBuffer aOut;
        switch( ePos )
        {
        case GraphicLocation_LEFT_TOP:
        case GraphicLocation_MIDDLE_TOP:
        case GraphicLocation_RIGHT_TOP:
            aOut.append( GetXMLToken(XML_TOP) );
            break;
        case GraphicLocation_LEFT_MIDDLE:
        case GraphicLocation_MIDDLE_MIDDLE:
        case GraphicLocation_RIGHT_MIDDLE:
            aOut.append( GetXMLToken(XML_CENTER) );
            break;
        case GraphicLocation_LEFT_BOTTOM:
        case GraphicLocation_MIDDLE_BOTTOM:
        case GraphicLocation_RIGHT_BOTTOM:
            aOut.append( GetXMLToken(XML_BOTTOM) );
            break;
        }

        if( aOut.getLength() )
        {
            aOut.append( sal_Unicode( ' ' ) );

            switch( ePos )
            {
            case GraphicLocation_LEFT_TOP:
            case GraphicLocation_LEFT_BOTTOM:
            case GraphicLocation_LEFT_MIDDLE:
                aOut.append( GetXMLToken(XML_LEFT) );
                break;
            case GraphicLocation_MIDDLE_TOP:
            case GraphicLocation_MIDDLE_MIDDLE:
            case GraphicLocation_MIDDLE_BOTTOM:
                aOut.append( GetXMLToken(XML_CENTER) );
                break;
            case GraphicLocation_RIGHT_MIDDLE:
            case GraphicLocation_RIGHT_TOP:
            case GraphicLocation_RIGHT_BOTTOM:
                aOut.append( GetXMLToken(XML_RIGHT) );
                break;
            }
        }
        if( aOut.getLength() )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                  XML_POSITION, aOut.makeStringAndClear() );

        if( GraphicLocation_AREA == ePos )
        {
            aOut.append( GetXMLToken(XML_BACKGROUND_STRETCH) );
        }
        else if( GraphicLocation_NONE != ePos && GraphicLocation_TILED != ePos  )
        {
            aOut.append( GetXMLToken(XML_BACKGROUND_NO_REPEAT) );
        }
        if( aOut.getLength() )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_REPEAT,
                          aOut.makeStringAndClear() );

        if( pFilter )
        {
            OUString sFilter;
            (*pFilter) >>= sFilter;
            if( sFilter.getLength() )
                GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FILTER_NAME,
                                          sFilter );
        }

        if( pTransparency )
        {
            sal_Int8 nTransparency;
            if( (*pTransparency) >>= nTransparency )
            {
                OUStringBuffer aOut;
                SvXMLUnitConverter::convertPercent( aOut, 100-nTransparency );
                GetExport().AddAttribute( XML_NAMESPACE_DRAW, XML_OPACITY,
                                          aOut.makeStringAndClear() );
            }
        }
    }

    {
        SvXMLElementExport aElem( GetExport(), nPrefix, rLocalName, sal_True, sal_True );
        if( sURL.getLength() && GraphicLocation_NONE != ePos )
        {
            // optional office:binary-data
            GetExport().AddEmbeddedGraphicObjectAsBase64( sURL );
        }
    }
}
<|endoftext|>


<commit_before>#include <EigenPerformance.h>
#include <iostream>
#include <chrono>

using Eigen::Matrix3d;
using Eigen::Matrix;

typedef std::chrono::high_resolution_clock::time_point time_point;
typedef std::chrono::high_resolution_clock::duration duration;

int main(int /*argc*/, char** /*argv*/){
    unsigned long long max_counter = 1e6;

    time_point begin;
    time_point end;

    duration sum = duration::zero();
    unsigned long long counter = 0;

    while (counter < max_counter){
        Matrix3d test;
        Matrix3d inverse;

        test << Matrix3d::Random();

        if(test.determinant()){
            begin = std::chrono::high_resolution_clock::now();
            inverse = test.inverse();
            end = std::chrono::high_resolution_clock::now();

            // we assume, that difference doesn't exeed the size of int
            sum += end - begin;

            counter++;

            if(counter%(max_counter/10) == 0){
               std::cout << "." << std::flush;
            }
        }
    }

    std::cout << std::endl;
    std::cout << "average time 3x3: " << sum.count()/counter << " ns" << std::endl;

    sum = duration::zero();
    counter = 0;

    while (counter < max_counter ){
        Matrix<double,6,6> test;
        Matrix<double,6,6> inverse;

        test << Matrix<double,6,6>::Random();

        if(test.determinant()){
            begin = std::chrono::high_resolution_clock::now();
            inverse = test.inverse();
            end = std::chrono::high_resolution_clock::now();

            // we assume, that difference doesn't exeed the size of int
            sum += end - begin;

            counter++;

            if(counter%(max_counter/10) == 0){
               std::cout << "." << std::flush;
            }
        }
    }

    std::cout << std::endl;
    std::cout << "average time 6x6: " << sum.count()/max_counter << " ns" << std::endl;

    return 0;
}
<commit_msg>fix performance test and add sse test<commit_after>#include <EigenPerformance.h>
#include <iostream>
#include <chrono>

using Eigen::Matrix3f;
using Eigen::Matrix;

typedef std::chrono::high_resolution_clock::time_point time_point;
typedef std::chrono::high_resolution_clock::duration duration;

unsigned long long max_counter = 1e6;

// the compiler is not allowed to optimize out global variables
Matrix3f inverse3x3;
Matrix<float,6,6> inverse6x6;
Matrix<float,4,100> y;

void test_invert(){
    time_point begin;
    time_point end;

    duration sum = duration::zero();
    unsigned long long counter = 0;

    while (counter < max_counter){
        Matrix3f test;
        test << Matrix3f::Random();

        if(test.determinant()){
            begin = std::chrono::high_resolution_clock::now();
            inverse3x3 = test.inverse();
            end = std::chrono::high_resolution_clock::now();

            // we assume, that difference doesn't exeed the size of int
            sum += end - begin;

            counter++;

            if(counter%(max_counter/10) == 0){
               std::cout << "." << std::flush;
            }
        }
    }

    std::cout << std::endl;
    std::cout << "average time 3x3: " << sum.count()/counter << " ns" << std::endl;

    sum = duration::zero();
    counter = 0;

    while (counter < max_counter ){
        Matrix<float,6,6> test;

        test << Matrix<float,6,6>::Random();

        if(test.determinant()){
            begin = std::chrono::high_resolution_clock::now();
            inverse6x6 = test.inverse();
            end = std::chrono::high_resolution_clock::now();

            // we assume, that difference doesn't exeed the size of int
            sum += end - begin;

            counter++;

            if(counter%(max_counter/10) == 0){
               std::cout << "." << std::flush;
            }
        }
    }

    std::cout << std::endl;
    std::cout << "average time 6x6: " << sum.count()/max_counter << " ns" << std::endl;
}

void test_sse(){
    time_point begin;
    time_point end;

    duration sum = duration::zero();
    unsigned long long counter = 0;

    Matrix<float, 4,4> A;
    Matrix<float, 4,100> x;

    while (counter < max_counter ){
        A << Matrix<float,4,4>::Random();
        x << Matrix<float,4,100>::Random();

        begin = std::chrono::high_resolution_clock::now();
        y = A*x;
        end = std::chrono::high_resolution_clock::now();

        // we assume, that difference doesn't exeed the size of int
        sum += end - begin;

        counter++;

        if(counter%(max_counter/10) == 0){
            std::cout << "." << std::flush;
        }
    }

    std::cout << std::endl;
    std::cout << "average time 4x4*4x100 float: " << sum.count()/max_counter << " ns" << std::endl;
}

int main(int /*argc*/, char** /*argv*/){
    test_invert();
    test_sse();

    return 0;
}
<|endoftext|>


<commit_before>#include "PipeProcess.h"

#ifdef WIN32
#include <windows.h>
#include <process.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
typedef int ssize_t;
typedef HANDLE fd_t;
typedef SOCKET socket_t;
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
typedef int fd_t;
typedef int socket_t;
#endif

#include <cstring>
#include <iostream>
#include <sstream>

#define BUFSIZE (64*1024-1)
#define STEPSIZE (1024)
//#define STEPSIZE BUFSIZE

namespace sofa
{

namespace helper
{

namespace system
{

PipeProcess::PipeProcess()
{
}

PipeProcess::~PipeProcess()
{
}
/**   File as Stdin for windows does not work (yet)
  *   So the filename must be given into the args vector
  *   and argument filenameStdin is currently ignored
  */

bool PipeProcess::executeProcess(const std::string &command,  const std::vector<std::string> &args, const std::string &filenameStdin, std::string & outString, std::string & errorString)
{
    std::string fileIN = filenameStdin;

    //Remove this line below when Windows will be able to read file as stdin
    fileIN = "";

    fd_t fds[2][2];

    //char eol = '\n';
    char** cargs;
    std::string newCommand(command);

    cargs = new char* [args.size()+2];
    cargs[0] = (char*)command.c_str();
    for (unsigned int i=1 ; i< args.size() + 1 ; i++)
        cargs[i] = (char*)args[i-1].c_str();
    cargs[args.size() + 1] = NULL;

    fd_t fdin;
    fd_t fdout;
    fd_t fderr;

#ifdef WIN32
    fdin = GetStdHandle(STD_INPUT_HANDLE);

    fdout = GetStdHandle(STD_OUTPUT_HANDLE);
    fderr = GetStdHandle(STD_ERROR_HANDLE);

    for (unsigned int i=0 ; i< args.size() ; i++)
        newCommand += cargs[i];

#else
    fdin = 0;
    fdout = 1;
    fderr = 2;
#endif

    outString = "";
    errorString = "";
    std::stringstream outStream;
    std::stringstream errorStream;

#ifdef WIN32
    SECURITY_ATTRIBUTES saAttr;
    // Set the bInheritHandle flag so pipe handles are inherited.
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    if (!CreatePipe(&fds[0][0],&fds[0][1],&saAttr,0) || !CreatePipe(&fds[1][0],&fds[1][1],&saAttr,0))
#else
    if (pipe(fds[0]) || pipe(fds[1]))
#endif
    {
        std::cerr << "pipe failed."<<std::endl;
        return false;
    }
#ifdef WIN32
    HANDLE hFile = 0;
    if (fileIN != "")
        hFile = CreateFileA( (fileIN.c_str()),
                GENERIC_READ,
                FILE_SHARE_READ,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        std::cerr<<"failed to open file for stdin\n";
    }

    // Ensure that the read handle to the child process's pipe for STDOUT is not inherited.
    SetHandleInformation( fds[0][0], HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation( fds[1][0], HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation( fdin, HANDLE_FLAG_INHERIT, 1);
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFOA siStartInfo;
    ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFOA) );
    siStartInfo.cb = sizeof(STARTUPINFOA);
    if (fileIN != "")
        siStartInfo.hStdInput = hFile;
    else siStartInfo.hStdInput = fdin;

    siStartInfo.hStdOutput = fds[0][1];
    siStartInfo.hStdError = fds[1][1];
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
    if (!CreateProcessA(NULL,
            (char*)newCommand.c_str(),       // command line
            NULL,          // process security attributes
            NULL,          // primary thread security attributes
            TRUE,          // handles are inherited
            0,             // creation flags
            NULL,          // use parent's environment
            NULL,          // use parent's current directory
            &siStartInfo,  // STARTUPINFO pointer
            &piProcInfo))  // receives PROCESS_INFORMATION
    {
        std::cerr << "CreateProcess failed : "<<GetLastError()<<std::endl;
        return 1;
    }

    {
        // parent process
        //char inbuf[BUFSIZE];
        char buf[2][BUFSIZE];
        int nfill[2];
        CloseHandle(fds[0][1]);
        CloseHandle(fds[1][1]);
        unsigned long exit = 0;
        for (int i=0; i<2; i++)
            nfill[i] = 0;
        for(int i=0;; i++)
        {
            GetExitCodeProcess(piProcInfo.hProcess,&exit);      //while the process is running
            if (exit != STILL_ACTIVE)
                break;

            bool busy = false;
            for (int i=0; i<2; i++)
            {
                DWORD n = BUFSIZE-nfill[i];
                if (n > STEPSIZE) n = STEPSIZE;
                DWORD bread = 0;
                DWORD avail = 0;
                PeekNamedPipe(fds[i][0],buf[i]+nfill[i],n,&bread,&avail,NULL);

                if (bread>0)
                {
                    busy = true;
                    ReadFile(fds[i][0], buf[i]+nfill[i], n, &n, NULL);
                    nfill[i] += n;
                    {
                        // write line
                        if (i==0)
                            outStream << std::string(buf[i],nfill[i]);
                        else
                            errorStream << std::string(buf[i],nfill[i]);

                        //std::cout << std::string(buf[i],nfill[i]) << std::endl;
                        nfill[i] = 0;
                    }
                }
            }
            if (!busy)
                Sleep(0);
        }
        CloseHandle(fds[0][0]);
        CloseHandle(fds[1][0]);
        int status=exit;
        CloseHandle(piProcInfo.hProcess);
        CloseHandle(piProcInfo.hThread);
        //waitpid(pid,&status,0);
#else
    int filefd = 0;
    if (fileIN != "")
        filefd = open(fileIN.c_str(),O_RDONLY);

    pid_t   pid;
    pid = fork();
    if (pid < 0)
    {
        std::cerr << "fork failed."<<std::endl;
        return false;
    }
    else if (pid == 0)
    {
        // child process
        close(fds[0][0]);
        close(fds[1][0]);
        // Remove standard input
        if (fileIN != "")
            dup2(filefd, 0);
        else dup2(open("/dev/null",O_RDONLY),0);

        dup2(fds[0][1],1);
        dup2(fds[1][1],2);

        int retexec = execvp(command.c_str(), cargs);
        std::cerr << "PipeProcess : ERROR: execlp( "<< command.c_str() << " " ;
        for (unsigned int i=0; i<args.size() + 1 ; i++)
            std::cerr << cargs[i] << " ";
        std::cerr << ") returned "<<retexec<<std::endl;
        return false;
    }
    else
    {
        // parent process
//		char inbuf[BUFSIZE];
        char buf[2][BUFSIZE];
        int nfill[2];
        close(fds[0][1]);
        close(fds[1][1]);
        fd_set rfds;
        int nfd = fdin+1;
        FD_ZERO(&rfds);
        FD_SET(fdin, &rfds);
        int nopen = 0;
        for (int i=0; i<2; i++)
        {
            //fcntl(fds[i][0],F_SETFL, fcntl(fds[i][0],F_GETFL)|O_NONBLOCK );
            FD_SET(fds[i][0], &rfds);
            if (fds[i][0] >= nfd) nfd = fds[i][0]+1;
            // add prefixes
            //buf[i][0] = '0'+i;
            //nfill[i] = 1;
            nfill[i] = 0;
            ++nopen;
        }
        fd_set ready;
        ready = rfds;
        while (nopen> 0 && select(nfd, &ready, NULL, NULL, NULL)> 0)
        {
            //read stdin
//			if (FD_ISSET(fdin, &ready))
//			{
//				int n = read(fdin, inbuf, BUFSIZE);
//				if (n>0)
//				{
//					writeall(2,inbuf,n);
//				}
//				else if (n==0)
//				{
//					FD_CLR(fdin, &rfds);
//				}
//			}
            for (int i=0; i<2; i++)
            {
                if (FD_ISSET(fds[i][0], &ready))
                {
                    int n = BUFSIZE-nfill[i];
                    if (n> STEPSIZE) n = STEPSIZE;
                    n = read(fds[i][0], buf[i]+nfill[i], n);

                    if (n == 0)
                    {
                        if (nfill[i]> 1)
                        {
                            buf[i][nfill[i]] = '\n';
                            if (i==0)
                                outStream << std::string(buf[i],nfill[i]+1);
                            else
                                errorStream << std::string(buf[i],nfill[i]+1);
                        }
                        --nopen;
                        FD_CLR(fds[i][0], &rfds);
                    }
                    else
                    {
                        nfill[i] += n;

                        // write line
                        if (i==0)
                            outStream << std::string(buf[i],nfill[i]);
                        else
                            errorStream << std::string(buf[i],nfill[i]);

                        //std::cout << std::string(buf[i],nfill[i]) << std::endl;
                        nfill[i] = 0;
                    }

                }
            }
            ready = rfds;
        }
        close(fds[0][0]);
        close(fds[1][0]);
        int status=0;
        waitpid(pid,&status,0);

        if (fdout != 1)
            close(fdout);
        close(filefd);
#endif

        outString = outStream.str();
        errorString = errorStream.str();
        return (status == 0);
    }
}

}
}
}

<commit_msg>r2392/sofa-dev : Fix:PipeProcess : arguments were not correctly appended for Win32's function CreateProcess<commit_after>#include "PipeProcess.h"

#ifdef WIN32
#include <windows.h>
#include <process.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
typedef int ssize_t;
typedef HANDLE fd_t;
typedef SOCKET socket_t;
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
typedef int fd_t;
typedef int socket_t;
#endif

#include <cstring>
#include <iostream>
#include <sstream>

#define BUFSIZE (64*1024-1)
#define STEPSIZE (1024)
//#define STEPSIZE BUFSIZE

namespace sofa
{

namespace helper
{

namespace system
{

PipeProcess::PipeProcess()
{
}

PipeProcess::~PipeProcess()
{
}
/**   File as Stdin for windows does not work (yet)
  *   So the filename must be given into the args vector
  *   and argument filenameStdin is currently ignored
  */

bool PipeProcess::executeProcess(const std::string &command,  const std::vector<std::string> &args, const std::string &filenameStdin, std::string & outString, std::string & errorString)
{
    std::string fileIN = filenameStdin;

    //Remove this line below when Windows will be able to read file as stdin
    fileIN = "";

    fd_t fds[2][2];

    //char eol = '\n';
    char** cargs;
    std::string newCommand(command);

    cargs = new char* [args.size()+2];
    cargs[0] = (char*)command.c_str();
    for (unsigned int i=1 ; i< args.size() + 1 ; i++)
        cargs[i] = (char*)args[i-1].c_str();
    cargs[args.size() + 1] = NULL;

    fd_t fdin;
    fd_t fdout;
    fd_t fderr;

#ifdef WIN32
    fdin = GetStdHandle(STD_INPUT_HANDLE);

    fdout = GetStdHandle(STD_OUTPUT_HANDLE);
    fderr = GetStdHandle(STD_ERROR_HANDLE);

    for (unsigned int i=0 ; i< args.size() ; i++)
        newCommand += " " + args[i];

#else
    fdin = 0;
    fdout = 1;
    fderr = 2;
#endif

    outString = "";
    errorString = "";
    std::stringstream outStream;
    std::stringstream errorStream;

#ifdef WIN32
    SECURITY_ATTRIBUTES saAttr;
    // Set the bInheritHandle flag so pipe handles are inherited.
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    if (!CreatePipe(&fds[0][0],&fds[0][1],&saAttr,0) || !CreatePipe(&fds[1][0],&fds[1][1],&saAttr,0))
#else
    if (pipe(fds[0]) || pipe(fds[1]))
#endif
    {
        std::cerr << "pipe failed."<<std::endl;
        return false;
    }
#ifdef WIN32
    HANDLE hFile = 0;
    if (fileIN != "")
        hFile = CreateFileA( (fileIN.c_str()),
                GENERIC_READ,
                FILE_SHARE_READ,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        std::cerr<<"failed to open file for stdin\n";
    }

    // Ensure that the read handle to the child process's pipe for STDOUT is not inherited.
    SetHandleInformation( fds[0][0], HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation( fds[1][0], HANDLE_FLAG_INHERIT, 0);
    SetHandleInformation( fdin, HANDLE_FLAG_INHERIT, 1);
    PROCESS_INFORMATION piProcInfo;
    STARTUPINFOA siStartInfo;
    ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFOA) );
    siStartInfo.cb = sizeof(STARTUPINFOA);
    if (fileIN != "")
        siStartInfo.hStdInput = hFile;
    else siStartInfo.hStdInput = fdin;

    siStartInfo.hStdOutput = fds[0][1];
    siStartInfo.hStdError = fds[1][1];
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
    if (!CreateProcessA(NULL,
            (char*)newCommand.c_str(),       // command line
            NULL,          // process security attributes
            NULL,          // primary thread security attributes
            TRUE,          // handles are inherited
            0,             // creation flags
            NULL,          // use parent's environment
            NULL,          // use parent's current directory
            &siStartInfo,  // STARTUPINFO pointer
            &piProcInfo))  // receives PROCESS_INFORMATION
    {
        std::cerr << "CreateProcess failed : "<<GetLastError()<<std::endl;
        return 1;
    }

    {
        // parent process
        //char inbuf[BUFSIZE];
        char buf[2][BUFSIZE];
        int nfill[2];
        CloseHandle(fds[0][1]);
        CloseHandle(fds[1][1]);
        unsigned long exit = 0;
        for (int i=0; i<2; i++)
            nfill[i] = 0;
        for(int i=0;; i++)
        {
            GetExitCodeProcess(piProcInfo.hProcess,&exit);      //while the process is running
            if (exit != STILL_ACTIVE)
                break;

            bool busy = false;
            for (int i=0; i<2; i++)
            {
                DWORD n = BUFSIZE-nfill[i];
                if (n > STEPSIZE) n = STEPSIZE;
                DWORD bread = 0;
                DWORD avail = 0;
                PeekNamedPipe(fds[i][0],buf[i]+nfill[i],n,&bread,&avail,NULL);

                if (bread>0)
                {
                    busy = true;
                    ReadFile(fds[i][0], buf[i]+nfill[i], n, &n, NULL);
                    nfill[i] += n;
                    {
                        // write line
                        if (i==0)
                            outStream << std::string(buf[i],nfill[i]);
                        else
                            errorStream << std::string(buf[i],nfill[i]);

                        //std::cout << std::string(buf[i],nfill[i]) << std::endl;
                        nfill[i] = 0;
                    }
                }
            }
            if (!busy)
                Sleep(0);
        }
        CloseHandle(fds[0][0]);
        CloseHandle(fds[1][0]);
        int status=exit;
        CloseHandle(piProcInfo.hProcess);
        CloseHandle(piProcInfo.hThread);
        //waitpid(pid,&status,0);
#else
    int filefd = 0;
    if (fileIN != "")
        filefd = open(fileIN.c_str(),O_RDONLY);

    pid_t   pid;
    pid = fork();
    if (pid < 0)
    {
        std::cerr << "fork failed."<<std::endl;
        return false;
    }
    else if (pid == 0)
    {
        // child process
        close(fds[0][0]);
        close(fds[1][0]);
        // Remove standard input
        if (fileIN != "")
            dup2(filefd, 0);
        else dup2(open("/dev/null",O_RDONLY),0);

        dup2(fds[0][1],1);
        dup2(fds[1][1],2);

        int retexec = execvp(command.c_str(), cargs);
        std::cerr << "PipeProcess : ERROR: execlp( "<< command.c_str() << " " ;
        for (unsigned int i=0; i<args.size() + 1 ; i++)
            std::cerr << cargs[i] << " ";
        std::cerr << ") returned "<<retexec<<std::endl;
        return false;
    }
    else
    {
        // parent process
//		char inbuf[BUFSIZE];
        char buf[2][BUFSIZE];
        int nfill[2];
        close(fds[0][1]);
        close(fds[1][1]);
        fd_set rfds;
        int nfd = fdin+1;
        FD_ZERO(&rfds);
        FD_SET(fdin, &rfds);
        int nopen = 0;
        for (int i=0; i<2; i++)
        {
            //fcntl(fds[i][0],F_SETFL, fcntl(fds[i][0],F_GETFL)|O_NONBLOCK );
            FD_SET(fds[i][0], &rfds);
            if (fds[i][0] >= nfd) nfd = fds[i][0]+1;
            // add prefixes
            //buf[i][0] = '0'+i;
            //nfill[i] = 1;
            nfill[i] = 0;
            ++nopen;
        }
        fd_set ready;
        ready = rfds;
        while (nopen> 0 && select(nfd, &ready, NULL, NULL, NULL)> 0)
        {
            //read stdin
//			if (FD_ISSET(fdin, &ready))
//			{
//				int n = read(fdin, inbuf, BUFSIZE);
//				if (n>0)
//				{
//					writeall(2,inbuf,n);
//				}
//				else if (n==0)
//				{
//					FD_CLR(fdin, &rfds);
//				}
//			}
            for (int i=0; i<2; i++)
            {
                if (FD_ISSET(fds[i][0], &ready))
                {
                    int n = BUFSIZE-nfill[i];
                    if (n> STEPSIZE) n = STEPSIZE;
                    n = read(fds[i][0], buf[i]+nfill[i], n);

                    if (n == 0)
                    {
                        if (nfill[i]> 1)
                        {
                            buf[i][nfill[i]] = '\n';
                            if (i==0)
                                outStream << std::string(buf[i],nfill[i]+1);
                            else
                                errorStream << std::string(buf[i],nfill[i]+1);
                        }
                        --nopen;
                        FD_CLR(fds[i][0], &rfds);
                    }
                    else
                    {
                        nfill[i] += n;

                        // write line
                        if (i==0)
                            outStream << std::string(buf[i],nfill[i]);
                        else
                            errorStream << std::string(buf[i],nfill[i]);

                        //std::cout << std::string(buf[i],nfill[i]) << std::endl;
                        nfill[i] = 0;
                    }

                }
            }
            ready = rfds;
        }
        close(fds[0][0]);
        close(fds[1][0]);
        int status=0;
        waitpid(pid,&status,0);

        if (fdout != 1)
            close(fdout);
        close(filefd);
#endif

        outString = outStream.str();
        errorString = errorStream.str();
        return (status == 0);
    }
}

}
}
}

<|endoftext|>