<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <cerrno>
#include <exception>

#include <thrift/transport/TFDTransport.h>
#include <thrift/transport/PlatformSocket.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef _WIN32
#include <io.h>
#endif

using std::string;

namespace apache {
namespace thrift {
namespace transport {

void TFDTransport::close() {
  if (!isOpen()) {
    return;
  }

  int rv = ::THRIFT_CLOSE(fd_);
  int errno_copy = THRIFT_ERRNO;
  fd_ = -1;
  // Have to check uncaught_exception because this is called in the destructor.
  if (rv < 0 && !std::uncaught_exception()) {
    throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::close()", errno_copy);
  }
}

uint32_t TFDTransport::read(uint8_t* buf, uint32_t len) {
  checkReadBytesAvailable(len);
  unsigned int maxRetries = 5; // same as the TSocket default
  unsigned int retries = 0;
  while (true) {
    THRIFT_SSIZET rv = ::THRIFT_READ(fd_, buf, len);
    if (rv < 0) {
      if (THRIFT_ERRNO == THRIFT_EINTR && retries < maxRetries) {
        // If interrupted, try again
        ++retries;
        continue;
      }
      int errno_copy = THRIFT_ERRNO;
      throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::read()", errno_copy);
    }
    // this should be fine, since we already checked for negative values,
    // and ::read should only return a 32-bit value since len is 32-bit.
    return static_cast<uint32_t>(rv);
  }
}

void TFDTransport::write(const uint8_t* buf, uint32_t len) {
  while (len > 0) {
    THRIFT_SSIZET rv = ::THRIFT_WRITE(fd_, buf, len);

    if (rv < 0) {
      int errno_copy = THRIFT_ERRNO;
      throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::write()", errno_copy);
    } else if (rv == 0) {
      throw TTransportException(TTransportException::END_OF_FILE, "TFDTransport::write()");
    }

    buf += rv;
    // this should be fine, as we've already checked for negative values, and
    //::write shouldn't return more than a uint32_t since len is a uint32_t
    len -= static_cast<uint32_t>(rv);
  }
}
}
}
} // apache::thrift::transport
<commit_msg>uncaught_exception -> uncaught_exceptions Client: cpp Author: Rune Olesen<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <cerrno>
#include <exception>

#include <thrift/transport/TFDTransport.h>
#include <thrift/transport/PlatformSocket.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef _WIN32
#include <io.h>
#endif

using std::string;

namespace apache {
namespace thrift {
namespace transport {

void TFDTransport::close() {
  if (!isOpen()) {
    return;
  }

  int rv = ::THRIFT_CLOSE(fd_);
  int errno_copy = THRIFT_ERRNO;
  fd_ = -1;
  // Have to check uncaught_exception because this is called in the destructor.
#ifdef __cpp_lib_uncaught_exceptions
  if (rv < 0 && !std::uncaught_exceptions()) {
#else
  if (rv < 0 && !std::uncaught_exception()) {
#endif
    throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::close()", errno_copy);
  }
}

uint32_t TFDTransport::read(uint8_t* buf, uint32_t len) {
  checkReadBytesAvailable(len);
  unsigned int maxRetries = 5; // same as the TSocket default
  unsigned int retries = 0;
  while (true) {
    THRIFT_SSIZET rv = ::THRIFT_READ(fd_, buf, len);
    if (rv < 0) {
      if (THRIFT_ERRNO == THRIFT_EINTR && retries < maxRetries) {
        // If interrupted, try again
        ++retries;
        continue;
      }
      int errno_copy = THRIFT_ERRNO;
      throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::read()", errno_copy);
    }
    // this should be fine, since we already checked for negative values,
    // and ::read should only return a 32-bit value since len is 32-bit.
    return static_cast<uint32_t>(rv);
  }
}

void TFDTransport::write(const uint8_t* buf, uint32_t len) {
  while (len > 0) {
    THRIFT_SSIZET rv = ::THRIFT_WRITE(fd_, buf, len);

    if (rv < 0) {
      int errno_copy = THRIFT_ERRNO;
      throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::write()", errno_copy);
    } else if (rv == 0) {
      throw TTransportException(TTransportException::END_OF_FILE, "TFDTransport::write()");
    }

    buf += rv;
    // this should be fine, as we've already checked for negative values, and
    //::write shouldn't return more than a uint32_t since len is a uint32_t
    len -= static_cast<uint32_t>(rv);
  }
}
}
}
} // apache::thrift::transport
<|endoftext|>


<commit_before>#include "openglwidget.h"

OpenGLWidget::OpenGLWidget(QWidget* parent)
    : QOpenGLWidget(parent)
{
    angle=0.0;

    factory = std::make_shared<ModelFactory>(this);

    player = new QMediaPlayer;

    player->setMedia(QUrl::fromLocalFile("C:\\Repos\\asteroids\\src\\sounds\\fire.wav"));
    player->setVolume(100);
}
void OpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();

    qDebug("OpenGL version : %s", glGetString(GL_VERSION));
    qDebug("GLSL %s", glGetString(GL_SHADING_LANGUAGE_VERSION));

    glEnable(GL_DEPTH_TEST);

    connect(&timer, SIGNAL(timeout()), this, SLOT(animate()));
    timer.start(0);

    time.start();
}

void OpenGLWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void OpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (!ship)
        return;

    //Nave do jogador
    ship->drawModel(angle, 0.1);

    if (!gunshot)
        return;

    //Tiros do jogador
    gunshot->drawModel(angle, 0.02);

    //Tiros do jogador
    //gunshot->drawModel(angle, X, Y, Z);

    //asteroid->drawModel(angle, x, y, z);
    //guardar info de radius e center(x,y,z)
}

void OpenGLWidget::loadSampleModel()
{
    //ship = std::make_shared<Ship>(this, shipOffModel);
    //ship->Create();

    ship = factory->GetShipInstance();

    //gunshot = std::make_shared<Gunshot>(this, shipOffModel);
    //gunshot->Create();

    update();
}

void OpenGLWidget::keyPressEvent(QKeyEvent* event)
{
    switch (event->key())
    {
    case Qt::Key_Left:
        angle+=5.0;
        qDebug("Angle: %f", angle);
        break;
    case Qt::Key_Right:
        angle-=5.0;
        qDebug("Angle: %f", angle);
        break;
    case Qt::Key_Up:
        float xPos, yPos;
        xPos= ship->atualPoint.x() + 0.05*cos((angle + 90)* (3.1416/180));
        yPos= ship->atualPoint.y() + 0.05*sin((angle + 90)* (3.1416/180));
        ship->atualPoint = QVector3D(xPos, yPos, 0);
        break;
    case Qt::Key_Space:
        float xShipPos, yShipPos;
        xShipPos= ship->atualPoint.x() + 0.05*cos((angle + 90)* (3.1416/180));
        yShipPos= ship->atualPoint.y() + 0.05*sin((angle + 90)* (3.1416/180));

        gunshot = factory->GetGunshotInstance();
        gunshot->atualPoint = QVector3D(xShipPos, yShipPos, 0);

        player->play();
        break;
    case Qt::Key_Escape:
        qApp->quit();
        break;
    default:
        break;
    }
    update();
}

void OpenGLWidget::animate()
{
    float elapsedTime = time.restart() / 1000.0f;

    if (!gunshot)
        return;

    float xPos, yPos;
    xPos= gunshot->atualPoint.x() + elapsedTime * 2 * cos((angle + 90)* (3.1416/180));
    yPos= gunshot->atualPoint.y() + elapsedTime * 2 * sin((angle + 90)* (3.1416/180));
    gunshot->atualPoint =  QVector3D(xPos, yPos, 0);

    //Limits:
    if(qAbs(gunshot->atualPoint.x())>1.2 || qAbs(gunshot->atualPoint.y()) >1.2){
        gunshot.reset();
    }

    //10 shots:
    for (int i = 0; i < 10; ++i) {
        if(ponteiro[i]){ //if exists
            //animate
        }
    }

    //during delete, insert

    update();
}
<commit_msg>restoring state<commit_after>#include "openglwidget.h"

OpenGLWidget::OpenGLWidget(QWidget* parent)
    : QOpenGLWidget(parent)
{
    angle=0.0;

    factory = std::make_shared<ModelFactory>(this);

    player = new QMediaPlayer;

    player->setMedia(QUrl::fromLocalFile("C:\\Repos\\asteroids\\src\\sounds\\fire.wav"));
    player->setVolume(100);
}
void OpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();

    qDebug("OpenGL version : %s", glGetString(GL_VERSION));
    qDebug("GLSL %s", glGetString(GL_SHADING_LANGUAGE_VERSION));

    glEnable(GL_DEPTH_TEST);

    connect(&timer, SIGNAL(timeout()), this, SLOT(animate()));
    timer.start(0);

    time.start();
}

void OpenGLWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void OpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (!ship)
        return;

    //Nave do jogador
    ship->drawModel(angle, 0.1);

    if (!gunshot)
        return;

    //Tiros do jogador
    gunshot->drawModel(angle, 0.02);

    //Tiros do jogador
    //gunshot->drawModel(angle, X, Y, Z);

    //asteroid->drawModel(angle, x, y, z);
    //guardar info de radius e center(x,y,z)
}

void OpenGLWidget::loadSampleModel()
{
    //ship = std::make_shared<Ship>(this, shipOffModel);
    //ship->Create();

    ship = factory->GetShipInstance();

    //gunshot = std::make_shared<Gunshot>(this, shipOffModel);
    //gunshot->Create();

    update();
}

void OpenGLWidget::keyPressEvent(QKeyEvent* event)
{
    switch (event->key())
    {
    case Qt::Key_Left:
        angle+=5.0;
        qDebug("Angle: %f", angle);
        break;
    case Qt::Key_Right:
        angle-=5.0;
        qDebug("Angle: %f", angle);
        break;
    case Qt::Key_Up:
        float xPos, yPos;
        xPos= ship->atualPoint.x() + 0.05*cos((angle + 90)* (3.1416/180));
        yPos= ship->atualPoint.y() + 0.05*sin((angle + 90)* (3.1416/180));
        ship->atualPoint = QVector3D(xPos, yPos, 0);
        break;
    case Qt::Key_Space:
        float xShipPos, yShipPos;
        xShipPos= ship->atualPoint.x() + 0.05*cos((angle + 90)* (3.1416/180));
        yShipPos= ship->atualPoint.y() + 0.05*sin((angle + 90)* (3.1416/180));

        gunshot = factory->GetGunshotInstance();
        gunshot->atualPoint = QVector3D(xShipPos, yShipPos, 0);

        player->play();
        break;
    case Qt::Key_Escape:
        qApp->quit();
        break;
    default:
        break;
    }
    update();
}

void OpenGLWidget::animate()
{
    float elapsedTime = time.restart() / 1000.0f;

    if (!gunshot)
        return;

    float xPos, yPos;
    xPos= gunshot->atualPoint.x() + elapsedTime * 2 * cos((angle + 90)* (3.1416/180));
    yPos= gunshot->atualPoint.y() + elapsedTime * 2 * sin((angle + 90)* (3.1416/180));
    gunshot->atualPoint =  QVector3D(xPos, yPos, 0);

    //Limits:
    if(qAbs(gunshot->atualPoint.x())>1.2 || qAbs(gunshot->atualPoint.y()) >1.2){
        gunshot.reset();
    }

    ////10 shots:
    //for (int i = 0; i < 10; ++i) {
    //    if(ponteiro[i]){ //if exists
    //        //animate
    //    }
    //}

    //during delete, insert

    update();
}
<|endoftext|>


<commit_before>#include "mrf_insert.h"

using namespace std;

// Size and location from handle

//void getinfo(GDALDatasetH hDS, img_info &img) {
img_info::img_info(GDALDatasetH hDS) {
    double	adfGT[6];
    GDALGetGeoTransform( hDS, adfGT );

    size.x=GDALGetRasterXSize(hDS);
    size.y=GDALGetRasterYSize(hDS);

    bbox.lx=adfGT[0];
    bbox.uy=adfGT[3];
    bbox.ux=adfGT[1]*size.x+bbox.lx;
    bbox.ly=adfGT[5]*size.y+bbox.uy;

    res.x=adfGT[1];
    res.y=adfGT[5];
}

static bool outside_bounds(const Bounds &inside,const Bounds &outside) {
    return (
        (inside.lx < outside.lx && !CPLIsEqual(inside.lx, outside.lx) ) ||
        (inside.ux > outside.ux && !CPLIsEqual(inside.ux, outside.ux) ) ||
        (inside.ly < outside.ly && !CPLIsEqual(inside.ly, outside.ly) ) ||
        (inside.uy > outside.uy && !CPLIsEqual(inside.uy, outside.uy) )
        );
}

// Insert the target in the base level
bool state::patch() {
    if (TargetName.empty())
        return false;

    // These are the same thing, the handle for the C functions, the dataset class for C++
    union {
        GDALDatasetH hDataset;
        GDALDataset *pTDS;
        GDALMRFDataset *pTarg;
    };

    union {
        GDALDatasetH hPatch;
        GDALDataset *pSDS;
    };

    CPLPushErrorHandler( CPLQuietErrorHandler );
    hDataset = GDALOpen( TargetName.c_str(), GA_Update );
    CPLPopErrorHandler();

    if( hDataset == NULL ) {
        CPLError(CE_Failure, CPLE_AppDefined,"Can't open target file %s for update",TargetName.c_str());
        return false;
    }

    try {

        // GetDescription is actually the driver ID, uppercase
        if (!EQUAL(pTDS->GetDriver()->GetDescription(),"MRF")) {
            CPLError(CE_Failure, CPLE_AppDefined,"Target file is not MRF");
            throw 1;
        }

        CPLPushErrorHandler( CPLQuietErrorHandler );
        hPatch= GDALOpen( SourceName.c_str(), GA_ReadOnly );
        CPLPopErrorHandler();

        if (hPatch == NULL ) {
            CPLError(CE_Failure, CPLE_AppDefined,"Can't open source file %s",SourceName.c_str());
            throw 1;
        };

    } catch (int e) {
        if (e>0) GDALClose(hDataset);
        return false;
    }

    Bounds blocks_bbox;
    Bounds pix_bbox;
    int overview_count=0;
    void *buffer=NULL;

    try {

        img_info in_img(hPatch);
        img_info out_img(hDataset);
        XY factor;
        factor.x=in_img.res.x/out_img.res.x;
        factor.y=in_img.res.x/out_img.res.x;

        if (verbose>0)
            cerr << "Out " << out_img.bbox << endl << "In " << in_img.bbox << endl;

        if (outside_bounds(in_img.bbox, out_img.bbox)) {
            CPLError(CE_Failure,CPLE_AppDefined,"Input patch outside of target");
            throw 2;
        }

        // Get the first band, which always exists, use it to collect some info
        GDALRasterBand *b0=pTDS->GetRasterBand(1);
        int bands=pTDS->GetRasterCount();
        int tsz_x,tsz_y;
        b0->GetBlockSize(&tsz_x,&tsz_y);
        GDALDataType eDataType=b0->GetRasterDataType();
        overview_count=b0->GetOverviewCount();

        int pixel_size=GDALGetDataTypeSize(eDataType)/8; // Bytes per pixel per band
        int line_size=tsz_x*pixel_size; // A line has this many bytes
        int buffer_size=line_size*tsz_y; // A block size in bytes

        // tolerance of 1/1000 of the resolution
        if ( (fabs(in_img.res.x - out_img.res.x) * 1000 > fabs(out_img.res.x)) ||
             (fabs(in_img.res.y - out_img.res.y) * 1000 > fabs(out_img.res.y)) )
        {
            CPLError(CE_Failure,CPLE_AppDefined,"Source and target resolutions don't match");
            throw 2;
        }

        //
        // Location in target pixels
        pix_bbox.lx=int((in_img.bbox.lx-out_img.bbox.lx)/in_img.res.x+0.5);
        pix_bbox.ux=int((in_img.bbox.ux-out_img.bbox.lx)/in_img.res.x+0.5);
        // uy < ly
        pix_bbox.uy=int((in_img.bbox.uy-out_img.bbox.uy)/in_img.res.y+0.5);
        pix_bbox.ly=int((in_img.bbox.ly-out_img.bbox.uy)/in_img.res.y+0.5);

        if (verbose != 0)
            cerr << "Pixel location " << pix_bbox << endl
                 << "Factor " << factor.x << "," << factor.y << endl;

        blocks_bbox.lx=int(pix_bbox.lx/tsz_x+0.5);
        blocks_bbox.ly=int(pix_bbox.ly/tsz_y+0.5);
        blocks_bbox.ux=int(pix_bbox.ux/tsz_x+0.5);
        blocks_bbox.uy=int(pix_bbox.uy/tsz_y+0.5);

        if (verbose != 0)
            cerr << "Blocks location " << blocks_bbox << endl;

        // Build a vector of output bands
        vector<GDALRasterBand *>src_b;
        vector<GDALRasterBand *>dst_b;

        for (int band=1;band<=bands;band++) {
            src_b.push_back(pSDS->GetRasterBand(band));
            dst_b.push_back(pTDS->GetRasterBand(band));
        }

        buffer=CPLMalloc(buffer_size); // Enough for one block

        //
        // Use the innner loop for bands, helps if output is interleaved
        //
        // Using the factor enables scaling of input
        // However, the input coverage still has to be exactly on
        // ouput block boundaries
        //
        for (int y=blocks_bbox.uy ; y < blocks_bbox.ly; y++) {
            int src_offset_y=tsz_y*(y-blocks_bbox.uy)*factor.y+0.5;
            for (int x=blocks_bbox.lx; x < blocks_bbox.ux; x++) {
                int src_offset_x=tsz_x*(x-blocks_bbox.lx)*factor.x+0.5;
                for (int band=0; band<bands; band++) { // Counting from zero in a vector
                    // cerr << " Y block " << y << " X block " << x << endl;
                    // READ
                    src_b[band]->RasterIO( GF_Read,
                        src_offset_x,src_offset_y, // offset in input image
                        tsz_x, tsz_y, // Size in input image
                        buffer, tsz_x, tsz_y, // Buffer and size in buffer
                        eDataType, // Requested type
                        pixel_size, line_size); // Pixel and line space
                    // WRITE
                    dst_b[band]->RasterIO( GF_Write,
                        x*tsz_x,y*tsz_y, // offset in output image
                        tsz_x, tsz_y, // Size in output image
                        buffer, tsz_x, tsz_y, // Buffer and size in buffer
                        eDataType, // Requested type
                        pixel_size, line_size ); // Pixel and line space
                }
            }
        }

        CPLFree(buffer);
    } catch (int e) {
        if (e>0) GDALClose(hDataset);
        CPLFree(buffer);
        return false;
    }

    // Close input, flush output, then worry about overviews
    GDALClose(hPatch);
    GDALFlushCache(hDataset);

    // Call the patchOverview for the MRF, this recursively
    // patches the overlays
    if (overlays)
        pTarg->PatchOverviews(blocks_bbox.lx,blocks_bbox.uy,
            blocks_bbox.ux-blocks_bbox.lx,
            blocks_bbox.ly-blocks_bbox.uy,0,true);

    // Now for the upper levels
    GDALFlushCache(hDataset);
    GDALClose(hDataset);
    return true;
 }

/************************************************************************/
/*                               Usage()                                */
/************************************************************************/

static int Usage()

{
    printf( "Usage: mrf_insert [-r {nearest,average,gauss,cubic,average_mp,average_magphase,mode}]\n"
            "                  [-q] [--help-general] source_file(s) target_file\n"
            "\n"
            "  -r : choice of resampling method (default: average)\n"
            "  -q : turn off progress display\n" );
    return 1;
}

int main(int nArgc, char **papszArgv) {
    state State;
    int ret=0;

    std::vector<std::string> fnames;

    /* Check that we are running against at least GDAL 1.9 */
    /* Note to developers : if using newer API, please change the requirement */
    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1900)
    {
        fprintf(stderr, "At least, GDAL >= 1.9.0 is required for this version of %s, "
                        "which was compiled against GDAL %s\n", papszArgv[0], GDAL_RELEASE_NAME);
        exit(1);
    }

    GDALAllRegister();

    //
    // Set up a reasonable large cache size, say 256MB
    // CPLSetConfigOption("GDAL_CACHEMAX","256");
    GDALSetCacheMax(256*1024*1024);
    //
    // Done before the CmdLineProcessor has looked at options, so it can be overriden by the user
    // by setting the GDAL_CACHEMAX env, or passing it as a --config option
    //
    // See http://trac.osgeo.org/gdal/wiki/ConfigOptions
    //

    // Pick up the GDAL options
    nArgc = GDALGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
    if( nArgc < 1 )
        exit( -nArgc );

/* -------------------------------------------------------------------- */
/*      Parse commandline, set up state                                 */
/* -------------------------------------------------------------------- */

    for( int iArg = 1; iArg < nArgc; iArg++ )
    {
        if( EQUAL(papszArgv[iArg], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(papszArgv[iArg],"-r") && iArg < nArgc-1 ) {
            State.setResampling(papszArgv[++iArg]);
            State.setOverlays();
        }
        else if( EQUAL(papszArgv[iArg],"-q") || EQUAL(papszArgv[iArg],"-quiet") )
            State.setProgress(GDALDummyProgress);
        else if( EQUAL(papszArgv[iArg],"-v"))
            State.setDebug(1);
        else fnames.push_back(papszArgv[iArg]);
    }

    // Need at least a target and a source
    if (fnames.size()>0)
    {
        State.setTarget(fnames[fnames.size()-1]);
        fnames.pop_back();
    }

    if(fnames.empty()) return Usage();

    try {

        // Each input file in sequence, as they were passed as arguments
        for (int i=0; i < fnames.size() ; i++) {
            State.setSource(fnames[i]);

            // false return means error was detected and printed, just exit
            if (!State.patch())
                throw 2;

        }

    } // Try, all execution
    catch (int err_ret) {
        ret=err_ret;
    };

    // General cleanup
    CSLDestroy( papszArgv );
    GDALDestroyDriverManager();
    return ret;
}
<commit_msg>#5 GIBS-353 Added some tolerance to north and west boundary detection so patch is not outside of target with rounding.<commit_after>#include "mrf_insert.h"

using namespace std;

// Size and location from handle

//void getinfo(GDALDatasetH hDS, img_info &img) {
img_info::img_info(GDALDatasetH hDS) {
    double	adfGT[6];
    GDALGetGeoTransform( hDS, adfGT );

    size.x=GDALGetRasterXSize(hDS);
    size.y=GDALGetRasterYSize(hDS);

    bbox.lx=adfGT[0];
    bbox.uy=adfGT[3];
    bbox.ux=adfGT[1]*size.x+bbox.lx;
    bbox.ly=adfGT[5]*size.y+bbox.uy;

    res.x=adfGT[1];
    res.y=adfGT[5];
}

static bool outside_bounds(const Bounds &inside,const Bounds &outside) {
    return (
        ((inside.lx+0.01) < outside.lx && !CPLIsEqual(inside.lx, outside.lx) ) ||
        (inside.ux > outside.ux && !CPLIsEqual(inside.ux, outside.ux) ) ||
        (inside.ly < outside.ly && !CPLIsEqual(inside.ly, outside.ly) ) ||
        ((inside.uy-0.01) > outside.uy && !CPLIsEqual(inside.uy, outside.uy) )
        );
}

// Insert the target in the base level
bool state::patch() {
    if (TargetName.empty())
        return false;

    // These are the same thing, the handle for the C functions, the dataset class for C++
    union {
        GDALDatasetH hDataset;
        GDALDataset *pTDS;
        GDALMRFDataset *pTarg;
    };

    union {
        GDALDatasetH hPatch;
        GDALDataset *pSDS;
    };

    CPLPushErrorHandler( CPLQuietErrorHandler );
    hDataset = GDALOpen( TargetName.c_str(), GA_Update );
    CPLPopErrorHandler();

    if( hDataset == NULL ) {
        CPLError(CE_Failure, CPLE_AppDefined,"Can't open target file %s for update",TargetName.c_str());
        return false;
    }

    try {

        // GetDescription is actually the driver ID, uppercase
        if (!EQUAL(pTDS->GetDriver()->GetDescription(),"MRF")) {
            CPLError(CE_Failure, CPLE_AppDefined,"Target file is not MRF");
            throw 1;
        }

        CPLPushErrorHandler( CPLQuietErrorHandler );
        hPatch= GDALOpen( SourceName.c_str(), GA_ReadOnly );
        CPLPopErrorHandler();

        if (hPatch == NULL ) {
            CPLError(CE_Failure, CPLE_AppDefined,"Can't open source file %s",SourceName.c_str());
            throw 1;
        };

    } catch (int e) {
        if (e>0) GDALClose(hDataset);
        return false;
    }

    Bounds blocks_bbox;
    Bounds pix_bbox;
    int overview_count=0;
    void *buffer=NULL;

    try {

        img_info in_img(hPatch);
        img_info out_img(hDataset);
        XY factor;
        factor.x=in_img.res.x/out_img.res.x;
        factor.y=in_img.res.x/out_img.res.x;

        if (verbose>0)
            cerr << "Out " << out_img.bbox << endl << "In " << in_img.bbox << endl;

        if (outside_bounds(in_img.bbox, out_img.bbox)) {
            CPLError(CE_Failure,CPLE_AppDefined,"Input patch outside of target");
            throw 2;
        }

        // Get the first band, which always exists, use it to collect some info
        GDALRasterBand *b0=pTDS->GetRasterBand(1);
        int bands=pTDS->GetRasterCount();
        int tsz_x,tsz_y;
        b0->GetBlockSize(&tsz_x,&tsz_y);
        GDALDataType eDataType=b0->GetRasterDataType();
        overview_count=b0->GetOverviewCount();

        int pixel_size=GDALGetDataTypeSize(eDataType)/8; // Bytes per pixel per band
        int line_size=tsz_x*pixel_size; // A line has this many bytes
        int buffer_size=line_size*tsz_y; // A block size in bytes

        // tolerance of 1/1000 of the resolution
        if ( (fabs(in_img.res.x - out_img.res.x) * 1000 > fabs(out_img.res.x)) ||
             (fabs(in_img.res.y - out_img.res.y) * 1000 > fabs(out_img.res.y)) )
        {
            CPLError(CE_Failure,CPLE_AppDefined,"Source and target resolutions don't match");
            throw 2;
        }

        //
        // Location in target pixels
        pix_bbox.lx=int((in_img.bbox.lx-out_img.bbox.lx)/in_img.res.x+0.5);
        pix_bbox.ux=int((in_img.bbox.ux-out_img.bbox.lx)/in_img.res.x+0.5);
        // uy < ly
        pix_bbox.uy=int((in_img.bbox.uy-out_img.bbox.uy)/in_img.res.y+0.5);
        pix_bbox.ly=int((in_img.bbox.ly-out_img.bbox.uy)/in_img.res.y+0.5);

        if (verbose != 0)
            cerr << "Pixel location " << pix_bbox << endl
                 << "Factor " << factor.x << "," << factor.y << endl;

        blocks_bbox.lx=int(pix_bbox.lx/tsz_x+0.5);
        blocks_bbox.ly=int(pix_bbox.ly/tsz_y+0.5);
        blocks_bbox.ux=int(pix_bbox.ux/tsz_x+0.5);
        blocks_bbox.uy=int(pix_bbox.uy/tsz_y+0.5);

        if (verbose != 0)
            cerr << "Blocks location " << blocks_bbox << endl;

        // Build a vector of output bands
        vector<GDALRasterBand *>src_b;
        vector<GDALRasterBand *>dst_b;

        for (int band=1;band<=bands;band++) {
            src_b.push_back(pSDS->GetRasterBand(band));
            dst_b.push_back(pTDS->GetRasterBand(band));
        }

        buffer=CPLMalloc(buffer_size); // Enough for one block

        //
        // Use the innner loop for bands, helps if output is interleaved
        //
        // Using the factor enables scaling of input
        // However, the input coverage still has to be exactly on
        // ouput block boundaries
        //
        for (int y=blocks_bbox.uy ; y < blocks_bbox.ly; y++) {
            int src_offset_y=tsz_y*(y-blocks_bbox.uy)*factor.y+0.5;
            for (int x=blocks_bbox.lx; x < blocks_bbox.ux; x++) {
                int src_offset_x=tsz_x*(x-blocks_bbox.lx)*factor.x+0.5;
                for (int band=0; band<bands; band++) { // Counting from zero in a vector
                    // cerr << " Y block " << y << " X block " << x << endl;
                    // READ
                    src_b[band]->RasterIO( GF_Read,
                        src_offset_x,src_offset_y, // offset in input image
                        tsz_x, tsz_y, // Size in input image
                        buffer, tsz_x, tsz_y, // Buffer and size in buffer
                        eDataType, // Requested type
                        pixel_size, line_size); // Pixel and line space
                    // WRITE
                    dst_b[band]->RasterIO( GF_Write,
                        x*tsz_x,y*tsz_y, // offset in output image
                        tsz_x, tsz_y, // Size in output image
                        buffer, tsz_x, tsz_y, // Buffer and size in buffer
                        eDataType, // Requested type
                        pixel_size, line_size ); // Pixel and line space
                }
            }
        }

        CPLFree(buffer);
    } catch (int e) {
        if (e>0) GDALClose(hDataset);
        CPLFree(buffer);
        return false;
    }

    // Close input, flush output, then worry about overviews
    GDALClose(hPatch);
    GDALFlushCache(hDataset);

    // Call the patchOverview for the MRF, this recursively
    // patches the overlays
    if (overlays)
        pTarg->PatchOverviews(blocks_bbox.lx,blocks_bbox.uy,
            blocks_bbox.ux-blocks_bbox.lx,
            blocks_bbox.ly-blocks_bbox.uy,0,true);

    // Now for the upper levels
    GDALFlushCache(hDataset);
    GDALClose(hDataset);
    return true;
 }

/************************************************************************/
/*                               Usage()                                */
/************************************************************************/

static int Usage()

{
    printf( "Usage: mrf_insert [-r {nearest,average,gauss,cubic,average_mp,average_magphase,mode}]\n"
            "                  [-q] [--help-general] source_file(s) target_file\n"
            "\n"
            "  -r : choice of resampling method (default: average)\n"
            "  -q : turn off progress display\n" );
    return 1;
}

int main(int nArgc, char **papszArgv) {
    state State;
    int ret=0;

    std::vector<std::string> fnames;

    /* Check that we are running against at least GDAL 1.9 */
    /* Note to developers : if using newer API, please change the requirement */
    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1900)
    {
        fprintf(stderr, "At least, GDAL >= 1.9.0 is required for this version of %s, "
                        "which was compiled against GDAL %s\n", papszArgv[0], GDAL_RELEASE_NAME);
        exit(1);
    }

    GDALAllRegister();

    //
    // Set up a reasonable large cache size, say 256MB
    // CPLSetConfigOption("GDAL_CACHEMAX","256");
    GDALSetCacheMax(256*1024*1024);
    //
    // Done before the CmdLineProcessor has looked at options, so it can be overriden by the user
    // by setting the GDAL_CACHEMAX env, or passing it as a --config option
    //
    // See http://trac.osgeo.org/gdal/wiki/ConfigOptions
    //

    // Pick up the GDAL options
    nArgc = GDALGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
    if( nArgc < 1 )
        exit( -nArgc );

/* -------------------------------------------------------------------- */
/*      Parse commandline, set up state                                 */
/* -------------------------------------------------------------------- */

    for( int iArg = 1; iArg < nArgc; iArg++ )
    {
        if( EQUAL(papszArgv[iArg], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(papszArgv[iArg],"-r") && iArg < nArgc-1 ) {
            State.setResampling(papszArgv[++iArg]);
            State.setOverlays();
        }
        else if( EQUAL(papszArgv[iArg],"-q") || EQUAL(papszArgv[iArg],"-quiet") )
            State.setProgress(GDALDummyProgress);
        else if( EQUAL(papszArgv[iArg],"-v"))
            State.setDebug(1);
        else fnames.push_back(papszArgv[iArg]);
    }

    // Need at least a target and a source
    if (fnames.size()>0)
    {
        State.setTarget(fnames[fnames.size()-1]);
        fnames.pop_back();
    }

    if(fnames.empty()) return Usage();

    try {

        // Each input file in sequence, as they were passed as arguments
        for (int i=0; i < fnames.size() ; i++) {
            State.setSource(fnames[i]);

            // false return means error was detected and printed, just exit
            if (!State.patch())
                throw 2;

        }

    } // Try, all execution
    catch (int err_ret) {
        ret=err_ret;
    };

    // General cleanup
    CSLDestroy( papszArgv );
    GDALDestroyDriverManager();
    return ret;
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "QmitkSeedPointSetComponent.h"
#include "QmitkSeedPointSetComponentGUI.h"

#include <QmitkDataTreeComboBox.h>

#include <QmitkPointListWidget.h>

#include "mitkRenderWindow.h"
#include "mitkRenderingManager.h"
#include "mitkProperties.h"
#include "mitkDataTreeFilterFunctions.h"

#include <qlineedit.h>
#include <qslider.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <qstring.h>

/***************       CONSTRUCTOR      ***************/
QmitkSeedPointSetComponent::QmitkSeedPointSetComponent(QObject * parent, const char * parentName, QmitkStdMultiWidget *mitkStdMultiWidget, mitk::DataTreeIteratorBase* it, bool /*updateSelector*/, bool /*showSelector*/)
: QmitkInteractionFunctionalityComponent(parent, parentName, mitkStdMultiWidget, it),
m_PointSetComponentGUI(NULL),
m_PointSetNodeExisting(false),
m_PointSetNodeName("SeedPoints"),
m_It(it)
{
  SetDataTreeIterator(it);
  SetAvailability(true);

  SetComponentName("PointSet");
}

/***************        DESTRUCTOR      ***************/
QmitkSeedPointSetComponent::~QmitkSeedPointSetComponent()
{

}

///*************** GET DATA TREE ITERATOR ***************/
//mitk::DataTreeIteratorBase* QmitkPixelGreyValueManipulatorComponent::GetDataTreeIterator()
//{
//  return m_DataTreeIterator.GetPointer();
//}

/*************** SET DATA TREE ITERATOR ***************/
void QmitkSeedPointSetComponent::SetDataTreeIterator(mitk::DataTreeIteratorBase* it)
{
  m_DataTreeIterator = it;
}

/*************** GET TREE NODE SELECTOR ***************/
QmitkDataTreeComboBox* QmitkSeedPointSetComponent::GetTreeNodeSelector()
{
  return m_PointSetComponentGUI->GetTreeNodeSelector();
}

/***************   GET POINT SET NODE   ***************/
 mitk::DataTreeNode::Pointer QmitkSeedPointSetComponent::GetPointSetNode()
 {
  return  m_PointSetNode;
 }

 /************ Update DATATREECOMBOBOX(ES) *************/
void QmitkSeedPointSetComponent::UpdateDataTreeComboBoxes()
{
  if(GetTreeNodeSelector() != NULL)
  {
   GetTreeNodeSelector()->Update();
  }
}

/***************       CONNECTIONS      ***************/
void QmitkSeedPointSetComponent::CreateConnections()
{
  if ( m_PointSetComponentGUI )
  {
    connect( (QObject*)(m_PointSetComponentGUI->GetTreeNodeSelector()), SIGNAL(activated(const mitk::DataTreeFilter::Item *)), (QObject*) this, SLOT(ImageSelected(const mitk::DataTreeFilter::Item *)));
    connect((QObject*)(m_PointSetComponentGUI->GetShowTreeNodeSelectorGroupBox()), SIGNAL(toggled(bool)), (QObject*) this, SLOT(ShowTreeNodeSelector()));
    connect((QObject*)(m_PointSetComponentGUI->GetShowComponent()), SIGNAL(toggled(bool)), (QObject*) this, SLOT(ShowComponentContent()));

        //to connect the toplevel checkable GroupBox with the method SetContentContainerVisibility to inform all containing komponent to shrink or to expand
    connect( (QObject*)(m_PointSetComponentGUI->GetShowComponent()),  SIGNAL(toggled(bool)), (QObject*) this, SLOT(SetContentContainerVisibility(bool)));

  }
}

/*************** SHOW COMPONENT CONTENT ***************/
void QmitkSeedPointSetComponent::ShowComponentContent()
{
 m_PointSetComponentGUI->GetComponentContent()->setShown(m_PointSetComponentGUI->GetShowComponent()->isChecked());
}

/*************** SHOW TREE NODE SELECTOR **************/
void QmitkSeedPointSetComponent::ShowTreeNodeSelector()
{
m_PointSetComponentGUI->GetTreeNodeSelectorContentGroupBox()->setShown(m_PointSetComponentGUI->GetShowTreeNodeSelectorGroupBox()->isChecked());
}

/***************     IMAGE SELECTED     ***************/
void QmitkSeedPointSetComponent::ImageSelected(const mitk::DataTreeFilter::Item * imageIt)
{
  m_SelectedItem = imageIt;
  mitk::DataTreeFilter::Item* currentItem(NULL);
  if(m_PointSetComponentGUI)
  {
    if(mitk::DataTreeFilter* filter = m_PointSetComponentGUI->GetTreeNodeSelector()->GetFilter())
    {
      if(imageIt)
      {
        currentItem = const_cast <mitk::DataTreeFilter::Item*> ( filter->FindItem( imageIt->GetNode() ) );
      }
    }
  }
  if(currentItem)
  {
    currentItem->SetSelected(true);
  }

  TreeChanged();
}

/*************** CREATE CONTAINER WIDGET **************/
QWidget* QmitkSeedPointSetComponent::CreateControlWidget(QWidget* parent)
{
  m_PointSetComponentGUI = new QmitkSeedPointSetComponentGUI(parent);
  m_GUI = m_PointSetComponentGUI;

  m_PointSetComponentGUI->GetTreeNodeSelector()->SetDataTree(GetDataTreeIterator());
  //m_PointSetComponentGUI->GetTreeNodeSelector()->GetFilter()->SetFilter(mitk::IsBaseDataTypeWithProperty<mitk::Image>("Points"));
  m_PointSetComponentGUI->GetTreeNodeSelector()->GetFilter()->SetFilter(mitk::IsBaseDataTypeWithProperty<mitk::PointSet>("SeedPoints"));

  return m_PointSetComponentGUI;
}

/*************** GET CONTENT CONTAINER  ***************/
QGroupBox * QmitkSeedPointSetComponent::GetContentContainer()
{
 return m_PointSetComponentGUI->GetComponentContent();
}

/************ GET MAIN CHECK BOX CONTAINER ************/
QGroupBox * QmitkSeedPointSetComponent::GetMainCheckBoxContainer()
{
 return m_PointSetComponentGUI->GetShowComponent();
}

/*********** SET CONTENT CONTAINER VISIBLE ************/
void QmitkSeedPointSetComponent::SetContentContainerVisibility(bool visible)
{
   GetContentContainer()->setShown(visible);
  if(GetMainCheckBoxContainer() != NULL)
  {
    if(GetMainCheckBoxContainer()->isChecked())
    {
      Activated();
    }
    else
    {
      Deactivated();
    }
  }
}

/***************   SET DATA TREE NAME   ***************/
void QmitkSeedPointSetComponent::SetDataTreeName(std::string pointSetNodeName)
{
  m_PointSetNodeName = pointSetNodeName;
}

/***************        ACTIVATED       ***************/
void QmitkSeedPointSetComponent::Activated()
{
  QmitkBaseFunctionalityComponent::Activated();
  m_Active = true;
  IsNodeExisting();
  CreatePointSetNode();
}

void QmitkSeedPointSetComponent::IsNodeExisting()
{
 //GetIteratorToNode(dataTree, m_PointSetNode, m_It);
  mitk::DataTree* dataTree = (mitk::DataTree*)m_It->GetTree();//m_It->GetFirstNodeByType<mitk::PointSet>(GetDataTreeIterator());
   // mitk::DataTreeIteratorClone dataTreeIteratorClone = dataTree->GetIteratorToNode( dataTree, m_PointSetNode );
  mitk::DataTreeIteratorClone iTClone = dataTree->GetIteratorToNode(dataTree, m_PointSetNode);
  if(iTClone->IsAtEnd())
  {
   m_PointSetNodeExisting = false;
  }
  else
   {
   m_PointSetNodeExisting = true;
  }
}

void QmitkSeedPointSetComponent::CreatePointSetNode()
{
  if(m_Active)
  {
    if(!m_PointSetNodeExisting)
    {

      //BEGIN ONLY FOR POINTS******************************************************************************************************************************************
      //if (m_PointSetNode.IsNull())
      //{
        //Points are to define the two Points for the ThresholdGradient
        //add Point with crtl + leftMouseButton
        m_Seeds = mitk::PointSet::New();

        m_PointSetNode = mitk::DataTreeNode::New();
        m_PointSetNode->SetData(m_Seeds);
        mitk::ColorProperty::Pointer color = new mitk::ColorProperty(0.2, 0.0, 0.8);
        mitk::Point3D colorTwo;
        mitk::FillVector3D(colorTwo, 0.2, 0.0, 0.8);
        m_PointSetInteractor = new mitk::PointSetInteractor("pointsetinteractor", m_PointSetNode, 2);
        m_PointSetInteractor->DebugOn();
        m_PointSetComponentGUI->GetPointListWidget()->SwitchInteraction(&m_PointSetInteractor, &m_PointSetNode, 2, colorTwo,"Points ");  //-1 for unlimited points
        m_PointSetNode->SetProperty("color",color);
        m_PointSetNode->SetIntProperty("layer", 101);
        m_PointSetNode->SetProperty("name", new mitk::StringProperty(m_PointSetNodeName));

        m_PointSetNode->SetProperty( "SeedPoints", new mitk::BoolProperty(true));
        m_DataTreeIterator.GetPointer()->Add(m_PointSetNode);
        //m_PointSetNodeExisting = true;

        mitk::GlobalInteraction::GetInstance()->AddInteractor(m_PointSetInteractor);
      }
      else
      {
        mitk::GlobalInteraction::GetInstance()->AddInteractor(m_PointSetInteractor);
      }
      //END ONLY FOR POINTS******************************************************************************************************************************************

  }
}
/***************       DEACTIVATED      ***************/
void QmitkSeedPointSetComponent::Deactivated()
{
    QmitkBaseFunctionalityComponent::Deactivated();
    m_Active = false;
  //  if(m_PointSetNode.IsNotNull())
  //{
  //  mitk::DataTreeIteratorClone iteratorClone = m_DataTreeIterator;
  //  while ( !iteratorClone->IsAtEnd() )
  //  {
  //    mitk::DataTreeNode::Pointer node = iteratorClone->Get();

  //    std::string name;
  //    node->GetName(name);

  //    if(name == m_PointSetNodeName)
  //    {
  //      iteratorClone->Disconnect();
  //      m_PointSetNodeExisting = false;
  //    }
  //    ++iteratorClone;
  //  }
  //}
  //BEGIN ONLY FOR SEEDPOINTS******************************************************************************************************************************************
  //deactivate m_SeedPointSetNode when leaving SurfaceCreator
  if (m_PointSetNode.IsNotNull())
  {
    mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor);
  }
  //END ONLY FOR SEEDPOINTS******************************************************************************************************************************************
}

<commit_msg>FIX warning<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "QmitkSeedPointSetComponent.h"
#include "QmitkSeedPointSetComponentGUI.h"

#include <QmitkDataTreeComboBox.h>

#include <QmitkPointListWidget.h>

#include "mitkRenderWindow.h"
#include "mitkRenderingManager.h"
#include "mitkProperties.h"
#include "mitkDataTreeFilterFunctions.h"

#include <qlineedit.h>
#include <qslider.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <qstring.h>

/***************       CONSTRUCTOR      ***************/
QmitkSeedPointSetComponent::QmitkSeedPointSetComponent(QObject * parent, const char * parentName, QmitkStdMultiWidget *mitkStdMultiWidget, mitk::DataTreeIteratorBase* it, bool /*updateSelector*/, bool /*showSelector*/)
: QmitkInteractionFunctionalityComponent(parent, parentName, mitkStdMultiWidget, it),
m_PointSetComponentGUI(NULL),
m_PointSetNodeExisting(false),
m_It(it),
m_PointSetNodeName("SeedPoints")
{
  SetDataTreeIterator(it);
  SetAvailability(true);

  SetComponentName("PointSet");
}

/***************        DESTRUCTOR      ***************/
QmitkSeedPointSetComponent::~QmitkSeedPointSetComponent()
{

}

///*************** GET DATA TREE ITERATOR ***************/
//mitk::DataTreeIteratorBase* QmitkPixelGreyValueManipulatorComponent::GetDataTreeIterator()
//{
//  return m_DataTreeIterator.GetPointer();
//}

/*************** SET DATA TREE ITERATOR ***************/
void QmitkSeedPointSetComponent::SetDataTreeIterator(mitk::DataTreeIteratorBase* it)
{
  m_DataTreeIterator = it;
}

/*************** GET TREE NODE SELECTOR ***************/
QmitkDataTreeComboBox* QmitkSeedPointSetComponent::GetTreeNodeSelector()
{
  return m_PointSetComponentGUI->GetTreeNodeSelector();
}

/***************   GET POINT SET NODE   ***************/
 mitk::DataTreeNode::Pointer QmitkSeedPointSetComponent::GetPointSetNode()
 {
  return  m_PointSetNode;
 }

 /************ Update DATATREECOMBOBOX(ES) *************/
void QmitkSeedPointSetComponent::UpdateDataTreeComboBoxes()
{
  if(GetTreeNodeSelector() != NULL)
  {
   GetTreeNodeSelector()->Update();
  }
}

/***************       CONNECTIONS      ***************/
void QmitkSeedPointSetComponent::CreateConnections()
{
  if ( m_PointSetComponentGUI )
  {
    connect( (QObject*)(m_PointSetComponentGUI->GetTreeNodeSelector()), SIGNAL(activated(const mitk::DataTreeFilter::Item *)), (QObject*) this, SLOT(ImageSelected(const mitk::DataTreeFilter::Item *)));
    connect((QObject*)(m_PointSetComponentGUI->GetShowTreeNodeSelectorGroupBox()), SIGNAL(toggled(bool)), (QObject*) this, SLOT(ShowTreeNodeSelector()));
    connect((QObject*)(m_PointSetComponentGUI->GetShowComponent()), SIGNAL(toggled(bool)), (QObject*) this, SLOT(ShowComponentContent()));

        //to connect the toplevel checkable GroupBox with the method SetContentContainerVisibility to inform all containing komponent to shrink or to expand
    connect( (QObject*)(m_PointSetComponentGUI->GetShowComponent()),  SIGNAL(toggled(bool)), (QObject*) this, SLOT(SetContentContainerVisibility(bool)));

  }
}

/*************** SHOW COMPONENT CONTENT ***************/
void QmitkSeedPointSetComponent::ShowComponentContent()
{
 m_PointSetComponentGUI->GetComponentContent()->setShown(m_PointSetComponentGUI->GetShowComponent()->isChecked());
}

/*************** SHOW TREE NODE SELECTOR **************/
void QmitkSeedPointSetComponent::ShowTreeNodeSelector()
{
m_PointSetComponentGUI->GetTreeNodeSelectorContentGroupBox()->setShown(m_PointSetComponentGUI->GetShowTreeNodeSelectorGroupBox()->isChecked());
}

/***************     IMAGE SELECTED     ***************/
void QmitkSeedPointSetComponent::ImageSelected(const mitk::DataTreeFilter::Item * imageIt)
{
  m_SelectedItem = imageIt;
  mitk::DataTreeFilter::Item* currentItem(NULL);
  if(m_PointSetComponentGUI)
  {
    if(mitk::DataTreeFilter* filter = m_PointSetComponentGUI->GetTreeNodeSelector()->GetFilter())
    {
      if(imageIt)
      {
        currentItem = const_cast <mitk::DataTreeFilter::Item*> ( filter->FindItem( imageIt->GetNode() ) );
      }
    }
  }
  if(currentItem)
  {
    currentItem->SetSelected(true);
  }

  TreeChanged();
}

/*************** CREATE CONTAINER WIDGET **************/
QWidget* QmitkSeedPointSetComponent::CreateControlWidget(QWidget* parent)
{
  m_PointSetComponentGUI = new QmitkSeedPointSetComponentGUI(parent);
  m_GUI = m_PointSetComponentGUI;

  m_PointSetComponentGUI->GetTreeNodeSelector()->SetDataTree(GetDataTreeIterator());
  //m_PointSetComponentGUI->GetTreeNodeSelector()->GetFilter()->SetFilter(mitk::IsBaseDataTypeWithProperty<mitk::Image>("Points"));
  m_PointSetComponentGUI->GetTreeNodeSelector()->GetFilter()->SetFilter(mitk::IsBaseDataTypeWithProperty<mitk::PointSet>("SeedPoints"));

  return m_PointSetComponentGUI;
}

/*************** GET CONTENT CONTAINER  ***************/
QGroupBox * QmitkSeedPointSetComponent::GetContentContainer()
{
 return m_PointSetComponentGUI->GetComponentContent();
}

/************ GET MAIN CHECK BOX CONTAINER ************/
QGroupBox * QmitkSeedPointSetComponent::GetMainCheckBoxContainer()
{
 return m_PointSetComponentGUI->GetShowComponent();
}

/*********** SET CONTENT CONTAINER VISIBLE ************/
void QmitkSeedPointSetComponent::SetContentContainerVisibility(bool visible)
{
   GetContentContainer()->setShown(visible);
  if(GetMainCheckBoxContainer() != NULL)
  {
    if(GetMainCheckBoxContainer()->isChecked())
    {
      Activated();
    }
    else
    {
      Deactivated();
    }
  }
}

/***************   SET DATA TREE NAME   ***************/
void QmitkSeedPointSetComponent::SetDataTreeName(std::string pointSetNodeName)
{
  m_PointSetNodeName = pointSetNodeName;
}

/***************        ACTIVATED       ***************/
void QmitkSeedPointSetComponent::Activated()
{
  QmitkBaseFunctionalityComponent::Activated();
  m_Active = true;
  IsNodeExisting();
  CreatePointSetNode();
}

void QmitkSeedPointSetComponent::IsNodeExisting()
{
 //GetIteratorToNode(dataTree, m_PointSetNode, m_It);
  mitk::DataTree* dataTree = (mitk::DataTree*)m_It->GetTree();//m_It->GetFirstNodeByType<mitk::PointSet>(GetDataTreeIterator());
   // mitk::DataTreeIteratorClone dataTreeIteratorClone = dataTree->GetIteratorToNode( dataTree, m_PointSetNode );
  mitk::DataTreeIteratorClone iTClone = dataTree->GetIteratorToNode(dataTree, m_PointSetNode);
  if(iTClone->IsAtEnd())
  {
   m_PointSetNodeExisting = false;
  }
  else
   {
   m_PointSetNodeExisting = true;
  }
}

void QmitkSeedPointSetComponent::CreatePointSetNode()
{
  if(m_Active)
  {
    if(!m_PointSetNodeExisting)
    {

      //BEGIN ONLY FOR POINTS******************************************************************************************************************************************
      //if (m_PointSetNode.IsNull())
      //{
        //Points are to define the two Points for the ThresholdGradient
        //add Point with crtl + leftMouseButton
        m_Seeds = mitk::PointSet::New();

        m_PointSetNode = mitk::DataTreeNode::New();
        m_PointSetNode->SetData(m_Seeds);
        mitk::ColorProperty::Pointer color = new mitk::ColorProperty(0.2, 0.0, 0.8);
        mitk::Point3D colorTwo;
        mitk::FillVector3D(colorTwo, 0.2, 0.0, 0.8);
        m_PointSetInteractor = new mitk::PointSetInteractor("pointsetinteractor", m_PointSetNode, 2);
        m_PointSetInteractor->DebugOn();
        m_PointSetComponentGUI->GetPointListWidget()->SwitchInteraction(&m_PointSetInteractor, &m_PointSetNode, 2, colorTwo,"Points ");  //-1 for unlimited points
        m_PointSetNode->SetProperty("color",color);
        m_PointSetNode->SetIntProperty("layer", 101);
        m_PointSetNode->SetProperty("name", new mitk::StringProperty(m_PointSetNodeName));

        m_PointSetNode->SetProperty( "SeedPoints", new mitk::BoolProperty(true));
        m_DataTreeIterator.GetPointer()->Add(m_PointSetNode);
        //m_PointSetNodeExisting = true;

        mitk::GlobalInteraction::GetInstance()->AddInteractor(m_PointSetInteractor);
      }
      else
      {
        mitk::GlobalInteraction::GetInstance()->AddInteractor(m_PointSetInteractor);
      }
      //END ONLY FOR POINTS******************************************************************************************************************************************

  }
}
/***************       DEACTIVATED      ***************/
void QmitkSeedPointSetComponent::Deactivated()
{
    QmitkBaseFunctionalityComponent::Deactivated();
    m_Active = false;
  //  if(m_PointSetNode.IsNotNull())
  //{
  //  mitk::DataTreeIteratorClone iteratorClone = m_DataTreeIterator;
  //  while ( !iteratorClone->IsAtEnd() )
  //  {
  //    mitk::DataTreeNode::Pointer node = iteratorClone->Get();

  //    std::string name;
  //    node->GetName(name);

  //    if(name == m_PointSetNodeName)
  //    {
  //      iteratorClone->Disconnect();
  //      m_PointSetNodeExisting = false;
  //    }
  //    ++iteratorClone;
  //  }
  //}
  //BEGIN ONLY FOR SEEDPOINTS******************************************************************************************************************************************
  //deactivate m_SeedPointSetNode when leaving SurfaceCreator
  if (m_PointSetNode.IsNotNull())
  {
    mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_PointSetInteractor);
  }
  //END ONLY FOR SEEDPOINTS******************************************************************************************************************************************
}

<|endoftext|>


<commit_before>/**********************************************************************
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.osgeo.org
 *
 * Copyright (C) 2020 Paul Ramsey
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/index/strtree/SimpleSTRtree.h>
#include <geos/index/strtree/SimpleSTRdistance.h>
#include <geos/index/ItemVisitor.h>
#include <geos/geom/Envelope.h>
#include <geos/geom/Geometry.h>
#include <geos/util.h>

#include <vector>
#include <cassert>
#include <cmath>
#include <algorithm> // std::sort
#include <iostream> // for debugging
#include <limits>
#include <geos/util/GEOSException.h>

using namespace geos::geom;

namespace geos {
namespace index { // geos.index
namespace strtree { // geos.index.strtree

/* private */
SimpleSTRnode*
SimpleSTRtree::createNode(int newLevel, const geom::Envelope* itemEnv, void* item)
{
    nodesQue.emplace_back(newLevel, itemEnv, item, nodeCapacity);
    SimpleSTRnode& node = nodesQue.back();
    return &node;
}

/* private */
SimpleSTRnode*
SimpleSTRtree::createNode(int newLevel)
{
    return createNode(newLevel, nullptr, nullptr);
}

/* public */
void
SimpleSTRtree::insert(geom::Geometry* geom)
{
    insert(geom->getEnvelopeInternal(), static_cast<void*>(geom));
}

/* public */
void
SimpleSTRtree::insert(const geom::Envelope* itemEnv, void* item)
{
    if (itemEnv->isNull())
        return;
    SimpleSTRnode *node = createNode(0, itemEnv, item);
    nodes.push_back(node);
}

/* private static */
void
SimpleSTRtree::sortNodesY(std::vector<SimpleSTRnode*>& nodeList)
{
    struct {
        bool operator()(SimpleSTRnode* a, SimpleSTRnode* b) const
        {
            const geom::Envelope& ea = a->getEnvelope();
            const geom::Envelope& eb = b->getEnvelope();
            double ya = (ea.getMinY() + ea.getMaxY()) / 2.0;
            double yb = (eb.getMinY() + eb.getMaxY()) / 2.0;
            return ya < yb;
        }
    } nodeSortByY;

    std::sort(nodeList.begin(), nodeList.end(), nodeSortByY);
}

/* private static */
void
SimpleSTRtree::sortNodesX(std::vector<SimpleSTRnode*>& nodeList)
{
    struct {
        bool operator()(SimpleSTRnode* a, SimpleSTRnode* b) const
        {
            const geom::Envelope& ea = a->getEnvelope();
            const geom::Envelope& eb = b->getEnvelope();
            double xa = (ea.getMinX() + ea.getMaxX()) / 2.0;
            double xb = (eb.getMinX() + eb.getMaxX()) / 2.0;
            return xa < xb;
        }
    } nodeSortByX;

    std::sort(nodeList.begin(), nodeList.end(), nodeSortByX);
}

/* private */
std::vector<SimpleSTRnode*>
SimpleSTRtree::createParentNodes(
    std::vector<SimpleSTRnode*>& childNodes,
    int newLevel)
{
    assert(!childNodes.empty());

    std::size_t minLeafCount = (std::size_t)std::ceil((double)(childNodes.size()) / (double)nodeCapacity);
    std::size_t sliceCount = (std::size_t)std::ceil(std::sqrt((double)minLeafCount));
    std::size_t sliceCapacity = (std::size_t)std::ceil((double)(childNodes.size()) / (double)sliceCount);

    sortNodesX(childNodes);

    std::size_t i = 0;
    std::size_t nChildren = childNodes.size();
    std::vector<SimpleSTRnode*> parentNodes;
    std::vector<SimpleSTRnode*> verticalSlice(sliceCapacity);
    for (std::size_t j = 0; j < sliceCount; j++) {
        verticalSlice.clear();
        std::size_t nodesAddedToSlice = 0;
        while(i < nChildren && nodesAddedToSlice < sliceCapacity) {
            verticalSlice.push_back(childNodes[i++]);
            ++nodesAddedToSlice;
        }
        addParentNodesFromVerticalSlice(verticalSlice, newLevel, parentNodes);
    }
    return parentNodes;
}

/* private */
void
SimpleSTRtree::addParentNodesFromVerticalSlice(
    std::vector<SimpleSTRnode*>& verticalSlice,
    int newLevel,
    std::vector<SimpleSTRnode*>& parentNodes)
{
    sortNodesY(verticalSlice);

    SimpleSTRnode* parent = nullptr;
    for (auto* node: verticalSlice) {
        if (!parent) {
            parent = createNode(newLevel);
        }
        parent->addChildNode(node);
        if (parent->size() == nodeCapacity) {
            parentNodes.push_back(parent);
            parent = nullptr;
        }
    }
    if (parent)
        parentNodes.push_back(parent);

    return;
}

/* private */
std::vector<SimpleSTRnode*>
SimpleSTRtree::createHigherLevels(
    std::vector<SimpleSTRnode*>& nodesOfALevel, int level)
{
    int nextLevel = level+1;
    std::vector<SimpleSTRnode*> parentNodes = createParentNodes(nodesOfALevel, nextLevel);
    if (parentNodes.size() == 1) {
        return parentNodes;
    }
    return createHigherLevels(parentNodes, nextLevel);
}

/* private */
void
SimpleSTRtree::build()
{
    if (built) return;

    if (nodes.empty()) {
        root = nullptr;
    }
    else {
        std::vector<SimpleSTRnode*> nodeTree = createHigherLevels(nodes, -1);
        assert(nodeTree.size()==1);
        root = nodeTree[0];
    }
    built = true;
}

void
SimpleSTRtree::iterate(ItemVisitor& visitor)
{
    for(auto* leafNode: nodes) {
        visitor.visitItem(leafNode->getItem());
    }
}

/* public */
void
SimpleSTRtree::query(const geom::Envelope* searchEnv, ItemVisitor& visitor)
{
    build();

    if(nodes.empty() || !root) {
        return;
    }

    if(root->getEnvelope().intersects(searchEnv)) {
        query(searchEnv, root, visitor);
    }
}

/* private */
void
SimpleSTRtree::query(const geom::Envelope* searchEnv,
    const SimpleSTRnode* node, ItemVisitor& visitor)
{
    for(auto* childNode: node->getChildNodes()) {

        if(!childNode->getEnvelope().intersects(searchEnv)) {
            continue;
        }

        if (childNode->isLeaf()) {
            visitor.visitItem(childNode->getItem());
        } else {
            query(searchEnv, childNode, visitor);
        }
    }
}

/* public */
void
SimpleSTRtree::query(const geom::Envelope* searchEnv, std::vector<void*>& matches)
{
    build();

    if(nodes.empty() || !root) {
        return;
    }

    if(root->getEnvelope().intersects(searchEnv)) {
        query(searchEnv, root, matches);
    }
}

/* private */
void
SimpleSTRtree::query(const geom::Envelope* searchEnv,
    const SimpleSTRnode* node, std::vector<void*>& matches)
{
    assert(node);

    for(auto* childNode: node->getChildNodes()) {

        if(!childNode->getEnvelope().intersects(searchEnv)) {
            continue;
        }

        if (childNode->isLeaf()) {
            matches.push_back(childNode->getItem());
        } else {
            query(searchEnv, childNode, matches);
        }
    }
}

/* public */
bool
SimpleSTRtree::remove(const geom::Envelope* itemEnv, void* item)
{
    ::geos::ignore_unused_variable_warning(itemEnv);
    ::geos::ignore_unused_variable_warning(item);
    assert(false);
}

/*public static*/
std::ostream&
operator<<(std::ostream& os, SimpleSTRtree& tree)
{

    os << "nodeCapacity: " << tree.getNodeCapacity() << std::endl;
    os << "nodes.size(): " << tree.getNumLeafNodes() << std::endl;
    os << "built: " << tree.getBuilt() << std::endl;

    if (tree.getRoot()) {
        os << "tree: " << std::endl;
        tree.getRoot()->toString(os, 1);
    }
    else {
        os << "tree: empty" << std::endl;
    }
    return os;
}

/*********************************************************************************/

/*public*/
std::pair<const void*, const void*>
SimpleSTRtree::nearestNeighbour(ItemDistance* itemDist)
{
    if (!this->getRoot()) {
        return std::pair<const void*, const void*>(nullptr, nullptr);
    }
    SimpleSTRdistance strDist(this->getRoot(), this->getRoot(), itemDist);
    return strDist.nearestNeighbour();
}

/*public*/
const void*
SimpleSTRtree::nearestNeighbour(const geom::Envelope* p_env, const void* p_item, ItemDistance* itemDist)
{
    if (!this->getRoot()) {
        return nullptr;
    }
    std::unique_ptr<SimpleSTRnode> ssn(new SimpleSTRnode(0, p_env, (void*)p_item));
    SimpleSTRdistance strDist(getRoot(), ssn.get(), itemDist);
    std::pair<const void*, const void*> result = strDist.nearestNeighbour();
    return result.first;
}

/*public*/
std::pair<const void*, const void*>
SimpleSTRtree::nearestNeighbour(SimpleSTRtree& tree, ItemDistance* itemDist)
{
    if (!(this->getRoot() && tree.getRoot())) {
        return std::pair<const void*, const void*>(nullptr, nullptr);
    }
    SimpleSTRdistance strDist(this->getRoot(), tree.getRoot(), itemDist);
    return strDist.nearestNeighbour();
}

/*public*/
bool
SimpleSTRtree::isWithinDistance(SimpleSTRtree& tree, ItemDistance* itemDist, double maxDistance)
{
    if (!(this->getRoot() && tree.getRoot())) {
        return false;
    }
    SimpleSTRdistance strDist(this->getRoot(), tree.getRoot(), itemDist);
    return strDist.isWithinDistance(maxDistance);
}

} // namespace geos.index.strtree
} // namespace geos.index
} // namespace geos
<commit_msg>CI MS build error<commit_after>/**********************************************************************
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.osgeo.org
 *
 * Copyright (C) 2020 Paul Ramsey
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/index/strtree/SimpleSTRtree.h>
#include <geos/index/strtree/SimpleSTRdistance.h>
#include <geos/index/ItemVisitor.h>
#include <geos/geom/Envelope.h>
#include <geos/geom/Geometry.h>
#include <geos/util.h>

#include <vector>
#include <cassert>
#include <cmath>
#include <algorithm> // std::sort
#include <iostream> // for debugging
#include <limits>
#include <geos/util/GEOSException.h>

using namespace geos::geom;

namespace geos {
namespace index { // geos.index
namespace strtree { // geos.index.strtree

/* private */
SimpleSTRnode*
SimpleSTRtree::createNode(int newLevel, const geom::Envelope* itemEnv, void* item)
{
    nodesQue.emplace_back(newLevel, itemEnv, item, nodeCapacity);
    SimpleSTRnode& node = nodesQue.back();
    return &node;
}

/* private */
SimpleSTRnode*
SimpleSTRtree::createNode(int newLevel)
{
    return createNode(newLevel, nullptr, nullptr);
}

/* public */
void
SimpleSTRtree::insert(geom::Geometry* geom)
{
    insert(geom->getEnvelopeInternal(), static_cast<void*>(geom));
}

/* public */
void
SimpleSTRtree::insert(const geom::Envelope* itemEnv, void* item)
{
    if (itemEnv->isNull())
        return;
    SimpleSTRnode *node = createNode(0, itemEnv, item);
    nodes.push_back(node);
}

/* private static */
void
SimpleSTRtree::sortNodesY(std::vector<SimpleSTRnode*>& nodeList)
{
    struct {
        bool operator()(SimpleSTRnode* a, SimpleSTRnode* b) const
        {
            const geom::Envelope& ea = a->getEnvelope();
            const geom::Envelope& eb = b->getEnvelope();
            double ya = (ea.getMinY() + ea.getMaxY()) / 2.0;
            double yb = (eb.getMinY() + eb.getMaxY()) / 2.0;
            return ya < yb;
        }
    } nodeSortByY;

    std::sort(nodeList.begin(), nodeList.end(), nodeSortByY);
}

/* private static */
void
SimpleSTRtree::sortNodesX(std::vector<SimpleSTRnode*>& nodeList)
{
    struct {
        bool operator()(SimpleSTRnode* a, SimpleSTRnode* b) const
        {
            const geom::Envelope& ea = a->getEnvelope();
            const geom::Envelope& eb = b->getEnvelope();
            double xa = (ea.getMinX() + ea.getMaxX()) / 2.0;
            double xb = (eb.getMinX() + eb.getMaxX()) / 2.0;
            return xa < xb;
        }
    } nodeSortByX;

    std::sort(nodeList.begin(), nodeList.end(), nodeSortByX);
}

/* private */
std::vector<SimpleSTRnode*>
SimpleSTRtree::createParentNodes(
    std::vector<SimpleSTRnode*>& childNodes,
    int newLevel)
{
    assert(!childNodes.empty());

    std::size_t minLeafCount = (std::size_t)std::ceil((double)(childNodes.size()) / (double)nodeCapacity);
    std::size_t sliceCount = (std::size_t)std::ceil(std::sqrt((double)minLeafCount));
    std::size_t sliceCapacity = (std::size_t)std::ceil((double)(childNodes.size()) / (double)sliceCount);

    sortNodesX(childNodes);

    std::size_t i = 0;
    std::size_t nChildren = childNodes.size();
    std::vector<SimpleSTRnode*> parentNodes;
    std::vector<SimpleSTRnode*> verticalSlice(sliceCapacity);
    for (std::size_t j = 0; j < sliceCount; j++) {
        verticalSlice.clear();
        std::size_t nodesAddedToSlice = 0;
        while(i < nChildren && nodesAddedToSlice < sliceCapacity) {
            verticalSlice.push_back(childNodes[i++]);
            ++nodesAddedToSlice;
        }
        addParentNodesFromVerticalSlice(verticalSlice, newLevel, parentNodes);
    }
    return parentNodes;
}

/* private */
void
SimpleSTRtree::addParentNodesFromVerticalSlice(
    std::vector<SimpleSTRnode*>& verticalSlice,
    int newLevel,
    std::vector<SimpleSTRnode*>& parentNodes)
{
    sortNodesY(verticalSlice);

    SimpleSTRnode* parent = nullptr;
    for (auto* node: verticalSlice) {
        if (!parent) {
            parent = createNode(newLevel);
        }
        parent->addChildNode(node);
        if (parent->size() == nodeCapacity) {
            parentNodes.push_back(parent);
            parent = nullptr;
        }
    }
    if (parent)
        parentNodes.push_back(parent);

    return;
}

/* private */
std::vector<SimpleSTRnode*>
SimpleSTRtree::createHigherLevels(
    std::vector<SimpleSTRnode*>& nodesOfALevel, int level)
{
    int nextLevel = level+1;
    std::vector<SimpleSTRnode*> parentNodes = createParentNodes(nodesOfALevel, nextLevel);
    if (parentNodes.size() == 1) {
        return parentNodes;
    }
    return createHigherLevels(parentNodes, nextLevel);
}

/* private */
void
SimpleSTRtree::build()
{
    if (built) return;

    if (nodes.empty()) {
        root = nullptr;
    }
    else {
        std::vector<SimpleSTRnode*> nodeTree = createHigherLevels(nodes, -1);
        assert(nodeTree.size()==1);
        root = nodeTree[0];
    }
    built = true;
}

void
SimpleSTRtree::iterate(ItemVisitor& visitor)
{
    for(auto* leafNode: nodes) {
        visitor.visitItem(leafNode->getItem());
    }
}

/* public */
void
SimpleSTRtree::query(const geom::Envelope* searchEnv, ItemVisitor& visitor)
{
    build();

    if(nodes.empty() || !root) {
        return;
    }

    if(root->getEnvelope().intersects(searchEnv)) {
        query(searchEnv, root, visitor);
    }
}

/* private */
void
SimpleSTRtree::query(const geom::Envelope* searchEnv,
    const SimpleSTRnode* node, ItemVisitor& visitor)
{
    for(auto* childNode: node->getChildNodes()) {

        if(!childNode->getEnvelope().intersects(searchEnv)) {
            continue;
        }

        if (childNode->isLeaf()) {
            visitor.visitItem(childNode->getItem());
        } else {
            query(searchEnv, childNode, visitor);
        }
    }
}

/* public */
void
SimpleSTRtree::query(const geom::Envelope* searchEnv, std::vector<void*>& matches)
{
    build();

    if(nodes.empty() || !root) {
        return;
    }

    if(root->getEnvelope().intersects(searchEnv)) {
        query(searchEnv, root, matches);
    }
}

/* private */
void
SimpleSTRtree::query(const geom::Envelope* searchEnv,
    const SimpleSTRnode* node, std::vector<void*>& matches)
{
    assert(node);

    for(auto* childNode: node->getChildNodes()) {

        if(!childNode->getEnvelope().intersects(searchEnv)) {
            continue;
        }

        if (childNode->isLeaf()) {
            matches.push_back(childNode->getItem());
        } else {
            query(searchEnv, childNode, matches);
        }
    }
}

/* public */
bool
SimpleSTRtree::remove(const geom::Envelope* itemEnv, void* item)
{
    ::geos::ignore_unused_variable_warning(itemEnv);
    ::geos::ignore_unused_variable_warning(item);
    assert(false);
    return false;
}

/*public static*/
std::ostream&
operator<<(std::ostream& os, SimpleSTRtree& tree)
{

    os << "nodeCapacity: " << tree.getNodeCapacity() << std::endl;
    os << "nodes.size(): " << tree.getNumLeafNodes() << std::endl;
    os << "built: " << tree.getBuilt() << std::endl;

    if (tree.getRoot()) {
        os << "tree: " << std::endl;
        tree.getRoot()->toString(os, 1);
    }
    else {
        os << "tree: empty" << std::endl;
    }
    return os;
}

/*********************************************************************************/

/*public*/
std::pair<const void*, const void*>
SimpleSTRtree::nearestNeighbour(ItemDistance* itemDist)
{
    if (!this->getRoot()) {
        return std::pair<const void*, const void*>(nullptr, nullptr);
    }
    SimpleSTRdistance strDist(this->getRoot(), this->getRoot(), itemDist);
    return strDist.nearestNeighbour();
}

/*public*/
const void*
SimpleSTRtree::nearestNeighbour(const geom::Envelope* p_env, const void* p_item, ItemDistance* itemDist)
{
    if (!this->getRoot()) {
        return nullptr;
    }
    std::unique_ptr<SimpleSTRnode> ssn(new SimpleSTRnode(0, p_env, (void*)p_item));
    SimpleSTRdistance strDist(getRoot(), ssn.get(), itemDist);
    std::pair<const void*, const void*> result = strDist.nearestNeighbour();
    return result.first;
}

/*public*/
std::pair<const void*, const void*>
SimpleSTRtree::nearestNeighbour(SimpleSTRtree& tree, ItemDistance* itemDist)
{
    if (!(this->getRoot() && tree.getRoot())) {
        return std::pair<const void*, const void*>(nullptr, nullptr);
    }
    SimpleSTRdistance strDist(this->getRoot(), tree.getRoot(), itemDist);
    return strDist.nearestNeighbour();
}

/*public*/
bool
SimpleSTRtree::isWithinDistance(SimpleSTRtree& tree, ItemDistance* itemDist, double maxDistance)
{
    if (!(this->getRoot() && tree.getRoot())) {
        return false;
    }
    SimpleSTRdistance strDist(this->getRoot(), tree.getRoot(), itemDist);
    return strDist.isWithinDistance(maxDistance);
}

} // namespace geos.index.strtree
} // namespace geos.index
} // namespace geos
<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

/**
 * @file EntityWithSources.cpp
 * @brief Implementation of all methods of the class EntityWithSources.
 */

#include <pandora/Util.hpp>
#include <pandora/Group.hpp>
#include <pandora/DataSet.hpp>
#include <pandora/PSize.hpp>
#include <pandora/File.hpp>
#include <pandora/Block.hpp>
#include <pandora/Source.hpp>
#include <pandora/EntityWithSources.hpp>

using namespace std;

namespace pandora {

EntityWithSources::EntityWithSources(File file, Block block, Group group, string id)
  : EntityWithMetadata(file, group, id), block(block)
{

}

EntityWithSources::EntityWithSources(File file, Block block, Group group, string id, time_t time)
  : EntityWithMetadata(file, group, id, time), block(block)
{

}

std::vector<std::string> EntityWithSources::source_ids() const
{
  vector<string> ids;

  if (group.hasData("sources")) {
    DataSet ds = group.openData("sources");
    ds.read(ids, true);
  }

  return ids;
}

size_t EntityWithSources::sourceCount() const {
  size_t count = 0;
  if (group.hasData("sources")) {
    DataSet dataset = group.openData("sources");
    PSize size = dataset.size();
    count = size[0];
  }
  return count;
}

bool EntityWithSources::hasSource(const Source &source) const {
  return hasSource(source.id());
}

bool EntityWithSources::hasSource(string id) const {
  bool found = false;

  if (sourceCount() > 0) {
    vector<Source> s = sources();
    for (size_t i = 0; i < s.size() && !found; i++) {
      if (s[i].id().compare(id) == 0) {
        found = true;
        break;
      }
    }
  }

  return found;
}

vector<Source> EntityWithSources::sources() const {
  vector<string> ids;
  vector<Source> source_obj;

  if (group.hasData("sources")) {
    DataSet ds = group.openData("sources");
    Selection fileSel = ds.createSelection();
    fileSel.select({0}, {sourceCount()});
    ds.read(ids, fileSel, true);
  }

  source_obj = block.findSources([&](const Source &source) {
    return std::find(ids.begin(), ids.end(), source.id()) != ids.end();
  });

  if (source_obj.size() != ids.size()) {
    // TODO What is the right thing to do here?
    throw runtime_error("Could not resolve all ids");
  }

  return source_obj;
}

void EntityWithSources::addSource(const Source &source) {
  string source_id = source.id();

  if (!block.hasSource(source_id)) {
    throw runtime_error("Unable to find source with id " + source_id +
                        "on block " + block.id());
  }

  if (!hasSource(source_id)) {
    vector<string> vals;
    vals.push_back(source_id);
    PSize start;
    DataSet ds((H5::DataSet()));

    if (group.hasData("sources")) {
      ds = group.openData("sources");
      PSize size = ds.size();
      PSize newSize = size + 1;
      ds.extend(newSize);
      start = size;
    } else {
      Charon<vector<string>> charon(vals);
      PSize size = { 1 };
      PSize maxsize = { H5S_UNLIMITED };
      PSize chunks = DataSet::guessChunking(size, DataType::Double);
      ds = DataSet::create(group.h5Group(), charon.getFileType(), "sources", size,
          &maxsize, &chunks);
      start = {0};
    }

    Selection fileSel = ds.createSelection();
    PSize count = { 1 };
    fileSel.select(count, start);
    ds.write(vals, fileSel);
  }
}

void EntityWithSources::sources(vector<Source> s) {
  vector<string> ids;

  for (size_t i = 0; i < s.size(); i++) {
    string id = s[i].id();
    if (block.hasSource(id)) {
      ids.push_back(id);
    } else {
      throw runtime_error("Unable to find source with id " + id +
                              "on block " + block.id());
    }
  }

  sort(ids.begin(), ids.end());

  // TODO It would be so cool if we could avoid/reduce this boiler plate code.
  group.removeData("sources");
  PSize start;
  DataSet ds((H5::DataSet()));
  Charon<vector<string> > charon(ids);
  PSize size = { ids.size() };
  PSize maxsize = { H5S_UNLIMITED };
  PSize chunks = DataSet::guessChunking(size, DataType::Double);
  ds = DataSet::create(group.h5Group(), charon.getFileType(), "sources", size,
      &maxsize, &chunks);
  start = {0};
  Selection fileSel = ds.createSelection();
  PSize count = { ids.size() };
  fileSel.select(count, start);
  ds.write(ids, fileSel);

}

bool EntityWithSources::removeSource(const Source &source){
  bool removed = false;
  vector<Source> source_obj = sources();

  for(size_t i = 0; i < source_obj.size() && !removed; i++){
    if (source_obj[i].compare(source) == 0) {
      source_obj.erase(source_obj.begin() + i);
      removed = true;
    }
  }

  if (removed) {
    sources(source_obj);
  }

  return removed;
}

EntityWithSources::~EntityWithSources() {

}

} //namespace
<commit_msg>EntityWithSources::hasSource: Use source_ids()<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

/**
 * @file EntityWithSources.cpp
 * @brief Implementation of all methods of the class EntityWithSources.
 */

#include <pandora/Util.hpp>
#include <pandora/Group.hpp>
#include <pandora/DataSet.hpp>
#include <pandora/PSize.hpp>
#include <pandora/File.hpp>
#include <pandora/Block.hpp>
#include <pandora/Source.hpp>
#include <pandora/EntityWithSources.hpp>

using namespace std;

namespace pandora {

EntityWithSources::EntityWithSources(File file, Block block, Group group, string id)
  : EntityWithMetadata(file, group, id), block(block)
{

}

EntityWithSources::EntityWithSources(File file, Block block, Group group, string id, time_t time)
  : EntityWithMetadata(file, group, id, time), block(block)
{

}

std::vector<std::string> EntityWithSources::source_ids() const
{
  vector<string> ids;

  if (group.hasData("sources")) {
    DataSet ds = group.openData("sources");
    ds.read(ids, true);
  }

  return ids;
}

size_t EntityWithSources::sourceCount() const {
  size_t count = 0;
  if (group.hasData("sources")) {
    DataSet dataset = group.openData("sources");
    PSize size = dataset.size();
    count = size[0];
  }
  return count;
}

bool EntityWithSources::hasSource(const Source &source) const {
  return hasSource(source.id());
}

bool EntityWithSources::hasSource(string id) const {
  vector<string> ids = source_ids();
  return std::find(ids.begin(), ids.end(), id) != ids.end();
}

vector<Source> EntityWithSources::sources() const {
  vector<string> ids;
  vector<Source> source_obj;

  if (group.hasData("sources")) {
    DataSet ds = group.openData("sources");
    Selection fileSel = ds.createSelection();
    fileSel.select({0}, {sourceCount()});
    ds.read(ids, fileSel, true);
  }

  source_obj = block.findSources([&](const Source &source) {
    return std::find(ids.begin(), ids.end(), source.id()) != ids.end();
  });

  if (source_obj.size() != ids.size()) {
    // TODO What is the right thing to do here?
    throw runtime_error("Could not resolve all ids");
  }

  return source_obj;
}

void EntityWithSources::addSource(const Source &source) {
  string source_id = source.id();

  if (!block.hasSource(source_id)) {
    throw runtime_error("Unable to find source with id " + source_id +
                        "on block " + block.id());
  }

  if (!hasSource(source_id)) {
    vector<string> vals;
    vals.push_back(source_id);
    PSize start;
    DataSet ds((H5::DataSet()));

    if (group.hasData("sources")) {
      ds = group.openData("sources");
      PSize size = ds.size();
      PSize newSize = size + 1;
      ds.extend(newSize);
      start = size;
    } else {
      Charon<vector<string>> charon(vals);
      PSize size = { 1 };
      PSize maxsize = { H5S_UNLIMITED };
      PSize chunks = DataSet::guessChunking(size, DataType::Double);
      ds = DataSet::create(group.h5Group(), charon.getFileType(), "sources", size,
          &maxsize, &chunks);
      start = {0};
    }

    Selection fileSel = ds.createSelection();
    PSize count = { 1 };
    fileSel.select(count, start);
    ds.write(vals, fileSel);
  }
}

void EntityWithSources::sources(vector<Source> s) {
  vector<string> ids;

  for (size_t i = 0; i < s.size(); i++) {
    string id = s[i].id();
    if (block.hasSource(id)) {
      ids.push_back(id);
    } else {
      throw runtime_error("Unable to find source with id " + id +
                              "on block " + block.id());
    }
  }

  sort(ids.begin(), ids.end());

  // TODO It would be so cool if we could avoid/reduce this boiler plate code.
  group.removeData("sources");
  PSize start;
  DataSet ds((H5::DataSet()));
  Charon<vector<string> > charon(ids);
  PSize size = { ids.size() };
  PSize maxsize = { H5S_UNLIMITED };
  PSize chunks = DataSet::guessChunking(size, DataType::Double);
  ds = DataSet::create(group.h5Group(), charon.getFileType(), "sources", size,
      &maxsize, &chunks);
  start = {0};
  Selection fileSel = ds.createSelection();
  PSize count = { ids.size() };
  fileSel.select(count, start);
  ds.write(ids, fileSel);

}

bool EntityWithSources::removeSource(const Source &source){
  bool removed = false;
  vector<Source> source_obj = sources();

  for(size_t i = 0; i < source_obj.size() && !removed; i++){
    if (source_obj[i].compare(source) == 0) {
      source_obj.erase(source_obj.begin() + i);
      removed = true;
    }
  }

  if (removed) {
    sources(source_obj);
  }

  return removed;
}

EntityWithSources::~EntityWithSources() {

}

} //namespace
<|endoftext|>


<commit_before>// -*- mode: C++ -*-
//
// Copyright (c) 2007, 2008, 2010, 2011 The University of Utah
// All rights reserved.
//
// This file is part of `csmith', a random generator of C programs.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistributions in binary form must reproduce the above copyright
//     notice, this list of conditions and the following disclaimer in the
//     documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include "ExpressionFuncall.h"
#include <cassert>

#include "Common.h"

#include "CGContext.h"
#include "CGOptions.h"
#include "ExpressionVariable.h"
#include "Function.h"
#include "FunctionInvocation.h"
#include "FunctionInvocationUser.h"
#include "VariableSelector.h"
#include "FactMgr.h"
#include "Error.h"
#include "Bookkeeper.h"
#include "StringUtils.h"
#include "Reducer.h"
#include "Block.h"
#include "random.h"

///////////////////////////////////////////////////////////////////////////////

/*
 *
 */
static bool
ExpressionFunctionProbability(const CGContext &/*cg_context*/)
{
	if (Function::reach_max_functions_cnt()) {
		return true;
	}
	return rnd_flipcoin(80);
}

/*
 *
 */
Expression *
ExpressionFuncall::make_random(CGContext &cg_context, const Type* type, const CVQualifiers* qfer)
{
	Expression *e = 0;
	bool std_func = ExpressionFunctionProbability(cg_context);
	ERROR_GUARD(NULL);
    // unary/binary "functions" produce scalar types only
	if (type && ((type->eType != eSimple && type->eType != eVector) || type->simple_type == eVoid))
		std_func = false;

	Effect effect_accum = cg_context.get_accum_effect();
	Effect effect_stm = cg_context.get_effect_stm();
	FactMgr* fm = get_fact_mgr(&cg_context);
	vector<const Fact*> facts_copy = fm->global_facts;
	FunctionInvocation *fi = FunctionInvocation::make_random(std_func, cg_context, type, qfer);
	ERROR_GUARD(NULL);

	if (fi->failed) {
		// if it's a invalid invocation, (see FunctionInvocationUser::revisit)
		// restore the env, and replace invocation with a simple var
		cg_context.reset_effect_accum(effect_accum);
		cg_context.reset_effect_stm(effect_stm);
		fm->restore_facts(facts_copy);
		e = ExpressionVariable::make_random(cg_context, type, qfer);
		delete fi;
	}
	else {
		e = new ExpressionFuncall(*fi);
	}
	return e;
}

/*
 *
 */
Expression *
ExpressionFuncall::clone() const
{
	const FunctionInvocation *fi = (this->invoke).clone();
	return new ExpressionFuncall(*fi);
}

/*
 *
 */
ExpressionFuncall::ExpressionFuncall(const FunctionInvocation &fi)
	: Expression(eFunction),
	  invoke(fi)
{
}

/*
 *
 */
ExpressionFuncall::~ExpressionFuncall(void)
{
	delete &invoke;
}

///////////////////////////////////////////////////////////////////////////////

/*
 *
 */
const Type &
ExpressionFuncall::get_type(void) const
{
	return invoke.get_type();
}

void
ExpressionFuncall::get_called_funcs(std::vector<const FunctionInvocationUser*>& funcs) const
{
	invoke.get_called_funcs(funcs);
}

unsigned int
ExpressionFuncall::get_complexity(void) const
{
	unsigned int comp = 0;
	const FunctionInvocation* invoke = get_invoke();
	if (invoke->invoke_type == eFuncCall) {
		comp++;  // function call itself counts as 1 complexity
	}
	for (size_t i=0; i<invoke->param_value.size(); i++) {
		comp += invoke->param_value[i]->get_complexity();
	}
	return comp;
}

bool
ExpressionFuncall::visit_facts(vector<const Fact*>& inputs, CGContext& cg_context) const
{
	return invoke.visit_facts(inputs, cg_context);
}

std::vector<const ExpressionVariable*>
ExpressionFuncall::get_dereferenced_ptrs(void) const
{
	// return a empty vector by default
	std::vector<const ExpressionVariable*> refs;
	for (size_t i=0; i<invoke.param_value.size(); i++) {
		// the parameters might has pointer dereferences
		const Expression* value = invoke.param_value[i];
		vector<const ExpressionVariable*> deref_ptrs = value->get_dereferenced_ptrs();
		refs.insert(refs.end(),  deref_ptrs.begin(), deref_ptrs.end());
	}
	return refs;
}

// find pointers used in the expression, recursively go into callee if this is a call
void
ExpressionFuncall::get_referenced_ptrs(std::vector<const Variable*>& ptrs) const
{
	for (size_t i=0; i<invoke.param_value.size(); i++) {
		// the parameters might has pointer references
		const Expression* value = invoke.param_value[i];
		value->get_referenced_ptrs(ptrs);
	}
	if (invoke.invoke_type == eFuncCall) {
		const FunctionInvocationUser* fiu = dynamic_cast<const FunctionInvocationUser*>(&invoke);
		assert(fiu);
		//cout << "follow " << fiu->get_func()->name << endl;
		add_variables_to_set(ptrs, fiu->get_func()->get_referenced_ptrs());
	}
}

bool
ExpressionFuncall::has_uncertain_call_recursive(void) const
{
	return invoke.has_uncertain_call_recursive();
}

/*
 * return the const/volatile qualifiers for function calls
 */
CVQualifiers
ExpressionFuncall::get_qualifiers(void) const
{
	return invoke.get_qualifiers();
}

/*
 * return if a variable is referenced in this expression
 */
bool
ExpressionFuncall::use_var(const Variable* v) const
{
	size_t i;
	for (i=0; i<invoke.param_value.size(); i++) {
		if (invoke.param_value[i]->use_var(v)) {
			return true;
		}
	}
	return false;
}

/*
 *
 */
bool
ExpressionFuncall::compatible(const Variable *v) const
{
	return invoke.compatible(v);
}

bool ExpressionFuncall::compatible(const Expression * /*exp*/) const
{
	return false;
}

/*
 *
 */
void
ExpressionFuncall::Output(std::ostream &out) const
{
	output_cast(out);
	Reducer* reducer = CGOptions::get_reducer();
	if (reducer && reducer->output_expr(this, out)) {
		return;
	}
	invoke.Output(out);
}

void
ExpressionFuncall::indented_output(std::ostream &out, int indent) const
{
	invoke.indented_output(out, indent);
}

///////////////////////////////////////////////////////////////////////////////

// Local Variables:
// c-basic-offset: 4
// tab-width: 4
// End:

// End of file.
<commit_msg>Prevented generation of function calls (user-defined) from being created in atomic blocks (would lead to nondeterminism).<commit_after>// -*- mode: C++ -*-
//
// Copyright (c) 2007, 2008, 2010, 2011 The University of Utah
// All rights reserved.
//
// This file is part of `csmith', a random generator of C programs.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistributions in binary form must reproduce the above copyright
//     notice, this list of conditions and the following disclaimer in the
//     documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include "ExpressionFuncall.h"
#include <cassert>

#include "Common.h"

#include "CGContext.h"
#include "CGOptions.h"
#include "ExpressionVariable.h"
#include "Function.h"
#include "FunctionInvocation.h"
#include "FunctionInvocationUser.h"
#include "VariableSelector.h"
#include "FactMgr.h"
#include "Error.h"
#include "Bookkeeper.h"
#include "StringUtils.h"
#include "Reducer.h"
#include "Block.h"
#include "random.h"

///////////////////////////////////////////////////////////////////////////////

/*
 *
 */
static bool
ExpressionFunctionProbability(const CGContext &/*cg_context*/)
{
	if (Function::reach_max_functions_cnt()) {
		return true;
	}
	return rnd_flipcoin(80);
}

/*
 *
 */
Expression *
ExpressionFuncall::make_random(CGContext &cg_context, const Type* type, const CVQualifiers* qfer)
{
	Expression *e = 0;
	bool std_func = cg_context.get_atomic_context() ? true : ExpressionFunctionProbability(cg_context);
	ERROR_GUARD(NULL);
    // unary/binary "functions" produce scalar types only
	if (type && ((type->eType != eSimple && type->eType != eVector) || type->simple_type == eVoid))
		std_func = false;

	Effect effect_accum = cg_context.get_accum_effect();
	Effect effect_stm = cg_context.get_effect_stm();
	FactMgr* fm = get_fact_mgr(&cg_context);
	vector<const Fact*> facts_copy = fm->global_facts;
	FunctionInvocation *fi = FunctionInvocation::make_random(std_func, cg_context, type, qfer);
	ERROR_GUARD(NULL);

	if (fi->failed) {
		// if it's a invalid invocation, (see FunctionInvocationUser::revisit)
		// restore the env, and replace invocation with a simple var
		cg_context.reset_effect_accum(effect_accum);
		cg_context.reset_effect_stm(effect_stm);
		fm->restore_facts(facts_copy);
		e = ExpressionVariable::make_random(cg_context, type, qfer);
		delete fi;
	}
	else {
		e = new ExpressionFuncall(*fi);
	}
	return e;
}

/*
 *
 */
Expression *
ExpressionFuncall::clone() const
{
	const FunctionInvocation *fi = (this->invoke).clone();
	return new ExpressionFuncall(*fi);
}

/*
 *
 */
ExpressionFuncall::ExpressionFuncall(const FunctionInvocation &fi)
	: Expression(eFunction),
	  invoke(fi)
{
}

/*
 *
 */
ExpressionFuncall::~ExpressionFuncall(void)
{
	delete &invoke;
}

///////////////////////////////////////////////////////////////////////////////

/*
 *
 */
const Type &
ExpressionFuncall::get_type(void) const
{
	return invoke.get_type();
}

void
ExpressionFuncall::get_called_funcs(std::vector<const FunctionInvocationUser*>& funcs) const
{
	invoke.get_called_funcs(funcs);
}

unsigned int
ExpressionFuncall::get_complexity(void) const
{
	unsigned int comp = 0;
	const FunctionInvocation* invoke = get_invoke();
	if (invoke->invoke_type == eFuncCall) {
		comp++;  // function call itself counts as 1 complexity
	}
	for (size_t i=0; i<invoke->param_value.size(); i++) {
		comp += invoke->param_value[i]->get_complexity();
	}
	return comp;
}

bool
ExpressionFuncall::visit_facts(vector<const Fact*>& inputs, CGContext& cg_context) const
{
	return invoke.visit_facts(inputs, cg_context);
}

std::vector<const ExpressionVariable*>
ExpressionFuncall::get_dereferenced_ptrs(void) const
{
	// return a empty vector by default
	std::vector<const ExpressionVariable*> refs;
	for (size_t i=0; i<invoke.param_value.size(); i++) {
		// the parameters might has pointer dereferences
		const Expression* value = invoke.param_value[i];
		vector<const ExpressionVariable*> deref_ptrs = value->get_dereferenced_ptrs();
		refs.insert(refs.end(),  deref_ptrs.begin(), deref_ptrs.end());
	}
	return refs;
}

// find pointers used in the expression, recursively go into callee if this is a call
void
ExpressionFuncall::get_referenced_ptrs(std::vector<const Variable*>& ptrs) const
{
	for (size_t i=0; i<invoke.param_value.size(); i++) {
		// the parameters might has pointer references
		const Expression* value = invoke.param_value[i];
		value->get_referenced_ptrs(ptrs);
	}
	if (invoke.invoke_type == eFuncCall) {
		const FunctionInvocationUser* fiu = dynamic_cast<const FunctionInvocationUser*>(&invoke);
		assert(fiu);
		//cout << "follow " << fiu->get_func()->name << endl;
		add_variables_to_set(ptrs, fiu->get_func()->get_referenced_ptrs());
	}
}

bool
ExpressionFuncall::has_uncertain_call_recursive(void) const
{
	return invoke.has_uncertain_call_recursive();
}

/*
 * return the const/volatile qualifiers for function calls
 */
CVQualifiers
ExpressionFuncall::get_qualifiers(void) const
{
	return invoke.get_qualifiers();
}

/*
 * return if a variable is referenced in this expression
 */
bool
ExpressionFuncall::use_var(const Variable* v) const
{
	size_t i;
	for (i=0; i<invoke.param_value.size(); i++) {
		if (invoke.param_value[i]->use_var(v)) {
			return true;
		}
	}
	return false;
}

/*
 *
 */
bool
ExpressionFuncall::compatible(const Variable *v) const
{
	return invoke.compatible(v);
}

bool ExpressionFuncall::compatible(const Expression * /*exp*/) const
{
	return false;
}

/*
 *
 */
void
ExpressionFuncall::Output(std::ostream &out) const
{
	output_cast(out);
	Reducer* reducer = CGOptions::get_reducer();
	if (reducer && reducer->output_expr(this, out)) {
		return;
	}
	invoke.Output(out);
}

void
ExpressionFuncall::indented_output(std::ostream &out, int indent) const
{
	invoke.indented_output(out, indent);
}

///////////////////////////////////////////////////////////////////////////////

// Local Variables:
// c-basic-offset: 4
// tab-width: 4
// End:

// End of file.
<|endoftext|>